Imported Upstream version 3.7.5 upstream/3.7.5
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 8 Dec 2020 04:45:06 +0000 (13:45 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 8 Dec 2020 04:45:06 +0000 (13:45 +0900)
363 files changed:
.azure-pipelines/ci.yml
.azure-pipelines/macos-steps.yml
.azure-pipelines/pr.yml
Doc/Makefile
Doc/bugs.rst
Doc/c-api/allocation.rst
Doc/c-api/buffer.rst
Doc/c-api/exceptions.rst
Doc/c-api/intro.rst
Doc/c-api/list.rst
Doc/c-api/memory.rst
Doc/c-api/module.rst
Doc/c-api/sequence.rst
Doc/conf.py
Doc/data/refcounts.dat
Doc/distutils/builtdist.rst
Doc/extending/extending.rst
Doc/extending/newtypes_tutorial.rst
Doc/faq/programming.rst
Doc/glossary.rst
Doc/howto/logging-cookbook.rst
Doc/howto/unicode.rst
Doc/includes/custom.c
Doc/includes/custom2.c
Doc/includes/custom3.c
Doc/includes/custom4.c
Doc/includes/email-mime.py
Doc/includes/sublist.c
Doc/library/argparse.rst
Doc/library/array.rst
Doc/library/ast.rst
Doc/library/asyncio-dev.rst
Doc/library/asyncio-future.rst
Doc/library/asyncio-protocol.rst
Doc/library/asyncio-sync.rst
Doc/library/asyncio-task.rst
Doc/library/codecs.rst
Doc/library/collections.rst
Doc/library/configparser.rst
Doc/library/ctypes.rst
Doc/library/curses.rst
Doc/library/datatypes.rst
Doc/library/datetime.rst
Doc/library/difflib.rst
Doc/library/faulthandler.rst
Doc/library/ftplib.rst
Doc/library/functions.rst
Doc/library/glob.rst
Doc/library/http.client.rst
Doc/library/http.cookiejar.rst
Doc/library/idle.rst
Doc/library/imp.rst
Doc/library/importlib.rst
Doc/library/io.rst
Doc/library/itertools.rst
Doc/library/logging.handlers.rst
Doc/library/logging.rst
Doc/library/mailbox.rst
Doc/library/mimetypes.rst
Doc/library/os.rst
Doc/library/parser.rst
Doc/library/pickle.rst
Doc/library/posix.rst
Doc/library/re.rst
Doc/library/select.rst
Doc/library/shlex.rst
Doc/library/signal.rst
Doc/library/ssl.rst
Doc/library/stdtypes.rst
Doc/library/string.rst
Doc/library/struct.rst
Doc/library/sys.rst
Doc/library/telnetlib.rst
Doc/library/tempfile.rst
Doc/library/test.rst
Doc/library/textwrap.rst
Doc/library/time.rst
Doc/library/typing.rst
Doc/library/unicodedata.rst
Doc/library/unittest.mock.rst
Doc/library/urllib.request.rst
Doc/library/venv.rst
Doc/library/winreg.rst
Doc/library/xml.etree.elementtree.rst
Doc/reference/datamodel.rst
Doc/reference/expressions.rst
Doc/tools/extensions/suspicious.py
Doc/tools/susp-ignored.csv
Doc/tools/templates/indexsidebar.html
Doc/tutorial/controlflow.rst
Doc/tutorial/errors.rst
Doc/tutorial/inputoutput.rst
Doc/tutorial/interpreter.rst
Doc/tutorial/stdlib.rst
Doc/using/cmdline.rst
Doc/using/editors.rst [new file with mode: 0644]
Doc/using/index.rst
Doc/using/unix.rst
Doc/using/venv-create.inc
Doc/whatsnew/3.3.rst
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.7.rst
Include/patchlevel.h
Include/pyport.h
Include/pytime.h
Lib/argparse.py
Lib/ast.py
Lib/asyncio/events.py
Lib/asyncio/runners.py
Lib/asyncio/unix_events.py
Lib/cgi.py
Lib/collections/__init__.py
Lib/ctypes/test/test_structures.py
Lib/dataclasses.py
Lib/datetime.py
Lib/distutils/_msvccompiler.py
Lib/distutils/ccompiler.py
Lib/distutils/command/bdist_wininst.py
Lib/email/_header_value_parser.py
Lib/email/_parseaddr.py
Lib/email/headerregistry.py
Lib/email/message.py
Lib/email/parser.py
Lib/ensurepip/__init__.py
Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl [deleted file]
Lib/ensurepip/_bundled/pip-19.2.3-py2.py3-none-any.whl [new file with mode: 0644]
Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl [deleted file]
Lib/ensurepip/_bundled/setuptools-41.2.0-py2.py3-none-any.whl [new file with mode: 0644]
Lib/enum.py
Lib/functools.py
Lib/genericpath.py
Lib/http/__init__.py
Lib/http/client.py
Lib/http/cookiejar.py
Lib/idlelib/NEWS.txt
Lib/idlelib/README.txt
Lib/idlelib/autocomplete.py
Lib/idlelib/autocomplete_w.py
Lib/idlelib/browser.py
Lib/idlelib/codecontext.py
Lib/idlelib/config-highlight.def
Lib/idlelib/config-main.def
Lib/idlelib/config.py
Lib/idlelib/configdialog.py
Lib/idlelib/editor.py
Lib/idlelib/format.py [new file with mode: 0644]
Lib/idlelib/help.html
Lib/idlelib/help.py
Lib/idlelib/history.py
Lib/idlelib/idle_test/htest.py
Lib/idlelib/idle_test/test_autocomplete.py
Lib/idlelib/idle_test/test_codecontext.py
Lib/idlelib/idle_test/test_config.py
Lib/idlelib/idle_test/test_editor.py
Lib/idlelib/idle_test/test_format.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_multicall.py
Lib/idlelib/idle_test/test_paragraph.py [deleted file]
Lib/idlelib/idle_test/test_pyparse.py
Lib/idlelib/idle_test/test_pyshell.py
Lib/idlelib/idle_test/test_query.py
Lib/idlelib/idle_test/test_rstrip.py [deleted file]
Lib/idlelib/idle_test/test_run.py
Lib/idlelib/idle_test/test_sidebar.py [new file with mode: 0644]
Lib/idlelib/idle_test/test_squeezer.py
Lib/idlelib/idle_test/test_textview.py
Lib/idlelib/idle_test/test_tooltip.py
Lib/idlelib/idle_test/test_tree.py
Lib/idlelib/mainmenu.py
Lib/idlelib/outwin.py
Lib/idlelib/paragraph.py [deleted file]
Lib/idlelib/pyparse.py
Lib/idlelib/pyshell.py
Lib/idlelib/query.py
Lib/idlelib/rstrip.py [deleted file]
Lib/idlelib/run.py
Lib/idlelib/runscript.py
Lib/idlelib/sidebar.py [new file with mode: 0644]
Lib/idlelib/squeezer.py
Lib/idlelib/textview.py
Lib/idlelib/tooltip.py
Lib/idlelib/tree.py
Lib/importlib/_bootstrap_external.py
Lib/inspect.py
Lib/ipaddress.py
Lib/lib2to3/refactor.py
Lib/locale.py
Lib/logging/config.py
Lib/mimetypes.py
Lib/multiprocessing/util.py
Lib/os.py
Lib/pdb.py
Lib/plistlib.py
Lib/pydoc_data/topics.py
Lib/shlex.py
Lib/sqlite3/test/factory.py
Lib/sre_parse.py
Lib/subprocess.py
Lib/test/_test_multiprocessing.py
Lib/test/datetimetester.py
Lib/test/keycert.passwd.pem
Lib/test/libregrtest/cmdline.py
Lib/test/libregrtest/main.py
Lib/test/libregrtest/runtest.py
Lib/test/libregrtest/runtest_mp.py
Lib/test/libregrtest/win_utils.py
Lib/test/make_ssl_certs.py
Lib/test/ssl_key.passwd.pem
Lib/test/support/__init__.py
Lib/test/test_argparse.py
Lib/test/test_ast.py
Lib/test/test_asyncgen.py
Lib/test/test_asyncio/test_unix_events.py
Lib/test/test_builtin.py
Lib/test/test_c_locale_coercion.py
Lib/test/test_cgi.py
Lib/test/test_codecs.py
Lib/test/test_dataclasses.py
Lib/test/test_descr.py
Lib/test/test_docxmlrpc.py
Lib/test/test_eintr.py
Lib/test/test_email/test__header_value_parser.py
Lib/test/test_email/test_email.py
Lib/test/test_email/test_headerregistry.py
Lib/test/test_email/test_message.py
Lib/test/test_email/test_policy.py
Lib/test/test_gdb.py
Lib/test/test_http_cookiejar.py
Lib/test/test_httplib.py
Lib/test/test_import/__init__.py
Lib/test/test_importlib/test_api.py
Lib/test/test_inspect.py
Lib/test/test_ipaddress.py
Lib/test/test_itertools.py
Lib/test/test_json/test_dump.py
Lib/test/test_list.py
Lib/test/test_locale.py
Lib/test/test_logging.py
Lib/test/test_lzma.py
Lib/test/test_mimetypes.py
Lib/test/test_msilib.py
Lib/test/test_ntpath.py
Lib/test/test_os.py
Lib/test/test_pathlib.py
Lib/test/test_pdb.py
Lib/test/test_posix.py
Lib/test/test_random.py
Lib/test/test_regrtest.py
Lib/test/test_shlex.py
Lib/test/test_source_encoding.py
Lib/test/test_ssl.py
Lib/test/test_subprocess.py
Lib/test/test_sys.py
Lib/test/test_tempfile.py
Lib/test/test_timeout.py
Lib/test/test_typing.py
Lib/test/test_unicode.py
Lib/test/test_utf8_mode.py
Lib/test/test_venv.py
Lib/test/test_weakref.py
Lib/test/test_winreg.py
Lib/test/test_wsgiref.py
Lib/textwrap.py
Lib/threading.py
Lib/typing.py
Lib/unittest/mock.py
Lib/unittest/test/testmock/testmock.py
Lib/uuid.py
Lib/venv/scripts/common/activate
Lib/venv/scripts/nt/activate.bat
Lib/weakref.py
Lib/xmlrpc/server.py
Mac/BuildScript/README.rst [new file with mode: 0644]
Mac/BuildScript/README.txt [deleted file]
Mac/BuildScript/build-installer.py
Mac/BuildScript/resources/License.rtf
Mac/BuildScript/resources/ReadMe.rtf
Mac/BuildScript/resources/Welcome.rtf
Mac/README [deleted file]
Mac/README.rst [new file with mode: 0644]
Makefile.pre.in
Misc/ACKS
Misc/NEWS
Modules/_csv.c
Modules/_ctypes/_ctypes.c
Modules/_ctypes/_ctypes_test.c
Modules/_ctypes/callbacks.c
Modules/_ctypes/callproc.c
Modules/_ctypes/stgdict.c
Modules/_cursesmodule.c
Modules/_datetimemodule.c
Modules/_hashopenssl.c
Modules/_lzmamodule.c
Modules/_pickle.c
Modules/_sqlite/row.c
Modules/_ssl.c
Modules/_testmultiphase.c
Modules/expat/asciitab.h
Modules/expat/expat.h
Modules/expat/expat_external.h
Modules/expat/iasciitab.h
Modules/expat/internal.h
Modules/expat/latin1tab.h
Modules/expat/loadlibrary.c [deleted file]
Modules/expat/nametab.h
Modules/expat/siphash.h
Modules/expat/utf8tab.h
Modules/expat/winconfig.h
Modules/expat/xmlparse.c
Modules/expat/xmlrole.c
Modules/expat/xmlrole.h
Modules/expat/xmltok.c
Modules/expat/xmltok.h
Modules/expat/xmltok_impl.c
Modules/expat/xmltok_impl.h
Modules/expat/xmltok_ns.c
Modules/faulthandler.c
Modules/getpath.c
Modules/itertoolsmodule.c
Modules/mmapmodule.c
Modules/overlapped.c
Modules/posixmodule.c
Modules/socketmodule.c
Modules/timemodule.c
Objects/bytearrayobject.c
Objects/dictobject.c
Objects/floatobject.c
Objects/genobject.c
Objects/listobject.c
Objects/longobject.c
Objects/obmalloc.c
Objects/structseq.c
Objects/unicodeobject.c
PC/bdist_wininst/install.c
PC/clinic/winreg.c.h
PC/errmap.h
PC/generrmap.c [deleted file]
PC/pyconfig.h
PC/winreg.c
PCbuild/_elementtree.vcxproj
PCbuild/_elementtree.vcxproj.filters
PCbuild/get_externals.bat
PCbuild/pyexpat.vcxproj
PCbuild/pyexpat.vcxproj.filters
PCbuild/python.props
PCbuild/python_uwp.vcxproj
Parser/tokenizer.c
Python/_warnings.c
Python/bltinmodule.c
Python/compile.c
Python/condvar.h
Python/fileutils.c
Python/import.c
Python/pystate.c
Python/pythonrun.c
Python/sysmodule.c
Python/thread.c
README.rst
Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp
Tools/msi/bundle/bundle.wxs
Tools/ssl/multissltests.py
configure
configure.ac
pyconfig.h.in

index fcfac85ed9c442d9e5d68e55e2736fd2b540ccdb..38d0cc3e47dd58f94580acefdfb361b0dbab1ee6 100644 (file)
@@ -42,7 +42,7 @@ jobs:
     testRunPlatform: macos
 
   pool:
-    vmImage: xcode9-macos10.13
+    vmImage: macos-10.14
 
   steps:
   - template: ./macos-steps.yml
@@ -59,7 +59,7 @@ jobs:
   variables:
     testRunTitle: '$(build.sourceBranchName)-linux'
     testRunPlatform: linux
-    openssl_version: 1.1.1c
+    openssl_version: 1.1.1d
 
   steps:
   - template: ./posix-steps.yml
@@ -116,7 +116,7 @@ jobs:
   variables:
     testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
     testRunPlatform: linux-coverage
-    openssl_version: 1.1.1c
+    openssl_version: 1.1.1d
 
   steps:
   - template: ./posix-steps.yml
index 647081689454acc3e64822b28cb04773303c0b55..d2ca580a93d7ddd9c9f3795fbf6db2a97c70dcd2 100644 (file)
@@ -14,6 +14,8 @@ steps:
 
 - script: make buildbottest TESTOPTS="-j4 -uall,-cpu --junit-xml=$(build.binariesDirectory)/test-results.xml"
   displayName: 'Tests'
+  continueOnError: true
+  timeoutInMinutes: 30
 
 - task: PublishTestResults@2
   displayName: 'Publish Test Results'
index 2486f88a63fb1584846268c22a98e1148c1db2a1..8661da93d7e7803e0a0404ee5936f54ab4eccd96 100644 (file)
@@ -40,7 +40,7 @@ jobs:
     testRunPlatform: macos
 
   pool:
-    vmImage: xcode9-macos10.13
+    vmImage: macos-10.14
 
   steps:
   - template: ./macos-steps.yml
@@ -59,7 +59,7 @@ jobs:
   variables:
     testRunTitle: '$(system.pullRequest.TargetBranch)-linux'
     testRunPlatform: linux
-    openssl_version: 1.1.1c
+    openssl_version: 1.1.1d
 
   steps:
   - template: ./posix-steps.yml
@@ -116,7 +116,7 @@ jobs:
   variables:
     testRunTitle: '$(Build.SourceBranchName)-linux-coverage'
     testRunPlatform: linux-coverage
-    openssl_version: 1.1.1c
+    openssl_version: 1.1.1d
 
   steps:
   - template: ./posix-steps.yml
index 307d1e0e7de10b0a2b9d98c68339b93f02f59122..08013c0ef48c035112ecf8d3529a3b82795a00da 100644 (file)
@@ -12,7 +12,11 @@ PAPER        =
 SOURCES      =
 DISTVERSION  = $(shell $(PYTHON) tools/extensions/patchlevel.py)
 
-ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_elements.papersize=$(PAPER) \
+# Internal variables.
+PAPEROPT_a4     = -D latex_elements.papersize=a4paper
+PAPEROPT_letter = -D latex_elements.papersize=letterpaper
+
+ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) \
                 $(SPHINXOPTS) . build/$(BUILDER) $(SOURCES)
 
 .PHONY: help build html htmlhelp latex text changes linkcheck \
index c449ba2e719203e77948f7f24535cb7bc7afb8db..1dbfadbf6e0bc76250a23b72969345a90151747e 100644 (file)
@@ -72,7 +72,7 @@ taken on the bug.
       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 <https://developer.mozilla.org/en-US/docs/Mozilla/QA/Bug_writing_guidelines>`_
+   `Bug Report Writing Guidelines <https://developer.mozilla.org/en-US/docs/Mozilla/QA/Bug_writing_guidelines>`_
       Information about writing a good bug report.  Some of this is specific to the
       Mozilla project, but describes general good practices.
 
index 25a867f139cc7a387c95bd4936c7d629f0e0e5bd..c5e548d2668b2bf8084a82c8649285f68e9f0cb4 100644 (file)
@@ -48,7 +48,7 @@ Allocating Objects on the Heap
    improving the memory management efficiency.
 
 
-.. c:function:: void PyObject_Del(PyObject *op)
+.. c:function:: void PyObject_Del(void *op)
 
    Releases memory allocated to an object using :c:func:`PyObject_New` or
    :c:func:`PyObject_NewVar`.  This is normally called from the
index c7c1e3cc745ac40555b71ee3e8ae464981243f3d..b639ba6ff7877b9debd3e80499a40cba8909ee48 100644 (file)
@@ -355,8 +355,10 @@ If :c:member:`~Py_buffer.strides` is *NULL*, the array is interpreted as
 a standard n-dimensional C-array. Otherwise, the consumer must access an
 n-dimensional array as follows:
 
-   ``ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1]``
-   ``item = *((typeof(item) *)ptr);``
+.. code-block:: c
+
+   ptr = (char *)buf + indices[0] * strides[0] + ... + indices[n-1] * strides[n-1];
+   item = *((typeof(item) *)ptr);
 
 
 As noted above, :c:member:`~Py_buffer.buf` can point to any location within
@@ -473,11 +475,24 @@ Buffer-related functions
    (*order* is ``'A'``).  Return ``0`` otherwise.  This function always succeeds.
 
 
+.. c:function:: void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
+
+   Get the memory area pointed to by the *indices* inside the given *view*.
+   *indices* must point to an array of ``view->ndim`` indices.
+
+
+.. c:function:: int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
+
+   Copy contiguous *len* bytes from *buf* to *view*.
+   *fort* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering).
+   ``0`` is returned on success, ``-1`` on error.
+
+
 .. c:function:: int PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
 
    Copy *len* bytes from *src* to its contiguous representation in *buf*.
-   *order* can be ``'C'`` or ``'F'`` (for C-style or Fortran-style ordering).
-   ``0`` is returned on success, ``-1`` on error.
+   *order* can be ``'C'`` or ``'F'`` or ``'A'`` (for C-style or Fortran-style
+   ordering or either one). ``0`` is returned on success, ``-1`` on error.
 
    This function fails if *len* != *src->len*.
 
index 13e00b544818faf90bc0ea054578d5cf11570db4..14ca2b409969cfa471333ad9d75c5b6c0ab390c9 100644 (file)
@@ -317,7 +317,7 @@ an error value).
    :mod:`warnings` module and the :option:`-W` option in the command line
    documentation.  There is no C API for warning control.
 
-.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *msg, PyObject *name, PyObject *path)
+.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
 
    Much like :c:func:`PyErr_SetImportError` but this function allows for
    specifying a subclass of :exc:`ImportError` to raise.
index 330871bc2ae3314dda815a4fb8116ad04bac14ef..964d348c2df1849a305e0472058a455a5eb489a5 100644 (file)
@@ -69,10 +69,12 @@ standard headers) have one of the prefixes ``Py`` or ``_Py``.  Names beginning
 with ``_Py`` are for internal use by the Python implementation and should not be
 used by extension writers. Structure member names do not have a reserved prefix.
 
-**Important:** user code should never define names that begin with ``Py`` or
-``_Py``.  This confuses the reader, and jeopardizes the portability of the user
-code to future Python versions, which may define additional names beginning with
-one of these prefixes.
+.. note::
+
+   User code should never define names that begin with ``Py`` or ``_Py``. This
+   confuses the reader, and jeopardizes the portability of the user code to
+   future Python versions, which may define additional names beginning with one
+   of these prefixes.
 
 The header files are typically installed with Python.  On Unix, these  are
 located in the directories :file:`{prefix}/include/pythonversion/` and
@@ -90,9 +92,9 @@ multi-platform builds since the platform independent headers under
 :envvar:`prefix` include the platform specific headers from
 :envvar:`exec_prefix`.
 
-C++ users should note that though the API is defined entirely using C, the
-header files do properly declare the entry points to be ``extern "C"``, so there
-is no need to do anything special to use the API from C++.
+C++ users should note that although the API is defined entirely using C, the
+header files properly declare the entry points to be ``extern "C"``. As a result,
+there is no need to do anything special to use the API from C++.
 
 
 Useful macros
index 5b263a7b1cdf04bfce4a3a78f58c09f9c6628e50..a5cd634a454a9968931b8fcabfafe7cba90a9898 100644 (file)
@@ -59,9 +59,9 @@ List Objects
 .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index)
 
    Return the object at position *index* in the list pointed to by *list*.  The
-   position must be positive, indexing from the end of the list is not
-   supported.  If *index* is out of bounds, return *NULL* and set an
-   :exc:`IndexError` exception.
+   position must be non-negative; indexing from the end of the list is not
+   supported.  If *index* is out of bounds (<0 or >=len(list)),
+   return *NULL* and set an :exc:`IndexError` exception.
 
 
 .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
index 9b42900b4350f258f0b9e70d064a34456f2fd517..01f7f4209fe9e47592a47c88d058ac660499579b 100644 (file)
@@ -67,7 +67,7 @@ example::
 
 In this example, the memory request for the I/O buffer is handled by the C
 library allocator. The Python memory manager is involved only in the allocation
-of the string object returned as a result.
+of the bytes object returned as a result.
 
 In most situations, however, it is recommended to allocate memory from the
 Python heap specifically because the latter is under control of the Python
index 017b656854a8cd1e5231d507597ef3edfddeefbe..7168dc7363cae83d6a58b089043514c76ac63648 100644 (file)
@@ -417,7 +417,22 @@ state:
 
    Add an object to *module* as *name*.  This is a convenience function which can
    be used from the module's initialization function.  This steals a reference to
-   *value*.  Return ``-1`` on error, ``0`` on success.
+   *value* on success.  Return ``-1`` on error, ``0`` on success.
+
+   .. note::
+
+      Unlike other functions that steal references, ``PyModule_AddObject()`` only
+      decrements the reference count of *value* **on success**.
+
+      This means that its return value must be checked, and calling code must
+      :c:func:`Py_DECREF` *value* manually on error. Example usage::
+
+         Py_INCREF(spam);
+         if (PyModule_AddObject(module, "spam", spam) < 0) {
+             Py_DECREF(module);
+             Py_DECREF(spam);
+             return NULL;
+         }
 
 .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
 
index 6d22f35e22b1f23bff1e314de4c870c6eddf6008..d653319f8064b8834c699bba5e8668115c7a89f6 100644 (file)
@@ -130,10 +130,17 @@ Sequence Protocol
 
 .. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m)
 
-   Return the sequence or iterable *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 or iterable, raises :exc:`TypeError` with *m* as the message text.
+   Return the sequence or iterable *o* as an object usable by the other
+   ``PySequence_Fast*`` family of functions. If the object is not a sequence or
+   iterable, raises :exc:`TypeError` with *m* as the message text. Returns
+   *NULL* on failure.
+
+   The ``PySequence_Fast*`` functions are thus named because they assume
+   *o* is a :c:type:`PyTupleObject` or a :c:type:`PyListObject` and access
+   the data fields of *o* directly.
+
+   As a CPython implementation detail, if *o* is already a sequence or list, it
+   will be returned.
 
 
 .. c:function:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o)
@@ -141,8 +148,8 @@ Sequence Protocol
    Returns the length of *o*, assuming that *o* was returned by
    :c:func:`PySequence_Fast` and that *o* is not *NULL*.  The size can also be
    gotten by calling :c:func:`PySequence_Size` on *o*, but
-   :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a list
-   or tuple.
+   :c:func:`PySequence_Fast_GET_SIZE` is faster because it can assume *o* is a
+   list or tuple.
 
 
 .. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i)
@@ -163,7 +170,7 @@ Sequence Protocol
 
 .. c:function:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)
 
-   Return the *i*\ th element of *o* or *NULL* on failure. Macro form of
+   Return the *i*\ th element of *o* or *NULL* on failure. Faster form of
    :c:func:`PySequence_GetItem` but without checking that
    :c:func:`PySequence_Check` on *o* is true and without adjustment for negative
    indices.
index da8b9d7b2a65bce03f4ae68e712cb4654836444b..ce2d47f5f8939eee22df3db10d11d50283bb11dc 100644 (file)
@@ -38,8 +38,10 @@ highlight_language = 'python3'
 needs_sphinx = "1.6.6"
 
 # Ignore any .rst files in the venv/ directory.
-venvdir = os.getenv('VENVDIR', 'venv')
-exclude_patterns = [venvdir+'/*', 'README.rst']
+exclude_patterns = ['venv/*', 'README.rst']
+venvdir = os.getenv('VENVDIR')
+if venvdir is not None:
+    exclude_patterns.append(venvdir + '/*')
 
 # Disable Docutils smartquotes for several translations
 smartquotes_excludes = {
index 213ddcb61fae60267ca0b889a5a774efb185b110..ec8094ef24863b20b94a95d46a4cc535646d9d39 100644 (file)
@@ -2444,7 +2444,7 @@ PyUnicode_FromWideChar:Py_ssize_t:size::
 PyUnicode_AsWideChar:Py_ssize_t:::
 PyUnicode_AsWideChar:PyObject*:*unicode:0:
 PyUnicode_AsWideChar:wchar_t*:w::
-PyUnicode_AsWideChar:Pyssize_t:size::
+PyUnicode_AsWideChar:Py_ssize_t:size::
 
 PyUnicode_AsWideCharString:wchar_t*:::
 PyUnicode_AsWideCharString:PyObject*:unicode:0:
index f1f3471261600ea38b04cb38e47f757d7359aa3d..0a83f8bd6599844b80a68a89211ba4b1d254cfd7 100644 (file)
@@ -313,8 +313,8 @@ or the :command:`bdist` command with the :option:`!--formats` option::
 
 If you have a pure module distribution (only containing pure Python modules and
 packages), the resulting installer will be version independent and have a name
-like :file:`foo-1.0.win32.exe`.  These installers can even be created on Unix
-platforms or Mac OS X.
+like :file:`foo-1.0.win32.exe`. Note that creating ``wininst`` binary
+distributions in only supported on Windows systems.
 
 If you have a non-pure distribution, the extensions can only be created on a
 Windows platform, and will be Python version dependent. The installer filename
index afed3aabb79ac2ea2b8c41697d2432f88f2f6afc..73a77c781bc29c1490f3f234201414bfca0d697b 100644 (file)
@@ -209,7 +209,7 @@ usually declare a static object variable at the beginning of your file::
    static PyObject *SpamError;
 
 and initialize it in your module's initialization function (:c:func:`PyInit_spam`)
-with an exception object (leaving out the error checking for now)::
+with an exception object::
 
    PyMODINIT_FUNC
    PyInit_spam(void)
@@ -221,8 +221,14 @@ with an exception object (leaving out the error checking for now)::
            return NULL;
 
        SpamError = PyErr_NewException("spam.error", NULL, NULL);
-       Py_INCREF(SpamError);
-       PyModule_AddObject(m, "error", SpamError);
+       Py_XINCREF(SpamError);
+       if (PyModule_AddObject(m, "error", SpamError) < 0) {
+           Py_XDECREF(SpamError);
+           Py_CLEAR(SpamError);
+           Py_DECREF(m);
+           return NULL;
+       }
+
        return m;
    }
 
@@ -1261,8 +1267,12 @@ function must take care of initializing the C API pointer array::
        /* Create a Capsule containing the API pointer array's address */
        c_api_object = PyCapsule_New((void *)PySpam_API, "spam._C_API", NULL);
 
-       if (c_api_object != NULL)
-           PyModule_AddObject(m, "_C_API", c_api_object);
+       if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) {
+           Py_XDECREF(c_api_object);
+           Py_DECREF(m);
+           return NULL;
+       }
+
        return m;
    }
 
index 07c2ef718aedf6b424bb2bba11355e3513581100..50be28fbcba2825a7cf6fee988681f7a5bc1e652 100644 (file)
@@ -179,7 +179,12 @@ This initializes the :class:`Custom` type, filling in a number of members
 to the appropriate default values, including :attr:`ob_type` that we initially
 set to *NULL*. ::
 
-   PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+   Py_INCREF(&CustomType);
+   if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+       Py_DECREF(&CustomType);
+       Py_DECREF(m);
+       return NULL;
+   }
 
 This adds the type to the module dictionary.  This allows us to create
 :class:`Custom` instances by calling the :class:`Custom` class:
@@ -864,7 +869,12 @@ function::
            return NULL;
 
        Py_INCREF(&SubListType);
-       PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+       if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
+           Py_DECREF(&SubListType);
+           Py_DECREF(m);
+           return NULL;
+       }
+
        return m;
    }
 
index f14e8cc824ef747b8fe3d6ad7aba8d59eb97aa53..a8aaebf7558ee3c257eb35f8a04efb097dc1dd11 100644 (file)
@@ -659,7 +659,7 @@ How can my code discover the name of an object?
 -----------------------------------------------
 
 Generally speaking, it can't, because objects don't really have names.
-Essentially, assignment always binds a name to a value; The same is true of
+Essentially, assignment always binds a name to a value; the same is true of
 ``def`` and ``class`` statements, but in that case the value is a
 callable. Consider the following code::
 
index df6f6b6462954dbb5859595b2341284108056b98..ed588612aeabed205b83db45ac447ad20db0b264 100644 (file)
@@ -243,7 +243,7 @@ Glossary
       Fortran contiguous arrays, the first index varies the fastest.
 
    coroutine
-      Coroutines is a more generalized form of subroutines. Subroutines are
+      Coroutines are 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
@@ -735,17 +735,28 @@ Glossary
       also :term:`immutable`.
 
    named tuple
-      Any tuple-like class whose indexable elements are also accessible using
-      named attributes (for example, :func:`time.localtime` returns a
-      tuple-like object where the *year* is accessible either with an
-      index such as ``t[0]`` or with a named attribute like ``t.tm_year``).
-
-      A named tuple can be a built-in type such as :class:`time.struct_time`,
-      or it can be created with a regular class definition.  A full featured
-      named tuple can also be created with the factory function
-      :func:`collections.namedtuple`.  The latter approach automatically
-      provides extra features such as a self-documenting representation like
-      ``Employee(name='jones', title='programmer')``.
+      The term "named tuple" applies to any type or class that inherits from
+      tuple and whose indexable elements are also accessible using named
+      attributes.  The type or class may have other features as well.
+
+      Several built-in types are named tuples, including the values returned
+      by :func:`time.localtime` and :func:`os.stat`.  Another example is
+      :data:`sys.float_info`::
+
+           >>> sys.float_info[1]                   # indexed access
+           1024
+           >>> sys.float_info.max_exp              # named field access
+           1024
+           >>> isinstance(sys.float_info, tuple)   # kind of tuple
+           True
+
+      Some named tuples are built-in types (such as the above examples).
+      Alternatively, a named tuple can be created from a regular class
+      definition that inherits from :class:`tuple` and that defines named
+      fields.  Such a class can be written by hand or it can be created with
+      the factory function :func:`collections.namedtuple`.  The latter
+      technique also adds some extra methods that may not be found in
+      hand-written or built-in named tuples.
 
    namespace
       The place where a variable is stored.  Namespaces are implemented as
@@ -1028,14 +1039,6 @@ Glossary
       an :term:`expression` or one of several constructs with a keyword, such
       as :keyword:`if`, :keyword:`while` or :keyword:`for`.
 
-   struct sequence
-      A tuple with named elements. Struct sequences expose an interface similar
-      to :term:`named tuple` in that elements can be accessed either by
-      index or as an attribute. However, they do not have any of the named tuple
-      methods like :meth:`~collections.somenamedtuple._make` or
-      :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.
 
index e391506ce2e49c946b19a0e44ddd6ce90282d99b..a9222ab6ce38ecd3d8513a07e0df14f2f1bf9d21 100644 (file)
@@ -949,6 +949,41 @@ This variant shows how you can e.g. apply configuration for particular loggers
 machinery in the main process (even though the logging events are generated in
 the worker processes) to direct the messages to the appropriate destinations.
 
+Using concurrent.futures.ProcessPoolExecutor
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you want to use :class:`concurrent.futures.ProcessPoolExecutor` to start
+your worker processes, you need to create the queue slightly differently.
+Instead of
+
+.. code-block:: python
+
+   queue = multiprocessing.Queue(-1)
+
+you should use
+
+.. code-block:: python
+
+   queue = multiprocessing.Manager().Queue(-1)  # also works with the examples above
+
+and you can then replace the worker creation from this::
+
+    workers = []
+    for i in range(10):
+        worker = multiprocessing.Process(target=worker_process,
+                                         args=(queue, worker_configurer))
+        workers.append(worker)
+        worker.start()
+    for w in workers:
+        w.join()
+
+to this (remembering to first import :mod:`concurrent.futures`)::
+
+    with concurrent.futures.ProcessPoolExecutor(max_workers=10) as executor:
+        for i in range(10):
+            executor.submit(worker_process, queue, worker_configurer)
+
+
 Using file rotation
 -------------------
 
@@ -2267,9 +2302,9 @@ 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.
+a level at which flushing should occur, and a capacity for the buffer (number of
+records buffered). These default to a :class:`~logging.StreamHandler` which
+writes to ``sys.stderr``, ``logging.ERROR`` and ``100`` respectively.
 
 Here's the script::
 
index d4b1b2a707269d34c387ab56c6974b765774b9f9..1ac4102034d33e9ae3e4c57a795f0ea1dc97fe38 100644 (file)
@@ -57,14 +57,14 @@ their corresponding code points:
    ...
    007B    '{'; LEFT CURLY BRACKET
    ...
-   2167    'â\85¦': ROMAN NUMERAL EIGHT
-   2168    'Ⅸ': ROMAN NUMERAL NINE
+   2167    'â\85§'; ROMAN NUMERAL EIGHT
+   2168    'Ⅸ'; ROMAN NUMERAL NINE
    ...
-   265E    '♞': BLACK CHESS KNIGHT
-   265F    '♟': BLACK CHESS PAWN
+   265E    '♞'; BLACK CHESS KNIGHT
+   265F    '♟'; BLACK CHESS PAWN
    ...
-   1F600   '😀': GRINNING FACE
-   1F609   '😉': WINKING FACE
+   1F600   '😀'; GRINNING FACE
+   1F609   '😉'; WINKING FACE
    ...
 
 Strictly, these definitions imply that it's meaningless to say 'this is
index 13d16f5424ae4de319c58f0ae61aae0a1bd28ea4..bda32e2ad81d464c54aac5a442346ce95691e03e 100644 (file)
@@ -35,6 +35,11 @@ PyInit_custom(void)
         return NULL;
 
     Py_INCREF(&CustomType);
-    PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+    if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+        Py_DECREF(&CustomType);
+        PY_DECREF(m);
+        return NULL;
+    }
+
     return m;
 }
index 6477a19dafed753b07f17a5fc10ff2e45e9a8176..5bacab7a2a9714c1cfb52bf6c6891c8983e346ac 100644 (file)
@@ -128,6 +128,11 @@ PyInit_custom2(void)
         return NULL;
 
     Py_INCREF(&CustomType);
-    PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+    if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+        Py_DECREF(&CustomType);
+        Py_DECREF(m);
+        return NULL;
+    }
+
     return m;
 }
index 213d0864ce1ca8c13cde37bd1045769dfeadfe9f..2b7a99ecf96c76be835db308ace6a5d7cd2a35a0 100644 (file)
@@ -179,6 +179,11 @@ PyInit_custom3(void)
         return NULL;
 
     Py_INCREF(&CustomType);
-    PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+    if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+        Py_DECREF(&CustomType);
+        Py_DECREF(m);
+        return NULL;
+    }
+
     return m;
 }
index b0b2906dbdc863913e9d09de1f3edcf4c3839db5..584992fc5f1a8a7a69585ff64f7252b5d5cee6b4 100644 (file)
@@ -193,6 +193,11 @@ PyInit_custom4(void)
         return NULL;
 
     Py_INCREF(&CustomType);
-    PyModule_AddObject(m, "Custom", (PyObject *) &CustomType);
+    if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) {
+        Py_DECREF(&CustomType);
+        Py_DECREF(m);
+        return NULL;
+    }
+
     return m;
 }
index c610242f11f843f5c5916628fa55142a929262cc..6af2be0b08a48da3dc0508eecf6f20ef5df1e103 100644 (file)
@@ -14,7 +14,7 @@ msg['Subject'] = 'Our family reunion'
 # family = the list of all recipients' email addresses
 msg['From'] = me
 msg['To'] = ', '.join(family)
-msg.preamble = 'Our family reunion'
+msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
 
 # Open the files in binary mode.  Use imghdr to figure out the
 # MIME subtype for each specific image.
index 76ff93948cfd6756abdd95666a5ee4ec5beed745..b2c26e73ebaf7e32785032ba6d45e00f57ef34f9 100644 (file)
@@ -59,6 +59,11 @@ PyInit_sublist(void)
         return NULL;
 
     Py_INCREF(&SubListType);
-    PyModule_AddObject(m, "SubList", (PyObject *) &SubListType);
+    if (PyModule_AddObject(m, "SubList", (PyObject *) &SubListType) < 0) {
+        Py_DECREF(&SubListType);
+        Py_DECREF(m);
+        return NULL;
+    }
+
     return m;
 }
index cef197f30555818d539db7b3d587251f640bf4ac..a2baa077cd890f2df1fb1f02c937c1e3dcd1de74 100644 (file)
@@ -1583,7 +1583,7 @@ Sub-commands
      stored; by default ``None`` and no value is stored
 
    * required_ - Whether or not a subcommand must be provided, by default
-     ``False``.
+     ``False`` (added in 3.7)
 
    * help_ - help for sub-parser group in help output, by default ``None``
 
@@ -1739,6 +1739,9 @@ Sub-commands
      >>> parser.parse_args(['2', 'frobble'])
      Namespace(subparser_name='2', y='frobble')
 
+   .. versionchanged:: 3.7
+      New *required* keyword argument.
+
 
 FileType objects
 ^^^^^^^^^^^^^^^^
index 4ac7bb5391a7a49f7d7ba452ddf5c63456cdc9f1..0da6b48721fb976f695d8cdf56a8aea7113852c4 100644 (file)
@@ -36,9 +36,9 @@ defined:
 +-----------+--------------------+-------------------+-----------------------+-------+
 | ``'L'``   | unsigned long      | int               | 4                     |       |
 +-----------+--------------------+-------------------+-----------------------+-------+
-| ``'q'``   | signed long long   | int               | 8                     | \(2)  |
+| ``'q'``   | signed long long   | int               | 8                     |       |
 +-----------+--------------------+-------------------+-----------------------+-------+
-| ``'Q'``   | unsigned long long | int               | 8                     | \(2)  |
+| ``'Q'``   | unsigned long long | int               | 8                     |       |
 +-----------+--------------------+-------------------+-----------------------+-------+
 | ``'f'``   | float              | float             | 4                     |       |
 +-----------+--------------------+-------------------+-----------------------+-------+
@@ -57,13 +57,6 @@ Notes:
 
    .. deprecated-removed:: 3.3 4.0
 
-(2)
-   The ``'q'`` and ``'Q'`` type codes are available only if
-   the platform C compiler used to build Python supports C :c:type:`long long`,
-   or, on Windows, :c:type:`__int64`.
-
-   .. versionadded:: 3.3
-
 The actual representation of values is determined by the machine architecture
 (strictly speaking, by the C implementation).  The actual size can be accessed
 through the :attr:`itemsize` attribute.
index 3c73f748acbe36549290abd04264cd4e4a18c922..699ad0456a02f8c106ffe878ea396f71ab827f27 100644 (file)
@@ -262,11 +262,12 @@ and classes for traversing abstract syntax trees:
 .. function:: dump(node, annotate_fields=True, include_attributes=False)
 
    Return a formatted dump of the tree in *node*.  This is mainly useful for
-   debugging purposes.  The returned string will show the names and the values
-   for fields.  This makes the code impossible to evaluate, so if evaluation is
-   wanted *annotate_fields* must be set to ``False``.  Attributes such as line
+   debugging purposes.  If *annotate_fields* is true (by default),
+   the returned string will show the names and the values for fields.
+   If *annotate_fields* is false, the result string will be more compact by
+   omitting unambiguous field names.  Attributes such as line
    numbers and column offsets are not dumped by default.  If this is wanted,
-   *include_attributes* can be set to ``True``.
+   *include_attributes* can be set to true.
 
 .. seealso::
 
index b728803619297968d9c57fb4f2b8a5e34566de2e..101e7817a95e98e638dc2d89c5cd34b0b71bb30f 100644 (file)
@@ -119,7 +119,7 @@ all concurrent asyncio Tasks and IO operations would be delayed
 by 1 second.
 
 An executor can be used to run a task in a different thread or even in
-a different process to avoid blocking block the OS thread with the
+a different process to avoid blocking the OS thread with the
 event loop.  See the :meth:`loop.run_in_executor` method for more
 details.
 
index 6e6e0137c1bdda4de224a63dc6a7c27fda4b4a34..c069471b519be95f385e167fa3bc7a31499c0466 100644 (file)
@@ -35,7 +35,9 @@ Future Functions
      is used for the test.)
 
    * a :class:`Task` object wrapping *obj*, if *obj* is a
-     coroutine (:func:`iscoroutine` is used for the test.)
+     coroutine (:func:`iscoroutine` is used for the test);
+     in this case the coroutine will be scheduled by
+     ``ensure_future()``.
 
    * a :class:`Task` object that would await on *obj*, if *obj* is an
      awaitable (:func:`inspect.isawaitable` is used for the test.)
index d8d7947c030ac2a967568bd4039b052e736062e1..1a7794e2126194b3150f34136620b0d7eb676744 100644 (file)
@@ -767,9 +767,8 @@ data, and waits until the connection is closed::
 
 
     class EchoClientProtocol(asyncio.Protocol):
-        def __init__(self, message, on_con_lost, loop):
+        def __init__(self, message, on_con_lost):
             self.message = message
-            self.loop = loop
             self.on_con_lost = on_con_lost
 
         def connection_made(self, transport):
@@ -793,7 +792,7 @@ data, and waits until the connection is closed::
         message = 'Hello World!'
 
         transport, protocol = await loop.create_connection(
-            lambda: EchoClientProtocol(message, on_con_lost, loop),
+            lambda: EchoClientProtocol(message, on_con_lost),
             '127.0.0.1', 8888)
 
         # Wait until the protocol signals that the connection
@@ -869,11 +868,10 @@ method, sends data and closes the transport when it receives the answer::
 
 
     class EchoClientProtocol:
-        def __init__(self, message, loop):
+        def __init__(self, message, on_con_lost):
             self.message = message
-            self.loop = loop
+            self.on_con_lost = on_con_lost
             self.transport = None
-            self.on_con_lost = loop.create_future()
 
         def connection_made(self, transport):
             self.transport = transport
@@ -899,13 +897,15 @@ method, sends data and closes the transport when it receives the answer::
         # low-level APIs.
         loop = asyncio.get_running_loop()
 
+        on_con_lost = loop.create_future()
         message = "Hello World!"
+
         transport, protocol = await loop.create_datagram_endpoint(
-            lambda: EchoClientProtocol(message, loop),
+            lambda: EchoClientProtocol(message, on_con_lost),
             remote_addr=('127.0.0.1', 9999))
 
         try:
-            await protocol.on_con_lost
+            await on_con_lost
         finally:
             transport.close()
 
@@ -927,9 +927,9 @@ Wait until a socket receives data using the
 
     class MyProtocol(asyncio.Protocol):
 
-        def __init__(self, loop):
+        def __init__(self, on_con_lost):
             self.transport = None
-            self.on_con_lost = loop.create_future()
+            self.on_con_lost = on_con_lost
 
         def connection_made(self, transport):
             self.transport = transport
@@ -950,13 +950,14 @@ Wait until a socket receives data using the
         # Get a reference to the event loop as we plan to use
         # low-level APIs.
         loop = asyncio.get_running_loop()
+        on_con_lost = loop.create_future()
 
         # Create a pair of connected sockets
         rsock, wsock = socket.socketpair()
 
         # Register the socket to wait for data.
         transport, protocol = await loop.create_connection(
-            lambda: MyProtocol(loop), sock=rsock)
+            lambda: MyProtocol(on_con_lost), sock=rsock)
 
         # Simulate the reception of data from the network.
         loop.call_soon(wsock.send, 'abc'.encode())
index 993bd13fb0301366139ecb272d929e331579d75f..79f6b02d85e2e535a411f908ee6d6f8bf965b28c 100644 (file)
@@ -187,11 +187,11 @@ Condition
        cond = asyncio.Condition()
 
        # ... later
-       await lock.acquire()
+       await cond.acquire()
        try:
            await cond.wait()
        finally:
-           lock.release()
+           cond.release()
 
    .. coroutinemethod:: acquire()
 
index 29ccafee908b134024711280273bc40946f61852..9a4cda1887887c5dee0b6454dce1b81d9bc97228 100644 (file)
@@ -212,6 +212,8 @@ Running an asyncio Program
 
 .. function:: run(coro, \*, debug=False)
 
+    Execute the :term:`coroutine` *coro* and return the result.
+
     This function runs the passed coroutine, taking care of
     managing the asyncio event loop and *finalizing asynchronous
     generators*.
@@ -225,6 +227,14 @@ Running an asyncio Program
     the end.  It should be used as a main entry point for asyncio
     programs, and should ideally only be called once.
 
+    Example::
+
+        async def main():
+            await asyncio.sleep(1)
+            print('hello')
+
+        asyncio.run(main())
+
     .. versionadded:: 3.7
        **Important:** this function has been added to asyncio in
        Python 3.7 on a :term:`provisional basis <provisional api>`.
index ff4f4933b37d618671fa9db3c5cbdfc39febba89..5c41828249c31497c74471c0dc98739701d26100 100644 (file)
@@ -292,7 +292,7 @@ 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
+accepting the *errors* string argument. The following string values are
 defined and implemented by all standard Python codecs:
 
 .. tabularcolumns:: |l|L|
@@ -301,11 +301,11 @@ defined and implemented by all standard Python codecs:
 | Value                   | Meaning                                       |
 +=========================+===============================================+
 | ``'strict'``            | Raise :exc:`UnicodeError` (or a subclass);    |
-|                         | this is the default.  Implemented in          |
+|                         | this is the default. Implemented in           |
 |                         | :func:`strict_errors`.                        |
 +-------------------------+-----------------------------------------------+
 | ``'ignore'``            | Ignore the malformed data and continue        |
-|                         | without further notice.  Implemented in       |
+|                         | without further notice. Implemented in        |
 |                         | :func:`ignore_errors`.                        |
 +-------------------------+-----------------------------------------------+
 
@@ -327,11 +327,11 @@ The following error handlers are only applicable to
 |                         | marker; Python will use the official          |
 |                         | ``U+FFFD`` REPLACEMENT CHARACTER for the      |
 |                         | built-in codecs on decoding, and '?' on       |
-|                         | encoding.  Implemented in                     |
+|                         | encoding. Implemented in                      |
 |                         | :func:`replace_errors`.                       |
 +-------------------------+-----------------------------------------------+
 | ``'xmlcharrefreplace'`` | Replace with the appropriate XML character    |
-|                         | reference (only for encoding).  Implemented   |
+|                         | reference (only for encoding). Implemented    |
 |                         | in :func:`xmlcharrefreplace_errors`.          |
 +-------------------------+-----------------------------------------------+
 | ``'backslashreplace'``  | Replace with backslashed escape sequences.    |
@@ -339,15 +339,15 @@ The following error handlers are only applicable to
 |                         | :func:`backslashreplace_errors`.              |
 +-------------------------+-----------------------------------------------+
 | ``'namereplace'``       | Replace with ``\N{...}`` escape sequences     |
-|                         | (only for encoding).  Implemented in          |
+|                         | (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    |
+|                         | ``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  |
+|                         | when encoding the data. (See :pep:`383` for   |
 |                         | more.)                                        |
 +-------------------------+-----------------------------------------------+
 
@@ -357,7 +357,7 @@ In addition, the following error handler is specific to the given codecs:
 | Value             | Codecs                 | Meaning                                   |
 +===================+========================+===========================================+
 |``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding of surrogate  |
-|                   | utf-16-be, utf-16-le,  | codes.  These codecs normally treat the   |
+|                   | utf-16-be, utf-16-le,  | codes. These codecs normally treat the    |
 |                   | utf-32-be, utf-32-le   | presence of surrogates as an error.       |
 +-------------------+------------------------+-------------------------------------------+
 
@@ -388,9 +388,9 @@ handler:
    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
+   :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
+   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.
@@ -484,7 +484,7 @@ function interfaces of the stateless encoder and decoder:
 .. method:: Codec.decode(input[, errors])
 
    Decodes the object *input* and returns a tuple (output object, length
-   consumed).  For instance, for a :term:`text encoding`, decoding converts
+   consumed). For instance, for a :term:`text encoding`, decoding converts
    a bytes object encoded using a particular
    character set encoding to a string object.
 
@@ -568,7 +568,7 @@ define in order to be compatible with the Python codec registry.
       implementation should make sure that ``0`` is the most common
       state. (States that are more complicated than integers can be converted
       into an integer by marshaling/pickling the state and encoding the bytes
-      of the resulting string into an integer).
+      of the resulting string into an integer.)
 
 
    .. method:: setstate(state)
@@ -751,7 +751,7 @@ compatible with the Python codec registry.
       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.  This parameter is intended to
+      possible. This parameter is intended to
       prevent having to decode huge files in one step.
 
       The *firstline* flag indicates that
@@ -780,8 +780,8 @@ compatible with the Python codec registry.
       Read all lines available on the input stream and return them as a list of
       lines.
 
-      Line-endings are implemented using the codec's decoder method and are
-      included in the list entries if *keepends* is true.
+      Line-endings are implemented using the codec's :meth:`decode` method and
+      are included in the list entries if *keepends* is true.
 
       *sizehint*, if given, is passed as the *size* argument to the stream's
       :meth:`read` method.
@@ -791,7 +791,7 @@ compatible with the Python codec registry.
 
       Resets the codec buffers used for keeping state.
 
-      Note that no stream repositioning should take place.  This method is
+      Note that no stream repositioning should take place. This method is
       primarily intended to be able to recover from decoding errors.
 
 
@@ -841,7 +841,7 @@ The design is such that one can use the factory functions returned by the
    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 transcodings from e.g. Latin-1
+   You can use these objects to do transparent transcodings, e.g., from Latin-1
    to UTF-8 and back.
 
    The *stream* argument must be a file-like object.
@@ -866,10 +866,10 @@ Encodings and Unicode
 ---------------------
 
 Strings are stored internally as sequences of code points in
-range ``0x0``--``0x10FFFF``.  (See :pep:`393` for
+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
+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
@@ -964,7 +964,7 @@ to determine the byte order used for generating the byte sequence, but as a
 signature that helps in guessing the encoding. On encoding the utf-8-sig codec
 will write ``0xef``, ``0xbb``, ``0xbf`` as the first three bytes to the file. On
 decoding ``utf-8-sig`` will skip those three bytes if they appear as the first
-three bytes in the file.  In UTF-8, the use of the BOM is discouraged and
+three bytes in the file. In UTF-8, the use of the BOM is discouraged and
 should generally be avoided.
 
 
@@ -984,7 +984,7 @@ e.g. ``'utf-8'`` is a valid alias for the ``'utf_8'`` codec.
 .. impl-detail::
 
    Some common encodings can bypass the codecs lookup machinery to
-   improve performance.  These optimization opportunities are only
+   improve performance. These optimization opportunities are only
    recognized by CPython for a limited set of (case insensitive)
    aliases: utf-8, utf8, latin-1, latin1, iso-8859-1, iso8859-1, mbcs
    (Windows only), ascii, us-ascii, utf-16, utf16, utf-32, utf32, and
@@ -1150,7 +1150,7 @@ particular, the following variants typically exist:
 | iso2022_kr      | csiso2022kr, iso2022kr,        | Korean                         |
 |                 | iso-2022-kr                    |                                |
 +-----------------+--------------------------------+--------------------------------+
-| latin_1         | iso-8859-1, iso8859-1, 8859,   | West Europe                    |
+| latin_1         | iso-8859-1, iso8859-1, 8859,   | Western Europe                 |
 |                 | cp819, latin, latin1, L1       |                                |
 +-----------------+--------------------------------+--------------------------------+
 | iso8859_2       | iso-8859-2, latin2, L2         | Central and Eastern Europe     |
@@ -1251,11 +1251,11 @@ Python Specific Encodings
 -------------------------
 
 A number of predefined codecs are specific to Python, so their codec names have
-no meaning outside Python.  These are listed in the tables below based on the
+no meaning outside Python. These are listed in the tables below based on the
 expected input and output types (note that while text encodings are the most
 common use case for codecs, the underlying codec infrastructure supports
-arbitrary data transforms rather than just text encodings).  For asymmetric
-codecs, the stated purpose describes the encoding direction.
+arbitrary data transforms rather than just text encodings). For asymmetric
+codecs, the stated meaning describes the encoding direction.
 
 Text Encodings
 ^^^^^^^^^^^^^^
@@ -1267,27 +1267,27 @@ encodings.
 .. tabularcolumns:: |l|p{0.3\linewidth}|p{0.3\linewidth}|
 
 +--------------------+---------+---------------------------+
-| Codec              | Aliases | Purpose                   |
+| Codec              | Aliases | Meaning                   |
 +====================+=========+===========================+
-| idna               |         | Implements :rfc:`3490`,   |
+| idna               |         | Implement :rfc:`3490`,    |
 |                    |         | see also                  |
 |                    |         | :mod:`encodings.idna`.    |
 |                    |         | Only ``errors='strict'``  |
 |                    |         | is supported.             |
 +--------------------+---------+---------------------------+
-| mbcs               | ansi,   | Windows only: Encode      |
+| mbcs               | ansi,   | Windows only: Encode the  |
 |                    | dbcs    | operand according to the  |
-|                    |         | ANSI codepage (CP_ACP)    |
+|                    |         | ANSI codepage (CP_ACP).   |
 +--------------------+---------+---------------------------+
-| oem                |         | Windows only: Encode      |
+| oem                |         | Windows only: Encode the  |
 |                    |         | operand according to the  |
-|                    |         | OEM codepage (CP_OEMCP)   |
+|                    |         | OEM codepage (CP_OEMCP).  |
 |                    |         |                           |
 |                    |         | .. versionadded:: 3.6     |
 +--------------------+---------+---------------------------+
-| palmos             |         | Encoding of PalmOS 3.5    |
+| palmos             |         | Encoding of PalmOS 3.5.   |
 +--------------------+---------+---------------------------+
-| punycode           |         | Implements :rfc:`3492`.   |
+| punycode           |         | Implement :rfc:`3492`.    |
 |                    |         | Stateful codecs are not   |
 |                    |         | supported.                |
 +--------------------+---------+---------------------------+
@@ -1310,8 +1310,8 @@ encodings.
 |                    |         | literal in ASCII-encoded  |
 |                    |         | Python source code,       |
 |                    |         | except that quotes are    |
-|                    |         | not escaped. Decodes from |
-|                    |         | Latin-1 source code.      |
+|                    |         | not escaped. Decode       |
+|                    |         | from Latin-1 source code. |
 |                    |         | Beware that Python source |
 |                    |         | code actually uses UTF-8  |
 |                    |         | by default.               |
@@ -1333,19 +1333,19 @@ Binary Transforms
 ^^^^^^^^^^^^^^^^^
 
 The following codecs provide binary transforms: :term:`bytes-like object`
-to :class:`bytes` mappings.  They are not supported by :meth:`bytes.decode`
+to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode`
 (which only produces :class:`str` output).
 
 
 .. tabularcolumns:: |l|L|L|L|
 
 +----------------------+------------------+------------------------------+------------------------------+
-| Codec                | Aliases          | Purpose                      | Encoder / decoder            |
+| Codec                | Aliases          | Meaning                      | Encoder / decoder            |
 +======================+==================+==============================+==============================+
-| 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'``)                    |                              |
+| base64_codec [#b64]_ | base64, base_64  | Convert the operand to       | :meth:`base64.encodebytes` / |
+|                      |                  | multiline MIME base64 (the   | :meth:`base64.decodebytes`   |
+|                      |                  | result always includes a     |                              |
+|                      |                  | trailing ``'\n'``).          |                              |
 |                      |                  |                              |                              |
 |                      |                  | .. versionchanged:: 3.4      |                              |
 |                      |                  |    accepts any               |                              |
@@ -1353,23 +1353,23 @@ to :class:`bytes` mappings.  They are not supported by :meth:`bytes.decode`
 |                      |                  |    as input for encoding and |                              |
 |                      |                  |    decoding                  |                              |
 +----------------------+------------------+------------------------------+------------------------------+
-| bz2_codec            | bz2              | Compress the operand         | :meth:`bz2.compress` /       |
-|                      |                  | using bz2                    | :meth:`bz2.decompress`       |
+| bz2_codec            | bz2              | Compress the operand using   | :meth:`bz2.compress` /       |
+|                      |                  | bz2.                         | :meth:`bz2.decompress`       |
 +----------------------+------------------+------------------------------+------------------------------+
-| hex_codec            | hex              | Convert operand to           | :meth:`binascii.b2a_hex` /   |
+| hex_codec            | hex              | Convert the operand to       | :meth:`binascii.b2a_hex` /   |
 |                      |                  | hexadecimal                  | :meth:`binascii.a2b_hex`     |
 |                      |                  | representation, with two     |                              |
-|                      |                  | digits per byte              |                              |
+|                      |                  | digits per byte.             |                              |
 +----------------------+------------------+------------------------------+------------------------------+
-| quopri_codec         | quopri,          | Convert operand to MIME      | :meth:`quopri.encode` with   |
-|                      | quotedprintable, | quoted printable             | ``quotetabs=True`` /         |
+| quopri_codec         | quopri,          | Convert the 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`            |
+|                      |                  | uuencode.                    | :meth:`uu.decode`            |
 +----------------------+------------------+------------------------------+------------------------------+
-| zlib_codec           | zip, zlib        | Compress the operand         | :meth:`zlib.compress` /      |
-|                      |                  | using gzip                   | :meth:`zlib.decompress`      |
+| zlib_codec           | zip, zlib        | Compress the operand using   | :meth:`zlib.compress` /      |
+|                      |                  | gzip.                        | :meth:`zlib.decompress`      |
 +----------------------+------------------+------------------------------+------------------------------+
 
 .. [#b64] In addition to :term:`bytes-like objects <bytes-like object>`,
@@ -1389,16 +1389,17 @@ Text Transforms
 ^^^^^^^^^^^^^^^
 
 The following codec provides a text transform: a :class:`str` to :class:`str`
-mapping.  It is not supported by :meth:`str.encode` (which only produces
+mapping. It is not supported by :meth:`str.encode` (which only produces
 :class:`bytes` output).
 
 .. tabularcolumns:: |l|l|L|
 
 +--------------------+---------+---------------------------+
-| Codec              | Aliases | Purpose                   |
+| Codec              | Aliases | Meaning                   |
 +====================+=========+===========================+
-| rot_13             | rot13   | Returns the Caesar-cypher |
-|                    |         | encryption of the operand |
+| rot_13             | rot13   | Return the Caesar-cypher  |
+|                    |         | encryption of the         |
+|                    |         | operand.                  |
 +--------------------+---------+---------------------------+
 
 .. versionadded:: 3.2
@@ -1436,7 +1437,7 @@ conversion between Unicode and ACE, separating an input string into labels
 based on the separator characters defined in :rfc:`section 3.1 of RFC 3490 <3490#section-3.1>`
 and converting each label to ACE as required, and conversely separating an input
 byte string into labels based on the ``.`` separator and converting any ACE
-labels found into unicode.  Furthermore, the :mod:`socket` module
+labels found into unicode. Furthermore, the :mod:`socket` module
 transparently converts Unicode host names to ACE, so that applications need not
 be concerned about converting host names themselves when they pass them to the
 socket module. On top of that, modules that have host names as function
@@ -1445,7 +1446,7 @@ names (:mod:`http.client` then also transparently sends an IDNA hostname in the
 :mailheader:`Host` field if it sends that field at all).
 
 When receiving host names from the wire (such as in reverse name lookup), no
-automatic conversion to Unicode is performed: Applications wishing to present
+automatic conversion to Unicode is performed: applications wishing to present
 such host names to the user should decode them to Unicode.
 
 The module :mod:`encodings.idna` also implements the nameprep procedure, which
@@ -1477,7 +1478,7 @@ functions can be used directly if desired.
 .. module:: encodings.mbcs
    :synopsis: Windows ANSI codepage
 
-Encode operand according to the ANSI codepage (CP_ACP).
+This module implements the ANSI codepage (CP_ACP).
 
 .. availability:: Windows only.
 
@@ -1496,7 +1497,7 @@ Encode operand according to the ANSI codepage (CP_ACP).
    :synopsis: UTF-8 codec with BOM signature
 .. moduleauthor:: Walter Dörwald
 
-This module implements a variant of the UTF-8 codec: On encoding a UTF-8 encoded
+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
+is only done once (on the first write to the byte stream). On decoding, an
 optional UTF-8 encoded BOM at the start of the data will be skipped.
index 9f47e8978da3527c0bac38a44d4dfec06708e389..e9dbd094e0a969a0ef1701a696bf0a1a3f5df8e5 100644 (file)
@@ -33,10 +33,10 @@ Python's general purpose built-in containers, :class:`dict`, :class:`list`,
 :class:`UserString`     wrapper around string objects for easier string subclassing
 =====================   ====================================================================
 
-.. versionchanged:: 3.3
+.. deprecated-removed:: 3.3 3.9
     Moved :ref:`collections-abstract-base-classes` to the :mod:`collections.abc` module.
     For backwards compatibility, they continue to be visible in this module through
-    Python 3.7.  Subsequently, they will be removed entirely.
+    Python 3.8.
 
 
 :class:`ChainMap` objects
index 68b663ff7f65e54b1d06b9fc96c689af3dcf8d1d..6ab858578ba24235bf9d81bb254e42d76ef6b899 100644 (file)
@@ -313,6 +313,8 @@ from ``get()`` calls.
       my_dir: %(home_dir)s/lumberjack
       my_pictures: %(my_dir)s/Pictures
 
+      [Escape]
+      gain: 80%%  # use a %% to escape the % sign (% is the only character that needs to be escaped)
 
    In the example above, :class:`ConfigParser` with *interpolation* set to
    ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of
@@ -346,6 +348,9 @@ from ``get()`` calls.
       my_dir: ${home_dir}/lumberjack
       my_pictures: ${my_dir}/Pictures
 
+      [Escape]
+      cost: $$80  # use a $$ to escape the $ sign ($ is the only character that needs to be escaped)
+
    Values from other sections can be fetched as well:
 
    .. code-block:: ini
index 60a2ec1c5e89516633279b91c62bcc7ea0c515c6..2eafa654e2e64ea7b0f897bfb3f2264690ef0269 100644 (file)
@@ -576,7 +576,7 @@ Here is a simple example of a POINT structure, which contains two integers named
    >>> POINT(1, 2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
-   ValueError: too many initializers
+   TypeError: too many initializers
    >>>
 
 You can, however, build much more complicated structures.  A structure can
@@ -1175,16 +1175,21 @@ Keep in mind that retrieving sub-objects from Structure, Unions, and Arrays
 doesn't *copy* the sub-object, instead it retrieves a wrapper object accessing
 the root-object's underlying buffer.
 
-Another example that may behave different from what one would expect is this::
+Another example that may behave differently from what one would expect is this::
 
    >>> s = c_char_p()
-   >>> s.value = "abc def ghi"
+   >>> s.value = b"abc def ghi"
    >>> s.value
-   'abc def ghi'
+   b'abc def ghi'
    >>> s.value is s.value
    False
    >>>
 
+.. note::
+
+   Objects instantiated from :class:`c_char_p` can only have their value set to bytes
+   or integers.
+
 Why is it printing ``False``?  ctypes instances are objects containing a memory
 block plus some :term:`descriptor`\s accessing the contents of the memory.
 Storing a Python object in the memory block does not store the object itself,
index 2a2ee2be84af2ac2aea75de15161589c934b9928..3e4856e14d34111c75b52e5a4e77b04b0a4ecc94 100644 (file)
@@ -1276,7 +1276,7 @@ The :mod:`curses` module defines the following data members:
 
 .. data:: ERR
 
-   Some curses routines  that  return  an integer, such as  :func:`getch`, return
+   Some curses routines  that  return  an integer, such as :meth:`~window.getch`, return
    :const:`ERR` upon failure.
 
 
index 48af0823aa4912ea9a45d7eefd1cc952916f81ba..94010c0e391b0b0ed67c746e242f5c32e5622994 100644 (file)
@@ -5,13 +5,14 @@ Data Types
 **********
 
 The modules described in this chapter provide a variety of specialized data
-types such as dates and times, fixed-type arrays, heap queues, synchronized
-queues, and sets.
+types such as dates and times, fixed-type arrays, heap queues, double-ended
+queues, and enumerations.
 
 Python also provides some built-in data types, in particular,
 :class:`dict`, :class:`list`, :class:`set` and :class:`frozenset`, and
 :class:`tuple`.  The :class:`str` class is used to hold
-Unicode strings, and the :class:`bytes` class is used to hold binary data.
+Unicode strings, and the :class:`bytes` and :class:`bytearray` classes are used
+to hold binary data.
 
 The following modules are documented in this chapter:
 
index 270b2386d7161b483124217b809a770212533239..342dc2b8cfbddc464c2d4362f30fd7224900d7d8 100644 (file)
@@ -401,7 +401,7 @@ systems.
 
 .. class:: date(year, month, day)
 
-   All arguments are required.  Arguments may be integers, in the following
+   All arguments are required.  Arguments must be integers in the following
    ranges:
 
    * ``MINYEAR <= year <= MAXYEAR``
@@ -707,7 +707,7 @@ Constructor:
 .. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
 
    The year, month and day arguments are required.  *tzinfo* may be ``None``, or an
-   instance of a :class:`tzinfo` subclass.  The remaining arguments may be integers,
+   instance of a :class:`tzinfo` subclass.  The remaining arguments must be integers
    in the following ranges:
 
    * ``MINYEAR <= year <= MAXYEAR``,
@@ -850,7 +850,9 @@ Other constructors, all class methods:
   .. caution::
 
     This does not support parsing arbitrary ISO 8601 strings - it is only intended
-    as the inverse operation of :meth:`datetime.isoformat`.
+    as the inverse operation of :meth:`datetime.isoformat`. A more full-featured
+    ISO 8601 parser, ``dateutil.parser.isoparse`` is available in the third-party package
+    `dateutil <https://dateutil.readthedocs.io/en/stable/parser.html#dateutil.parser.isoparse>`_.
 
   .. versionadded:: 3.7
 
@@ -1422,7 +1424,7 @@ day, and subject to adjustment via a :class:`tzinfo` object.
 .. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
 
    All arguments are optional.  *tzinfo* may be ``None``, or an instance of a
-   :class:`tzinfo` subclass.  The remaining arguments may be integers, in the
+   :class:`tzinfo` subclass.  The remaining arguments must be integers in the
    following ranges:
 
    * ``0 <= hour < 24``,
index f044cb2d6e0a865c2f67efceba156845d0fcb4a3..e245ab81cfb9496f6a0b5e941bb4691ecea18470 100644 (file)
@@ -543,6 +543,16 @@ The :class:`SequenceMatcher` class has this constructor:
       to try :meth:`quick_ratio` or :meth:`real_quick_ratio` first to get an
       upper bound.
 
+      .. note::
+
+         Caution: The result of a :meth:`ratio` call may depend on the order of
+         the arguments. For instance::
+
+            >>> SequenceMatcher(None, 'tide', 'diet').ratio()
+            0.25
+            >>> SequenceMatcher(None, 'diet', 'tide').ratio()
+            0.5
+
 
    .. method:: quick_ratio()
 
index 94ebd87639c5019cecf3b4a50973ead566424e7f..b588dfa18db2dda687115c07914e73cbdae35b70 100644 (file)
@@ -100,8 +100,10 @@ Dumping the tracebacks after a timeout
    :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.
+   This function is implemented using a watchdog thread.
+
+   .. versionchanged:: 3.7
+      This function is now always available.
 
    .. versionchanged:: 3.5
       Added support for passing file descriptor to this function.
index 6c39f9a59fc1fdef5a5f10e4f22d4065c7ec2d8b..d9701f4871d956bc6b07452f1fa10e57ac4879fb 100644 (file)
@@ -33,7 +33,8 @@ Here's a sample session using the :mod:`ftplib` module::
    drwxr-sr-x    4 1176     1176         4096 Nov 17  2008 project
    drwxr-xr-x    3 1176     1176         4096 Oct 10  2012 tools
    '226 Directory send OK.'
-   >>> ftp.retrbinary('RETR README', open('README', 'wb').write)
+   >>> with open('README', 'wb') as fp:
+   >>>     ftp.retrbinary('RETR README', fp.write)
    '226 Transfer complete.'
    >>> ftp.quit()
 
index 11147525d7e829d7a1d591adf77f88d4b4b47ad4..06ba323ca30c6c3ad2fd14eb3e7b5bb37c51fbe8 100644 (file)
@@ -426,7 +426,7 @@ are always available.  They are listed here in alphabetical order.
               n += 1
 
 
-.. function:: eval(expression, globals=None, locals=None)
+.. function:: eval(expression[, globals[, locals]])
 
    The arguments are a string and optional globals and locals.  If provided,
    *globals* must be a dictionary.  If provided, *locals* can be any mapping
@@ -1532,6 +1532,10 @@ are always available.  They are listed here in alphabetical order.
               super().method(arg)    # This does the same thing as:
                                      # super(C, self).method(arg)
 
+   In addition to method lookups, :func:`super` also works for attribute
+   lookups.  One possible use case for this is calling :term:`descriptor`\s
+   in a parent or sibling class.
+
    Note that :func:`super` is implemented as part of the binding process for
    explicit dotted attribute lookups such as ``super().__getitem__(name)``.
    It does so by implementing its own :meth:`__getattribute__` method for searching
index 0db10b5efc10cb9d8b0253c84bb12999cc7900e1..9ab79d7a6bab44e2dd95a48be4b4393561a84601 100644 (file)
@@ -48,8 +48,9 @@ For example, ``'[?]'`` matches the character ``'?'``.
       single: **; in glob-style wildcards
 
    If *recursive* is true, the pattern "``**``" will match any files and zero or
-   more directories and subdirectories.  If the pattern is followed by an
-   ``os.sep``, only directories and subdirectories match.
+   more directories, subdirectories and symbolic links to directories. If the
+   pattern is followed by an :data:`os.sep` or :data:`os.altsep` then files will not
+   match.
 
    .. note::
       Using the "``**``" pattern in large directory trees may consume
index 3ebeb10aee9a97d31ebfe30718521d143bf1451c..bc73c7a9bdf77b72408cea4ba99889b6b7a3543a 100644 (file)
@@ -497,8 +497,11 @@ Here is an example session that uses the ``GET`` method::
    >>> # The following example demonstrates reading data in chunks.
    >>> conn.request("GET", "/")
    >>> r1 = conn.getresponse()
-   >>> while not r1.closed:
-   ...     print(r1.read(200))  # 200 bytes
+   >>> while True:
+   ...     chunk = r1.read(200)  # 200 bytes
+   ...     if not chunk:
+   ...          break
+   ...     print(repr(chunk))
    b'<!doctype html>\n<!--[if"...
    ...
    >>> # Example of an invalid request
index d8da6683a3a52f8ac67d973bab1bc83a6b7b4d6b..8bacd72c811a8475ead8141ab54a0a8aa7e200ad 100644 (file)
@@ -153,7 +153,7 @@ contained :class:`Cookie` objects.
    the :class:`CookieJar`'s :class:`CookiePolicy` instance are true and false
    respectively), the :mailheader:`Cookie2` header is also added when appropriate.
 
-   The *request* object (usually a :class:`urllib.request..Request` instance)
+   The *request* object (usually a :class:`urllib.request.Request` instance)
    must support the methods :meth:`get_full_url`, :meth:`get_host`,
    :meth:`get_type`, :meth:`unverifiable`, :meth:`has_header`,
    :meth:`get_header`, :meth:`header_items`, :meth:`add_unredirected_header`
index fb886a714d7471e50f4058fc8fa4f87d135e3001..0bd248c22b1820459baa5a6cdb6dd02451727598 100644 (file)
@@ -207,20 +207,6 @@ Strip trailing whitespace
 Run menu (Editor window only)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. _python-shell:
-
-Python Shell
-   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 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:
 
 Run Module
@@ -239,6 +225,20 @@ Run... Customized
    settings.  *Command Line Arguments* extend :data:`sys.argv` as if passed
    on a command line. The module can be run in the Shell without restarting.
 
+.. _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 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.
+
+.. _python-shell:
+
+Python Shell
+   Open or wake up the Python Shell window.
+
 
 Shell menu (Shell window only)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -290,22 +290,31 @@ Options menu (Shell and Editor)
 Configure IDLE
    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.  On macOS,  open the
+   size, additional help sources, and extensions.  On macOS, open the
    configuration dialog by selecting Preferences in the application
-   menu. For more, see
+   menu. For more details, see
    :ref:`Setting preferences <preferences>` under Help and preferences.
 
+Most configuration options apply to all windows or all future windows.
+The option items below only apply to the active window.
+
 Show/Hide Code Context (Editor Window only)
    Open a pane at the top of the edit window which shows the block context
    of the code which has scrolled above the top of the window.  See
-   :ref:`Code Context <code-context>` in the Editing and Navigation section below.
+   :ref:`Code Context <code-context>` in the Editing and Navigation section
+   below.
+
+Show/Hide Line Numbers (Editor Window only)
+   Open a column to the left of the edit window which shows the number
+   of each line of text.  The default is off, which may be changed in the
+   preferences (see :ref:`Setting preferences <preferences>`).
 
 Zoom/Restore Height
    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 maximum height for a screen is determined by
    momentarily maximizing a window the first time one is zoomed on the screen.
-   Changing screen settings may invalidate the saved height.  This toogle has
+   Changing screen settings may invalidate the saved height.  This toggle has
    no effect when a window is maximized.
 
 Window menu (Shell and Editor)
@@ -713,6 +722,10 @@ or ``print`` or ``write`` to sys.stdout or sys.stderr,
 IDLE should be started in a command line window.  The secondary subprocess
 will then be attached to that window for input and output.
 
+The IDLE code running in the execution process adds frames to the call stack
+that would not be there otherwise.  IDLE wraps ``sys.getrecursionlimit`` and
+``sys.setrecursionlimit`` to reduce the effect of the additional stack frames.
+
 If ``sys`` is reset by user code, such as with ``importlib.reload(sys)``,
 IDLE's changes are lost and input from the keyboard and output to the screen
 will not work correctly.
index 04f207f58d38daa0ad5f061bdad8d7a5043cfe47..f5ad8c7229644fc93e97acbd7fd05846b6fc5fd8 100644 (file)
@@ -66,12 +66,11 @@ This module provides an interface to the mechanisms used to implement the
    contained in the list returned by :func:`get_suffixes` describing the kind of
    module found.
 
-   If the module does not live in a file, the returned *file* is ``None``,
-   *pathname* is the empty string, and the *description* tuple contains empty
-   strings for its suffix and mode; the module type is indicated as given in
-   parentheses above.  If the search is unsuccessful, :exc:`ImportError` is
-   raised.  Other exceptions indicate problems with the arguments or
-   environment.
+   If the module is built-in or frozen then *file* and *pathname* are both ``None``
+   and the *description* tuple contains empty strings for its suffix and mode;
+   the module type is indicated as given in parentheses above.  If the search
+   is unsuccessful, :exc:`ImportError` is raised.  Other exceptions indicate
+   problems with the arguments or environment.
 
    If the module is a package, *file* is ``None``, *pathname* is the package
    path and the last item in the *description* tuple is :const:`PKG_DIRECTORY`.
index 23831c75842f1f26555f1be24e4e656edc26fecf..974dbb461a158ecb3e91d6090b7b8e681a3af42d 100644 (file)
@@ -274,6 +274,8 @@ ABC hierarchy::
       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 guess about what spec to return.
+      :func:`importlib.util.spec_from_loader` may be useful for implementing
+      concrete ``MetaPathFinders``.
 
       .. versionadded:: 3.4
 
@@ -323,7 +325,8 @@ ABC hierarchy::
       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
-      guess about what spec to return.
+      guess about what spec to return. :func:`importlib.util.spec_from_loader`
+      may be useful for implementing concrete ``PathEntryFinders``.
 
       .. versionadded:: 3.4
 
@@ -500,7 +503,7 @@ ABC hierarchy::
     packages or a module).
 
     Loaders that wish to support resource reading are expected to
-    provide a method called ``get_resource_loader(fullname)`` which
+    provide a method called ``get_resource_reader(fullname)`` which
     returns an object implementing this ABC's interface. If the module
     specified by fullname is not a package, this method should return
     :const:`None`. An object compatible with this ABC should only be
index 9738c5c2ad274d31b014ef66f3f9470bbf2927ee..6bf56bc415b2728acf329d00a1986d0d41147582 100644 (file)
@@ -306,7 +306,7 @@ 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])
+   .. method:: seek(offset, whence=SEEK_SET)
 
       Change the stream position to the given byte *offset*.  *offset* is
       interpreted relative to the position indicated by *whence*.  The default
@@ -810,7 +810,7 @@ Text I/O
 
       If *size* is specified, at most *size* characters will be read.
 
-   .. method:: seek(offset[, whence])
+   .. method:: seek(offset, whence=SEEK_SET)
 
       Change the stream position to the given *offset*.  Behaviour depends on
       the *whence* parameter.  The default value for *whence* is
@@ -924,7 +924,7 @@ Text I/O
       *errors*, *newline*, *line_buffering* and *write_through*.
 
       Parameters not specified keep current settings, except
-      ``errors='strict`` is used when *encoding* is specified but
+      ``errors='strict'`` is used when *encoding* is specified but
       *errors* is not specified.
 
       It is not possible to change the encoding or newline if some data
index 959424ff914390e8151089da5dfaa24a8aa9433e..76899ce753685a1ce8b37a9b11a720a184fa719a 100644 (file)
@@ -628,6 +628,10 @@ loops that truncate the stream.
    used anywhere else; otherwise, the *iterable* could get advanced without
    the tee objects being informed.
 
+   ``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be
+   raised when using simultaneously iterators returned by the same :func:`tee`
+   call, even if the original *iterable* is threadsafe.
+
    This itertool may require significant auxiliary storage (depending on how
    much temporary data needs to be stored). In general, if one iterator uses
    most or all of the data before another iterator starts, it is faster to use
index dee9a84e3337643e2429ce2dcca0ba5f679a05f7..0e9870408ff43de273cf8954f4541fceda309b05 100644 (file)
@@ -470,7 +470,12 @@ sends logging output to a network socket. The base class uses a TCP socket.
    .. method:: makePickle(record)
 
       Pickles the record's attribute dictionary in binary format with a length
-      prefix, and returns it ready for transmission across the socket.
+      prefix, and returns it ready for transmission across the socket. The
+      details of this operation are equivalent to::
+
+          data = pickle.dumps(record_attr_dict, 1)
+          datalen = struct.pack('>L', len(data))
+          return datalen + data
 
       Note that pickles aren't completely secure. If you are concerned about
       security, you may want to override this method to implement a more secure
@@ -481,8 +486,12 @@ sends logging output to a network socket. The base class uses a TCP socket.
 
    .. method:: send(packet)
 
-      Send a pickled string *packet* to the socket. This function allows for
-      partial sends which can happen when the network is busy.
+      Send a pickled byte-string *packet* to the socket. The format of the sent
+      byte-string is as described in the documentation for
+      :meth:`~SocketHandler.makePickle`.
+
+      This function allows for partial sends, which can happen when the network
+      is busy.
 
 
    .. method:: createSocket()
@@ -543,7 +552,8 @@ over UDP sockets.
 
    .. method:: send(s)
 
-      Send a pickled string to a socket.
+      Send a pickled byte-string to a socket. The format of the sent byte-string
+      is as described in the documentation for :meth:`SocketHandler.makePickle`.
 
 
 .. _syslog-handler:
@@ -830,7 +840,8 @@ should, then :meth:`flush` is expected to do the flushing.
 
 .. class:: BufferingHandler(capacity)
 
-   Initializes the handler with a buffer of the specified capacity.
+   Initializes the handler with a buffer of the specified capacity. Here,
+   *capacity* means the number of logging records buffered.
 
 
    .. method:: emit(record)
@@ -854,12 +865,13 @@ should, then :meth:`flush` is expected to do the flushing.
 .. class:: MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True)
 
    Returns a new instance of the :class:`MemoryHandler` class. The instance is
-   initialized with a buffer size of *capacity*. If *flushLevel* is not specified,
-   :const:`ERROR` is used. If no *target* is specified, the target will need to be
-   set using :meth:`setTarget` before this handler does anything useful. If
-   *flushOnClose* is specified as ``False``, then the buffer is *not* flushed when
-   the handler is closed. If not specified or specified as ``True``, the previous
-   behaviour of flushing the buffer will occur when the handler is closed.
+   initialized with a buffer size of *capacity* (number of records buffered).
+   If *flushLevel* is not specified, :const:`ERROR` is used. If no *target* is
+   specified, the target will need to be set using :meth:`setTarget` before this
+   handler does anything useful. If *flushOnClose* is specified as ``False``,
+   then the buffer is *not* flushed when the handler is closed. If not specified
+   or specified as ``True``, the previous behaviour of flushing the buffer will
+   occur when the handler is closed.
 
    .. versionchanged:: 3.6
       The *flushOnClose* parameter was added.
@@ -959,14 +971,21 @@ possible, while any potentially slow operations (such as sending an email via
 .. class:: QueueHandler(queue)
 
    Returns a new instance of the :class:`QueueHandler` class. The instance is
-   initialized with the queue to send messages to. The queue can be any
-   queue-like object; it's used as-is by the :meth:`enqueue` method, which needs
-   to know how to send messages to it.
+   initialized with the queue to send messages to. The *queue* can be any
+   queue-like object; it's used as-is by the :meth:`enqueue` method, which
+   needs to know how to send messages to it. The queue is not *required* to
+   have the task tracking API, which means that you can use
+   :class:`~queue.SimpleQueue` instances for *queue*.
 
 
    .. method:: emit(record)
 
-      Enqueues the result of preparing the LogRecord.
+      Enqueues the result of preparing the LogRecord. Should an exception
+      occur (e.g. because a bounded queue has filled up), the
+      :meth:`~logging.Handler.handleError` method is called to handle the
+      error. This can result in the record silently being dropped (if
+      :attr:`logging.raiseExceptions` is ``False``) or a message printed to
+      ``sys.stderr`` (if :attr:`logging.raiseExceptions` is ``True``).
 
    .. method:: prepare(record)
 
@@ -1017,14 +1036,17 @@ possible, while any potentially slow operations (such as sending an email via
    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. 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.
+   to know how to get messages from it. The queue is not *required* to have the
+   task tracking API (though it's used if available), which means that you can
+   use :class:`~queue.SimpleQueue` instances for *queue*.
+
+   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.
+      The ``respect_handler_level`` argument was added.
 
    .. method:: dequeue(block)
 
index 0e65f316735ea81d70d894557cf3f35ced734384..cec2f142dfc1114a43e50b176f75a23d4c8f83cc 100644 (file)
@@ -50,8 +50,8 @@ listed below.
 Logger Objects
 --------------
 
-Loggers have the following attributes and methods.  Note that Loggers are never
-instantiated directly, but always through the module-level function
+Loggers have the following attributes and methods.  Note that Loggers should
+*NEVER* be instantiated directly, but always through the module-level function
 ``logging.getLogger(name)``.  Multiple calls to :func:`getLogger` with the same
 name will always return a reference to the same Logger object.
 
@@ -124,11 +124,11 @@ is the module's name in the Python package namespace.
          :meth:`isEnabledFor` will return/expect to be passed integers.
 
 
-   .. method:: Logger.isEnabledFor(lvl)
+   .. method:: Logger.isEnabledFor(level)
 
-      Indicates if a message of severity *lvl* would be processed by this logger.
+      Indicates if a message of severity *level* would be processed by this logger.
       This method checks first the module-level level set by
-      ``logging.disable(lvl)`` and then the logger's effective level as determined
+      ``logging.disable(level)`` and then the logger's effective level as determined
       by :meth:`getEffectiveLevel`.
 
 
@@ -258,9 +258,9 @@ is the module's name in the Python package namespace.
       interpreted as for :meth:`debug`.
 
 
-   .. method:: Logger.log(lvl, msg, *args, **kwargs)
+   .. method:: Logger.log(level, msg, *args, **kwargs)
 
-      Logs a message with integer level *lvl* on this logger. The other arguments are
+      Logs a message with integer level *level* on this logger. The other arguments are
       interpreted as for :meth:`debug`.
 
 
@@ -315,7 +315,7 @@ is the module's name in the Python package namespace.
       Logger-level filtering is applied using :meth:`~Logger.filter`.
 
 
-   .. method:: Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)
+   .. method:: Logger.makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)
 
       This is a factory method which can be overridden in subclasses to create
       specialized :class:`LogRecord` instances.
@@ -1041,12 +1041,12 @@ functions.
       handlers being added multiple times to the root logger, which can in turn
       lead to multiple messages for the same event.
 
-.. function:: disable(lvl=CRITICAL)
+.. function:: disable(level=CRITICAL)
 
-   Provides an overriding level *lvl* for all loggers which takes precedence over
+   Provides an overriding level *level* for all loggers which takes precedence over
    the logger's own level. When the need arises to temporarily throttle logging
    output down across the whole application, this function can be useful. Its
-   effect is to disable all logging calls of severity *lvl* and below, so that
+   effect is to disable all logging calls of severity *level* and below, so that
    if you call it with a value of INFO, then all INFO and DEBUG events would be
    discarded, whereas those of severity WARNING and above would be processed
    according to the logger's effective level. If
@@ -1056,16 +1056,16 @@ functions.
 
    Note that if you have defined any custom logging level higher than
    ``CRITICAL`` (this is not recommended), you won't be able to rely on the
-   default value for the *lvl* parameter, but will have to explicitly supply a
+   default value for the *level* parameter, but will have to explicitly supply a
    suitable value.
 
    .. versionchanged:: 3.7
-      The *lvl* parameter was defaulted to level ``CRITICAL``. See Issue
+      The *level* parameter was defaulted to level ``CRITICAL``. See Issue
       #28524 for more information about this change.
 
-.. function:: addLevelName(lvl, levelName)
+.. function:: addLevelName(level, levelName)
 
-   Associates level *lvl* with text *levelName* in an internal dictionary, which is
+   Associates level *level* with text *levelName* in an internal dictionary, which is
    used to map numeric levels to a textual representation, for example when a
    :class:`Formatter` formats a message. This function can also be used to define
    your own levels. The only constraints are that all levels used must be
@@ -1075,15 +1075,15 @@ functions.
    .. note:: If you are thinking of defining your own levels, please see the
       section on :ref:`custom-levels`.
 
-.. function:: getLevelName(lvl)
+.. function:: getLevelName(level)
 
-   Returns the textual representation of logging level *lvl*. If the level is one
+   Returns the textual representation of logging level *level*. If the level is one
    of the predefined levels :const:`CRITICAL`, :const:`ERROR`, :const:`WARNING`,
    :const:`INFO` or :const:`DEBUG` then you get the corresponding string. If you
    have associated levels with names using :func:`addLevelName` then the name you
-   have associated with *lvl* is returned. If a numeric value corresponding to one
+   have associated with *level* is returned. If a numeric value corresponding to one
    of the defined levels is passed in, the corresponding string representation is
-   returned. Otherwise, the string 'Level %s' % lvl is returned.
+   returned. Otherwise, the string 'Level %s' % level 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
@@ -1191,7 +1191,9 @@ functions.
    The class should define :meth:`__init__` such that only a name argument is
    required, and the :meth:`__init__` should call :meth:`Logger.__init__`. This
    function is typically called before any loggers are instantiated by applications
-   which need to use custom logger behavior.
+   which need to use custom logger behavior. After this call, as at any other
+   time, do not instantiate loggers directly using the subclass: continue to use
+   the :func:`logging.getLogger` API to get your loggers.
 
 
 .. function:: setLogRecordFactory(factory)
index d901ad2cc1c48e1948bb40f07bb188ae9ed430dd..f82a3b200deb7c4d01820376a7d51a72e2c4dc7b 100644 (file)
@@ -308,6 +308,9 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF.
    representation. If *create* is ``True``, the mailbox is created if it does not
    exist.
 
+   If *create* is ``True`` and the *dirname* path exists, it will be treated as
+   an existing maildir without attempting to verify its directory layout.
+
    It is for historical reasons that *dirname* is named as such rather than *path*.
 
    Maildir is a directory-based mailbox format invented for the qmail mail
index 5c1982b4735ed67cdba13dc0a8cbfd9049f3b2c0..4c445fb7350141b17350567b641dd11214f5c7bd 100644 (file)
@@ -88,6 +88,10 @@ behavior of the module.
    Specifying an empty list for *files* will prevent the system defaults from
    being applied: only the well-known values will be present from a built-in list.
 
+   If *files* is ``None`` the internal data structure is completely rebuilt to its
+   initial default value. This is a stable operation and will produce the same results
+   when called multiple times.
+
    .. versionchanged:: 3.2
       Previously, Windows registry settings were ignored.
 
index 9ed999eb458b7c4167fe7114a003b64a93f6fa3c..1556422a1704331acb63adce33d45c9c26cb3128 100644 (file)
@@ -35,9 +35,9 @@ Notes on the availability of these functions:
 
 .. note::
 
-   All functions in this module raise :exc:`OSError` in the case of invalid or
-   inaccessible file names and paths, or other arguments that have the correct
-   type, but are not accepted by the operating system.
+   All functions in this module raise :exc:`OSError` (or subclasses thereof) in
+   the case of invalid or inaccessible file names and paths, or other arguments
+   that have the correct type, but are not accepted by the operating system.
 
 .. exception:: error
 
@@ -1566,6 +1566,9 @@ features:
    This function can support :ref:`specifying a file descriptor <path_fd>`.  The
    descriptor must refer to an opened directory, not an open file.
 
+   This function can raise :exc:`OSError` and subclasses such as
+   :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`.
+
    .. versionadded:: 3.3
       Added support for specifying *path* as a file descriptor
       on some platforms.
@@ -1858,8 +1861,8 @@ features:
    directories you can set the umask before invoking :func:`makedirs`.  The
    file permission bits of existing parent directories are not changed.
 
-   If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if the
-   target directory already exists.
+   If *exist_ok* is ``False`` (the default), an :exc:`FileExistsError` is
+   raised if the target directory already exists.
 
    .. note::
 
@@ -2010,8 +2013,8 @@ features:
 
 .. function:: remove(path, *, dir_fd=None)
 
-   Remove (delete) the file *path*.  If *path* is a directory, :exc:`OSError` is
-   raised.  Use :func:`rmdir` to remove directories.
+   Remove (delete) the file *path*.  If *path* is a directory, an
+   :exc:`IsADirectoryError` is raised.  Use :func:`rmdir` to remove directories.
 
    This function can support :ref:`paths relative to directory descriptors
    <dir_fd>`.
@@ -2048,13 +2051,19 @@ features:
 
 .. function:: rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
 
-   Rename the file or directory *src* to *dst*.  If *dst* is a directory,
-   :exc:`OSError` will be raised.  On Unix, if *dst* exists and is a file, it will
-   be replaced silently if the user has permission.  The operation may fail on some
-   Unix flavors if *src* and *dst* are on different filesystems.  If successful,
-   the renaming will be an atomic operation (this is a POSIX requirement).  On
-   Windows, if *dst* already exists, :exc:`OSError` will be raised even if it is a
-   file.
+   Rename the file or directory *src* to *dst*. If *dst* exists, the operation
+   will fail with an :exc:`OSError` subclass in a number of cases:
+
+   On Windows, if *dst* exists a :exc:`FileExistsError` is always raised.
+
+   On Unix, if *src* is a file and *dst* is a directory or vice-versa, an
+   :exc:`IsADirectoryError` or a :exc:`NotADirectoryError` will be raised
+   respectively.  If both are directories and *dst* is empty, *dst* will be
+   silently replaced.  If *dst* is a non-empty directory, an :exc:`OSError`
+   is raised. If both are files, *dst* it will be replaced silently if the user
+   has permission.  The operation may fail on some Unix flavors if *src* and
+   *dst* are on different filesystems.  If successful, the renaming will be an
+   atomic operation (this is a POSIX requirement).
 
    This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to
    supply :ref:`paths relative to directory descriptors <dir_fd>`.
@@ -2103,9 +2112,10 @@ features:
 
 .. function:: rmdir(path, *, dir_fd=None)
 
-   Remove (delete) the directory *path*.  Only works when the directory is
-   empty, otherwise, :exc:`OSError` is raised.  In order to remove whole
-   directory trees, :func:`shutil.rmtree` can be used.
+   Remove (delete) the directory *path*.  If the directory does not exist or is
+   not empty, an :exc:`FileNotFoundError` or an :exc:`OSError` is raised
+   respectively.  In order to remove whole directory trees,
+   :func:`shutil.rmtree` can be used.
 
    This function can support :ref:`paths relative to directory descriptors
    <dir_fd>`.
@@ -3592,7 +3602,9 @@ written in Python, such as a mail server's external command delivery program.
    :attr:`children_system`, and :attr:`elapsed` in that order.
 
    See the Unix manual page
-   :manpage:`times(2)` or the corresponding Windows Platform API documentation.
+   :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN
+   <https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes>`
+   _ on Windows.
    On Windows, only :attr:`user` and :attr:`system` are known; the other
    attributes are zero.
 
index a302681eca056855c8b458d2412f6d4380833b55..1d2da300709c87eb7e1c87813e585c164dc550fb 100644 (file)
@@ -51,7 +51,8 @@ Python version to another as source text will always allow correct parse trees
 to be created in the target version, with the only restriction being that
 migrating to an older version of the interpreter will not support more recent
 language constructs.  The parse trees are not typically compatible from one
-version to another, whereas source code has always been forward-compatible.
+version to another, though source code has usually been forward-compatible within
+a major release series.
 
 Each element of the sequences returned by :func:`st2list` or :func:`st2tuple`
 has a simple form.  Sequences representing non-terminal elements in the grammar
index 2d01d8b7ab2502d7ed4729058de0f2db3ff3968a..f741976c93064d21ebe3296d3c34d7c8fabc3598 100644 (file)
@@ -189,8 +189,9 @@ process more convenient:
 
 .. function:: dump(obj, file, protocol=None, \*, fix_imports=True)
 
-   Write a pickled representation of *obj* to the open :term:`file object` *file*.
-   This is equivalent to ``Pickler(file, protocol).dump(obj)``.
+   Write the pickled representation of the object *obj* to the open
+   :term:`file object` *file*.  This is equivalent to
+   ``Pickler(file, protocol).dump(obj)``.
 
    The optional *protocol* argument, an integer, tells the pickler to use
    the given protocol; supported protocols are 0 to :data:`HIGHEST_PROTOCOL`.
@@ -208,7 +209,7 @@ process more convenient:
 
 .. function:: dumps(obj, protocol=None, \*, fix_imports=True)
 
-   Return the pickled representation of the object as a :class:`bytes` object,
+   Return the pickled representation of the object *obj* as a :class:`bytes` object,
    instead of writing it to a file.
 
    Arguments *protocol* and *fix_imports* have the same meaning as in
@@ -216,13 +217,13 @@ process more convenient:
 
 .. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict")
 
-   Read a pickled object representation from the open :term:`file object`
+   Read the pickled representation of an object 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.
+   protocol argument is needed.  Bytes past the pickled representation
+   of the object 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
@@ -243,12 +244,12 @@ process more convenient:
 
 .. 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.
+   Return the reconstituted object hierarchy of the pickled representation
+   *bytes_object* of an object.
 
    The protocol version of the pickle is detected automatically, so no
-   protocol argument is needed.  Bytes past the pickled object's
-   representation are ignored.
+   protocol argument is needed.  Bytes past the pickled representation
+   of the object are ignored.
 
    Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
    which are used to control compatibility support for pickle stream generated
@@ -310,7 +311,7 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and
 
    .. method:: dump(obj)
 
-      Write a pickled representation of *obj* to the open file object given in
+      Write the pickled representation of *obj* to the open file object given in
       the constructor.
 
    .. method:: persistent_id(obj)
@@ -382,9 +383,10 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and
 
    .. method:: load()
 
-      Read a pickled object representation from the open file object given in
-      the constructor, and return the reconstituted object hierarchy specified
-      therein.  Bytes past the pickled object's representation are ignored.
+      Read the pickled representation of an object from the open file object
+      given in the constructor, and return the reconstituted object hierarchy
+      specified therein.  Bytes past the pickled representation of the object
+      are ignored.
 
    .. method:: persistent_load(pid)
 
@@ -649,13 +651,13 @@ alphanumeric characters (for protocol 0) [#]_ or just an arbitrary object (for
 any newer protocol).
 
 The resolution of such persistent IDs is not defined by the :mod:`pickle`
-module; it will delegate this resolution to the user defined methods on the
+module; it will delegate this resolution to the user-defined methods on the
 pickler and unpickler, :meth:`~Pickler.persistent_id` and
 :meth:`~Unpickler.persistent_load` respectively.
 
-To pickle objects that have an external persistent id, the pickler must have a
+To pickle objects that have an external persistent ID, the pickler must have a
 custom :meth:`~Pickler.persistent_id` method that takes an object as an
-argument and returns either ``None`` or the persistent id for that object.
+argument and returns either ``None`` or the persistent ID for that object.
 When ``None`` is returned, the pickler simply pickles the object as normal.
 When a persistent ID string is returned, the pickler will pickle that object,
 along with a marker so that the unpickler will recognize it as a persistent ID.
index 9cbc5505aee6f3b2fbdd028f7ae2acd05107016b..2105af9215f7694065e7fcb237e76f875afcb41e 100644 (file)
@@ -44,8 +44,8 @@ by defining the relevant size and offset types as 64-bit values. Such files are
 sometimes referred to as :dfn:`large files`.
 
 Large file support is enabled in Python when the size of an :c:type:`off_t` is
-larger than a :c:type:`long` and the :c:type:`long long` type is available and is
-at least as large as an :c:type:`off_t`.
+larger than a :c:type:`long` and the :c:type:`long long` is at least as large
+as an :c:type:`off_t`.
 It may be necessary to configure and compile Python with certain compiler flags
 to enable this mode. For example, it is enabled by default with recent versions
 of Irix, but with Solaris 2.6 and 2.7 you need to do something like::
index 2e6c7f715d20d68baf527006bf7aba0d8f27c933..4245c2417fee67dc75e5cfb42486837b37b6bcab 100644 (file)
@@ -537,8 +537,8 @@ character ``'$'``.
    Matches any character which is not a word character. This is
    the opposite of ``\w``. If the :const:`ASCII` flag is used this
    becomes the equivalent of ``[^a-zA-Z0-9_]``.  If the :const:`LOCALE` flag is
-   used, matches characters considered alphanumeric in the current locale
-   and the underscore.
+   used, matches characters which are neither alphanumeric in the current locale
+   nor the underscore.
 
 .. index:: single: \Z; in regular expressions
 
@@ -925,8 +925,8 @@ form.
    This is useful if you want to match an arbitrary literal string that may
    have regular expression metacharacters in it.  For example::
 
-      >>> print(re.escape('python.exe'))
-      python\.exe
+      >>> print(re.escape('http://www.python.org'))
+      http://www\.python\.org
 
       >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
       >>> print('[%s]+' % re.escape(legal_chars))
@@ -936,7 +936,7 @@ form.
       >>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
       /|\-|\+|\*\*|\*
 
-   This functions must not be used for the replacement string in :func:`sub`
+   This function must not be used for the replacement string in :func:`sub`
    and :func:`subn`, only backslashes should be escaped.  For example::
 
       >>> digits_re = r'\d+'
@@ -949,7 +949,9 @@ form.
 
    .. versionchanged:: 3.7
       Only characters that can have special meaning in a regular expression
-      are escaped.
+      are escaped. As a result, ``'!'``, ``'"'``, ``'%'``, ``"'"``, ``','``,
+      ``'/'``, ``':'``, ``';'``, ``'<'``, ``'='``, ``'>'``, ``'@'``, and
+      ``"`"`` are no longer escaped.
 
 
 .. function:: purge()
index 5b8fd7ee805c5216c6ce6ff9046688144c878ac3..7d65363e493133222d24a705da3567307bc5e929 100644 (file)
@@ -480,13 +480,14 @@ Kqueue Objects
    Create a kqueue object from a given file descriptor.
 
 
-.. method:: kqueue.control(changelist, max_events[, timeout=None]) -> eventlist
+.. method:: kqueue.control(changelist, max_events[, timeout]) -> eventlist
 
    Low level interface to kevent
 
-   - changelist must be an iterable of kevent object or ``None``
+   - changelist must be an iterable of kevent objects or ``None``
    - max_events must be 0 or a positive integer
-   - timeout in seconds (floats possible)
+   - timeout in seconds (floats possible); the default is ``None``,
+     to wait forever
 
    .. versionchanged:: 3.5
       The function is now retried with a recomputed timeout when interrupted by
index fb335c690068165e1d34b69e0780b193c4c7ecbb..d5b5ec6b14e476add75d9a17cd81b49c6da310e6 100644 (file)
@@ -98,7 +98,9 @@ The :mod:`shlex` module defines the following class:
    characters, those characters will be used as the punctuation characters.  Any
    characters in the :attr:`wordchars` attribute that appear in
    *punctuation_chars* will be removed from :attr:`wordchars`.  See
-   :ref:`improved-shell-compatibility` for more information.
+   :ref:`improved-shell-compatibility` for more information. *punctuation_chars*
+   can be set only upon :class:`~shlex.shlex` instance creation and can't be
+   modified later.
 
    .. versionchanged:: 3.6
       The *punctuation_chars* parameter was added.
@@ -299,8 +301,8 @@ variables which either control lexical analysis or can be used for debugging:
 
 .. attribute:: shlex.punctuation_chars
 
-   Characters that will be considered punctuation. Runs of punctuation
-   characters will be returned as a single token. However, note that no
+   A read-only property. Characters that will be considered punctuation. Runs of
+   punctuation characters will be returned as a single token. However, note that no
    semantic validity checking will be performed: for example, '>>>' could be
    returned as a token, even though it may not be recognised as such by shells.
 
index b6716eea95fbc8c22b931e127095b006a4f5ef4f..75008118b7ca231859128d7706f7218e7bd35784 100644 (file)
@@ -95,7 +95,7 @@ The variables defined in the :mod:`signal` module are:
 
    All the signal numbers are defined symbolically.  For example, the hangup signal
    is defined as :const:`signal.SIGHUP`; the variable names are identical to the
-   names used in C programs, as found in ``<signal.h>``. The Unix man page for
+   names used in C programs, as found in ``<signal.h>``.  The Unix man page for
    ':c:func:`signal`' lists the existing signals (on some systems this is
    :manpage:`signal(2)`, on others the list is in :manpage:`signal(7)`). Note that
    not all systems define the same set of signal names; only those names defined by
@@ -193,10 +193,10 @@ The :mod:`signal` module defines the following functions:
    canceled (only one alarm can be scheduled at any time).  The returned value is
    then the number of seconds before any previously set alarm was to have been
    delivered. If *time* is zero, no alarm is scheduled, and any scheduled alarm is
-   canceled.  If the return value is zero, no alarm is currently scheduled.  (See
-   the Unix man page :manpage:`alarm(2)`.)
+   canceled.  If the return value is zero, no alarm is currently scheduled.
 
-   .. availability:: Unix.
+   .. availability:: Unix.  See the man page :manpage:`alarm(2)` for further
+      information.
 
 
 .. function:: getsignal(signalnum)
@@ -213,8 +213,10 @@ The :mod:`signal` module defines the following functions:
 .. function:: pause()
 
    Cause the process to sleep until a signal is received; the appropriate handler
-   will then be called.  Returns nothing.  Not on Windows. (See the Unix man page
-   :manpage:`signal(2)`.)
+   will then be called.  Returns nothing.
+
+   .. availability:: Unix.  See the man page :manpage:`signal(2)` for further
+      information.
 
    See also :func:`sigwait`, :func:`sigwaitinfo`, :func:`sigtimedwait` and
    :func:`sigpending`.
@@ -237,8 +239,8 @@ The :mod:`signal` module defines the following functions:
    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
-      information).
+   .. availability:: Unix.  See the man page :manpage:`pthread_kill(3)` for further
+      information.
 
    See also :func:`os.kill`.
 
@@ -268,7 +270,7 @@ The :mod:`signal` module defines the following functions:
    For example, ``signal.pthread_sigmask(signal.SIG_BLOCK, [])`` reads the
    signal mask of the calling thread.
 
-   .. availability:: Unix. See the man page :manpage:`sigprocmask(3)` and
+   .. availability:: Unix.  See the man page :manpage:`sigprocmask(3)` and
       :manpage:`pthread_sigmask(3)` for further information.
 
    See also :func:`pause`, :func:`sigpending` and :func:`sigwait`.
@@ -355,8 +357,8 @@ The :mod:`signal` module defines the following functions:
    calls will be restarted when interrupted by signal *signalnum*, otherwise
    system calls will be interrupted.  Returns nothing.
 
-   .. availability:: Unix (see the man page :manpage:`siginterrupt(3)`
-      for further information).
+   .. availability:: Unix.  See the man page :manpage:`siginterrupt(3)`
+      for further information.
 
    Note that installing a signal handler with :func:`signal` will reset the
    restart behaviour to interruptible by implicitly calling
@@ -369,7 +371,7 @@ The :mod:`signal` module defines the following functions:
    be a callable Python object taking two arguments (see below), or one of the
    special values :const:`signal.SIG_IGN` or :const:`signal.SIG_DFL`.  The previous
    signal handler will be returned (see the description of :func:`getsignal`
-   above).  (See the Unix man page :manpage:`signal(2)`.)
+   above).  (See the Unix man page :manpage:`signal(2)` for further information.)
 
    When threads are enabled, this function can only be called from the main thread;
    attempting to call it from other threads will cause a :exc:`ValueError`
@@ -395,8 +397,8 @@ The :mod:`signal` module defines the following functions:
    thread (i.e., the signals which have been raised while blocked).  Return the
    set of the pending signals.
 
-   .. availability:: Unix (see the man page :manpage:`sigpending(2)` for further
-      information).
+   .. availability:: Unix.  See the man page :manpage:`sigpending(2)` for further
+      information.
 
    See also :func:`pause`, :func:`pthread_sigmask` and :func:`sigwait`.
 
@@ -409,8 +411,8 @@ The :mod:`signal` module defines the following functions:
    signals specified in the signal set *sigset*.  The function accepts the signal
    (removes it from the pending list of signals), and returns the signal number.
 
-   .. availability:: Unix (see the man page :manpage:`sigwait(3)` for further
-      information).
+   .. availability:: Unix.  See the man page :manpage:`sigwait(3)` for further
+      information.
 
    See also :func:`pause`, :func:`pthread_sigmask`, :func:`sigpending`,
    :func:`sigwaitinfo` and :func:`sigtimedwait`.
@@ -434,8 +436,8 @@ The :mod:`signal` module defines the following functions:
    :attr:`si_errno`, :attr:`si_pid`, :attr:`si_uid`, :attr:`si_status`,
    :attr:`si_band`.
 
-   .. availability:: Unix (see the man page :manpage:`sigwaitinfo(2)` for further
-      information).
+   .. availability:: Unix.  See the man page :manpage:`sigwaitinfo(2)` for further
+      information.
 
    See also :func:`pause`, :func:`sigwait` and :func:`sigtimedwait`.
 
@@ -453,8 +455,8 @@ The :mod:`signal` module defines the following functions:
    specifying a timeout. If *timeout* is specified as :const:`0`, a poll is
    performed. Returns :const:`None` if a timeout occurs.
 
-   .. availability:: Unix (see the man page :manpage:`sigtimedwait(2)` for further
-      information).
+   .. availability:: Unix.  See the man page :manpage:`sigtimedwait(2)` for further
+      information.
 
    See also :func:`pause`, :func:`sigwait` and :func:`sigwaitinfo`.
 
index fba9d5a63dd0069cded8b21ffdf1a4e8dd80a694..3730d74e05d639e4bb19fd02bba9d93e5d2fe46c 100644 (file)
@@ -605,9 +605,9 @@ Constants
 .. data:: VERIFY_CRL_CHECK_LEAF
 
    Possible value for :attr:`SSLContext.verify_flags`. In this mode, only the
-   peer cert is check but non of the intermediate CA certificates. The mode
+   peer cert is checked but none of the intermediate CA certificates. The mode
    requires a valid CRL that is signed by the peer cert's issuer (its direct
-   ancestor CA). If no proper has been loaded
+   ancestor CA). If no proper CRL has has been loaded with
    :attr:`SSLContext.load_verify_locations`, validation will fail.
 
    .. versionadded:: 3.4
@@ -665,7 +665,7 @@ Constants
 
 .. data:: PROTOCOL_SSLv23
 
-   Alias for data:`PROTOCOL_TLS`.
+   Alias for :data:`PROTOCOL_TLS`.
 
    .. deprecated:: 3.6
 
@@ -1821,7 +1821,7 @@ to speed up repeated connections from the same clients.
 
 .. attribute:: SSLContext.sslsocket_class
 
-   The return type of :meth:`SSLContext.wrap_sockets`, defaults to
+   The return type of :meth:`SSLContext.wrap_socket`, defaults to
    :class:`SSLSocket`. The attribute can be overridden on instance of class
    in order to return a custom subclass of :class:`SSLSocket`.
 
@@ -1831,7 +1831,7 @@ to speed up repeated connections from the same clients.
                                 server_hostname=None, session=None)
 
    Wrap the BIO objects *incoming* and *outgoing* and return an instance of
-   attr:`SSLContext.sslobject_class` (default :class:`SSLObject`). The SSL
+   :attr:`SSLContext.sslobject_class` (default :class:`SSLObject`). The SSL
    routines will read input data from the incoming BIO and write data to the
    outgoing BIO.
 
@@ -1873,13 +1873,15 @@ to speed up repeated connections from the same clients.
    :meth:`~SSLContext.wrap_socket` in order to match the hostname.  Enabling
    hostname checking automatically sets :attr:`~SSLContext.verify_mode` from
    :data:`CERT_NONE` to :data:`CERT_REQUIRED`.  It cannot be set back to
-   :data:`CERT_NONE` as long as hostname checking is enabled.
+   :data:`CERT_NONE` as long as hostname checking is enabled. The
+   :data:`PROTOCOL_TLS_CLIENT` protocol enables hostname checking by default.
+   With other protocols, hostname checking must be enabled explicitly.
 
    Example::
 
       import socket, ssl
 
-      context = ssl.SSLContext()
+      context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
       context.verify_mode = ssl.CERT_REQUIRED
       context.check_hostname = True
       context.load_default_certs()
@@ -2181,19 +2183,23 @@ 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()
-   >>> context.verify_mode = ssl.CERT_REQUIRED
-   >>> context.check_hostname = True
+   >>> context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    >>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
 
 (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)
 
+The :data:`PROTOCOL_TLS_CLIENT` protocol configures the context for cert
+validation and hostname verification. :attr:`~SSLContext.verify_mode` is
+set to :data:`CERT_REQUIRED` and :attr:`~SSLContext.check_hostname` is set
+to ``True``. All other protocols create SSL contexts with insecure defaults.
+
 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::
+and :attr:`~SSLContext.check_hostname` validate the server certificate: it
+ensures that the server certificate was signed with one of the CA
+certificates, checks the signature for correctness, and verifies other
+properties like validity and identity of the hostname::
 
    >>> conn = context.wrap_socket(socket.socket(socket.AF_INET),
    ...                            server_hostname="www.python.org")
index 3b74331e51f25d06ea4d8aea6b80d1eea6d75dd1..57b72c5b65620f9576a32de14109597928acad95 100644 (file)
@@ -267,9 +267,8 @@ which is narrower than complex.  Comparisons between numbers of mixed type use
 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 (all numeric operations have a higher priority than
-comparison operations):
+All numeric types (except complex) support the following operations (for priorities of
+the operations, see :ref:`operator-summary`):
 
 +---------------------+---------------------------------+---------+--------------------+
 | Operation           | Result                          | Notes   | Full documentation |
@@ -1731,9 +1730,13 @@ expression support in the :mod:`re` module).
 .. method:: str.isspace()
 
    Return true if there are only whitespace characters in the string and there is
-   at least one character, false otherwise.  Whitespace characters  are those
-   characters defined in the Unicode character database as "Other" or "Separator"
-   and those with bidirectional property being one of "WS", "B", or "S".
+   at least one character, false otherwise.
+
+   A character is *whitespace* if in the Unicode character database
+   (see :mod:`unicodedata`), either its general category is ``Zs``
+   ("Separator, space"), or its bidirectional class is one of ``WS``,
+   ``B``, or ``S``.
+
 
 .. method:: str.istitle()
 
@@ -3733,7 +3736,7 @@ copying.
          >>> z.nbytes
          48
 
-      Cast 1D/unsigned char to 2D/unsigned long::
+      Cast 1D/unsigned long to 2D/unsigned long::
 
          >>> buf = struct.pack("L"*6, *list(range(6)))
          >>> x = memoryview(buf)
@@ -4138,6 +4141,10 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098:
    These are the operations that dictionaries support (and therefore, custom
    mapping types should support too):
 
+   .. describe:: list(d)
+
+      Return a list of all the keys used in the dictionary *d*.
+
    .. describe:: len(d)
 
       Return the number of items in the dictionary *d*.
@@ -4264,8 +4271,16 @@ 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>`.
 
+      An equality comparison between one ``dict.values()`` view and another
+      will always return ``False``. This also applies when comparing
+      ``dict.values()`` to itself::
+
+         >>> d = {'a': 1}
+         >>> d.values() == d.values()
+         False
+
    Dictionaries compare equal if and only if they have the same ``(key,
-   value)`` pairs. Order comparisons ('<', '<=', '>=', '>') raise
+   value)`` pairs (regardless of ordering). Order comparisons ('<', '<=', '>=', '>') raise
    :exc:`TypeError`.
 
    Dictionaries preserve insertion order.  Note that updating a key does not
index 46b2bfc82b738bc1279393672133b18d5a023b57..bbbfed273ee459c9250c21dcf4f75a961b315a2b 100644 (file)
@@ -508,7 +508,8 @@ The available presentation types for floating point and decimal values are:
    |         | with presentation type ``'e'`` and precision ``p-1``.    |
    |         | In both cases insignificant trailing zeros are removed   |
    |         | from the significand, and the decimal point is also      |
-   |         | removed if there are no remaining digits following it.   |
+   |         | removed if there are no remaining digits following it,   |
+   |         | unless the ``'#'`` option is used.                       |
    |         |                                                          |
    |         | Positive and negative infinity, positive and negative    |
    |         | zero, and nans, are formatted as ``inf``, ``-inf``,      |
index df2416e5bc9260b12a9280db65a22e0eba60d691..48885d14f4f4b8dd1529289ef48cf6c00a943616 100644 (file)
@@ -197,44 +197,44 @@ platform-dependent.
 +--------+--------------------------+--------------------+----------------+------------+
 | ``c``  | :c:type:`char`           | bytes of length 1  | 1              |            |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``b``  | :c:type:`signed char`    | integer            | 1              | \(1),\(3)  |
+| ``b``  | :c:type:`signed char`    | integer            | 1              | \(1), \(2) |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``B``  | :c:type:`unsigned char`  | integer            | 1              | \(3)       |
+| ``B``  | :c:type:`unsigned char`  | integer            | 1              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
 | ``?``  | :c:type:`_Bool`          | bool               | 1              | \(1)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``h``  | :c:type:`short`          | integer            | 2              | \(3)       |
+| ``h``  | :c:type:`short`          | integer            | 2              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``H``  | :c:type:`unsigned short` | integer            | 2              | \(3)       |
+| ``H``  | :c:type:`unsigned short` | integer            | 2              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``i``  | :c:type:`int`            | integer            | 4              | \(3)       |
+| ``i``  | :c:type:`int`            | integer            | 4              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``I``  | :c:type:`unsigned int`   | integer            | 4              | \(3)       |
+| ``I``  | :c:type:`unsigned int`   | integer            | 4              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``l``  | :c:type:`long`           | integer            | 4              | \(3)       |
+| ``l``  | :c:type:`long`           | integer            | 4              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``L``  | :c:type:`unsigned long`  | integer            | 4              | \(3)       |
+| ``L``  | :c:type:`unsigned long`  | integer            | 4              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``q``  | :c:type:`long long`      | integer            | 8              | \(2), \(3) |
+| ``q``  | :c:type:`long long`      | integer            | 8              | \(2)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``Q``  | :c:type:`unsigned long   | integer            | 8              | \(2), \(3) |
+| ``Q``  | :c:type:`unsigned long   | integer            | 8              | \(2)       |
 |        | long`                    |                    |                |            |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``n``  | :c:type:`ssize_t`        | integer            |                | \(4)       |
+| ``n``  | :c:type:`ssize_t`        | integer            |                | \(3)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``N``  | :c:type:`size_t`         | integer            |                | \(4)       |
+| ``N``  | :c:type:`size_t`         | integer            |                | \(3)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``e``  | \(7)                     | float              | 2              | \(5)       |
+| ``e``  | \(6)                     | float              | 2              | \(4)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``f``  | :c:type:`float`          | float              | 4              | \(5)       |
+| ``f``  | :c:type:`float`          | float              | 4              | \(4)       |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``d``  | :c:type:`double`         | float              | 8              | \(5)       |
+| ``d``  | :c:type:`double`         | float              | 8              | \(4)       |
 +--------+--------------------------+--------------------+----------------+------------+
 | ``s``  | :c:type:`char[]`         | bytes              |                |            |
 +--------+--------------------------+--------------------+----------------+------------+
 | ``p``  | :c:type:`char[]`         | bytes              |                |            |
 +--------+--------------------------+--------------------+----------------+------------+
-| ``P``  | :c:type:`void \*`        | integer            |                | \(6)       |
+| ``P``  | :c:type:`void \*`        | integer            |                | \(5)       |
 +--------+--------------------------+--------------------+----------------+------------+
 
 .. versionchanged:: 3.3
@@ -254,11 +254,6 @@ Notes:
    standard mode, it is always represented by one byte.
 
 (2)
-   The ``'q'`` and ``'Q'`` conversion codes are available in native mode only if
-   the platform C compiler supports C :c:type:`long long`, or, on Windows,
-   :c:type:`__int64`.  They are always available in standard modes.
-
-(3)
    When attempting to pack a non-integer using any of the integer conversion
    codes, if the non-integer has a :meth:`__index__` method then that method is
    called to convert the argument to an integer before packing.
@@ -266,26 +261,26 @@ Notes:
    .. versionchanged:: 3.2
       Use of the :meth:`__index__` method for non-integers is new in 3.2.
 
-(4)
+(3)
    The ``'n'`` and ``'N'`` conversion codes are only available for the native
    size (selected as the default or with the ``'@'`` byte order character).
    For the standard size, you can use whichever of the other integer formats
    fits your application.
 
-(5)
+(4)
    For the ``'f'``, ``'d'`` and ``'e'`` conversion codes, the packed
    representation uses the IEEE 754 binary32, binary64 or binary16 format (for
    ``'f'``, ``'d'`` or ``'e'`` respectively), regardless of the floating-point
    format used by the platform.
 
-(6)
+(5)
    The ``'P'`` format character is only available for the native byte ordering
    (selected as the default or with the ``'@'`` byte order character). The byte
    order character ``'='`` chooses to use little- or big-endian ordering based
    on the host system. The struct module does not interpret this as native
    ordering, so the ``'P'`` format is not available.
 
-(7)
+(6)
    The IEEE 754 binary16 "half precision" type was introduced in the 2008
    revision of the `IEEE 754 standard <ieee 754 standard_>`_. It has a sign
    bit, a 5-bit exponent and 11-bit precision (with 10 bits explicitly stored),
index 9a8c2ca0c5d05e9a6df7482c6091ffcafc83295c..822e22e334bbe0028b73ccc33f1ecd7b2118dfcd 100644 (file)
@@ -324,7 +324,7 @@ always available.
 
 .. data:: flags
 
-   The :term:`struct sequence` *flags* exposes the status of command line
+   The :term:`named tuple` *flags* exposes the status of command line
    flags. The attributes are read only.
 
    ============================= =============================
@@ -366,7 +366,7 @@ always available.
 
 .. data:: float_info
 
-   A :term:`struct sequence` holding information about the float type. It
+   A :term:`named tuple` holding information about the float type. It
    contains low level information about the precision and internal
    representation.  The values correspond to the various floating-point
    constants defined in the standard header file :file:`float.h` for the 'C'
@@ -716,7 +716,7 @@ always available.
 
 .. data:: hash_info
 
-   A :term:`struct sequence` giving parameters of the numeric hash
+   A :term:`named tuple` giving parameters of the numeric hash
    implementation.  For more details about hashing of numeric types, see
    :ref:`numeric-hash`.
 
@@ -764,7 +764,7 @@ always available.
 
    This is called ``hexversion`` since it only really looks meaningful when viewed
    as the result of passing it to the built-in :func:`hex` function.  The
-   :term:`struct sequence`  :data:`sys.version_info` may be used for a more
+   :term:`named tuple`  :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`.
@@ -809,10 +809,14 @@ always available.
 
    .. versionadded:: 3.3
 
+   .. note::
+
+      The addition of new required attributes must go through the normal PEP
+      process. See :pep:`421` for more information.
 
 .. data:: int_info
 
-   A :term:`struct sequence` that holds information about Python's internal
+   A :term:`named tuple` that holds information about Python's internal
    representation of integers.  The attributes are read only.
 
    .. tabularcolumns:: |l|L|
@@ -1181,7 +1185,8 @@ always available.
 
    The trace function is invoked (with *event* set to ``'call'``) whenever a new
    local scope is entered; it should return a reference to a local trace
-   function to be used that scope, or ``None`` if the scope shouldn't be traced.
+   function to be used for the new scope, or ``None`` if the scope shouldn't be
+   traced.
 
    The local trace function should return a reference to itself (or to another
    function for further tracing in that scope), or ``None`` to turn off tracing
@@ -1228,6 +1233,17 @@ always available.
    Note that as an exception is propagated down the chain of callers, an
    ``'exception'`` event is generated at each level.
 
+   For more fine-grained usage, it's possible to set a trace function by
+   assigning ``frame.f_trace = tracefunc`` explicitly, rather than relying on
+   it being set indirectly via the return value from an already installed
+   trace function. This is also required for activating the trace function on
+   the current frame, which :func:`settrace` doesn't do. Note that in order
+   for this to work, a global tracing function must have been installed
+   with :func:`settrace` in order to enable the runtime tracing machinery,
+   but it doesn't need to be the same tracing function (e.g. it could be a
+   low overhead tracing function that simply returns ``None`` to disable
+   itself immediately on each frame).
+
    For more information on code and frame objects, refer to :ref:`types`.
 
    .. impl-detail::
@@ -1418,7 +1434,7 @@ always available.
 
 .. data:: thread_info
 
-   A :term:`struct sequence` holding information about the thread
+   A :term:`named tuple` holding information about the thread
    implementation.
 
    .. tabularcolumns:: |l|p{0.7\linewidth}|
index 4ba426425277f9fb22c006a6f3b21fb92bf9ce5a..931711963b1620b2a1da871e48206c93fc6594b7 100644 (file)
@@ -29,7 +29,7 @@ Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin).
 .. class:: Telnet(host=None, port=0[, timeout])
 
    :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
+   initially not connected by default; the :meth:`~Telnet.open` method must be used to
    establish a connection.  Alternatively, the host name and optional port
    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
index 746adb1eee484151e88829babaa65f7341e5733d..dd24a1c6f4ffd4e9fd4242230a8a8b51276ffa2e 100644 (file)
@@ -174,6 +174,9 @@ The module defines the following user-callable items:
       *suffix* and *prefix* now accept and default to ``None`` to cause
       an appropriate default value to be used.
 
+   .. versionchanged:: 3.6
+      The *dir* parameter now accepts a :term:`path-like object`.
+
 
 .. function:: mkdtemp(suffix=None, prefix=None, dir=None)
 
@@ -195,6 +198,9 @@ The module defines the following user-callable items:
       *suffix* and *prefix* now accept and default to ``None`` to cause
       an appropriate default value to be used.
 
+   .. versionchanged:: 3.6
+      The *dir* parameter now accepts a :term:`path-like object`.
+
 
 .. function:: gettempdir()
 
index de79cdfc5fa9f3e83bd25c142f9018b1e64cbb9e..e93ef450f022771cb840bf69eb8eb6c512d0e767 100644 (file)
@@ -356,11 +356,28 @@ The :mod:`test.support` module defines the following constants:
 
    Check for presence of docstrings.
 
+
 .. data:: TEST_HTTP_URL
 
    Define the URL of a dedicated HTTP server for the network tests.
 
 
+.. data:: ALWAYS_EQ
+
+   Object that is equal to anything.  Used to test mixed type comparison.
+
+
+.. data:: LARGEST
+
+   Object that is greater than anything (except itself).
+   Used to test mixed type comparison.
+
+
+.. data:: SMALLEST
+
+   Object that is less than anything (except itself).
+   Used to test mixed type comparison.
+
 
 The :mod:`test.support` module defines the following functions:
 
index d254466c9a320d8ea9e13b28de8261cd42e314c8..0f11ef401569de600fe0194f62475cc66cf7ce1d 100644 (file)
@@ -77,6 +77,9 @@ functions should be good enough; otherwise, you should use an instance of
    equal: the lines ``"  hello"`` and ``"\thello"`` are considered to have no
    common leading whitespace.
 
+   Lines containing only whitespace are ignored in the input and normalized to a
+   single newline character in the output.
+
    For example::
 
       def test():
index 4230c19faf1028f2c89ebf01dc6639fb4ddd19f0..17f8cfc5461473204b03829d157b13d1cbd5dcdc 100644 (file)
@@ -630,7 +630,7 @@ Functions
 
 .. function:: time_ns() -> int
 
-   Similar to :func:`time` but returns time as an integer number of nanoseconds
+   Similar to :func:`~time.time` but returns time as an integer number of nanoseconds
    since the epoch_.
 
    .. versionadded:: 3.7
index 12f4c03f4232b868eacbc9f99990fb4934464532..2c84551e4eae0ce7512e6b039bed70ca5f048115 100644 (file)
 
 .. note::
 
-   The typing module has been included in the standard library on a
-   :term:`provisional basis <provisional api>`. New features might
-   be added and API may change even between minor releases if deemed
-   necessary by the core developers.
+   The Python runtime does not enforce function and variable type annotations.
+   They can be used by third party tools such as type checkers, IDEs, linters,
+   etc.
 
 --------------
 
@@ -231,8 +230,8 @@ A user-defined class can be defined as a generic class.
 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::
+The :class:`Generic` base class defines :meth:`__class_getitem__` so that
+``LoggedVar[t]`` is valid as a type::
 
    from typing import Iterable
 
@@ -307,9 +306,10 @@ User defined generic type aliases are also supported. Examples::
    def inproduct(v: Vec[T]) -> T: # Same as Iterable[Tuple[T, T]]
        return sum(x*y for x, y in v)
 
-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
+.. versionchanged:: 3.7
+    :class:`Generic` no longer has a custom metaclass.
+
+A user-defined generic class can have ABCs as base classes without a metaclass
 conflict. Generic metaclasses are not supported. The outcome of parameterizing
 generics is cached, and most types in the typing module are hashable and
 comparable for equality.
@@ -876,6 +876,13 @@ The module defines the following classes, functions and decorators:
    .. versionchanged:: 3.6.1
       Added support for default values, methods, and docstrings.
 
+.. class:: ForwardRef
+
+   A class used for internal typing representation of string forward references.
+   For example, ``List["SomeClass"]`` is implicitly transformed into
+   ``List[ForwardRef("SomeClass")]``.  This class should not be instantiated by
+   a user, but may be used by introspection tools.
+
 .. function:: NewType(typ)
 
    A helper function to indicate a distinct types to a typechecker,
@@ -1049,7 +1056,8 @@ The module defines the following classes, functions and decorators:
 .. data:: Tuple
 
    Tuple type; ``Tuple[X, Y]`` is the type of a tuple of two items
-   with the first item of type X and the second of type Y.
+   with the first item of type X and the second of type Y. The type of
+   the empty tuple can be written as ``Tuple[()]``.
 
    Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding
    to type variables T1 and T2.  ``Tuple[int, float, str]`` is a tuple
index 59548f3e8b4ac5ffc71bfa02924419a233198735..d0dae72f8070439f32ebef4a96ddcfb82f5305ba 100644 (file)
@@ -22,7 +22,7 @@ this database is compiled from the `UCD version 11.0.0
 
 The module uses the same names and symbols as defined by Unicode
 Standard Annex #44, `"Unicode Character Database"
-<http://www.unicode.org/reports/tr44/tr44-6.html>`_.  It defines the
+<https://www.unicode.org/reports/tr44/>`_.  It defines the
 following functions:
 
 
index b76ae712a971b719e2ecd19fd28f3b8a153e8c07..36cc0c2fc4bdcc8d582203afed88ecedb211cc64 100644 (file)
@@ -262,7 +262,7 @@ the *new_callable* argument to :func:`patch`.
     used to set attributes on the mock after it is created. See the
     :meth:`configure_mock` method for details.
 
-    .. method:: assert_called(*args, **kwargs)
+    .. method:: assert_called()
 
         Assert that the mock was called at least once.
 
@@ -273,7 +273,7 @@ the *new_callable* argument to :func:`patch`.
 
         .. versionadded:: 3.6
 
-    .. method:: assert_called_once(*args, **kwargs)
+    .. method:: assert_called_once()
 
         Assert that the mock was called exactly once.
 
index 1bc81e05b38b136ff843cba0e034f9ffd12f2730..5d8c0ec4303cd672a8f681012f554cbbec6a40ce 100644 (file)
@@ -220,7 +220,7 @@ The following classes are provided:
    is not None, ``Content-Type: application/x-www-form-urlencoded`` will
    be added as a default.
 
-   The final two arguments are only of interest for correct handling
+   The next two arguments are only of interest for correct handling
    of third-party HTTP cookies:
 
    *origin_req_host* should be the request-host of the origin
index d61df484f9e7ebdc71678d3013be6e56ea9865ed..18804b5eed64aa332270d8991365187429948345 100644 (file)
@@ -52,7 +52,7 @@ Creating virtual environments
    A virtual environment is a directory tree which contains Python executable
    files and other files which indicate that it is a virtual environment.
 
-   Common installation tools such as ``Setuptools`` and ``pip`` work as
+   Common installation tools such as setuptools_ and pip_ work as
    expected with virtual environments. In other words, when a virtual
    environment is active, they install Python packages into the virtual
    environment without needing to be told to do so explicitly.
@@ -69,24 +69,25 @@ Creating virtual environments
    Python installation).
 
    When a virtual environment is active, any options that change the
-   installation path will be ignored from all distutils configuration files to
-   prevent projects being inadvertently installed outside of the virtual
-   environment.
+   installation path will be ignored from all :mod:`distutils` configuration
+   files to prevent projects being inadvertently installed outside of the
+   virtual environment.
 
    When working in a command shell, users can make a virtual environment active
    by running an ``activate`` script in the virtual environment's executables
-   directory (the precise filename is shell-dependent), which prepends the
-   virtual environment's directory for executables to the ``PATH`` environment
-   variable for the running shell. There should be no need in other
-   circumstances to activate a virtual environment—scripts installed into
-   virtual environments have a "shebang" line which points to the virtual
-   environment's Python interpreter. This means that the script will run with
-   that interpreter regardless of the value of ``PATH``. On Windows, "shebang"
-   line processing is supported if you have the Python Launcher for Windows
-   installed (this was added to Python in 3.3 - see :pep:`397` for more
-   details). Thus, double-clicking an installed script in a Windows Explorer
-   window should run the script with the correct interpreter without there
-   needing to be any reference to its virtual environment in ``PATH``.
+   directory (the precise filename and command to use the file is
+   shell-dependent), which prepends the virtual environment's directory for
+   executables to the ``PATH`` environment variable for the running shell. There
+   should be no need in other circumstances to activate a virtual
+   environment; scripts installed into virtual environments have a "shebang"
+   line which points to the virtual environment's Python interpreter. This means
+   that the script will run with that interpreter regardless of the value of
+   ``PATH``. On Windows, "shebang" line processing is supported if you have the
+   Python Launcher for Windows installed (this was added to Python in 3.3 - see
+   :pep:`397` for more details). Thus, double-clicking an installed script in a
+   Windows Explorer window should run the script with the correct interpreter
+   without there needing to be any reference to its virtual environment in
+   ``PATH``.
 
 
 .. _venv-api:
@@ -135,20 +136,20 @@ creation according to their needs, the :class:`EnvBuilder` class.
        Added the ``prompt`` parameter
 
     Creators of third-party virtual environment tools will be free to use the
-    provided ``EnvBuilder`` class as a base class.
+    provided :class:`EnvBuilder` class as a base class.
 
     The returned env-builder is an object which has a method, ``create``:
 
     .. method:: create(env_dir)
 
-        This method takes as required argument the path (absolute or relative to
-        the current directory) of the target directory which is to contain the
+        Create a virtual environment by specifying the target directory
+        (absolute or relative to the current directory) which is to contain the
         virtual environment.  The ``create`` method will either create the
         environment in the specified directory, or raise an appropriate
         exception.
 
-        The ``create`` method of the ``EnvBuilder`` class illustrates the hooks
-        available for subclass customization::
+        The ``create`` method of the :class:`EnvBuilder` class illustrates the
+        hooks available for subclass customization::
 
             def create(self, env_dir):
                 """
@@ -476,3 +477,7 @@ subclass which installs setuptools and pip into a created virtual environment::
 
 This script is also available for download `online
 <https://gist.github.com/vsajip/4673395>`_.
+
+
+.. _setuptools: https://pypi.org/project/setuptools/
+.. _pip: https://pypi.org/project/pip/
index e9c026102273310f88bab7b8ef63d0db5658b95e..cb67f2f39d7603dbcf32162a743b50c431834c3d 100644 (file)
@@ -456,7 +456,7 @@ This module offers the following functions:
    *key* is an already open key, or one of the predefined :ref:`HKEY_* constants
    <hkey-constants>`.
 
-   Will generally raise :exc:`NotImplemented` if executed on a 32-bit operating
+   Will generally raise :exc:`NotImplementedError` if executed on a 32-bit operating
    system.
 
    If the key is not on the reflection list, the function succeeds but has no
@@ -471,7 +471,7 @@ This module offers the following functions:
    *key* is an already open key, or one of the predefined :ref:`HKEY_* constants
    <hkey-constants>`.
 
-   Will generally raise :exc:`NotImplemented` if executed on a 32-bit operating
+   Will generally raise :exc:`NotImplementedError` if executed on a 32-bit operating
    system.
 
    Restoring reflection for a key does not affect reflection of any subkeys.
@@ -486,7 +486,7 @@ This module offers the following functions:
 
    Returns ``True`` if reflection is disabled.
 
-   Will generally raise :exc:`NotImplemented` if executed on a 32-bit
+   Will generally raise :exc:`NotImplementedError` if executed on a 32-bit
    operating system.
 
 
index 5f799aba994d709fa4fd1e6ca68b95cebec3309d..ca6bdf6095b8a5c0fc502d16d19690eb64f2285a 100644 (file)
@@ -640,6 +640,95 @@ Functions
    :class:`Element` instance and a dictionary.
 
 
+.. _elementtree-xinclude:
+
+XInclude support
+----------------
+
+This module provides limited support for
+`XInclude directives <https://www.w3.org/TR/xinclude/>`_, via the :mod:`xml.etree.ElementInclude` helper module.  This module can be used to insert subtrees and text strings into element trees, based on information in the tree.
+
+Example
+^^^^^^^
+
+Here's an example that demonstrates use of the XInclude module. To include an XML document in the current document, use the ``{http://www.w3.org/2001/XInclude}include`` element and set the **parse** attribute to ``"xml"``, and use the **href** attribute to specify the document to include.
+
+.. code-block:: xml
+
+    <?xml version="1.0"?>
+    <document xmlns:xi="http://www.w3.org/2001/XInclude">
+      <xi:include href="source.xml" parse="xml" />
+    </document>
+
+By default, the **href** attribute is treated as a file name. You can use custom loaders to override this behaviour. Also note that the standard helper does not support XPointer syntax.
+
+To process this file, load it as usual, and pass the root element to the :mod:`xml.etree.ElementTree` module:
+
+.. code-block:: python
+
+   from xml.etree import ElementTree, ElementInclude
+
+   tree = ElementTree.parse("document.xml")
+   root = tree.getroot()
+
+   ElementInclude.include(root)
+
+The ElementInclude module replaces the ``{http://www.w3.org/2001/XInclude}include`` element with the root element from the **source.xml** document. The result might look something like this:
+
+.. code-block:: xml
+
+    <document xmlns:xi="http://www.w3.org/2001/XInclude">
+      <para>This is a paragraph.</para>
+    </document>
+
+If the **parse** attribute is omitted, it defaults to "xml". The href attribute is required.
+
+To include a text document, use the ``{http://www.w3.org/2001/XInclude}include`` element, and set the **parse** attribute to "text":
+
+.. code-block:: xml
+
+    <?xml version="1.0"?>
+    <document xmlns:xi="http://www.w3.org/2001/XInclude">
+      Copyright (c) <xi:include href="year.txt" parse="text" />.
+    </document>
+
+The result might look something like:
+
+.. code-block:: xml
+
+    <document xmlns:xi="http://www.w3.org/2001/XInclude">
+      Copyright (c) 2003.
+    </document>
+
+Reference
+---------
+
+.. _elementinclude-functions:
+
+Functions
+^^^^^^^^^
+
+.. function:: xml.etree.ElementInclude.default_loader( href, parse, encoding=None)
+
+   Default loader. This default loader reads an included resource from disk.  *href* is a URL.
+   *parse* is for parse mode either "xml" or "text".  *encoding*
+   is an optional text encoding.  If not given, encoding is ``utf-8``.  Returns the
+   expanded resource.  If the parse mode is ``"xml"``, this is an ElementTree
+   instance.  If the parse mode is "text", this is a Unicode string.  If the
+   loader fails, it can return None or raise an exception.
+
+
+.. function:: xml.etree.ElementInclude.include( elem, loader=None)
+
+   This function expands XInclude directives.  *elem* is the root element.  *loader* is
+   an optional resource loader.  If omitted, it defaults to :func:`default_loader`.
+   If given, it should be a callable that implements the same interface as
+   :func:`default_loader`.  Returns the expanded resource.  If the parse mode is
+   ``"xml"``, this is an ElementTree instance.  If the parse mode is "text",
+   this is a Unicode string.  If the loader fails, it can return None or
+   raise an exception.
+
+
 .. _elementtree-element-objects:
 
 Element Objects
index 962ec7e6c719de3bee61d59c2082a015fc1ccdfb..f5e23d85b9d8671160e9ef15c08aec638e1e256a 100644 (file)
@@ -2142,7 +2142,9 @@ through the container; for mappings, :meth:`__iter__` should be the same as
 
    Called to implement :func:`operator.length_hint`. Should return an estimated
    length for the object (which may be greater or less than the actual length).
-   The length must be an integer ``>=`` 0. This method is purely an
+   The length must be an integer ``>=`` 0. The return value may also be
+   :const:`NotImplemented`, which is treated the same as if the
+   ``__length_hint__`` method didn't exist at all. This method is purely an
    optimization and is never required for correctness.
 
    .. versionadded:: 3.4
index 990600ec18888f74c2b541e24d0cafb19d18d32d..0a61ded2e3abd56ff6f62b6df93413f557b0bfa7 100644 (file)
@@ -148,9 +148,8 @@ immutable, the same rules as for literals apply (i.e., two occurrences of the em
 tuple may or may not yield the same object).
 
 .. index::
-   single: comma; tuple display
-   pair: tuple; display
-   single: , (comma); tuple display
+   single: comma
+   single: , (comma)
 
 Note that tuples are not formed by the parentheses, but rather by use of the
 comma operator.  The exception is the empty tuple, for which parentheses *are*
@@ -1833,7 +1832,8 @@ precedence and have a left-to-right chaining feature as described in the
 | ``x[index]``, ``x[index:index]``,             | Subscription, slicing,              |
 | ``x(arguments...)``, ``x.attribute``          | call, attribute reference           |
 +-----------------------------------------------+-------------------------------------+
-| ``(expressions...)``,                         | Binding or tuple display,           |
+| ``(expressions...)``,                         | Binding or parenthesized            |
+|                                               | expression,                         |
 | ``[expressions...]``,                         | list display,                       |
 | ``{key: value...}``,                          | dictionary display,                 |
 | ``{expressions...}``                          | set display                         |
index 8d80f6759bffd4354a24d4dc288927ce1fbf2e4f..fd50f318170b15324a6191f28d9256c49468690f 100644 (file)
@@ -115,10 +115,12 @@ class CheckSuspiciousMarkupBuilder(Builder):
     def finish(self):
         unused_rules = [rule for rule in self.rules if not rule.used]
         if unused_rules:
-            self.warn('Found %s/%s unused rules:' %
-                      (len(unused_rules), len(self.rules)))
-            for rule in unused_rules:
-                self.logger.info(repr(rule))
+            self.logger.warning(
+                'Found %s/%s unused rules: %s' % (
+                    len(unused_rules), len(self.rules),
+                    ''.join(repr(rule) for rule in unused_rules),
+                )
+            )
         return
 
     def check_issue(self, line, lineno, issue):
@@ -152,14 +154,15 @@ class CheckSuspiciousMarkupBuilder(Builder):
         self.any_issue = True
         self.write_log_entry(lineno, issue, text)
         if py3:
-            self.warn('[%s:%d] "%s" found in "%-.120s"' %
-                      (self.docname, lineno, issue, text))
+            self.logger.warning('[%s:%d] "%s" found in "%-.120s"' %
+                                (self.docname, lineno, issue, text))
         else:
-            self.warn('[%s:%d] "%s" found in "%-.120s"' % (
-                self.docname.encode(sys.getdefaultencoding(),'replace'),
-                lineno,
-                issue.encode(sys.getdefaultencoding(),'replace'),
-                text.strip().encode(sys.getdefaultencoding(),'replace')))
+            self.logger.warning(
+                '[%s:%d] "%s" found in "%-.120s"' % (
+                    self.docname.encode(sys.getdefaultencoding(),'replace'),
+                    lineno,
+                    issue.encode(sys.getdefaultencoding(),'replace'),
+                    text.strip().encode(sys.getdefaultencoding(),'replace')))
         self.app.statuscode = 1
 
     def write_log_entry(self, lineno, issue, text):
index 30271bb9ce93574775197bb61d2b29120a63f1ca..36d93a45b0209e884a592b49423f4666e2b6b9f6 100644 (file)
@@ -332,6 +332,9 @@ library/xml.etree.elementtree,,:character,<fictional:character>Commander Clement
 library/xml.etree.elementtree,,:actor,"for actor in root.findall('real_person:actor', ns):"
 library/xml.etree.elementtree,,:name,"name = actor.find('real_person:name', ns)"
 library/xml.etree.elementtree,,:character,"for char in actor.findall('role:character', ns):"
+library/xml.etree.elementtree,,:xi,<document xmlns:xi="http://www.w3.org/2001/XInclude">
+library/xml.etree.elementtree,,:include,  <xi:include href="source.xml" parse="xml" />
+library/xml.etree.elementtree,,:include,  Copyright (c) <xi:include href="year.txt" parse="text" />.
 library/zipapp,,:main,"$ python -m zipapp myapp -m ""myapp:main"""
 library/zipapp,,:fn,"pkg.mod:fn"
 library/zipapp,,:callable,"pkg.module:callable"
@@ -351,3 +354,4 @@ whatsnew/3.7,,::,error::BytesWarning
 whatsnew/changelog,,::,error::BytesWarning
 whatsnew/changelog,,::,default::BytesWarning
 whatsnew/changelog,,::,default::DeprecationWarning
+library/re,,`,"`"
index 0adaf038d0e522ddca1bfb5b989611dd4d2cb0c0..e5748f2ab0fc6e981ffb8ef988c32c3fb910648a 100644 (file)
@@ -3,7 +3,7 @@
 <h3>{% trans %}Docs by version{% endtrans %}</h3>
 <ul>
   <li><a href="https://docs.python.org/3.9/">{% trans %}Python 3.9 (in development){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/3.8/">{% trans %}Python 3.8 (pre-release){% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/3.8/">{% trans %}Python 3.8 (stable){% endtrans %}</a></li>
   <li><a href="https://docs.python.org/3.7/">{% trans %}Python 3.7 (stable){% endtrans %}</a></li>
   <li><a href="https://docs.python.org/3.6/">{% trans %}Python 3.6 (security-fixes){% endtrans %}</a></li>
   <li><a href="https://docs.python.org/3.5/">{% trans %}Python 3.5 (security-fixes){% endtrans %}</a></li>
index c3ce1205e52e41767b2bd1c3a038beb61ddaef59..b7638dfffa4f0f1ee01d8fdbc97e7a0bc2aa27b8 100644 (file)
@@ -4,8 +4,8 @@
 More Control Flow Tools
 ***********************
 
-Besides the :keyword:`while` statement just introduced, Python knows the usual
-control flow statements known from other languages, with some twists.
+Besides the :keyword:`while` statement just introduced, Python uses the usual
+flow control statements known from other languages, with some twists.
 
 
 .. _tut-if:
@@ -744,7 +744,7 @@ extracted for you:
   bracketing constructs: ``a = f(1, 2) + g(3, 4)``.
 
 * Name your classes and functions consistently; the convention is to use
-  ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions
+  ``UpperCamelCase`` for classes and ``lowercase_with_underscores`` for functions
   and methods.  Always use ``self`` as the name for the first method argument
   (see :ref:`tut-firstclasses` for more on classes and methods).
 
index 4e287bbd8d29ff45adcf6e2404047798d4928f71..4bc7184d1078c543a400e089ba6d18a9d7a785a3 100644 (file)
@@ -341,15 +341,28 @@ example::
      File "<stdin>", line 2, in <module>
    KeyboardInterrupt
 
-A *finally clause* is always executed before leaving the :keyword:`try`
-statement, whether an exception has occurred or not. When an exception has
-occurred in the :keyword:`!try` clause and has not been handled by an
-:keyword:`except` clause (or it has occurred in an :keyword:`!except` or
-:keyword:`!else` clause), it is re-raised after the :keyword:`finally` clause has
-been executed.  The :keyword:`!finally` clause is also executed "on the way out"
-when any other clause of the :keyword:`!try` statement is left via a
-:keyword:`break`, :keyword:`continue` or :keyword:`return` statement.  A more
-complicated example::
+If a :keyword:`finally` clause is present, the :keyword:`finally` clause will execute as the last task before the :keyword:`try` statement completes. The :keyword:`finally` clause runs whether or not the :keyword:`try` statement produces an exception. The following points discuss more complex cases when an exception occurs:
+
+* If an exception occurs during execution of the :keyword:`!try` clause, the exception may be handled by an :keyword:`except` clause. If the exception is not handled by an :keyword:`except` clause, the exception is re-raised after the :keyword:`!finally` clause has been executed.
+
+* An exception could occur during execution of an :keyword:`!except` or :keyword:`!else` clause. Again, the exception is re-raised after the :keyword:`!finally` clause has been executed.
+
+* If the :keyword:`!try` statement reaches a :keyword:`break`, :keyword:`continue` or :keyword:`return` statement, the :keyword:`finally` clause will execute just prior to the :keyword:`break`, :keyword:`continue` or :keyword:`return` statement's execution.
+
+* If a :keyword:`finally` clause includes a :keyword:`return` statement, the :keyword:`finally` clause's :keyword:`return` statement will execute before, and instead of, the :keyword:`return` statement in a :keyword:`try` clause.
+
+For example::
+
+   >>> def bool_return():
+   ...     try:
+   ...         return True
+   ...     finally:
+   ...         return False
+   ...
+   >>> bool_return()
+   False
+
+A more complicated example::
 
    >>> def divide(x, y):
    ...     try:
index 79427860f518ff842fa4e262f0cc63ba8e8c6be4..74f381d4a0da57679be4896e868785c0061a5bc0 100644 (file)
@@ -356,8 +356,8 @@ To read a file's contents, call ``f.read(size)``, which reads some quantity of
 data and returns it as a string (in text mode) or bytes object (in binary mode).
 *size* is an optional numeric argument.  When *size* is omitted or negative, the
 entire contents of the file will be read and returned; it's your problem if the
-file is twice as large as your machine's memory. Otherwise, at most *size* bytes
-are read and returned.
+file is twice as large as your machine's memory. Otherwise, at most *size*
+characters (in text mode) or *size* bytes (in binary mode) are read and returned.
 If the end of the file has been reached, ``f.read()`` will return an empty
 string (``''``).  ::
 
@@ -410,11 +410,11 @@ or a bytes object (in binary mode) -- before writing them::
 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
+To change the file object's position, use ``f.seek(offset, whence)``.  The position is computed
 from adding *offset* to a reference point; the reference point is selected by
-the *from_what* argument.  A *from_what* value of 0 measures from the beginning
+the *whence* argument.  A *whence* value of 0 measures from the beginning
 of the file, 1 uses the current file position, and 2 uses the end of the file as
-the reference point.  *from_what* can be omitted and defaults to 0, using the
+the reference point.  *whence* can be omitted and defaults to 0, using the
 beginning of the file as the reference point. ::
 
    >>> f = open('workfile', 'rb+')
index 647dd72b374fa01b82cae71724c1fcd6b75d361c..daa4173642447c55e5bda9f48b8ba43291eaefd8 100644 (file)
@@ -34,13 +34,14 @@ status.  If that doesn't work, you can exit the interpreter by typing the
 following command: ``quit()``.
 
 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.
+substitution and code completion on systems that support the `GNU Readline
+<https://tiswww.case.edu/php/chet/readline/rltop.html>`_ library.
+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;
index f5ec8acf58ad7fd21d619c4844a15e72aec1306d..26f11950e79e765114749b5b9c57e6f0105a40ff 100644 (file)
@@ -72,10 +72,21 @@ three`` at the command line::
    >>> print(sys.argv)
    ['demo.py', 'one', 'two', 'three']
 
-The :mod:`getopt` module processes *sys.argv* using the conventions of the Unix
-:func:`getopt` function.  More powerful and flexible command line processing is
-provided by the :mod:`argparse` module.
-
+The :mod:`argparse` module provides a mechanism to process command line arguments.
+It should always be preferred over directly processing ``sys.argv`` manually.
+
+Take, for example, the below snippet of code::
+
+   >>> import argparse
+   >>> from getpass import getuser
+   >>> parser = argparse.ArgumentParser(description='An argparse example.')
+   >>> parser.add_argument('name', nargs='?', default=getuser(), help='The name of someone to greet.')
+   >>> parser.add_argument('--verbose', '-v', action='count')
+   >>> args = parser.parse_args()
+   >>> greeting = ["Hi", "Hello", "Greetings! its very nice to meet you"][args.verbose % 3]
+   >>> print(f'{greeting}, {args.name}')
+   >>> if not args.verbose:
+   >>>     print('Try running this again with multiple "-v" flags!')
 
 .. _tut-stderr:
 
index dca89eceeda98a11f35bc61f21b9469279d6481b..6a60bc4954c625e384fad5d1ea3d1d1f0ed6e85f 100644 (file)
@@ -100,6 +100,11 @@ source.
    first element will be set to ``"-m"``). As with the :option:`-c` option,
    the current directory will be added to the start of :data:`sys.path`.
 
+   :option:`-I` option can  be used to run the script in isolated mode where
+   :data:`sys.path` contains neither the current directory nor the user's
+   site-packages directory. All :envvar:`PYTHON*` environment variables are
+   ignored, too.
+
    Many standard library modules contain code that is invoked on their execution
    as a script.  An example is the :mod:`timeit` module::
 
@@ -119,6 +124,7 @@ source.
    .. versionchanged:: 3.4
       namespace packages are also supported
 
+.. _cmdarg-dash:
 
 .. describe:: -
 
@@ -130,6 +136,8 @@ source.
    :data:`sys.path`.
 
 
+.. _cmdarg-script:
+
 .. describe:: <script>
 
    Execute the Python code contained in *script*, which must be a filesystem
@@ -148,6 +156,11 @@ source.
    added to the start of :data:`sys.path` and the ``__main__.py`` file in
    that location is executed as the :mod:`__main__` module.
 
+   :option:`-I` option can  be used to run the script in isolated mode where
+   :data:`sys.path` contains neither the script's directory nor the user's
+   site-packages directory. All :envvar:`PYTHON*` environment variables are
+   ignored, too.
+
    .. seealso::
       :func:`runpy.run_path`
          Equivalent functionality directly available to Python code
diff --git a/Doc/using/editors.rst b/Doc/using/editors.rst
new file mode 100644 (file)
index 0000000..f36f570
--- /dev/null
@@ -0,0 +1,14 @@
+.. highlight:: none
+
+.. _editors:
+
+******************
+ Editors and IDEs
+******************
+
+There are a number of IDEs that support Python programming language.
+Many editors and IDEs provide syntax highlighting, debugging tools, and :pep:`8` checks.
+
+Please go to `Python Editors <https://wiki.python.org/moin/PythonEditors>`_ and
+`Integrated Development Environments <https://wiki.python.org/moin/IntegratedDevelopmentEnvironments>`_
+for a comprehensive list.
index 4f0aa7d9577df6fb1398f4d0c34095b3d935d588..4a45121ac2eebd817c55097de74dbb4887c3ad5b 100644 (file)
@@ -17,3 +17,4 @@ interpreter and things that make working with Python easier.
    unix.rst
    windows.rst
    mac.rst
+   editors.rst
index d18fd067062783f478ef8004b1b7b3d53f3ab0df..7fdab5d43329cd4ca42829dbee017ab62c7006a5 100644 (file)
@@ -134,14 +134,3 @@ some Unices may not have the :program:`env` command, so you may need to hardcode
 ``/usr/bin/python3`` as the interpreter path.
 
 To use shell commands in your Python scripts, look at the :mod:`subprocess` module.
-
-
-Editors and IDEs
-================
-
-There are a number of IDEs that support Python programming language.
-Many editors and IDEs provide syntax highlighting, debugging tools, and :pep:`8` checks.
-
-Please go to `Python Editors <https://wiki.python.org/moin/PythonEditors>`_ and
-`Integrated Development Environments <https://wiki.python.org/moin/IntegratedDevelopmentEnvironments>`_
-for a comprehensive list.
index 1ada83c07a67f15032a8db8a106677a69d434063..4a795704ed9a38ce26cb7343e000d99bcc8e9f9a 100644 (file)
@@ -115,10 +115,8 @@ installed in a virtual environment should be runnable without activating it,
 and run with the virtual environment's Python automatically.
 
 You can deactivate a virtual environment by typing "deactivate" in your shell.
-The exact mechanism is platform-specific: for example, the Bash activation
-script defines a "deactivate" function, whereas on Windows there are separate
-scripts called ``deactivate.bat`` and ``Deactivate.ps1`` which are installed
-when the virtual environment is created.
+The exact mechanism is platform-specific and is an internal implementation
+detail (typically a script or shell function will be used).
 
 .. versionadded:: 3.4
    ``fish`` and ``csh`` activation scripts.
index 8862b37e062823d3ce57280723ecc8b63dcb4e09..eac200b2cc5d6c65356183b2ef68b2dedbcb96ba 100644 (file)
@@ -2002,8 +2002,8 @@ platform-independent fashion.  (Contributed by Ross Lagerwall in
 sys
 ---
 
-The :mod:`sys` module has a new :data:`~sys.thread_info` :term:`struct
-sequence` holding information about the thread implementation
+The :mod:`sys` module has a new :data:`~sys.thread_info` :term:`named
+tuple` holding information about the thread implementation
 (:issue:`11223`).
 
 
index 845e327cabc86c84af85580fd73c3641e570ff04..822ba81be8a7fe9fe457641c1fe62f948cb1ada6 100644 (file)
@@ -1849,7 +1849,7 @@ 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
+The PEP adds additional fields to the :attr:`sys.hash_info` named tuple to
 describe the hash algorithm in use by the currently executing binary.  Otherwise,
 the PEP does not alter any existing CPython APIs.
 
index e78af225d3857c032a6ff4db57d242b722b10b7f..f6476a30f889f5c69d5d9812d84b4ecaca395c90 100644 (file)
@@ -1017,6 +1017,22 @@ by right-clicking the button.  (Contributed by Tal Einat in :issue:`1529353`.)
 
 The changes above have been backported to 3.6 maintenance releases.
 
+NEW in 3.7.4:
+
+Add "Run Customized" to the Run menu to run a module with customized
+settings. Any command line arguments entered are added to sys.argv.
+They re-appear in the box for the next customized run.  One can also
+suppress the normal Shell main module restart.  (Contributed by Cheryl
+Sabella, Terry Jan Reedy, and others in :issue:`5680` and :issue:`37627`.)
+
+New in 3.7.5:
+
+Add optional line numbers for IDLE editor windows. Windows
+open without line numbers unless set otherwise in the General
+tab of the configuration dialog.  Line numbers for an existing
+window are shown and hidden in the Options menu.
+(Contributed by Tal Einat and Saimadhav Heblikar in :issue:`17535`.)
+
 
 importlib
 ---------
@@ -2398,6 +2414,10 @@ Changes in the Python API
   instead of a :class:`bytes` instance.
   (Contributed by Victor Stinner in :issue:`21071`.)
 
+* :mod:`argparse` subparsers can now be made mandatory by passing ``required=True``
+  to :meth:`ArgumentParser.add_subparsers() <argparse.ArgumentParser.add_subparsers>`.
+  (Contributed by Anthony Sottile in :issue:`26510`.)
+
 * :meth:`ast.literal_eval()` is now stricter.  Addition and subtraction of
   arbitrary numbers are no longer allowed.
   (Contributed by Serhiy Storchaka in :issue:`31778`.)
index a388239c7524f3bd1eab6f2b7e7d8d3f434f678c..083aeb8bc6297052d55e3c8694b98b7ba757832e 100644 (file)
 /*--start constants--*/
 #define PY_MAJOR_VERSION        3
 #define PY_MINOR_VERSION        7
-#define PY_MICRO_VERSION        4
+#define PY_MICRO_VERSION        5
 #define PY_RELEASE_LEVEL        PY_RELEASE_LEVEL_FINAL
 #define PY_RELEASE_SERIAL       0
 
 /* Version as a string */
-#define PY_VERSION              "3.7.4"
+#define PY_VERSION              "3.7.5"
 /*--end constants--*/
 
 /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
index c1f4c7fbb52c99394bb099eae8954a6c560b58a0..27e51b42c617bd5bc3af5770249192342e7b54b5 100644 (file)
@@ -324,7 +324,7 @@ extern "C" {
         } \
     } while(0)
 
-/* Py_SET_ERANGE_ON_OVERFLOW(x)
+/* Py_SET_ERANGE_IF_OVERFLOW(x)
  * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility.
  */
 #define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X)
index 4870a9df5b46c8019fb4ef0832778dca1a541f32..bdda1da2e6b8f2ec6bce29688a67f8137f7d9208 100644 (file)
@@ -17,8 +17,8 @@ extern "C" {
    store a duration, and so indirectly a date (related to another date, like
    UNIX epoch). */
 typedef int64_t _PyTime_t;
-#define _PyTime_MIN PY_LLONG_MIN
-#define _PyTime_MAX PY_LLONG_MAX
+#define _PyTime_MIN INT64_MIN
+#define _PyTime_MAX INT64_MAX
 
 typedef enum {
     /* Round towards minus infinity (-inf).
index a0307492476259c51d603bb6b15653f6d3a99d85..24af355b74413018540ee3093cc02aad484d3999 100644 (file)
@@ -407,13 +407,19 @@ class HelpFormatter(object):
                             inserts[start] += ' ['
                         else:
                             inserts[start] = '['
-                        inserts[end] = ']'
+                        if end in inserts:
+                            inserts[end] += ']'
+                        else:
+                            inserts[end] = ']'
                     else:
                         if start in inserts:
                             inserts[start] += ' ('
                         else:
                             inserts[start] = '('
-                        inserts[end] = ')'
+                        if end in inserts:
+                            inserts[end] += ')'
+                        else:
+                            inserts[end] = ')'
                     for i in range(start + 1, end):
                         inserts[i] = '|'
 
index bfe346bba8e3d75217914f0a1b2930f6b85d8c65..1bc6b38da8d5aefaec1ab220d410952e2dfd630c 100644 (file)
@@ -93,26 +93,35 @@ def literal_eval(node_or_string):
 
 def dump(node, annotate_fields=True, include_attributes=False):
     """
-    Return a formatted dump of the tree in *node*.  This is mainly useful for
-    debugging purposes.  The returned string will show the names and the values
-    for fields.  This makes the code impossible to evaluate, so if evaluation is
-    wanted *annotate_fields* must be set to False.  Attributes such as line
+    Return a formatted dump of the tree in node.  This is mainly useful for
+    debugging purposes.  If annotate_fields is true (by default),
+    the returned string will show the names and the values for fields.
+    If annotate_fields is false, the result string will be more compact by
+    omitting unambiguous field names.  Attributes such as line
     numbers and column offsets are not dumped by default.  If this is wanted,
-    *include_attributes* can be set to True.
+    include_attributes can be set to true.
     """
     def _format(node):
         if isinstance(node, AST):
-            fields = [(a, _format(b)) for a, b in iter_fields(node)]
-            rv = '%s(%s' % (node.__class__.__name__, ', '.join(
-                ('%s=%s' % field for field in fields)
-                if annotate_fields else
-                (b for a, b in fields)
-            ))
+            args = []
+            keywords = annotate_fields
+            for field in node._fields:
+                try:
+                    value = getattr(node, field)
+                except AttributeError:
+                    keywords = True
+                else:
+                    if keywords:
+                        args.append('%s=%s' % (field, _format(value)))
+                    else:
+                        args.append(_format(value))
             if include_attributes and node._attributes:
-                rv += fields and ', ' or ' '
-                rv += ', '.join('%s=%s' % (a, _format(getattr(node, a)))
-                                for a in node._attributes)
-            return rv + ')'
+                for a in node._attributes:
+                    try:
+                        args.append('%s=%s' % (a, _format(getattr(node, a))))
+                    except AttributeError:
+                        pass
+            return '%s(%s)' % (node.__class__.__name__, ', '.join(args))
         elif isinstance(node, list):
             return '[%s]' % ', '.join(_format(x) for x in node)
         return repr(node)
index e4e632206af1bc5411094d51de533201feabe25f..e8a6a1beeab9b0260975292d1f33e4eb75bd5e97 100644 (file)
@@ -630,9 +630,9 @@ class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):
         self._local = self._Local()
 
     def get_event_loop(self):
-        """Get the event loop.
+        """Get the event loop for the current context.
 
-        This may be None or an instance of EventLoop.
+        Returns an instance of EventLoop or raises an exception.
         """
         if (self._local._loop is None and
                 not self._local._set_called and
index 5fbab03dd001ac5ff1890a22b8f486cccae8cb4b..2e37e18b45fc150536f6deedfc388c30e8aa6410 100644 (file)
@@ -6,7 +6,7 @@ from . import tasks
 
 
 def run(main, *, debug=False):
-    """Run a coroutine.
+    """Execute the coroutine and return the result.
 
     This function runs the passed coroutine, taking care of
     managing the asyncio event loop and finalizing asynchronous
index a0fc996d23a0de7fe34132214e6e8057bfa0db40..7034fc28d3e1ea3f64e68cf13c73ed11e401d107 100644 (file)
@@ -431,6 +431,7 @@ class _UnixReadPipeTransport(transports.ReadTransport):
         self._fileno = pipe.fileno()
         self._protocol = protocol
         self._closing = False
+        self._paused = False
 
         mode = os.fstat(self._fileno).st_mode
         if not (stat.S_ISFIFO(mode) or
@@ -492,10 +493,20 @@ class _UnixReadPipeTransport(transports.ReadTransport):
                 self._loop.call_soon(self._call_connection_lost, None)
 
     def pause_reading(self):
+        if self._closing or self._paused:
+            return
+        self._paused = True
         self._loop._remove_reader(self._fileno)
+        if self._loop.get_debug():
+            logger.debug("%r pauses reading", self)
 
     def resume_reading(self):
+        if self._closing or not self._paused:
+            return
+        self._paused = False
         self._loop._add_reader(self._fileno, self._read_ready)
+        if self._loop.get_debug():
+            logger.debug("%r resumes reading", self)
 
     def set_protocol(self, protocol):
         self._protocol = protocol
index 8cf668718ded35d296b717cfedf2659a0ef4febb..df84f1fe69cfb9cfb9a05dff94396c6fb2489a8e 100755 (executable)
@@ -478,7 +478,7 @@ class FieldStorage:
             if maxlen and clen > maxlen:
                 raise ValueError('Maximum content length exceeded')
         self.length = clen
-        if self.limit is None and clen:
+        if self.limit is None and clen >= 0:
             self.limit = clen
 
         self.list = self.file = None
@@ -659,8 +659,10 @@ class FieldStorage:
             if 'content-length' in headers:
                 del headers['content-length']
 
+            limit = None if self.limit is None \
+                else self.limit - self.bytes_read
             part = klass(self.fp, headers, ib, environ, keep_blank_values,
-                         strict_parsing,self.limit-self.bytes_read,
+                         strict_parsing, limit,
                          self.encoding, self.errors, max_num_fields)
 
             if max_num_fields is not None:
@@ -751,7 +753,7 @@ class FieldStorage:
         last_line_lfend = True
         _read = 0
         while 1:
-            if _read >= self.limit:
+            if self.limit is not None and _read >= self.limit:
                 break
             line = self.fp.readline(1<<16) # bytes
             self.bytes_read += len(line)
index 64bbee8faba8978f2fed8fdd693572b4d96885e9..d353ff2b6f127b7deff9370df7b81feb9eef9fff 100644 (file)
@@ -47,8 +47,8 @@ def __getattr__(name):
         obj = getattr(_collections_abc, name)
         import warnings
         warnings.warn("Using or importing the ABCs from 'collections' instead "
-                      "of from 'collections.abc' is deprecated"
-                      "and in 3.8 it will stop working",
+                      "of from 'collections.abc' is deprecated since Python 3.3,"
+                      "and in 3.9 it will stop working",
                       DeprecationWarning, stacklevel=2)
         globals()[name] = obj
         return obj
@@ -444,7 +444,7 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non
         '__slots__': (),
         '_fields': field_names,
         '_field_defaults': field_defaults,
-        # alternate spelling for backward compatiblity
+        # alternate spelling for backward compatibility
         '_fields_defaults': field_defaults,
         '__new__': __new__,
         '_make': _make,
index d1ea43bc7e3b6f172ae3b716b826afc6f90545b2..d8d6c657928bfc60340fbae46d53ec6ca5fb6cc0 100644 (file)
@@ -1,3 +1,5 @@
+import platform
+import sys
 import unittest
 from ctypes import *
 from ctypes.test import need_symbol
@@ -438,6 +440,97 @@ class StructureTestCase(unittest.TestCase):
         self.assertEqual(s.first, got.first)
         self.assertEqual(s.second, got.second)
 
+    def test_array_in_struct(self):
+        # See bpo-22273
+
+        # These should mirror the structures in Modules/_ctypes/_ctypes_test.c
+        class Test2(Structure):
+            _fields_ = [
+                ('data', c_ubyte * 16),
+            ]
+
+        class Test3(Structure):
+            _fields_ = [
+                ('data', c_double * 2),
+            ]
+
+        class Test3A(Structure):
+            _fields_ = [
+                ('data', c_float * 2),
+            ]
+
+        class Test3B(Test3A):
+            _fields_ = [
+                ('more_data', c_float * 2),
+            ]
+
+        s = Test2()
+        expected = 0
+        for i in range(16):
+            s.data[i] = i
+            expected += i
+        dll = CDLL(_ctypes_test.__file__)
+        func = dll._testfunc_array_in_struct1
+        func.restype = c_int
+        func.argtypes = (Test2,)
+        result = func(s)
+        self.assertEqual(result, expected)
+        # check the passed-in struct hasn't changed
+        for i in range(16):
+            self.assertEqual(s.data[i], i)
+
+        s = Test3()
+        s.data[0] = 3.14159
+        s.data[1] = 2.71828
+        expected = 3.14159 + 2.71828
+        func = dll._testfunc_array_in_struct2
+        func.restype = c_double
+        func.argtypes = (Test3,)
+        result = func(s)
+        self.assertEqual(result, expected)
+        # check the passed-in struct hasn't changed
+        self.assertEqual(s.data[0], 3.14159)
+        self.assertEqual(s.data[1], 2.71828)
+
+        s = Test3B()
+        s.data[0] = 3.14159
+        s.data[1] = 2.71828
+        s.more_data[0] = -3.0
+        s.more_data[1] = -2.0
+
+        expected = 3.14159 + 2.71828 - 5.0
+        func = dll._testfunc_array_in_struct2a
+        func.restype = c_double
+        func.argtypes = (Test3B,)
+        result = func(s)
+        self.assertAlmostEqual(result, expected, places=6)
+        # check the passed-in struct hasn't changed
+        self.assertAlmostEqual(s.data[0], 3.14159, places=6)
+        self.assertAlmostEqual(s.data[1], 2.71828, places=6)
+        self.assertAlmostEqual(s.more_data[0], -3.0, places=6)
+        self.assertAlmostEqual(s.more_data[1], -2.0, places=6)
+
+    def test_38368(self):
+        class U(Union):
+            _fields_ = [
+                ('f1', c_uint8 * 16),
+                ('f2', c_uint16 * 8),
+                ('f3', c_uint32 * 4),
+            ]
+        u = U()
+        u.f3[0] = 0x01234567
+        u.f3[1] = 0x89ABCDEF
+        u.f3[2] = 0x76543210
+        u.f3[3] = 0xFEDCBA98
+        f1 = [u.f1[i] for i in range(16)]
+        f2 = [u.f2[i] for i in range(8)]
+        if sys.byteorder == 'little':
+            self.assertEqual(f1, [0x67, 0x45, 0x23, 0x01,
+                                  0xef, 0xcd, 0xab, 0x89,
+                                  0x10, 0x32, 0x54, 0x76,
+                                  0x98, 0xba, 0xdc, 0xfe])
+            self.assertEqual(f2, [0x4567, 0x0123, 0xcdef, 0x89ab,
+                                  0x3210, 0x7654, 0xba98, 0xfedc])
 
 class PointerMemberTestCase(unittest.TestCase):
 
index 325b822d9f06f110127e252015d6cc80c95899a0..33e26460c74ea66dc90a6b9409db9e746319a2f6 100644 (file)
@@ -1011,13 +1011,14 @@ def fields(class_or_instance):
 
 def _is_dataclass_instance(obj):
     """Returns True if obj is an instance of a dataclass."""
-    return not isinstance(obj, type) and hasattr(obj, _FIELDS)
+    return hasattr(type(obj), _FIELDS)
 
 
 def is_dataclass(obj):
     """Returns True if obj is a dataclass or an instance of a
     dataclass."""
-    return hasattr(obj, _FIELDS)
+    cls = obj if isinstance(obj, type) else type(obj)
+    return hasattr(cls, _FIELDS)
 
 
 def asdict(obj, *, dict_factory=dict):
@@ -1185,7 +1186,7 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
             raise TypeError(f'Invalid field: {item!r}')
 
         if not isinstance(name, str) or not name.isidentifier():
-            raise TypeError(f'Field names must be valid identifers: {name!r}')
+            raise TypeError(f'Field names must be valid identifiers: {name!r}')
         if keyword.iskeyword(name):
             raise TypeError(f'Field names must not be keywords: {name!r}')
         if name in seen:
@@ -1202,7 +1203,7 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
                      unsafe_hash=unsafe_hash, frozen=frozen)
 
 
-def replace(obj, **changes):
+def replace(*args, **changes):
     """Return a new object replacing specified fields with new values.
 
     This is especially useful for frozen classes.  Example usage:
@@ -1216,6 +1217,14 @@ def replace(obj, **changes):
       c1 = replace(c, x=3)
       assert c1.x == 3 and c1.y == 2
       """
+    if len(args) > 1:
+        raise TypeError(f'replace() takes 1 positional argument but {len(args)} were given')
+    if args:
+        obj, = args
+    elif 'obj' in changes:
+        obj = changes.pop('obj')
+    else:
+        raise TypeError("replace() missing 1 required positional argument: 'obj'")
 
     # We're going to mutate 'changes', but that's okay because it's a
     # new dict, even if called with 'replace(obj, **my_changes)'.
index a964b202e3c7a9856c46014fd98fb5f11d9b93d6..5a2ee6a2035a0720fe22b6813123c99c3b3eadb1 100644 (file)
@@ -718,31 +718,31 @@ class timedelta:
         if isinstance(other, timedelta):
             return self._cmp(other) == 0
         else:
-            return False
+            return NotImplemented
 
     def __le__(self, other):
         if isinstance(other, timedelta):
             return self._cmp(other) <= 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def __lt__(self, other):
         if isinstance(other, timedelta):
             return self._cmp(other) < 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def __ge__(self, other):
         if isinstance(other, timedelta):
             return self._cmp(other) >= 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def __gt__(self, other):
         if isinstance(other, timedelta):
             return self._cmp(other) > 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def _cmp(self, other):
         assert isinstance(other, timedelta)
@@ -1261,31 +1261,31 @@ class time:
         if isinstance(other, time):
             return self._cmp(other, allow_mixed=True) == 0
         else:
-            return False
+            return NotImplemented
 
     def __le__(self, other):
         if isinstance(other, time):
             return self._cmp(other) <= 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def __lt__(self, other):
         if isinstance(other, time):
             return self._cmp(other) < 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def __ge__(self, other):
         if isinstance(other, time):
             return self._cmp(other) >= 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def __gt__(self, other):
         if isinstance(other, time):
             return self._cmp(other) > 0
         else:
-            _cmperror(self, other)
+            return NotImplemented
 
     def _cmp(self, other, allow_mixed=False):
         assert isinstance(other, time)
@@ -2167,9 +2167,9 @@ class timezone(tzinfo):
         return (self._offset, self._name)
 
     def __eq__(self, other):
-        if type(other) != timezone:
-            return False
-        return self._offset == other._offset
+        if isinstance(other, timezone):
+            return self._offset == other._offset
+        return NotImplemented
 
     def __hash__(self):
         return hash(self._offset)
@@ -2226,7 +2226,7 @@ class timezone(tzinfo):
         raise TypeError("fromutc() argument must be a datetime instance"
                         " or None")
 
-    _maxoffset = timedelta(hours=23, minutes=59)
+    _maxoffset = timedelta(hours=24, microseconds=-1)
     _minoffset = -_maxoffset
 
     @staticmethod
@@ -2250,8 +2250,11 @@ class timezone(tzinfo):
         return f'UTC{sign}{hours:02d}:{minutes:02d}'
 
 timezone.utc = timezone._create(timedelta(0))
-timezone.min = timezone._create(timezone._minoffset)
-timezone.max = timezone._create(timezone._maxoffset)
+# bpo-37642: These attributes are rounded to the nearest minute for backwards
+# compatibility, even though the constructor will accept a wider range of
+# values. This may change in the future.
+timezone.min = timezone._create(-timedelta(hours=23, minutes=59))
+timezone.max = timezone._create(timedelta(hours=23, minutes=59))
 _EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc)
 
 # Some time zone algebra.  For a datetime x, let
index 58b20a2102473394a64b627de3339da2e6cc5fe4..26112b481af3d5f7132f7b221eeae4593f6859f7 100644 (file)
@@ -95,7 +95,7 @@ def _find_vcvarsall(plat_spec):
     vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86'
     if best_dir:
         vcredist = os.path.join(best_dir, "..", "..", "redist", "MSVC", "**",
-            "Microsoft.VC141.CRT", "vcruntime140.dll")
+            vcruntime_plat, "Microsoft.VC14*.CRT", "vcruntime140.dll")
         try:
             import glob
             vcruntime = glob.glob(vcredist, recursive=True)[-1]
index b71d1d39bcda87227165df1c33c925146d6d5807..b70e5e4b5f039fd48f897a80db428d32ab07be7c 100644 (file)
@@ -781,8 +781,9 @@ class CCompiler:
             for incl in includes:
                 f.write("""#include "%s"\n""" % incl)
             f.write("""\
-main (int argc, char **argv) {
+int main (int argc, char **argv) {
     %s();
+    return 0;
 }
 """ % funcname)
         finally:
index fde56754e8916e1943087cd56358d22d388bfec0..15434c3a98983553286e64412fc501475fa834ea 100644 (file)
@@ -55,6 +55,9 @@ class bdist_wininst(Command):
     boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
                        'skip-build']
 
+    # bpo-10945: bdist_wininst requires mbcs encoding only available on Windows
+    _unsupported = (sys.platform != "win32")
+
     def initialize_options(self):
         self.bdist_dir = None
         self.plat_name = None
index fc00b4a098cbbd59d2e01613f72d13adced4e875..7cc9a4672601fe2ed8423ede52a7f9dc06f7b011 100644 (file)
@@ -566,6 +566,8 @@ class DisplayName(Phrase):
     @property
     def display_name(self):
         res = TokenList(self)
+        if len(res) == 0:
+            return res.value
         if res[0].token_type == 'cfws':
             res.pop(0)
         else:
@@ -587,7 +589,7 @@ class DisplayName(Phrase):
             for x in self:
                 if x.token_type == 'quoted-string':
                     quote = True
-        if quote:
+        if len(self) != 0 and quote:
             pre = post = ''
             if self[0].token_type=='cfws' or self[0][0].token_type=='cfws':
                 pre = ' '
@@ -931,6 +933,10 @@ class EWWhiteSpaceTerminal(WhiteSpaceTerminal):
         return ''
 
 
+class _InvalidEwError(errors.HeaderParseError):
+    """Invalid encoded word found while parsing headers."""
+
+
 # XXX these need to become classes and used as instances so
 # that a program can't change them in a parse tree and screw
 # up other parse trees.  Maybe should have  tests for that, too.
@@ -1035,7 +1041,10 @@ def get_encoded_word(value):
         raise errors.HeaderParseError(
             "expected encoded word but found {}".format(value))
     remstr = ''.join(remainder)
-    if len(remstr) > 1 and remstr[0] in hexdigits and remstr[1] in hexdigits:
+    if (len(remstr) > 1 and
+        remstr[0] in hexdigits and
+        remstr[1] in hexdigits and
+        tok.count('?') < 2):
         # The ? after the CTE was followed by an encoded word escape (=XX).
         rest, *remainder = remstr.split('?=', 1)
         tok = tok + '?=' + rest
@@ -1047,7 +1056,7 @@ def get_encoded_word(value):
     try:
         text, charset, lang, defects = _ew.decode('=?' + tok + '?=')
     except ValueError:
-        raise errors.HeaderParseError(
+        raise _InvalidEwError(
             "encoded word format invalid: '{}'".format(ew.cte))
     ew.charset = charset
     ew.lang = lang
@@ -1097,9 +1106,12 @@ def get_unstructured(value):
             token, value = get_fws(value)
             unstructured.append(token)
             continue
+        valid_ew = True
         if value.startswith('=?'):
             try:
                 token, value = get_encoded_word(value)
+            except _InvalidEwError:
+                valid_ew = False
             except errors.HeaderParseError:
                 # XXX: Need to figure out how to register defects when
                 # appropriate here.
@@ -1121,7 +1133,10 @@ def get_unstructured(value):
         # Split in the middle of an atom if there is a rfc2047 encoded word
         # which does not have WSP on both sides. The defect will be registered
         # the next time through the loop.
-        if rfc2047_matcher.search(tok):
+        # This needs to only be performed when the encoded word is valid;
+        # otherwise, performing it on an invalid encoded word can cause
+        # the parser to go in an infinite loop.
+        if valid_ew and rfc2047_matcher.search(tok):
             tok, *remainder = value.partition('=?')
         vtext = ValueTerminal(tok, 'vtext')
         _validate_xtext(vtext)
@@ -1189,7 +1204,7 @@ def get_bare_quoted_string(value):
             "expected '\"' but found '{}'".format(value))
     bare_quoted_string = BareQuotedString()
     value = value[1:]
-    if value[0] == '"':
+    if value and value[0] == '"':
         token, value = get_qcontent(value)
         bare_quoted_string.append(token)
     while value and value[0] != '"':
@@ -1358,6 +1373,9 @@ def get_word(value):
         leader, value = get_cfws(value)
     else:
         leader = None
+    if not value:
+        raise errors.HeaderParseError(
+            "Expected 'atom' or 'quoted-string' but found nothing.")
     if value[0]=='"':
         token, value = get_quoted_string(value)
     elif value[0] in SPECIALS:
@@ -1582,6 +1600,8 @@ def get_domain(value):
         token, value = get_dot_atom(value)
     except errors.HeaderParseError:
         token, value = get_atom(value)
+    if value and value[0] == '@':
+        raise errors.HeaderParseError('Invalid Domain')
     if leader is not None:
         token[:0] = [leader]
     domain.append(token)
@@ -2387,6 +2407,9 @@ def get_parameter(value):
         while value:
             if value[0] in WSP:
                 token, value = get_fws(value)
+            elif value[0] == '"':
+                token = ValueTerminal('"', 'DQUOTE')
+                value = value[1:]
             else:
                 token, value = get_qcontent(value)
             v.append(token)
@@ -2627,6 +2650,9 @@ def _refold_parse_tree(parse_tree, *, policy):
             wrap_as_ew_blocked -= 1
             continue
         tstr = str(part)
+        if part.token_type == 'ptext' and set(tstr) & SPECIALS:
+            # Encode if tstr contains special characters.
+            want_encoding = True
         try:
             tstr.encode(encoding)
             charset = encoding
@@ -2737,15 +2763,22 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset):
         trailing_wsp = to_encode[-1]
         to_encode = to_encode[:-1]
     new_last_ew = len(lines[-1]) if last_ew is None else last_ew
+
+    encode_as = 'utf-8' if charset == 'us-ascii' else charset
+
+    # The RFC2047 chrome takes up 7 characters plus the length
+    # of the charset name.
+    chrome_len = len(encode_as) + 7
+
+    if (chrome_len + 1) >= maxlen:
+        raise errors.HeaderParseError(
+            "max_line_length is too small to fit an encoded word")
+
     while to_encode:
         remaining_space = maxlen - len(lines[-1])
-        # The RFC2047 chrome takes up 7 characters plus the length
-        # of the charset name.
-        encode_as = 'utf-8' if charset == 'us-ascii' else charset
-        text_space = remaining_space - len(encode_as) - 7
+        text_space = remaining_space - chrome_len
         if text_space <= 0:
             lines.append(' ')
-            # XXX We'll get an infinite loop here if maxlen is <= 7
             continue
 
         to_encode_word = to_encode[:text_space]
index cdfa3729adc79efa0b8fc2cf972a76f301c24fdb..41ff6f8c000d57d23445fa529b33297b1ffa07fc 100644 (file)
@@ -379,7 +379,12 @@ class AddrlistClass:
         aslist.append('@')
         self.pos += 1
         self.gotonext()
-        return EMPTYSTRING.join(aslist) + self.getdomain()
+        domain = self.getdomain()
+        if not domain:
+            # Invalid domain, return an empty address instead of returning a
+            # local part to denote failed parsing.
+            return EMPTYSTRING
+        return EMPTYSTRING.join(aslist) + domain
 
     def getdomain(self):
         """Get the complete domain name from an address."""
@@ -394,6 +399,10 @@ class AddrlistClass:
             elif self.field[self.pos] == '.':
                 self.pos += 1
                 sdlist.append('.')
+            elif self.field[self.pos] == '@':
+                # bpo-34155: Don't parse domains with two `@` like
+                # `a@malicious.org@important.com`.
+                return EMPTYSTRING
             elif self.field[self.pos] in self.atomends:
                 break
             else:
index 00652049f2fa2fc5ca53769f87b523d551ecc23b..0218cbfbd098d4e62df373890e2e552d1572f062 100644 (file)
@@ -245,7 +245,7 @@ class BaseHeader(str):
         the header name and the ': ' separator.
 
         """
-        # At some point we need to put fws here iif it was in the source.
+        # At some point we need to put fws here if it was in the source.
         header = parser.Header([
             parser.HeaderLabel([
                 parser.ValueTerminal(self.name, 'header-name'),
index b6512f2198af43fcdde27d5559fad50d3853d81c..12626026179608e198e079d69d56dbd94c594004 100644 (file)
@@ -1041,7 +1041,16 @@ class MIMEPart(Message):
         maintype, subtype = self.get_content_type().split('/')
         if maintype != 'multipart' or subtype == 'alternative':
             return
-        parts = self.get_payload().copy()
+        payload = self.get_payload()
+        # Certain malformed messages can have content type set to `multipart/*`
+        # but still have single part body, in which case payload.copy() can
+        # fail with AttributeError.
+        try:
+            parts = payload.copy()
+        except AttributeError:
+            # payload is not a list, it is most probably a string.
+            return
+
         if maintype == 'multipart' and subtype == 'related':
             # For related, we treat everything but the root as an attachment.
             # The root may be indicated by 'start'; if there's no start or we
index 555b17256061942e9fe29c5ffa87303e18bc4e52..7db4da1ff081c1c66c1f0224d7543e68aa3b89a5 100644 (file)
@@ -13,7 +13,6 @@ from email.feedparser import FeedParser, BytesFeedParser
 from email._policybase import compat32
 
 
-\f
 class Parser:
     def __init__(self, _class=None, *, policy=compat32):
         """Parser of RFC 2822 and MIME email messages.
index 526dfd004a41d8daa7492de7a56ddad9627b638b..7a0d3ee0db946fc022f6a460d0882fbf7f42c053 100644 (file)
@@ -8,9 +8,9 @@ import tempfile
 __all__ = ["version", "bootstrap"]
 
 
-_SETUPTOOLS_VERSION = "40.8.0"
+_SETUPTOOLS_VERSION = "41.2.0"
 
-_PIP_VERSION = "19.0.3"
+_PIP_VERSION = "19.2.3"
 
 _PROJECTS = [
     ("setuptools", _SETUPTOOLS_VERSION),
diff --git a/Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl
deleted file mode 100644 (file)
index 24f247c..0000000
Binary files a/Lib/ensurepip/_bundled/pip-19.0.3-py2.py3-none-any.whl and /dev/null differ
diff --git a/Lib/ensurepip/_bundled/pip-19.2.3-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-19.2.3-py2.py3-none-any.whl
new file mode 100644 (file)
index 0000000..8118df8
Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-19.2.3-py2.py3-none-any.whl differ
diff --git a/Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl
deleted file mode 100644 (file)
index fdc66e9..0000000
Binary files a/Lib/ensurepip/_bundled/setuptools-40.8.0-py2.py3-none-any.whl and /dev/null differ
diff --git a/Lib/ensurepip/_bundled/setuptools-41.2.0-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-41.2.0-py2.py3-none-any.whl
new file mode 100644 (file)
index 0000000..82df6f6
Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-41.2.0-py2.py3-none-any.whl differ
index 5e97a9e8d810c1b77df7ece149c1f6348951ea11..d0b03b4aa56ce4713356d0f23aa91293aaaf999a 100644 (file)
@@ -682,7 +682,7 @@ class Flag(Enum):
         Generate the next value when not given.
 
         name: the name of the member
-        start: the initital start value or None
+        start: the initial start value or None
         count: the number of existing members
         last_value: the last value assigned or None
         """
index 1daa1d1775911afd4267330e989758e4456bc134..badaa826af9e2a9226a639dc7cf43b346286a507 100644 (file)
@@ -471,7 +471,7 @@ def lru_cache(maxsize=128, typed=False):
     with f.cache_info().  Clear the cache and statistics with f.cache_clear().
     Access the underlying function with f.__wrapped__.
 
-    See:  http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
+    See:  http://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
 
     """
 
index 303b3b349a9f408c901bad8c569244343c125a8e..85f4a57582f2a2d9f28b2a851f11a0e96a6bb6aa 100644 (file)
@@ -92,7 +92,11 @@ def samestat(s1, s2):
 
 # Are two filenames really pointing to the same file?
 def samefile(f1, f2):
-    """Test whether two pathnames reference the same actual file"""
+    """Test whether two pathnames reference the same actual file or directory
+
+    This is determined by the device number and i-node number and
+    raises an exception if an os.stat() call on either pathname fails.
+    """
     s1 = os.stat(f1)
     s2 = os.stat(f2)
     return samestat(s1, s2)
index aed94a5850467721035ac1c65dafca83f8d6455a..e14a1eb074c5937cf176f7401db5c4cc088b9c57 100644 (file)
@@ -59,7 +59,7 @@ class HTTPStatus(IntEnum):
     TEMPORARY_REDIRECT = (307, 'Temporary Redirect',
         'Object moved temporarily -- see URI list')
     PERMANENT_REDIRECT = (308, 'Permanent Redirect',
-        'Object moved temporarily -- see URI list')
+        'Object moved permanently -- see URI list')
 
     # client error
     BAD_REQUEST = (400, 'Bad Request',
index dd23edcd597c310931bb03f85fc9fba7804d1441..f7a183c77403203627da40fd44e052f08c4c2179 100644 (file)
@@ -1107,19 +1107,15 @@ class HTTPConnection:
         else:
             raise CannotSendRequest(self.__state)
 
-        # Save the method we use, we need it later in the response phase
+        # Save the method for use later in the response phase
         self._method = method
-        if not url:
-            url = '/'
-        # Prevent CVE-2019-9740.
-        match = _contains_disallowed_url_pchar_re.search(url)
-        if match:
-            raise InvalidURL(f"URL can't contain control characters. {url!r} "
-                             f"(found at least {match.group()!r})")
+
+        url = url or '/'
+        self._validate_path(url)
+
         request = '%s %s %s' % (method, url, self._http_vsn_str)
 
-        # Non-ASCII characters should have been eliminated earlier
-        self._output(request.encode('ascii'))
+        self._output(self._encode_request(request))
 
         if self._http_vsn == 11:
             # Issue some standard headers for better HTTP/1.1 compliance
@@ -1197,6 +1193,18 @@ class HTTPConnection:
             # For HTTP/1.0, the server will assume "not chunked"
             pass
 
+    def _encode_request(self, request):
+        # ASCII also helps prevent CVE-2019-9740.
+        return request.encode('ascii')
+
+    def _validate_path(self, url):
+        """Validate a url for putrequest."""
+        # Prevent CVE-2019-9740.
+        match = _contains_disallowed_url_pchar_re.search(url)
+        if match:
+            raise InvalidURL(f"URL can't contain control characters. {url!r} "
+                             f"(found at least {match.group()!r})")
+
     def putheader(self, header, *values):
         """Send a request header line to the server.
 
index d63544a5f52e2325a77d1f5434e4ff9bea10f6f0..1bed893b1e2666ed9a51f4b96b11d4799c2f290c 100644 (file)
@@ -1590,6 +1590,7 @@ class CookieJar:
         headers = response.info()
         rfc2965_hdrs = headers.get_all("Set-Cookie2", [])
         ns_hdrs = headers.get_all("Set-Cookie", [])
+        self._policy._now = self._now = int(time.time())
 
         rfc2965 = self._policy.rfc2965
         netscape = self._policy.netscape
@@ -1669,8 +1670,6 @@ class CookieJar:
         _debug("extract_cookies: %s", response.info())
         self._cookies_lock.acquire()
         try:
-            self._policy._now = self._now = int(time.time())
-
             for cookie in self.make_cookies(response, request):
                 if self._policy.set_ok(cookie, request):
                     _debug(" setting cookie: %s", cookie)
index 42227b60e7ae7c542e202e168336c194b0cffd47..32fda8c75bb8f3c2fc58cb6a75c050a71f655b66 100644 (file)
@@ -1,12 +1,87 @@
+What's New in IDLE 3.7.5
+Released on 2019-09-30?
+======================================
+
+bpo-35379: When exiting IDLE, catch any AttributeError.  One happens
+when EditorWindow.close is called twice.  Printing a traceback, when
+IDLE is run from a terminal, is useless and annoying.
+
+bpo-38183: To avoid test issues, test_idle ignores the user config
+directory.  It no longer tries to create or access .idlerc or any files
+within.  Users must run IDLE to discover problems with saving settings.
+
+bpo-38077: IDLE no longer adds 'argv' to the user namespace when
+initializing it.  This bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4.
+
+bpo-38401: Shell restart lines now fill the window width, always start
+with '=', and avoid wrapping unnecessarily. The line will still wrap
+if the included file name is long relative to the width.
+
+bpo-37092: Add mousewheel scrolling for IDLE module, path, and stack
+browsers.  Patch by George Zhang.
+
+bpo-35771: To avoid occasional spurious test_idle failures on slower
+machines, increase the ``hover_delay`` in test_tooltip.
+
+bpo-37824: Properly handle user input warnings in IDLE shell.
+Cease turning SyntaxWarnings into SyntaxErrors.
+
+bpo-37929: IDLE Settings dialog now closes properly when there is no
+shell window.
+
+bpo-37849: Fix completions list appearing too high or low when shown
+above the current line.
+
+bpo-36419: Refactor autocompete and improve testing.
+
+bpo-37748: Reorder the Run menu.  Put the most common choice,
+Run Module, at the top.
+
+bpo-37692: Improve highlight config sample with example shell
+interaction and better labels for shell elements.
+
+bpo-37628: Settings dialog no longer expands with font size.
+The font and highlight sample boxes gain scrollbars instead.
+
+bpo-17535: Add optional line numbers for IDLE editor windows.
+
+bpo-37627: Initialize the Customize Run dialog with the command line
+arguments most recently entered before.  The user can optionally edit
+before submitting them.
+
+bpo-33610: Code context always shows the correct context when toggled on.
+
+bpo-36390: Gather Format menu functions into format.py.  Combine
+paragraph.py, rstrip.py, and format methods from editor.py.
+
+bpo-37530: Optimize code context to reduce unneeded background activity.
+Font and highlight changes now occur along with text changes instead
+of after a random delay.
+
+bpo-27452: Cleanup config.py by inlining RemoveFile and simplifying
+the handling of __file__ in CreateConfigHandlers/
+
+
 What's New in IDLE 3.7.4
-Released on 2019-06-24?
+Released on 2019-07-08
 ======================================
 
+bpo-26806: To compensate for stack frames added by IDLE and avoid
+possible problems with low recursion limits, add 30 to limits in the
+user code execution process.  Subtract 30 when reporting recursion
+limits to make this addition mostly transparent.
+
+bpo-37325: Fix tab focus traversal order for help source and custom
+run dialogs.
 
 bpo-37321: Both subprocess connection error messages now refer to
 the 'Startup failure' section of the IDLE doc.
 
-bpo-37039: Adjust "Zoom Height" to individual screens by momemtarily
+bpo-37177: Properly attach search dialogs to their main window so
+that they behave like other dialogs and do not get hidden behind
+their main window.
+
+bpo-37039: Adjust "Zoom Height" to individual screens by momentarily
 maximizing the window on first use with a particular screen.  Changing
 screen settings may invalidate the saved height.  While a window is
 maximized, "Zoom Height" has no effect.
@@ -14,6 +89,10 @@ maximized, "Zoom Height" has no effect.
 bpo-35763: Make calltip reminder about '/' meaning positional-only less
 obtrusive by only adding it when there is room on the first line.
 
+bpo-5680: Add 'Run Customized' to the Run menu to run a module with
+customized settings. Any command line arguments entered are added
+to sys.argv. One can suppress the normal Shell main module restart.
+
 bpo-35610: Replace now redundant editor.context_use_ps1 with
 .prompt_last_line.  This finishes change started in bpo-31858.
 
@@ -58,6 +137,9 @@ None or False since 2007.
 
 bpo-36096: Make colorizer state variables instance-only.
 
+bpo-32129: Avoid blurry IDLE application icon on macOS with Tk 8.6.
+Patch by Kevin Walzer.
+
 bpo-24310: Document settings dialog font tab sample.
 
 bpo-35689: Add docstrings and tests for colorizer.
index c784a1a0b6133bfaaad1045fc1eb16db36ea7906..48a1f4a425c9e374274f653da7b8abe33f182a55 100644 (file)
@@ -68,7 +68,7 @@ pyshell.py        # Start IDLE, manage shell, complete editor window
 query.py          # Query user for information
 redirector.py     # Intercept widget subcommands (for percolator) (nim).
 replace.py        # Search and replace pattern in text.
-rpc.py            # Commuicate between idle and user processes (nim).
+rpc.py            # Communicate between idle and user processes (nim).
 rstrip.py         # Strip trailing whitespace.
 run.py            # Manage user code execution subprocess.
 runscript.py      # Check and run user code.
@@ -80,7 +80,7 @@ stackviewer.py    # View stack after exception.
 statusbar.py      # Define status bar for windows (nim).
 tabbedpages.py    # Define tabbed pages widget (nim).
 textview.py       # Define read-only text widget (nim).
-tree.py           # Define tree widger, used in browsers (nim).
+tree.py           # Define tree widget, used in browsers (nim).
 undo.py           # Manage undo stack.
 windows.py        # Manage window list and define listed top level.
 zoomheight.py     # Zoom window to full height of screen.
@@ -97,7 +97,7 @@ 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
+README.txt   # this file, displayed by About IDLE
 TODO.txt     # needs review
 extend.txt   # about writing extensions
 help.html    # copy of idle.html in docs, displayed by IDLE Help
@@ -115,7 +115,7 @@ tooltip.py # unused
 
 IDLE MENUS
 Top level items and most submenu items are defined in mainmenu.
-Extenstions add submenu items when active.  The names given are
+Extensions add submenu items when active.  The names given are
 found, quoted, in one of these modules, paired with a '<<pseudoevent>>'.
 Each pseudoevent is bound to an event handler.  Some event handlers
 call another function that does the actual work.  The annotations below
@@ -166,7 +166,7 @@ Shell  # pyshell
 
 Debug (Shell only)
   Go to File/Line
-  debugger         # debugger, debugger_r, PyShell.toggle_debuger
+  debugger         # debugger, debugger_r, PyShell.toggle_debugger
   Stack Viewer     # stackviewer, PyShell.open_stack_viewer
   Auto-open Stack Viewer  # stackviewer
 
index e20b757d871043942e32eb06d1365c5b48404646..c623d45a1534230658602db394c390f1c5e419fa 100644 (file)
@@ -8,42 +8,45 @@ import os
 import string
 import sys
 
-# These constants represent the two different types of completions.
-# They must be defined here so autocomple_w can import them.
-COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1)
-
+# Two types of completions; defined here for autocomplete_w import below.
+ATTRS, FILES = 0, 1
 from idlelib import autocomplete_w
 from idlelib.config import idleConf
 from idlelib.hyperparser import HyperParser
 
+# Tuples passed to open_completions.
+#       EvalFunc, Complete, WantWin, Mode
+FORCE = True,     False,    True,    None   # Control-Space.
+TAB   = False,    True,     True,    None   # Tab.
+TRY_A = False,    False,    False,   ATTRS  # '.' for attributes.
+TRY_F = False,    False,    False,   FILES  # '/' in quotes for file name.
+
 # This string includes all chars that may be in an identifier.
 # TODO Update this here and elsewhere.
 ID_CHARS = string.ascii_letters + string.digits + "_"
 
-SEPS = os.sep
-if os.altsep:  # e.g. '/' on Windows...
-    SEPS += os.altsep
-
+SEPS = f"{os.sep}{os.altsep if os.altsep else ''}"
+TRIGGERS = f".{SEPS}"
 
 class AutoComplete:
 
     def __init__(self, editwin=None):
         self.editwin = editwin
-        if editwin is not None:   # not in subprocess or test
+        if editwin is not None:   # not in subprocess or no-gui test
             self.text = editwin.text
-            self.autocompletewindow = None
-            # id of delayed call, and the index of the text insert when
-            # the delayed call was issued. If _delayed_completion_id is
-            # None, there is no delayed call.
-            self._delayed_completion_id = None
-            self._delayed_completion_index = None
+        self.autocompletewindow = None
+        # id of delayed call, and the index of the text insert when
+        # the delayed call was issued. If _delayed_completion_id is
+        # None, there is no delayed call.
+        self._delayed_completion_id = None
+        self._delayed_completion_index = None
 
     @classmethod
     def reload(cls):
         cls.popupwait = idleConf.GetOption(
             "extensions", "AutoComplete", "popupwait", type="int", default=0)
 
-    def _make_autocomplete_window(self):
+    def _make_autocomplete_window(self):  # Makes mocking easier.
         return autocomplete_w.AutoCompleteWindow(self.text)
 
     def _remove_autocomplete_window(self, event=None):
@@ -52,30 +55,12 @@ class AutoComplete:
             self.autocompletewindow = None
 
     def force_open_completions_event(self, event):
-        """Happens when the user really wants to open a completion list, even
-        if a function call is needed.
-        """
-        self.open_completions(True, False, True)
+        "(^space) Open completion list, even if a function call is needed."
+        self.open_completions(FORCE)
         return "break"
 
-    def try_open_completions_event(self, event):
-        """Happens when it would be nice to open a completion list, but not
-        really necessary, for example after a dot, so function
-        calls won't be made.
-        """
-        lastchar = self.text.get("insert-1c")
-        if lastchar == ".":
-            self._open_completions_later(False, False, False,
-                                         COMPLETE_ATTRIBUTES)
-        elif lastchar in SEPS:
-            self._open_completions_later(False, False, False,
-                                         COMPLETE_FILES)
-
     def autocomplete_event(self, event):
-        """Happens when the user wants to complete his word, and if necessary,
-        open a completion list after that (if there is more than one
-        completion)
-        """
+        "(tab) Complete word or open list if multiple options."
         if hasattr(event, "mc_state") and event.mc_state or\
                 not self.text.get("insert linestart", "insert").strip():
             # A modifier was pressed along with the tab or
@@ -85,34 +70,34 @@ class AutoComplete:
             self.autocompletewindow.complete()
             return "break"
         else:
-            opened = self.open_completions(False, True, True)
+            opened = self.open_completions(TAB)
             return "break" if opened else None
 
-    def _open_completions_later(self, *args):
-        self._delayed_completion_index = self.text.index("insert")
-        if self._delayed_completion_id is not None:
-            self.text.after_cancel(self._delayed_completion_id)
-        self._delayed_completion_id = \
-            self.text.after(self.popupwait, self._delayed_open_completions,
-                            *args)
-
-    def _delayed_open_completions(self, *args):
+    def try_open_completions_event(self, event=None):
+        "(./) Open completion list after pause with no movement."
+        lastchar = self.text.get("insert-1c")
+        if lastchar in TRIGGERS:
+            args = TRY_A if lastchar == "." else TRY_F
+            self._delayed_completion_index = self.text.index("insert")
+            if self._delayed_completion_id is not None:
+                self.text.after_cancel(self._delayed_completion_id)
+            self._delayed_completion_id = self.text.after(
+                self.popupwait, self._delayed_open_completions, args)
+
+    def _delayed_open_completions(self, args):
+        "Call open_completions if index unchanged."
         self._delayed_completion_id = None
         if self.text.index("insert") == self._delayed_completion_index:
-            self.open_completions(*args)
+            self.open_completions(args)
 
-    def open_completions(self, evalfuncs, complete, userWantsWin, mode=None):
+    def open_completions(self, args):
         """Find the completions and create the AutoCompleteWindow.
         Return True if successful (no syntax error or so found).
         If complete is True, then if there's nothing to complete and no
         start of completion, won't open completions and return False.
         If mode is given, will open a completion list only in this mode.
-
-        Action  Function                Eval   Complete WantWin Mode
-        ^space  force_open_completions  True,  False,   True    no
-        . or /  try_open_completions    False, False,   False   yes
-        tab     autocomplete            False, True,    True    no
         """
+        evalfuncs, complete, wantwin, mode = args
         # Cancel another delayed call, if it exists.
         if self._delayed_completion_id is not None:
             self.text.after_cancel(self._delayed_completion_id)
@@ -121,14 +106,14 @@ class AutoComplete:
         hp = HyperParser(self.editwin, "insert")
         curline = self.text.get("insert linestart", "insert")
         i = j = len(curline)
-        if hp.is_in_string() and (not mode or mode==COMPLETE_FILES):
+        if hp.is_in_string() and (not mode or mode==FILES):
             # Find the beginning of the string.
             # fetch_completions will look at the file system to determine
             # whether the string value constitutes an actual file name
             # XXX could consider raw strings here and unescape the string
             # value if it's not raw.
             self._remove_autocomplete_window()
-            mode = COMPLETE_FILES
+            mode = FILES
             # Find last separator or string start
             while i and curline[i-1] not in "'\"" + SEPS:
                 i -= 1
@@ -138,17 +123,17 @@ class AutoComplete:
             while i and curline[i-1] not in "'\"":
                 i -= 1
             comp_what = curline[i:j]
-        elif hp.is_in_code() and (not mode or mode==COMPLETE_ATTRIBUTES):
+        elif hp.is_in_code() and (not mode or mode==ATTRS):
             self._remove_autocomplete_window()
-            mode = COMPLETE_ATTRIBUTES
+            mode = ATTRS
             while i and (curline[i-1] in ID_CHARS or ord(curline[i-1]) > 127):
                 i -= 1
             comp_start = curline[i:j]
-            if i and curline[i-1] == '.':
+            if i and curline[i-1] == '.':  # Need object with attributes.
                 hp.set_index("insert-%dc" % (len(curline)-(i-1)))
                 comp_what = hp.get_expression()
-                if not comp_what or \
-                   (not evalfuncs and comp_what.find('(') != -1):
+                if (not comp_what or
+                   (not evalfuncs and comp_what.find('(') != -1)):
                     return None
             else:
                 comp_what = ""
@@ -163,7 +148,7 @@ class AutoComplete:
         self.autocompletewindow = self._make_autocomplete_window()
         return not self.autocompletewindow.show_window(
                 comp_lists, "insert-%dc" % len(comp_start),
-                complete, mode, userWantsWin)
+                complete, mode, wantwin)
 
     def fetch_completions(self, what, mode):
         """Return a pair of lists of completions for something. The first list
@@ -185,7 +170,7 @@ class AutoComplete:
             return rpcclt.remotecall("exec", "get_the_completion_list",
                                      (what, mode), {})
         else:
-            if mode == COMPLETE_ATTRIBUTES:
+            if mode == ATTRS:
                 if what == "":
                     namespace = {**__main__.__builtins__.__dict__,
                                  **__main__.__dict__}
@@ -207,7 +192,7 @@ class AutoComplete:
                     except:
                         return [], []
 
-            elif mode == COMPLETE_FILES:
+            elif mode == FILES:
                 if what == "":
                     what = "."
                 try:
index c249625277369f86bfbb93513edb4315aaac67ec..5035e067392e5fe86a672bf364a27a15b3dfe5b8 100644 (file)
@@ -6,7 +6,7 @@ import platform
 from tkinter import *
 from tkinter.ttk import Frame, Scrollbar
 
-from idlelib.autocomplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES
+from idlelib.autocomplete import FILES, ATTRS
 from idlelib.multicall import MC_SHIFT
 
 HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
@@ -39,8 +39,7 @@ class AutoCompleteWindow:
         self.completions = None
         # A list with more completions, or None
         self.morecompletions = None
-        # The completion mode. Either autocomplete.COMPLETE_ATTRIBUTES or
-        # autocomplete.COMPLETE_FILES
+        # The completion mode, either autocomplete.ATTRS or .FILES.
         self.mode = None
         # The current completion start, on the text box (a string)
         self.start = None
@@ -53,10 +52,12 @@ class AutoCompleteWindow:
         # (for example, he clicked the list)
         self.userwantswindow = None
         # event ids
-        self.hideid = self.keypressid = self.listupdateid = self.winconfigid \
-        = self.keyreleaseid = self.doubleclickid                         = None
+        self.hideid = self.keypressid = self.listupdateid = \
+            self.winconfigid = self.keyreleaseid = self.doubleclickid = None
         # Flag set if last keypress was a tab
         self.lastkey_was_tab = False
+        # Flag set to avoid recursive <Configure> callback invocations.
+        self.is_configuring = False
 
     def _change_start(self, newstart):
         min_len = min(len(self.start), len(newstart))
@@ -73,8 +74,8 @@ class AutoCompleteWindow:
 
     def _binary_search(self, s):
         """Find the first index in self.completions where completions[i] is
-        greater or equal to s, or the last index if there is no such
-        one."""
+        greater or equal to s, or the last index if there is no such.
+        """
         i = 0; j = len(self.completions)
         while j > i:
             m = (i + j) // 2
@@ -87,7 +88,8 @@ class AutoCompleteWindow:
     def _complete_string(self, s):
         """Assuming that s is the prefix of a string in self.completions,
         return the longest string which is a prefix of all the strings which
-        s is a prefix of them. If s is not a prefix of a string, return s."""
+        s is a prefix of them. If s is not a prefix of a string, return s.
+        """
         first = self._binary_search(s)
         if self.completions[first][:len(s)] != s:
             # There is not even one completion which s is a prefix of.
@@ -116,8 +118,10 @@ class AutoCompleteWindow:
         return first_comp[:i]
 
     def _selection_changed(self):
-        """Should be called when the selection of the Listbox has changed.
-        Updates the Listbox display and calls _change_start."""
+        """Call when the selection of the Listbox has changed.
+
+        Updates the Listbox display and calls _change_start.
+        """
         cursel = int(self.listbox.curselection()[0])
 
         self.listbox.see(cursel)
@@ -153,8 +157,10 @@ class AutoCompleteWindow:
 
     def show_window(self, comp_lists, index, complete, mode, userWantsWin):
         """Show the autocomplete list, bind events.
-        If complete is True, complete the text, and if there is exactly one
-        matching completion, don't open a list."""
+
+        If complete is True, complete the text, and if there is exactly
+        one matching completion, don't open a list.
+        """
         # Handle the start we already have
         self.completions, self.morecompletions = comp_lists
         self.mode = mode
@@ -219,12 +225,18 @@ class AutoCompleteWindow:
         self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE)
         self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE,
                                          self.listselect_event)
+        self.is_configuring = False
         self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
         self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE,
                                           self.doubleclick_event)
         return None
 
     def winconfig_event(self, event):
+        if self.is_configuring:
+            # Avoid running on recursive <Configure> callback invocations.
+            return
+
+        self.is_configuring = True
         if not self.is_active():
             return
         # Position the completion list window
@@ -232,6 +244,7 @@ class AutoCompleteWindow:
         text.see(self.startindex)
         x, y, cx, cy = text.bbox(self.startindex)
         acw = self.autocompletewindow
+        acw.update()
         acw_width, acw_height = acw.winfo_width(), acw.winfo_height()
         text_width, text_height = text.winfo_width(), text.winfo_height()
         new_x = text.winfo_rootx() + min(x, max(0, text_width - acw_width))
@@ -252,6 +265,8 @@ class AutoCompleteWindow:
             acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
             self.winconfigid = None
 
+        self.is_configuring = False
+
     def _hide_event_check(self):
         if not self.autocompletewindow:
             return
@@ -300,7 +315,7 @@ class AutoCompleteWindow:
         if keysym != "Tab":
             self.lastkey_was_tab = False
         if (len(keysym) == 1 or keysym in ("underscore", "BackSpace")
-            or (self.mode == COMPLETE_FILES and keysym in
+            or (self.mode == FILES and keysym in
                 ("period", "minus"))) \
            and not (state & ~MC_SHIFT):
             # Normal editing of text
@@ -329,10 +344,10 @@ class AutoCompleteWindow:
             self.hide_window()
             return 'break'
 
-        elif (self.mode == COMPLETE_ATTRIBUTES and keysym in
+        elif (self.mode == ATTRS and keysym in
               ("period", "space", "parenleft", "parenright", "bracketleft",
                "bracketright")) or \
-             (self.mode == COMPLETE_FILES and keysym in
+             (self.mode == FILES and keysym in
               ("slash", "backslash", "quotedbl", "apostrophe")) \
              and not (state & ~MC_SHIFT):
             # If start is a prefix of the selection, but is not '' when
@@ -340,7 +355,7 @@ class AutoCompleteWindow:
             # selected completion. Anyway, close the list.
             cursel = int(self.listbox.curselection()[0])
             if self.completions[cursel][:len(self.start)] == self.start \
-               and (self.mode == COMPLETE_ATTRIBUTES or self.start):
+               and (self.mode == ATTRS or self.start):
                 self._change_start(self.completions[cursel])
             self.hide_window()
             return None
index e5b0bc53c662402346a5076861709e7cec71c8e0..3c3a53a6599a79282c0141e157712ae71cbc8c44 100644 (file)
@@ -29,7 +29,7 @@ def transform_children(child_dict, modname=None):
     The dictionary maps names to pyclbr information objects.
     Filter out imported objects.
     Augment class names with bases.
-    The insertion order of the dictonary is assumed to have been in line
+    The insertion order of the dictionary is assumed to have been in line
     number order, so sorting is not necessary.
 
     The current tree only calls this once per child_dict as it saves
index 2aed76de7fb6f870ac3f0fb2fe4255b6a91b74e1..4ce98136fe417592ba0e1aa05146ae12b6742007 100644 (file)
@@ -13,14 +13,12 @@ import re
 from sys import maxsize as INFINITY
 
 import tkinter
-from tkinter.constants import TOP, X, SUNKEN
+from tkinter.constants import NSEW, SUNKEN
 
 from idlelib.config import idleConf
 
 BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for",
                 "if", "try", "while", "with", "async"}
-UPDATEINTERVAL = 100 # millisec
-CONFIGUPDATEINTERVAL = 1000 # millisec
 
 
 def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")):
@@ -44,13 +42,13 @@ def get_line_info(codeline):
 
 class CodeContext:
     "Display block context above the edit window."
+    UPDATEINTERVAL = 100  # millisec
 
     def __init__(self, editwin):
         """Initialize settings for context block.
 
         editwin is the Editor window for the context block.
         self.text is the editor window text widget.
-        self.textfont is the editor window font.
 
         self.context displays the code context text above the editor text.
           Initially None, it is toggled via <<toggle-code-context>>.
@@ -65,29 +63,30 @@ class CodeContext:
         """
         self.editwin = editwin
         self.text = editwin.text
-        self.textfont = self.text["font"]
-        self.contextcolors = CodeContext.colors
+        self._reset()
+
+    def _reset(self):
         self.context = None
+        self.cell00 = None
+        self.t1 = None
         self.topvisible = 1
         self.info = [(0, -1, "", False)]
-        # Start two update cycles, one for context lines, one for font changes.
-        self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event)
-        self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event)
 
     @classmethod
     def reload(cls):
         "Load class variables from config."
         cls.context_depth = idleConf.GetOption("extensions", "CodeContext",
-                                       "maxlines", type="int", default=15)
-        cls.colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'context')
+                                               "maxlines", type="int",
+                                               default=15)
 
     def __del__(self):
         "Cancel scheduled events."
-        try:
-            self.text.after_cancel(self.t1)
-            self.text.after_cancel(self.t2)
-        except:
-            pass
+        if self.t1 is not None:
+            try:
+                self.text.after_cancel(self.t1)
+            except tkinter.TclError:
+                pass
+            self.t1 = None
 
     def toggle_code_context_event(self, event=None):
         """Toggle code context display.
@@ -96,7 +95,7 @@ class CodeContext:
         window text (toggle on).  If it does exist, destroy it (toggle off).
         Return 'break' to complete the processing of the binding.
         """
-        if not self.context:
+        if self.context is None:
             # Calculate the border width and horizontal padding required to
             # align the context with the text in the main Text widget.
             #
@@ -107,25 +106,39 @@ class CodeContext:
             padx = 0
             border = 0
             for widget in widgets:
-                padx += widget.tk.getint(widget.pack_info()['padx'])
+                info = (widget.grid_info()
+                        if widget is self.editwin.text
+                        else widget.pack_info())
+                padx += widget.tk.getint(info['padx'])
                 padx += widget.tk.getint(widget.cget('padx'))
                 border += widget.tk.getint(widget.cget('border'))
             self.context = tkinter.Text(
-                    self.editwin.top, font=self.textfont,
-                    bg=self.contextcolors['background'],
-                    fg=self.contextcolors['foreground'],
-                    height=1,
-                    width=1,  # Don't request more than we get.
-                    padx=padx, border=border, relief=SUNKEN, state='disabled')
+                self.editwin.text_frame,
+                height=1,
+                width=1,  # Don't request more than we get.
+                highlightthickness=0,
+                padx=padx, border=border, relief=SUNKEN, state='disabled')
+            self.update_font()
+            self.update_highlight_colors()
             self.context.bind('<ButtonRelease-1>', self.jumptoline)
-            # Pack the context widget before and above the text_frame widget,
-            # thus ensuring that it will appear directly above text_frame.
-            self.context.pack(side=TOP, fill=X, expand=False,
-                            before=self.editwin.text_frame)
+            # Get the current context and initiate the recurring update event.
+            self.timer_event()
+            # Grid the context widget above the text widget.
+            self.context.grid(row=0, column=1, sticky=NSEW)
+
+            line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(),
+                                                       'linenumber')
+            self.cell00 = tkinter.Frame(self.editwin.text_frame,
+                                        bg=line_number_colors['background'])
+            self.cell00.grid(row=0, column=0, sticky=NSEW)
             menu_status = 'Hide'
         else:
             self.context.destroy()
             self.context = None
+            self.cell00.destroy()
+            self.cell00 = None
+            self.text.after_cancel(self.t1)
+            self._reset()
             menu_status = 'Show'
         self.editwin.update_menu_label(menu='options', index='* Code Context',
                                        label=f'{menu_status} Code Context')
@@ -169,7 +182,7 @@ class CodeContext:
         be retrieved and the context area will be updated with the code,
         up to the number of maxlines.
         """
-        new_topvisible = int(self.text.index("@0,0").split('.')[0])
+        new_topvisible = self.editwin.getlineno("@0,0")
         if self.topvisible == new_topvisible:      # Haven't scrolled.
             return
         if self.topvisible < new_topvisible:       # Scroll down.
@@ -217,21 +230,25 @@ class CodeContext:
 
     def timer_event(self):
         "Event on editor text widget triggered every UPDATEINTERVAL ms."
-        if self.context:
+        if self.context is not None:
             self.update_code_context()
-        self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event)
-
-    def config_timer_event(self):
-        "Event on editor text widget triggered every CONFIGUPDATEINTERVAL ms."
-        newtextfont = self.text["font"]
-        if (self.context and (newtextfont != self.textfont or
-                            CodeContext.colors != self.contextcolors)):
-            self.textfont = newtextfont
-            self.contextcolors = CodeContext.colors
-            self.context["font"] = self.textfont
-            self.context['background'] = self.contextcolors['background']
-            self.context['foreground'] = self.contextcolors['foreground']
-        self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event)
+            self.t1 = self.text.after(self.UPDATEINTERVAL, self.timer_event)
+
+    def update_font(self):
+        if self.context is not None:
+            font = idleConf.GetFont(self.text, 'main', 'EditorWindow')
+            self.context['font'] = font
+
+    def update_highlight_colors(self):
+        if self.context is not None:
+            colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'context')
+            self.context['background'] = colors['background']
+            self.context['foreground'] = colors['foreground']
+
+        if self.cell00 is not None:
+            line_number_colors = idleConf.GetHighlight(idleConf.CurrentTheme(),
+                                                       'linenumber')
+            self.cell00.config(bg=line_number_colors['background'])
 
 
 CodeContext.reload()
index aaa2b57a7f6d851b00e6c5f425d4351627a7f164..a7b0433831c533c28e2a3f6d8b3ee3bbb44bad43 100644 (file)
@@ -22,6 +22,10 @@ hit-foreground= #ffffff
 hit-background= #000000
 error-foreground= #000000
 error-background= #ff7777
+context-foreground= #000000
+context-background= lightgray
+linenumber-foreground= gray
+linenumber-background= #ffffff
 #cursor (only foreground can be set, restart IDLE)
 cursor-foreground= black
 #shell window
@@ -31,8 +35,6 @@ stderr-foreground= red
 stderr-background= #ffffff
 console-foreground= #770000
 console-background= #ffffff
-context-foreground= #000000
-context-background= lightgray
 
 [IDLE New]
 normal-foreground= #000000
@@ -55,6 +57,10 @@ hit-foreground= #ffffff
 hit-background= #000000
 error-foreground= #000000
 error-background= #ff7777
+context-foreground= #000000
+context-background= lightgray
+linenumber-foreground= gray
+linenumber-background= #ffffff
 #cursor (only foreground can be set, restart IDLE)
 cursor-foreground= black
 #shell window
@@ -64,8 +70,6 @@ stderr-foreground= red
 stderr-background= #ffffff
 console-foreground= #770000
 console-background= #ffffff
-context-foreground= #000000
-context-background= lightgray
 
 [IDLE Dark]
 comment-foreground = #dd0000
@@ -97,3 +101,5 @@ comment-background = #002240
 break-foreground = #FFFFFF
 context-foreground= #ffffff
 context-background= #454545
+linenumber-foreground= gray
+linenumber-background= #002240
index 06e3c5adb0e35b62b0d3808fdec3e0981335fc10..b2be6250d021afe9f073fe3fc1f30b3d06026620 100644 (file)
@@ -36,7 +36,7 @@
 # Additional help sources are listed in the [HelpFiles] section below
 # and should be viewable by a web browser (or the Windows Help viewer in
 # the case of .chm files). These sources will be listed on the Help
-# menu.  The pattern, and two examples, are
+# menu.  The pattern, and two examples, are:
 #
 # <sequence_number = menu item;/path/to/help/source>
 # 1 = IDLE;C:/Programs/Python36/Lib/idlelib/help.html
@@ -46,7 +46,7 @@
 # platform specific because of path separators, drive specs etc.
 #
 # The default files should not be edited except to add new sections to
-# config-extensions.def for added extensions .  The user files should be
+# config-extensions.def for added extensions.  The user files should be
 # modified through the Settings dialog.
 
 [General]
@@ -65,6 +65,7 @@ font= TkFixedFont
 font-size= 10
 font-bold= 0
 encoding= none
+line-numbers-default= 0
 
 [PyShell]
 auto-squeeze-min-lines= 50
index 2233dacd66ba504dcdb110a88d8f914749c6db59..12e6f9fae78b80fdada01e1723e99c9a6c6c13f2 100644 (file)
@@ -123,20 +123,14 @@ class IdleUserConfParser(IdleConfParser):
         self.RemoveEmptySections()
         return not self.sections()
 
-    def RemoveFile(self):
-        "Remove user config file self.file from disk if it exists."
-        if os.path.exists(self.file):
-            os.remove(self.file)
-
     def Save(self):
         """Update user configuration file.
 
         If self not empty after removing empty sections, write the file
         to disk. Otherwise, remove the file from disk if it exists.
-
         """
         fname = self.file
-        if fname:
+        if fname and fname[0] != '#':
             if not self.IsEmpty():
                 try:
                     cfgFile = open(fname, 'w')
@@ -145,8 +139,8 @@ class IdleUserConfParser(IdleConfParser):
                     cfgFile = open(fname, 'w')
                 with cfgFile:
                     self.write(cfgFile)
-            else:
-                self.RemoveFile()
+            elif os.path.exists(self.file):
+                os.remove(self.file)
 
 class IdleConf:
     """Hold config parsers for all idle config files in singleton instance.
@@ -171,24 +165,13 @@ class IdleConf:
 
     def CreateConfigHandlers(self):
         "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])
-        self.userdir = userDir = self.GetUserCfgDir()
-
-        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])
+        idledir = os.path.dirname(__file__)
+        self.userdir = userdir = '' if idlelib.testing else self.GetUserCfgDir()
+        for cfg_type in self.config_types:
+            self.defaultCfg[cfg_type] = IdleConfParser(
+                os.path.join(idledir, f'config-{cfg_type}.def'))
+            self.userCfg[cfg_type] = IdleUserConfParser(
+                os.path.join(userdir or '#', f'config-{cfg_type}.cfg'))
 
     def GetUserCfgDir(self):
         """Return a filesystem directory for storing user config files.
@@ -199,12 +182,13 @@ class IdleConf:
         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.')
-                try:
-                    print(warn, file=sys.stderr)
-                except OSError:
-                    pass
+                if not idlelib.testing:
+                    warn = ('\n Warning: os.path.expanduser("~") points to\n ' +
+                            userDir + ',\n but the path does not exist.')
+                    try:
+                        print(warn, file=sys.stderr)
+                    except OSError:
+                        pass
                 userDir = '~'
         if userDir == "~": # still no path to home!
             # traditionally IDLE has defaulted to os.getcwd(), is this adequate?
@@ -214,10 +198,13 @@ class IdleConf:
             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')
                 if not idlelib.testing:
-                    print(warn, file=sys.stderr)
+                    warn = ('\n Warning: unable to create user config directory\n' +
+                            userDir + '\n Check path and permissions.\n Exiting!\n')
+                    try:
+                        print(warn, file=sys.stderr)
+                    except OSError:
+                        pass
                 raise SystemExit
         # TODO continue without userDIr instead of exit
         return userDir
@@ -336,6 +323,10 @@ class IdleConf:
                 'hit-background':'#000000',
                 'error-foreground':'#ffffff',
                 'error-background':'#000000',
+                'context-foreground':'#000000',
+                'context-background':'#ffffff',
+                'linenumber-foreground':'#000000',
+                'linenumber-background':'#ffffff',
                 #cursor (only foreground can be set)
                 'cursor-foreground':'#000000',
                 #shell window
@@ -345,11 +336,11 @@ class IdleConf:
                 'stderr-background':'#ffffff',
                 'console-foreground':'#000000',
                 'console-background':'#ffffff',
-                'context-foreground':'#000000',
-                'context-background':'#ffffff',
                 }
         for element in theme:
-            if not cfgParser.has_option(themeName, element):
+            if not (cfgParser.has_option(themeName, element) or
+                    # Skip warning for new elements.
+                    element.startswith(('context-', 'linenumber-'))):
                 # Print warning that will return a default color
                 warning = ('\n Warning: config.IdleConf.GetThemeDict'
                            ' -\n problem retrieving theme element %r'
index 807ff60413d1b0fcade988af3ba83f20abd1f4cb..df216582fe60930c27732c8ab52c32d5ec83511a 100644 (file)
@@ -9,6 +9,8 @@ Note that tab width in IDLE is currently fixed at eight due to Tk issues.
 Refer to comments in EditorWindow autoindent code for details.
 
 """
+import re
+
 from tkinter import (Toplevel, Listbox, Text, Scale, Canvas,
                      StringVar, BooleanVar, IntVar, TRUE, FALSE,
                      TOP, BOTTOM, RIGHT, LEFT, SOLID, GROOVE,
@@ -29,8 +31,9 @@ from idlelib.textview import view_text
 from idlelib.autocomplete import AutoComplete
 from idlelib.codecontext import CodeContext
 from idlelib.parenmatch import ParenMatch
-from idlelib.paragraph import FormatParagraph
+from idlelib.format import FormatParagraph
 from idlelib.squeezer import Squeezer
+from idlelib.textview import ScrollableTextFrame
 
 changes = ConfigChanges()
 # Reload changed options in the following classes.
@@ -554,7 +557,9 @@ class FontPage(Frame):
                 frame_font_param, variable=self.font_bold,
                 onvalue=1, offvalue=0, text='Bold')
         # frame_sample.
-        self.font_sample = Text(frame_sample, width=20, height=20)
+        font_sample_frame = ScrollableTextFrame(frame_sample)
+        self.font_sample = font_sample_frame.text
+        self.font_sample.config(wrap=NONE, width=1, height=1)
         self.font_sample.insert(END, font_sample_text)
         # frame_indent.
         indent_title = Label(
@@ -566,8 +571,9 @@ class FontPage(Frame):
 
         # Grid and pack widgets:
         self.columnconfigure(1, weight=1)
+        self.rowconfigure(2, weight=1)
         frame_font.grid(row=0, column=0, padx=5, pady=5)
-        frame_sample.grid(row=0, column=1, rowspan=2, padx=5, pady=5,
+        frame_sample.grid(row=0, column=1, rowspan=3, padx=5, pady=5,
                           sticky='nsew')
         frame_indent.grid(row=1, column=0, padx=5, pady=5, sticky='ew')
         # frame_font.
@@ -580,7 +586,7 @@ class FontPage(Frame):
         self.sizelist.pack(side=LEFT, anchor=W)
         self.bold_toggle.pack(side=LEFT, anchor=W, padx=20)
         # frame_sample.
-        self.font_sample.pack(expand=TRUE, fill=BOTH)
+        font_sample_frame.pack(expand=TRUE, fill=BOTH)
         # frame_indent.
         indent_title.pack(side=TOP, anchor=W, padx=5)
         self.indent_scale.pack(side=TOP, padx=5, fill=X)
@@ -802,7 +808,7 @@ class HighPage(Frame):
                 (*)theme_message: Label
         """
         self.theme_elements = {
-            'Normal Text': ('normal', '00'),
+            'Normal Code or Text': ('normal', '00'),
             'Code Context': ('context', '01'),
             'Python Keywords': ('keyword', '02'),
             'Python Definitions': ('definition', '03'),
@@ -813,10 +819,11 @@ class HighPage(Frame):
             'Found Text': ('hit', '08'),
             'Cursor': ('cursor', '09'),
             'Editor Breakpoint': ('break', '10'),
-            'Shell Normal Text': ('console', '11'),
-            'Shell Error Text': ('error', '12'),
-            'Shell Stdout Text': ('stdout', '13'),
-            'Shell Stderr Text': ('stderr', '14'),
+            'Shell Prompt': ('console', '11'),
+            'Error Text': ('error', '12'),
+            'Shell User Output': ('stdout', '13'),
+            'Shell User Exception': ('stderr', '14'),
+            'Line Number': ('linenumber', '16'),
             }
         self.builtin_name = tracers.add(
                 StringVar(self), self.var_changed_builtin_name)
@@ -837,33 +844,39 @@ class HighPage(Frame):
         frame_theme = LabelFrame(self, borderwidth=2, relief=GROOVE,
                                  text=' Highlighting Theme ')
         # frame_custom.
-        text = self.highlight_sample = Text(
-                frame_custom, relief=SOLID, borderwidth=1,
-                font=('courier', 12, ''), cursor='hand2', width=21, height=13,
+        sample_frame = ScrollableTextFrame(
+                frame_custom, relief=SOLID, borderwidth=1)
+        text = self.highlight_sample = sample_frame.text
+        text.configure(
+                font=('courier', 12, ''), cursor='hand2', width=1, height=1,
                 takefocus=FALSE, highlightthickness=0, wrap=NONE)
         text.bind('<Double-Button-1>', lambda e: 'break')
         text.bind('<B1-Motion>', lambda e: 'break')
-        text_and_tags=(
-            ('\n', 'normal'),
-            ('#you can click here', 'comment'), ('\n', 'normal'),
-            ('#to choose items', 'comment'), ('\n', 'normal'),
-            ('code context section', 'context'), ('\n\n', 'normal'),
+        string_tags=(
+            ('# Click selects item.', 'comment'), ('\n', 'normal'),
+            ('code context section', 'context'), ('\n', 'normal'),
+            ('| cursor', 'cursor'), ('\n', 'normal'),
             ('def', 'keyword'), (' ', 'normal'),
             ('func', 'definition'), ('(param):\n  ', 'normal'),
-            ('"""string"""', 'string'), ('\n  var0 = ', 'normal'),
+            ('"Return None."', '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\n', 'normal'))
-        for texttag in text_and_tags:
-            text.insert(END, texttag[0], texttag[1])
+            ('>>>', 'console'), (' 3.14**2\n', 'normal'),
+            ('9.8596', 'stdout'), ('\n', 'normal'),
+            ('>>>', 'console'), (' pri ', 'normal'),
+            ('n', 'error'), ('t(\n', 'normal'),
+            ('SyntaxError', 'stderr'), ('\n', 'normal'))
+        for string, tag in string_tags:
+            text.insert(END, string, tag)
+        n_lines = len(text.get('1.0', END).splitlines())
+        for lineno in range(1, n_lines):
+            text.insert(f'{lineno}.0',
+                        f'{lineno:{len(str(n_lines))}d} ',
+                        'linenumber')
         for element in self.theme_elements:
             def tem(event, elem=element):
                 # event.widget.winfo_top_level().highlight_target.set(elem)
@@ -912,9 +925,9 @@ class HighPage(Frame):
         frame_custom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
         frame_theme.pack(side=TOP, padx=5, pady=5, fill=X)
         # frame_custom.
-        self.frame_color_set.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X)
+        self.frame_color_set.pack(side=TOP, padx=5, pady=5, fill=X)
         frame_fg_bg_toggle.pack(side=TOP, padx=5, pady=0)
-        self.highlight_sample.pack(
+        sample_frame.pack(
                 side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
         self.button_set_color.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4)
         self.targetlist.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=3)
@@ -1764,14 +1777,23 @@ class GenPage(Frame):
 
     def __init__(self, master):
         super().__init__(master)
+
+        self.init_validators()
         self.create_page_general()
         self.load_general_cfg()
 
+    def init_validators(self):
+        digits_or_empty_re = re.compile(r'[0-9]*')
+        def is_digits_or_empty(s):
+            "Return 's is blank or contains only digits'"
+            return digits_or_empty_re.fullmatch(s) is not None
+        self.digits_only = (self.register(is_digits_or_empty), '%P',)
+
     def create_page_general(self):
         """Return frame of widgets for General tab.
 
         Enable users to provisionally change general options. Function
-        load_general_cfg intializes tk variables and helplist using
+        load_general_cfg initializes tk variables and helplist using
         idleConf.  Radiobuttons startup_shell_on and startup_editor_on
         set var startup_edit. Radiobuttons save_ask_on and save_auto_on
         set var autosave. Entry boxes win_width_int and win_height_int
@@ -1816,6 +1838,9 @@ class GenPage(Frame):
                 frame_format: Frame
                     format_width_title: Label
                     (*)format_width_int: Entry - format_width
+                frame_line_numbers_default: Frame
+                    line_numbers_default_title: Label
+                    (*)line_numbers_default_bool: Checkbutton - line_numbers_default
                 frame_context: Frame
                     context_title: Label
                     (*)context_int: Entry - context_lines
@@ -1855,6 +1880,9 @@ class GenPage(Frame):
                 IntVar(self), ('main', 'General', 'autosave'))
         self.format_width = tracers.add(
                 StringVar(self), ('extensions', 'FormatParagraph', 'max-width'))
+        self.line_numbers_default = tracers.add(
+                BooleanVar(self),
+                ('main', 'EditorWindow', 'line-numbers-default'))
         self.context_lines = tracers.add(
                 StringVar(self), ('extensions', 'CodeContext', 'maxlines'))
 
@@ -1883,16 +1911,23 @@ class GenPage(Frame):
                 frame_win_size, text='Initial Window Size  (in characters)')
         win_width_title = Label(frame_win_size, text='Width')
         self.win_width_int = Entry(
-                frame_win_size, textvariable=self.win_width, width=3)
+                frame_win_size, textvariable=self.win_width, width=3,
+                validatecommand=self.digits_only, validate='key',
+        )
         win_height_title = Label(frame_win_size, text='Height')
         self.win_height_int = Entry(
-                frame_win_size, textvariable=self.win_height, width=3)
+                frame_win_size, textvariable=self.win_height, width=3,
+                validatecommand=self.digits_only, validate='key',
+        )
 
         frame_autocomplete = Frame(frame_window, borderwidth=0,)
         auto_wait_title = Label(frame_autocomplete,
                                text='Completions Popup Wait (milliseconds)')
         self.auto_wait_int = Entry(frame_autocomplete, width=6,
-                                   textvariable=self.autocomplete_wait)
+                                   textvariable=self.autocomplete_wait,
+                                   validatecommand=self.digits_only,
+                                   validate='key',
+                                   )
 
         frame_paren1 = Frame(frame_window, borderwidth=0)
         paren_style_title = Label(frame_paren1, text='Paren Match Style')
@@ -1922,20 +1957,34 @@ class GenPage(Frame):
         format_width_title = Label(frame_format,
                                    text='Format Paragraph Max Width')
         self.format_width_int = Entry(
-                frame_format, textvariable=self.format_width, width=4)
+                frame_format, textvariable=self.format_width, width=4,
+                validatecommand=self.digits_only, validate='key',
+        )
+
+        frame_line_numbers_default = Frame(frame_editor, borderwidth=0)
+        line_numbers_default_title = Label(
+            frame_line_numbers_default, text='Show line numbers in new windows')
+        self.line_numbers_default_bool = Checkbutton(
+                frame_line_numbers_default,
+                variable=self.line_numbers_default,
+                width=1)
 
         frame_context = Frame(frame_editor, borderwidth=0)
         context_title = Label(frame_context, text='Max Context Lines :')
         self.context_int = Entry(
-                frame_context, textvariable=self.context_lines, width=3)
+                frame_context, textvariable=self.context_lines, width=3,
+                validatecommand=self.digits_only, validate='key',
+        )
 
         # Frame_shell.
         frame_auto_squeeze_min_lines = Frame(frame_shell, borderwidth=0)
         auto_squeeze_min_lines_title = Label(frame_auto_squeeze_min_lines,
                                              text='Auto-Squeeze Min. Lines:')
         self.auto_squeeze_min_lines_int = Entry(
-            frame_auto_squeeze_min_lines, width=4,
-            textvariable=self.auto_squeeze_min_lines)
+                frame_auto_squeeze_min_lines, width=4,
+                textvariable=self.auto_squeeze_min_lines,
+                validatecommand=self.digits_only, validate='key',
+        )
 
         # frame_help.
         frame_helplist = Frame(frame_help)
@@ -1997,6 +2046,10 @@ class GenPage(Frame):
         frame_format.pack(side=TOP, padx=5, pady=0, fill=X)
         format_width_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
         self.format_width_int.pack(side=TOP, padx=10, pady=5)
+        # frame_line_numbers_default.
+        frame_line_numbers_default.pack(side=TOP, padx=5, pady=0, fill=X)
+        line_numbers_default_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
+        self.line_numbers_default_bool.pack(side=LEFT, padx=5, pady=5)
         # frame_context.
         frame_context.pack(side=TOP, padx=5, pady=0, fill=X)
         context_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
@@ -2039,6 +2092,8 @@ class GenPage(Frame):
                 'main', 'General', 'autosave', default=0, type='bool'))
         self.format_width.set(idleConf.GetOption(
                 'extensions', 'FormatParagraph', 'max-width', type='int'))
+        self.line_numbers_default.set(idleConf.GetOption(
+                'main', 'EditorWindow', 'line-numbers-default', type='bool'))
         self.context_lines.set(idleConf.GetOption(
                 'extensions', 'CodeContext', 'maxlines', type='int'))
 
index 606de71a6add889540f6ad350e2f2d9c80965f74..b969f8c493b27765a49ea930a58e2427a4a78ece 100644 (file)
@@ -2,12 +2,15 @@ import importlib.abc
 import importlib.util
 import os
 import platform
+import re
 import string
+import sys
 import tokenize
 import traceback
 import webbrowser
 
 from tkinter import *
+from tkinter.font import Font
 from tkinter.ttk import Scrollbar
 import tkinter.simpledialog as tkSimpleDialog
 import tkinter.messagebox as tkMessageBox
@@ -23,6 +26,7 @@ from idlelib import pyparse
 from idlelib import query
 from idlelib import replace
 from idlelib import search
+from idlelib.tree import wheel_event
 from idlelib import window
 
 # The default tab setting for a Text widget, in average-width characters.
@@ -53,15 +57,18 @@ class EditorWindow(object):
     from idlelib.autoexpand import AutoExpand
     from idlelib.calltip import Calltip
     from idlelib.codecontext import CodeContext
-    from idlelib.paragraph import FormatParagraph
+    from idlelib.sidebar import LineNumbers
+    from idlelib.format import FormatParagraph, FormatRegion, Indents, Rstrip
     from idlelib.parenmatch import ParenMatch
-    from idlelib.rstrip import Rstrip
     from idlelib.squeezer import Squeezer
     from idlelib.zoomheight import ZoomHeight
 
     filesystemencoding = sys.getfilesystemencoding()  # for file names
     help_url = None
 
+    allow_code_context = True
+    allow_line_numbers = True
+
     def __init__(self, flist=None, filename=None, key=None, root=None):
         # Delay import: runscript imports pyshell imports EditorWindow.
         from idlelib.runscript import ScriptBinding
@@ -109,20 +116,19 @@ class EditorWindow(object):
             self.tkinter_vars = {}  # keys: Tkinter event names
                                     # values: Tkinter variable instances
             self.top.instance_dict = {}
-        self.recent_files_path = os.path.join(
+        self.recent_files_path = idleConf.userdir and os.path.join(
                 idleConf.userdir, 'recent-files.lst')
 
         self.prompt_last_line = ''  # Override in PyShell
         self.text_frame = text_frame = Frame(top)
         self.vbar = vbar = Scrollbar(text_frame, name='vbar')
-        self.width = idleConf.GetOption('main', 'EditorWindow',
-                                        'width', type='int')
+        width = idleConf.GetOption('main', 'EditorWindow', 'width', type='int')
         text_options = {
                 'name': 'text',
                 'padx': 5,
                 'wrap': 'none',
                 'highlightthickness': 0,
-                'width': self.width,
+                'width': width,
                 'tabstyle': 'wordprocessor',  # new in 8.5
                 'height': idleConf.GetOption(
                         'main', 'EditorWindow', 'height', type='int'),
@@ -146,9 +152,11 @@ class EditorWindow(object):
         else:
             # Elsewhere, use right-click for popup menus.
             text.bind("<3>",self.right_menu_event)
-        text.bind('<MouseWheel>', self.mousescroll)
-        text.bind('<Button-4>', self.mousescroll)
-        text.bind('<Button-5>', self.mousescroll)
+
+        text.bind('<MouseWheel>', wheel_event)
+        text.bind('<Button-4>', wheel_event)
+        text.bind('<Button-5>', wheel_event)
+        text.bind('<Configure>', self.handle_winconfig)
         text.bind("<<cut>>", self.cut)
         text.bind("<<copy>>", self.copy)
         text.bind("<<paste>>", self.paste)
@@ -170,14 +178,16 @@ class EditorWindow(object):
         text.bind("<<smart-backspace>>",self.smart_backspace_event)
         text.bind("<<newline-and-indent>>",self.newline_and_indent_event)
         text.bind("<<smart-indent>>",self.smart_indent_event)
-        text.bind("<<indent-region>>",self.indent_region_event)
-        text.bind("<<dedent-region>>",self.dedent_region_event)
-        text.bind("<<comment-region>>",self.comment_region_event)
-        text.bind("<<uncomment-region>>",self.uncomment_region_event)
-        text.bind("<<tabify-region>>",self.tabify_region_event)
-        text.bind("<<untabify-region>>",self.untabify_region_event)
-        text.bind("<<toggle-tabs>>",self.toggle_tabs_event)
-        text.bind("<<change-indentwidth>>",self.change_indentwidth_event)
+        self.fregion = fregion = self.FormatRegion(self)
+        # self.fregion used in smart_indent_event to access indent_region.
+        text.bind("<<indent-region>>", fregion.indent_region_event)
+        text.bind("<<dedent-region>>", fregion.dedent_region_event)
+        text.bind("<<comment-region>>", fregion.comment_region_event)
+        text.bind("<<uncomment-region>>", fregion.uncomment_region_event)
+        text.bind("<<tabify-region>>", fregion.tabify_region_event)
+        text.bind("<<untabify-region>>", fregion.untabify_region_event)
+        text.bind("<<toggle-tabs>>", self.Indents.toggle_tabs_event)
+        text.bind("<<change-indentwidth>>", self.Indents.change_indentwidth_event)
         text.bind("<Left>", self.move_at_edge_if_selection(0))
         text.bind("<Right>", self.move_at_edge_if_selection(1))
         text.bind("<<del-word-left>>", self.del_word_left)
@@ -195,13 +205,16 @@ class EditorWindow(object):
             text.bind("<<open-turtle-demo>>", self.open_turtle_demo)
 
         self.set_status_bar()
+        text_frame.pack(side=LEFT, fill=BOTH, expand=1)
+        text_frame.rowconfigure(1, weight=1)
+        text_frame.columnconfigure(1, weight=1)
         vbar['command'] = self.handle_yview
-        vbar.pack(side=RIGHT, fill=Y)
+        vbar.grid(row=1, column=2, sticky=NSEW)
         text['yscrollcommand'] = vbar.set
         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.grid(row=1, column=1, sticky=NSEW)
         text.focus_set()
+        self.set_width()
 
         # usetabs true  -> literal tab characters are used by indent and
         #                  dedent cmds, possibly mixed with spaces if
@@ -247,6 +260,8 @@ class EditorWindow(object):
         self.good_load = False
         self.set_indentation_params(False)
         self.color = None # initialized below in self.ResetColorizer
+        self.code_context = None # optionally initialized later below
+        self.line_numbers = None # optionally initialized later below
         if filename:
             if os.path.exists(filename) and not os.path.isdir(filename):
                 if io.loadfile(filename):
@@ -312,8 +327,36 @@ class EditorWindow(object):
         text.bind("<<refresh-calltip>>", ctip.refresh_calltip_event)
         text.bind("<<force-open-calltip>>", ctip.force_open_calltip_event)
         text.bind("<<zoom-height>>", self.ZoomHeight(self).zoom_height_event)
-        text.bind("<<toggle-code-context>>",
-                  self.CodeContext(self).toggle_code_context_event)
+        if self.allow_code_context:
+            self.code_context = self.CodeContext(self)
+            text.bind("<<toggle-code-context>>",
+                      self.code_context.toggle_code_context_event)
+        else:
+            self.update_menu_state('options', '*Code Context', 'disabled')
+        if self.allow_line_numbers:
+            self.line_numbers = self.LineNumbers(self)
+            if idleConf.GetOption('main', 'EditorWindow',
+                                  'line-numbers-default', type='bool'):
+                self.toggle_line_numbers_event()
+            text.bind("<<toggle-line-numbers>>", self.toggle_line_numbers_event)
+        else:
+            self.update_menu_state('options', '*Line Numbers', 'disabled')
+
+    def handle_winconfig(self, event=None):
+        self.set_width()
+
+    def set_width(self):
+        text = self.text
+        inner_padding = sum(map(text.tk.getint, [text.cget('border'),
+                                                 text.cget('padx')]))
+        pixel_width = text.winfo_width() - 2 * inner_padding
+
+        # Divide the width of the Text widget by the font width,
+        # which is taken to be the width of '0' (zero).
+        # http://www.tcl.tk/man/tcl8.6/TkCmd/text.htm#M21
+        zero_char_width = \
+            Font(text, font=text.cget('font')).measure('0')
+        self.width = pixel_width // zero_char_width
 
     def _filename_to_unicode(self, filename):
         """Return filename as BMP unicode so displayable in Tk."""
@@ -461,23 +504,6 @@ class EditorWindow(object):
         self.text.yview(event, *args)
         return 'break'
 
-    def mousescroll(self, event):
-        """Handle scrollwheel event.
-
-        For wheel up, event.delta = 120*n on Windows, -1*n on darwin,
-        where n can be > 1 if one scrolls fast.  Flicking the wheel
-        generates up to maybe 20 events with n up to 10 or more 1.
-        Macs use wheel down (delta = 1*n) to scroll up, so positive
-        delta means to scroll up on both systems.
-
-        X-11 sends Control-Button-4 event instead.
-        """
-        up = {EventType.MouseWheel: event.delta > 0,
-              EventType.Button: event.num == 4}
-        lines = -5 if up[event.type] else 5
-        self.text.yview_scroll(lines, 'units')
-        return 'break'
-
     rmenu = None
 
     def right_menu_event(self, event):
@@ -773,6 +799,12 @@ class EditorWindow(object):
         self._addcolorizer()
         EditorWindow.color_config(self.text)
 
+        if self.code_context is not None:
+            self.code_context.update_highlight_colors()
+
+        if self.line_numbers is not None:
+            self.line_numbers.update_colors()
+
     IDENTCHARS = string.ascii_letters + string.digits + "_"
 
     def colorize_syntax_error(self, text, pos):
@@ -790,7 +822,18 @@ class EditorWindow(object):
         "Update the text widgets' font if it is changed"
         # Called from configdialog.py
 
-        self.text['font'] = idleConf.GetFont(self.root, 'main','EditorWindow')
+        # Update the code context widget first, since its height affects
+        # the height of the text widget.  This avoids double re-rendering.
+        if self.code_context is not None:
+            self.code_context.update_font()
+        # Next, update the line numbers widget, since its width affects
+        # the width of the text widget.
+        if self.line_numbers is not None:
+            self.line_numbers.update_font()
+        # Finally, update the main text widget.
+        new_font = idleConf.GetFont(self.root, 'main', 'EditorWindow')
+        self.text['font'] = new_font
+        self.set_width()
 
     def RemoveKeybindings(self):
         "Remove the keybindings before they are changed."
@@ -881,9 +924,11 @@ class EditorWindow(object):
 
     def update_recent_files_list(self, new_file=None):
         "Load and update the recent files list and menus"
+        # TODO: move to iomenu.
         rf_list = []
-        if os.path.exists(self.recent_files_path):
-            with open(self.recent_files_path, 'r',
+        file_path = self.recent_files_path
+        if file_path and os.path.exists(file_path):
+            with open(file_path, 'r',
                       encoding='utf_8', errors='replace') as rf_list_file:
                 rf_list = rf_list_file.readlines()
         if new_file:
@@ -899,19 +944,19 @@ class EditorWindow(object):
         rf_list = [path for path in rf_list if path not in bad_paths]
         ulchars = "1234567890ABCDEFGHIJK"
         rf_list = rf_list[0:len(ulchars)]
-        try:
-            with open(self.recent_files_path, 'w',
-                        encoding='utf_8', errors='replace') as rf_file:
-                rf_file.writelines(rf_list)
-        except OSError as err:
-            if not getattr(self.root, "recentfilelist_error_displayed", False):
-                self.root.recentfilelist_error_displayed = True
-                tkMessageBox.showwarning(title='IDLE Warning',
-                    message="Cannot update File menu Recent Files list. "
-                            "Your operating system says:\n%s\n"
-                            "Select OK and IDLE will continue without updating."
-                        % self._filename_to_unicode(str(err)),
-                    parent=self.text)
+        if file_path:
+            try:
+                with open(file_path, 'w',
+                          encoding='utf_8', errors='replace') as rf_file:
+                    rf_file.writelines(rf_list)
+            except OSError as err:
+                if not getattr(self.root, "recentfiles_message", False):
+                    self.root.recentfiles_message = True
+                    tkMessageBox.showwarning(title='IDLE Warning',
+                        message="Cannot save Recent Files list to disk.\n"
+                                f"  {err}\n"
+                                "Select OK to continue.",
+                        parent=self.text)
         # for each edit window instance, construct the recent files menu
         for instance in self.top.instance_dict:
             menu = instance.recent_files_menu
@@ -1016,10 +1061,13 @@ class EditorWindow(object):
             return self.io.maybesave()
 
     def close(self):
-        reply = self.maybesave()
-        if str(reply) != "cancel":
-            self._close()
-        return reply
+        try:
+            reply = self.maybesave()
+            if str(reply) != "cancel":
+                self._close()
+            return reply
+        except AttributeError:  # bpo-35379: close called twice
+            pass
 
     def _close(self):
         if self.io.filename:
@@ -1277,11 +1325,11 @@ class EditorWindow(object):
         try:
             if first and last:
                 if index2line(first) != index2line(last):
-                    return self.indent_region_event(event)
+                    return self.fregion.indent_region_event(event)
                 text.delete(first, last)
                 text.mark_set("insert", first)
             prefix = text.get("insert linestart", "insert")
-            raw, effective = classifyws(prefix, self.tabwidth)
+            raw, effective = get_line_indent(prefix, self.tabwidth)
             if raw == len(prefix):
                 # only whitespace to the left
                 self.reindent_to(effective + self.indentwidth)
@@ -1410,86 +1458,6 @@ class EditorWindow(object):
             return _icis(_startindex + "+%dc" % offset)
         return inner
 
-    def indent_region_event(self, event):
-        head, tail, chars, lines = self.get_region()
-        for pos in range(len(lines)):
-            line = lines[pos]
-            if line:
-                raw, effective = classifyws(line, self.tabwidth)
-                effective = effective + self.indentwidth
-                lines[pos] = self._make_blanks(effective) + line[raw:]
-        self.set_region(head, tail, chars, lines)
-        return "break"
-
-    def dedent_region_event(self, event):
-        head, tail, chars, lines = self.get_region()
-        for pos in range(len(lines)):
-            line = lines[pos]
-            if line:
-                raw, effective = classifyws(line, self.tabwidth)
-                effective = max(effective - self.indentwidth, 0)
-                lines[pos] = self._make_blanks(effective) + line[raw:]
-        self.set_region(head, tail, chars, lines)
-        return "break"
-
-    def comment_region_event(self, event):
-        head, tail, chars, lines = self.get_region()
-        for pos in range(len(lines) - 1):
-            line = lines[pos]
-            lines[pos] = '##' + line
-        self.set_region(head, tail, chars, lines)
-        return "break"
-
-    def uncomment_region_event(self, event):
-        head, tail, chars, lines = self.get_region()
-        for pos in range(len(lines)):
-            line = lines[pos]
-            if not line:
-                continue
-            if line[:2] == '##':
-                line = line[2:]
-            elif line[:1] == '#':
-                line = line[1:]
-            lines[pos] = line
-        self.set_region(head, tail, chars, lines)
-        return "break"
-
-    def tabify_region_event(self, event):
-        head, tail, chars, lines = self.get_region()
-        tabwidth = self._asktabwidth()
-        if tabwidth is None: return
-        for pos in range(len(lines)):
-            line = lines[pos]
-            if line:
-                raw, effective = classifyws(line, tabwidth)
-                ntabs, nspaces = divmod(effective, tabwidth)
-                lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
-        self.set_region(head, tail, chars, lines)
-        return "break"
-
-    def untabify_region_event(self, event):
-        head, tail, chars, lines = self.get_region()
-        tabwidth = self._asktabwidth()
-        if tabwidth is None: return
-        for pos in range(len(lines)):
-            lines[pos] = lines[pos].expandtabs(tabwidth)
-        self.set_region(head, tail, chars, lines)
-        return "break"
-
-    def toggle_tabs_event(self, event):
-        if self.askyesno(
-              "Toggle tabs",
-              "Turn tabs " + ("on", "off")[self.usetabs] +
-              "?\nIndent width " +
-              ("will be", "remains at")[self.usetabs] + " 8." +
-              "\n Note: a tab is always 8 columns",
-              parent=self.text):
-            self.usetabs = not self.usetabs
-            # Try to prevent inconsistent indentation.
-            # User must change indent width manually after using tabs.
-            self.indentwidth = 8
-        return "break"
-
     # XXX this isn't bound to anything -- see tabwidth comments
 ##     def change_tabwidth_event(self, event):
 ##         new = self._asktabwidth()
@@ -1498,45 +1466,6 @@ class EditorWindow(object):
 ##             self.set_indentation_params(0, guess=0)
 ##         return "break"
 
-    def change_indentwidth_event(self, event):
-        new = self.askinteger(
-                  "Indent width",
-                  "New indent width (2-16)\n(Always use 8 when using tabs)",
-                  parent=self.text,
-                  initialvalue=self.indentwidth,
-                  minvalue=2,
-                  maxvalue=16)
-        if new and new != self.indentwidth and not self.usetabs:
-            self.indentwidth = new
-        return "break"
-
-    def get_region(self):
-        text = self.text
-        first, last = self.get_selection_indices()
-        if first and last:
-            head = text.index(first + " linestart")
-            tail = text.index(last + "-1c lineend +1c")
-        else:
-            head = text.index("insert linestart")
-            tail = text.index("insert lineend +1c")
-        chars = text.get(head, tail)
-        lines = chars.split("\n")
-        return head, tail, chars, lines
-
-    def set_region(self, head, tail, chars, lines):
-        text = self.text
-        newchars = "\n".join(lines)
-        if newchars == chars:
-            text.bell()
-            return
-        text.tag_remove("sel", "1.0", "end")
-        text.mark_set("insert", head)
-        text.undo_block_start()
-        text.delete(head, tail)
-        text.insert(head, newchars)
-        text.undo_block_stop()
-        text.tag_add("sel", head, "insert")
-
     # Make string that displays as n leading blanks.
 
     def _make_blanks(self, n):
@@ -1558,15 +1487,6 @@ class EditorWindow(object):
             text.insert("insert", self._make_blanks(column))
         text.undo_block_stop()
 
-    def _asktabwidth(self):
-        return self.askinteger(
-            "Tab width",
-            "Columns per tab? (2-16)",
-            parent=self.text,
-            initialvalue=self.indentwidth,
-            minvalue=2,
-            maxvalue=16)
-
     # Guess indentwidth from text content.
     # Return guessed indentwidth.  This should not be believed unless
     # it's in a reasonable range (e.g., it will be 0 if no indented
@@ -1575,33 +1495,39 @@ class EditorWindow(object):
     def guess_indent(self):
         opener, indented = IndentSearcher(self.text, self.tabwidth).run()
         if opener and indented:
-            raw, indentsmall = classifyws(opener, self.tabwidth)
-            raw, indentlarge = classifyws(indented, self.tabwidth)
+            raw, indentsmall = get_line_indent(opener, self.tabwidth)
+            raw, indentlarge = get_line_indent(indented, self.tabwidth)
         else:
             indentsmall = indentlarge = 0
         return indentlarge - indentsmall
 
+    def toggle_line_numbers_event(self, event=None):
+        if self.line_numbers is None:
+            return
+
+        if self.line_numbers.is_shown:
+            self.line_numbers.hide_sidebar()
+            menu_label = "Show"
+        else:
+            self.line_numbers.show_sidebar()
+            menu_label = "Hide"
+        self.update_menu_label(menu='options', index='*Line Numbers',
+                               label=f'{menu_label} Line Numbers')
+
 # "line.col" -> line, as an int
 def index2line(index):
     return int(float(index))
 
-# Look at the leading whitespace in s.
-# Return pair (# of leading ws characters,
-#              effective # of leading blanks after expanding
-#              tabs to width tabwidth)
-
-def classifyws(s, tabwidth):
-    raw = effective = 0
-    for ch in s:
-        if ch == ' ':
-            raw = raw + 1
-            effective = effective + 1
-        elif ch == '\t':
-            raw = raw + 1
-            effective = (effective // tabwidth + 1) * tabwidth
-        else:
-            break
-    return raw, effective
+
+_line_indent_re = re.compile(r'[ \t]*')
+def get_line_indent(line, tabwidth):
+    """Return a line's indentation as (# chars, effective # of spaces).
+
+    The effective # of spaces is the length after properly "expanding"
+    the tabs into spaces, as done by str.expandtabs(tabwidth).
+    """
+    m = _line_indent_re.match(line)
+    return m.end(), len(m.group().expandtabs(tabwidth))
 
 
 class IndentSearcher(object):
diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py
new file mode 100644 (file)
index 0000000..bced4c1
--- /dev/null
@@ -0,0 +1,417 @@
+"""Format all or a selected region (line slice) of text.
+
+Region formatting options: paragraph, comment block, indent, deindent,
+comment, uncomment, tabify, and untabify.
+
+File renamed from paragraph.py with functions added from editor.py.
+"""
+import re
+from tkinter.messagebox import askyesno
+from tkinter.simpledialog import askinteger
+from idlelib.config import idleConf
+
+
+class FormatParagraph:
+    """Format a paragraph, comment block, or selection to a max width.
+
+    Does basic, standard text formatting, and also understands Python
+    comment blocks. Thus, for editing Python source code, this
+    extension is really only suitable for reformatting these comment
+    blocks or triple-quoted strings.
+
+    Known problems with comment reformatting:
+    * If there is a selection marked, and the first line of the
+      selection is not complete, the block will probably not be detected
+      as comments, and will have the normal "text formatting" rules
+      applied.
+    * If a comment block has leading whitespace that mixes tabs and
+      spaces, they will not be considered part of the same block.
+    * Fancy comments, like this bulleted list, aren't handled :-)
+    """
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    @classmethod
+    def reload(cls):
+        cls.max_width = idleConf.GetOption('extensions', 'FormatParagraph',
+                                           'max-width', type='int', default=72)
+
+    def close(self):
+        self.editwin = None
+
+    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
+        at the max width, starting from the beginning selection.
+
+        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.
+        """
+        limit = self.max_width if limit is None else limit
+        text = self.editwin.text
+        first, last = self.editwin.get_selection_indices()
+        if first and last:
+            data = text.get(first, last)
+            comment_header = get_comment_header(data)
+        else:
+            first, last, comment_header, data = \
+                    find_paragraph(text, text.index("insert"))
+        if comment_header:
+            newdata = reformat_comment(data, limit, comment_header)
+        else:
+            newdata = reformat_paragraph(data, limit)
+        text.tag_remove("sel", "1.0", "end")
+
+        if newdata != data:
+            text.mark_set("insert", first)
+            text.undo_block_start()
+            text.delete(first, last)
+            text.insert(first, newdata)
+            text.undo_block_stop()
+        else:
+            text.mark_set("insert", last)
+        text.see("insert")
+        return "break"
+
+
+FormatParagraph.reload()
+
+def find_paragraph(text, mark):
+    """Returns the start/stop indices enclosing the paragraph that mark is in.
+
+    Also returns the comment format string, if any, and paragraph of text
+    between the start/stop indices.
+    """
+    lineno, col = map(int, mark.split("."))
+    line = text.get("%d.0" % lineno, "%d.end" % lineno)
+
+    # Look for start of next paragraph if the index passed in is a blank line
+    while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line):
+        lineno = lineno + 1
+        line = text.get("%d.0" % lineno, "%d.end" % lineno)
+    first_lineno = lineno
+    comment_header = get_comment_header(line)
+    comment_header_len = len(comment_header)
+
+    # Once start line found, search for end of paragraph (a blank line)
+    while get_comment_header(line)==comment_header and \
+              not is_all_white(line[comment_header_len:]):
+        lineno = lineno + 1
+        line = text.get("%d.0" % lineno, "%d.end" % lineno)
+    last = "%d.0" % lineno
+
+    # Search back to beginning of paragraph (first blank line before)
+    lineno = first_lineno - 1
+    line = text.get("%d.0" % lineno, "%d.end" % lineno)
+    while lineno > 0 and \
+              get_comment_header(line)==comment_header and \
+              not is_all_white(line[comment_header_len:]):
+        lineno = lineno - 1
+        line = text.get("%d.0" % lineno, "%d.end" % lineno)
+    first = "%d.0" % (lineno+1)
+
+    return first, last, comment_header, text.get(first, last)
+
+# This should perhaps be replaced with textwrap.wrap
+def reformat_paragraph(data, limit):
+    """Return data reformatted to specified width (limit)."""
+    lines = data.split("\n")
+    i = 0
+    n = len(lines)
+    while i < n and is_all_white(lines[i]):
+        i = i+1
+    if i >= n:
+        return data
+    indent1 = get_indent(lines[i])
+    if i+1 < n and not is_all_white(lines[i+1]):
+        indent2 = get_indent(lines[i+1])
+    else:
+        indent2 = indent1
+    new = lines[:i]
+    partial = indent1
+    while i < n and not is_all_white(lines[i]):
+        # XXX Should take double space after period (etc.) into account
+        words = re.split(r"(\s+)", lines[i])
+        for j in range(0, len(words), 2):
+            word = words[j]
+            if not word:
+                continue # Can happen when line ends in whitespace
+            if len((partial + word).expandtabs()) > limit and \
+                   partial != indent1:
+                new.append(partial.rstrip())
+                partial = indent2
+            partial = partial + word + " "
+            if j+1 < len(words) and words[j+1] != " ":
+                partial = partial + " "
+        i = i+1
+    new.append(partial.rstrip())
+    # XXX Should reformat remaining paragraphs as well
+    new.extend(lines[i:])
+    return "\n".join(new)
+
+def reformat_comment(data, limit, comment_header):
+    """Return data reformatted to specified width with comment header."""
+
+    # Remove header from the comment lines
+    lc = len(comment_header)
+    data = "\n".join(line[lc:] for line in data.split("\n"))
+    # Reformat to maxformatwidth chars or a 20 char width,
+    # whichever is greater.
+    format_width = max(limit - len(comment_header), 20)
+    newdata = reformat_paragraph(data, format_width)
+    # re-split and re-insert the comment header.
+    newdata = newdata.split("\n")
+    # If the block ends in a \n, we don't want the comment prefix
+    # inserted after it. (Im not sure it makes sense to reformat a
+    # comment block that is not made of complete lines, but whatever!)
+    # Can't think of a clean solution, so we hack away
+    block_suffix = ""
+    if not newdata[-1]:
+        block_suffix = "\n"
+        newdata = newdata[:-1]
+    return '\n'.join(comment_header+line for line in newdata) + block_suffix
+
+def is_all_white(line):
+    """Return True if line is empty or all whitespace."""
+
+    return re.match(r"^\s*$", line) is not None
+
+def get_indent(line):
+    """Return the initial space or tab indent of line."""
+    return re.match(r"^([ \t]*)", line).group()
+
+def get_comment_header(line):
+    """Return string with leading whitespace and '#' from line or ''.
+
+    A null return indicates that the line is not a comment line. A non-
+    null return, such as '    #', will be used to find the other lines of
+    a comment block with the same  indent.
+    """
+    m = re.match(r"^([ \t]*#*)", line)
+    if m is None: return ""
+    return m.group(1)
+
+
+# Copied from editor.py; importing it would cause an import cycle.
+_line_indent_re = re.compile(r'[ \t]*')
+
+def get_line_indent(line, tabwidth):
+    """Return a line's indentation as (# chars, effective # of spaces).
+
+    The effective # of spaces is the length after properly "expanding"
+    the tabs into spaces, as done by str.expandtabs(tabwidth).
+    """
+    m = _line_indent_re.match(line)
+    return m.end(), len(m.group().expandtabs(tabwidth))
+
+
+class FormatRegion:
+    "Format selected text (region)."
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    def get_region(self):
+        """Return line information about the selected text region.
+
+        If text is selected, the first and last indices will be
+        for the selection.  If there is no text selected, the
+        indices will be the current cursor location.
+
+        Return a tuple containing (first index, last index,
+            string representation of text, list of text lines).
+        """
+        text = self.editwin.text
+        first, last = self.editwin.get_selection_indices()
+        if first and last:
+            head = text.index(first + " linestart")
+            tail = text.index(last + "-1c lineend +1c")
+        else:
+            head = text.index("insert linestart")
+            tail = text.index("insert lineend +1c")
+        chars = text.get(head, tail)
+        lines = chars.split("\n")
+        return head, tail, chars, lines
+
+    def set_region(self, head, tail, chars, lines):
+        """Replace the text between the given indices.
+
+        Args:
+            head: Starting index of text to replace.
+            tail: Ending index of text to replace.
+            chars: Expected to be string of current text
+                between head and tail.
+            lines: List of new lines to insert between head
+                and tail.
+        """
+        text = self.editwin.text
+        newchars = "\n".join(lines)
+        if newchars == chars:
+            text.bell()
+            return
+        text.tag_remove("sel", "1.0", "end")
+        text.mark_set("insert", head)
+        text.undo_block_start()
+        text.delete(head, tail)
+        text.insert(head, newchars)
+        text.undo_block_stop()
+        text.tag_add("sel", head, "insert")
+
+    def indent_region_event(self, event=None):
+        "Indent region by indentwidth spaces."
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if line:
+                raw, effective = get_line_indent(line, self.editwin.tabwidth)
+                effective = effective + self.editwin.indentwidth
+                lines[pos] = self.editwin._make_blanks(effective) + line[raw:]
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def dedent_region_event(self, event=None):
+        "Dedent region by indentwidth spaces."
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if line:
+                raw, effective = get_line_indent(line, self.editwin.tabwidth)
+                effective = max(effective - self.editwin.indentwidth, 0)
+                lines[pos] = self.editwin._make_blanks(effective) + line[raw:]
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def comment_region_event(self, event=None):
+        """Comment out each line in region.
+
+        ## is appended to the beginning of each line to comment it out.
+        """
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines) - 1):
+            line = lines[pos]
+            lines[pos] = '##' + line
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def uncomment_region_event(self, event=None):
+        """Uncomment each line in region.
+
+        Remove ## or # in the first positions of a line.  If the comment
+        is not in the beginning position, this command will have no effect.
+        """
+        head, tail, chars, lines = self.get_region()
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if not line:
+                continue
+            if line[:2] == '##':
+                line = line[2:]
+            elif line[:1] == '#':
+                line = line[1:]
+            lines[pos] = line
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def tabify_region_event(self, event=None):
+        "Convert leading spaces to tabs for each line in selected region."
+        head, tail, chars, lines = self.get_region()
+        tabwidth = self._asktabwidth()
+        if tabwidth is None:
+            return
+        for pos in range(len(lines)):
+            line = lines[pos]
+            if line:
+                raw, effective = get_line_indent(line, tabwidth)
+                ntabs, nspaces = divmod(effective, tabwidth)
+                lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def untabify_region_event(self, event=None):
+        "Expand tabs to spaces for each line in region."
+        head, tail, chars, lines = self.get_region()
+        tabwidth = self._asktabwidth()
+        if tabwidth is None:
+            return
+        for pos in range(len(lines)):
+            lines[pos] = lines[pos].expandtabs(tabwidth)
+        self.set_region(head, tail, chars, lines)
+        return "break"
+
+    def _asktabwidth(self):
+        "Return value for tab width."
+        return askinteger(
+            "Tab width",
+            "Columns per tab? (2-16)",
+            parent=self.editwin.text,
+            initialvalue=self.editwin.indentwidth,
+            minvalue=2,
+            maxvalue=16)
+
+
+# With mixed indents not allowed, these are semi-useless and not unittested.
+class Indents:  # pragma: no cover
+    "Change future indents."
+
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    def toggle_tabs_event(self, event):
+        editwin = self.editwin
+        usetabs = editwin.usetabs
+        if askyesno(
+              "Toggle tabs",
+              "Turn tabs " + ("on", "off")[usetabs] +
+              "?\nIndent width " +
+              ("will be", "remains at")[usetabs] + " 8." +
+              "\n Note: a tab is always 8 columns",
+              parent=editwin.text):
+            editwin.usetabs = not usetabs
+            # Try to prevent inconsistent indentation.
+            # User must change indent width manually after using tabs.
+            editwin.indentwidth = 8
+        return "break"
+
+    def change_indentwidth_event(self, event):
+        editwin = self.editwin
+        new = askinteger(
+                  "Indent width",
+                  "New indent width (2-16)\n(Always use 8 when using tabs)",
+                  parent=editwin.text,
+                  initialvalue=editwin.indentwidth,
+                  minvalue=2,
+                  maxvalue=16)
+        if new and new != editwin.indentwidth and not editwin.usetabs:
+            editwin.indentwidth = new
+        return "break"
+
+
+class Rstrip:  # 'Strip Trailing Whitespace" on "Format" menu.
+    def __init__(self, editwin):
+        self.editwin = editwin
+
+    def do_rstrip(self, event=None):
+        text = self.editwin.text
+        undo = self.editwin.undo
+        undo.undo_block_start()
+
+        end_line = int(float(text.index('end')))
+        for cur in range(1, end_line):
+            txt = text.get('%i.0' % cur, '%i.end' % cur)
+            raw = len(txt)
+            cut = len(txt.rstrip())
+            # Since text.delete() marks file as changed, even if not,
+            # only call it when needed to actually delete something.
+            if cut < raw:
+                text.delete('%i.%i' % (cur, cut), '%i.end' % cur)
+
+        undo.undo_block_stop()
+
+
+if __name__ == "__main__":
+    from unittest import main
+    main('idlelib.idle_test.test_format', verbosity=2, exit=False)
index 91803fd06c8f1eab0ea5e342ed76472d474c6539..0754f2453baf669770b8ceff086acc85a5cd5ab7 100644 (file)
@@ -1,11 +1,9 @@
 
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!DOCTYPE html>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
-    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta charset="utf-8" />
     <title>IDLE &#8212; Python 3.9.0a0 documentation</title>
     <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
     <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@@ -14,7 +12,7 @@
     <script type="text/javascript" src="../_static/jquery.js"></script>
     <script type="text/javascript" src="../_static/underscore.js"></script>
     <script type="text/javascript" src="../_static/doctools.js"></script>
-    <script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+    <script type="text/javascript" src="../_static/language_data.js"></script>
 
     <script type="text/javascript" src="../_static/sidebar.js"></script>
 
 <p>IDLE is Python’s Integrated Development and Learning Environment.</p>
 <p>IDLE has the following features:</p>
 <ul class="simple">
-<li>coded in 100% pure Python, using the <a class="reference internal" href="tkinter.html#module-tkinter" title="tkinter: Interface to Tcl/Tk for graphical user interfaces"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter</span></code></a> GUI toolkit</li>
-<li>cross-platform: works mostly the same on Windows, Unix, and macOS</li>
-<li>Python shell window (interactive interpreter) with colorizing
-of code input, output, and error messages</li>
-<li>multi-window text editor with multiple undo, Python colorizing,
-smart indent, call tips, auto completion, and other features</li>
-<li>search within any window, replace within editor windows, and search
-through multiple files (grep)</li>
-<li>debugger with persistent breakpoints, stepping, and viewing
-of global and local namespaces</li>
-<li>configuration, browsers, and other dialogs</li>
+<li><p>coded in 100% pure Python, using the <a class="reference internal" href="tkinter.html#module-tkinter" title="tkinter: Interface to Tcl/Tk for graphical user interfaces"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter</span></code></a> GUI toolkit</p></li>
+<li><p>cross-platform: works mostly the same on Windows, Unix, and macOS</p></li>
+<li><p>Python shell window (interactive interpreter) with colorizing
+of code input, output, and error messages</p></li>
+<li><p>multi-window text editor with multiple undo, Python colorizing,
+smart indent, call tips, auto completion, and other features</p></li>
+<li><p>search within any window, replace within editor windows, and search
+through multiple files (grep)</p></li>
+<li><p>debugger with persistent breakpoints, stepping, and viewing
+of global and local namespaces</p></li>
+<li><p>configuration, browsers, and other dialogs</p></li>
 </ul>
 <div class="section" id="menus">
 <h2>Menus<a class="headerlink" href="#menus" title="Permalink to this headline">¶</a></h2>
@@ -134,207 +132,216 @@ to the window currently selected.  It has an IDLE menu, and some entries
 described below are moved around to conform to Apple guidelines.</p>
 <div class="section" id="file-menu-shell-and-editor">
 <h3>File menu (Shell and Editor)<a class="headerlink" href="#file-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>New File</dt>
-<dd>Create a new file editing window.</dd>
-<dt>Open…</dt>
-<dd>Open an existing file with an Open dialog.</dd>
-<dt>Recent Files</dt>
-<dd>Open a list of recent files.  Click one to open it.</dd>
-<dt>Open Module…</dt>
-<dd>Open an existing module (searches sys.path).</dd>
+<dl class="simple">
+<dt>New File</dt><dd><p>Create a new file editing window.</p>
+</dd>
+<dt>Open…</dt><dd><p>Open an existing file with an Open dialog.</p>
+</dd>
+<dt>Recent Files</dt><dd><p>Open a list of recent files.  Click one to open it.</p>
+</dd>
+<dt>Open Module…</dt><dd><p>Open an existing module (searches sys.path).</p>
+</dd>
 </dl>
-<dl class="docutils" id="index-1">
-<dt>Class Browser</dt>
-<dd>Show functions, classes, and methods in the current Editor file in a
-tree structure.  In the shell, open a module first.</dd>
-<dt>Path Browser</dt>
-<dd>Show sys.path directories, modules, functions, classes and methods in a
-tree structure.</dd>
-<dt>Save</dt>
-<dd>Save the current window to the associated file, if there is one.  Windows
+<dl class="simple" id="index-1">
+<dt>Class Browser</dt><dd><p>Show functions, classes, and methods in the current Editor file in a
+tree structure.  In the shell, open a module first.</p>
+</dd>
+<dt>Path Browser</dt><dd><p>Show sys.path directories, modules, functions, classes and methods in a
+tree structure.</p>
+</dd>
+<dt>Save</dt><dd><p>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.</dd>
-<dt>Save As…</dt>
-<dd>Save the current window with a Save As dialog.  The file saved becomes the
-new associated file for the window.</dd>
-<dt>Save Copy As…</dt>
-<dd>Save the current window to different file without changing the associated
-file.</dd>
-<dt>Print Window</dt>
-<dd>Print the current window to the default printer.</dd>
-<dt>Close</dt>
-<dd>Close the current window (ask to save if unsaved).</dd>
-<dt>Exit</dt>
-<dd>Close all windows and quit IDLE (ask to save unsaved windows).</dd>
+do Save As instead.</p>
+</dd>
+<dt>Save As…</dt><dd><p>Save the current window with a Save As dialog.  The file saved becomes the
+new associated file for the window.</p>
+</dd>
+<dt>Save Copy As…</dt><dd><p>Save the current window to different file without changing the associated
+file.</p>
+</dd>
+<dt>Print Window</dt><dd><p>Print the current window to the default printer.</p>
+</dd>
+<dt>Close</dt><dd><p>Close the current window (ask to save if unsaved).</p>
+</dd>
+<dt>Exit</dt><dd><p>Close all windows and quit IDLE (ask to save unsaved windows).</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="edit-menu-shell-and-editor">
 <h3>Edit menu (Shell and Editor)<a class="headerlink" href="#edit-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>Undo</dt>
-<dd>Undo the last change to the current window.  A maximum of 1000 changes may
-be undone.</dd>
-<dt>Redo</dt>
-<dd>Redo the last undone change to the current window.</dd>
-<dt>Cut</dt>
-<dd>Copy selection into the system-wide clipboard; then delete the selection.</dd>
-<dt>Copy</dt>
-<dd>Copy selection into the system-wide clipboard.</dd>
-<dt>Paste</dt>
-<dd>Insert contents of the system-wide clipboard into the current window.</dd>
+<dl class="simple">
+<dt>Undo</dt><dd><p>Undo the last change to the current window.  A maximum of 1000 changes may
+be undone.</p>
+</dd>
+<dt>Redo</dt><dd><p>Redo the last undone change to the current window.</p>
+</dd>
+<dt>Cut</dt><dd><p>Copy selection into the system-wide clipboard; then delete the selection.</p>
+</dd>
+<dt>Copy</dt><dd><p>Copy selection into the system-wide clipboard.</p>
+</dd>
+<dt>Paste</dt><dd><p>Insert contents of the system-wide clipboard into the current window.</p>
+</dd>
 </dl>
 <p>The clipboard functions are also available in context menus.</p>
-<dl class="docutils">
-<dt>Select All</dt>
-<dd>Select the entire contents of the current window.</dd>
-<dt>Find…</dt>
-<dd>Open a search dialog with many options</dd>
-<dt>Find Again</dt>
-<dd>Repeat the last search, if there is one.</dd>
-<dt>Find Selection</dt>
-<dd>Search for the currently selected string, if there is one.</dd>
-<dt>Find in Files…</dt>
-<dd>Open a file search dialog.  Put results in a new output window.</dd>
-<dt>Replace…</dt>
-<dd>Open a search-and-replace dialog.</dd>
-<dt>Go to Line</dt>
-<dd>Move cursor to the line number requested and make that line visible.</dd>
-<dt>Show Completions</dt>
-<dd>Open a scrollable list allowing selection of keywords and attributes. See
-<a class="reference internal" href="#completions"><span class="std std-ref">Completions</span></a> in the Editing and navigation section below.</dd>
-<dt>Expand Word</dt>
-<dd>Expand a prefix you have typed to match a full word in the same window;
-repeat to get a different expansion.</dd>
-<dt>Show call tip</dt>
-<dd>After an unclosed parenthesis for a function, open a small window with
+<dl class="simple">
+<dt>Select All</dt><dd><p>Select the entire contents of the current window.</p>
+</dd>
+<dt>Find…</dt><dd><p>Open a search dialog with many options</p>
+</dd>
+<dt>Find Again</dt><dd><p>Repeat the last search, if there is one.</p>
+</dd>
+<dt>Find Selection</dt><dd><p>Search for the currently selected string, if there is one.</p>
+</dd>
+<dt>Find in Files…</dt><dd><p>Open a file search dialog.  Put results in a new output window.</p>
+</dd>
+<dt>Replace…</dt><dd><p>Open a search-and-replace dialog.</p>
+</dd>
+<dt>Go to Line</dt><dd><p>Move cursor to the line number requested and make that line visible.</p>
+</dd>
+<dt>Show Completions</dt><dd><p>Open a scrollable list allowing selection of keywords and attributes. See
+<a class="reference internal" href="#completions"><span class="std std-ref">Completions</span></a> in the Editing and navigation section below.</p>
+</dd>
+<dt>Expand Word</dt><dd><p>Expand a prefix you have typed to match a full word in the same window;
+repeat to get a different expansion.</p>
+</dd>
+<dt>Show call tip</dt><dd><p>After an unclosed parenthesis for a function, open a small window with
 function parameter hints.  See <a class="reference internal" href="#calltips"><span class="std std-ref">Calltips</span></a> in the
-Editing and navigation section below.</dd>
-<dt>Show surrounding parens</dt>
-<dd>Highlight the surrounding parenthesis.</dd>
+Editing and navigation section below.</p>
+</dd>
+<dt>Show surrounding parens</dt><dd><p>Highlight the surrounding parenthesis.</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="format-menu-editor-window-only">
 <span id="format-menu"></span><h3>Format menu (Editor window only)<a class="headerlink" href="#format-menu-editor-window-only" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>Indent Region</dt>
-<dd>Shift selected lines right by the indent width (default 4 spaces).</dd>
-<dt>Dedent Region</dt>
-<dd>Shift selected lines left by the indent width (default 4 spaces).</dd>
-<dt>Comment Out Region</dt>
-<dd>Insert ## in front of selected lines.</dd>
-<dt>Uncomment Region</dt>
-<dd>Remove leading # or ## from selected lines.</dd>
-<dt>Tabify Region</dt>
-<dd>Turn <em>leading</em> stretches of spaces into tabs. (Note: We recommend using
-4 space blocks to indent Python code.)</dd>
-<dt>Untabify Region</dt>
-<dd>Turn <em>all</em> tabs into the correct number of spaces.</dd>
-<dt>Toggle Tabs</dt>
-<dd>Open a dialog to switch between indenting with spaces and tabs.</dd>
-<dt>New Indent Width</dt>
-<dd>Open a dialog to change indent width. The accepted default by the Python
-community is 4 spaces.</dd>
-<dt>Format Paragraph</dt>
-<dd>Reformat the current blank-line-delimited paragraph in comment block or
+<dl class="simple">
+<dt>Indent Region</dt><dd><p>Shift selected lines right by the indent width (default 4 spaces).</p>
+</dd>
+<dt>Dedent Region</dt><dd><p>Shift selected lines left by the indent width (default 4 spaces).</p>
+</dd>
+<dt>Comment Out Region</dt><dd><p>Insert ## in front of selected lines.</p>
+</dd>
+<dt>Uncomment Region</dt><dd><p>Remove leading # or ## from selected lines.</p>
+</dd>
+<dt>Tabify Region</dt><dd><p>Turn <em>leading</em> stretches of spaces into tabs. (Note: We recommend using
+4 space blocks to indent Python code.)</p>
+</dd>
+<dt>Untabify Region</dt><dd><p>Turn <em>all</em> tabs into the correct number of spaces.</p>
+</dd>
+<dt>Toggle Tabs</dt><dd><p>Open a dialog to switch between indenting with spaces and tabs.</p>
+</dd>
+<dt>New Indent Width</dt><dd><p>Open a dialog to change indent width. The accepted default by the Python
+community is 4 spaces.</p>
+</dd>
+<dt>Format Paragraph</dt><dd><p>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.</dd>
-<dt>Strip trailing whitespace</dt>
-<dd>Remove trailing space and other whitespace characters after the last
+paragraph will be formatted to less than N columns, where N defaults to 72.</p>
+</dd>
+<dt>Strip trailing whitespace</dt><dd><p>Remove trailing space and other whitespace characters after the last
 non-whitespace character of a line by applying str.rstrip to each line,
-including lines within multiline strings.</dd>
+including lines within multiline strings.</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="run-menu-editor-window-only">
 <span id="index-2"></span><h3>Run menu (Editor window only)<a class="headerlink" href="#run-menu-editor-window-only" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils" id="python-shell">
-<dt>Python Shell</dt>
-<dd>Open or wake up the Python Shell window.</dd>
-</dl>
-<dl class="docutils" id="check-module">
-<dt>Check Module</dt>
-<dd>Check the syntax of the module currently open in the Editor window. If the
-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.</dd>
-</dl>
-<dl class="docutils" id="run-module">
-<dt>Run Module</dt>
-<dd>Do <a class="reference internal" href="#check-module"><span class="std std-ref">Check Module</span></a>.  If no error, restart the shell to clean the
+<dl class="simple" id="run-module">
+<dt>Run Module</dt><dd><p>Do <a class="reference internal" href="#check-module"><span class="std std-ref">Check Module</span></a>.  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 <code class="docutils literal notranslate"><span class="pre">print</span></code> or <code class="docutils literal notranslate"><span class="pre">write</span></code>.
 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 <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-i</span> <span class="pre">file</span></code> at a command
-line.</dd>
+line.</p>
+</dd>
 </dl>
-<dl class="docutils" id="run-custom">
-<dt>Run… Customized</dt>
-<dd>Same as <a class="reference internal" href="#run-module"><span class="std std-ref">Run Module</span></a>, but run the module with customized
+<dl class="simple" id="run-custom">
+<dt>Run… Customized</dt><dd><p>Same as <a class="reference internal" href="#run-module"><span class="std std-ref">Run Module</span></a>, but run the module with customized
 settings.  <em>Command Line Arguments</em> extend <a class="reference internal" href="sys.html#sys.argv" title="sys.argv"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.argv</span></code></a> as if passed
-on a command line. The module can be run in the Shell without restarting.</dd>
+on a command line. The module can be run in the Shell without restarting.</p>
+</dd>
+</dl>
+<dl class="simple" id="check-module">
+<dt>Check Module</dt><dd><p>Check the syntax of the module currently open in the Editor window. If the
+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.</p>
+</dd>
+</dl>
+<dl class="simple" id="python-shell">
+<dt>Python Shell</dt><dd><p>Open or wake up the Python Shell window.</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="shell-menu-shell-window-only">
 <h3>Shell menu (Shell window only)<a class="headerlink" href="#shell-menu-shell-window-only" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>View Last Restart</dt>
-<dd>Scroll the shell window to the last Shell restart.</dd>
-<dt>Restart Shell</dt>
-<dd>Restart the shell to clean the environment.</dd>
-<dt>Previous History</dt>
-<dd>Cycle through earlier commands in history which match the current entry.</dd>
-<dt>Next History</dt>
-<dd>Cycle through later commands in history which match the current entry.</dd>
-<dt>Interrupt Execution</dt>
-<dd>Stop a running program.</dd>
+<dl class="simple">
+<dt>View Last Restart</dt><dd><p>Scroll the shell window to the last Shell restart.</p>
+</dd>
+<dt>Restart Shell</dt><dd><p>Restart the shell to clean the environment.</p>
+</dd>
+<dt>Previous History</dt><dd><p>Cycle through earlier commands in history which match the current entry.</p>
+</dd>
+<dt>Next History</dt><dd><p>Cycle through later commands in history which match the current entry.</p>
+</dd>
+<dt>Interrupt Execution</dt><dd><p>Stop a running program.</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="debug-menu-shell-window-only">
 <h3>Debug menu (Shell window only)<a class="headerlink" href="#debug-menu-shell-window-only" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>Go to File/Line</dt>
-<dd>Look on the current line. with the cursor, and the line above for a filename
+<dl class="simple">
+<dt>Go to File/Line</dt><dd><p>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.</dd>
+the Shell window and Output windows.</p>
+</dd>
 </dl>
-<dl class="docutils" id="index-3">
-<dt>Debugger (toggle)</dt>
-<dd>When activated, code entered in the Shell or run from an Editor will run
+<dl class="simple" id="index-3">
+<dt>Debugger (toggle)</dt><dd><p>When activated, 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.</dd>
-<dt>Stack Viewer</dt>
-<dd>Show the stack traceback of the last exception in a tree widget, with
-access to locals and globals.</dd>
-<dt>Auto-open Stack Viewer</dt>
-<dd>Toggle automatically opening the stack viewer on an unhandled exception.</dd>
+menu.  This feature is still incomplete and somewhat experimental.</p>
+</dd>
+<dt>Stack Viewer</dt><dd><p>Show the stack traceback of the last exception in a tree widget, with
+access to locals and globals.</p>
+</dd>
+<dt>Auto-open Stack Viewer</dt><dd><p>Toggle automatically opening the stack viewer on an unhandled exception.</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="options-menu-shell-and-editor">
 <h3>Options menu (Shell and Editor)<a class="headerlink" href="#options-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>Configure IDLE</dt>
-<dd>Open a configuration dialog and change preferences for the following:
+<dl class="simple">
+<dt>Configure IDLE</dt><dd><p>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.  On macOS,  open the
+size, additional help sources, and extensions.  On macOS, open the
 configuration dialog by selecting Preferences in the application
-menu. For more, see
-<a class="reference internal" href="#preferences"><span class="std std-ref">Setting preferences</span></a> under Help and preferences.</dd>
-<dt>Show/Hide Code Context (Editor Window only)</dt>
-<dd>Open a pane at the top of the edit window which shows the block context
+menu. For more details, see
+<a class="reference internal" href="#preferences"><span class="std std-ref">Setting preferences</span></a> under Help and preferences.</p>
+</dd>
+</dl>
+<p>Most configuration options apply to all windows or all future windows.
+The option items below only apply to the active window.</p>
+<dl class="simple">
+<dt>Show/Hide Code Context (Editor Window only)</dt><dd><p>Open a pane at the top of the edit window which shows the block context
 of the code which has scrolled above the top of the window.  See
-<a class="reference internal" href="#code-context"><span class="std std-ref">Code Context</span></a> in the Editing and Navigation section below.</dd>
-<dt>Zoom/Restore Height</dt>
-<dd>Toggles the window between normal size and maximum height. The initial size
+<a class="reference internal" href="#code-context"><span class="std std-ref">Code Context</span></a> in the Editing and Navigation section
+below.</p>
+</dd>
+<dt>Show/Hide Line Numbers (Editor Window only)</dt><dd><p>Open a column to the left of the edit window which shows the number
+of each line of text.  The default is off, which may be changed in the
+preferences (see <a class="reference internal" href="#preferences"><span class="std std-ref">Setting preferences</span></a>).</p>
+</dd>
+<dt>Zoom/Restore Height</dt><dd><p>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 maximum height for a screen is determined by
 momentarily maximizing a window the first time one is zoomed on the screen.
-Changing screen settings may invalidate the saved height.  This toogle has
-no effect when a window is maximized.</dd>
+Changing screen settings may invalidate the saved height.  This toggle has
+no effect when a window is maximized.</p>
+</dd>
 </dl>
 </div>
 <div class="section" id="window-menu-shell-and-editor">
@@ -344,17 +351,17 @@ no effect when a window is maximized.</dd>
 </div>
 <div class="section" id="help-menu-shell-and-editor">
 <h3>Help menu (Shell and Editor)<a class="headerlink" href="#help-menu-shell-and-editor" title="Permalink to this headline">¶</a></h3>
-<dl class="docutils">
-<dt>About IDLE</dt>
-<dd>Display version, copyright, license, credits, and more.</dd>
-<dt>IDLE Help</dt>
-<dd>Display this IDLE document, detailing the menu options, basic editing and
-navigation, and other tips.</dd>
-<dt>Python Docs</dt>
-<dd>Access local Python documentation, if installed, or start a web browser
-and open docs.python.org showing the latest Python documentation.</dd>
-<dt>Turtle Demo</dt>
-<dd>Run the turtledemo module with example Python code and turtle drawings.</dd>
+<dl class="simple">
+<dt>About IDLE</dt><dd><p>Display version, copyright, license, credits, and more.</p>
+</dd>
+<dt>IDLE Help</dt><dd><p>Display this IDLE document, detailing the menu options, basic editing and
+navigation, and other tips.</p>
+</dd>
+<dt>Python Docs</dt><dd><p>Access local Python documentation, if installed, or start a web browser
+and open docs.python.org showing the latest Python documentation.</p>
+</dd>
+<dt>Turtle Demo</dt><dd><p>Run the turtledemo module with example Python code and turtle drawings.</p>
+</dd>
 </dl>
 <p>Additional help sources may be added here with the Configure IDLE dialog under
 the General tab. See the <a class="reference internal" href="#help-sources"><span class="std std-ref">Help sources</span></a> subsection below
@@ -364,34 +371,34 @@ for more on Help menu choices.</p>
 <span id="index-4"></span><h3>Context Menus<a class="headerlink" href="#context-menus" title="Permalink to this headline">¶</a></h3>
 <p>Open a context menu by right-clicking in a window (Control-click on macOS).
 Context menus have the standard clipboard functions also on the Edit menu.</p>
-<dl class="docutils">
-<dt>Cut</dt>
-<dd>Copy selection into the system-wide clipboard; then delete the selection.</dd>
-<dt>Copy</dt>
-<dd>Copy selection into the system-wide clipboard.</dd>
-<dt>Paste</dt>
-<dd>Insert contents of the system-wide clipboard into the current window.</dd>
+<dl class="simple">
+<dt>Cut</dt><dd><p>Copy selection into the system-wide clipboard; then delete the selection.</p>
+</dd>
+<dt>Copy</dt><dd><p>Copy selection into the system-wide clipboard.</p>
+</dd>
+<dt>Paste</dt><dd><p>Insert contents of the system-wide clipboard into the current window.</p>
+</dd>
 </dl>
 <p>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.</p>
-<dl class="docutils">
-<dt>Set Breakpoint</dt>
-<dd>Set a breakpoint on the current line.</dd>
-<dt>Clear Breakpoint</dt>
-<dd>Clear the breakpoint on that line.</dd>
+<dl class="simple">
+<dt>Set Breakpoint</dt><dd><p>Set a breakpoint on the current line.</p>
+</dd>
+<dt>Clear Breakpoint</dt><dd><p>Clear the breakpoint on that line.</p>
+</dd>
 </dl>
 <p>Shell and Output windows also have the following.</p>
-<dl class="docutils">
-<dt>Go to file/line</dt>
-<dd>Same as in Debug menu.</dd>
+<dl class="simple">
+<dt>Go to file/line</dt><dd><p>Same as in Debug menu.</p>
+</dd>
 </dl>
 <p>The Shell window also has an output squeezing facility explained in the <em>Python
 Shell window</em> subsection below.</p>
-<dl class="docutils">
-<dt>Squeeze</dt>
-<dd>If the cursor is over an output line, squeeze all the output between
-the code above and the prompt below down to a ‘Squeezed text’ label.</dd>
+<dl class="simple">
+<dt>Squeeze</dt><dd><p>If the cursor is over an output line, squeeze all the output between
+the code above and the prompt below down to a ‘Squeezed text’ label.</p>
+</dd>
 </dl>
 </div>
 </div>
@@ -414,32 +421,26 @@ and that other files do not.  Run Python code with the Run menu.</p>
 <p>In this section, ‘C’ refers to the <kbd class="kbd docutils literal notranslate">Control</kbd> key on Windows and Unix and
 the <kbd class="kbd docutils literal notranslate">Command</kbd> key on macOS.</p>
 <ul>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">Backspace</kbd> deletes to the left; <kbd class="kbd docutils literal notranslate">Del</kbd> deletes to the right</p>
-</li>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">C-Backspace</kbd> delete word left; <kbd class="kbd docutils literal notranslate">C-Del</kbd> delete word to the right</p>
-</li>
-<li><p class="first">Arrow keys and <kbd class="kbd docutils literal notranslate">Page Up</kbd>/<kbd class="kbd docutils literal notranslate">Page Down</kbd> to move around</p>
-</li>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">C-LeftArrow</kbd> and <kbd class="kbd docutils literal notranslate">C-RightArrow</kbd> moves by words</p>
-</li>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">Home</kbd>/<kbd class="kbd docutils literal notranslate">End</kbd> go to begin/end of line</p>
-</li>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">C-Home</kbd>/<kbd class="kbd docutils literal notranslate">C-End</kbd> go to begin/end of file</p>
-</li>
-<li><p class="first">Some useful Emacs bindings are inherited from Tcl/Tk:</p>
+<li><p><kbd class="kbd docutils literal notranslate">Backspace</kbd> deletes to the left; <kbd class="kbd docutils literal notranslate">Del</kbd> deletes to the right</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-Backspace</kbd> delete word left; <kbd class="kbd docutils literal notranslate">C-Del</kbd> delete word to the right</p></li>
+<li><p>Arrow keys and <kbd class="kbd docutils literal notranslate">Page Up</kbd>/<kbd class="kbd docutils literal notranslate">Page Down</kbd> to move around</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-LeftArrow</kbd> and <kbd class="kbd docutils literal notranslate">C-RightArrow</kbd> moves by words</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">Home</kbd>/<kbd class="kbd docutils literal notranslate">End</kbd> go to begin/end of line</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-Home</kbd>/<kbd class="kbd docutils literal notranslate">C-End</kbd> go to begin/end of file</p></li>
+<li><p>Some useful Emacs bindings are inherited from Tcl/Tk:</p>
 <blockquote>
 <div><ul class="simple">
-<li><kbd class="kbd docutils literal notranslate">C-a</kbd> beginning of line</li>
-<li><kbd class="kbd docutils literal notranslate">C-e</kbd> end of line</li>
-<li><kbd class="kbd docutils literal notranslate">C-k</kbd> kill line (but doesn’t put it in clipboard)</li>
-<li><kbd class="kbd docutils literal notranslate">C-l</kbd> center window around the insertion point</li>
-<li><kbd class="kbd docutils literal notranslate">C-b</kbd> go backward one character without deleting (usually you can
-also use the cursor key for this)</li>
-<li><kbd class="kbd docutils literal notranslate">C-f</kbd> go forward one character without deleting (usually you can
-also use the cursor key for this)</li>
-<li><kbd class="kbd docutils literal notranslate">C-p</kbd> go up one line (usually you can also use the cursor key for
-this)</li>
-<li><kbd class="kbd docutils literal notranslate">C-d</kbd> delete next character</li>
+<li><p><kbd class="kbd docutils literal notranslate">C-a</kbd> beginning of line</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-e</kbd> end of line</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-k</kbd> kill line (but doesn’t put it in clipboard)</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-l</kbd> center window around the insertion point</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-b</kbd> go backward one character without deleting (usually you can
+also use the cursor key for this)</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-f</kbd> go forward one character without deleting (usually you can
+also use the cursor key for this)</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-p</kbd> go up one line (usually you can also use the cursor key for
+this)</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-d</kbd> delete next character</p></li>
 </ul>
 </div></blockquote>
 </li>
@@ -542,17 +543,15 @@ If one pastes more that one statement into Shell, the result will be a
 <p>The editing features described in previous subsections work when entering
 code interactively.  IDLE’s Shell window also responds to the following keys.</p>
 <ul>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">C-c</kbd> interrupts executing command</p>
-</li>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">C-d</kbd> sends end-of-file; closes window if typed at a <code class="docutils literal notranslate"><span class="pre">&gt;&gt;&gt;</span></code> prompt</p>
-</li>
-<li><p class="first"><kbd class="kbd docutils literal notranslate">Alt-/</kbd> (Expand word) is also useful to reduce typing</p>
+<li><p><kbd class="kbd docutils literal notranslate">C-c</kbd> interrupts executing command</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">C-d</kbd> sends end-of-file; closes window if typed at a <code class="docutils literal notranslate"><span class="pre">&gt;&gt;&gt;</span></code> prompt</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">Alt-/</kbd> (Expand word) is also useful to reduce typing</p>
 <p>Command history</p>
 <ul class="simple">
-<li><kbd class="kbd docutils literal notranslate">Alt-p</kbd> retrieves previous command matching what you have typed. On
-macOS use <kbd class="kbd docutils literal notranslate">C-p</kbd>.</li>
-<li><kbd class="kbd docutils literal notranslate">Alt-n</kbd> retrieves next. On macOS use <kbd class="kbd docutils literal notranslate">C-n</kbd>.</li>
-<li><kbd class="kbd docutils literal notranslate">Return</kbd> while on any previous command retrieves that command</li>
+<li><p><kbd class="kbd docutils literal notranslate">Alt-p</kbd> retrieves previous command matching what you have typed. On
+macOS use <kbd class="kbd docutils literal notranslate">C-p</kbd>.</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">Alt-n</kbd> retrieves next. On macOS use <kbd class="kbd docutils literal notranslate">C-n</kbd>.</p></li>
+<li><p><kbd class="kbd docutils literal notranslate">Return</kbd> while on any previous command retrieves that command</p></li>
 </ul>
 </li>
 </ul>
@@ -602,12 +601,12 @@ functions to be used from IDLE’s Python shell.</p>
 </div>
 <p>If there are arguments:</p>
 <ul class="simple">
-<li>If <code class="docutils literal notranslate"><span class="pre">-</span></code>, <code class="docutils literal notranslate"><span class="pre">-c</span></code>, or <code class="docutils literal notranslate"><span class="pre">r</span></code> is used, all arguments are placed in
+<li><p>If <code class="docutils literal notranslate"><span class="pre">-</span></code>, <code class="docutils literal notranslate"><span class="pre">-c</span></code>, or <code class="docutils literal notranslate"><span class="pre">r</span></code> is used, all arguments are placed in
 <code class="docutils literal notranslate"><span class="pre">sys.argv[1:...]</span></code> and <code class="docutils literal notranslate"><span class="pre">sys.argv[0]</span></code> is set to <code class="docutils literal notranslate"><span class="pre">''</span></code>, <code class="docutils literal notranslate"><span class="pre">'-c'</span></code>,
 or <code class="docutils literal notranslate"><span class="pre">'-r'</span></code>.  No editor window is opened, even if that is the default
-set in the Options dialog.</li>
-<li>Otherwise, arguments are files opened for editing and
-<code class="docutils literal notranslate"><span class="pre">sys.argv</span></code> reflects the arguments passed to IDLE itself.</li>
+set in the Options dialog.</p></li>
+<li><p>Otherwise, arguments are files opened for editing and
+<code class="docutils literal notranslate"><span class="pre">sys.argv</span></code> reflects the arguments passed to IDLE itself.</p></li>
 </ul>
 </div>
 <div class="section" id="startup-failure">
@@ -670,6 +669,9 @@ such as multiprocessing.  If such subprocess use <code class="docutils literal n
 or <code class="docutils literal notranslate"><span class="pre">print</span></code> or <code class="docutils literal notranslate"><span class="pre">write</span></code> to sys.stdout or sys.stderr,
 IDLE should be started in a command line window.  The secondary subprocess
 will then be attached to that window for input and output.</p>
+<p>The IDLE code running in the execution process adds frames to the call stack
+that would not be there otherwise.  IDLE wraps <code class="docutils literal notranslate"><span class="pre">sys.getrecursionlimit</span></code> and
+<code class="docutils literal notranslate"><span class="pre">sys.setrecursionlimit</span></code> to reduce the effect of the additional stack frames.</p>
 <p>If <code class="docutils literal notranslate"><span class="pre">sys</span></code> is reset by user code, such as with <code class="docutils literal notranslate"><span class="pre">importlib.reload(sys)</span></code>,
 IDLE’s changes are lost and input from the keyboard and output to the screen
 will not work correctly.</p>
@@ -772,7 +774,7 @@ 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.</p>
 <div class="deprecated">
-<p><span class="versionmodified">Deprecated since version 3.4.</span></p>
+<p><span class="versionmodified deprecated">Deprecated since version 3.4.</span></p>
 </div>
 </div>
 </div>
@@ -885,7 +887,7 @@ also used for testing.</p>
 
   <h4>Previous topic</h4>
   <p class="topless"><a href="tkinter.scrolledtext.html"
-                        title="previous chapter"><code class="docutils literal notranslate"><span class="pre">tkinter.scrolledtext</span></code> — Scrolled Text Widget</a></p>
+                        title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">tkinter.scrolledtext</span></code> — Scrolled Text Widget</a></p>
   <h4>Next topic</h4>
   <p class="topless"><a href="othergui.html"
                         title="next chapter">Other Graphical User Interface Packages</a></p>
@@ -957,11 +959,11 @@ also used for testing.</p>
 <br />
     <br />
 
-    Last updated on Jun 17, 2019.
+    Last updated on Sep 01, 2019.
     <a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
     <br />
 
-    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.8.1.
+    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2.
     </div>
 
   </body>
index 652444a7f14937303d84eb43e8add92775109c19..9f63ea0d3990e6db84adc16ed1d191ab51787ea5 100644 (file)
@@ -50,20 +50,22 @@ class HelpParser(HTMLParser):
     """
     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 <dl>
-        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
+        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        # Exclude html page navigation.
+        self.hdrlink = False     # Exclude html header links.
+        self.level = 0           # Track indentation level.
+        self.pre = False         # Displaying preformatted text?
+        self.hprefix = ''        # Heading prefix (like '25.5'?) to remove.
+        self.nested_dl = False   # In a nested <dl>?
+        self.simplelist = False  # In a simple list (no double spacing)?
+        self.toc = []            # Pair headers with text indexes for toc.
+        self.header = ''         # Text within header tags for toc.
+        self.prevtag = None      # Previous tag info (opener?, tag).
 
     def indent(self, amt=1):
+        "Change indent (+1, 0, -1) and tags."
         self.level += amt
         self.tags = '' if self.level == 0 else 'l'+str(self.level)
 
@@ -75,11 +77,14 @@ class HelpParser(HTMLParser):
                 class_ = v
         s = ''
         if tag == 'div' and class_ == 'section':
-            self.show = True    # start of main content
+            self.show = True    # Start main content.
         elif tag == 'div' and class_ == 'sphinxsidebar':
-            self.show = False   # end of main content
-        elif tag == 'p' and class_ != 'first':
-            s = '\n\n'
+            self.show = False   # End main content.
+        elif tag == 'p' and self.prevtag and not self.prevtag[0]:
+            # Begin a new block for <p> tags after a closed tag.
+            # Avoid extra lines, e.g. after <pre> tags.
+            lastline = self.text.get('end-1c linestart', 'end-1c')
+            s = '\n\n' if lastline and not lastline.isspace() else '\n'
         elif tag == 'span' and class_ == 'pre':
             self.chartags = 'pre'
         elif tag == 'span' and class_ == 'versionmodified':
@@ -99,7 +104,7 @@ class HelpParser(HTMLParser):
         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
+            s = '\n\n' if not self.nested_dl else '\n'  # Avoid extra line.
             self.nested_dl = False
         elif tag == 'dd':
             self.indent()
@@ -120,16 +125,18 @@ class HelpParser(HTMLParser):
             self.tags = tag
         if self.show:
             self.text.insert('end', s, (self.tags, self.chartags))
+        self.prevtag = (True, tag)
 
     def handle_endtag(self, tag):
         "Handle endtags in help.html."
         if tag in ['h1', 'h2', 'h3']:
-            self.indent(0)  # clear tag, reset indent
+            assert self.level == 0
             if self.show:
                 indent = ('        ' if tag == 'h3' else
                           '    ' if tag == 'h2' else
                           '')
                 self.toc.append((indent+self.header, self.text.index('insert')))
+            self.tags = ''
         elif tag in ['span', 'em']:
             self.chartags = ''
         elif tag == 'a':
@@ -138,7 +145,8 @@ class HelpParser(HTMLParser):
             self.pre = False
             self.tags = ''
         elif tag in ['ul', 'dd', 'ol']:
-            self.indent(amt=-1)
+            self.indent(-1)
+        self.prevtag = (False, tag)
 
     def handle_data(self, data):
         "Handle date segments in help.html."
@@ -163,7 +171,7 @@ class HelpText(Text):
         "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
+        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)
 
@@ -203,7 +211,6 @@ class HelpFrame(Frame):
     "Display html text, scrollbar, and toc."
     def __init__(self, parent, filename):
         Frame.__init__(self, parent)
-        # keep references to widgets for test access.
         self.text = text = HelpText(self, filename)
         self['background'] = text['background']
         self.toc = toc = self.toc_menu(text)
@@ -211,7 +218,7 @@ class HelpFrame(Frame):
         text['yscrollcommand'] = scroll.set
 
         self.rowconfigure(0, weight=1)
-        self.columnconfigure(1, weight=1)  # text
+        self.columnconfigure(1, weight=1)  # Only expand the text widget.
         toc.grid(row=0, column=0, sticky='nw')
         text.grid(row=0, column=1, sticky='nsew')
         scroll.grid(row=0, column=2, sticky='ns')
@@ -257,7 +264,7 @@ def copy_strip():
     same, help.html can be backported.  The internal Python version
     number is not displayed.  If maintenance idle.rst diverges from
     the master version, then instead of backporting help.html from
-    master, repeat the proceedure above to generate a maintenance
+    master, repeat the procedure above to generate a maintenance
     version.
     """
     src = join(abspath(dirname(dirname(dirname(__file__)))),
@@ -273,7 +280,7 @@ 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
+        # Try copy_strip, present message.
         return
     HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version())
 
index 56f53a0f2fb9912925b3c566aab9d412c8864d95..ad44a96a9de2c0fb82f31d515d74aa9ff6119cb0 100644 (file)
@@ -39,7 +39,7 @@ class History:
         return "break"
 
     def fetch(self, reverse):
-        '''Fetch statememt and replace current line in text widget.
+        '''Fetch statement and replace current line in text widget.
 
         Set prefix and pointer as needed for successive fetches.
         Reset them to None, None when returning to the start line.
index 6ce8cc8a5f60469899dbc7fc1b5c14a58e501f2a..1373b7642a6ea91039f8f8ffd2e1a600e1a92932 100644 (file)
@@ -67,6 +67,7 @@ outwin.OutputWindow (indirectly being tested with grep test)
 
 import idlelib.pyshell  # Set Windows DPI awareness before Tk().
 from importlib import import_module
+import textwrap
 import tkinter as tk
 from tkinter.ttk import Scrollbar
 tk.NoDefaultRoot()
@@ -110,10 +111,11 @@ _color_delegator_spec = {
 
 CustomRun_spec = {
     'file': 'query',
-    'kwds': {'title': 'Custom Run Args',
+    'kwds': {'title': 'Customize query.py Run',
              '_htest': True},
-    'msg': "Enter with <Return> or [Ok].  Print valid entry to Shell\n"
+    'msg': "Enter with <Return> or [Run].  Print valid entry to Shell\n"
            "Arguments are parsed into a list\n"
+           "Mode is currently restart True or False\n"
            "Close dialog with valid entry, <Escape>, [Cancel], [X]"
     }
 
@@ -204,6 +206,26 @@ _io_binding_spec = {
            "Check that changes were saved by opening the file elsewhere."
     }
 
+_linenumbers_drag_scrolling_spec = {
+    'file': 'sidebar',
+    'kwds': {},
+    'msg': textwrap.dedent("""\
+        1. Click on the line numbers and drag down below the edge of the
+        window, moving the mouse a bit and then leaving it there for a while.
+        The text and line numbers should gradually scroll down, with the
+        selection updated continuously.
+
+        2. With the lines still selected, click on a line number above the
+        selected lines. Only the line whose number was clicked should be
+        selected.
+
+        3. Repeat step #1, dragging to above the window. The text and line
+        numbers should gradually scroll up, with the selection updated
+        continuously.
+
+        4. Repeat step #2, clicking a line number below the selection."""),
+    }
+
 _multi_call_spec = {
     'file': 'multicall',
     'kwds': {},
@@ -334,7 +356,7 @@ _undo_delegator_spec = {
 ViewWindow_spec = {
     'file': 'textview',
     'kwds': {'title': 'Test textview',
-             'text': 'The quick brown fox jumps over the lazy dog.\n'*35,
+             'contents': 'The quick brown fox jumps over the lazy dog.\n'*35,
              '_htest': True},
     'msg': "Test for read-only property of text.\n"
            "Select text, scroll window, close"
index 6181b29ec250cc64c743b1495562f823a0d1fe93..2c478cd5c2a14664cf3d728e6ae76ff555408660 100644 (file)
@@ -1,4 +1,4 @@
-"Test autocomplete, coverage 87%."
+"Test autocomplete, coverage 93%."
 
 import unittest
 from unittest.mock import Mock, patch
@@ -45,127 +45,177 @@ class AutoCompleteTest(unittest.TestCase):
 
     def test_init(self):
         self.assertEqual(self.autocomplete.editwin, self.editor)
+        self.assertEqual(self.autocomplete.text, self.text)
 
     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)
+        acp = self.autocomplete
+        acp.autocompletewindow = m = Mock()
+        acp._remove_autocomplete_window()
+        m.hide_window.assert_called_once()
+        self.assertIsNone(acp.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))
+        # Call _open_completions and break.
+        acp = self.autocomplete
+        open_c = Func()
+        acp.open_completions = open_c
+        self.assertEqual(acp.force_open_completions_event('event'), 'break')
+        self.assertEqual(open_c.args[0], ac.FORCE)
 
     def test_autocomplete_event(self):
         Equal = self.assertEqual
-        autocomplete = self.autocomplete
+        acp = self.autocomplete
 
-        # Test that the autocomplete event is ignored if user is pressing a
-        # modifier key in addition to the tab key.
+        # Result of autocomplete event: If modified tab, None.
         ev = Event(mc_state=True)
-        self.assertIsNone(autocomplete.autocomplete_event(ev))
+        self.assertIsNone(acp.autocomplete_event(ev))
         del ev.mc_state
 
-        # Test that tab after whitespace is ignored.
+        # If tab after whitespace, None.
         self.text.insert('1.0', '        """Docstring.\n    ')
-        self.assertIsNone(autocomplete.autocomplete_event(ev))
+        self.assertIsNone(acp.autocomplete_event(ev))
         self.text.delete('1.0', 'end')
 
-        # If autocomplete window is open, complete() method is called.
+        # If active autocomplete window, complete() and 'break'.
         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.
+        acp.autocompletewindow = mock = Mock()
+        mock.is_active = Mock(return_value=True)
+        Equal(acp.autocomplete_event(ev), 'break')
+        mock.complete.assert_called_once()
+        acp.autocompletewindow = None
+
+        # If no active autocomplete window, open_completions(), None/break.
+        open_c = Func(result=False)
+        acp.open_completions = open_c
+        Equal(acp.autocomplete_event(ev), None)
+        Equal(open_c.args[0], ac.TAB)
+        open_c.result = True
+        Equal(acp.autocomplete_event(ev), 'break')
+        Equal(open_c.args[0], ac.TAB)
+
+    def test_try_open_completions_event(self):
+        Equal = self.assertEqual
+        text = self.text
         acp = self.autocomplete
+        trycompletions = acp.try_open_completions_event
+        after = Func(result='after1')
+        acp.text.after = after
+
+        # If no text or trigger, after not called.
+        trycompletions()
+        Equal(after.called, 0)
+        text.insert('1.0', 're')
+        trycompletions()
+        Equal(after.called, 0)
+
+        # Attribute needed, no existing callback.
+        text.insert('insert', ' re.')
         acp._delayed_completion_id = None
-        acp._open_completions_later(False, False, False, ac.COMPLETE_ATTRIBUTES)
+        trycompletions()
+        Equal(acp._delayed_completion_index, text.index('insert'))
+        Equal(after.args,
+              (acp.popupwait, acp._delayed_open_completions, ac.TRY_A))
         cb1 = acp._delayed_completion_id
-        self.assertTrue(cb1.startswith('after'))
-
-        # Test that cb1 is cancelled and cb2 is new.
-        acp._open_completions_later(False, False, False, ac.COMPLETE_FILES)
-        self.assertNotIn(cb1, self.root.tk.call('after', 'info'))
-        cb2 = acp._delayed_completion_id
-        self.assertTrue(cb2.startswith('after') and cb2 != cb1)
-        self.text.after_cancel(cb2)
+        Equal(cb1, 'after1')
+
+        # File needed, existing callback cancelled.
+        text.insert('insert', ' "./Lib/')
+        after.result = 'after2'
+        cancel = Func()
+        acp.text.after_cancel = cancel
+        trycompletions()
+        Equal(acp._delayed_completion_index, text.index('insert'))
+        Equal(cancel.args, (cb1,))
+        Equal(after.args,
+              (acp.popupwait, acp._delayed_open_completions, ac.TRY_F))
+        Equal(acp._delayed_completion_id, 'after2')
 
     def test_delayed_open_completions(self):
-        # Test that autocomplete._delayed_completion_id set to None
-        # and that open_completions is not called if the index is not
-        # equal to _delayed_completion_index.
+        Equal = self.assertEqual
         acp = self.autocomplete
-        acp.open_completions = Func()
+        open_c = Func()
+        acp.open_completions = open_c
+        self.text.insert('1.0', '"dict.')
+
+        # Set autocomplete._delayed_completion_id to None.
+        # Text index changed, don't call open_completions.
         acp._delayed_completion_id = 'after'
         acp._delayed_completion_index = self.text.index('insert+1c')
-        acp._delayed_open_completions(1, 2, 3)
+        acp._delayed_open_completions('dummy')
         self.assertIsNone(acp._delayed_completion_id)
-        self.assertEqual(acp.open_completions.called, 0)
+        Equal(open_c.called, 0)
 
-        # Test that open_completions is called if indexes match.
+        # Text index unchanged, call open_completions.
         acp._delayed_completion_index = self.text.index('insert')
-        acp._delayed_open_completions(1, 2, 3, ac.COMPLETE_FILES)
-        self.assertEqual(acp.open_completions.args, (1, 2, 3, 2))
+        acp._delayed_open_completions((1, 2, 3, ac.FILES))
+        self.assertEqual(open_c.args[0], (1, 2, 3, ac.FILES))
+
+    def test_oc_cancel_comment(self):
+        none = self.assertIsNone
+        acp = self.autocomplete
+
+        # Comment is in neither code or string.
+        acp._delayed_completion_id = 'after'
+        after = Func(result='after')
+        acp.text.after_cancel = after
+        self.text.insert(1.0, '# comment')
+        none(acp.open_completions(ac.TAB))  # From 'else' after 'elif'.
+        none(acp._delayed_completion_id)
+
+    def test_oc_no_list(self):
+        acp = self.autocomplete
+        fetch = Func(result=([],[]))
+        acp.fetch_completions = fetch
+        self.text.insert('1.0', 'object')
+        self.assertIsNone(acp.open_completions(ac.TAB))
+        self.text.insert('insert', '.')
+        self.assertIsNone(acp.open_completions(ac.TAB))
+        self.assertEqual(fetch.called, 2)
+
+
+    def test_open_completions_none(self):
+        # Test other two None returns.
+        none = self.assertIsNone
+        acp = self.autocomplete
+
+        # No object for attributes or need call not allowed.
+        self.text.insert(1.0, '.')
+        none(acp.open_completions(ac.TAB))
+        self.text.insert('insert', ' int().')
+        none(acp.open_completions(ac.TAB))
+
+        # Blank or quote trigger 'if complete ...'.
+        self.text.delete(1.0, 'end')
+        self.assertFalse(acp.open_completions(ac.TAB))
+        self.text.insert('1.0', '"')
+        self.assertFalse(acp.open_completions(ac.TAB))
+        self.text.delete('1.0', 'end')
+
+    class dummy_acw():
+        __init__ = Func()
+        show_window = Func(result=False)
+        hide_window = Func()
 
     def test_open_completions(self):
-        # Test completions of files and attributes as well as non-completion
-        # of errors.
-        self.text.insert('1.0', 'pr')
-        self.assertTrue(self.autocomplete.open_completions(False, True, True))
+        # Test completions of files and attributes.
+        acp = self.autocomplete
+        fetch = Func(result=(['tem'],['tem', '_tem']))
+        acp.fetch_completions = fetch
+        def make_acw(): return self.dummy_acw()
+        acp._make_autocomplete_window = make_acw
+
+        self.text.insert('1.0', 'int.')
+        acp.open_completions(ac.TAB)
+        self.assertIsInstance(acp.autocompletewindow, self.dummy_acw)
         self.text.delete('1.0', 'end')
 
         # Test files.
         self.text.insert('1.0', '"t')
-        #self.assertTrue(self.autocomplete.open_completions(False, True, True))
-        self.text.delete('1.0', 'end')
-
-        # Test with blank will fail.
-        self.assertFalse(self.autocomplete.open_completions(False, True, True))
-
-        # Test with only string quote will fail.
-        self.text.insert('1.0', '"')
-        self.assertFalse(self.autocomplete.open_completions(False, True, True))
+        self.assertTrue(acp.open_completions(ac.TAB))
         self.text.delete('1.0', 'end')
 
     def test_fetch_completions(self):
@@ -174,21 +224,21 @@ class AutoCompleteTest(unittest.TestCase):
         # 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 '.'.
-        autocomplete = self.autocomplete
-        small, large = self.autocomplete.fetch_completions(
-                '', ac.COMPLETE_ATTRIBUTES)
+        acp = self.autocomplete
+        small, large = acp.fetch_completions(
+                '', ac.ATTRS)
         if __main__.__file__ != ac.__file__:
             self.assertNotIn('AutoComplete', small)  # See issue 36405.
 
         # Test attributes
-        s, b = autocomplete.fetch_completions('', ac.COMPLETE_ATTRIBUTES)
+        s, b = acp.fetch_completions('', ac.ATTRS)
         self.assertLess(len(small), len(large))
         self.assertTrue(all(filter(lambda x: x.startswith('_'), s)))
         self.assertTrue(any(filter(lambda x: x.startswith('_'), b)))
 
         # Test smalll should respect to __all__.
         with patch.dict('__main__.__dict__', {'__all__': ['a', 'b']}):
-            s, b = autocomplete.fetch_completions('', ac.COMPLETE_ATTRIBUTES)
+            s, b = acp.fetch_completions('', ac.ATTRS)
             self.assertEqual(s, ['a', 'b'])
             self.assertIn('__name__', b)    # From __main__.__dict__
             self.assertIn('sum', b)         # From __main__.__builtins__.__dict__
@@ -197,7 +247,7 @@ class AutoCompleteTest(unittest.TestCase):
         mock = Mock()
         mock._private = Mock()
         with patch.dict('__main__.__dict__', {'foo': mock}):
-            s, b = autocomplete.fetch_completions('foo', ac.COMPLETE_ATTRIBUTES)
+            s, b = acp.fetch_completions('foo', ac.ATTRS)
             self.assertNotIn('_private', s)
             self.assertIn('_private', b)
             self.assertEqual(s, [i for i in sorted(dir(mock)) if i[:1] != '_'])
@@ -211,36 +261,36 @@ class AutoCompleteTest(unittest.TestCase):
             return ['monty', 'python', '.hidden']
 
         with patch.object(os, 'listdir', _listdir):
-            s, b = autocomplete.fetch_completions('', ac.COMPLETE_FILES)
+            s, b = acp.fetch_completions('', ac.FILES)
             self.assertEqual(s, ['bar', 'foo'])
             self.assertEqual(b, ['.hidden', 'bar', 'foo'])
 
-            s, b = autocomplete.fetch_completions('~', ac.COMPLETE_FILES)
+            s, b = acp.fetch_completions('~', ac.FILES)
             self.assertEqual(s, ['monty', 'python'])
             self.assertEqual(b, ['.hidden', 'monty', 'python'])
 
     def test_get_entity(self):
         # Test that a name is in the namespace of sys.modules and
         # __main__.__dict__.
-        autocomplete = self.autocomplete
+        acp = self.autocomplete
         Equal = self.assertEqual
 
-        Equal(self.autocomplete.get_entity('int'), int)
+        Equal(acp.get_entity('int'), int)
 
         # Test name from sys.modules.
         mock = Mock()
         with patch.dict('sys.modules', {'tempfile': mock}):
-            Equal(autocomplete.get_entity('tempfile'), mock)
+            Equal(acp.get_entity('tempfile'), mock)
 
         # Test name from __main__.__dict__.
         di = {'foo': 10, 'bar': 20}
         with patch.dict('__main__.__dict__', {'d': di}):
-            Equal(autocomplete.get_entity('d'), di)
+            Equal(acp.get_entity('d'), di)
 
         # Test name not in namespace.
         with patch.dict('__main__.__dict__', {}):
             with self.assertRaises(NameError):
-                autocomplete.get_entity('not_exist')
+                acp.get_entity('not_exist')
 
 
 if __name__ == '__main__':
index 6c6893580f42f6c9ed584c50eafe3f9aaa518bfc..3ec49e97af6f916c19111e09553ac096b65e306f 100644 (file)
@@ -2,8 +2,9 @@
 
 from idlelib import codecontext
 import unittest
+import unittest.mock
 from test.support import requires
-from tkinter import Tk, Frame, Text, TclError
+from tkinter import NSEW, Tk, Frame, Text, TclError
 
 from unittest import mock
 import re
@@ -42,6 +43,9 @@ class DummyEditwin:
         self.text = text
         self.label = ''
 
+    def getlineno(self, index):
+        return int(float(self.text.index(index)))
+
     def update_menu_label(self, **kwargs):
         self.label = kwargs['label']
 
@@ -58,7 +62,7 @@ class CodeContextTest(unittest.TestCase):
         text.insert('1.0', code_sample)
         # Need to pack for creation of code context text widget.
         frame.pack(side='left', fill='both', expand=1)
-        text.pack(side='top', fill='both', expand=1)
+        text.grid(row=1, column=1, sticky=NSEW)
         cls.editor = DummyEditwin(root, frame, text)
         codecontext.idleConf.userCfg = testcfg
 
@@ -73,8 +77,29 @@ class CodeContextTest(unittest.TestCase):
 
     def setUp(self):
         self.text.yview(0)
+        self.text['font'] = 'TkFixedFont'
         self.cc = codecontext.CodeContext(self.editor)
 
+        self.highlight_cfg = {"background": '#abcdef',
+                              "foreground": '#123456'}
+        orig_idleConf_GetHighlight = codecontext.idleConf.GetHighlight
+        def mock_idleconf_GetHighlight(theme, element):
+            if element == 'context':
+                return self.highlight_cfg
+            return orig_idleConf_GetHighlight(theme, element)
+        GetHighlight_patcher = unittest.mock.patch.object(
+            codecontext.idleConf, 'GetHighlight', mock_idleconf_GetHighlight)
+        GetHighlight_patcher.start()
+        self.addCleanup(GetHighlight_patcher.stop)
+
+        self.font_override = 'TkFixedFont'
+        def mock_idleconf_GetFont(root, configType, section):
+            return self.font_override
+        GetFont_patcher = unittest.mock.patch.object(
+            codecontext.idleConf, 'GetFont', mock_idleconf_GetFont)
+        GetFont_patcher.start()
+        self.addCleanup(GetFont_patcher.stop)
+
     def tearDown(self):
         if self.cc.context:
             self.cc.context.destroy()
@@ -89,30 +114,24 @@ class CodeContextTest(unittest.TestCase):
 
         eq(cc.editwin, ed)
         eq(cc.text, ed.text)
-        eq(cc.textfont, ed.text['font'])
+        eq(cc.text['font'], ed.text['font'])
         self.assertIsNone(cc.context)
         eq(cc.info, [(0, -1, '', False)])
         eq(cc.topvisible, 1)
-        eq(self.root.tk.call('after', 'info', self.cc.t1)[1], 'timer')
-        eq(self.root.tk.call('after', 'info', self.cc.t2)[1], 'timer')
+        self.assertIsNone(self.cc.t1)
 
     def test_del(self):
         self.cc.__del__()
-        with self.assertRaises(TclError) as msg:
-            self.root.tk.call('after', 'info', self.cc.t1)
-            self.assertIn("doesn't exist", msg)
-        with self.assertRaises(TclError) as msg:
-            self.root.tk.call('after', 'info', self.cc.t2)
-            self.assertIn("doesn't exist", msg)
-        # For coverage on the except.  Have to delete because the
-        # above Tcl error is caught by after_cancel.
-        del self.cc.t1, self.cc.t2
+
+    def test_del_with_timer(self):
+        timer = self.cc.t1 = self.text.after(10000, lambda: None)
         self.cc.__del__()
+        with self.assertRaises(TclError) as cm:
+            self.root.tk.call('after', 'info', timer)
+        self.assertIn("doesn't exist", str(cm.exception))
 
     def test_reload(self):
         codecontext.CodeContext.reload()
-        self.assertEqual(self.cc.colors, {'background': 'lightgray',
-                                          'foreground': '#000000'})
         self.assertEqual(self.cc.context_depth, 15)
 
     def test_toggle_code_context_event(self):
@@ -125,18 +144,31 @@ class CodeContextTest(unittest.TestCase):
             toggle()
 
         # Toggle on.
-        eq(toggle(), 'break')
+        toggle()
         self.assertIsNotNone(cc.context)
-        eq(cc.context['font'], cc.textfont)
-        eq(cc.context['fg'], cc.colors['foreground'])
-        eq(cc.context['bg'], cc.colors['background'])
+        eq(cc.context['font'], self.text['font'])
+        eq(cc.context['fg'], self.highlight_cfg['foreground'])
+        eq(cc.context['bg'], self.highlight_cfg['background'])
         eq(cc.context.get('1.0', 'end-1c'), '')
         eq(cc.editwin.label, 'Hide Code Context')
+        eq(self.root.tk.call('after', 'info', self.cc.t1)[1], 'timer')
 
         # Toggle off.
-        eq(toggle(), 'break')
+        toggle()
         self.assertIsNone(cc.context)
         eq(cc.editwin.label, 'Show Code Context')
+        self.assertIsNone(self.cc.t1)
+
+        # Scroll down and toggle back on.
+        line11_context = '\n'.join(x[2] for x in cc.get_context(11)[0])
+        cc.text.yview(11)
+        toggle()
+        eq(cc.context.get('1.0', 'end-1c'), line11_context)
+
+        # Toggle off and on again.
+        toggle()
+        toggle()
+        eq(cc.context.get('1.0', 'end-1c'), line11_context)
 
     def test_get_context(self):
         eq = self.assertEqual
@@ -227,7 +259,7 @@ class CodeContextTest(unittest.TestCase):
                      (4, 4, '    def __init__(self, a, b):', 'def')])
         eq(cc.topvisible, 5)
         eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n'
-                             '    def __init__(self, a, b):')
+                                            '    def __init__(self, a, b):')
 
         # Scroll down to line 11.  Last 'def' is removed.
         cc.text.yview(11)
@@ -239,9 +271,9 @@ class CodeContextTest(unittest.TestCase):
                      (10, 8, '        elif a < b:', 'elif')])
         eq(cc.topvisible, 12)
         eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n'
-                             '    def compare(self):\n'
-                             '        if a > b:\n'
-                             '        elif a < b:')
+                                            '    def compare(self):\n'
+                                            '        if a > b:\n'
+                                            '        elif a < b:')
 
         # No scroll.  No update, even though context_depth changed.
         cc.update_code_context()
@@ -253,9 +285,9 @@ class CodeContextTest(unittest.TestCase):
                      (10, 8, '        elif a < b:', 'elif')])
         eq(cc.topvisible, 12)
         eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n'
-                             '    def compare(self):\n'
-                             '        if a > b:\n'
-                             '        elif a < b:')
+                                            '    def compare(self):\n'
+                                            '        if a > b:\n'
+                                            '        elif a < b:')
 
         # Scroll up.
         cc.text.yview(5)
@@ -276,7 +308,7 @@ class CodeContextTest(unittest.TestCase):
             cc.toggle_code_context_event()
 
         # Empty context.
-        cc.text.yview(f'{2}.0')
+        cc.text.yview('2.0')
         cc.update_code_context()
         eq(cc.topvisible, 2)
         cc.context.mark_set('insert', '1.5')
@@ -284,7 +316,7 @@ class CodeContextTest(unittest.TestCase):
         eq(cc.topvisible, 1)
 
         # 4 lines of context showing.
-        cc.text.yview(f'{12}.0')
+        cc.text.yview('12.0')
         cc.update_code_context()
         eq(cc.topvisible, 12)
         cc.context.mark_set('insert', '3.0')
@@ -293,7 +325,7 @@ class CodeContextTest(unittest.TestCase):
 
         # More context lines than limit.
         cc.context_depth = 2
-        cc.text.yview(f'{12}.0')
+        cc.text.yview('12.0')
         cc.update_code_context()
         eq(cc.topvisible, 12)
         cc.context.mark_set('insert', '1.0')
@@ -313,56 +345,62 @@ class CodeContextTest(unittest.TestCase):
         self.cc.timer_event()
         mock_update.assert_called()
 
-    def test_config_timer_event(self):
+    def test_font(self):
         eq = self.assertEqual
         cc = self.cc
-        save_font = cc.text['font']
-        save_colors = codecontext.CodeContext.colors
-        test_font = 'FakeFont'
+
+        orig_font = cc.text['font']
+        test_font = 'TkTextFont'
+        self.assertNotEqual(orig_font, test_font)
+
+        # Ensure code context is not active.
+        if cc.context is not None:
+            cc.toggle_code_context_event()
+
+        self.font_override = test_font
+        # Nothing breaks or changes with inactive code context.
+        cc.update_font()
+
+        # Activate code context, previous font change is immediately effective.
+        cc.toggle_code_context_event()
+        eq(cc.context['font'], test_font)
+
+        # Call the font update, change is picked up.
+        self.font_override = orig_font
+        cc.update_font()
+        eq(cc.context['font'], orig_font)
+
+    def test_highlight_colors(self):
+        eq = self.assertEqual
+        cc = self.cc
+
+        orig_colors = dict(self.highlight_cfg)
         test_colors = {'background': '#222222', 'foreground': '#ffff00'}
 
+        def assert_colors_are_equal(colors):
+            eq(cc.context['background'], colors['background'])
+            eq(cc.context['foreground'], colors['foreground'])
+
         # Ensure code context is not active.
         if cc.context:
             cc.toggle_code_context_event()
 
-        # Nothing updates on inactive code context.
-        cc.text['font'] = test_font
-        codecontext.CodeContext.colors = test_colors
-        cc.config_timer_event()
-        eq(cc.textfont, save_font)
-        eq(cc.contextcolors, save_colors)
+        self.highlight_cfg = test_colors
+        # Nothing breaks with inactive code context.
+        cc.update_highlight_colors()
 
-        # Activate code context, but no change to font or color.
+        # Activate code context, previous colors change is immediately effective.
         cc.toggle_code_context_event()
-        cc.text['font'] = save_font
-        codecontext.CodeContext.colors = save_colors
-        cc.config_timer_event()
-        eq(cc.textfont, save_font)
-        eq(cc.contextcolors, save_colors)
-        eq(cc.context['font'], save_font)
-        eq(cc.context['background'], save_colors['background'])
-        eq(cc.context['foreground'], save_colors['foreground'])
-
-        # Active code context, change font.
-        cc.text['font'] = test_font
-        cc.config_timer_event()
-        eq(cc.textfont, test_font)
-        eq(cc.contextcolors, save_colors)
-        eq(cc.context['font'], test_font)
-        eq(cc.context['background'], save_colors['background'])
-        eq(cc.context['foreground'], save_colors['foreground'])
-
-        # Active code context, change color.
-        cc.text['font'] = save_font
-        codecontext.CodeContext.colors = test_colors
-        cc.config_timer_event()
-        eq(cc.textfont, save_font)
-        eq(cc.contextcolors, test_colors)
-        eq(cc.context['font'], save_font)
-        eq(cc.context['background'], test_colors['background'])
-        eq(cc.context['foreground'], test_colors['foreground'])
-        codecontext.CodeContext.colors = save_colors
-        cc.config_timer_event()
+        assert_colors_are_equal(test_colors)
+
+        # Call colors update with no change to the configured colors.
+        cc.update_highlight_colors()
+        assert_colors_are_equal(test_colors)
+
+        # Call the colors update with code context active, change is picked up.
+        self.highlight_cfg = orig_colors
+        cc.update_highlight_colors()
+        assert_colors_are_equal(orig_colors)
 
 
 class HelperFunctionText(unittest.TestCase):
index 255210df7d96088562443465cad3633cfc6693d0..697fda527968dedf09b71ad91d449e88adacec24 100644 (file)
@@ -159,19 +159,6 @@ class IdleUserConfParserTest(unittest.TestCase):
         self.assertFalse(parser.IsEmpty())
         self.assertCountEqual(parser.sections(), ['Foo'])
 
-    def test_remove_file(self):
-        with tempfile.TemporaryDirectory() as tdir:
-            path = os.path.join(tdir, 'test.cfg')
-            parser = self.new_parser(path)
-            parser.RemoveFile()  # Should not raise exception.
-
-            parser.AddSection('Foo')
-            parser.SetOption('Foo', 'bar', 'true')
-            parser.Save()
-            self.assertTrue(os.path.exists(path))
-            parser.RemoveFile()
-            self.assertFalse(os.path.exists(path))
-
     def test_save(self):
         with tempfile.TemporaryDirectory() as tdir:
             path = os.path.join(tdir, 'test.cfg')
@@ -233,7 +220,7 @@ class IdleConfTest(unittest.TestCase):
 
     @unittest.skipIf(sys.platform.startswith('win'), 'this is test for unix system')
     def test_get_user_cfg_dir_unix(self):
-        "Test to get user config directory under unix"
+        # Test to get user config directory under unix.
         conf = self.new_config(_utest=True)
 
         # Check normal way should success
@@ -256,7 +243,7 @@ class IdleConfTest(unittest.TestCase):
 
     @unittest.skipIf(not sys.platform.startswith('win'), 'this is test for Windows system')
     def test_get_user_cfg_dir_windows(self):
-        "Test to get user config directory under Windows"
+        # Test to get user config directory under Windows.
         conf = self.new_config(_utest=True)
 
         # Check normal way should success
@@ -297,12 +284,12 @@ class IdleConfTest(unittest.TestCase):
             self.assertIsInstance(user_parser, config.IdleUserConfParser)
 
         # Check config path are correct
-        for config_type, parser in conf.defaultCfg.items():
+        for cfg_type, parser in conf.defaultCfg.items():
             self.assertEqual(parser.file,
-                             os.path.join(idle_dir, 'config-%s.def' % config_type))
-        for config_type, parser in conf.userCfg.items():
+                             os.path.join(idle_dir, f'config-{cfg_type}.def'))
+        for cfg_type, parser in conf.userCfg.items():
             self.assertEqual(parser.file,
-                             os.path.join(conf.userdir, 'config-%s.cfg' % config_type))
+                             os.path.join(conf.userdir or '#', f'config-{cfg_type}.cfg'))
 
     def test_load_cfg_files(self):
         conf = self.new_config(_utest=True)
@@ -386,7 +373,7 @@ class IdleConfTest(unittest.TestCase):
                                                        'background': '#171717'})
 
     def test_get_theme_dict(self):
-        "XXX: NOT YET DONE"
+        # TODO: finish.
         conf = self.mock_config()
 
         # These two should be the same
index 12bc8473668334ca22f49eb9f8686eab416a468a..4af4ff0242d740c556fc372ab8e5ca623ed0918d 100644 (file)
@@ -42,5 +42,66 @@ class EditorFunctionTest(unittest.TestCase):
             self.assertEqual(func(dummy, inp), out)
 
 
+class TestGetLineIndent(unittest.TestCase):
+    def test_empty_lines(self):
+        for tabwidth in [1, 2, 4, 6, 8]:
+            for line in ['', '\n']:
+                with self.subTest(line=line, tabwidth=tabwidth):
+                    self.assertEqual(
+                        editor.get_line_indent(line, tabwidth=tabwidth),
+                        (0, 0),
+                    )
+
+    def test_tabwidth_4(self):
+        #        (line, (raw, effective))
+        tests = (('no spaces', (0, 0)),
+                 # Internal space isn't counted.
+                 ('    space test', (4, 4)),
+                 ('\ttab test', (1, 4)),
+                 ('\t\tdouble tabs test', (2, 8)),
+                 # Different results when mixing tabs and spaces.
+                 ('    \tmixed test', (5, 8)),
+                 ('  \t  mixed test', (5, 6)),
+                 ('\t    mixed test', (5, 8)),
+                 # Spaces not divisible by tabwidth.
+                 ('  \tmixed test', (3, 4)),
+                 (' \t mixed test', (3, 5)),
+                 ('\t  mixed test', (3, 6)),
+                 # Only checks spaces and tabs.
+                 ('\nnewline test', (0, 0)))
+
+        for line, expected in tests:
+            with self.subTest(line=line):
+                self.assertEqual(
+                    editor.get_line_indent(line, tabwidth=4),
+                    expected,
+                )
+
+    def test_tabwidth_8(self):
+        #        (line, (raw, effective))
+        tests = (('no spaces', (0, 0)),
+                 # Internal space isn't counted.
+                 ('        space test', (8, 8)),
+                 ('\ttab test', (1, 8)),
+                 ('\t\tdouble tabs test', (2, 16)),
+                 # Different results when mixing tabs and spaces.
+                 ('        \tmixed test', (9, 16)),
+                 ('      \t  mixed test', (9, 10)),
+                 ('\t        mixed test', (9, 16)),
+                 # Spaces not divisible by tabwidth.
+                 ('  \tmixed test', (3, 8)),
+                 (' \t mixed test', (3, 9)),
+                 ('\t  mixed test', (3, 10)),
+                 # Only checks spaces and tabs.
+                 ('\nnewline test', (0, 0)))
+
+        for line, expected in tests:
+            with self.subTest(line=line):
+                self.assertEqual(
+                    editor.get_line_indent(line, tabwidth=8),
+                    expected,
+                )
+
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py
new file mode 100644 (file)
index 0000000..c7b123e
--- /dev/null
@@ -0,0 +1,623 @@
+"Test format, coverage 99%."
+
+from idlelib import format as ft
+import unittest
+from unittest import mock
+from test.support import requires
+from tkinter import Tk, Text
+from idlelib.editor import EditorWindow
+from idlelib.idle_test.mock_idle import Editor as MockEditor
+
+
+class Is_Get_Test(unittest.TestCase):
+    """Test the is_ and get_ functions"""
+    test_comment = '# This is a comment'
+    test_nocomment = 'This is not a comment'
+    trailingws_comment = '# This is a comment   '
+    leadingws_comment = '    # This is a comment'
+    leadingws_nocomment = '    This is not a comment'
+
+    def test_is_all_white(self):
+        self.assertTrue(ft.is_all_white(''))
+        self.assertTrue(ft.is_all_white('\t\n\r\f\v'))
+        self.assertFalse(ft.is_all_white(self.test_comment))
+
+    def test_get_indent(self):
+        Equal = self.assertEqual
+        Equal(ft.get_indent(self.test_comment), '')
+        Equal(ft.get_indent(self.trailingws_comment), '')
+        Equal(ft.get_indent(self.leadingws_comment), '    ')
+        Equal(ft.get_indent(self.leadingws_nocomment), '    ')
+
+    def test_get_comment_header(self):
+        Equal = self.assertEqual
+        # Test comment strings
+        Equal(ft.get_comment_header(self.test_comment), '#')
+        Equal(ft.get_comment_header(self.trailingws_comment), '#')
+        Equal(ft.get_comment_header(self.leadingws_comment), '    #')
+        # Test non-comment strings
+        Equal(ft.get_comment_header(self.leadingws_nocomment), '    ')
+        Equal(ft.get_comment_header(self.test_nocomment), '')
+
+
+class FindTest(unittest.TestCase):
+    """Test the find_paragraph function in paragraph module.
+
+    Using the runcase() function, find_paragraph() is called with 'mark' set at
+    multiple indexes before and inside the test paragraph.
+
+    It appears that code with the same indentation as a quoted string is grouped
+    as part of the same paragraph, which is probably incorrect behavior.
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        from idlelib.idle_test.mock_tk import Text
+        cls.text = Text()
+
+    def runcase(self, inserttext, stopline, expected):
+        # Check that find_paragraph returns the expected paragraph when
+        # the mark index is set to beginning, middle, end of each line
+        # up to but not including the stop line
+        text = self.text
+        text.insert('1.0', inserttext)
+        for line in range(1, stopline):
+            linelength = int(text.index("%d.end" % line).split('.')[1])
+            for col in (0, linelength//2, linelength):
+                tempindex = "%d.%d" % (line, col)
+                self.assertEqual(ft.find_paragraph(text, tempindex), expected)
+        text.delete('1.0', 'end')
+
+    def test_find_comment(self):
+        comment = (
+            "# Comment block with no blank lines before\n"
+            "# Comment line\n"
+            "\n")
+        self.runcase(comment, 3, ('1.0', '3.0', '#', comment[0:58]))
+
+        comment = (
+            "\n"
+            "# Comment block with whitespace line before and after\n"
+            "# Comment line\n"
+            "\n")
+        self.runcase(comment, 4, ('2.0', '4.0', '#', comment[1:70]))
+
+        comment = (
+            "\n"
+            "    # Indented comment block with whitespace before and after\n"
+            "    # Comment line\n"
+            "\n")
+        self.runcase(comment, 4, ('2.0', '4.0', '    #', comment[1:82]))
+
+        comment = (
+            "\n"
+            "# Single line comment\n"
+            "\n")
+        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:23]))
+
+        comment = (
+            "\n"
+            "    # Single line comment with leading whitespace\n"
+            "\n")
+        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:51]))
+
+        comment = (
+            "\n"
+            "# Comment immediately followed by code\n"
+            "x = 42\n"
+            "\n")
+        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:40]))
+
+        comment = (
+            "\n"
+            "    # Indented comment immediately followed by code\n"
+            "x = 42\n"
+            "\n")
+        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:53]))
+
+        comment = (
+            "\n"
+            "# Comment immediately followed by indented code\n"
+            "    x = 42\n"
+            "\n")
+        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:49]))
+
+    def test_find_paragraph(self):
+        teststring = (
+            '"""String with no blank lines before\n'
+            'String line\n'
+            '"""\n'
+            '\n')
+        self.runcase(teststring, 4, ('1.0', '4.0', '', teststring[0:53]))
+
+        teststring = (
+            "\n"
+            '"""String with whitespace line before and after\n'
+            'String line.\n'
+            '"""\n'
+            '\n')
+        self.runcase(teststring, 5, ('2.0', '5.0', '', teststring[1:66]))
+
+        teststring = (
+            '\n'
+            '    """Indented string with whitespace before and after\n'
+            '    Comment string.\n'
+            '    """\n'
+            '\n')
+        self.runcase(teststring, 5, ('2.0', '5.0', '    ', teststring[1:85]))
+
+        teststring = (
+            '\n'
+            '"""Single line string."""\n'
+            '\n')
+        self.runcase(teststring, 3, ('2.0', '3.0', '', teststring[1:27]))
+
+        teststring = (
+            '\n'
+            '    """Single line string with leading whitespace."""\n'
+            '\n')
+        self.runcase(teststring, 3, ('2.0', '3.0', '    ', teststring[1:55]))
+
+
+class ReformatFunctionTest(unittest.TestCase):
+    """Test the reformat_paragraph function without the editor window."""
+
+    def test_reformat_paragraph(self):
+        Equal = self.assertEqual
+        reform = ft.reformat_paragraph
+        hw = "O hello world"
+        Equal(reform(' ', 1), ' ')
+        Equal(reform("Hello    world", 20), "Hello  world")
+
+        # Test without leading newline
+        Equal(reform(hw, 1), "O\nhello\nworld")
+        Equal(reform(hw, 6), "O\nhello\nworld")
+        Equal(reform(hw, 7), "O hello\nworld")
+        Equal(reform(hw, 12), "O hello\nworld")
+        Equal(reform(hw, 13), "O hello world")
+
+        # Test with leading newline
+        hw = "\nO hello world"
+        Equal(reform(hw, 1), "\nO\nhello\nworld")
+        Equal(reform(hw, 6), "\nO\nhello\nworld")
+        Equal(reform(hw, 7), "\nO hello\nworld")
+        Equal(reform(hw, 12), "\nO hello\nworld")
+        Equal(reform(hw, 13), "\nO hello world")
+
+
+class ReformatCommentTest(unittest.TestCase):
+    """Test the reformat_comment function without the editor window."""
+
+    def test_reformat_comment(self):
+        Equal = self.assertEqual
+
+        # reformat_comment formats to a minimum of 20 characters
+        test_string = (
+            "    \"\"\"this is a test of a reformat for a triple quoted string"
+            " will it reformat to less than 70 characters for me?\"\"\"")
+        result = ft.reformat_comment(test_string, 70, "    ")
+        expected = (
+            "    \"\"\"this is a test of a reformat for a triple quoted string will it\n"
+            "    reformat to less than 70 characters for me?\"\"\"")
+        Equal(result, expected)
+
+        test_comment = (
+            "# this is a test of a reformat for a triple quoted string will "
+            "it reformat to less than 70 characters for me?")
+        result = ft.reformat_comment(test_comment, 70, "#")
+        expected = (
+            "# this is a test of a reformat for a triple quoted string will it\n"
+            "# reformat to less than 70 characters for me?")
+        Equal(result, expected)
+
+
+class FormatClassTest(unittest.TestCase):
+    def test_init_close(self):
+        instance = ft.FormatParagraph('editor')
+        self.assertEqual(instance.editwin, 'editor')
+        instance.close()
+        self.assertEqual(instance.editwin, None)
+
+
+# For testing format_paragraph_event, Initialize FormatParagraph with
+# a mock Editor with .text and  .get_selection_indices.  The text must
+# be a Text wrapper that adds two methods
+
+# A real EditorWindow creates unneeded, time-consuming baggage and
+# sometimes emits shutdown warnings like this:
+# "warning: callback failed in WindowList <class '_tkinter.TclError'>
+# : invalid command name ".55131368.windows".
+# Calling EditorWindow._close in tearDownClass prevents this but causes
+# other problems (windows left open).
+
+class TextWrapper:
+    def __init__(self, master):
+        self.text = Text(master=master)
+    def __getattr__(self, name):
+        return getattr(self.text, name)
+    def undo_block_start(self): pass
+    def undo_block_stop(self): pass
+
+class Editor:
+    def __init__(self, root):
+        self.text = TextWrapper(root)
+    get_selection_indices = EditorWindow. get_selection_indices
+
+class FormatEventTest(unittest.TestCase):
+    """Test the formatting of text inside a Text widget.
+
+    This is done with FormatParagraph.format.paragraph_event,
+    which calls functions in the module as appropriate.
+    """
+    test_string = (
+        "    '''this is a test of a reformat for a triple "
+        "quoted string will it reformat to less than 70 "
+        "characters for me?'''\n")
+    multiline_test_string = (
+        "    '''The first line is under the max width.\n"
+        "    The second line's length is way over the max width. It goes "
+        "on and on until it is over 100 characters long.\n"
+        "    Same thing with the third line. It is also way over the max "
+        "width, but FormatParagraph will fix it.\n"
+        "    '''\n")
+    multiline_test_comment = (
+        "# The first line is under the max width.\n"
+        "# The second line's length is way over the max width. It goes on "
+        "and on until it is over 100 characters long.\n"
+        "# Same thing with the third line. It is also way over the max "
+        "width, but FormatParagraph will fix it.\n"
+        "# The fourth line is short like the first line.")
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        editor = Editor(root=cls.root)
+        cls.text = editor.text.text  # Test code does not need the wrapper.
+        cls.formatter = ft.FormatParagraph(editor).format_paragraph_event
+        # Sets the insert mark just after the re-wrapped and inserted  text.
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.text, cls.formatter
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
+
+    def test_short_line(self):
+        self.text.insert('1.0', "Short line\n")
+        self.formatter("Dummy")
+        self.assertEqual(self.text.get('1.0', 'insert'), "Short line\n" )
+        self.text.delete('1.0', 'end')
+
+    def test_long_line(self):
+        text = self.text
+
+        # 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', limit=70)
+        result = text.get('1.0', 'insert')
+        # find function includes \n
+        expected = (
+"    '''this is a test of a reformat for a triple quoted string will it\n"
+"    reformat to less than 70 characters for me?'''\n")  # yes
+        self.assertEqual(result, expected)
+        text.delete('1.0', 'end')
+
+        # 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', limit=70)
+        result = text.get('1.0', 'insert')
+        # selection excludes \n
+        expected = (
+"    '''this is a test of a reformat for a triple quoted string will it reformat\n"
+" to less than 70 characters for me?'''")  # no
+        self.assertEqual(result, expected)
+        text.delete('1.0', 'end')
+
+    def test_multiple_lines(self):
+        text = self.text
+        #  Select 2 long lines.
+        text.insert('1.0', self.multiline_test_string)
+        text.tag_add('sel', '2.0', '4.0')
+        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"
+"    on until it is over 100 characters long. Same thing with the third\n"
+"    line. It is also way over the max width, but FormatParagraph will\n"
+"    fix it.\n")
+        self.assertEqual(result, expected)
+        text.delete('1.0', 'end')
+
+    def test_comment_block(self):
+        text = self.text
+
+        # Set cursor ('insert') to '1.0', within block.
+        text.insert('1.0', self.multiline_test_comment)
+        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"
+"# way over the max width. It goes on and on until it is over 100\n"
+"# characters long. Same thing with the third line. It is also way over\n"
+"# the max width, but FormatParagraph will fix it. The fourth line is\n"
+"# short like the first line.\n")
+        self.assertEqual(result, expected)
+        text.delete('1.0', 'end')
+
+        # 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', limit=70)
+        result = text.get('1.0', 'insert')
+        expected = (
+"# The first line is under the max width.\n"
+"# The second line's length is way over the max width. It goes on and\n"
+"# on until it is over 100 characters long.\n")
+        self.assertEqual(result, expected)
+        text.delete('1.0', 'end')
+
+# The following block worked with EditorWindow but fails with the mock.
+# Lines 2 and 3 get pasted together even though the previous block left
+# the previous line alone. More investigation is needed.
+##        # Select lines 3 and 4
+##        text.insert('1.0', self.multiline_test_comment)
+##        text.tag_add('sel', '3.0', '5.0')
+##        self.formatter('ParameterDoesNothing')
+##        result = text.get('3.0', 'insert')
+##        expected = (
+##"# Same thing with the third line. It is also way over the max width,\n"
+##"# but FormatParagraph will fix it. The fourth line is short like the\n"
+##"# first line.\n")
+##        self.assertEqual(result, expected)
+##        text.delete('1.0', 'end')
+
+
+class DummyEditwin:
+    def __init__(self, root, text):
+        self.root = root
+        self.text = text
+        self.indentwidth = 4
+        self.tabwidth = 4
+        self.usetabs = False
+        self.context_use_ps1 = True
+
+    _make_blanks = EditorWindow._make_blanks
+    get_selection_indices = EditorWindow.get_selection_indices
+
+
+class FormatRegionTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = Tk()
+        cls.root.withdraw()
+        cls.text = Text(cls.root)
+        cls.text.undo_block_start = mock.Mock()
+        cls.text.undo_block_stop = mock.Mock()
+        cls.editor = DummyEditwin(cls.root, cls.text)
+        cls.formatter = ft.FormatRegion(cls.editor)
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.text, cls.formatter, cls.editor
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
+
+    def setUp(self):
+        self.text.insert('1.0', self.code_sample)
+
+    def tearDown(self):
+        self.text.delete('1.0', 'end')
+
+    code_sample = """\
+
+class C1():
+    # Class comment.
+    def __init__(self, a, b):
+        self.a = a
+        self.b = b
+
+    def compare(self):
+        if a > b:
+            return a
+        elif a < b:
+            return b
+        else:
+            return None
+"""
+
+    def test_get_region(self):
+        get = self.formatter.get_region
+        text = self.text
+        eq = self.assertEqual
+
+        # Add selection.
+        text.tag_add('sel', '7.0', '10.0')
+        expected_lines = ['',
+                          '    def compare(self):',
+                          '        if a > b:',
+                          '']
+        eq(get(), ('7.0', '10.0', '\n'.join(expected_lines), expected_lines))
+
+        # Remove selection.
+        text.tag_remove('sel', '1.0', 'end')
+        eq(get(), ('15.0', '16.0', '\n', ['', '']))
+
+    def test_set_region(self):
+        set_ = self.formatter.set_region
+        text = self.text
+        eq = self.assertEqual
+
+        save_bell = text.bell
+        text.bell = mock.Mock()
+        line6 = self.code_sample.splitlines()[5]
+        line10 = self.code_sample.splitlines()[9]
+
+        text.tag_add('sel', '6.0', '11.0')
+        head, tail, chars, lines = self.formatter.get_region()
+
+        # No changes.
+        set_(head, tail, chars, lines)
+        text.bell.assert_called_once()
+        eq(text.get('6.0', '11.0'), chars)
+        eq(text.get('sel.first', 'sel.last'), chars)
+        text.tag_remove('sel', '1.0', 'end')
+
+        # Alter selected lines by changing lines and adding a newline.
+        newstring = 'added line 1\n\n\n\n'
+        newlines = newstring.split('\n')
+        set_('7.0', '10.0', chars, newlines)
+        # Selection changed.
+        eq(text.get('sel.first', 'sel.last'), newstring)
+        # Additional line added, so last index is changed.
+        eq(text.get('7.0', '11.0'), newstring)
+        # Before and after lines unchanged.
+        eq(text.get('6.0', '7.0-1c'), line6)
+        eq(text.get('11.0', '12.0-1c'), line10)
+        text.tag_remove('sel', '1.0', 'end')
+
+        text.bell = save_bell
+
+    def test_indent_region_event(self):
+        indent = self.formatter.indent_region_event
+        text = self.text
+        eq = self.assertEqual
+
+        text.tag_add('sel', '7.0', '10.0')
+        indent()
+        # Blank lines aren't affected by indent.
+        eq(text.get('7.0', '10.0'), ('\n        def compare(self):\n            if a > b:\n'))
+
+    def test_dedent_region_event(self):
+        dedent = self.formatter.dedent_region_event
+        text = self.text
+        eq = self.assertEqual
+
+        text.tag_add('sel', '7.0', '10.0')
+        dedent()
+        # Blank lines aren't affected by dedent.
+        eq(text.get('7.0', '10.0'), ('\ndef compare(self):\n    if a > b:\n'))
+
+    def test_comment_region_event(self):
+        comment = self.formatter.comment_region_event
+        text = self.text
+        eq = self.assertEqual
+
+        text.tag_add('sel', '7.0', '10.0')
+        comment()
+        eq(text.get('7.0', '10.0'), ('##\n##    def compare(self):\n##        if a > b:\n'))
+
+    def test_uncomment_region_event(self):
+        comment = self.formatter.comment_region_event
+        uncomment = self.formatter.uncomment_region_event
+        text = self.text
+        eq = self.assertEqual
+
+        text.tag_add('sel', '7.0', '10.0')
+        comment()
+        uncomment()
+        eq(text.get('7.0', '10.0'), ('\n    def compare(self):\n        if a > b:\n'))
+
+        # Only remove comments at the beginning of a line.
+        text.tag_remove('sel', '1.0', 'end')
+        text.tag_add('sel', '3.0', '4.0')
+        uncomment()
+        eq(text.get('3.0', '3.end'), ('    # Class comment.'))
+
+        self.formatter.set_region('3.0', '4.0', '', ['# Class comment.', ''])
+        uncomment()
+        eq(text.get('3.0', '3.end'), (' Class comment.'))
+
+    @mock.patch.object(ft.FormatRegion, "_asktabwidth")
+    def test_tabify_region_event(self, _asktabwidth):
+        tabify = self.formatter.tabify_region_event
+        text = self.text
+        eq = self.assertEqual
+
+        text.tag_add('sel', '7.0', '10.0')
+        # No tabwidth selected.
+        _asktabwidth.return_value = None
+        self.assertIsNone(tabify())
+
+        _asktabwidth.return_value = 3
+        self.assertIsNotNone(tabify())
+        eq(text.get('7.0', '10.0'), ('\n\t def compare(self):\n\t\t  if a > b:\n'))
+
+    @mock.patch.object(ft.FormatRegion, "_asktabwidth")
+    def test_untabify_region_event(self, _asktabwidth):
+        untabify = self.formatter.untabify_region_event
+        text = self.text
+        eq = self.assertEqual
+
+        text.tag_add('sel', '7.0', '10.0')
+        # No tabwidth selected.
+        _asktabwidth.return_value = None
+        self.assertIsNone(untabify())
+
+        _asktabwidth.return_value = 2
+        self.formatter.tabify_region_event()
+        _asktabwidth.return_value = 3
+        self.assertIsNotNone(untabify())
+        eq(text.get('7.0', '10.0'), ('\n      def compare(self):\n            if a > b:\n'))
+
+    @mock.patch.object(ft, "askinteger")
+    def test_ask_tabwidth(self, askinteger):
+        ask = self.formatter._asktabwidth
+        askinteger.return_value = 10
+        self.assertEqual(ask(), 10)
+
+
+class rstripTest(unittest.TestCase):
+
+    def test_rstrip_line(self):
+        editor = MockEditor()
+        text = editor.text
+        do_rstrip = ft.Rstrip(editor).do_rstrip
+        eq = self.assertEqual
+
+        do_rstrip()
+        eq(text.get('1.0', 'insert'), '')
+        text.insert('1.0', '     ')
+        do_rstrip()
+        eq(text.get('1.0', 'insert'), '')
+        text.insert('1.0', '     \n')
+        do_rstrip()
+        eq(text.get('1.0', 'insert'), '\n')
+
+    def test_rstrip_multiple(self):
+        editor = MockEditor()
+        #  Comment above, uncomment 3 below to test with real Editor & Text.
+        #from idlelib.editor import EditorWindow as Editor
+        #from tkinter import Tk
+        #editor = Editor(root=Tk())
+        text = editor.text
+        do_rstrip = ft.Rstrip(editor).do_rstrip
+
+        original = (
+            "Line with an ending tab    \n"
+            "Line ending in 5 spaces     \n"
+            "Linewithnospaces\n"
+            "    indented line\n"
+            "    indented line with trailing space \n"
+            "    ")
+        stripped = (
+            "Line with an ending tab\n"
+            "Line ending in 5 spaces\n"
+            "Linewithnospaces\n"
+            "    indented line\n"
+            "    indented line with trailing space\n")
+
+        text.insert('1.0', original)
+        do_rstrip()
+        self.assertEqual(text.get('1.0', 'insert'), stripped)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2, exit=2)
index 68156a743d7b9b63050082b6cde0655a20211672..ba582bb3ca51b4c99c2365317374649943773323 100644 (file)
@@ -35,6 +35,14 @@ class MultiCallTest(unittest.TestCase):
         mctext = self.mc(self.root)
         self.assertIsInstance(mctext._MultiCall__binders, list)
 
+    def test_yview(self):
+        # Added for tree.wheel_event
+        # (it depends on yview to not be overriden)
+        mc = self.mc
+        self.assertIs(mc.yview, Text.yview)
+        mctext = self.mc(self.root)
+        self.assertIs(mctext.yview.__func__, Text.yview)
+
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_paragraph.py b/Lib/idlelib/idle_test/test_paragraph.py
deleted file mode 100644 (file)
index 0cb966f..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-"Test paragraph, coverage 76%."
-
-from idlelib import paragraph as pg
-import unittest
-from test.support import requires
-from tkinter import Tk, Text
-from idlelib.editor import EditorWindow
-
-
-class Is_Get_Test(unittest.TestCase):
-    """Test the is_ and get_ functions"""
-    test_comment = '# This is a comment'
-    test_nocomment = 'This is not a comment'
-    trailingws_comment = '# This is a comment   '
-    leadingws_comment = '    # This is a comment'
-    leadingws_nocomment = '    This is not a comment'
-
-    def test_is_all_white(self):
-        self.assertTrue(pg.is_all_white(''))
-        self.assertTrue(pg.is_all_white('\t\n\r\f\v'))
-        self.assertFalse(pg.is_all_white(self.test_comment))
-
-    def test_get_indent(self):
-        Equal = self.assertEqual
-        Equal(pg.get_indent(self.test_comment), '')
-        Equal(pg.get_indent(self.trailingws_comment), '')
-        Equal(pg.get_indent(self.leadingws_comment), '    ')
-        Equal(pg.get_indent(self.leadingws_nocomment), '    ')
-
-    def test_get_comment_header(self):
-        Equal = self.assertEqual
-        # Test comment strings
-        Equal(pg.get_comment_header(self.test_comment), '#')
-        Equal(pg.get_comment_header(self.trailingws_comment), '#')
-        Equal(pg.get_comment_header(self.leadingws_comment), '    #')
-        # Test non-comment strings
-        Equal(pg.get_comment_header(self.leadingws_nocomment), '    ')
-        Equal(pg.get_comment_header(self.test_nocomment), '')
-
-
-class FindTest(unittest.TestCase):
-    """Test the find_paragraph function in paragraph module.
-
-    Using the runcase() function, find_paragraph() is called with 'mark' set at
-    multiple indexes before and inside the test paragraph.
-
-    It appears that code with the same indentation as a quoted string is grouped
-    as part of the same paragraph, which is probably incorrect behavior.
-    """
-
-    @classmethod
-    def setUpClass(cls):
-        from idlelib.idle_test.mock_tk import Text
-        cls.text = Text()
-
-    def runcase(self, inserttext, stopline, expected):
-        # Check that find_paragraph returns the expected paragraph when
-        # the mark index is set to beginning, middle, end of each line
-        # up to but not including the stop line
-        text = self.text
-        text.insert('1.0', inserttext)
-        for line in range(1, stopline):
-            linelength = int(text.index("%d.end" % line).split('.')[1])
-            for col in (0, linelength//2, linelength):
-                tempindex = "%d.%d" % (line, col)
-                self.assertEqual(pg.find_paragraph(text, tempindex), expected)
-        text.delete('1.0', 'end')
-
-    def test_find_comment(self):
-        comment = (
-            "# Comment block with no blank lines before\n"
-            "# Comment line\n"
-            "\n")
-        self.runcase(comment, 3, ('1.0', '3.0', '#', comment[0:58]))
-
-        comment = (
-            "\n"
-            "# Comment block with whitespace line before and after\n"
-            "# Comment line\n"
-            "\n")
-        self.runcase(comment, 4, ('2.0', '4.0', '#', comment[1:70]))
-
-        comment = (
-            "\n"
-            "    # Indented comment block with whitespace before and after\n"
-            "    # Comment line\n"
-            "\n")
-        self.runcase(comment, 4, ('2.0', '4.0', '    #', comment[1:82]))
-
-        comment = (
-            "\n"
-            "# Single line comment\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:23]))
-
-        comment = (
-            "\n"
-            "    # Single line comment with leading whitespace\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:51]))
-
-        comment = (
-            "\n"
-            "# Comment immediately followed by code\n"
-            "x = 42\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:40]))
-
-        comment = (
-            "\n"
-            "    # Indented comment immediately followed by code\n"
-            "x = 42\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:53]))
-
-        comment = (
-            "\n"
-            "# Comment immediately followed by indented code\n"
-            "    x = 42\n"
-            "\n")
-        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:49]))
-
-    def test_find_paragraph(self):
-        teststring = (
-            '"""String with no blank lines before\n'
-            'String line\n'
-            '"""\n'
-            '\n')
-        self.runcase(teststring, 4, ('1.0', '4.0', '', teststring[0:53]))
-
-        teststring = (
-            "\n"
-            '"""String with whitespace line before and after\n'
-            'String line.\n'
-            '"""\n'
-            '\n')
-        self.runcase(teststring, 5, ('2.0', '5.0', '', teststring[1:66]))
-
-        teststring = (
-            '\n'
-            '    """Indented string with whitespace before and after\n'
-            '    Comment string.\n'
-            '    """\n'
-            '\n')
-        self.runcase(teststring, 5, ('2.0', '5.0', '    ', teststring[1:85]))
-
-        teststring = (
-            '\n'
-            '"""Single line string."""\n'
-            '\n')
-        self.runcase(teststring, 3, ('2.0', '3.0', '', teststring[1:27]))
-
-        teststring = (
-            '\n'
-            '    """Single line string with leading whitespace."""\n'
-            '\n')
-        self.runcase(teststring, 3, ('2.0', '3.0', '    ', teststring[1:55]))
-
-
-class ReformatFunctionTest(unittest.TestCase):
-    """Test the reformat_paragraph function without the editor window."""
-
-    def test_reformat_paragraph(self):
-        Equal = self.assertEqual
-        reform = pg.reformat_paragraph
-        hw = "O hello world"
-        Equal(reform(' ', 1), ' ')
-        Equal(reform("Hello    world", 20), "Hello  world")
-
-        # Test without leading newline
-        Equal(reform(hw, 1), "O\nhello\nworld")
-        Equal(reform(hw, 6), "O\nhello\nworld")
-        Equal(reform(hw, 7), "O hello\nworld")
-        Equal(reform(hw, 12), "O hello\nworld")
-        Equal(reform(hw, 13), "O hello world")
-
-        # Test with leading newline
-        hw = "\nO hello world"
-        Equal(reform(hw, 1), "\nO\nhello\nworld")
-        Equal(reform(hw, 6), "\nO\nhello\nworld")
-        Equal(reform(hw, 7), "\nO hello\nworld")
-        Equal(reform(hw, 12), "\nO hello\nworld")
-        Equal(reform(hw, 13), "\nO hello world")
-
-
-class ReformatCommentTest(unittest.TestCase):
-    """Test the reformat_comment function without the editor window."""
-
-    def test_reformat_comment(self):
-        Equal = self.assertEqual
-
-        # reformat_comment formats to a minimum of 20 characters
-        test_string = (
-            "    \"\"\"this is a test of a reformat for a triple quoted string"
-            " will it reformat to less than 70 characters for me?\"\"\"")
-        result = pg.reformat_comment(test_string, 70, "    ")
-        expected = (
-            "    \"\"\"this is a test of a reformat for a triple quoted string will it\n"
-            "    reformat to less than 70 characters for me?\"\"\"")
-        Equal(result, expected)
-
-        test_comment = (
-            "# this is a test of a reformat for a triple quoted string will "
-            "it reformat to less than 70 characters for me?")
-        result = pg.reformat_comment(test_comment, 70, "#")
-        expected = (
-            "# this is a test of a reformat for a triple quoted string will it\n"
-            "# reformat to less than 70 characters for me?")
-        Equal(result, expected)
-
-
-class FormatClassTest(unittest.TestCase):
-    def test_init_close(self):
-        instance = pg.FormatParagraph('editor')
-        self.assertEqual(instance.editwin, 'editor')
-        instance.close()
-        self.assertEqual(instance.editwin, None)
-
-
-# For testing format_paragraph_event, Initialize FormatParagraph with
-# a mock Editor with .text and  .get_selection_indices.  The text must
-# be a Text wrapper that adds two methods
-
-# A real EditorWindow creates unneeded, time-consuming baggage and
-# sometimes emits shutdown warnings like this:
-# "warning: callback failed in WindowList <class '_tkinter.TclError'>
-# : invalid command name ".55131368.windows".
-# Calling EditorWindow._close in tearDownClass prevents this but causes
-# other problems (windows left open).
-
-class TextWrapper:
-    def __init__(self, master):
-        self.text = Text(master=master)
-    def __getattr__(self, name):
-        return getattr(self.text, name)
-    def undo_block_start(self): pass
-    def undo_block_stop(self): pass
-
-class Editor:
-    def __init__(self, root):
-        self.text = TextWrapper(root)
-    get_selection_indices = EditorWindow. get_selection_indices
-
-class FormatEventTest(unittest.TestCase):
-    """Test the formatting of text inside a Text widget.
-
-    This is done with FormatParagraph.format.paragraph_event,
-    which calls functions in the module as appropriate.
-    """
-    test_string = (
-        "    '''this is a test of a reformat for a triple "
-        "quoted string will it reformat to less than 70 "
-        "characters for me?'''\n")
-    multiline_test_string = (
-        "    '''The first line is under the max width.\n"
-        "    The second line's length is way over the max width. It goes "
-        "on and on until it is over 100 characters long.\n"
-        "    Same thing with the third line. It is also way over the max "
-        "width, but FormatParagraph will fix it.\n"
-        "    '''\n")
-    multiline_test_comment = (
-        "# The first line is under the max width.\n"
-        "# The second line's length is way over the max width. It goes on "
-        "and on until it is over 100 characters long.\n"
-        "# Same thing with the third line. It is also way over the max "
-        "width, but FormatParagraph will fix it.\n"
-        "# The fourth line is short like the first line.")
-
-    @classmethod
-    def setUpClass(cls):
-        requires('gui')
-        cls.root = Tk()
-        cls.root.withdraw()
-        editor = Editor(root=cls.root)
-        cls.text = editor.text.text  # Test code does not need the wrapper.
-        cls.formatter = pg.FormatParagraph(editor).format_paragraph_event
-        # Sets the insert mark just after the re-wrapped and inserted  text.
-
-    @classmethod
-    def tearDownClass(cls):
-        del cls.text, cls.formatter
-        cls.root.update_idletasks()
-        cls.root.destroy()
-        del cls.root
-
-    def test_short_line(self):
-        self.text.insert('1.0', "Short line\n")
-        self.formatter("Dummy")
-        self.assertEqual(self.text.get('1.0', 'insert'), "Short line\n" )
-        self.text.delete('1.0', 'end')
-
-    def test_long_line(self):
-        text = self.text
-
-        # 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', limit=70)
-        result = text.get('1.0', 'insert')
-        # find function includes \n
-        expected = (
-"    '''this is a test of a reformat for a triple quoted string will it\n"
-"    reformat to less than 70 characters for me?'''\n")  # yes
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-        # 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', limit=70)
-        result = text.get('1.0', 'insert')
-        # selection excludes \n
-        expected = (
-"    '''this is a test of a reformat for a triple quoted string will it reformat\n"
-" to less than 70 characters for me?'''")  # no
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-    def test_multiple_lines(self):
-        text = self.text
-        #  Select 2 long lines.
-        text.insert('1.0', self.multiline_test_string)
-        text.tag_add('sel', '2.0', '4.0')
-        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"
-"    on until it is over 100 characters long. Same thing with the third\n"
-"    line. It is also way over the max width, but FormatParagraph will\n"
-"    fix it.\n")
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-    def test_comment_block(self):
-        text = self.text
-
-        # Set cursor ('insert') to '1.0', within block.
-        text.insert('1.0', self.multiline_test_comment)
-        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"
-"# way over the max width. It goes on and on until it is over 100\n"
-"# characters long. Same thing with the third line. It is also way over\n"
-"# the max width, but FormatParagraph will fix it. The fourth line is\n"
-"# short like the first line.\n")
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-        # 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', limit=70)
-        result = text.get('1.0', 'insert')
-        expected = (
-"# The first line is under the max width.\n"
-"# The second line's length is way over the max width. It goes on and\n"
-"# on until it is over 100 characters long.\n")
-        self.assertEqual(result, expected)
-        text.delete('1.0', 'end')
-
-# The following block worked with EditorWindow but fails with the mock.
-# Lines 2 and 3 get pasted together even though the previous block left
-# the previous line alone. More investigation is needed.
-##        # Select lines 3 and 4
-##        text.insert('1.0', self.multiline_test_comment)
-##        text.tag_add('sel', '3.0', '5.0')
-##        self.formatter('ParameterDoesNothing')
-##        result = text.get('3.0', 'insert')
-##        expected = (
-##"# Same thing with the third line. It is also way over the max width,\n"
-##"# but FormatParagraph will fix it. The fourth line is short like the\n"
-##"# first line.\n")
-##        self.assertEqual(result, expected)
-##        text.delete('1.0', 'end')
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=2)
index 479b84a216b02c26ed41622483bf9ee1d2177fea..f7154e6ded9574e14e9389f664090a3155de4514 100644 (file)
@@ -206,8 +206,8 @@ class PyParseTest(unittest.TestCase):
                                            'openbracket', 'bracketing'])
         tests = (
             TestInfo('', 0, 0, '', None, ((0, 0),)),
-            TestInfo("'''This is a multiline continutation docstring.\n\n",
-                     0, 49, "'", None, ((0, 0), (0, 1), (49, 0))),
+            TestInfo("'''This is a multiline continuation docstring.\n\n",
+                     0, 48, "'", None, ((0, 0), (0, 1), (48, 0))),
             TestInfo(' # Comment\\\n',
                      0, 12, '', None, ((0, 0), (1, 1), (12, 0))),
             # A comment without a space is a special case
index 581444ca5ef21fe9041424bf7629808db7d0b9b7..4a096676f25796379f637c214b8dc3f7edee5b56 100644 (file)
@@ -7,6 +7,28 @@ from test.support import requires
 from tkinter import Tk
 
 
+class FunctionTest(unittest.TestCase):
+    # Test stand-alone module level non-gui functions.
+
+    def test_restart_line_wide(self):
+        eq = self.assertEqual
+        for file, mul, extra in (('', 22, ''), ('finame', 21, '=')):
+            width = 60
+            bar = mul * '='
+            with self.subTest(file=file, bar=bar):
+                file = file or 'Shell'
+                line = pyshell.restart_line(width, file)
+                eq(len(line), width)
+                eq(line, f"{bar+extra} RESTART: {file} {bar}")
+
+    def test_restart_line_narrow(self):
+        expect, taglen = "= RESTART: Shell", 16
+        for width in (taglen-1, taglen, taglen+1):
+            with self.subTest(width=width):
+                self.assertEqual(pyshell.restart_line(width, ''), expect)
+        self.assertEqual(pyshell.restart_line(taglen+2, ''), expect+' =')
+
+
 class PyShellFileListTest(unittest.TestCase):
 
     @classmethod
index 3b444de15d7c0fba76555370801ba5ad5c349c6d..f957585190dc83e3817448386ea63df7a08a14b0 100644 (file)
@@ -12,7 +12,7 @@ HelpSource htests.  These are run by running query.py.
 from idlelib import query
 import unittest
 from test.support import requires
-from tkinter import Tk
+from tkinter import Tk, END
 
 import sys
 from unittest import mock
@@ -392,10 +392,12 @@ class CustomRunGuiTest(unittest.TestCase):
     def test_click_args(self):
         root = Tk()
         root.withdraw()
-        dialog =  query.CustomRun(root, 'Title', _utest=True)
-        dialog.entry.insert(0, 'okay')
+        dialog =  query.CustomRun(root, 'Title',
+                                  cli_args=['a', 'b=1'], _utest=True)
+        self.assertEqual(dialog.entry.get(), 'a b=1')
+        dialog.entry.insert(END, ' c')
         dialog.button_ok.invoke()
-        self.assertEqual(dialog.result, (['okay'], True))
+        self.assertEqual(dialog.result, (['a', 'b=1', 'c'], True))
         root.destroy()
 
 
diff --git a/Lib/idlelib/idle_test/test_rstrip.py b/Lib/idlelib/idle_test/test_rstrip.py
deleted file mode 100644 (file)
index 2bc7c6f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-"Test rstrip, coverage 100%."
-
-from idlelib import rstrip
-import unittest
-from idlelib.idle_test.mock_idle import Editor
-
-class rstripTest(unittest.TestCase):
-
-    def test_rstrip_line(self):
-        editor = Editor()
-        text = editor.text
-        do_rstrip = rstrip.Rstrip(editor).do_rstrip
-
-        do_rstrip()
-        self.assertEqual(text.get('1.0', 'insert'), '')
-        text.insert('1.0', '     ')
-        do_rstrip()
-        self.assertEqual(text.get('1.0', 'insert'), '')
-        text.insert('1.0', '     \n')
-        do_rstrip()
-        self.assertEqual(text.get('1.0', 'insert'), '\n')
-
-    def test_rstrip_multiple(self):
-        editor = Editor()
-        #  Comment above, uncomment 3 below to test with real Editor & Text.
-        #from idlelib.editor import EditorWindow as Editor
-        #from tkinter import Tk
-        #editor = Editor(root=Tk())
-        text = editor.text
-        do_rstrip = rstrip.Rstrip(editor).do_rstrip
-
-        original = (
-            "Line with an ending tab    \n"
-            "Line ending in 5 spaces     \n"
-            "Linewithnospaces\n"
-            "    indented line\n"
-            "    indented line with trailing space \n"
-            "    ")
-        stripped = (
-            "Line with an ending tab\n"
-            "Line ending in 5 spaces\n"
-            "Linewithnospaces\n"
-            "    indented line\n"
-            "    indented line with trailing space\n")
-
-        text.insert('1.0', original)
-        do_rstrip()
-        self.assertEqual(text.get('1.0', 'insert'), stripped)
-
-
-
-if __name__ == '__main__':
-    unittest.main(verbosity=2)
index 46f0235fbfdca171390227363059f11ce5fd94e3..cad0b4d98f8e0da2b9182d7c53cf5d50ee9c0c0e 100644 (file)
@@ -6,6 +6,8 @@ from unittest import mock
 from test.support import captured_stderr
 
 import io
+import sys
+
 
 class RunTest(unittest.TestCase):
 
@@ -260,5 +262,44 @@ class PseudeOutputFilesTest(unittest.TestCase):
         self.assertRaises(TypeError, f.close, 1)
 
 
+class TestSysRecursionLimitWrappers(unittest.TestCase):
+
+    def test_bad_setrecursionlimit_calls(self):
+        run.install_recursionlimit_wrappers()
+        self.addCleanup(run.uninstall_recursionlimit_wrappers)
+        f = sys.setrecursionlimit
+        self.assertRaises(TypeError, f, limit=100)
+        self.assertRaises(TypeError, f, 100, 1000)
+        self.assertRaises(ValueError, f, 0)
+
+    def test_roundtrip(self):
+        run.install_recursionlimit_wrappers()
+        self.addCleanup(run.uninstall_recursionlimit_wrappers)
+
+        # check that setting the recursion limit works
+        orig_reclimit = sys.getrecursionlimit()
+        self.addCleanup(sys.setrecursionlimit, orig_reclimit)
+        sys.setrecursionlimit(orig_reclimit + 3)
+
+        # check that the new limit is returned by sys.getrecursionlimit()
+        new_reclimit = sys.getrecursionlimit()
+        self.assertEqual(new_reclimit, orig_reclimit + 3)
+
+    def test_default_recursion_limit_preserved(self):
+        orig_reclimit = sys.getrecursionlimit()
+        run.install_recursionlimit_wrappers()
+        self.addCleanup(run.uninstall_recursionlimit_wrappers)
+        new_reclimit = sys.getrecursionlimit()
+        self.assertEqual(new_reclimit, orig_reclimit)
+
+    def test_fixdoc(self):
+        def func(): "docstring"
+        run.fixdoc(func, "more")
+        self.assertEqual(func.__doc__, "docstring\n\nmore")
+        func.__doc__ = None
+        run.fixdoc(func, "more")
+        self.assertEqual(func.__doc__, "more")
+
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_sidebar.py b/Lib/idlelib/idle_test/test_sidebar.py
new file mode 100644 (file)
index 0000000..0f5b4c7
--- /dev/null
@@ -0,0 +1,375 @@
+"""Test sidebar, coverage 93%"""
+import idlelib.sidebar
+from sys import platform
+from itertools import chain
+import unittest
+import unittest.mock
+from test.support import requires
+import tkinter as tk
+
+from idlelib.delegator import Delegator
+from idlelib.percolator import Percolator
+
+
+class Dummy_editwin:
+    def __init__(self, text):
+        self.text = text
+        self.text_frame = self.text.master
+        self.per = Percolator(text)
+        self.undo = Delegator()
+        self.per.insertfilter(self.undo)
+
+    def setvar(self, name, value):
+        pass
+
+    def getlineno(self, index):
+        return int(float(self.text.index(index)))
+
+
+class LineNumbersTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        requires('gui')
+        cls.root = tk.Tk()
+
+        cls.text_frame = tk.Frame(cls.root)
+        cls.text_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
+        cls.text_frame.rowconfigure(1, weight=1)
+        cls.text_frame.columnconfigure(1, weight=1)
+
+        cls.text = tk.Text(cls.text_frame, width=80, height=24, wrap=tk.NONE)
+        cls.text.grid(row=1, column=1, sticky=tk.NSEW)
+
+        cls.editwin = Dummy_editwin(cls.text)
+        cls.editwin.vbar = tk.Scrollbar(cls.text_frame)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.editwin.per.close()
+        cls.root.update()
+        cls.root.destroy()
+        del cls.text, cls.text_frame, cls.editwin, cls.root
+
+    def setUp(self):
+        self.linenumber = idlelib.sidebar.LineNumbers(self.editwin)
+
+        self.highlight_cfg = {"background": '#abcdef',
+                              "foreground": '#123456'}
+        orig_idleConf_GetHighlight = idlelib.sidebar.idleConf.GetHighlight
+        def mock_idleconf_GetHighlight(theme, element):
+            if element == 'linenumber':
+                return self.highlight_cfg
+            return orig_idleConf_GetHighlight(theme, element)
+        GetHighlight_patcher = unittest.mock.patch.object(
+            idlelib.sidebar.idleConf, 'GetHighlight', mock_idleconf_GetHighlight)
+        GetHighlight_patcher.start()
+        self.addCleanup(GetHighlight_patcher.stop)
+
+        self.font_override = 'TkFixedFont'
+        def mock_idleconf_GetFont(root, configType, section):
+            return self.font_override
+        GetFont_patcher = unittest.mock.patch.object(
+            idlelib.sidebar.idleConf, 'GetFont', mock_idleconf_GetFont)
+        GetFont_patcher.start()
+        self.addCleanup(GetFont_patcher.stop)
+
+    def tearDown(self):
+        self.text.delete('1.0', 'end')
+
+    def get_selection(self):
+        return tuple(map(str, self.text.tag_ranges('sel')))
+
+    def get_line_screen_position(self, line):
+        bbox = self.linenumber.sidebar_text.bbox(f'{line}.end -1c')
+        x = bbox[0] + 2
+        y = bbox[1] + 2
+        return x, y
+
+    def assert_state_disabled(self):
+        state = self.linenumber.sidebar_text.config()['state']
+        self.assertEqual(state[-1], tk.DISABLED)
+
+    def get_sidebar_text_contents(self):
+        return self.linenumber.sidebar_text.get('1.0', tk.END)
+
+    def assert_sidebar_n_lines(self, n_lines):
+        expected = '\n'.join(chain(map(str, range(1, n_lines + 1)), ['']))
+        self.assertEqual(self.get_sidebar_text_contents(), expected)
+
+    def assert_text_equals(self, expected):
+        return self.assertEqual(self.text.get('1.0', 'end'), expected)
+
+    def test_init_empty(self):
+        self.assert_sidebar_n_lines(1)
+
+    def test_init_not_empty(self):
+        self.text.insert('insert', 'foo bar\n'*3)
+        self.assert_text_equals('foo bar\n'*3 + '\n')
+        self.assert_sidebar_n_lines(4)
+
+    def test_toggle_linenumbering(self):
+        self.assertEqual(self.linenumber.is_shown, False)
+        self.linenumber.show_sidebar()
+        self.assertEqual(self.linenumber.is_shown, True)
+        self.linenumber.hide_sidebar()
+        self.assertEqual(self.linenumber.is_shown, False)
+        self.linenumber.hide_sidebar()
+        self.assertEqual(self.linenumber.is_shown, False)
+        self.linenumber.show_sidebar()
+        self.assertEqual(self.linenumber.is_shown, True)
+        self.linenumber.show_sidebar()
+        self.assertEqual(self.linenumber.is_shown, True)
+
+    def test_insert(self):
+        self.text.insert('insert', 'foobar')
+        self.assert_text_equals('foobar\n')
+        self.assert_sidebar_n_lines(1)
+        self.assert_state_disabled()
+
+        self.text.insert('insert', '\nfoo')
+        self.assert_text_equals('foobar\nfoo\n')
+        self.assert_sidebar_n_lines(2)
+        self.assert_state_disabled()
+
+        self.text.insert('insert', 'hello\n'*2)
+        self.assert_text_equals('foobar\nfoohello\nhello\n\n')
+        self.assert_sidebar_n_lines(4)
+        self.assert_state_disabled()
+
+        self.text.insert('insert', '\nworld')
+        self.assert_text_equals('foobar\nfoohello\nhello\n\nworld\n')
+        self.assert_sidebar_n_lines(5)
+        self.assert_state_disabled()
+
+    def test_delete(self):
+        self.text.insert('insert', 'foobar')
+        self.assert_text_equals('foobar\n')
+        self.text.delete('1.1', '1.3')
+        self.assert_text_equals('fbar\n')
+        self.assert_sidebar_n_lines(1)
+        self.assert_state_disabled()
+
+        self.text.insert('insert', 'foo\n'*2)
+        self.assert_text_equals('fbarfoo\nfoo\n\n')
+        self.assert_sidebar_n_lines(3)
+        self.assert_state_disabled()
+
+        # Note: deleting up to "2.end" doesn't delete the final newline.
+        self.text.delete('2.0', '2.end')
+        self.assert_text_equals('fbarfoo\n\n\n')
+        self.assert_sidebar_n_lines(3)
+        self.assert_state_disabled()
+
+        self.text.delete('1.3', 'end')
+        self.assert_text_equals('fba\n')
+        self.assert_sidebar_n_lines(1)
+        self.assert_state_disabled()
+
+        # Note: Text widgets always keep a single '\n' character at the end.
+        self.text.delete('1.0', 'end')
+        self.assert_text_equals('\n')
+        self.assert_sidebar_n_lines(1)
+        self.assert_state_disabled()
+
+    def test_sidebar_text_width(self):
+        """
+        Test that linenumber text widget is always at the minimum
+        width
+        """
+        def get_width():
+            return self.linenumber.sidebar_text.config()['width'][-1]
+
+        self.assert_sidebar_n_lines(1)
+        self.assertEqual(get_width(), 1)
+
+        self.text.insert('insert', 'foo')
+        self.assert_sidebar_n_lines(1)
+        self.assertEqual(get_width(), 1)
+
+        self.text.insert('insert', 'foo\n'*8)
+        self.assert_sidebar_n_lines(9)
+        self.assertEqual(get_width(), 1)
+
+        self.text.insert('insert', 'foo\n')
+        self.assert_sidebar_n_lines(10)
+        self.assertEqual(get_width(), 2)
+
+        self.text.insert('insert', 'foo\n')
+        self.assert_sidebar_n_lines(11)
+        self.assertEqual(get_width(), 2)
+
+        self.text.delete('insert -1l linestart', 'insert linestart')
+        self.assert_sidebar_n_lines(10)
+        self.assertEqual(get_width(), 2)
+
+        self.text.delete('insert -1l linestart', 'insert linestart')
+        self.assert_sidebar_n_lines(9)
+        self.assertEqual(get_width(), 1)
+
+        self.text.insert('insert', 'foo\n'*90)
+        self.assert_sidebar_n_lines(99)
+        self.assertEqual(get_width(), 2)
+
+        self.text.insert('insert', 'foo\n')
+        self.assert_sidebar_n_lines(100)
+        self.assertEqual(get_width(), 3)
+
+        self.text.insert('insert', 'foo\n')
+        self.assert_sidebar_n_lines(101)
+        self.assertEqual(get_width(), 3)
+
+        self.text.delete('insert -1l linestart', 'insert linestart')
+        self.assert_sidebar_n_lines(100)
+        self.assertEqual(get_width(), 3)
+
+        self.text.delete('insert -1l linestart', 'insert linestart')
+        self.assert_sidebar_n_lines(99)
+        self.assertEqual(get_width(), 2)
+
+        self.text.delete('50.0 -1c', 'end -1c')
+        self.assert_sidebar_n_lines(49)
+        self.assertEqual(get_width(), 2)
+
+        self.text.delete('5.0 -1c', 'end -1c')
+        self.assert_sidebar_n_lines(4)
+        self.assertEqual(get_width(), 1)
+
+        # Note: Text widgets always keep a single '\n' character at the end.
+        self.text.delete('1.0', 'end -1c')
+        self.assert_sidebar_n_lines(1)
+        self.assertEqual(get_width(), 1)
+
+    def test_click_selection(self):
+        self.linenumber.show_sidebar()
+        self.text.insert('1.0', 'one\ntwo\nthree\nfour\n')
+        self.root.update()
+
+        # Click on the second line.
+        x, y = self.get_line_screen_position(2)
+        self.linenumber.sidebar_text.event_generate('<Button-1>', x=x, y=y)
+        self.linenumber.sidebar_text.update()
+        self.root.update()
+
+        self.assertEqual(self.get_selection(), ('2.0', '3.0'))
+
+    def simulate_drag(self, start_line, end_line):
+        start_x, start_y = self.get_line_screen_position(start_line)
+        end_x, end_y = self.get_line_screen_position(end_line)
+
+        self.linenumber.sidebar_text.event_generate('<Button-1>',
+                                                    x=start_x, y=start_y)
+        self.root.update()
+
+        def lerp(a, b, steps):
+            """linearly interpolate from a to b (inclusive) in equal steps"""
+            last_step = steps - 1
+            for i in range(steps):
+                yield ((last_step - i) / last_step) * a + (i / last_step) * b
+
+        for x, y in zip(
+                map(int, lerp(start_x, end_x, steps=11)),
+                map(int, lerp(start_y, end_y, steps=11)),
+        ):
+            self.linenumber.sidebar_text.event_generate('<B1-Motion>', x=x, y=y)
+            self.root.update()
+
+        self.linenumber.sidebar_text.event_generate('<ButtonRelease-1>',
+                                                    x=end_x, y=end_y)
+        self.root.update()
+
+    def test_drag_selection_down(self):
+        self.linenumber.show_sidebar()
+        self.text.insert('1.0', 'one\ntwo\nthree\nfour\nfive\n')
+        self.root.update()
+
+        # Drag from the second line to the fourth line.
+        self.simulate_drag(2, 4)
+        self.assertEqual(self.get_selection(), ('2.0', '5.0'))
+
+    def test_drag_selection_up(self):
+        self.linenumber.show_sidebar()
+        self.text.insert('1.0', 'one\ntwo\nthree\nfour\nfive\n')
+        self.root.update()
+
+        # Drag from the fourth line to the second line.
+        self.simulate_drag(4, 2)
+        self.assertEqual(self.get_selection(), ('2.0', '5.0'))
+
+    def test_scroll(self):
+        self.linenumber.show_sidebar()
+        self.text.insert('1.0', 'line\n' * 100)
+        self.root.update()
+
+        # Scroll down 10 lines.
+        self.text.yview_scroll(10, 'unit')
+        self.root.update()
+        self.assertEqual(self.text.index('@0,0'), '11.0')
+        self.assertEqual(self.linenumber.sidebar_text.index('@0,0'), '11.0')
+
+        # Generate a mouse-wheel event and make sure it scrolled up or down.
+        # The meaning of the "delta" is OS-dependant, so this just checks for
+        # any change.
+        self.linenumber.sidebar_text.event_generate('<MouseWheel>',
+                                                    x=0, y=0,
+                                                    delta=10)
+        self.root.update()
+        self.assertNotEqual(self.text.index('@0,0'), '11.0')
+        self.assertNotEqual(self.linenumber.sidebar_text.index('@0,0'), '11.0')
+
+    def test_font(self):
+        ln = self.linenumber
+
+        orig_font = ln.sidebar_text['font']
+        test_font = 'TkTextFont'
+        self.assertNotEqual(orig_font, test_font)
+
+        # Ensure line numbers aren't shown.
+        ln.hide_sidebar()
+
+        self.font_override = test_font
+        # Nothing breaks when line numbers aren't shown.
+        ln.update_font()
+
+        # Activate line numbers, previous font change is immediately effective.
+        ln.show_sidebar()
+        self.assertEqual(ln.sidebar_text['font'], test_font)
+
+        # Call the font update with line numbers shown, change is picked up.
+        self.font_override = orig_font
+        ln.update_font()
+        self.assertEqual(ln.sidebar_text['font'], orig_font)
+
+    def test_highlight_colors(self):
+        ln = self.linenumber
+
+        orig_colors = dict(self.highlight_cfg)
+        test_colors = {'background': '#222222', 'foreground': '#ffff00'}
+
+        def assert_colors_are_equal(colors):
+            self.assertEqual(ln.sidebar_text['background'], colors['background'])
+            self.assertEqual(ln.sidebar_text['foreground'], colors['foreground'])
+
+        # Ensure line numbers aren't shown.
+        ln.hide_sidebar()
+
+        self.highlight_cfg = test_colors
+        # Nothing breaks with inactive code context.
+        ln.update_colors()
+
+        # Show line numbers, previous colors change is immediately effective.
+        ln.show_sidebar()
+        assert_colors_are_equal(test_colors)
+
+        # Call colors update with no change to the configured colors.
+        ln.update_colors()
+        assert_colors_are_equal(test_colors)
+
+        # Call the colors update with line numbers shown, change is picked up.
+        self.highlight_cfg = orig_colors
+        ln.update_colors()
+        assert_colors_are_equal(orig_colors)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
index 4e3da030a3adce048ba52ebdf99b9305fc53bf06..1af2ce832845cdaca1a70e96adf4b2f1364e80cd 100644 (file)
@@ -82,18 +82,10 @@ class CountLinesTest(unittest.TestCase):
 
 class SqueezerTest(unittest.TestCase):
     """Tests for the Squeezer class."""
-    def tearDown(self):
-        # Clean up the Squeezer class's reference to its instance,
-        # to avoid side-effects from one test case upon another.
-        if Squeezer._instance_weakref is not None:
-            Squeezer._instance_weakref = None
-
     def make_mock_editor_window(self, with_text_widget=False):
         """Create a mock EditorWindow instance."""
         editwin = NonCallableMagicMock()
-        # isinstance(editwin, PyShell) must be true for Squeezer to enable
-        # auto-squeezing; in practice this will always be true.
-        editwin.__class__ = PyShell
+        editwin.width = 80
 
         if with_text_widget:
             editwin.root = get_test_tk_root(self)
@@ -107,7 +99,6 @@ class SqueezerTest(unittest.TestCase):
         if editor_window is None:
             editor_window = self.make_mock_editor_window()
         squeezer = Squeezer(editor_window)
-        squeezer.get_line_width = Mock(return_value=80)
         return squeezer
 
     def make_text_widget(self, root=None):
@@ -143,8 +134,8 @@ class SqueezerTest(unittest.TestCase):
                               line_width=line_width,
                               expected=expected):
                 text = eval(text_code)
-                squeezer.get_line_width.return_value = line_width
-                self.assertEqual(squeezer.count_lines(text), expected)
+                with patch.object(editwin, 'width', line_width):
+                    self.assertEqual(squeezer.count_lines(text), expected)
 
     def test_init(self):
         """Test the creation of Squeezer instances."""
@@ -294,7 +285,6 @@ class SqueezerTest(unittest.TestCase):
         """Test the reload() class-method."""
         editwin = self.make_mock_editor_window(with_text_widget=True)
         squeezer = self.make_squeezer_instance(editwin)
-        squeezer.load_font = Mock()
 
         orig_auto_squeeze_min_lines = squeezer.auto_squeeze_min_lines
 
@@ -307,7 +297,6 @@ class SqueezerTest(unittest.TestCase):
         Squeezer.reload()
         self.assertEqual(squeezer.auto_squeeze_min_lines,
                          new_auto_squeeze_min_lines)
-        squeezer.load_font.assert_called()
 
     def test_reload_no_squeezer_instances(self):
         """Test that Squeezer.reload() runs without any instances existing."""
index 6f0c1930518a51e5c4c9c9819ce927d3f337018a..7189378ab3dd615e04cf17c2869e1fd611cb4eb1 100644 (file)
@@ -6,12 +6,12 @@ Using mock Text would not change this.  Other mocks are used to retrieve
 information about calls.
 """
 from idlelib import textview as tv
-import unittest
 from test.support import requires
 requires('gui')
 
 import os
-from tkinter import Tk
+import unittest
+from tkinter import Tk, TclError, CHAR, NONE, WORD
 from tkinter.ttk import Button
 from idlelib.idle_test.mock_idle import Func
 from idlelib.idle_test.mock_tk import Mbox_func
@@ -69,13 +69,65 @@ class ViewWindowTest(unittest.TestCase):
         view.destroy()
 
 
-class TextFrameTest(unittest.TestCase):
+class AutoHideScrollbarTest(unittest.TestCase):
+    # Method set is tested in ScrollableTextFrameTest
+    def test_forbidden_geometry(self):
+        scroll = tv.AutoHideScrollbar(root)
+        self.assertRaises(TclError, scroll.pack)
+        self.assertRaises(TclError, scroll.place)
+
+
+class ScrollableTextFrameTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = root = Tk()
+        root.withdraw()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
+
+    def make_frame(self, wrap=NONE, **kwargs):
+        frame = tv.ScrollableTextFrame(self.root, wrap=wrap, **kwargs)
+        def cleanup_frame():
+            frame.update_idletasks()
+            frame.destroy()
+        self.addCleanup(cleanup_frame)
+        return frame
+
+    def test_line1(self):
+        frame = self.make_frame()
+        frame.text.insert('1.0', 'test text')
+        self.assertEqual(frame.text.get('1.0', '1.end'), 'test text')
+
+    def test_horiz_scrollbar(self):
+        # The horizontal scrollbar should be shown/hidden according to
+        # the 'wrap' setting: It should only be shown when 'wrap' is
+        # set to NONE.
+
+        # wrap = NONE -> with horizontal scrolling
+        frame = self.make_frame(wrap=NONE)
+        self.assertEqual(frame.text.cget('wrap'), NONE)
+        self.assertIsNotNone(frame.xscroll)
+
+        # wrap != NONE -> no horizontal scrolling
+        for wrap in [CHAR, WORD]:
+            with self.subTest(wrap=wrap):
+                frame = self.make_frame(wrap=wrap)
+                self.assertEqual(frame.text.cget('wrap'), wrap)
+                self.assertIsNone(frame.xscroll)
+
+
+class ViewFrameTest(unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
         cls.root = root = Tk()
         root.withdraw()
-        cls.frame = tv.TextFrame(root, 'test text')
+        cls.frame = tv.ViewFrame(root, 'test text')
 
     @classmethod
     def tearDownClass(cls):
index 44ea1110e155dcb8fa2b4c28cfedda9ceb17350a..c616d4fde3b6d30433c0e163206059c1c55f1ea2 100644 (file)
@@ -1,3 +1,10 @@
+"""Test tooltip, coverage 100%.
+
+Coverage is 100% after excluding 6 lines with "# pragma: no cover".
+They involve TclErrors that either should or should not happen in a
+particular situation, and which are 'pass'ed if they do.
+"""
+
 from idlelib.tooltip import TooltipBase, Hovertip
 from test.support import requires
 requires('gui')
@@ -12,16 +19,13 @@ def setUpModule():
     global root
     root = Tk()
 
-def root_update():
-    global root
-    root.update()
-
 def tearDownModule():
     global root
     root.update_idletasks()
     root.destroy()
     del root
 
+
 def add_call_counting(func):
     @wraps(func)
     def wrapped_func(*args, **kwargs):
@@ -65,22 +69,25 @@ class HovertipTest(unittest.TestCase):
     def setUp(self):
         self.top, self.button = _make_top_and_button(self)
 
+    def is_tipwindow_shown(self, tooltip):
+        return tooltip.tipwindow and tooltip.tipwindow.winfo_viewable()
+
     def test_showtip(self):
         tooltip = Hovertip(self.button, 'ToolTip text')
         self.addCleanup(tooltip.hidetip)
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        self.assertFalse(self.is_tipwindow_shown(tooltip))
         tooltip.showtip()
-        self.assertTrue(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        self.assertTrue(self.is_tipwindow_shown(tooltip))
 
     def test_showtip_twice(self):
         tooltip = Hovertip(self.button, 'ToolTip text')
         self.addCleanup(tooltip.hidetip)
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        self.assertFalse(self.is_tipwindow_shown(tooltip))
         tooltip.showtip()
-        self.assertTrue(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        self.assertTrue(self.is_tipwindow_shown(tooltip))
         orig_tipwindow = tooltip.tipwindow
         tooltip.showtip()
-        self.assertTrue(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        self.assertTrue(self.is_tipwindow_shown(tooltip))
         self.assertIs(tooltip.tipwindow, orig_tipwindow)
 
     def test_hidetip(self):
@@ -88,59 +95,67 @@ class HovertipTest(unittest.TestCase):
         self.addCleanup(tooltip.hidetip)
         tooltip.showtip()
         tooltip.hidetip()
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        self.assertFalse(self.is_tipwindow_shown(tooltip))
 
     def test_showtip_on_mouse_enter_no_delay(self):
         tooltip = Hovertip(self.button, 'ToolTip text', hover_delay=None)
         self.addCleanup(tooltip.hidetip)
         tooltip.showtip = add_call_counting(tooltip.showtip)
-        root_update()
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        root.update()
+        self.assertFalse(self.is_tipwindow_shown(tooltip))
         self.button.event_generate('<Enter>', x=0, y=0)
-        root_update()
-        self.assertTrue(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        root.update()
+        self.assertTrue(self.is_tipwindow_shown(tooltip))
         self.assertGreater(len(tooltip.showtip.call_args_list), 0)
 
-    def test_showtip_on_mouse_enter_hover_delay(self):
-        tooltip = Hovertip(self.button, 'ToolTip text', hover_delay=50)
-        self.addCleanup(tooltip.hidetip)
-        tooltip.showtip = add_call_counting(tooltip.showtip)
-        root_update()
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+    def test_hover_with_delay(self):
+        # Run multiple tests requiring an actual delay simultaneously.
+
+        # Test #1: A hover tip with a non-zero delay appears after the delay.
+        tooltip1 = Hovertip(self.button, 'ToolTip text', hover_delay=100)
+        self.addCleanup(tooltip1.hidetip)
+        tooltip1.showtip = add_call_counting(tooltip1.showtip)
+        root.update()
+        self.assertFalse(self.is_tipwindow_shown(tooltip1))
         self.button.event_generate('<Enter>', x=0, y=0)
-        root_update()
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
-        time.sleep(0.1)
-        root_update()
-        self.assertTrue(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
-        self.assertGreater(len(tooltip.showtip.call_args_list), 0)
+        root.update()
+        self.assertFalse(self.is_tipwindow_shown(tooltip1))
+
+        # Test #2: A hover tip with a non-zero delay doesn't appear when
+        # the mouse stops hovering over the base widget before the delay
+        # expires.
+        tooltip2 = Hovertip(self.button, 'ToolTip text', hover_delay=100)
+        self.addCleanup(tooltip2.hidetip)
+        tooltip2.showtip = add_call_counting(tooltip2.showtip)
+        root.update()
+        self.button.event_generate('<Enter>', x=0, y=0)
+        root.update()
+        self.button.event_generate('<Leave>', x=0, y=0)
+        root.update()
+
+        time.sleep(0.15)
+        root.update()
+
+        # Test #1 assertions.
+        self.assertTrue(self.is_tipwindow_shown(tooltip1))
+        self.assertGreater(len(tooltip1.showtip.call_args_list), 0)
+
+        # Test #2 assertions.
+        self.assertFalse(self.is_tipwindow_shown(tooltip2))
+        self.assertEqual(tooltip2.showtip.call_args_list, [])
 
     def test_hidetip_on_mouse_leave(self):
         tooltip = Hovertip(self.button, 'ToolTip text', hover_delay=None)
         self.addCleanup(tooltip.hidetip)
         tooltip.showtip = add_call_counting(tooltip.showtip)
-        root_update()
+        root.update()
         self.button.event_generate('<Enter>', x=0, y=0)
-        root_update()
+        root.update()
         self.button.event_generate('<Leave>', x=0, y=0)
-        root_update()
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
+        root.update()
+        self.assertFalse(self.is_tipwindow_shown(tooltip))
         self.assertGreater(len(tooltip.showtip.call_args_list), 0)
 
-    def test_dont_show_on_mouse_leave_before_delay(self):
-        tooltip = Hovertip(self.button, 'ToolTip text', hover_delay=50)
-        self.addCleanup(tooltip.hidetip)
-        tooltip.showtip = add_call_counting(tooltip.showtip)
-        root_update()
-        self.button.event_generate('<Enter>', x=0, y=0)
-        root_update()
-        self.button.event_generate('<Leave>', x=0, y=0)
-        root_update()
-        time.sleep(0.1)
-        root_update()
-        self.assertFalse(tooltip.tipwindow and tooltip.tipwindow.winfo_viewable())
-        self.assertEqual(tooltip.showtip.call_args_list, [])
-
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
index 9be9abee361f083632626437e483602cdc93c771..b3e4c10cf9e38e7efc183352f6de98673841d9fd 100644 (file)
@@ -4,7 +4,7 @@ from idlelib import tree
 import unittest
 from test.support import requires
 requires('gui')
-from tkinter import Tk
+from tkinter import Tk, EventType, SCROLL
 
 
 class TreeTest(unittest.TestCase):
@@ -29,5 +29,32 @@ class TreeTest(unittest.TestCase):
         node.expand()
 
 
+class TestScrollEvent(unittest.TestCase):
+
+    def test_wheel_event(self):
+        # Fake widget class containing `yview` only.
+        class _Widget:
+            def __init__(widget, *expected):
+                widget.expected = expected
+            def yview(widget, *args):
+                self.assertTupleEqual(widget.expected, args)
+        # Fake event class
+        class _Event:
+            pass
+        #        (type, delta, num, amount)
+        tests = ((EventType.MouseWheel, 120, -1, -5),
+                 (EventType.MouseWheel, -120, -1, 5),
+                 (EventType.ButtonPress, -1, 4, -5),
+                 (EventType.ButtonPress, -1, 5, 5))
+
+        event = _Event()
+        for ty, delta, num, amount in tests:
+            event.type = ty
+            event.delta = delta
+            event.num = num
+            res = tree.wheel_event(event, _Widget(SCROLL, amount, "units"))
+            self.assertEqual(res, "break")
+
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
index 1b8dc475650d8db679781e485248e214acb8bd10..74edce234838292859c4e5e17e5ac0f428b7dffd 100644 (file)
@@ -60,6 +60,7 @@ menudefs = [
    ]),
 
  ('format', [
+   ('F_ormat Paragraph', '<<format-paragraph>>'),
    ('_Indent Region', '<<indent-region>>'),
    ('_Dedent Region', '<<dedent-region>>'),
    ('Comment _Out Region', '<<comment-region>>'),
@@ -68,15 +69,14 @@ menudefs = [
    ('Untabify Region', '<<untabify-region>>'),
    ('Toggle Tabs', '<<toggle-tabs>>'),
    ('New Indent Width', '<<change-indentwidth>>'),
-   ('F_ormat Paragraph', '<<format-paragraph>>'),
    ('S_trip Trailing Whitespace', '<<do-rstrip>>'),
    ]),
 
  ('run', [
-   ('Python Shell', '<<open-python-shell>>'),
-   ('C_heck Module', '<<check-module>>'),
    ('R_un Module', '<<run-module>>'),
    ('Run... _Customized', '<<run-custom>>'),
+   ('C_heck Module', '<<check-module>>'),
+   ('Python Shell', '<<open-python-shell>>'),
    ]),
 
  ('shell', [
@@ -100,7 +100,8 @@ menudefs = [
    ('Configure _IDLE', '<<open-config-dialog>>'),
    None,
    ('Show _Code Context', '<<toggle-code-context>>'),
-   ('Zoom Height', '<<zoom-height>>'),
+   ('Show _Line Numbers', '<<toggle-line-numbers>>'),
+   ('_Zoom Height', '<<zoom-height>>'),
    ]),
 
  ('window', [
index ecc53ef0195dc644e8bdfde4d6d4121aef7a59e4..90272b6feb4af6eaf99746959c289f92e3af2a2e 100644 (file)
@@ -74,11 +74,11 @@ class OutputWindow(EditorWindow):
         ("Go to file/line", "<<goto-file-line>>", None),
     ]
 
+    allow_code_context = False
+
     def __init__(self, *args):
         EditorWindow.__init__(self, *args)
         self.text.bind("<<goto-file-line>>", self.goto_file_line)
-        self.text.unbind("<<toggle-code-context>>")
-        self.update_menu_state('options', '*Code Context', 'disabled')
 
     # Customize EditorWindow
     def ispythonsource(self, filename):
diff --git a/Lib/idlelib/paragraph.py b/Lib/idlelib/paragraph.py
deleted file mode 100644 (file)
index 8142257..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-"""Format a paragraph, comment block, or selection to a max width.
-
-Does basic, standard text formatting, and also understands Python
-comment blocks. Thus, for editing Python source code, this
-extension is really only suitable for reformatting these comment
-blocks or triple-quoted strings.
-
-Known problems with comment reformatting:
-* If there is a selection marked, and the first line of the
-  selection is not complete, the block will probably not be detected
-  as comments, and will have the normal "text formatting" rules
-  applied.
-* If a comment block has leading whitespace that mixes tabs and
-  spaces, they will not be considered part of the same block.
-* Fancy comments, like this bulleted list, aren't handled :-)
-"""
-import re
-
-from idlelib.config import idleConf
-
-
-class FormatParagraph:
-
-    def __init__(self, editwin):
-        self.editwin = editwin
-
-    @classmethod
-    def reload(cls):
-        cls.max_width = idleConf.GetOption('extensions', 'FormatParagraph',
-                                           'max-width', type='int', default=72)
-
-    def close(self):
-        self.editwin = None
-
-    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
-        at the max width, starting from the beginning selection.
-
-        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.
-        """
-        limit = self.max_width if limit is None else limit
-        text = self.editwin.text
-        first, last = self.editwin.get_selection_indices()
-        if first and last:
-            data = text.get(first, last)
-            comment_header = get_comment_header(data)
-        else:
-            first, last, comment_header, data = \
-                    find_paragraph(text, text.index("insert"))
-        if comment_header:
-            newdata = reformat_comment(data, limit, comment_header)
-        else:
-            newdata = reformat_paragraph(data, limit)
-        text.tag_remove("sel", "1.0", "end")
-
-        if newdata != data:
-            text.mark_set("insert", first)
-            text.undo_block_start()
-            text.delete(first, last)
-            text.insert(first, newdata)
-            text.undo_block_stop()
-        else:
-            text.mark_set("insert", last)
-        text.see("insert")
-        return "break"
-
-
-FormatParagraph.reload()
-
-def find_paragraph(text, mark):
-    """Returns the start/stop indices enclosing the paragraph that mark is in.
-
-    Also returns the comment format string, if any, and paragraph of text
-    between the start/stop indices.
-    """
-    lineno, col = map(int, mark.split("."))
-    line = text.get("%d.0" % lineno, "%d.end" % lineno)
-
-    # Look for start of next paragraph if the index passed in is a blank line
-    while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line):
-        lineno = lineno + 1
-        line = text.get("%d.0" % lineno, "%d.end" % lineno)
-    first_lineno = lineno
-    comment_header = get_comment_header(line)
-    comment_header_len = len(comment_header)
-
-    # Once start line found, search for end of paragraph (a blank line)
-    while get_comment_header(line)==comment_header and \
-              not is_all_white(line[comment_header_len:]):
-        lineno = lineno + 1
-        line = text.get("%d.0" % lineno, "%d.end" % lineno)
-    last = "%d.0" % lineno
-
-    # Search back to beginning of paragraph (first blank line before)
-    lineno = first_lineno - 1
-    line = text.get("%d.0" % lineno, "%d.end" % lineno)
-    while lineno > 0 and \
-              get_comment_header(line)==comment_header and \
-              not is_all_white(line[comment_header_len:]):
-        lineno = lineno - 1
-        line = text.get("%d.0" % lineno, "%d.end" % lineno)
-    first = "%d.0" % (lineno+1)
-
-    return first, last, comment_header, text.get(first, last)
-
-# This should perhaps be replaced with textwrap.wrap
-def reformat_paragraph(data, limit):
-    """Return data reformatted to specified width (limit)."""
-    lines = data.split("\n")
-    i = 0
-    n = len(lines)
-    while i < n and is_all_white(lines[i]):
-        i = i+1
-    if i >= n:
-        return data
-    indent1 = get_indent(lines[i])
-    if i+1 < n and not is_all_white(lines[i+1]):
-        indent2 = get_indent(lines[i+1])
-    else:
-        indent2 = indent1
-    new = lines[:i]
-    partial = indent1
-    while i < n and not is_all_white(lines[i]):
-        # XXX Should take double space after period (etc.) into account
-        words = re.split(r"(\s+)", lines[i])
-        for j in range(0, len(words), 2):
-            word = words[j]
-            if not word:
-                continue # Can happen when line ends in whitespace
-            if len((partial + word).expandtabs()) > limit and \
-                   partial != indent1:
-                new.append(partial.rstrip())
-                partial = indent2
-            partial = partial + word + " "
-            if j+1 < len(words) and words[j+1] != " ":
-                partial = partial + " "
-        i = i+1
-    new.append(partial.rstrip())
-    # XXX Should reformat remaining paragraphs as well
-    new.extend(lines[i:])
-    return "\n".join(new)
-
-def reformat_comment(data, limit, comment_header):
-    """Return data reformatted to specified width with comment header."""
-
-    # Remove header from the comment lines
-    lc = len(comment_header)
-    data = "\n".join(line[lc:] for line in data.split("\n"))
-    # Reformat to maxformatwidth chars or a 20 char width,
-    # whichever is greater.
-    format_width = max(limit - len(comment_header), 20)
-    newdata = reformat_paragraph(data, format_width)
-    # re-split and re-insert the comment header.
-    newdata = newdata.split("\n")
-    # If the block ends in a \n, we don't want the comment prefix
-    # inserted after it. (Im not sure it makes sense to reformat a
-    # comment block that is not made of complete lines, but whatever!)
-    # Can't think of a clean solution, so we hack away
-    block_suffix = ""
-    if not newdata[-1]:
-        block_suffix = "\n"
-        newdata = newdata[:-1]
-    return '\n'.join(comment_header+line for line in newdata) + block_suffix
-
-def is_all_white(line):
-    """Return True if line is empty or all whitespace."""
-
-    return re.match(r"^\s*$", line) is not None
-
-def get_indent(line):
-    """Return the initial space or tab indent of line."""
-    return re.match(r"^([ \t]*)", line).group()
-
-def get_comment_header(line):
-    """Return string with leading whitespace and '#' from line or ''.
-
-    A null return indicates that the line is not a comment line. A non-
-    null return, such as '    #', will be used to find the other lines of
-    a comment block with the same  indent.
-    """
-    m = re.match(r"^([ \t]*#*)", line)
-    if m is None: return ""
-    return m.group(1)
-
-
-if __name__ == "__main__":
-    from unittest import main
-    main('idlelib.idle_test.test_paragraph', verbosity=2, exit=False)
index 81e7f539803c08e3737056737d6d9ffbd4615542..feb57cbb74056410868c3e8a83457130c5468342 100644 (file)
@@ -575,7 +575,7 @@ class Parser:
         return code[i:j]
 
     def is_block_opener(self):
-        "Return True if the last interesting statemtent opens a block."
+        "Return True if the last interesting statement opens a block."
         self._study2()
         return self.lastch == ':'
 
index 7ad5a76c3bd5e06830d13bd9934d94d5e13ca805..2e4dfad401221f5614fb964113d0c936441947ed 100755 (executable)
@@ -133,6 +133,7 @@ class PyShellEditorWindow(EditorWindow):
         self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
         self.text.bind("<<open-python-shell>>", self.flist.open_shell)
 
+        #TODO: don't read/write this from/to .idlerc when testing
         self.breakpointPath = os.path.join(
                 idleConf.userdir, 'breakpoints.lst')
         # whenever a file is changed, restore breakpoints
@@ -387,6 +388,19 @@ class MyRPCClient(rpc.RPCClient):
         "Override the base class - just re-raise EOFError"
         raise EOFError
 
+def restart_line(width, filename):  # See bpo-38141.
+    """Return width long restart line formatted with filename.
+
+    Fill line with balanced '='s, with any extras and at least one at
+    the beginning.  Do not end with a trailing space.
+    """
+    tag = f"= RESTART: {filename or 'Shell'} ="
+    if width >= len(tag):
+        div, mod = divmod((width -len(tag)), 2)
+        return f"{(div+mod)*'='}{tag}{div*'='}"
+    else:
+        return tag[:-2]  # Remove ' ='.
+
 
 class ModifiedInterpreter(InteractiveInterpreter):
 
@@ -394,7 +408,6 @@ class ModifiedInterpreter(InteractiveInterpreter):
         self.tkconsole = tkconsole
         locals = sys.modules['__main__'].__dict__
         InteractiveInterpreter.__init__(self, locals=locals)
-        self.save_warnings_filters = None
         self.restarting = False
         self.subprocess_arglist = None
         self.port = PORT
@@ -492,9 +505,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
         console.stop_readline()
         # annotate restart in shell window and mark it
         console.text.delete("iomark", "end-1c")
-        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.write('\n')
+        console.write(restart_line(console.width, filename))
         console.text.mark_set("restart", "end-1c")
         console.text.mark_gravity("restart", "left")
         if not filename:
@@ -665,8 +677,6 @@ class ModifiedInterpreter(InteractiveInterpreter):
         "Extend base class method: Stuff the source in the line cache first"
         filename = self.stuffsource(source)
         self.more = 0
-        self.save_warnings_filters = warnings.filters[:]
-        warnings.filterwarnings(action="error", category=SyntaxWarning)
         # at the moment, InteractiveInterpreter expects str
         assert isinstance(source, str)
         #if isinstance(source, str):
@@ -677,14 +687,9 @@ class ModifiedInterpreter(InteractiveInterpreter):
         #        self.tkconsole.resetoutput()
         #        self.write("Unsupported characters in input\n")
         #        return
-        try:
-            # InteractiveInterpreter.runsource() calls its runcode() method,
-            # which is overridden (see below)
-            return InteractiveInterpreter.runsource(self, source, filename)
-        finally:
-            if self.save_warnings_filters is not None:
-                warnings.filters[:] = self.save_warnings_filters
-                self.save_warnings_filters = None
+        # InteractiveInterpreter.runsource() calls its runcode() method,
+        # which is overridden (see below)
+        return InteractiveInterpreter.runsource(self, source, filename)
 
     def stuffsource(self, source):
         "Stuff source in the filename cache"
@@ -763,9 +768,6 @@ class ModifiedInterpreter(InteractiveInterpreter):
         if self.tkconsole.executing:
             self.interp.restart_subprocess()
         self.checklinecache()
-        if self.save_warnings_filters is not None:
-            warnings.filters[:] = self.save_warnings_filters
-            self.save_warnings_filters = None
         debugger = self.debugger
         try:
             self.tkconsole.beginexecuting()
@@ -861,6 +863,8 @@ class PyShell(OutputWindow):
         ("Squeeze", "<<squeeze-current-text>>"),
     ]
 
+    allow_line_numbers = False
+
     # New classes
     from idlelib.history import History
 
index 9b3bb1d186b89c6af20385bb07d7b8e485e1f65e..097e6e61e3569cf4ea2e78c7716390cc89fb9b5c 100644 (file)
@@ -36,10 +36,10 @@ class Query(Toplevel):
     """
     def __init__(self, parent, title, message, *, text0='', used_names={},
                  _htest=False, _utest=False):
-        """Create popup, do not return until tk widget destroyed.
+        """Create modal popup, return when destroyed.
 
-        Additional subclass init must be done before calling this
-        unless  _utest=True is passed to suppress wait_window().
+        Additional subclass init must be done before this unless
+        _utest=True is passed to suppress wait_window().
 
         title - string, title of popup dialog
         message - string, informational message to display
@@ -48,15 +48,17 @@ class Query(Toplevel):
         _htest - bool, change box location when running htest
         _utest - bool, leave window hidden and not modal
         """
-        Toplevel.__init__(self, parent)
-        self.withdraw()  # Hide while configuring, especially geometry.
-        self.parent = parent
-        self.title(title)
+        self.parent = parent  # Needed for Font call.
         self.message = message
         self.text0 = text0
         self.used_names = used_names
+
+        Toplevel.__init__(self, parent)
+        self.withdraw()  # Hide while configuring, especially geometry.
+        self.title(title)
         self.transient(parent)
         self.grab_set()
+
         windowingsystem = self.tk.call('tk', 'windowingsystem')
         if windowingsystem == 'aqua':
             try:
@@ -69,9 +71,9 @@ class Query(Toplevel):
         self.protocol("WM_DELETE_WINDOW", self.cancel)
         self.bind('<Key-Return>', self.ok)
         self.bind("<KP_Enter>", self.ok)
-        self.resizable(height=False, width=False)
+
         self.create_widgets()
-        self.update_idletasks()  # Needed here for winfo_reqwidth below.
+        self.update_idletasks()  # Need here for winfo_reqwidth below.
         self.geometry(  # Center dialog over parent (or below htest box).
                 "+%d+%d" % (
                     parent.winfo_rootx() +
@@ -80,12 +82,19 @@ class Query(Toplevel):
                     ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                     if not _htest else 150)
                 ) )
+        self.resizable(height=False, width=False)
+
         if not _utest:
             self.deiconify()  # Unhide now that geometry set.
             self.wait_window()
 
-    def create_widgets(self, ok_text='OK'):  # Call from override, if any.
-        # Bind to self widgets needed for entry_ok or unittest.
+    def create_widgets(self, ok_text='OK'):  # Do not replace.
+        """Create entry (rows, extras, buttons.
+
+        Entry stuff on rows 0-2, spanning cols 0-2.
+        Buttons on row 99, cols 1, 2.
+        """
+        # Bind to self the widgets needed for entry_ok or unittest.
         self.frame = frame = Frame(self, padding=10)
         frame.grid(column=0, row=0, sticky='news')
         frame.grid_columnconfigure(0, weight=1)
@@ -99,19 +108,24 @@ class Query(Toplevel):
                                exists=True, root=self.parent)
         self.entry_error = Label(frame, text=' ', foreground='red',
                                  font=self.error_font)
-        self.button_ok = Button(
-                frame, text=ok_text, default='active', command=self.ok)
-        self.button_cancel = Button(
-                frame, text='Cancel', command=self.cancel)
-
         entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
         self.entry.grid(column=0, row=1, columnspan=3, padx=5, sticky=W+E,
                         pady=[10,0])
         self.entry_error.grid(column=0, row=2, columnspan=3, padx=5,
                               sticky=W+E)
+
+        self.create_extra()
+
+        self.button_ok = Button(
+                frame, text=ok_text, default='active', command=self.ok)
+        self.button_cancel = Button(
+                frame, text='Cancel', command=self.cancel)
+
         self.button_ok.grid(column=1, row=99, padx=5)
         self.button_cancel.grid(column=2, row=99, padx=5)
 
+    def create_extra(self): pass  # Override to add widgets.
+
     def showerror(self, message, widget=None):
         #self.bell(displayof=self)
         (widget or self.entry_error)['text'] = 'ERROR: ' + message
@@ -227,8 +241,8 @@ class HelpSource(Query):
                 parent, title, message, text0=menuitem,
                 used_names=used_names, _htest=_htest, _utest=_utest)
 
-    def create_widgets(self):
-        super().create_widgets()
+    def create_extra(self):
+        "Add path widjets to rows 10-12."
         frame = self.frame
         pathlabel = Label(frame, anchor='w', justify='left',
                           text='Help File Path: Enter URL or browse for file')
@@ -311,16 +325,20 @@ class CustomRun(Query):
     """
     # Used in runscript.run_custom_event
 
-    def __init__(self, parent, title, *, cli_args='',
+    def __init__(self, parent, title, *, cli_args=[],
                  _htest=False, _utest=False):
-        # TODO Use cli_args to pre-populate entry.
+        """cli_args is a list of strings.
+
+        The list is assigned to the default Entry StringVar.
+        The strings are displayed joined by ' ' for display.
+        """
         message = 'Command Line Arguments for sys.argv:'
         super().__init__(
                 parent, title, message, text0=cli_args,
                 _htest=_htest, _utest=_utest)
 
-    def create_widgets(self):
-        super().create_widgets(ok_text='Run')
+    def create_extra(self):
+        "Add run mode on rows 10-12."
         frame = self.frame
         self.restartvar = BooleanVar(self, value=True)
         restart = Checkbutton(frame, variable=self.restartvar, onvalue=True,
@@ -328,7 +346,7 @@ class CustomRun(Query):
         self.args_error = Label(frame, text=' ', foreground='red',
                                 font=self.error_font)
 
-        restart.grid(column=0, row=4, columnspan=3, padx=5, sticky='w')
+        restart.grid(column=0, row=10, columnspan=3, padx=5, sticky='w')
         self.args_error.grid(column=0, row=12, columnspan=3, padx=5,
                              sticky='we')
 
diff --git a/Lib/idlelib/rstrip.py b/Lib/idlelib/rstrip.py
deleted file mode 100644 (file)
index f93b5e8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-'Provides "Strip trailing whitespace" under the "Format" menu.'
-
-class Rstrip:
-
-    def __init__(self, editwin):
-        self.editwin = editwin
-
-    def do_rstrip(self, event=None):
-
-        text = self.editwin.text
-        undo = self.editwin.undo
-
-        undo.undo_block_start()
-
-        end_line = int(float(text.index('end')))
-        for cur in range(1, end_line):
-            txt = text.get('%i.0' % cur, '%i.end' % cur)
-            raw = len(txt)
-            cut = len(txt.rstrip())
-            # Since text.delete() marks file as changed, even if not,
-            # only call it when needed to actually delete something.
-            if cut < raw:
-                text.delete('%i.%i' % (cur, cut), '%i.end' % cur)
-
-        undo.undo_block_stop()
-
-if __name__ == "__main__":
-    from unittest import main
-    main('idlelib.idle_test.test_rstrip', verbosity=2,)
index 6b3928b7bf2bc79fb24351ee348edc7562461864..41e0ded44029375eebd70e8f7c9d850d173b4980 100644 (file)
@@ -4,10 +4,12 @@ Simplified, pyshell.ModifiedInterpreter spawns a subprocess with
 f'''{sys.executable} -c "__import__('idlelib.run').run.main()"'''
 '.run' is needed because __import__ returns idlelib, not idlelib.run.
 """
+import functools
 import io
 import linecache
 import queue
 import sys
+import textwrap
 import time
 import traceback
 import _thread as thread
@@ -305,6 +307,67 @@ def fix_scaling(root):
                 font['size'] = round(-0.75*size)
 
 
+def fixdoc(fun, text):
+    tem = (fun.__doc__ + '\n\n') if fun.__doc__ is not None else ''
+    fun.__doc__ = tem + textwrap.fill(textwrap.dedent(text))
+
+RECURSIONLIMIT_DELTA = 30
+
+def install_recursionlimit_wrappers():
+    """Install wrappers to always add 30 to the recursion limit."""
+    # see: bpo-26806
+
+    @functools.wraps(sys.setrecursionlimit)
+    def setrecursionlimit(*args, **kwargs):
+        # mimic the original sys.setrecursionlimit()'s input handling
+        if kwargs:
+            raise TypeError(
+                "setrecursionlimit() takes no keyword arguments")
+        try:
+            limit, = args
+        except ValueError:
+            raise TypeError(f"setrecursionlimit() takes exactly one "
+                            f"argument ({len(args)} given)")
+        if not limit > 0:
+            raise ValueError(
+                "recursion limit must be greater or equal than 1")
+
+        return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA)
+
+    fixdoc(setrecursionlimit, f"""\
+            This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible
+            uninterruptible loops.""")
+
+    @functools.wraps(sys.getrecursionlimit)
+    def getrecursionlimit():
+        return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA
+
+    fixdoc(getrecursionlimit, f"""\
+            This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate
+            for the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit.""")
+
+    # add the delta to the default recursion limit, to compensate
+    sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA)
+
+    sys.setrecursionlimit = setrecursionlimit
+    sys.getrecursionlimit = getrecursionlimit
+
+
+def uninstall_recursionlimit_wrappers():
+    """Uninstall the recursion limit wrappers from the sys module.
+
+    IDLE only uses this for tests. Users can import run and call
+    this to remove the wrapping.
+    """
+    if (
+            getattr(sys.setrecursionlimit, '__wrapped__', None) and
+            getattr(sys.getrecursionlimit, '__wrapped__', None)
+    ):
+        sys.setrecursionlimit = sys.setrecursionlimit.__wrapped__
+        sys.getrecursionlimit = sys.getrecursionlimit.__wrapped__
+        sys.setrecursionlimit(sys.getrecursionlimit() - RECURSIONLIMIT_DELTA)
+
+
 class MyRPCServer(rpc.RPCServer):
 
     def handle_error(self, request, client_address):
@@ -448,6 +511,8 @@ class MyHandler(rpc.RPCHandler):
         # sys.stdin gets changed from within IDLE's shell. See issue17838.
         self._keep_stdin = sys.stdin
 
+        install_recursionlimit_wrappers()
+
         self.interp = self.get_remote_proxy("interp")
         rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
 
index b041e56fb840e1f8fed33a9e0bd952dff957f233..de73bf8458151f7f3ab152fa8359ad5b3097ae80 100644 (file)
@@ -39,6 +39,8 @@ class ScriptBinding:
         # XXX This should be done differently
         self.flist = self.editwin.flist
         self.root = self.editwin.root
+        # cli_args is list of strings that extends sys.argv
+        self.cli_args = []
 
         if macosx.isCocoaTk():
             self.editwin.text_frame.bind('<<run-module-event-2>>', self._run_module_event)
@@ -137,10 +139,11 @@ class ScriptBinding:
             return 'break'
         if customize:
             title = f"Customize {self.editwin.short_title()} Run"
-            run_args = CustomRun(self.shell.text, title).result
+            run_args = CustomRun(self.shell.text, title,
+                                 cli_args=self.cli_args).result
             if not run_args:  # User cancelled.
                 return 'break'
-        cli_args, restart = run_args if customize else ([], True)
+        self.cli_args, restart = run_args if customize else ([], True)
         interp = self.shell.interp
         if pyshell.use_subprocess and restart:
             interp.restart_subprocess(
@@ -148,8 +151,8 @@ class ScriptBinding:
                     self.editwin._filename_to_unicode(filename))
         dirname = os.path.dirname(filename)
         argv = [filename]
-        if cli_args:
-            argv += cli_args
+        if self.cli_args:
+            argv += self.cli_args
         interp.runcommand(f"""if 1:
             __file__ = {filename!r}
             import sys as _sys
@@ -161,7 +164,7 @@ class ScriptBinding:
                 _sys.argv = argv
             import os as _os
             _os.chdir({dirname!r})
-            del _sys, _basename, _os
+            del _sys, argv, _basename, _os
             \n""")
         interp.prepend_syspath(filename)
         # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
diff --git a/Lib/idlelib/sidebar.py b/Lib/idlelib/sidebar.py
new file mode 100644 (file)
index 0000000..41c0968
--- /dev/null
@@ -0,0 +1,341 @@
+"""Line numbering implementation for IDLE as an extension.
+Includes BaseSideBar which can be extended for other sidebar based extensions
+"""
+import functools
+import itertools
+
+import tkinter as tk
+from idlelib.config import idleConf
+from idlelib.delegator import Delegator
+
+
+def get_end_linenumber(text):
+    """Utility to get the last line's number in a Tk text widget."""
+    return int(float(text.index('end-1c')))
+
+
+def get_widget_padding(widget):
+    """Get the total padding of a Tk widget, including its border."""
+    # TODO: use also in codecontext.py
+    manager = widget.winfo_manager()
+    if manager == 'pack':
+        info = widget.pack_info()
+    elif manager == 'grid':
+        info = widget.grid_info()
+    else:
+        raise ValueError(f"Unsupported geometry manager: {manager}")
+
+    # All values are passed through getint(), since some
+    # values may be pixel objects, which can't simply be added to ints.
+    padx = sum(map(widget.tk.getint, [
+        info['padx'],
+        widget.cget('padx'),
+        widget.cget('border'),
+    ]))
+    pady = sum(map(widget.tk.getint, [
+        info['pady'],
+        widget.cget('pady'),
+        widget.cget('border'),
+    ]))
+    return padx, pady
+
+
+class BaseSideBar:
+    """
+    The base class for extensions which require a sidebar.
+    """
+    def __init__(self, editwin):
+        self.editwin = editwin
+        self.parent = editwin.text_frame
+        self.text = editwin.text
+
+        _padx, pady = get_widget_padding(self.text)
+        self.sidebar_text = tk.Text(self.parent, width=1, wrap=tk.NONE,
+                                    padx=2, pady=pady,
+                                    borderwidth=0, highlightthickness=0)
+        self.sidebar_text.config(state=tk.DISABLED)
+        self.text['yscrollcommand'] = self.redirect_yscroll_event
+        self.update_font()
+        self.update_colors()
+
+        self.is_shown = False
+
+    def update_font(self):
+        """Update the sidebar text font, usually after config changes."""
+        font = idleConf.GetFont(self.text, 'main', 'EditorWindow')
+        self._update_font(font)
+
+    def _update_font(self, font):
+        self.sidebar_text['font'] = font
+
+    def update_colors(self):
+        """Update the sidebar text colors, usually after config changes."""
+        colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'normal')
+        self._update_colors(foreground=colors['foreground'],
+                            background=colors['background'])
+
+    def _update_colors(self, foreground, background):
+        self.sidebar_text.config(
+            fg=foreground, bg=background,
+            selectforeground=foreground, selectbackground=background,
+            inactiveselectbackground=background,
+        )
+
+    def show_sidebar(self):
+        if not self.is_shown:
+            self.sidebar_text.grid(row=1, column=0, sticky=tk.NSEW)
+            self.is_shown = True
+
+    def hide_sidebar(self):
+        if self.is_shown:
+            self.sidebar_text.grid_forget()
+            self.is_shown = False
+
+    def redirect_yscroll_event(self, *args, **kwargs):
+        """Redirect vertical scrolling to the main editor text widget.
+
+        The scroll bar is also updated.
+        """
+        self.editwin.vbar.set(*args)
+        self.sidebar_text.yview_moveto(args[0])
+        return 'break'
+
+    def redirect_focusin_event(self, event):
+        """Redirect focus-in events to the main editor text widget."""
+        self.text.focus_set()
+        return 'break'
+
+    def redirect_mousebutton_event(self, event, event_name):
+        """Redirect mouse button events to the main editor text widget."""
+        self.text.focus_set()
+        self.text.event_generate(event_name, x=0, y=event.y)
+        return 'break'
+
+    def redirect_mousewheel_event(self, event):
+        """Redirect mouse wheel events to the editwin text widget."""
+        self.text.event_generate('<MouseWheel>',
+                                 x=0, y=event.y, delta=event.delta)
+        return 'break'
+
+
+class EndLineDelegator(Delegator):
+    """Generate callbacks with the current end line number after
+       insert or delete operations"""
+    def __init__(self, changed_callback):
+        """
+        changed_callback - Callable, will be called after insert
+                           or delete operations with the current
+                           end line number.
+        """
+        Delegator.__init__(self)
+        self.changed_callback = changed_callback
+
+    def insert(self, index, chars, tags=None):
+        self.delegate.insert(index, chars, tags)
+        self.changed_callback(get_end_linenumber(self.delegate))
+
+    def delete(self, index1, index2=None):
+        self.delegate.delete(index1, index2)
+        self.changed_callback(get_end_linenumber(self.delegate))
+
+
+class LineNumbers(BaseSideBar):
+    """Line numbers support for editor windows."""
+    def __init__(self, editwin):
+        BaseSideBar.__init__(self, editwin)
+        self.prev_end = 1
+        self._sidebar_width_type = type(self.sidebar_text['width'])
+        self.sidebar_text.config(state=tk.NORMAL)
+        self.sidebar_text.insert('insert', '1', 'linenumber')
+        self.sidebar_text.config(state=tk.DISABLED)
+        self.sidebar_text.config(takefocus=False, exportselection=False)
+        self.sidebar_text.tag_config('linenumber', justify=tk.RIGHT)
+
+        self.bind_events()
+
+        end = get_end_linenumber(self.text)
+        self.update_sidebar_text(end)
+
+        end_line_delegator = EndLineDelegator(self.update_sidebar_text)
+        # Insert the delegator after the undo delegator, so that line numbers
+        # are properly updated after undo and redo actions.
+        end_line_delegator.setdelegate(self.editwin.undo.delegate)
+        self.editwin.undo.setdelegate(end_line_delegator)
+        # Reset the delegator caches of the delegators "above" the
+        # end line delegator we just inserted.
+        delegator = self.editwin.per.top
+        while delegator is not end_line_delegator:
+            delegator.resetcache()
+            delegator = delegator.delegate
+
+        self.is_shown = False
+
+    def bind_events(self):
+        # Ensure focus is always redirected to the main editor text widget.
+        self.sidebar_text.bind('<FocusIn>', self.redirect_focusin_event)
+
+        # Redirect mouse scrolling to the main editor text widget.
+        #
+        # Note that without this, scrolling with the mouse only scrolls
+        # the line numbers.
+        self.sidebar_text.bind('<MouseWheel>', self.redirect_mousewheel_event)
+
+        # Redirect mouse button events to the main editor text widget,
+        # except for the left mouse button (1).
+        #
+        # Note: X-11 sends Button-4 and Button-5 events for the scroll wheel.
+        def bind_mouse_event(event_name, target_event_name):
+            handler = functools.partial(self.redirect_mousebutton_event,
+                                        event_name=target_event_name)
+            self.sidebar_text.bind(event_name, handler)
+
+        for button in [2, 3, 4, 5]:
+            for event_name in (f'<Button-{button}>',
+                               f'<ButtonRelease-{button}>',
+                               f'<B{button}-Motion>',
+                               ):
+                bind_mouse_event(event_name, target_event_name=event_name)
+
+            # Convert double- and triple-click events to normal click events,
+            # since event_generate() doesn't allow generating such events.
+            for event_name in (f'<Double-Button-{button}>',
+                               f'<Triple-Button-{button}>',
+                               ):
+                bind_mouse_event(event_name,
+                                 target_event_name=f'<Button-{button}>')
+
+        # This is set by b1_mousedown_handler() and read by
+        # drag_update_selection_and_insert_mark(), to know where dragging
+        # began.
+        start_line = None
+        # These are set by b1_motion_handler() and read by selection_handler().
+        # last_y is passed this way since the mouse Y-coordinate is not
+        # available on selection event objects.  last_yview is passed this way
+        # to recognize scrolling while the mouse isn't moving.
+        last_y = last_yview = None
+
+        def b1_mousedown_handler(event):
+            # select the entire line
+            lineno = int(float(self.sidebar_text.index(f"@0,{event.y}")))
+            self.text.tag_remove("sel", "1.0", "end")
+            self.text.tag_add("sel", f"{lineno}.0", f"{lineno+1}.0")
+            self.text.mark_set("insert", f"{lineno+1}.0")
+
+            # remember this line in case this is the beginning of dragging
+            nonlocal start_line
+            start_line = lineno
+        self.sidebar_text.bind('<Button-1>', b1_mousedown_handler)
+
+        def b1_mouseup_handler(event):
+            # On mouse up, we're no longer dragging.  Set the shared persistent
+            # variables to None to represent this.
+            nonlocal start_line
+            nonlocal last_y
+            nonlocal last_yview
+            start_line = None
+            last_y = None
+            last_yview = None
+        self.sidebar_text.bind('<ButtonRelease-1>', b1_mouseup_handler)
+
+        def drag_update_selection_and_insert_mark(y_coord):
+            """Helper function for drag and selection event handlers."""
+            lineno = int(float(self.sidebar_text.index(f"@0,{y_coord}")))
+            a, b = sorted([start_line, lineno])
+            self.text.tag_remove("sel", "1.0", "end")
+            self.text.tag_add("sel", f"{a}.0", f"{b+1}.0")
+            self.text.mark_set("insert",
+                               f"{lineno if lineno == a else lineno + 1}.0")
+
+        # Special handling of dragging with mouse button 1.  In "normal" text
+        # widgets this selects text, but the line numbers text widget has
+        # selection disabled.  Still, dragging triggers some selection-related
+        # functionality under the hood.  Specifically, dragging to above or
+        # below the text widget triggers scrolling, in a way that bypasses the
+        # other scrolling synchronization mechanisms.i
+        def b1_drag_handler(event, *args):
+            nonlocal last_y
+            nonlocal last_yview
+            last_y = event.y
+            last_yview = self.sidebar_text.yview()
+            if not 0 <= last_y <= self.sidebar_text.winfo_height():
+                self.text.yview_moveto(last_yview[0])
+            drag_update_selection_and_insert_mark(event.y)
+        self.sidebar_text.bind('<B1-Motion>', b1_drag_handler)
+
+        # With mouse-drag scrolling fixed by the above, there is still an edge-
+        # case we need to handle: When drag-scrolling, scrolling can continue
+        # while the mouse isn't moving, leading to the above fix not scrolling
+        # properly.
+        def selection_handler(event):
+            if last_yview is None:
+                # This logic is only needed while dragging.
+                return
+            yview = self.sidebar_text.yview()
+            if yview != last_yview:
+                self.text.yview_moveto(yview[0])
+                drag_update_selection_and_insert_mark(last_y)
+        self.sidebar_text.bind('<<Selection>>', selection_handler)
+
+    def update_colors(self):
+        """Update the sidebar text colors, usually after config changes."""
+        colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'linenumber')
+        self._update_colors(foreground=colors['foreground'],
+                            background=colors['background'])
+
+    def update_sidebar_text(self, end):
+        """
+        Perform the following action:
+        Each line sidebar_text contains the linenumber for that line
+        Synchronize with editwin.text so that both sidebar_text and
+        editwin.text contain the same number of lines"""
+        if end == self.prev_end:
+            return
+
+        width_difference = len(str(end)) - len(str(self.prev_end))
+        if width_difference:
+            cur_width = int(float(self.sidebar_text['width']))
+            new_width = cur_width + width_difference
+            self.sidebar_text['width'] = self._sidebar_width_type(new_width)
+
+        self.sidebar_text.config(state=tk.NORMAL)
+        if end > self.prev_end:
+            new_text = '\n'.join(itertools.chain(
+                [''],
+                map(str, range(self.prev_end + 1, end + 1)),
+            ))
+            self.sidebar_text.insert(f'end -1c', new_text, 'linenumber')
+        else:
+            self.sidebar_text.delete(f'{end+1}.0 -1c', 'end -1c')
+        self.sidebar_text.config(state=tk.DISABLED)
+
+        self.prev_end = end
+
+
+def _linenumbers_drag_scrolling(parent):  # htest #
+    from idlelib.idle_test.test_sidebar import Dummy_editwin
+
+    toplevel = tk.Toplevel(parent)
+    text_frame = tk.Frame(toplevel)
+    text_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
+    text_frame.rowconfigure(1, weight=1)
+    text_frame.columnconfigure(1, weight=1)
+
+    font = idleConf.GetFont(toplevel, 'main', 'EditorWindow')
+    text = tk.Text(text_frame, width=80, height=24, wrap=tk.NONE, font=font)
+    text.grid(row=1, column=1, sticky=tk.NSEW)
+
+    editwin = Dummy_editwin(text)
+    editwin.vbar = tk.Scrollbar(text_frame)
+
+    linenumbers = LineNumbers(editwin)
+    linenumbers.show_sidebar()
+
+    text.insert('1.0', '\n'.join('a'*i for i in range(1, 101)))
+
+
+if __name__ == '__main__':
+    from unittest import main
+    main('idlelib.idle_test.test_sidebar', verbosity=2, exit=False)
+
+    from idlelib.idle_test.htest import run
+    run(_linenumbers_drag_scrolling)
index 032401f2abc738cb1ba3525b71682a2154074f5c..be1538a25fdedfc53281985398606dc427c67713 100644 (file)
@@ -15,10 +15,8 @@ output written to the standard error stream ("stderr"), such as exception
 messages and their tracebacks.
 """
 import re
-import weakref
 
 import tkinter as tk
-from tkinter.font import Font
 import tkinter.messagebox as tkMessageBox
 
 from idlelib.config import idleConf
@@ -203,8 +201,6 @@ class Squeezer:
     This avoids IDLE's shell slowing down considerably, and even becoming
     completely unresponsive, when very long outputs are written.
     """
-    _instance_weakref = None
-
     @classmethod
     def reload(cls):
         """Load class variables from config."""
@@ -213,14 +209,6 @@ class Squeezer:
             type="int", default=50,
         )
 
-        # Loading the font info requires a Tk root. IDLE doesn't rely
-        # on Tkinter's "default root", so the instance will reload
-        # font info using its editor windows's Tk root.
-        if cls._instance_weakref is not None:
-            instance = cls._instance_weakref()
-            if instance is not None:
-                instance.load_font()
-
     def __init__(self, editwin):
         """Initialize settings for Squeezer.
 
@@ -241,9 +229,6 @@ class Squeezer:
         # however, needs to make such changes.
         self.base_text = editwin.per.bottom
 
-        Squeezer._instance_weakref = weakref.ref(self)
-        self.load_font()
-
         # Twice the text widget's border width and internal padding;
         # pre-calculated here for the get_line_width() method.
         self.window_width_delta = 2 * (
@@ -298,24 +283,7 @@ class Squeezer:
 
         Tabs are considered tabwidth characters long.
         """
-        linewidth = self.get_line_width()
-        return count_lines_with_wrapping(s, linewidth)
-
-    def get_line_width(self):
-        # The maximum line length in pixels: The width of the text
-        # widget, minus twice the border width and internal padding.
-        linewidth_pixels = \
-            self.base_text.winfo_width() - self.window_width_delta
-
-        # Divide the width of the Text widget by the font width,
-        # which is taken to be the width of '0' (zero).
-        # http://www.tcl.tk/man/tcl8.6/TkCmd/text.htm#M21
-        return linewidth_pixels // self.zero_char_width
-
-    def load_font(self):
-        text = self.base_text
-        self.zero_char_width = \
-            Font(text, font=text.cget('font')).measure('0')
+        return count_lines_with_wrapping(s, self.editwin.width)
 
     def squeeze_current_text_event(self, event):
         """squeeze-current-text event handler
index 4867a80db1abe6da978e62cad9de801627fa8396..808a2aefab4f71a3306413cad3abb024a85900fd 100644 (file)
@@ -2,14 +2,15 @@
 
 """
 from tkinter import Toplevel, Text, TclError,\
-    HORIZONTAL, VERTICAL, N, S, E, W
+    HORIZONTAL, VERTICAL, NS, EW, NSEW, NONE, WORD, SUNKEN
 from tkinter.ttk import Frame, Scrollbar, Button
 from tkinter.messagebox import showerror
 
+from functools import update_wrapper
 from idlelib.colorizer import color_config
 
 
-class AutoHiddenScrollbar(Scrollbar):
+class AutoHideScrollbar(Scrollbar):
     """A scrollbar that is automatically hidden when not needed.
 
     Only the grid geometry manager is supported.
@@ -28,52 +29,70 @@ class AutoHiddenScrollbar(Scrollbar):
         raise TclError(f'{self.__class__.__name__} does not support "place"')
 
 
-class TextFrame(Frame):
-    "Display text with scrollbar."
+class ScrollableTextFrame(Frame):
+    """Display text with scrollbar(s)."""
 
-    def __init__(self, parent, rawtext, wrap='word'):
+    def __init__(self, master, wrap=NONE, **kwargs):
         """Create a frame for Textview.
 
-        parent - parent widget for this frame
-        rawtext - text to display
+        master - master widget for this frame
+        wrap - type of text wrapping to use ('word', 'char' or 'none')
+
+        All parameters except for 'wrap' are passed to Frame.__init__().
+
+        The Text widget is accessible via the 'text' attribute.
+
+        Note: Changing the wrapping mode of the text widget after
+        instantiation is not supported.
         """
-        super().__init__(parent)
-        self['relief'] = 'sunken'
-        self['height'] = 700
+        super().__init__(master, **kwargs)
 
-        self.text = text = Text(self, wrap=wrap, highlightthickness=0)
-        color_config(text)
-        text.grid(row=0, column=0, sticky=N+S+E+W)
+        text = self.text = Text(self, wrap=wrap)
+        text.grid(row=0, column=0, sticky=NSEW)
         self.grid_rowconfigure(0, weight=1)
         self.grid_columnconfigure(0, weight=1)
-        text.insert(0.0, rawtext)
-        text['state'] = 'disabled'
-        text.focus_set()
 
         # vertical scrollbar
-        self.yscroll = yscroll = AutoHiddenScrollbar(self, orient=VERTICAL,
-                                                     takefocus=False,
-                                                     command=text.yview)
-        text['yscrollcommand'] = yscroll.set
-        yscroll.grid(row=0, column=1, sticky=N+S)
-
-        if wrap == 'none':
-            # horizontal scrollbar
-            self.xscroll = xscroll = AutoHiddenScrollbar(self, orient=HORIZONTAL,
-                                                         takefocus=False,
-                                                         command=text.xview)
-            text['xscrollcommand'] = xscroll.set
-            xscroll.grid(row=1, column=0, sticky=E+W)
+        self.yscroll = AutoHideScrollbar(self, orient=VERTICAL,
+                                         takefocus=False,
+                                         command=text.yview)
+        self.yscroll.grid(row=0, column=1, sticky=NS)
+        text['yscrollcommand'] = self.yscroll.set
+
+        # horizontal scrollbar - only when wrap is set to NONE
+        if wrap == NONE:
+            self.xscroll = AutoHideScrollbar(self, orient=HORIZONTAL,
+                                             takefocus=False,
+                                             command=text.xview)
+            self.xscroll.grid(row=1, column=0, sticky=EW)
+            text['xscrollcommand'] = self.xscroll.set
+        else:
+            self.xscroll = None
 
 
 class ViewFrame(Frame):
     "Display TextFrame and Close button."
-    def __init__(self, parent, text, wrap='word'):
+    def __init__(self, parent, contents, wrap='word'):
+        """Create a frame for viewing text with a "Close" button.
+
+        parent - parent widget for this frame
+        contents - text to display
+        wrap - type of text wrapping to use ('word', 'char' or 'none')
+
+        The Text widget is accessible via the 'text' attribute.
+        """
         super().__init__(parent)
         self.parent = parent
         self.bind('<Return>', self.ok)
         self.bind('<Escape>', self.ok)
-        self.textframe = TextFrame(self, text, wrap=wrap)
+        self.textframe = ScrollableTextFrame(self, relief=SUNKEN, height=700)
+
+        text = self.text = self.textframe.text
+        text.insert('1.0', contents)
+        text.configure(wrap=wrap, highlightthickness=0, state='disabled')
+        color_config(text)
+        text.focus_set()
+
         self.button_ok = button_ok = Button(
                 self, text='Close', command=self.ok, takefocus=False)
         self.textframe.pack(side='top', expand=True, fill='both')
@@ -87,7 +106,7 @@ class ViewFrame(Frame):
 class ViewWindow(Toplevel):
     "A simple text viewer dialog for IDLE."
 
-    def __init__(self, parent, title, text, modal=True, wrap='word',
+    def __init__(self, parent, title, contents, modal=True, wrap=WORD,
                  *, _htest=False, _utest=False):
         """Show the given text in a scrollable window with a 'close' button.
 
@@ -96,7 +115,7 @@ class ViewWindow(Toplevel):
 
         parent - parent of this dialog
         title - string which is title of popup dialog
-        text - text to display in dialog
+        contents - text to display in dialog
         wrap - type of text wrapping to use ('word', 'char' or 'none')
         _htest - bool; change box location when running htest.
         _utest - bool; don't wait_window when running unittest.
@@ -109,7 +128,7 @@ class ViewWindow(Toplevel):
         self.geometry(f'=750x500+{x}+{y}')
 
         self.title(title)
-        self.viewframe = ViewFrame(self, text, wrap=wrap)
+        self.viewframe = ViewFrame(self, contents, wrap=wrap)
         self.protocol("WM_DELETE_WINDOW", self.ok)
         self.button_ok = button_ok = Button(self, text='Close',
                                             command=self.ok, takefocus=False)
@@ -129,18 +148,18 @@ class ViewWindow(Toplevel):
         self.destroy()
 
 
-def view_text(parent, title, text, modal=True, wrap='word', _utest=False):
+def view_text(parent, title, contents, modal=True, wrap='word', _utest=False):
     """Create text viewer for given text.
 
     parent - parent of this dialog
     title - string which is the title of popup dialog
-    text - text to display in this dialog
+    contents - text to display in this dialog
     wrap - type of text wrapping to use ('word', 'char' or 'none')
     modal - controls if users can interact with other windows while this
             dialog is displayed
     _utest - bool; controls wait_window on unittest
     """
-    return ViewWindow(parent, title, text, modal, wrap=wrap, _utest=_utest)
+    return ViewWindow(parent, title, contents, modal, wrap=wrap, _utest=_utest)
 
 
 def view_file(parent, title, filename, encoding, modal=True, wrap='word',
index f54ea36f059d6fa305610dad96bd8447c8cbb5e2..69658264dbd4a485051d25cf7762e50098b01b3f 100644 (file)
@@ -75,7 +75,7 @@ class TooltipBase(object):
         if tw:
             try:
                 tw.destroy()
-            except TclError:
+            except TclError:  # pragma: no cover
                 pass
 
 
@@ -103,8 +103,8 @@ class OnHoverTooltipBase(TooltipBase):
     def __del__(self):
         try:
             self.anchor_widget.unbind("<Enter>", self._id1)
-            self.anchor_widget.unbind("<Leave>", self._id2)
-            self.anchor_widget.unbind("<Button>", self._id3)
+            self.anchor_widget.unbind("<Leave>", self._id2)  # pragma: no cover
+            self.anchor_widget.unbind("<Button>", self._id3) # pragma: no cover
         except TclError:
             pass
         super(OnHoverTooltipBase, self).__del__()
@@ -137,7 +137,7 @@ class OnHoverTooltipBase(TooltipBase):
         """hide the tooltip"""
         try:
             self.unschedule()
-        except TclError:
+        except TclError:  # pragma: no cover
             pass
         super(OnHoverTooltipBase, self).hidetip()
 
index 21426cbb33e0da063915005e668f1d878d47b304..6229be4e5a8ad5cae0ce2fa0a11d114eb1e1bb90 100644 (file)
@@ -56,6 +56,30 @@ def listicons(icondir=ICONDIR):
             column = 0
     root.images = images
 
+def wheel_event(event, widget=None):
+    """Handle scrollwheel event.
+
+    For wheel up, event.delta = 120*n on Windows, -1*n on darwin,
+    where n can be > 1 if one scrolls fast.  Flicking the wheel
+    generates up to maybe 20 events with n up to 10 or more 1.
+    Macs use wheel down (delta = 1*n) to scroll up, so positive
+    delta means to scroll up on both systems.
+
+    X-11 sends Control-Button-4,5 events instead.
+
+    The widget parameter is needed so browser label bindings can pass
+    the underlying canvas.
+
+    This function depends on widget.yview to not be overridden by
+    a subclass.
+    """
+    up = {EventType.MouseWheel: event.delta > 0,
+          EventType.ButtonPress: event.num == 4}
+    lines = -5 if up[event.type] else 5
+    widget = event.widget if widget is None else widget
+    widget.yview(SCROLL, lines, 'units')
+    return 'break'
+
 
 class TreeNode:
 
@@ -260,6 +284,9 @@ class TreeNode:
                                        anchor="nw", window=self.label)
         self.label.bind("<1>", self.select_or_edit)
         self.label.bind("<Double-1>", self.flip)
+        self.label.bind("<MouseWheel>", lambda e: wheel_event(e, self.canvas))
+        self.label.bind("<Button-4>", lambda e: wheel_event(e, self.canvas))
+        self.label.bind("<Button-5>", lambda e: wheel_event(e, self.canvas))
         self.text_id = id
 
     def select_or_edit(self, event=None):
@@ -410,6 +437,7 @@ class FileTreeItem(TreeItem):
 # A canvas widget with scroll bars and some useful bindings
 
 class ScrolledCanvas:
+
     def __init__(self, master, **opts):
         if 'yscrollincrement' not in opts:
             opts['yscrollincrement'] = 17
@@ -431,6 +459,9 @@ class ScrolledCanvas:
         self.canvas.bind("<Key-Next>", self.page_down)
         self.canvas.bind("<Key-Up>", self.unit_up)
         self.canvas.bind("<Key-Down>", self.unit_down)
+        self.canvas.bind("<MouseWheel>", wheel_event)
+        self.canvas.bind("<Button-4>", wheel_event)
+        self.canvas.bind("<Button-5>", wheel_event)
         #if isinstance(master, Toplevel) or isinstance(master, Tk):
         self.canvas.bind("<Alt-Key-2>", self.zoom_height)
         self.canvas.focus_set()
index 53b24ff1b0f223902cd48bc2c9ef55d135183240..66a16a68396266d0458e3f55ca5044f7465e7aed 100644 (file)
@@ -246,7 +246,7 @@ _code_type = type(_write_atomic.__code__)
 #     Python 3.7a2  3391 (update GET_AITER #31709)
 #     Python 3.7a4  3392 (PEP 552: Deterministic pycs #31650)
 #     Python 3.7b1  3393 (remove STORE_ANNOTATION opcode #32550)
-#     Python 3.7b5  3394 (restored docstring as the firts stmt in the body;
+#     Python 3.7b5  3394 (restored docstring as the first stmt in the body;
 #                         this might affected the first line number #32911)
 #
 # MAGIC must change whenever the bytecode emitted by the compiler may no
index 4d4f33dcc57b5edad4fab44f33524be455c32078..bbecd98f94abdce75603d03299b1bf4cd247f2eb 100644 (file)
@@ -2358,7 +2358,7 @@ def _signature_from_callable(obj, *,
                 if (obj.__init__ is object.__init__ and
                     obj.__new__ is object.__new__):
                     # Return a signature of 'object' builtin.
-                    return signature(object)
+                    return sigcls.from_callable(object)
                 else:
                     raise ValueError(
                         'no signature found for builtin type {!r}'.format(obj))
@@ -3108,7 +3108,7 @@ def _main():
                                                     type(exc).__name__,
                                                     exc)
         print(msg, file=sys.stderr)
-        exit(2)
+        sys.exit(2)
 
     if has_attrs:
         parts = attrs.split(".")
@@ -3118,7 +3118,7 @@ def _main():
 
     if module.__name__ in sys.builtin_module_names:
         print("Can't get info for builtin modules.", file=sys.stderr)
-        exit(1)
+        sys.exit(1)
 
     if args.details:
         print('Target: {}'.format(target))
index 4eec1f337c13379050aefc107398439e76ef50f8..80249288d73ab11ddcfe6d18508afe879d8b9440 100644 (file)
@@ -532,6 +532,30 @@ class _IPAddressBase:
         except ValueError:
             cls._report_invalid_netmask(ip_str)
 
+    @classmethod
+    def _split_addr_prefix(cls, address):
+        """Helper function to parse address of Network/Interface.
+
+        Arg:
+            address: Argument of Network/Interface.
+
+        Returns:
+            (addr, prefix) tuple.
+        """
+        # a packed address or integer
+        if isinstance(address, (bytes, int)):
+            return address, cls._max_prefixlen
+
+        if not isinstance(address, tuple):
+            # Assume input argument to be string or any object representation
+            # which converts into a formatted IP prefix string.
+            address = _split_optional_netmask(address)
+
+        # Constructing from a tuple (addr, [mask])
+        if len(address) > 1:
+            return address
+        return address[0], cls._max_prefixlen
+
     def __reduce__(self):
         return self.__class__, (str(self),)
 
@@ -1381,32 +1405,13 @@ class IPv4Address(_BaseV4, _BaseAddress):
 class IPv4Interface(IPv4Address):
 
     def __init__(self, address):
-        if isinstance(address, (bytes, int)):
-            IPv4Address.__init__(self, address)
-            self.network = IPv4Network(self._ip)
-            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])
-
-        self.network = IPv4Network(address, strict=False)
-        self._prefixlen = self.network._prefixlen
+        addr, mask = self._split_addr_prefix(address)
 
+        IPv4Address.__init__(self, addr)
+        self.network = IPv4Network((addr, mask), strict=False)
         self.netmask = self.network.netmask
         self.hostmask = self.network.hostmask
+        self._prefixlen = self.network._prefixlen
 
     def __str__(self):
         return '%s/%d' % (self._string_from_ip_int(self._ip),
@@ -1511,24 +1516,9 @@ class IPv4Network(_BaseV4, _BaseNetwork):
               an IPv4 address.
             ValueError: If strict is True and a network address is not
               supplied.
-
         """
         _BaseNetwork.__init__(self, address)
-
-        # Constructing from a packed address or integer
-        if isinstance(address, (int, bytes)):
-            addr = address
-            mask = self._max_prefixlen
-        # Constructing from a tuple (addr, [mask])
-        elif isinstance(address, tuple):
-            addr = address[0]
-            mask = address[1] if len(address) > 1 else self._max_prefixlen
-        # Assume input argument to be string or any object representation
-        # which converts into a formatted IP prefix string.
-        else:
-            args = _split_optional_netmask(address)
-            addr = self._ip_int_from_string(args[0])
-            mask = args[1] if len(args) == 2 else self._max_prefixlen
+        addr, mask = self._split_addr_prefix(address)
 
         self.network_address = IPv4Address(addr)
         self.netmask, self._prefixlen = self._make_netmask(mask)
@@ -2061,28 +2051,13 @@ class IPv6Address(_BaseV6, _BaseAddress):
 class IPv6Interface(IPv6Address):
 
     def __init__(self, address):
-        if isinstance(address, (bytes, int)):
-            IPv6Address.__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, mask = self._split_addr_prefix(address)
 
-        addr = _split_optional_netmask(address)
-        IPv6Address.__init__(self, addr[0])
-        self.network = IPv6Network(address, strict=False)
+        IPv6Address.__init__(self, addr)
+        self.network = IPv6Network((addr, mask), strict=False)
         self.netmask = self.network.netmask
-        self._prefixlen = self.network._prefixlen
         self.hostmask = self.network.hostmask
+        self._prefixlen = self.network._prefixlen
 
     def __str__(self):
         return '%s/%d' % (self._string_from_ip_int(self._ip),
@@ -2191,24 +2166,9 @@ class IPv6Network(_BaseV6, _BaseNetwork):
               an IPv6 address.
             ValueError: If strict was True and a network address was not
               supplied.
-
         """
         _BaseNetwork.__init__(self, address)
-
-        # Constructing from a packed address or integer
-        if isinstance(address, (int, bytes)):
-            addr = address
-            mask = self._max_prefixlen
-        # Constructing from a tuple (addr, [mask])
-        elif isinstance(address, tuple):
-            addr = address[0]
-            mask = address[1] if len(address) > 1 else self._max_prefixlen
-        # Assume input argument to be string or any object representation
-        # which converts into a formatted IP prefix string.
-        else:
-            args = _split_optional_netmask(address)
-            addr = self._ip_int_from_string(args[0])
-            mask = args[1] if len(args) == 2 else self._max_prefixlen
+        addr, mask = self._split_addr_prefix(address)
 
         self.network_address = IPv6Address(addr)
         self.netmask, self._prefixlen = self._make_netmask(mask)
index 7841b99a5cd4c1ee7dcc48b405a1c8edb4340739..55fd60fa27c3da9ba0eed4fff1c472aac62e5d9d 100644 (file)
@@ -14,6 +14,7 @@ __author__ = "Guido van Rossum <guido@python.org>"
 # Python imports
 import io
 import os
+import pkgutil
 import sys
 import logging
 import operator
@@ -30,13 +31,12 @@ from . import btm_matcher as bm
 def get_all_fix_names(fixer_pkg, remove_prefix=True):
     """Return a sorted list of all available fix names in the given package."""
     pkg = __import__(fixer_pkg, [], [], ["*"])
-    fixer_dir = os.path.dirname(pkg.__file__)
     fix_names = []
-    for name in sorted(os.listdir(fixer_dir)):
-        if name.startswith("fix_") and name.endswith(".py"):
+    for finder, name, ispkg in pkgutil.iter_modules(pkg.__path__):
+        if name.startswith("fix_"):
             if remove_prefix:
                 name = name[4:]
-            fix_names.append(name[:-3])
+            fix_names.append(name)
     return fix_names
 
 
index f3d3973d038c5188973e9a7cb7c9e5b295a6367f..dd8a08524a018e8ff34f10a8d96b6cbbc171b063 100644 (file)
@@ -492,6 +492,10 @@ def _parse_localename(localename):
         return tuple(code.split('.')[:2])
     elif code == 'C':
         return None, None
+    elif code == 'UTF-8':
+        # On macOS "LC_CTYPE=UTF-8" is a valid locale setting
+        # for getting UTF-8 handling for text.
+        return None, 'UTF-8'
     raise ValueError('unknown locale: %s' % localename)
 
 def _build_localename(localetuple):
index fa1a398aee2a2b1d5385e5aed78adf032e6aa5c5..f58be930893590bdf0eb904a64d7c925e90f7861 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2019 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,7 +19,7 @@ Configuration functions for the logging package for Python. The core package
 is based on PEP 282 and comments thereto in comp.lang.python, and influenced
 by Apache's log4j system.
 
-Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved.
 
 To use, simply 'import logging' and log away!
 """
@@ -173,9 +173,10 @@ def _handle_existing_loggers(existing, child_loggers, disable_existing):
     for log in existing:
         logger = root.manager.loggerDict[log]
         if log in child_loggers:
-            logger.level = logging.NOTSET
-            logger.handlers = []
-            logger.propagate = True
+            if not isinstance(logger, logging.PlaceHolder):
+                logger.setLevel(logging.NOTSET)
+                logger.handlers = []
+                logger.propagate = True
         else:
             logger.disabled = disable_existing
 
index 1206d8e9b6a8346f827cee3d95bb6cfd55107913..bcf522835f4c954b33357b4c0c152beadfd1b7ac 100644 (file)
@@ -66,13 +66,13 @@ class MimeTypes:
     def __init__(self, filenames=(), strict=True):
         if not inited:
             init()
-        self.encodings_map = encodings_map.copy()
-        self.suffix_map = suffix_map.copy()
+        self.encodings_map = _encodings_map_default.copy()
+        self.suffix_map = _suffix_map_default.copy()
         self.types_map = ({}, {}) # dict for (non-strict, strict)
         self.types_map_inv = ({}, {})
-        for (ext, type) in types_map.items():
+        for (ext, type) in _types_map_default.items():
             self.add_type(type, ext, True)
-        for (ext, type) in common_types.items():
+        for (ext, type) in _common_types_default.items():
             self.add_type(type, ext, False)
         for name in filenames:
             self.read(name, strict)
@@ -113,6 +113,7 @@ class MimeTypes:
         Optional `strict' argument when False adds a bunch of commonly found,
         but non-standard types.
         """
+        url = os.fspath(url)
         scheme, url = urllib.parse.splittype(url)
         if scheme == 'data':
             # syntax of data URLs:
@@ -345,11 +346,19 @@ def init(files=None):
     global suffix_map, types_map, encodings_map, common_types
     global inited, _db
     inited = True    # so that MimeTypes.__init__() doesn't call us again
-    db = MimeTypes()
-    if files is None:
+
+    if files is None or _db is None:
+        db = MimeTypes()
         if _winreg:
             db.read_windows_registry()
-        files = knownfiles
+
+        if files is None:
+            files = knownfiles
+        else:
+            files = knownfiles + list(files)
+    else:
+        db = _db
+
     for file in files:
         if os.path.isfile(file):
             db.read(file)
@@ -373,12 +382,12 @@ def read_mime_types(file):
 
 
 def _default_mime_types():
-    global suffix_map
-    global encodings_map
-    global types_map
-    global common_types
+    global suffix_map, _suffix_map_default
+    global encodings_map, _encodings_map_default
+    global types_map, _types_map_default
+    global common_types, _common_types_default
 
-    suffix_map = {
+    suffix_map = _suffix_map_default = {
         '.svgz': '.svg.gz',
         '.tgz': '.tar.gz',
         '.taz': '.tar.gz',
@@ -387,7 +396,7 @@ def _default_mime_types():
         '.txz': '.tar.xz',
         }
 
-    encodings_map = {
+    encodings_map = _encodings_map_default = {
         '.gz': 'gzip',
         '.Z': 'compress',
         '.bz2': 'bzip2',
@@ -398,151 +407,155 @@ def _default_mime_types():
     # at http://www.iana.org/assignments/media-types
     # or extensions, i.e. using the x- prefix
 
-    # If you add to these, please keep them sorted!
-    types_map = {
+    # If you add to these, please keep them sorted by mime type.
+    # Make sure the entry with the preferred file extension for a particular mime type
+    # appears before any others of the same mimetype.
+    types_map = _types_map_default = {
+        '.js'     : 'application/javascript',
+        '.mjs'    : 'application/javascript',
+        '.json'   : 'application/json',
+        '.doc'    : 'application/msword',
+        '.dot'    : 'application/msword',
+        '.wiz'    : 'application/msword',
+        '.bin'    : 'application/octet-stream',
         '.a'      : 'application/octet-stream',
+        '.dll'    : 'application/octet-stream',
+        '.exe'    : 'application/octet-stream',
+        '.o'      : 'application/octet-stream',
+        '.obj'    : 'application/octet-stream',
+        '.so'     : 'application/octet-stream',
+        '.oda'    : 'application/oda',
+        '.pdf'    : 'application/pdf',
+        '.p7c'    : 'application/pkcs7-mime',
+        '.ps'     : 'application/postscript',
         '.ai'     : 'application/postscript',
-        '.aif'    : 'audio/x-aiff',
-        '.aifc'   : 'audio/x-aiff',
-        '.aiff'   : 'audio/x-aiff',
-        '.au'     : 'audio/basic',
-        '.avi'    : 'video/x-msvideo',
-        '.bat'    : 'text/plain',
+        '.eps'    : 'application/postscript',
+        '.m3u'    : 'application/vnd.apple.mpegurl',
+        '.m3u8'   : 'application/vnd.apple.mpegurl',
+        '.xls'    : 'application/vnd.ms-excel',
+        '.xlb'    : 'application/vnd.ms-excel',
+        '.ppt'    : 'application/vnd.ms-powerpoint',
+        '.pot'    : 'application/vnd.ms-powerpoint',
+        '.ppa'    : 'application/vnd.ms-powerpoint',
+        '.pps'    : 'application/vnd.ms-powerpoint',
+        '.pwz'    : 'application/vnd.ms-powerpoint',
+        '.wasm'   : 'application/wasm',
         '.bcpio'  : 'application/x-bcpio',
-        '.bin'    : 'application/octet-stream',
-        '.bmp'    : 'image/bmp',
-        '.c'      : 'text/plain',
-        '.cdf'    : 'application/x-netcdf',
         '.cpio'   : 'application/x-cpio',
         '.csh'    : 'application/x-csh',
-        '.css'    : 'text/css',
-        '.csv'    : 'text/csv',
-        '.dll'    : 'application/octet-stream',
-        '.doc'    : 'application/msword',
-        '.dot'    : 'application/msword',
         '.dvi'    : 'application/x-dvi',
-        '.eml'    : 'message/rfc822',
-        '.eps'    : 'application/postscript',
-        '.etx'    : 'text/x-setext',
-        '.exe'    : 'application/octet-stream',
-        '.gif'    : 'image/gif',
         '.gtar'   : 'application/x-gtar',
-        '.h'      : 'text/plain',
         '.hdf'    : 'application/x-hdf',
-        '.htm'    : 'text/html',
-        '.html'   : 'text/html',
-        '.ico'    : 'image/vnd.microsoft.icon',
-        '.ief'    : 'image/ief',
-        '.jpe'    : 'image/jpeg',
-        '.jpeg'   : 'image/jpeg',
-        '.jpg'    : 'image/jpeg',
-        '.js'     : 'application/javascript',
-        '.json'   : 'application/json',
-        '.ksh'    : 'text/plain',
         '.latex'  : 'application/x-latex',
-        '.m1v'    : 'video/mpeg',
-        '.m3u'    : 'application/vnd.apple.mpegurl',
-        '.m3u8'   : 'application/vnd.apple.mpegurl',
-        '.man'    : 'application/x-troff-man',
-        '.me'     : 'application/x-troff-me',
-        '.mht'    : 'message/rfc822',
-        '.mhtml'  : 'message/rfc822',
         '.mif'    : 'application/x-mif',
-        '.mjs'    : 'application/javascript',
-        '.mov'    : 'video/quicktime',
-        '.movie'  : 'video/x-sgi-movie',
-        '.mp2'    : 'audio/mpeg',
-        '.mp3'    : 'audio/mpeg',
-        '.mp4'    : 'video/mp4',
-        '.mpa'    : 'video/mpeg',
-        '.mpe'    : 'video/mpeg',
-        '.mpeg'   : 'video/mpeg',
-        '.mpg'    : 'video/mpeg',
-        '.ms'     : 'application/x-troff-ms',
+        '.cdf'    : 'application/x-netcdf',
         '.nc'     : 'application/x-netcdf',
-        '.nws'    : 'message/rfc822',
-        '.o'      : 'application/octet-stream',
-        '.obj'    : 'application/octet-stream',
-        '.oda'    : 'application/oda',
         '.p12'    : 'application/x-pkcs12',
-        '.p7c'    : 'application/pkcs7-mime',
-        '.pbm'    : 'image/x-portable-bitmap',
-        '.pdf'    : 'application/pdf',
         '.pfx'    : 'application/x-pkcs12',
-        '.pgm'    : 'image/x-portable-graymap',
-        '.pl'     : 'text/plain',
-        '.png'    : 'image/png',
-        '.pnm'    : 'image/x-portable-anymap',
-        '.pot'    : 'application/vnd.ms-powerpoint',
-        '.ppa'    : 'application/vnd.ms-powerpoint',
-        '.ppm'    : 'image/x-portable-pixmap',
-        '.pps'    : 'application/vnd.ms-powerpoint',
-        '.ppt'    : 'application/vnd.ms-powerpoint',
-        '.ps'     : 'application/postscript',
-        '.pwz'    : 'application/vnd.ms-powerpoint',
-        '.py'     : 'text/x-python',
+        '.ram'    : 'application/x-pn-realaudio',
         '.pyc'    : 'application/x-python-code',
         '.pyo'    : 'application/x-python-code',
-        '.qt'     : 'video/quicktime',
-        '.ra'     : 'audio/x-pn-realaudio',
-        '.ram'    : 'application/x-pn-realaudio',
-        '.ras'    : 'image/x-cmu-raster',
-        '.rdf'    : 'application/xml',
-        '.rgb'    : 'image/x-rgb',
-        '.roff'   : 'application/x-troff',
-        '.rtx'    : 'text/richtext',
-        '.sgm'    : 'text/x-sgml',
-        '.sgml'   : 'text/x-sgml',
         '.sh'     : 'application/x-sh',
         '.shar'   : 'application/x-shar',
-        '.snd'    : 'audio/basic',
-        '.so'     : 'application/octet-stream',
-        '.src'    : 'application/x-wais-source',
+        '.swf'    : 'application/x-shockwave-flash',
         '.sv4cpio': 'application/x-sv4cpio',
         '.sv4crc' : 'application/x-sv4crc',
-        '.svg'    : 'image/svg+xml',
-        '.swf'    : 'application/x-shockwave-flash',
-        '.t'      : 'application/x-troff',
         '.tar'    : 'application/x-tar',
         '.tcl'    : 'application/x-tcl',
         '.tex'    : 'application/x-tex',
         '.texi'   : 'application/x-texinfo',
         '.texinfo': 'application/x-texinfo',
-        '.tif'    : 'image/tiff',
-        '.tiff'   : 'image/tiff',
+        '.roff'   : 'application/x-troff',
+        '.t'      : 'application/x-troff',
         '.tr'     : 'application/x-troff',
-        '.tsv'    : 'text/tab-separated-values',
-        '.txt'    : 'text/plain',
+        '.man'    : 'application/x-troff-man',
+        '.me'     : 'application/x-troff-me',
+        '.ms'     : 'application/x-troff-ms',
         '.ustar'  : 'application/x-ustar',
-        '.vcf'    : 'text/x-vcard',
-        '.wav'    : 'audio/x-wav',
-        '.webm'   : 'video/webm',
-        '.wiz'    : 'application/msword',
+        '.src'    : 'application/x-wais-source',
+        '.xsl'    : 'application/xml',
+        '.rdf'    : 'application/xml',
         '.wsdl'   : 'application/xml',
-        '.xbm'    : 'image/x-xbitmap',
-        '.xlb'    : 'application/vnd.ms-excel',
-        '.xls'    : 'application/vnd.ms-excel',
-        '.xml'    : 'text/xml',
         '.xpdl'   : 'application/xml',
+        '.zip'    : 'application/zip',
+        '.au'     : 'audio/basic',
+        '.snd'    : 'audio/basic',
+        '.mp3'    : 'audio/mpeg',
+        '.mp2'    : 'audio/mpeg',
+        '.aif'    : 'audio/x-aiff',
+        '.aifc'   : 'audio/x-aiff',
+        '.aiff'   : 'audio/x-aiff',
+        '.ra'     : 'audio/x-pn-realaudio',
+        '.wav'    : 'audio/x-wav',
+        '.bmp'    : 'image/bmp',
+        '.gif'    : 'image/gif',
+        '.ief'    : 'image/ief',
+        '.jpg'    : 'image/jpeg',
+        '.jpe'    : 'image/jpeg',
+        '.jpeg'   : 'image/jpeg',
+        '.png'    : 'image/png',
+        '.svg'    : 'image/svg+xml',
+        '.tiff'   : 'image/tiff',
+        '.tif'    : 'image/tiff',
+        '.ico'    : 'image/vnd.microsoft.icon',
+        '.ras'    : 'image/x-cmu-raster',
+        '.bmp'    : 'image/x-ms-bmp',
+        '.pnm'    : 'image/x-portable-anymap',
+        '.pbm'    : 'image/x-portable-bitmap',
+        '.pgm'    : 'image/x-portable-graymap',
+        '.ppm'    : 'image/x-portable-pixmap',
+        '.rgb'    : 'image/x-rgb',
+        '.xbm'    : 'image/x-xbitmap',
         '.xpm'    : 'image/x-xpixmap',
-        '.xsl'    : 'application/xml',
         '.xwd'    : 'image/x-xwindowdump',
-        '.zip'    : 'application/zip',
+        '.eml'    : 'message/rfc822',
+        '.mht'    : 'message/rfc822',
+        '.mhtml'  : 'message/rfc822',
+        '.nws'    : 'message/rfc822',
+        '.css'    : 'text/css',
+        '.csv'    : 'text/csv',
+        '.html'   : 'text/html',
+        '.htm'    : 'text/html',
+        '.txt'    : 'text/plain',
+        '.bat'    : 'text/plain',
+        '.c'      : 'text/plain',
+        '.h'      : 'text/plain',
+        '.ksh'    : 'text/plain',
+        '.pl'     : 'text/plain',
+        '.rtx'    : 'text/richtext',
+        '.tsv'    : 'text/tab-separated-values',
+        '.py'     : 'text/x-python',
+        '.etx'    : 'text/x-setext',
+        '.sgm'    : 'text/x-sgml',
+        '.sgml'   : 'text/x-sgml',
+        '.vcf'    : 'text/x-vcard',
+        '.xml'    : 'text/xml',
+        '.mp4'    : 'video/mp4',
+        '.mpeg'   : 'video/mpeg',
+        '.m1v'    : 'video/mpeg',
+        '.mpa'    : 'video/mpeg',
+        '.mpe'    : 'video/mpeg',
+        '.mpg'    : 'video/mpeg',
+        '.mov'    : 'video/quicktime',
+        '.qt'     : 'video/quicktime',
+        '.webm'   : 'video/webm',
+        '.avi'    : 'video/x-msvideo',
+        '.movie'  : 'video/x-sgi-movie',
         }
 
     # These are non-standard types, commonly found in the wild.  They will
     # only match if strict=0 flag is given to the API methods.
 
     # Please sort these too
-    common_types = {
-        '.jpg' : 'image/jpg',
-        '.mid' : 'audio/midi',
+    common_types = _common_types_default = {
+        '.rtf' : 'application/rtf',
         '.midi': 'audio/midi',
+        '.mid' : 'audio/midi',
+        '.jpg' : 'image/jpg',
+        '.pict': 'image/pict',
         '.pct' : 'image/pict',
         '.pic' : 'image/pict',
-        '.pict': 'image/pict',
-        '.rtf' : 'application/rtf',
-        '.xul' : 'text/xul'
+        '.xul' : 'text/xul',
         }
 
 
index 0c4eb2473273b4028967b15e571717422cb224f5..0f9eac7e9fb4dcd2bbaf8f50c9e70abbef2e1e05 100644 (file)
@@ -106,6 +106,15 @@ def log_to_stderr(level=None):
 # Function returning a temp directory which will be removed on exit
 #
 
+def _remove_temp_dir(rmtree, tempdir):
+    rmtree(tempdir)
+
+    current_process = process.current_process()
+    # current_process() can be None if the finalizer is called
+    # late during Python finalization
+    if current_process is not None:
+        current_process._config['tempdir'] = None
+
 def get_temp_dir():
     # get name of a temp directory which will be automatically cleaned up
     tempdir = process.current_process()._config.get('tempdir')
@@ -113,7 +122,10 @@ def get_temp_dir():
         import shutil, tempfile
         tempdir = tempfile.mkdtemp(prefix='pymp-')
         info('created temp directory %s', tempdir)
-        Finalize(None, shutil.rmtree, args=[tempdir], exitpriority=-100)
+        # keep a strong reference to shutil.rmtree(), since the finalizer
+        # can be called late during Python shutdown
+        Finalize(None, _remove_temp_dir, args=(shutil.rmtree, tempdir),
+                 exitpriority=-100)
         process.current_process()._config['tempdir'] = tempdir
     return tempdir
 
index 499e6285618f212801d3690311badc739b824070..b93f95d98ede1cd8a57da3676ed4a77a8c9db6de 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -300,10 +300,11 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
     (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. No matter
-    the value of topdown, the list of subdirectories is retrieved before the
-    tuples for the directory and its subdirectories are generated.
+    topdown is false has no effect on the behavior of os.walk(), 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
@@ -574,7 +575,7 @@ def execvpe(file, args, env):
     """execvpe(file, args, env)
 
     Execute the executable file (which is searched for along $PATH)
-    with argument list args and environment env , replacing the
+    with argument list args and environment env, replacing the
     current process.
     args may be a list or tuple of strings. """
     _execvpe(file, args, env)
index 59b23dfc8beaba13638db8304e3befcc1a396dd5..806bc6741f2b2379980a707d3fbb9e3e52032624 100755 (executable)
@@ -159,16 +159,14 @@ class Pdb(bdb.Bdb, cmd.Cmd):
         self.allow_kbdint = False
         self.nosigint = nosigint
 
-        # Read $HOME/.pdbrc and ./.pdbrc
+        # Read ~/.pdbrc and ./.pdbrc
         self.rcLines = []
         if readrc:
-            if 'HOME' in os.environ:
-                envHome = os.environ['HOME']
-                try:
-                    with open(os.path.join(envHome, ".pdbrc")) as rcFile:
-                        self.rcLines.extend(rcFile)
-                except OSError:
-                    pass
+            try:
+                with open(os.path.expanduser('~/.pdbrc')) as rcFile:
+                    self.rcLines.extend(rcFile)
+            except OSError:
+                pass
             try:
                 with open(".pdbrc") as rcFile:
                     self.rcLines.extend(rcFile)
@@ -1659,7 +1657,7 @@ To let the script run up to a given line X in the debugged file, use
 def main():
     import getopt
 
-    opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['--help', '--command='])
+    opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['help', 'command='])
 
     if not args:
         print(_usage)
index 21ebec3f00459076d008e2c8c1f4959e413d72b5..33b79a133b0a84c91366a28a48685cfbe92ff818 100644 (file)
@@ -929,7 +929,7 @@ _FORMATS={
 
 
 def load(fp, *, fmt=None, use_builtin_types=True, dict_type=dict):
-    """Read a .plist file. 'fp' should be (readable) file object.
+    """Read a .plist file. 'fp' should be a readable and binary file object.
     Return the unpacked root object (which usually is a dictionary).
     """
     if fmt is None:
@@ -960,8 +960,8 @@ def loads(value, *, fmt=None, use_builtin_types=True, dict_type=dict):
 
 
 def dump(value, fp, *, fmt=FMT_XML, sort_keys=True, skipkeys=False):
-    """Write 'value' to a .plist file. 'fp' should be a (writable)
-    file object.
+    """Write 'value' to a .plist file. 'fp' should be a writable,
+    binary file object.
     """
     if fmt not in _FORMATS:
         raise ValueError("Unsupported format: %r"%(fmt,))
index 5e3229ab86103ddabc62bbcef21fdcc99a4df33f..ffde9d4309c58ff1d426849bd1cb4de77af7fcaf 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Tue Jun 18 16:49:39 2019
+# Autogenerated by Sphinx on Mon Oct 14 18:26:58 2019
 topics = {'assert': 'The "assert" statement\n'
            '**********************\n'
            '\n'
@@ -5365,17 +5365,19 @@ topics = {'assert': 'The "assert" statement\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'
+                  'it, unless the     |\n'
+                  '   |           | "\'#\'" option is used.  Positive and '
+                  'negative infinity,     |\n'
+                  '   |           | positive and negative zero, and nans, are '
+                  'formatted as     |\n'
+                  '   |           | "inf", "-inf", "0", "-0" and "nan" '
+                  'respectively,           |\n'
+                  '   |           | regardless of the precision.  A precision '
+                  'of "0" is        |\n'
+                  '   |           | treated as equivalent to a precision of '
+                  '"1". The default   |\n'
+                  '   |           | precision is '
+                  '"6".                                          |\n'
                   '   '
                   '+-----------+------------------------------------------------------------+\n'
                   '   | "\'G\'"     | General format. Same as "\'g\'" except '
@@ -7078,10 +7080,10 @@ topics = {'assert': 'The "assert" statement\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'
+                     '| "(expressions...)",  "[expressions...]", "{key: | '
+                     'Binding or parenthesized expression,  |\n'
+                     '| value...}", "{expressions...}"                  | list '
+                     'display, dictionary display, set |\n'
                      '|                                                 | '
                      'display                               |\n'
                      '+-------------------------------------------------+---------------------------------------+\n'
@@ -7449,7 +7451,11 @@ topics = {'assert': 'The "assert" statement\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'
+                   '0. The\n'
+                   '   return value may also be "NotImplemented", which is '
+                   'treated the\n'
+                   '   same as if the "__length_hint__" method didn’t exist at '
+                   'all. This\n'
                    '   method is purely an optimization and is never required '
                    'for\n'
                    '   correctness.\n'
@@ -9152,7 +9158,11 @@ topics = {'assert': 'The "assert" statement\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'
+                 'The\n'
+                 '   return value may also be "NotImplemented", which is '
+                 'treated the\n'
+                 '   same as if the "__length_hint__" method didn’t exist at '
+                 'all. This\n'
                  '   method is purely an optimization and is never required '
                  'for\n'
                  '   correctness.\n'
@@ -9989,13 +9999,15 @@ topics = {'assert': 'The "assert" statement\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'
+                   '   and there is at least one character, false otherwise.\n'
+                   '\n'
+                   '   A character is *whitespace* if in the Unicode character '
+                   'database\n'
+                   '   (see "unicodedata"), either its general category is '
+                   '"Zs"\n'
+                   '   (“Separator, space”), or its bidirectional class is one '
+                   'of "WS",\n'
+                   '   "B", or "S".\n'
                    '\n'
                    'str.istitle()\n'
                    '\n'
@@ -12087,6 +12099,11 @@ topics = {'assert': 'The "assert" statement\n'
                  'therefore,\n'
                  '   custom mapping types should support too):\n'
                  '\n'
+                 '   list(d)\n'
+                 '\n'
+                 '      Return a list of all the keys used in the dictionary '
+                 '*d*.\n'
+                 '\n'
                  '   len(d)\n'
                  '\n'
                  '      Return the number of items in the dictionary *d*.\n'
@@ -12243,11 +12260,21 @@ topics = {'assert': 'The "assert" statement\n'
                  'the\n'
                  '      documentation of view objects.\n'
                  '\n'
+                 '      An equality comparison between one "dict.values()" '
+                 'view and\n'
+                 '      another will always return "False". This also applies '
+                 'when\n'
+                 '      comparing "dict.values()" to itself:\n'
+                 '\n'
+                 "         >>> d = {'a': 1}\n"
+                 '         >>> d.values() == d.values()\n'
+                 '         False\n'
+                 '\n'
                  '   Dictionaries compare equal if and only if they have the '
                  'same "(key,\n'
-                 '   value)" pairs. Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) '
-                 'raise\n'
-                 '   "TypeError".\n'
+                 '   value)" pairs (regardless of ordering). Order comparisons '
+                 '(‘<’,\n'
+                 '   ‘<=’, ‘>=’, ‘>’) raise "TypeError".\n'
                  '\n'
                  '   Dictionaries preserve insertion order.  Note that '
                  'updating a key\n'
index 2c9786c517a350f2bd766b539e41ac860f9dd435..195dc12bbce95e290eed5667da88ce8de7181f88 100644 (file)
@@ -55,7 +55,7 @@ class shlex:
             punctuation_chars = ''
         elif punctuation_chars is True:
             punctuation_chars = '();<>|&'
-        self.punctuation_chars = punctuation_chars
+        self._punctuation_chars = punctuation_chars
         if punctuation_chars:
             # _pushback_chars is a push back queue used by lookahead logic
             self._pushback_chars = deque()
@@ -65,6 +65,10 @@ class shlex:
             t = self.wordchars.maketrans(dict.fromkeys(punctuation_chars))
             self.wordchars = self.wordchars.translate(t)
 
+    @property
+    def punctuation_chars(self):
+        return self._punctuation_chars
+
     def push_token(self, tok):
         "Push a token onto the stack popped by the get_token method"
         if self.debug >= 1:
index ced8445536e3c69ddabf9283aaa62d546e859e2a..95dd24bdfadca694a81da0b56f4734aa46efa4a0 100644 (file)
@@ -98,16 +98,14 @@ class RowFactoryTests(unittest.TestCase):
 
     def CheckSqliteRowIndex(self):
         self.con.row_factory = sqlite.Row
-        row = self.con.execute("select 1 as a, 2 as b").fetchone()
+        row = self.con.execute("select 1 as a_1, 2 as b").fetchone()
         self.assertIsInstance(row, sqlite.Row)
 
-        col1, col2 = row["a"], row["b"]
-        self.assertEqual(col1, 1, "by name: wrong result for column 'a'")
-        self.assertEqual(col2, 2, "by name: wrong result for column 'a'")
+        self.assertEqual(row["a_1"], 1, "by name: wrong result for column 'a_1'")
+        self.assertEqual(row["b"], 2, "by name: wrong result for column 'b'")
 
-        col1, col2 = row["A"], row["B"]
-        self.assertEqual(col1, 1, "by name: wrong result for column 'A'")
-        self.assertEqual(col2, 2, "by name: wrong result for column 'B'")
+        self.assertEqual(row["A_1"], 1, "by name: wrong result for column 'A_1'")
+        self.assertEqual(row["B"], 2, "by name: wrong result for column 'B'")
 
         self.assertEqual(row[0], 1, "by index: wrong result for column 0")
         self.assertEqual(row[1], 2, "by index: wrong result for column 1")
@@ -116,6 +114,10 @@ class RowFactoryTests(unittest.TestCase):
 
         with self.assertRaises(IndexError):
             row['c']
+        with self.assertRaises(IndexError):
+            row['a_\x11']
+        with self.assertRaises(IndexError):
+            row['a\x7f1']
         with self.assertRaises(IndexError):
             row[2]
         with self.assertRaises(IndexError):
@@ -123,6 +125,15 @@ class RowFactoryTests(unittest.TestCase):
         with self.assertRaises(IndexError):
             row[2**1000]
 
+    def CheckSqliteRowIndexUnicode(self):
+        self.con.row_factory = sqlite.Row
+        row = self.con.execute("select 1 as \xff").fetchone()
+        self.assertEqual(row["\xff"], 1)
+        with self.assertRaises(IndexError):
+            row['\u0178']
+        with self.assertRaises(IndexError):
+            row['\xdf']
+
     def CheckSqliteRowSlice(self):
         # A sqlite.Row can be sliced like a list.
         self.con.row_factory = sqlite.Row
@@ -169,19 +180,33 @@ class RowFactoryTests(unittest.TestCase):
         row_1 = self.con.execute("select 1 as a, 2 as b").fetchone()
         row_2 = self.con.execute("select 1 as a, 2 as b").fetchone()
         row_3 = self.con.execute("select 1 as a, 3 as b").fetchone()
+        row_4 = self.con.execute("select 1 as b, 2 as a").fetchone()
+        row_5 = self.con.execute("select 2 as b, 1 as a").fetchone()
 
-        self.assertEqual(row_1, row_1)
-        self.assertEqual(row_1, row_2)
-        self.assertTrue(row_2 != row_3)
+        self.assertTrue(row_1 == row_1)
+        self.assertTrue(row_1 == row_2)
+        self.assertFalse(row_1 == row_3)
+        self.assertFalse(row_1 == row_4)
+        self.assertFalse(row_1 == row_5)
+        self.assertFalse(row_1 == object())
 
         self.assertFalse(row_1 != row_1)
         self.assertFalse(row_1 != row_2)
-        self.assertFalse(row_2 == row_3)
+        self.assertTrue(row_1 != row_3)
+        self.assertTrue(row_1 != row_4)
+        self.assertTrue(row_1 != row_5)
+        self.assertTrue(row_1 != object())
+
+        with self.assertRaises(TypeError):
+            row_1 > row_2
+        with self.assertRaises(TypeError):
+            row_1 < row_2
+        with self.assertRaises(TypeError):
+            row_1 >= row_2
+        with self.assertRaises(TypeError):
+            row_1 <= row_2
 
-        self.assertEqual(row_1, row_2)
         self.assertEqual(hash(row_1), hash(row_2))
-        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 """
index a53735b07ded420ca2bc9fa636f40b9eb2241500..cb2c4c3281c9c3e5e5affecf0bb65c9373aed3df 100644 (file)
@@ -406,13 +406,7 @@ def _escape(source, escape, state):
     raise source.error("bad escape %s" % escape, len(escape))
 
 def _uniq(items):
-    if len(set(items)) == len(items):
-        return items
-    newitems = []
-    for item in items:
-        if item not in newitems:
-            newitems.append(item)
-    return newitems
+    return list(dict.fromkeys(items))
 
 def _parse_sub(source, state, verbose, nested):
     # parse an alternation: a|b|c
index 53a5e720997437514c1938886c26acc92986673a..d1b6de57857899112777794574a52659f35a31fc 100644 (file)
@@ -217,22 +217,38 @@ if _mswindows:
         __str__ = __repr__
 
 
-# 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
-# for synchronously from _cleanup() when a new Popen object is created, to avoid
-# zombie processes.
-_active = []
-
-def _cleanup():
-    for inst in _active[:]:
-        res = inst._internal_poll(_deadstate=sys.maxsize)
-        if res is not None:
-            try:
-                _active.remove(inst)
-            except ValueError:
-                # This can happen if two threads create a new Popen instance.
-                # It's harmless that it was already removed, so ignore.
-                pass
+if _mswindows:
+    # On Windows we just need to close `Popen._handle` when we no longer need
+    # it, so that the kernel can free it. `Popen._handle` gets closed
+    # implicitly when the `Popen` instance is finalized (see `Handle.__del__`,
+    # which is calling `CloseHandle` as requested in [1]), so there is nothing
+    # for `_cleanup` to do.
+    #
+    # [1] https://docs.microsoft.com/en-us/windows/desktop/ProcThread/
+    # creating-processes
+    _active = None
+
+    def _cleanup():
+        pass
+else:
+    # 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 for synchronously from _cleanup() when a new Popen object is
+    # created, to avoid zombie processes.
+    _active = []
+
+    def _cleanup():
+        if _active is None:
+            return
+        for inst in _active[:]:
+            res = inst._internal_poll(_deadstate=sys.maxsize)
+            if res is not None:
+                try:
+                    _active.remove(inst)
+                except ValueError:
+                    # This can happen if two threads create a new Popen instance.
+                    # It's harmless that it was already removed, so ignore.
+                    pass
 
 PIPE = -1
 STDOUT = -2
@@ -378,7 +394,7 @@ def check_output(*popenargs, timeout=None, **kwargs):
     b'when in the course of barman events\n'
 
     By default, all communication is in bytes, and therefore any "input"
-    should be bytes, and the return value wil be bytes.  If in text mode,
+    should be bytes, and the return value will be bytes.  If in text mode,
     any "input" should be a string, and the return value will be a string
     decoded according to locale encoding, or by "encoding" if set. Text mode
     is triggered by setting any of text, encoding, errors or universal_newlines.
@@ -472,11 +488,20 @@ def run(*popenargs,
     with Popen(*popenargs, **kwargs) as process:
         try:
             stdout, stderr = process.communicate(input, timeout=timeout)
-        except TimeoutExpired:
+        except TimeoutExpired as exc:
             process.kill()
-            stdout, stderr = process.communicate()
-            raise TimeoutExpired(process.args, timeout, output=stdout,
-                                 stderr=stderr)
+            if _mswindows:
+                # Windows accumulates the output in a single blocking
+                # read() call run on child threads, with the timeout
+                # being done in a join() on those threads.  communicate()
+                # _after_ kill() is required to collect that and add it
+                # to the exception.
+                exc.stdout, exc.stderr = process.communicate()
+            else:
+                # POSIX _communicate already populated the output so
+                # far into the TimeoutExpired exception.
+                process.wait()
+            raise
         except:  # Including KeyboardInterrupt, communicate handled that.
             process.kill()
             # We don't call process.wait() as .__exit__ does that for us.
@@ -974,12 +999,16 @@ class Popen(object):
             return endtime - _time()
 
 
-    def _check_timeout(self, endtime, orig_timeout):
+    def _check_timeout(self, endtime, orig_timeout, stdout_seq, stderr_seq,
+                       skip_check_and_raise=False):
         """Convenience for checking if a timeout has expired."""
         if endtime is None:
             return
-        if _time() > endtime:
-            raise TimeoutExpired(self.args, orig_timeout)
+        if skip_check_and_raise or _time() > endtime:
+            raise TimeoutExpired(
+                    self.args, orig_timeout,
+                    output=b''.join(stdout_seq) if stdout_seq else None,
+                    stderr=b''.join(stderr_seq) if stderr_seq else None)
 
 
     def wait(self, timeout=None):
@@ -1676,10 +1705,15 @@ class Popen(object):
                 while selector.get_map():
                     timeout = self._remaining_time(endtime)
                     if timeout is not None and timeout < 0:
-                        raise TimeoutExpired(self.args, orig_timeout)
+                        self._check_timeout(endtime, orig_timeout,
+                                            stdout, stderr,
+                                            skip_check_and_raise=True)
+                        raise RuntimeError(  # Impossible :)
+                            '_check_timeout(..., skip_check_and_raise=True) '
+                            'failed to raise TimeoutExpired.')
 
                     ready = selector.select(timeout)
-                    self._check_timeout(endtime, orig_timeout)
+                    self._check_timeout(endtime, orig_timeout, stdout, stderr)
 
                     # XXX Rewrite these to use non-blocking I/O on the file
                     # objects; they are no longer using C stdio!
index fb65e5e1aba55675621084c7e89703c11d672590..18947170cbcdc35f5eb9558a8672f3c6d775068d 100644 (file)
@@ -1057,8 +1057,7 @@ class _TestQueue(BaseTestCase):
             q = self.Queue()
             q.put(NotSerializable())
             q.put(True)
-            # bpo-30595: use a timeout of 1 second for slow buildbots
-            self.assertTrue(q.get(timeout=1.0))
+            self.assertTrue(q.get(timeout=TIMEOUT))
             close_queue(q)
 
         with test.support.captured_stderr():
@@ -2690,16 +2689,17 @@ class _TestMyManager(BaseTestCase):
         self.common(manager)
         manager.shutdown()
 
-        # If the manager process exited cleanly then the exitcode
-        # will be zero.  Otherwise (after a short timeout)
-        # terminate() is used, resulting in an exitcode of -SIGTERM.
-        self.assertEqual(manager._process.exitcode, 0)
+        # bpo-30356: BaseManager._finalize_manager() sends SIGTERM
+        # to the manager process if it takes longer than 1 second to stop,
+        # which happens on slow buildbots.
+        self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM))
 
     def test_mymanager_context(self):
         with MyManager() as manager:
             self.common(manager)
         # bpo-30356: BaseManager._finalize_manager() sends SIGTERM
-        # to the manager process if it takes longer than 1 second to stop.
+        # to the manager process if it takes longer than 1 second to stop,
+        # which happens on slow buildbots.
         self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM))
 
     def test_mymanager_context_prestarted(self):
index 2f8975d8c07fc4cc667c2899d806ef2322914f08..ba3722295ddb7ceafa18664b9ac07e8e03c42ca2 100644 (file)
@@ -2,11 +2,8 @@
 
 See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
 """
-from test.support import is_resource_enabled
-
 import itertools
 import bisect
-
 import copy
 import decimal
 import sys
@@ -22,6 +19,7 @@ from array import array
 from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod
 
 from test import support
+from test.support import is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST
 
 import datetime as datetime_module
 from datetime import MINYEAR, MAXYEAR
@@ -53,6 +51,7 @@ OTHERSTUFF = (10, 34.5, "abc", {}, [], ())
 INF = float("inf")
 NAN = float("nan")
 
+
 #############################################################################
 # module tests
 
@@ -340,6 +339,18 @@ class TestTimeZone(unittest.TestCase):
         self.assertTrue(timezone(ZERO) != None)
         self.assertFalse(timezone(ZERO) ==  None)
 
+        tz = timezone(ZERO)
+        self.assertTrue(tz == ALWAYS_EQ)
+        self.assertFalse(tz != ALWAYS_EQ)
+        self.assertTrue(tz < LARGEST)
+        self.assertFalse(tz > LARGEST)
+        self.assertTrue(tz <= LARGEST)
+        self.assertFalse(tz >= LARGEST)
+        self.assertFalse(tz < SMALLEST)
+        self.assertTrue(tz > SMALLEST)
+        self.assertFalse(tz <= SMALLEST)
+        self.assertTrue(tz >= SMALLEST)
+
     def test_aware_datetime(self):
         # test that timezone instances can be used by datetime
         t = datetime(1, 1, 1)
@@ -377,6 +388,36 @@ class TestTimeZone(unittest.TestCase):
         tz_copy = copy.deepcopy(tz)
         self.assertIs(tz_copy, tz)
 
+    def test_offset_boundaries(self):
+        # Test timedeltas close to the boundaries
+        time_deltas = [
+            timedelta(hours=23, minutes=59),
+            timedelta(hours=23, minutes=59, seconds=59),
+            timedelta(hours=23, minutes=59, seconds=59, microseconds=999999),
+        ]
+        time_deltas.extend([-delta for delta in time_deltas])
+
+        for delta in time_deltas:
+            with self.subTest(test_type='good', delta=delta):
+                timezone(delta)
+
+        # Test timedeltas on and outside the boundaries
+        bad_time_deltas = [
+            timedelta(hours=24),
+            timedelta(hours=24, microseconds=1),
+        ]
+        bad_time_deltas.extend([-delta for delta in bad_time_deltas])
+
+        for delta in bad_time_deltas:
+            with self.subTest(test_type='bad', delta=delta):
+                with self.assertRaises(ValueError):
+                    timezone(delta)
+
+    def test_comparison_with_tzinfo(self):
+        # Constructing tzinfo objects directly should not be done by users
+        # and serves only to check the bug described in bpo-37915
+        self.assertNotEqual(timezone.utc, tzinfo())
+        self.assertNotEqual(timezone(timedelta(hours=1)), tzinfo())
 
 #############################################################################
 # Base class for testing a particular aspect of timedelta, time, date and
@@ -399,6 +440,24 @@ class HarmlessMixedComparison:
         self.assertIn(me, [1, 20, [], me])
         self.assertIn([], [me, 1, 20, []])
 
+        # Comparison to objects of unsupported types should return
+        # NotImplemented which falls back to the right hand side's __eq__
+        # method. In this case, ALWAYS_EQ.__eq__ always returns True.
+        # ALWAYS_EQ.__ne__ always returns False.
+        self.assertTrue(me == ALWAYS_EQ)
+        self.assertFalse(me != ALWAYS_EQ)
+
+        # If the other class explicitly defines ordering
+        # relative to our class, it is allowed to do so
+        self.assertTrue(me < LARGEST)
+        self.assertFalse(me > LARGEST)
+        self.assertTrue(me <= LARGEST)
+        self.assertFalse(me >= LARGEST)
+        self.assertFalse(me < SMALLEST)
+        self.assertTrue(me > SMALLEST)
+        self.assertFalse(me <= SMALLEST)
+        self.assertTrue(me >= SMALLEST)
+
     def test_harmful_mixed_comparison(self):
         me = self.theclass(1, 1, 1)
 
@@ -1352,15 +1411,20 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         t.strftime("%f")
 
     def test_strftime_trailing_percent(self):
-        # bpo-35066: make sure trailing '%' doesn't cause
-        # datetime's strftime to complain
+        # bpo-35066: Make sure trailing '%' doesn't cause datetime's strftime to
+        # complain. Different libcs have different handling of trailing
+        # percents, so we simply check datetime's strftime acts the same as
+        # time.strftime.
         t = self.theclass(2005, 3, 2)
         try:
             _time.strftime('%')
         except ValueError:
             self.skipTest('time module does not support trailing %')
-        self.assertEqual(t.strftime('%'), '%')
-        self.assertEqual(t.strftime("m:%m d:%d y:%y %"), "m:03 d:02 y:05 %")
+        self.assertEqual(t.strftime('%'), _time.strftime('%', t.timetuple()))
+        self.assertEqual(
+            t.strftime("m:%m d:%d y:%y %"),
+            _time.strftime("m:03 d:02 y:05 %", t.timetuple()),
+        )
 
     def test_format(self):
         dt = self.theclass(2007, 9, 10)
@@ -1524,29 +1588,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         self.assertRaises(TypeError, lambda: our < their)
         self.assertRaises(TypeError, lambda: their < our)
 
-        # However, if the other class explicitly defines ordering
-        # relative to our class, it is allowed to do so
-
-        class LargerThanAnything:
-            def __lt__(self, other):
-                return False
-            def __le__(self, other):
-                return isinstance(other, LargerThanAnything)
-            def __eq__(self, other):
-                return isinstance(other, LargerThanAnything)
-            def __gt__(self, other):
-                return not isinstance(other, LargerThanAnything)
-            def __ge__(self, other):
-                return True
-
-        their = LargerThanAnything()
-        self.assertEqual(our == their, False)
-        self.assertEqual(their == our, False)
-        self.assertEqual(our != their, True)
-        self.assertEqual(their != our, True)
-        self.assertEqual(our < their, True)
-        self.assertEqual(their < our, False)
-
     def test_bool(self):
         # All dates are considered true.
         self.assertTrue(self.theclass.min)
@@ -3149,16 +3190,25 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
 
     def test_compat_unpickle(self):
         tests = [
-            b"cdatetime\ntime\n(S'\\x14;\\x10\\x00\\x10\\x00'\ntR.",
-            b'cdatetime\ntime\n(U\x06\x14;\x10\x00\x10\x00tR.',
-            b'\x80\x02cdatetime\ntime\nU\x06\x14;\x10\x00\x10\x00\x85R.',
+            (b"cdatetime\ntime\n(S'\\x14;\\x10\\x00\\x10\\x00'\ntR.",
+             (20, 59, 16, 64**2)),
+            (b'cdatetime\ntime\n(U\x06\x14;\x10\x00\x10\x00tR.',
+             (20, 59, 16, 64**2)),
+            (b'\x80\x02cdatetime\ntime\nU\x06\x14;\x10\x00\x10\x00\x85R.',
+             (20, 59, 16, 64**2)),
+            (b"cdatetime\ntime\n(S'\\x14;\\x19\\x00\\x10\\x00'\ntR.",
+             (20, 59, 25, 64**2)),
+            (b'cdatetime\ntime\n(U\x06\x14;\x19\x00\x10\x00tR.',
+             (20, 59, 25, 64**2)),
+            (b'\x80\x02cdatetime\ntime\nU\x06\x14;\x19\x00\x10\x00\x85R.',
+             (20, 59, 25, 64**2)),
         ]
-        args = 20, 59, 16, 64**2
-        expected = self.theclass(*args)
-        for data in tests:
-            for loads in pickle_loads:
-                derived = loads(data, encoding='latin1')
-                self.assertEqual(derived, expected)
+        for i, (data, args) in enumerate(tests):
+            with self.subTest(i=i):
+                expected = self.theclass(*args)
+                for loads in pickle_loads:
+                    derived = loads(data, encoding='latin1')
+                    self.assertEqual(derived, expected)
 
     def test_bool(self):
         # time is always True.
@@ -3622,8 +3672,8 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
         self.assertRaises(ValueError, base.replace, microsecond=1000000)
 
     def test_mixed_compare(self):
-        t1 = time(1, 2, 3)
-        t2 = time(1, 2, 3)
+        t1 = self.theclass(1, 2, 3)
+        t2 = self.theclass(1, 2, 3)
         self.assertEqual(t1, t2)
         t2 = t2.replace(tzinfo=None)
         self.assertEqual(t1, t2)
index cbb3c3bccd2ca551ba8f7f7088a6d2d5bbd92e9e..c330c36d8f9fde0d9d7235dc7069e75b6b4c84d5 100644 (file)
@@ -1,45 +1,45 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,D134E931C96D9DEC
-
-nuGFEej7vIjkYWSMz5OJeVTNntDRQi6ZM4DBm3g8T7i/0odr3WFqGMMKZcIhLYQf
-rgRq7RSKtrJ1y5taVucMV+EuCjyfzDo0TsYt+ZrXv/D08eZhjRmkhoHnGVF0TqQm
-nQEXM/ERT4J2RM78dnG+homMkI76qOqxgGbRqQqJo6AiVRcAZ45y8s96bru2TAB8
-+pWjO/v0Je7AFVdwSU52N8OOY6uoSAygW+0UY1WVxbVGJF2XfRsNpPX+YQHYl6e+
-3xM5XBVCgr6kmdAyub5qUJ38X3TpdVGoR0i+CVS9GTr2pSRib1zURAeeHnlqiUZM
-4m0Gn9s72nJevU1wxED8pwOhR8fnHEmMKGD2HPhKoOCbzDhwwBZO27TNa1uWeM3f
-M5oixKDi2PqMn3y2cDx1NjJtP661688EcJ5a2Ih9BgO9xpnhSyzBWEKcAn0tJB0H
-/56M0FW6cdOOIzMveGGL7sHW5E+iOdI1n5e7C6KJUzew78Y9qJnhS53EdI6qTz9R
-wsIsj1i070Fk6RbPo6zpLlF6w7Zj8GlZaZA7OZZv9wo5VEV/0ST8gmiiBOBc4C6Y
-u9hyLIIu4dFEBKyQHRvBnQSLNpKx6or1OGFDVBay2In9Yh2BHh1+vOj/OIz/wq48
-EHOIV27fRJxLu4jeK5LIGDhuPnMJ8AJYQ0bQOUP6fd7p+TxWkAQZPB/Dx/cs3hxr
-nFEdzx+eO+IAsObx/b1EGZyEJyETBslu4GwYX7/KK3HsJhDJ1bdZ//28jOCaoir6
-ZOMT72GRwmVoQTJ0XpccfjHfKJDRLT7C1xvzo4Eibth0hpTZkA75IUYUp6qK/PuJ
-kH/qdiC7QIkRKtsrawW4vEDna3YtxIYhQqz9+KwO6u/0gzooZtv1RU4U3ifMDB5u
-5P5GAzACRqlY8QYBkM869lvWqzQPHvybC4ak9Yx6/heMO9ddjdIW9BaK8BLxvN/6
-UCD936Y4fWltt09jHZIoxWFykouBwmd7bXooNYXmDRNmjTdVhKJuOEOQw8hDzx7e
-pWFJ9Z/V4Qm1tvXbCD7QFqMCDoY3qFvVG8DBqXpmxe1yPfz21FWrT7IuqDXAD3ns
-vxfN/2a+Cy04U9FBNVCvWqWIs5AgNpdCMJC2FlXKTy+H3/7rIjNyFyvbX0vxIXtK
-liOVNXiyVM++KZXqktqMUDlsJENmIHV9B046luqbgW018fHkyEYlL3iRZGbYegwr
-XO9VVIKVPw1BEvJ8VNdGFGuZGepd8qX2ezfYADrNR+4t85HDm8inbjTobSjWuljs
-ftUNkOeCHqAvWCFQTLCfdykvV08EJfVY79y7yFPtfRV2gxYokXFifjo3su9sVQr1
-UiIS5ZAsIC1hBXWeXoBN7QVTkFi7Yto6E1q2k10LiT3obpUUUQ/oclhrJOCJVjrS
-oRcj2QBy8OT4T9slJr5maTWdgd7Lt6+I6cGQXPaDvjGOJl0eBYM14vhx4rRQWytJ
-k07hhHFO4+9CGCuHS8AAy2gR6acYFWt2ZiiNZ0z/iPIHNK4YEyy9aLf6uZH/KQjE
-jmHToo7XD6QvCAEC5qTHby3o3LfHIhyZi/4L+AhS4FKUHF6M0peeyYt4z3HaK2d2
-N6mHLPdjwNjra7GOmcns4gzcrdfoF+R293KpPal4PjknvR3dZL4kKP/ougTAM5zv
-qDIvRbkHzjP8ChTpoLcJsNVXykNcNkjcSi0GHtIpYjh6QX6P2uvR/S4+Bbb9p9rn
-hIy/ovu9tWN2hiPxGPe6torF6BulAxsTYlDercC204AyzsrdA0pr6HBgJH9C6ML1
-TchwodbFJqn9rSv91i1liusAGoOvE81AGBdrXY7LxfSNhYY1IK6yR/POJPTd53sA
-uX2/j6Rtoksd/2BHPM6AUnI/2B9slhuzWX2aCtWLeuwvXDS6rYuTigaQmLkzTRfM
-dlMI3s9KLXxgi5YVumUZleJWXwBNP7KiKajd+VTSD+7WAhyhM5FIG5wVOaxmy4G2
-TyqZ/Ax9d2VEjTQHWvQlLPQ4Mp0EIz0aEl94K/S8CK8bJRH6+PRkar+dJi1xqlL+
-BYb42At9mEJ8odLlFikvNi1+t7jqXk5jRi5C0xFKx3nTtzoH2zNUeuA3R6vSocVK
-45jnze9IkKmxMlJ4loR5sgszdpDCD3kXqjtCcbMTmcrGyzJek3HSOTpiEORoTFOe
-Rhg6jH5lm+QcC263oipojS0qEQcnsWJP2CylNYMYHR9O/9NQxT3o2lsRHqZTMELV
-uQa/SFH+paQNbZOj8MRwPSqqiIxJFuLswKte1R+W7LKn1yBSM7Pp39lNbzGvJD2E
-YRfnCwFpJ54voVAuQ4jXJvigCW2qeCjXlxeD6K2j4eGJEEOmIjIW1wjubyBY6OI3
------END RSA PRIVATE KEY-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIHbTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIhD+rJdxqb6ECAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDTdyjCP3riOSUfxix4aXEvBIIH
+ECGkbsFabrcFMZcplw5jHMaOlG7rYjUzwDJ80JM8uzbv2Jb8SvNlns2+xmnEvH/M
+mNvRmnXmplbVjH3XBMK8o2Psnr2V/a0j7/pgqpRxHykG+koOY4gzdt3MAg8JPbS2
+hymSl+Y5EpciO3xLfz4aFL1ZNqspQbO/TD13Ij7DUIy7xIRBMp4taoZCrP0cEBAZ
++wgu9m23I4dh3E8RUBzWyFFNic2MVVHrui6JbHc4dIHfyKLtXJDhUcS0vIC9PvcV
+jhorh3UZC4lM+/jjXV5AhzQ0VrJ2tXAUX2dA144XHzkSH2QmwfnajPsci7BL2CGC
+rjyTy4NfB/lDwU+55dqJZQSKXMxAapJMrtgw7LD5CKQcN6zmfhXGssJ7HQUXKkaX
+I1YOFzuUD7oo56BVCnVswv0jX9RxrE5QYNreMlOP9cS+kIYH65N+PAhlURuQC14K
+PgDkHn5knSa2UQA5tc5f7zdHOZhGRUfcjLP+KAWA3nh+/2OKw/X3zuPx75YT/FKe
+tACPw5hjEpl62m9Xa0eWepZXwqkIOkzHMmCyNCsbC0mmRoEjmvfnslfsmnh4Dg/c
+4YsTYMOLLIeCa+WIc38aA5W2lNO9lW0LwLhX1rP+GRVPv+TVHXlfoyaI+jp0iXrJ
+t3xxT0gaiIR/VznyS7Py68QV/zB7VdqbsNzS7LdquHK1k8+7OYiWjY3gqyU40Iu2
+d1eSnIoDvQJwyYp7XYXbOlXNLY+s1Qb7yxcW3vXm0Bg3gKT8r1XHWJ9rj+CxAn5r
+ysfkPs1JsesxzzQjwTiDNvHnBnZnwxuxfBr26ektEHmuAXSl8V6dzLN/aaPjpTj4
+CkE7KyqX3U9bLkp+ztl4xWKEmW44nskzm0+iqrtrxMyTfvvID4QrABjZL4zmWIqc
+e3ZfA3AYk9VDIegk/YKGC5VZ8YS7ZXQ0ASK652XqJ7QlMKTxxV7zda6Fp4uW6/qN
+ezt5wgbGGhZQXj2wDQmWNQYyG/juIgYTpCUA54U5XBIjuR6pg+Ytm0UrvNjsUoAC
+wGelyqaLDq8U8jdIFYVTJy9aJjQOYXjsUJ0dZN2aGHSlju0ZGIZc49cTIVQ9BTC5
+Yc0Vlwzpl+LuA25DzKZNSb/ci0lO/cQGJ2uXQQgaNgdsHlu8nukENGJhnIzx4fzK
+wEh3yHxhTRCzPPwDfXmx0IHXrPqJhSpAgaXBVIm8OjvmMxO+W75W4uLfNY/B7e2H
+3cjklGuvkofOf7sEOrGUYf4cb6Obg8FpvHgpKo5Twwmoh/qvEKckBFqNhZXDDl88
+GbGlSEgyaAV1Ig8s1NJKBolWFa0juyPAwJ8vT1T4iwW7kQ7KXKt2UNn96K/HxkLu
+pikvukz8oRHMlfVHa0R48UB1fFHwZLzPmwkpu6ancIxk3uO3yfhf6iDk3bmnyMlz
+g3k/b6MrLYaOVByRxay85jH3Vvgqfgn6wa6BJ7xQ81eZ8B45gFuTH0J5JtLL7SH8
+darRPLCYfA+Ums9/H6pU5EXfd3yfjMIbvhCXHkJrrljkZ+th3p8dyto6wmYqIY6I
+qR9sU+o6DhRaiP8tCICuhHxQpXylUM6WeJkJwduTJ8KWIvzsj4mReIKOl/oC2jSd
+gIdKhb9Q3zj9ce4N5m6v66tyvjxGZ+xf3BvUPDD+LwZeXgf7OBsNVbXzQbzto594
+nbCzPocFi3gERE50ru4K70eQCy08TPG5NpOz+DDdO5vpAuMLYEuI7O3L+3GjW40Q
+G5bu7H5/i7o/RWR67qhG/7p9kPw3nkUtYgnvnWaPMIuTfb4c2d069kjlfgWjIbbI
+tpSKmm5DHlqTE4/ECAbIEDtSaw9dXHCdL3nh5+n428xDdGbjN4lT86tfu17EYKzl
+ydH1RJ1LX3o3TEj9UkmDPt7LnftvwybMFEcP7hM2xD4lC++wKQs7Alg6dTkBnJV4
+5xU78WRntJkJTU7kFkpPKA0QfyCuSF1fAMoukDBkqUdOj6jE0BlJQlHk5iwgnJlt
+uEdkTjHZEjIUxWC6llPcAzaPNlmnD45AgfEW+Jn21IvutmJiQAz5lm9Z9PXaR0C8
+hXB6owRY67C0YKQwXhoNf6xQun2xGBGYy5rPEEezX1S1tUH5GR/KW1Lh+FzFqHXI
+ZEb5avfDqHKehGAjPON+Br7akuQ125M9LLjKuSyPaQzeeCAy356Xd7XzVwbPddbm
+9S9WSPqzaPgh10chIHoNoC8HMd33dB5j9/Q6jrbU/oPlptu/GlorWblvJdcTuBGI
+IVn45RFnkG8hCz0GJSNzW7+70YdESQbfJW79vssWMaiSjFE0pMyFXrFR5lBywBTx
+PiGEUWtvrKG94X1TMlGUzDzDJOQNZ9dT94bonNe9pVmP5BP4/DzwwiWh6qrzWk6p
+j8OE4cfCSh2WvHnhJbH7/N0v+JKjtxeIeJ16jx/K2oK5
+-----END ENCRYPTED PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
 MIIEWTCCAsGgAwIBAgIJAJinz4jHSjLtMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV
 BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
@@ -66,3 +66,4 @@ jMqTFlmO7kpf/jpCSmamp3/JSEE1BJKHwQ6Ql4nzRA2N1mnvWH7Zxcv043gkHeAu
 9Wc2uXpw9xF8itV4Uvcdr3dwqByvIqn7iI/gB+4l41e0u8OmH2MKOx4Nxlly5TNW
 HcVKQHyOeyvnINuBAQ==
 -----END CERTIFICATE-----
+
index dc0d88071946cfbaeef85258291fd83606c241a8..9f1bf6800824a617e92dc2ad8d265f48705085b9 100644 (file)
@@ -272,8 +272,10 @@ def _create_parser():
     group.add_argument('--junit-xml', dest='xmlpath', metavar='FILENAME',
                        help='writes JUnit-style XML results to the specified '
                             'file')
-    group.add_argument('--tempdir', dest='tempdir', metavar='PATH',
+    group.add_argument('--tempdir', metavar='PATH',
                        help='override the working directory for the test run')
+    group.add_argument('--cleanup', action='store_true',
+                       help='remove old test_python_* directories')
     return parser
 
 
index a9b2b352d120e653220be1d0cd68d00a5a3ebc51..5ae8878638a5c192449cf25d68f0f48730b729fa 100644 (file)
@@ -14,13 +14,19 @@ from test.libregrtest.cmdline import _parse_args
 from test.libregrtest.runtest import (
     findtests, runtest, get_abs_module,
     STDTESTS, NOTTESTS, PASSED, FAILED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED,
-    INTERRUPTED, CHILD_ERROR, TEST_DID_NOT_RUN,
+    INTERRUPTED, CHILD_ERROR, TEST_DID_NOT_RUN, TIMEOUT,
     PROGRESS_MIN_TIME, format_test_result, is_failed)
 from test.libregrtest.setup import setup_tests
 from test.libregrtest.utils import removepy, count, format_duration, printlist
 from test import support
 
 
+# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()).
+# Used to protect against threading._shutdown() hang.
+# Must be smaller than buildbot "1200 seconds without output" limit.
+EXIT_TIMEOUT = 120.0
+
+
 class Regrtest:
     """Execute a test suite.
 
@@ -114,6 +120,8 @@ class Regrtest:
             self.run_no_tests.append(test_name)
         elif ok == INTERRUPTED:
             self.interrupted = True
+        elif ok == TIMEOUT:
+            self.bad.append(test_name)
         else:
             raise ValueError("invalid test result: %r" % ok)
 
@@ -155,11 +163,6 @@ class Regrtest:
     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.xmlpath:
             support.junit_xml_list = self.testsuite_xml = []
 
@@ -173,7 +176,19 @@ class Regrtest:
         # Strip .py extensions.
         removepy(ns.args)
 
-        return ns
+        if ns.huntrleaks:
+            warmup, repetitions, _ = ns.huntrleaks
+            if warmup < 1 or repetitions < 1:
+                msg = ("Invalid values for the --huntrleaks/-R parameters. The "
+                       "number of warmups and repetitions must be at least 1 "
+                       "each (1:1).")
+                print(msg, file=sys.stderr, flush=True)
+                sys.exit(2)
+
+        if ns.tempdir:
+            ns.tempdir = os.path.expanduser(ns.tempdir)
+
+        self.ns = ns
 
     def find_tests(self, tests):
         self.tests = tests
@@ -488,10 +503,6 @@ class Regrtest:
             self.run_tests_sequential()
 
     def finalize(self):
-        if self.win_load_tracker is not None:
-            self.win_load_tracker.close()
-            self.win_load_tracker = None
-
         if self.next_single_filename:
             if self.next_single_test:
                 with open(self.next_single_filename, 'w') as fp:
@@ -537,7 +548,7 @@ class Regrtest:
             for s in ET.tostringlist(root):
                 f.write(s)
 
-    def create_temp_dir(self):
+    def set_temp_dir(self):
         if self.ns.tempdir:
             self.tmp_dir = self.ns.tempdir
 
@@ -558,6 +569,8 @@ class Regrtest:
                 self.tmp_dir = tempfile.gettempdir()
 
         self.tmp_dir = os.path.abspath(self.tmp_dir)
+
+    def create_temp_dir(self):
         os.makedirs(self.tmp_dir, exist_ok=True)
 
         # Define a writable temp dir that will be used as cwd while running
@@ -565,27 +578,54 @@ class Regrtest:
         # testing (see the -j option).
         pid = os.getpid()
         if self.worker_test_name is not None:
-            test_cwd = 'worker_{}'.format(pid)
+            test_cwd = 'test_python_worker_{}'.format(pid)
         else:
             test_cwd = 'test_python_{}'.format(pid)
         test_cwd = os.path.join(self.tmp_dir, test_cwd)
         return test_cwd
 
+    def cleanup(self):
+        import glob
+
+        path = os.path.join(self.tmp_dir, 'test_python_*')
+        print("Cleanup %s directory" % self.tmp_dir)
+        for name in glob.glob(path):
+            if os.path.isdir(name):
+                print("Remove directory: %s" % name)
+                support.rmtree(name)
+            else:
+                print("Remove file: %s" % name)
+                support.unlink(name)
+
     def main(self, tests=None, **kwargs):
-        self.ns = self.parse_args(kwargs)
+        self.parse_args(kwargs)
+
+        self.set_temp_dir()
+
+        if self.ns.cleanup:
+            self.cleanup()
+            sys.exit(0)
 
         test_cwd = self.create_temp_dir()
 
-        # 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):
-            # When using multiprocessing, worker processes will use test_cwd
-            # as their parent temporary directory. So when the main process
-            # exit, it removes also subdirectories of worker processes.
-            self.ns.tempdir = test_cwd
-            self._main(tests, kwargs)
+        try:
+            # 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):
+                # When using multiprocessing, worker processes will use test_cwd
+                # as their parent temporary directory. So when the main process
+                # exit, it removes also subdirectories of worker processes.
+                self.ns.tempdir = test_cwd
+
+                self._main(tests, kwargs)
+        except SystemExit as exc:
+            # bpo-38203: Python can hang at exit in Py_Finalize(), especially
+            # on threading._shutdown() call: put a timeout
+            faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True)
+
+            sys.exit(exc.code)
 
     def getloadavg(self):
         if self.win_load_tracker is not None:
@@ -597,15 +637,6 @@ class Regrtest:
         return None
 
     def _main(self, tests, kwargs):
-        if self.ns.huntrleaks:
-            warmup, repetitions, _ = self.ns.huntrleaks
-            if warmup < 1 or repetitions < 1:
-                msg = ("Invalid values for the --huntrleaks/-R parameters. The "
-                       "number of warmups and repetitions must be at least 1 "
-                       "each (1:1).")
-                print(msg, file=sys.stderr, flush=True)
-                sys.exit(2)
-
         if self.worker_test_name is not None:
             from test.libregrtest.runtest_mp import run_tests_worker
             run_tests_worker(self.ns, self.worker_test_name)
@@ -639,11 +670,16 @@ class Regrtest:
                 # typeperf.exe for x64, x86 or ARM
                 print(f'Failed to create WindowsLoadTracker: {error}')
 
-        self.run_tests()
-        self.display_result()
+        try:
+            self.run_tests()
+            self.display_result()
 
-        if self.ns.verbose2 and self.bad:
-            self.rerun_failed_tests()
+            if self.ns.verbose2 and self.bad:
+                self.rerun_failed_tests()
+        finally:
+            if self.win_load_tracker is not None:
+                self.win_load_tracker.close()
+                self.win_load_tracker = None
 
         self.finalize()
 
index a43b7666cd1e35707ad048e161553064dd3ef1dd..e7dce180cb37535a2af2ae646c9e074436189d5c 100644 (file)
@@ -13,7 +13,7 @@ import unittest
 from test import support
 from test.libregrtest.refleak import dash_R, clear_caches
 from test.libregrtest.save_env import saved_test_environment
-from test.libregrtest.utils import print_warning
+from test.libregrtest.utils import format_duration, print_warning
 
 
 # Test result constants.
@@ -25,6 +25,7 @@ RESOURCE_DENIED = -3
 INTERRUPTED = -4
 CHILD_ERROR = -5   # error in a child process
 TEST_DID_NOT_RUN = -6
+TIMEOUT = -7
 
 _FORMAT_TEST_RESULT = {
     PASSED: '%s passed',
@@ -35,6 +36,7 @@ _FORMAT_TEST_RESULT = {
     INTERRUPTED: '%s interrupted',
     CHILD_ERROR: '%s crashed',
     TEST_DID_NOT_RUN: '%s run no tests',
+    TIMEOUT: '%s timed out',
 }
 
 # Minimum duration of a test to display its duration or to mention that
@@ -75,7 +77,10 @@ def is_failed(result, ns):
 
 def format_test_result(result):
     fmt = _FORMAT_TEST_RESULT.get(result.result, "%s")
-    return fmt % result.test_name
+    text = fmt % result.test_name
+    if result.result == TIMEOUT:
+        text = '%s (%s)' % (text, format_duration(result.test_time))
+    return text
 
 
 def findtestdir(path=None):
@@ -179,6 +184,7 @@ def runtest(ns, test_name):
         FAILED           test failed
         PASSED           test passed
         EMPTY_TEST_SUITE test ran no subtests.
+        TIMEOUT          test timed out.
 
     If ns.xmlpath is not None, xml_data is a list containing each
     generated testsuite element.
index aa2409b4ef7985f3f887ae118233eee7c66d847e..38b05781de5fc7538919d3b83375f73a532efbec 100644 (file)
@@ -13,13 +13,14 @@ from test import support
 
 from test.libregrtest.runtest import (
     runtest, INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME,
-    format_test_result, TestResult, is_failed)
+    format_test_result, TestResult, is_failed, TIMEOUT)
 from test.libregrtest.setup import setup_tests
-from test.libregrtest.utils import format_duration
+from test.libregrtest.utils import format_duration, print_warning
 
 
 # Display the running tests if nothing happened last N seconds
 PROGRESS_UPDATE = 30.0   # seconds
+assert PROGRESS_UPDATE >= PROGRESS_MIN_TIME
 
 # Time to wait until a worker completes: should be immediate
 JOIN_TIMEOUT = 30.0   # seconds
@@ -102,22 +103,28 @@ class ExitThread(Exception):
     pass
 
 
-class MultiprocessThread(threading.Thread):
-    def __init__(self, pending, output, ns):
+class TestWorkerProcess(threading.Thread):
+    def __init__(self, worker_id, pending, output, ns, timeout):
         super().__init__()
+        self.worker_id = worker_id
         self.pending = pending
         self.output = output
         self.ns = ns
+        self.timeout = timeout
         self.current_test_name = None
         self.start_time = None
         self._popen = None
         self._killed = False
+        self._stopped = False
 
     def __repr__(self):
-        info = ['MultiprocessThread']
-        test = self.current_test_name
+        info = [f'TestWorkerProcess #{self.worker_id}']
         if self.is_alive():
-            info.append('alive')
+            dt = time.monotonic() - self.start_time
+            info.append("running for %s" % format_duration(dt))
+        else:
+            info.append('stopped')
+        test = self.current_test_name
         if test:
             info.append(f'test={test}')
         popen = self._popen
@@ -125,54 +132,103 @@ class MultiprocessThread(threading.Thread):
             info.append(f'pid={popen.pid}')
         return '<%s>' % ' '.join(info)
 
-    def kill(self):
+    def _kill(self):
+        if self._killed:
+            return
         self._killed = True
 
         popen = self._popen
         if popen is None:
             return
-        popen.kill()
-        # stdout and stderr must be closed to ensure that communicate()
-        # does not hang
-        popen.stdout.close()
-        popen.stderr.close()
 
-    def _runtest(self, test_name):
+        print(f"Kill {self}", file=sys.stderr, flush=True)
         try:
-            self.start_time = time.monotonic()
-            self.current_test_name = test_name
+            popen.kill()
+        except OSError as exc:
+            print_warning(f"Failed to kill {self}: {exc!r}")
+
+    def stop(self):
+        # Method called from a different thread to stop this thread
+        self._stopped = True
+        self._kill()
+
+    def mp_result_error(self, test_name, error_type, stdout='', stderr='',
+                        err_msg=None):
+        test_time = time.monotonic() - self.start_time
+        result = TestResult(test_name, error_type, test_time, None)
+        return MultiprocessResult(result, stdout, stderr, err_msg)
 
+    def _timedout(self, test_name):
+        self._kill()
+
+        stdout = stderr = ''
+        popen = self._popen
+        try:
+            stdout, stderr = popen.communicate(timeout=JOIN_TIMEOUT)
+        except (subprocess.TimeoutExpired, OSError) as exc:
+            print_warning(f"Failed to read {self} output "
+                          f"(timeout={format_duration(JOIN_TIMEOUT)}): "
+                          f"{exc!r}")
+
+        return self.mp_result_error(test_name, TIMEOUT, stdout, stderr)
+
+    def _run_process(self, test_name):
+        self.start_time = time.monotonic()
+
+        self.current_test_name = test_name
+        try:
+            self._killed = False
             self._popen = run_test_in_subprocess(test_name, self.ns)
             popen = self._popen
-            with popen:
-                try:
-                    if self._killed:
-                        # If kill() has been called before self._popen is set,
-                        # self._popen is still running. Call again kill()
-                        # to ensure that the process is killed.
-                        self.kill()
-                        raise ExitThread
-
-                    try:
-                        stdout, stderr = popen.communicate()
-                    except OSError:
-                        if self._killed:
-                            # kill() has been called: communicate() fails
-                            # on reading closed stdout/stderr
-                            raise ExitThread
-                        raise
-                except:
-                    self.kill()
-                    popen.wait()
-                    raise
-
-            retcode = popen.wait()
-        finally:
+        except:
             self.current_test_name = None
+            raise
+
+        try:
+            if self._stopped:
+                # If kill() has been called before self._popen is set,
+                # self._popen is still running. Call again kill()
+                # to ensure that the process is killed.
+                self._kill()
+                raise ExitThread
+
+            try:
+                stdout, stderr = popen.communicate(timeout=self.timeout)
+            except subprocess.TimeoutExpired:
+                if self._stopped:
+                    # kill() has been called: communicate() fails
+                    # on reading closed stdout/stderr
+                    raise ExitThread
+
+                return self._timedout(test_name)
+            except OSError:
+                if self._stopped:
+                    # kill() has been called: communicate() fails
+                    # on reading closed stdout/stderr
+                    raise ExitThread
+                raise
+
+            retcode = popen.returncode
+            stdout = stdout.strip()
+            stderr = stderr.rstrip()
+
+            return (retcode, stdout, stderr)
+        except:
+            self._kill()
+            raise
+        finally:
+            self._wait_completed()
             self._popen = None
+            self.current_test_name = None
+
+    def _runtest(self, test_name):
+        result = self._run_process(test_name)
 
-        stdout = stdout.strip()
-        stderr = stderr.rstrip()
+        if isinstance(result, MultiprocessResult):
+            # _timedout() case
+            return result
+
+        retcode, stdout, stderr = result
 
         err_msg = None
         if retcode != 0:
@@ -191,13 +247,12 @@ class MultiprocessThread(threading.Thread):
                     err_msg = "Failed to parse worker JSON: %s" % exc
 
         if err_msg is not None:
-            test_time = time.monotonic() - self.start_time
-            result = TestResult(test_name, CHILD_ERROR, test_time, None)
+            return self.mp_result_error(test_name, CHILD_ERROR, stdout, stderr, err_msg)
 
         return MultiprocessResult(result, stdout, stderr, err_msg)
 
     def run(self):
-        while not self._killed:
+        while not self._stopped:
             try:
                 try:
                     test_name = next(self.pending)
@@ -215,6 +270,33 @@ class MultiprocessThread(threading.Thread):
                 self.output.put((True, traceback.format_exc()))
                 break
 
+    def _wait_completed(self):
+        popen = self._popen
+
+        # stdout and stderr must be closed to ensure that communicate()
+        # does not hang
+        popen.stdout.close()
+        popen.stderr.close()
+
+        try:
+            popen.wait(JOIN_TIMEOUT)
+        except (subprocess.TimeoutExpired, OSError) as exc:
+            print_warning(f"Failed to wait for {self} completion "
+                          f"(timeout={format_duration(JOIN_TIMEOUT)}): "
+                          f"{exc!r}")
+
+    def wait_stopped(self, start_time):
+        while True:
+            # Write a message every second
+            self.join(1.0)
+            if not self.is_alive():
+                break
+            dt = time.monotonic() - start_time
+            print(f"Waiting for {self} thread for {format_duration(dt)}", flush=True)
+            if dt > JOIN_TIMEOUT:
+                print_warning(f"Failed to join {self} in {format_duration(dt)}")
+                break
+
 
 def get_running(workers):
     running = []
@@ -229,41 +311,33 @@ def get_running(workers):
     return running
 
 
-class MultiprocessRunner:
+class MultiprocessTestRunner:
     def __init__(self, regrtest):
         self.regrtest = regrtest
         self.ns = regrtest.ns
         self.output = queue.Queue()
         self.pending = MultiprocessIterator(self.regrtest.tests)
         if self.ns.timeout is not None:
-            self.test_timeout = self.ns.timeout * 1.5
+            self.worker_timeout = self.ns.timeout * 1.5
         else:
-            self.test_timeout = None
+            self.worker_timeout = None
         self.workers = None
 
     def start_workers(self):
-        self.workers = [MultiprocessThread(self.pending, self.output, self.ns)
-                        for _ in range(self.ns.use_mp)]
+        self.workers = [TestWorkerProcess(index, self.pending, self.output,
+                                          self.ns, self.worker_timeout)
+                        for index in range(1, self.ns.use_mp + 1)]
         print("Run tests in parallel using %s child processes"
               % len(self.workers))
         for worker in self.workers:
             worker.start()
 
-    def wait_workers(self):
+    def stop_workers(self):
         start_time = time.monotonic()
         for worker in self.workers:
-            worker.kill()
+            worker.stop()
         for worker in self.workers:
-            while True:
-                worker.join(1.0)
-                if not worker.is_alive():
-                    break
-                dt = time.monotonic() - start_time
-                print("Wait for regrtest worker %r for %.1f sec" % (worker, dt))
-                if dt > JOIN_TIMEOUT:
-                    print("Warning -- failed to join a regrtest worker %s"
-                          % worker)
-                    break
+            worker.wait_stopped(start_time)
 
     def _get_result(self):
         if not any(worker.is_alive() for worker in self.workers):
@@ -273,12 +347,13 @@ class MultiprocessRunner:
             except queue.Empty:
                 return None
 
+        use_faulthandler = (self.ns.timeout is not None)
+        timeout = PROGRESS_UPDATE
         while True:
-            if self.test_timeout is not None:
-                faulthandler.dump_traceback_later(self.test_timeout, exit=True)
+            if use_faulthandler:
+                faulthandler.dump_traceback_later(timeout * 2.0, exit=True)
 
             # wait for a thread
-            timeout = max(PROGRESS_UPDATE, PROGRESS_MIN_TIME)
             try:
                 return self.output.get(timeout=timeout)
             except queue.Empty:
@@ -343,13 +418,14 @@ class MultiprocessRunner:
             print()
             self.regrtest.interrupted = True
         finally:
-            if self.test_timeout is not None:
+            if self.ns.timeout is not None:
                 faulthandler.cancel_dump_traceback_later()
 
-        # a test failed (and --failfast is set) or all tests completed
-        self.pending.stop()
-        self.wait_workers()
+            # Always ensure that all worker processes are no longer
+            # worker when we exit this function
+            self.pending.stop()
+            self.stop_workers()
 
 
 def run_tests_multiprocess(regrtest):
-    MultiprocessRunner(regrtest).run_tests()
+    MultiprocessTestRunner(regrtest).run_tests()
index adfe278ba39bf22c9ced510eee10b805eb54922f..f0c17b906f51923f581f4adb42a883c8ff4247a8 100644 (file)
@@ -3,28 +3,36 @@ import msvcrt
 import os
 import subprocess
 import uuid
+import winreg
 from test import support
+from test.libregrtest.utils import print_warning
 
 
 # Max size of asynchronous reads
 BUFSIZE = 8192
 # Exponential damping factor (see below)
 LOAD_FACTOR_1 = 0.9200444146293232478931553241
+
 # Seconds per measurement
 SAMPLING_INTERVAL = 5
-COUNTER_NAME = r'\System\Processor Queue Length'
+# Windows registry subkey of HKEY_LOCAL_MACHINE where the counter names
+# of typeperf are registered
+COUNTER_REGISTRY_KEY = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion"
+                        r"\Perflib\CurrentLanguage")
 
 
 class WindowsLoadTracker():
     """
     This class asynchronously interacts with the `typeperf` command to read
-    the system load on Windows. Mulitprocessing and threads can't be used
+    the system load on Windows. Multiprocessing and threads can't be used
     here because they interfere with the test suite's cases for those
     modules.
     """
 
     def __init__(self):
         self.load = 0.0
+        self.counter_name = ''
+        self.popen = None
         self.start()
 
     def start(self):
@@ -54,31 +62,46 @@ class WindowsLoadTracker():
         overlap.GetOverlappedResult(True)
 
         # Spawn off the load monitor
-        command = ['typeperf', COUNTER_NAME, '-si', str(SAMPLING_INTERVAL)]
-        self.p = subprocess.Popen(command, stdout=command_stdout, cwd=support.SAVEDCWD)
+        counter_name = self._get_counter_name()
+        command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)]
+        self.popen = subprocess.Popen(' '.join(command), stdout=command_stdout, cwd=support.SAVEDCWD)
 
         # Close our copy of the write end of the pipe
         os.close(command_stdout)
 
+    def _get_counter_name(self):
+        # accessing the registry to get the counter localization name
+        with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, COUNTER_REGISTRY_KEY) as perfkey:
+            counters = winreg.QueryValueEx(perfkey, 'Counter')[0]
+
+        # Convert [key1, value1, key2, value2, ...] list
+        # to {key1: value1, key2: value2, ...} dict
+        counters = iter(counters)
+        counters_dict = dict(zip(counters, counters))
+
+        # System counter has key '2' and Processor Queue Length has key '44'
+        system = counters_dict['2']
+        process_queue_length = counters_dict['44']
+        return f'"\\{system}\\{process_queue_length}"'
+
     def close(self):
-        if self.p is None:
+        if self.popen is None:
             return
-        self.p.kill()
-        self.p.wait()
-        self.p = None
+        self.popen.kill()
+        self.popen.wait()
+        self.popen = None
 
     def __del__(self):
         self.close()
 
     def read_output(self):
-        import _winapi
-
         overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True)
         bytes_read, res = overlapped.GetOverlappedResult(False)
         if res != 0:
             return
 
-        return overlapped.getbuffer().decode()
+        output = overlapped.getbuffer()
+        return output.decode('oem', 'replace')
 
     def getloadavg(self):
         typeperf_output = self.read_output()
@@ -88,14 +111,29 @@ class WindowsLoadTracker():
 
         # Process the backlog of load values
         for line in typeperf_output.splitlines():
+            # Ignore the initial header:
+            # "(PDH-CSV 4.0)","\\\\WIN\\System\\Processor Queue Length"
+            if '\\\\' in line:
+                continue
+
+            # Ignore blank lines
+            if not line.strip():
+                continue
+
             # typeperf outputs in a CSV format like this:
             # "07/19/2018 01:32:26.605","3.000000"
-            toks = line.split(',')
-            # Ignore blank lines and the initial header
-            if line.strip() == '' or (COUNTER_NAME in line) or len(toks) != 2:
+            # (date, process queue length)
+            try:
+                tokens = line.split(',')
+                if len(tokens) != 2:
+                    raise ValueError
+
+                value = tokens[1].replace('"', '')
+                load = float(value)
+            except ValueError:
+                print_warning("Failed to parse typeperf output: %a" % line)
                 continue
 
-            load = float(toks[1].replace('"', ''))
             # We use an exponentially weighted moving average, imitating the
             # load calculation on Unix systems.
             # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation
index 362276583f500050b62870f4cc9cd169bd7de23e..41b5f46c882ca3efe3ea76991eac0a49a15398e7 100644 (file)
@@ -206,8 +206,8 @@ if __name__ == '__main__':
     with open('ssl_key.pem', 'w') as f:
         f.write(key)
     print("password protecting ssl_key.pem in ssl_key.passwd.pem")
-    check_call(['openssl','rsa','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-des3','-passout','pass:somepass'])
-    check_call(['openssl','rsa','-in','ssl_key.pem','-out','keycert.passwd.pem','-des3','-passout','pass:somepass'])
+    check_call(['openssl','pkey','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-aes256','-passout','pass:somepass'])
+    check_call(['openssl','pkey','-in','ssl_key.pem','-out','keycert.passwd.pem','-aes256','-passout','pass:somepass'])
 
     with open('keycert.pem', 'w') as f:
         f.write(key)
index e4f1370ab270c85af561d552182ad2da41a3d895..46de61ab85b1369394d240a20c8449430acdc373 100644 (file)
@@ -1,42 +1,42 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,8064BE1494B24B13
-
-KJrffOMbo8M0I3PzcYxRZGMpKD1yB3Ii4+bT5XoanxjIJ+4fdx6LfZ0Rsx+riyzs
-tymsQu/iYY9j+4rCvN9+eetsL1X6iZpiimKsLexcid9M3fb0vxED5Sgw0dvunCUA
-xhqjLIKR92MKbODHf6KrDKCpsiPbjq4gZ7P+uCGXAMHL3MXIJSC0hW9rK7Ce6oyO
-CjpIcgB8x+GUWZZZhAFdlzIHMZrteNP2P5HK6QcaT71P034Dz1hhqoj4Q0t+Fta2
-4tfsM/bnTR/l6hwlhPa1e3Uj322tDTDWBScgWANn5+sEWldLmozMaWhZsn22pfk2
-KjRMGXG024JVheV882nbdOBvG7oq+lxkZ/ZP+vvqJqnvYtf7WtM8UivzYpe5Hz5b
-kVvWzPjBLUSZ9whM9rDLqSSqMPyPvDTuEmLkuq+xm7pYJmsLqIMP2klZLqRxLX6K
-uqwplb8UG440qauxgnQ905PId1l2fJEnRtV+7vXprA0L0QotgXLVHBhLmTFM+3PH
-9H3onf31dionUAPrn3nfVE36HhvVgRyvDBnBzJSIMighgq21Qx/d1dk0DRYi1hUI
-nCHl0YJPXheVcXR7JiSF2XQCAaFuS1Mr7NCXfWZOZQC/0dkvmHnl9DUAhuqq9BNZ
-1cKhZXcKHadg2/r0Zup/oDzmHPUEfTAXT0xbqoWlhkdwbF2veWQ96A/ncx3ISTb4
-PkXBlX9rdia8nmtyQDQRn4NuvchbaGkj4WKFC8pF8Hn7naHqwjpHaDUimBc0CoQW
-edNJqruKWwtSVLuwKHCC2gZFX9AXSKJXJz/QRSUlhFGOhuF/J6yKaXj6n5lxWNiQ
-54J+OP/hz2aS95CD2+Zf1SKpxdWiLZSIQqESpmmUrXROixNJZ/Z7gI74Dd9dSJOH
-W+3AU03vrrFZVrJVZhjcINHoH1Skh6JKscH18L6x4U868nSr4SrRLX8BhHllOQyD
-bmU+PZAjF8ZBIaCtTGulDXD29F73MeAZeTSsgQjFu0iKLj1wPiphbx8i/SUtR4YP
-X6PVA04g66r1NBw+3RQASVorZ3g1MSFvITHXcbKkBDeJH2z1+c6t/VVyTONnQhM5
-lLgRSk6HCbetvT9PKxWrWutA12pdBYEHdZhMHVf2+xclky7l09w8hg2/qqcdGRGe
-oAOZ72t0l5ObNyaruDKUS6f4AjOyWq/Xj5xuFtf1n3tQHyslSyCTPcAbQhDfTHUx
-vixb/V9qvYPt7OCn8py7v1M69NH42QVFAvwveDIFjZdqfIKBoJK2V4qPoevJI6uj
-Q5ByMt8OXOjSXNpHXpYQWUiWeCwOEBXJX8rzCHdMtg37jJ0zCmeErR1NTdg+EujM
-TWYgd06jlT67tURST0aB2kg4ijKgUJefD313LW1zC6gVsTbjSZxYyRbPfSP6flQB
-yCi1C19E2OsgleqbkBVC5GlYUzaJT7SGjCRmGx1eqtbrALu+LVH24Wceexlpjydl
-+s2nf/DZlKun/tlPh6YioifPCJjByZMQOCEfIox6BkemZETz8uYA4TTWimG13Z03
-gyDGC2jdpEW414J2qcQDvrdUgJ+HlhrAAHaWpMQDbXYxBGoZ+3+ORvQV4kAsCwL8
-k3EIrVpePdik+1xgOWsyLj6QxFXlTMvL6Wc5pnArFPORsgHEolJvxSPTf9aAHNPn
-V2WBvxiLBtYpGrujAUM40Syx/aN2RPtcXYPAusHUBw+S8/p+/8Kg8GZmnIXG3F89
-45Eepl2quZYIrou7a1fwIpIIZ0hFiBQ1mlHVMFtxwVHS1bQb3SU2GeO+JcGjdVXc
-04qeGuQ5M164eQ5C0T7ZQ1ULiUlFWKD30m+cjqmZzt3d7Q0mKpMKuESIuZJo/wpD
-Nas432aLKUhcNx/pOYLkKJRpGZKOupQoD5iUj/j44o8JoFkDK33v2S57XB5QGz28
-9Zuhx49b3W8mbM6EBanlQKLWJGCxXqc/jhYhFWn+b0MhidynFgA0oeWvf6ZDyt6H
-Yi5Etxsar09xp0Do3NxtQXLuSUu0ji2pQzSIKuoqQWKqldm6VrpwojiqJhy4WQBQ
-aVVyFeWBC7G3Zj76dO+yp2sfJ0itJUQ8AIB9Cg0f34rEZu+r9luPmqBoUeL95Tk7
-YvCOU3Jl8Iqysv8aNpVXT8sa8rrSbruWCByEePZ37RIdHLMVBwVY0eVaFQjrjU7E
-mXmM9eaoYLfXOllsQ+M2+qPFUITr/GU3Qig13DhK/+yC1R6V2a0l0WRhMltIPYKW
-Ztvvr4hK5LcYCeS113BLiMbDIMMZZYGDZGMdC8DnnVbT2loF0Rfmp80Af31KmMQ4
-6XvMatW9UDjBoY5a/YMpdm7SRwm+MgV2KNPpc2kST87/yi9oprGAb8qiarHiHTM0
------END RSA PRIVATE KEY-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIHbTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI072N7W+PDDMCAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBA/AuaRNi4vE4KGqI4In+70BIIH
+ENGS5Vex5NID873frmd1UZEHZ+O/Bd0wDb+NUpIqesHkRYf7kKi6Gnr+nKQ/oVVn
+Lm3JjE7c8ECP0OkOOXmiXuWL1SkzBBWqCI4stSGUPvBiHsGwNnvJAaGjUffgMlcC
+aJOA2+dnejLkzblq4CB2LQdm06N3Xoe9tyqtQaUHxfzJAf5Ydd8uj7vpKN2MMhY7
+icIPJwSyh0N7S6XWVtHEokr9Kp4y2hS5a+BgCWV1/1z0aF7agnSVndmT1VR+nWmc
+lM14k+lethmHMB+fsNSjnqeJ7XOPlOTHqhiZ9bBSTgF/xr5Bck/NiKRzHjdovBox
+TKg+xchaBhpRh7wBPBIlNJeHmIjv+8obOKjKU98Ig/7R9+IryZaNcKAH0PuOT+Sw
+QHXiCGQbOiYHB9UyhDTWiB7YVjd8KHefOFxfHzOQb/iBhbv1x3bTl3DgepvRN6VO
+dIsPLoIZe42sdf9GeMsk8mGJyZUQ6AzsfhWk3grb/XscizPSvrNsJ2VL1R7YTyT3
+3WA4ZXR1EqvXnWL7N/raemQjy62iOG6t7fcF5IdP9CMbWP+Plpsz4cQW7FtesCTq
+a5ZXraochQz361ODFNIeBEGU+0qqXUtZDlmos/EySkZykSeU/L0bImS62VGE3afo
+YXBmznTTT9kkFkqv7H0MerfJsrE/wF8puP3GM01DW2JRgXRpSWlvbPV/2LnMtRuD
+II7iH4rWDtTjCN6BWKAgDOnPkc9sZ4XulqT32lcUeV6LTdMBfq8kMEc8eDij1vUT
+maVCRpuwaq8EIT3lVgNLufHiG96ojlyYtj3orzw22IjkgC/9ee8UDik9CqbMVmFf
+fVHhsw8LNSg8Q4bmwm5Eg2w2it2gtI68+mwr75oCxuJ/8OMjW21Prj8XDh5reie2
+c0lDKQOFZ9UnLU1bXR/6qUM+JFKR4DMq+fOCuoQSVoyVUEOsJpvBOYnYZN9cxsZm
+vh9dKafMEcKZ8flsbr+gOmOw7+Py2ifSlf25E/Frb1W4gtbTb0LQVHb6+drutrZj
+8HEu4CnHYFCD4ZnOJb26XlZCb8GFBddW86yJYyUqMMV6Q1aJfAOAglsTo1LjIMOZ
+byo0BTAmwUevU/iuOXQ4qRBXXcoidDcTCrxfUSPG9wdt9l+m5SdQpWqfQ+fx5O7m
+SLlrHyZCiPSFMtC9DxqjIklHjf5W3wslGLgaD30YXa4VDYkRihf3CNsxGQ+tVvef
+l0ZjoAitF7Gaua06IESmKnpHe23dkr1cjYq+u2IV+xGH8LeExdwsQ9kpuTeXPnQs
+JOA99SsFx1ct32RrwjxnDDsiNkaViTKo9GDkV3jQTfoFgAVqfSgg9wGXpqUqhNG7
+TiSIHCowllLny2zn4XrXCy2niD3VDt0skb3l/PaegHE2z7S5YY85nQtYwpLiwB9M
+SQ08DYKxPBZYKtS2iZ/fsA1gjSRQDPg/SIxMhUC3M3qH8iWny1Lzl25F2Uq7VVEX
+LdTUtaby49jRTT3CQGr5n6z7bMbUegiY7h8WmOekuThGDH+4xZp6+rDP4GFk4FeK
+JcF70vMQYIjQZhadic6olv+9VtUP42ltGG/yP9a3eWRkzfAf2eCh6B1rYdgEWwE8
+rlcZzwM+y6eUmeNF2FVWB8iWtTMQHy+dYNPM+Jtus1KQKxiiq/yCRs7nWvzWRFWA
+HRyqV0J6/lqgm4FvfktFt1T0W+mDoLJOR2/zIwMy2lgL5zeHuR3SaMJnCikJbqKS
+HB3UvrhAWUcZqdH29+FhVWeM7ybyF1Wccmf+IIC/ePLa6gjtqPV8lG/5kbpcpnB6
+UQY8WWaKMxyr3jJ9bAX5QKshchp04cDecOLZrpFGNNQngR8RxSEkiIgAqNxWunIu
+KrdBDrupv/XAgEOclmgToY3iywLJSV5gHAyHWDUhRH4cFCLiGPl4XIcnXOuTze3H
+3j+EYSiS3v3DhHjp33YU2pXlJDjiYsKzAXejEh66++Y8qaQdCAad3ruWRCzW3kgk
+Md0A1VGzntTnQsewvExQEMZH2LtYIsPv3KCYGeSAuLabX4tbGk79PswjnjLLEOr0
+Ghf6RF6qf5/iFyJoG4vrbKT8kx6ywh0InILCdjUunuDskIBxX6tEcr9XwajoIvb2
+kcmGdjam5kKLS7QOWQTl8/r/cuFes0dj34cX5Qpq+Gd7tRq/D+b0207926Cxvftv
+qQ1cVn8HiLxKkZzd3tpf2xnoV1zkTL0oHrNg+qzxoxXUTUcwtIf1d/HRbYEAhi/d
+bBBoFeftEHWNq+sJgS9bH+XNzo/yK4u04B5miOq8v4CSkJdzu+ZdF22d4cjiGmtQ
+8BTmcn0Unzm+u5H0+QSZe54QBHJGNXXOIKMTkgnOdW27g4DbI1y7fCqJiSMbRW6L
+oHmMfbdB3GWqGbsUkhY8i6h9op0MU6WOX7ea2Rxyt4t6
+-----END ENCRYPTED PRIVATE KEY-----
index 87bfa9f546272e8dfa847c9d0933e2440b001649..d04d19985f7a052ccb73e23f824a224a7d87d57e 100644 (file)
@@ -109,6 +109,7 @@ __all__ = [
     "run_with_locale", "swap_item",
     "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict",
     "run_with_tz", "PGO", "missing_compiler_executable", "fd_count",
+    "ALWAYS_EQ", "LARGEST", "SMALLEST"
     ]
 
 class Error(Exception):
@@ -1422,6 +1423,9 @@ def get_socket_conn_refused_errs():
         # bpo-31910: socket.create_connection() fails randomly
         # with EADDRNOTAVAIL on Travis CI
         errors.append(errno.EADDRNOTAVAIL)
+    if hasattr(errno, 'EHOSTUNREACH'):
+        # bpo-37583: The destination host cannot be reached
+        errors.append(errno.EHOSTUNREACH)
     return errors
 
 
@@ -2806,7 +2810,7 @@ def fd_count():
     if sys.platform.startswith(('linux', 'freebsd')):
         try:
             names = os.listdir("/proc/self/fd")
-            # Substract one because listdir() opens internally a file
+            # Subtract one because listdir() internally opens a file
             # descriptor to list the content of the /proc/self/fd/ directory.
             return len(names) - 1
         except FileNotFoundError:
@@ -2919,3 +2923,39 @@ class FakePath:
             raise self.path
         else:
             return self.path
+
+
+class _ALWAYS_EQ:
+    """
+    Object that is equal to anything.
+    """
+    def __eq__(self, other):
+        return True
+    def __ne__(self, other):
+        return False
+
+ALWAYS_EQ = _ALWAYS_EQ()
+
+@functools.total_ordering
+class _LARGEST:
+    """
+    Object that is greater than anything (except itself).
+    """
+    def __eq__(self, other):
+        return isinstance(other, _LARGEST)
+    def __lt__(self, other):
+        return False
+
+LARGEST = _LARGEST()
+
+@functools.total_ordering
+class _SMALLEST:
+    """
+    Object that is less than anything (except itself).
+    """
+    def __eq__(self, other):
+        return isinstance(other, _SMALLEST)
+    def __gt__(self, other):
+        return False
+
+SMALLEST = _SMALLEST()
index 51f0effaf2ff65e71694f0db2e38d9aebf80a3dd..3cdaff61c7cc3d69e57448992d161c20d10d9f31 100644 (file)
@@ -2772,6 +2772,46 @@ class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase):
           -c          c help
         '''
 
+class TestMutuallyExclusiveNested(MEMixin, TestCase):
+
+    def get_parser(self, required):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('-a')
+        group.add_argument('-b')
+        group2 = group.add_mutually_exclusive_group(required=required)
+        group2.add_argument('-c')
+        group2.add_argument('-d')
+        group3 = group2.add_mutually_exclusive_group(required=required)
+        group3.add_argument('-e')
+        group3.add_argument('-f')
+        return parser
+
+    usage_when_not_required = '''\
+        usage: PROG [-h] [-a A | -b B | [-c C | -d D | [-e E | -f F]]]
+        '''
+    usage_when_required = '''\
+        usage: PROG [-h] (-a A | -b B | (-c C | -d D | (-e E | -f F)))
+        '''
+
+    help = '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -a A
+          -b B
+          -c C
+          -d D
+          -e E
+          -f F
+        '''
+
+    # We are only interested in testing the behavior of format_usage().
+    test_failures_when_not_required = None
+    test_failures_when_required = None
+    test_successes_when_not_required = None
+    test_successes_when_required = None
+
 # =================================================
 # Mutually exclusive group in parent parser tests
 # =================================================
index 72f8467847e8dc468a8c419b6c5d0647b6bf01a8..2d0b5b24ee7dc2a2e3a37a6cf6a395ea34fc7e43 100644 (file)
@@ -4,6 +4,7 @@ import os
 import sys
 import unittest
 import weakref
+from textwrap import dedent
 
 from test import support
 
@@ -461,6 +462,35 @@ class ASTHelpers_Test(unittest.TestCase):
             "lineno=1, col_offset=0), lineno=1, col_offset=0)])"
         )
 
+    def test_dump_incomplete(self):
+        node = ast.Raise(lineno=3, col_offset=4)
+        self.assertEqual(ast.dump(node),
+            "Raise()"
+        )
+        self.assertEqual(ast.dump(node, include_attributes=True),
+            "Raise(lineno=3, col_offset=4)"
+        )
+        node = ast.Raise(exc=ast.Name(id='e', ctx=ast.Load()), lineno=3, col_offset=4)
+        self.assertEqual(ast.dump(node),
+            "Raise(exc=Name(id='e', ctx=Load()))"
+        )
+        self.assertEqual(ast.dump(node, annotate_fields=False),
+            "Raise(Name('e', Load()))"
+        )
+        self.assertEqual(ast.dump(node, include_attributes=True),
+            "Raise(exc=Name(id='e', ctx=Load()), lineno=3, col_offset=4)"
+        )
+        self.assertEqual(ast.dump(node, annotate_fields=False, include_attributes=True),
+            "Raise(Name('e', Load()), lineno=3, col_offset=4)"
+        )
+        node = ast.Raise(cause=ast.Name(id='e', ctx=ast.Load()))
+        self.assertEqual(ast.dump(node),
+            "Raise(cause=Name(id='e', ctx=Load()))"
+        )
+        self.assertEqual(ast.dump(node, annotate_fields=False),
+            "Raise(cause=Name('e', Load()))"
+        )
+
     def test_copy_location(self):
         src = ast.parse('1 + 1', mode='eval')
         src.body.right = ast.copy_location(ast.Num(2), src.body.right)
@@ -1123,6 +1153,44 @@ class ConstantTests(unittest.TestCase):
         self.assertEqual(ast.literal_eval(binop), 10+20j)
 
 
+class NodeVisitorTests(unittest.TestCase):
+    def test_old_constant_nodes(self):
+        class Visitor(ast.NodeVisitor):
+            def visit_Num(self, node):
+                log.append((node.lineno, 'Num', node.n))
+            def visit_Str(self, node):
+                log.append((node.lineno, 'Str', node.s))
+            def visit_Bytes(self, node):
+                log.append((node.lineno, 'Bytes', node.s))
+            def visit_NameConstant(self, node):
+                log.append((node.lineno, 'NameConstant', node.value))
+            def visit_Ellipsis(self, node):
+                log.append((node.lineno, 'Ellipsis', ...))
+        mod = ast.parse(dedent('''\
+            i = 42
+            f = 4.25
+            c = 4.25j
+            s = 'string'
+            b = b'bytes'
+            t = True
+            n = None
+            e = ...
+            '''))
+        visitor = Visitor()
+        log = []
+        visitor.visit(mod)
+        self.assertEqual(log, [
+            (1, 'Num', 42),
+            (2, 'Num', 4.25),
+            (3, 'Num', 4.25j),
+            (4, 'Str', 'string'),
+            (5, 'Bytes', b'bytes'),
+            (6, 'NameConstant', True),
+            (7, 'NameConstant', None),
+            (8, 'Ellipsis', ...),
+        ])
+
+
 def main():
     if __name__ != '__main__':
         return
index 5a36423dc97afa3e8e22ea50f390243d14d823b6..94c2633f330a4c44fdad60c19b16fccad26b22fa 100644 (file)
@@ -1068,6 +1068,28 @@ class AsyncGenAsyncioTest(unittest.TestCase):
         res = self.loop.run_until_complete(run())
         self.assertEqual(res, [i * 2 for i in range(1, 10)])
 
+    def test_asyncgen_nonstarted_hooks_are_cancellable(self):
+        # See https://bugs.python.org/issue38013
+        messages = []
+
+        def exception_handler(loop, context):
+            messages.append(context)
+
+        async def async_iterate():
+            yield 1
+            yield 2
+
+        async def main():
+            loop = asyncio.get_running_loop()
+            loop.set_exception_handler(exception_handler)
+
+            async for i in async_iterate():
+                break
+
+        asyncio.run(main())
+
+        self.assertEqual([], messages)
+
 
 if __name__ == "__main__":
     unittest.main()
index ec171fa83da39f23a379285ea14a00c805888c4a..66a6bc16803142652cd53602fbfa0bb07ba89f9a 100644 (file)
@@ -722,6 +722,7 @@ class UnixReadPipeTransportTests(test_utils.TestCase):
     @mock.patch('os.read')
     def test_resume_reading(self, m_read):
         tr = self.read_pipe_transport()
+        tr.pause_reading()
         tr.resume_reading()
         self.loop.assert_reader(5, tr._read_ready)
 
@@ -776,6 +777,32 @@ class UnixReadPipeTransportTests(test_utils.TestCase):
         self.assertIsNone(tr._protocol)
         self.assertIsNone(tr._loop)
 
+    def test_pause_reading_on_closed_pipe(self):
+        tr = self.read_pipe_transport()
+        tr.close()
+        test_utils.run_briefly(self.loop)
+        self.assertIsNone(tr._loop)
+        tr.pause_reading()
+
+    def test_pause_reading_on_paused_pipe(self):
+        tr = self.read_pipe_transport()
+        tr.pause_reading()
+        # the second call should do nothing
+        tr.pause_reading()
+
+    def test_resume_reading_on_closed_pipe(self):
+        tr = self.read_pipe_transport()
+        tr.close()
+        test_utils.run_briefly(self.loop)
+        self.assertIsNone(tr._loop)
+        tr.resume_reading()
+
+    def test_resume_reading_on_paused_pipe(self):
+        tr = self.read_pipe_transport()
+        # the pipe is not paused
+        # resuming should do nothing
+        tr.resume_reading()
+
 
 class UnixWritePipeTransportTests(test_utils.TestCase):
 
index c3f04ec7447c6ede04cca98ebecfa2bd7cee141a..c60560ea6d3a0a5fef73a8004a70daa82ea6d682 100644 (file)
@@ -154,6 +154,11 @@ class BuiltinTest(unittest.TestCase):
         self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
         self.assertRaises(ValueError, __import__, '')
         self.assertRaises(TypeError, __import__, 'sys', name='sys')
+        # Relative import outside of a package with no __package__ or __spec__ (bpo-37409).
+        with self.assertWarns(ImportWarning):
+            self.assertRaises(ImportError, __import__, '',
+                              {'__package__': None, '__spec__': None, '__name__': '__main__'},
+                              locals={}, fromlist=('foo',), level=1)
         # embedded null character
         self.assertRaises(ModuleNotFoundError, __import__, 'string\x00')
 
@@ -1511,6 +1516,11 @@ class BuiltinTest(unittest.TestCase):
         self.assertRaises(ValueError, x.translate, b"1", 1)
         self.assertRaises(TypeError, x.translate, b"1"*256, 1)
 
+    def test_bytearray_extend_error(self):
+        array = bytearray()
+        bad_iter = map(int, "X")
+        self.assertRaises(ValueError, array.extend, bad_iter)
+
     def test_construct_singletons(self):
         for const in None, Ellipsis, NotImplemented:
             tp = type(const)
index 134f07a17ec13939a73125b777a976ea626d30af..0355547436b2f9366a4977206e7373bcba4356f1 100644 (file)
@@ -100,11 +100,11 @@ _EncodingDetails = namedtuple("EncodingDetails", _fields)
 class EncodingDetails(_EncodingDetails):
     # XXX (ncoghlan): Using JSON for child state reporting may be less fragile
     CHILD_PROCESS_SCRIPT = ";".join([
-        "import sys, os",
-        "print(sys.getfilesystemencoding())",
-        "print(sys.stdin.encoding + ':' + sys.stdin.errors)",
-        "print(sys.stdout.encoding + ':' + sys.stdout.errors)",
-        "print(sys.stderr.encoding + ':' + sys.stderr.errors)",
+        "import sys, os, codecs",
+        "print(codecs.lookup(sys.getfilesystemencoding()).name)",
+        "print(codecs.lookup(sys.stdin.encoding).name + ':' + sys.stdin.errors)",
+        "print(codecs.lookup(sys.stdout.encoding).name + ':' + sys.stdout.errors)",
+        "print(codecs.lookup(sys.stderr.encoding).name + ':' + sys.stderr.errors)",
         "print(os.environ.get('LANG', 'not set'))",
         "print(os.environ.get('LC_CTYPE', 'not set'))",
         "print(os.environ.get('LC_ALL', 'not set'))",
@@ -119,28 +119,15 @@ class EncodingDetails(_EncodingDetails):
         stream_info = 2*[_stream.format("surrogateescape")]
         # stderr should always use backslashreplace
         stream_info.append(_stream.format("backslashreplace"))
-        expected_lang = env_vars.get("LANG", "not set").lower()
+        expected_lang = env_vars.get("LANG", "not set")
         if coercion_expected:
-            expected_lc_ctype = CLI_COERCION_TARGET.lower()
+            expected_lc_ctype = CLI_COERCION_TARGET
         else:
-            expected_lc_ctype = env_vars.get("LC_CTYPE", "not set").lower()
-        expected_lc_all = env_vars.get("LC_ALL", "not set").lower()
+            expected_lc_ctype = env_vars.get("LC_CTYPE", "not set")
+        expected_lc_all = env_vars.get("LC_ALL", "not set")
         env_info = expected_lang, expected_lc_ctype, expected_lc_all
         return dict(cls(fs_encoding, *stream_info, *env_info)._asdict())
 
-    @staticmethod
-    def _handle_output_variations(data):
-        """Adjust the output to handle platform specific idiosyncrasies
-
-        * Some platforms report ASCII as ANSI_X3.4-1968
-        * Some platforms report ASCII as US-ASCII
-        * Some platforms report UTF-8 instead of utf-8
-        """
-        data = data.replace(b"ANSI_X3.4-1968", b"ascii")
-        data = data.replace(b"US-ASCII", b"ascii")
-        data = data.lower()
-        return data
-
     @classmethod
     def get_child_details(cls, env_vars):
         """Retrieves fsencoding and standard stream details from a child process
@@ -160,8 +147,7 @@ class EncodingDetails(_EncodingDetails):
         if not result.rc == 0:
             result.fail(py_cmd)
         # All subprocess outputs in this test case should be pure ASCII
-        adjusted_output = cls._handle_output_variations(result.out)
-        stdout_lines = adjusted_output.decode("ascii").splitlines()
+        stdout_lines = result.out.decode("ascii").splitlines()
         child_encoding_details = dict(cls(*stdout_lines)._asdict())
         stderr_lines = result.err.decode("ascii").rstrip().splitlines()
         return child_encoding_details, stderr_lines
index f4e00c7a72c5d253b9e0f5dc4550cbbae787892f..b46be67f77329959623db5ff052119272dd80aae 100644 (file)
@@ -363,6 +363,23 @@ Larry
         self.assertEqual(fs.list[0].name, 'submit-name')
         self.assertEqual(fs.list[0].value, 'Larry')
 
+    def test_field_storage_multipart_no_content_length(self):
+        fp = BytesIO(b"""--MyBoundary
+Content-Disposition: form-data; name="my-arg"; filename="foo"
+
+Test
+
+--MyBoundary--
+""")
+        env = {
+            "REQUEST_METHOD": "POST",
+            "CONTENT_TYPE": "multipart/form-data; boundary=MyBoundary",
+            "wsgi.input": fp,
+        }
+        fields = cgi.FieldStorage(fp, environ=env)
+
+        self.assertEqual(len(fields["my-arg"].file.read()), 5)
+
     def test_fieldstorage_as_context_manager(self):
         fp = BytesIO(b'x' * 10)
         env = {'REQUEST_METHOD': 'PUT'}
index b39ea54e4b2a396782e458a71b42a5a75abf4dad..cd2761353490a63f01adf3e3bc7c0f10f9a19d04 100644 (file)
@@ -3229,13 +3229,13 @@ class CodePageTest(unittest.TestCase):
             self.assertEqual(codec.name, 'mbcs')
 
     @support.bigmemtest(size=2**31, memuse=7, dry_run=False)
-    def test_large_input(self):
+    def test_large_input(self, size):
         # Test input longer than INT_MAX.
         # Input should contain undecodable bytes before and after
         # the INT_MAX limit.
-        encoded = (b'01234567' * (2**28-1) +
+        encoded = (b'01234567' * ((size//8)-1) +
                    b'\x85\x86\xea\xeb\xec\xef\xfc\xfd\xfe\xff')
-        self.assertEqual(len(encoded), 2**31+2)
+        self.assertEqual(len(encoded), size+2)
         decoded = codecs.code_page_decode(932, encoded, 'surrogateescape', True)
         self.assertEqual(decoded[1], len(encoded))
         del encoded
@@ -3246,6 +3246,20 @@ class CodePageTest(unittest.TestCase):
                          '\udc85\udc86\udcea\udceb\udcec'
                          '\udcef\udcfc\udcfd\udcfe\udcff')
 
+    @support.bigmemtest(size=2**31, memuse=6, dry_run=False)
+    def test_large_utf8_input(self, size):
+        # Test input longer than INT_MAX.
+        # Input should contain a decodable multi-byte character
+        # surrounding INT_MAX
+        encoded = (b'0123456\xed\x84\x80' * (size//8))
+        self.assertEqual(len(encoded), size // 8 * 10)
+        decoded = codecs.code_page_decode(65001, encoded, 'ignore', True)
+        self.assertEqual(decoded[1], len(encoded))
+        del encoded
+        self.assertEqual(len(decoded[0]), size)
+        self.assertEqual(decoded[0][:10], '0123456\ud10001')
+        self.assertEqual(decoded[0][-11:], '56\ud1000123456\ud100')
+
 
 class ASCIITest(unittest.TestCase):
     def test_encode(self):
index a2c7ceea9da23fec905660871c05782a4570e935..99086e5f6d25495edd646359201bd26915add779 100755 (executable)
@@ -1294,6 +1294,32 @@ class TestCase(unittest.TestCase):
         self.assertTrue(is_dataclass(d.d))
         self.assertFalse(is_dataclass(d.e))
 
+    def test_is_dataclass_when_getattr_always_returns(self):
+        # See bpo-37868.
+        class A:
+            def __getattr__(self, key):
+                return 0
+        self.assertFalse(is_dataclass(A))
+        a = A()
+
+        # Also test for an instance attribute.
+        class B:
+            pass
+        b = B()
+        b.__dataclass_fields__ = []
+
+        for obj in a, b:
+            with self.subTest(obj=obj):
+                self.assertFalse(is_dataclass(obj))
+
+                # Indirect tests for _is_dataclass_instance().
+                with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'):
+                    asdict(obj)
+                with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'):
+                    astuple(obj)
+                with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'):
+                    replace(obj, x=0)
+
     def test_helper_fields_with_class_instance(self):
         # Check that we can call fields() on either a class or instance,
         #  and get back the same thing.
@@ -3037,11 +3063,11 @@ class TestMakeDataclass(unittest.TestCase):
     def test_non_identifier_field_names(self):
         for field in ['()', 'x,y', '*', '2@3', '', 'little johnny tables']:
             with self.subTest(field=field):
-                with self.assertRaisesRegex(TypeError, 'must be valid identifers'):
+                with self.assertRaisesRegex(TypeError, 'must be valid identifiers'):
                     make_dataclass('C', ['a', field])
-                with self.assertRaisesRegex(TypeError, 'must be valid identifers'):
+                with self.assertRaisesRegex(TypeError, 'must be valid identifiers'):
                     make_dataclass('C', [field])
-                with self.assertRaisesRegex(TypeError, 'must be valid identifers'):
+                with self.assertRaisesRegex(TypeError, 'must be valid identifiers'):
                     make_dataclass('C', [field, 'a'])
 
     def test_underscore_field_names(self):
index 675f9748e8050076341f530e11014da987c2d01d..87304749974f57fe2305b00d1b1ce4ec798f2ea6 100644 (file)
@@ -2627,12 +2627,8 @@ order (MRO) for bases """
         self.assertEqual(Sub.test(), Base.aProp)
 
         # Verify that super() doesn't allow keyword args
-        try:
+        with self.assertRaises(TypeError):
             super(Base, kw=1)
-        except TypeError:
-            pass
-        else:
-            self.assertEqual("super shouldn't accept keyword args")
 
     def test_basic_inheritance(self):
         # Testing inheritance from basic types...
index f077f05f5b4f71dcb8ebc94f6f32efe0cf096be1..38215659b67d906d2b30394f21b9fc069f094272 100644 (file)
@@ -1,5 +1,6 @@
 from xmlrpc.server import DocXMLRPCServer
 import http.client
+import re
 import sys
 import threading
 from test import support
@@ -193,6 +194,21 @@ class DocXMLRPCHTTPGETServer(unittest.TestCase):
              b'method_annotation</strong></a>(x: bytes)</dt></dl>'),
             response.read())
 
+    def test_server_title_escape(self):
+        # bpo-38243: Ensure that the server title and documentation
+        # are escaped for HTML.
+        self.serv.set_server_title('test_title<script>')
+        self.serv.set_server_documentation('test_documentation<script>')
+        self.assertEqual('test_title<script>', self.serv.server_title)
+        self.assertEqual('test_documentation<script>',
+                self.serv.server_documentation)
+
+        generated = self.serv.generate_html_documentation()
+        title = re.search(r'<title>(.+?)</title>', generated).group()
+        documentation = re.search(r'<p><tt>(.+?)</tt></p>', generated).group()
+        self.assertEqual('<title>Python: test_title&lt;script&gt;</title>', title)
+        self.assertEqual('<p><tt>test_documentation&lt;script&gt;</tt></p>', documentation)
+
 
 if __name__ == '__main__':
     unittest.main()
index f61efa3c648e6677631a0f14194205a033f63389..a5f8f6465e88b8a966be488f462e8c1a3b6438cf 100644 (file)
@@ -22,7 +22,7 @@ class EINTRTests(unittest.TestCase):
             print()
             print("--- run eintr_tester.py ---", flush=True)
             # In verbose mode, the child process inherit stdout and stdout,
-            # to see output in realtime and reduce the risk of loosing output.
+            # to see output in realtime and reduce the risk of losing output.
             args = [sys.executable, "-E", "-X", "faulthandler", *args]
             proc = subprocess.run(args)
             print(f"--- eintr_tester.py completed: "
index 693487bc960fc06aae1912d7cefd6efccc80b2eb..8bb0365739f7ef1e2f7dc4cfb81c36fb89f4edd9 100644 (file)
@@ -383,6 +383,22 @@ class TestParser(TestParserMixin, TestEmailBase):
             [errors.InvalidHeaderDefect],
             '')
 
+    def test_get_unstructured_without_trailing_whitespace_hang_case(self):
+        self._test_get_x(self._get_unst,
+            '=?utf-8?q?somevalue?=aa',
+            'somevalueaa',
+            'somevalueaa',
+            [errors.InvalidHeaderDefect],
+            '')
+
+    def test_get_unstructured_invalid_ew(self):
+        self._test_get_x(self._get_unst,
+            '=?utf-8?q?=somevalue?=',
+            '=?utf-8?q?=somevalue?=',
+            '=?utf-8?q?=somevalue?=',
+            [],
+            '')
+
     # get_qp_ctext
 
     def test_get_qp_ctext_only(self):
@@ -522,6 +538,10 @@ class TestParser(TestParserMixin, TestEmailBase):
         self._test_get_x(parser.get_bare_quoted_string,
                          '""', '""', '', [], '')
 
+    def test_get_bare_quoted_string_missing_endquotes(self):
+        self._test_get_x(parser.get_bare_quoted_string,
+                         '"', '""', '', [errors.InvalidHeaderDefect], '')
+
     def test_get_bare_quoted_string_following_wsp_preserved(self):
         self._test_get_x(parser.get_bare_quoted_string,
              '"foo"\t bar', '"foo"', 'foo', [], '\t bar')
@@ -930,6 +950,12 @@ class TestParser(TestParserMixin, TestEmailBase):
         self.assertEqual(word.token_type, 'atom')
         self.assertEqual(word[0].token_type, 'cfws')
 
+    def test_get_word_all_CFWS(self):
+        # bpo-29412: Test that we don't raise IndexError when parsing CFWS only
+        # token.
+        with self.assertRaises(errors.HeaderParseError):
+            parser.get_word('(Recipients list suppressed')
+
     def test_get_word_qs_yields_qs(self):
         word = self._test_get_x(parser.get_word,
             '"bar " (bang) ah', '"bar " (bang) ', 'bar  ', [], 'ah')
@@ -1438,6 +1464,16 @@ class TestParser(TestParserMixin, TestEmailBase):
         self.assertEqual(addr_spec.domain, 'example.com')
         self.assertEqual(addr_spec.addr_spec, 'star.a.star@example.com')
 
+    def test_get_addr_spec_multiple_domains(self):
+        with self.assertRaises(errors.HeaderParseError):
+            parser.get_addr_spec('star@a.star@example.com')
+
+        with self.assertRaises(errors.HeaderParseError):
+            parser.get_addr_spec('star@a@example.com')
+
+        with self.assertRaises(errors.HeaderParseError):
+            parser.get_addr_spec('star@172.17.0.1@example.com')
+
     # get_obs_route
 
     def test_get_obs_route_simple(self):
@@ -1680,6 +1716,14 @@ class TestParser(TestParserMixin, TestEmailBase):
         self.assertEqual(display_name[3].comments, ['with trailing comment'])
         self.assertEqual(display_name.display_name, 'simple phrase.')
 
+    def test_get_display_name_for_invalid_address_field(self):
+        # bpo-32178: Test that address fields starting with `:` don't cause
+        # IndexError when parsing the display name.
+        display_name = self._test_get_x(
+            parser.get_display_name,
+            ':Foo ', '', '', [errors.InvalidHeaderDefect], ':Foo ')
+        self.assertEqual(display_name.value, '')
+
     # get_name_addr
 
     def test_get_name_addr_angle_addr_only(self):
@@ -2343,6 +2387,17 @@ class TestParser(TestParserMixin, TestEmailBase):
 
     # get_address_list
 
+    def test_get_address_list_CFWS(self):
+        address_list = self._test_get_x(parser.get_address_list,
+                                        '(Recipient list suppressed)',
+                                        '(Recipient list suppressed)',
+                                        ' ',
+                                        [errors.ObsoleteHeaderDefect],  # no content in address list
+                                        '')
+        self.assertEqual(address_list.token_type, 'address-list')
+        self.assertEqual(len(address_list.mailboxes), 0)
+        self.assertEqual(address_list.mailboxes, address_list.all_mailboxes)
+
     def test_get_address_list_mailboxes_simple(self):
         address_list = self._test_get_x(parser.get_address_list,
             'dinsdale@example.com',
@@ -2621,6 +2676,13 @@ class Test_parse_mime_parameters(TestParserMixin, TestEmailBase):
             # Defects are apparent missing *0*, and two 'out of sequence'.
             [errors.InvalidHeaderDefect]*3),
 
+        # bpo-37461: Check that we don't go into an infinite loop.
+        'extra_dquote': (
+            'r*="\'a\'\\"',
+            ' r="\\""',
+            'r*=\'a\'"',
+            [('r', '"')],
+            [errors.InvalidHeaderDefect]*2),
     }
 
 @parameterize
index c29cc56203b1f7b902aa1882e25db23c576aa08a..5414cf070cc12fc9cf736dc4918d0e72c2b00ac2 100644 (file)
@@ -3041,6 +3041,20 @@ class TestMiscellaneous(TestEmailBase):
         self.assertEqual(utils.parseaddr('<>'), ('', ''))
         self.assertEqual(utils.formataddr(utils.parseaddr('<>')), '')
 
+    def test_parseaddr_multiple_domains(self):
+        self.assertEqual(
+            utils.parseaddr('a@b@c'),
+            ('', '')
+        )
+        self.assertEqual(
+            utils.parseaddr('a@b.c@c'),
+            ('', '')
+        )
+        self.assertEqual(
+            utils.parseaddr('a@172.17.0.1@c'),
+            ('', '')
+        )
+
     def test_noquote_dump(self):
         self.assertEqual(
             utils.formataddr(('A Silly Person', 'person@dom.ain')),
@@ -5367,6 +5381,27 @@ Content-Type: application/x-foo;
         eq(language, 'en-us')
         eq(s, 'My Document For You')
 
+    def test_should_not_hang_on_invalid_ew_messages(self):
+        messages = ["""From: user@host.com
+To: user@host.com
+Bad-Header:
+ =?us-ascii?Q?LCSwrV11+IB0rSbSker+M9vWR7wEDSuGqmHD89Gt=ea0nJFSaiz4vX3XMJPT4vrE?=
+ =?us-ascii?Q?xGUZeOnp0o22pLBB7CYLH74Js=wOlK6Tfru2U47qR?=
+ =?us-ascii?Q?72OfyEY2p2=2FrA9xNFyvH+fBTCmazxwzF8nGkK6D?=
+
+Hello!
+""", """From: ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ <xxx@xxx>
+To: "xxx" <xxx@xxx>
+Subject:   ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½
+MIME-Version: 1.0
+Content-Type: text/plain; charset="windows-1251";
+Content-Transfer-Encoding: 8bit
+
+�� ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
+"""]
+        for m in messages:
+            with self.subTest(m=m):
+                msg = email.message_from_string(m)
 
 
 # Tests to ensure that signed parts of an email are completely preserved, as
index e6db3acedcc139248a7eafadb0d687045369987d..b54df3ebc61a13706437e158ca5ef71cd0294178 100644 (file)
@@ -1528,6 +1528,30 @@ class TestAddressAndGroup(TestEmailBase):
 
 class TestFolding(TestHeaderBase):
 
+    def test_address_display_names(self):
+        """Test the folding and encoding of address headers."""
+        for name, result in (
+                ('Foo Bar, France', '"Foo Bar, France"'),
+                ('Foo Bar (France)', '"Foo Bar (France)"'),
+                ('Foo Bar, España', 'Foo =?utf-8?q?Bar=2C_Espa=C3=B1a?='),
+                ('Foo Bar (España)', 'Foo Bar =?utf-8?b?KEVzcGHDsWEp?='),
+                ('Foo, Bar España', '=?utf-8?q?Foo=2C_Bar_Espa=C3=B1a?='),
+                ('Foo, Bar [España]', '=?utf-8?q?Foo=2C_Bar_=5BEspa=C3=B1a=5D?='),
+                ('Foo Bär, France', 'Foo =?utf-8?q?B=C3=A4r=2C?= France'),
+                ('Foo Bär <France>', 'Foo =?utf-8?q?B=C3=A4r_=3CFrance=3E?='),
+                (
+                    'Lôrem ipsum dôlôr sit amet, cônsectetuer adipiscing. '
+                    'Suspendisse pôtenti. Aliquam nibh. Suspendisse pôtenti.',
+                    '=?utf-8?q?L=C3=B4rem_ipsum_d=C3=B4l=C3=B4r_sit_amet=2C_c'
+                    '=C3=B4nsectetuer?=\n =?utf-8?q?adipiscing=2E_Suspendisse'
+                    '_p=C3=B4tenti=2E_Aliquam_nibh=2E?=\n Suspendisse =?utf-8'
+                    '?q?p=C3=B4tenti=2E?=',
+                    ),
+                ):
+            h = self.make_header('To', Address(name, addr_spec='a@b.com'))
+            self.assertEqual(h.fold(policy=policy.default),
+                                    'To: %s <a@b.com>\n' % result)
+
     def test_short_unstructured(self):
         h = self.make_header('subject', 'this is a test')
         self.assertEqual(h.fold(policy=policy.default),
index 5dc46e1b812c5d8cf2767881805416bf5613ff51..fab97d91882b8b42c962ceb3588f1df89df5f7d6 100644 (file)
@@ -929,6 +929,15 @@ class TestMIMEPart(TestEmailMessageBase, TestEmailBase):
         m.set_content(content_manager=cm)
         self.assertNotIn('MIME-Version', m)
 
+    def test_string_payload_with_multipart_content_type(self):
+        msg = message_from_string(textwrap.dedent("""\
+        Content-Type: multipart/mixed; charset="utf-8"
+
+        sample text
+        """), policy=policy.default)
+        attachments = msg.iter_attachments()
+        self.assertEqual(list(attachments), [])
+
 
 if __name__ == '__main__':
     unittest.main()
index 0aea934df4348efa7d993b5d45dc5e4375dcfd6b..ebc3ce6f7682501b9f872598713b20ea62603ff7 100644 (file)
@@ -3,6 +3,7 @@ import sys
 import types
 import textwrap
 import unittest
+import email.errors
 import email.policy
 import email.parser
 import email.generator
@@ -258,6 +259,25 @@ class PolicyAPITests(unittest.TestCase):
             'Subject: \n' +
             12 * ' =?utf-8?q?=C4=85?=\n')
 
+    def test_short_maxlen_error(self):
+        # RFC 2047 chrome takes up 7 characters, plus the length of the charset
+        # name, so folding should fail if maxlen is lower than the minimum
+        # required length for a line.
+
+        # Note: This is only triggered when there is a single word longer than
+        # max_line_length, hence the 1234567890 at the end of this whimsical
+        # subject. This is because when we encounter a word longer than
+        # max_line_length, it is broken down into encoded words to fit
+        # max_line_length. If the max_line_length isn't large enough to even
+        # contain the RFC 2047 chrome (`?=<charset>?q??=`), we fail.
+        subject = "Melt away the pounds with this one simple trick! 1234567890"
+
+        for maxlen in [3, 7, 9]:
+            with self.subTest(maxlen=maxlen):
+                policy = email.policy.default.clone(max_line_length=maxlen)
+                with self.assertRaises(email.errors.HeaderParseError):
+                    policy.fold("Subject", subject)
+
     # XXX: Need subclassing tests.
     # For adding subclassed objects, make sure the usual rules apply (subclass
     # wins), but that the order still works (right overrides left).
index 711fb69ebdffcac0c0451d82cdb2ba0f9dac5aa6..1a9975fb84d1e972c19132e11005d899c782dbc6 100644 (file)
@@ -211,43 +211,22 @@ class DebuggerTests(unittest.TestCase):
         elif script:
             args += [script]
 
-        # print args
-        # print (' '.join(args))
-
         # Use "args" to invoke gdb, capturing stdout, stderr:
         out, err = run_gdb(*args, PYTHONHASHSEED=PYTHONHASHSEED)
 
-        errlines = err.splitlines()
-        unexpected_errlines = []
-
-        # Ignore some benign messages on stderr.
-        ignore_patterns = (
-            'Function "%s" not defined.' % breakpoint,
-            'Do you need "set solib-search-path" or '
-            '"set sysroot"?',
-            # BFD: /usr/lib/debug/(...): unable to initialize decompress
-            # status for section .debug_aranges
-            'BFD: ',
-            # ignore all warnings
-            'warning: ',
-            )
-        for line in errlines:
-            if not line:
-                continue
-            # bpo34007: Sometimes some versions of the shared libraries that
-            # are part of the traceback are compiled in optimised mode and the
-            # Program Counter (PC) is not present, not allowing gdb to walk the
-            # frames back. When this happens, the Python bindings of gdb raise
-            # an exception, making the test impossible to succeed.
-            if "PC not saved" in line:
-                raise unittest.SkipTest("gdb cannot walk the frame object"
-                                        " because the Program Counter is"
-                                        " not present")
-            if not line.startswith(ignore_patterns):
-                unexpected_errlines.append(line)
-
-        # Ensure no unexpected error messages:
-        self.assertEqual(unexpected_errlines, [])
+        for line in err.splitlines():
+            print(line, file=sys.stderr)
+
+        # bpo-34007: Sometimes some versions of the shared libraries that
+        # are part of the traceback are compiled in optimised mode and the
+        # Program Counter (PC) is not present, not allowing gdb to walk the
+        # frames back. When this happens, the Python bindings of gdb raise
+        # an exception, making the test impossible to succeed.
+        if "PC not saved" in err:
+            raise unittest.SkipTest("gdb cannot walk the frame object"
+                                    " because the Program Counter is"
+                                    " not present")
+
         return out
 
     def get_gdb_repr(self, source,
@@ -273,8 +252,15 @@ class DebuggerTests(unittest.TestCase):
         # gdb can insert additional '\n' and space characters in various places
         # in its output, depending on the width of the terminal it's connected
         # to (using its "wrap_here" function)
-        m = re.match(r'.*#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)\)\s+at\s+\S*Python/bltinmodule.c.*',
-                     gdb_output, re.DOTALL)
+        m = re.search(
+            # Match '#0 builtin_id(self=..., v=...)'
+            r'#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)'
+            # Match ' at Python/bltinmodule.c'.
+            # bpo-38239: builtin_id() is defined in Python/bltinmodule.c,
+            # but accept any "Directory\file.c" to support Link Time
+            # Optimization (LTO).
+            r'\s+at\s+\S*[A-Za-z]+/[A-Za-z0-9_-]+\.c',
+            gdb_output, re.DOTALL)
         if not m:
             self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output))
         return m.group(1), gdb_output
index 16edf34a99259f64a8dec005c58505e831d3833c..6eabeeae999d8b00a29ab29d5ce5b1b8a3704545 100644 (file)
@@ -6,6 +6,7 @@ import test.support
 import time
 import unittest
 import urllib.request
+import warnings
 
 from http.cookiejar import (time2isoz, http2time, iso2time, time2netscape,
      parse_ns_headers, join_header_words, split_header_words, Cookie,
@@ -560,6 +561,16 @@ class CookieTests(unittest.TestCase):
         # if expires is in future, keep cookie...
         c = CookieJar()
         future = time2netscape(time.time()+3600)
+
+        with warnings.catch_warnings(record=True) as warns:
+            headers = [f"Set-Cookie: FOO=BAR; path=/; expires={future}"]
+            req = urllib.request.Request("http://www.coyote.com/")
+            res = FakeResponse(headers, "http://www.coyote.com/")
+            cookies = c.make_cookies(res, req)
+            self.assertEqual(len(cookies), 1)
+            self.assertEqual(time2netscape(cookies[0].expires), future)
+            self.assertEqual(len(warns), 0)
+
         interact_netscape(c, "http://www.acme.com/", 'spam="bar"; expires=%s' %
                           future)
         self.assertEqual(len(c), 1)
index c4246671586f63c567e991a2846e699e1395b8c5..9facb2e360179613f8a38a1a4817979fc7f1a2bd 100644 (file)
@@ -1157,6 +1157,34 @@ class BasicTest(TestCase):
         thread.join()
         self.assertEqual(result, b"proxied data\n")
 
+    def test_putrequest_override_validation(self):
+        """
+        It should be possible to override the default validation
+        behavior in putrequest (bpo-38216).
+        """
+        class UnsafeHTTPConnection(client.HTTPConnection):
+            def _validate_path(self, url):
+                pass
+
+        conn = UnsafeHTTPConnection('example.com')
+        conn.sock = FakeSocket('')
+        conn.putrequest('GET', '/\x00')
+
+    def test_putrequest_override_encoding(self):
+        """
+        It should be possible to override the default encoding
+        to transmit bytes in another encoding even if invalid
+        (bpo-36274).
+        """
+        class UnsafeHTTPConnection(client.HTTPConnection):
+            def _encode_request(self, str_url):
+                return str_url.encode('utf-8')
+
+        conn = UnsafeHTTPConnection('example.com')
+        conn.sock = FakeSocket('')
+        conn.putrequest('GET', '/☃')
+
+
 class ExtendedReadTest(TestCase):
     """
     Test peek(), read1(), readline()
@@ -1281,6 +1309,7 @@ class ExtendedReadTest(TestCase):
         p = self.resp.peek(0)
         self.assertLessEqual(0, len(p))
 
+
 class ExtendedReadTestChunked(ExtendedReadTest):
     """
     Test peek(), read1(), readline() in chunked mode
index 1fc4de11e1789605cdae73b5e5caaf992e194482..4b9907d5329d308ca413f3ebbb961c34f98e957e 100644 (file)
@@ -711,6 +711,11 @@ class RelativeImportTests(unittest.TestCase):
         ns = dict(__package__=object())
         self.assertRaises(TypeError, check_relative)
 
+    def test_parentless_import_shadowed_by_global(self):
+        # Test as if this were done from the REPL where this error most commonly occurs (bpo-37409).
+        script_helper.assert_python_failure('-W', 'ignore', '-c',
+            "foo = 1; from . import foo")
+
     def test_absolute_import_without_future(self):
         # If explicit relative import syntax is used, then do not try
         # to perform an absolute import in the face of failure.
index edb745c2cd49ba8244928c57831051f687777096..0fb1346f9eec8f5a50116d434871a38cd1909c8d 100644 (file)
@@ -363,7 +363,7 @@ class ReloadTests:
 
     def test_module_missing_spec(self):
         #Test that reload() throws ModuleNotFounderror when reloading
-        # a module who's missing a spec. (bpo-29851)
+        # a module whose missing a spec. (bpo-29851)
         name = 'spam'
         with test_util.uncache(name):
             module = sys.modules[name] = types.ModuleType(name)
index f3eb2f62c37e19b1af706b8d6adff730d5538e2a..75ac40ba4f813ceffca21b693fce70c695a9ce6f 100644 (file)
@@ -3050,14 +3050,21 @@ class TestSignatureObject(unittest.TestCase):
         class MySignature(inspect.Signature): pass
         def foo(a, *, b:1): pass
         foo_sig = MySignature.from_callable(foo)
-        self.assertTrue(isinstance(foo_sig, MySignature))
+        self.assertIsInstance(foo_sig, MySignature)
+
+    def test_signature_from_callable_class(self):
+        # A regression test for a class inheriting its signature from `object`.
+        class MySignature(inspect.Signature): pass
+        class foo: pass
+        foo_sig = MySignature.from_callable(foo)
+        self.assertIsInstance(foo_sig, MySignature)
 
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_signature_from_callable_builtin_obj(self):
         class MySignature(inspect.Signature): pass
         sig = MySignature.from_callable(_pickle.Pickler)
-        self.assertTrue(isinstance(sig, MySignature))
+        self.assertIsInstance(sig, MySignature)
 
     def test_signature_definition_order_preserved_on_kwonly(self):
         for fn in signatures_with_lexicographic_keyword_only_parameters():
index 3c50eec456ab2c9714b836a86a99f73a584c529c..455b893fb126f6b6138757d29010731f3a16ace4 100644 (file)
@@ -12,6 +12,7 @@ import operator
 import pickle
 import ipaddress
 import weakref
+from test.support import LARGEST, SMALLEST
 
 
 class BaseTestCase(unittest.TestCase):
@@ -405,7 +406,13 @@ class NetmaskTestMixin_v4(CommonTestMixin_v4):
     """Input validation on interfaces and networks is very similar"""
 
     def test_no_mask(self):
-        self.assertEqual(str(self.factory('1.2.3.4')), '1.2.3.4/32')
+        for address in ('1.2.3.4', 0x01020304, b'\x01\x02\x03\x04'):
+            net = self.factory(address)
+            self.assertEqual(str(net), '1.2.3.4/32')
+            self.assertEqual(str(net.netmask), '255.255.255.255')
+            self.assertEqual(str(net.hostmask), '0.0.0.0')
+            # IPv4Network has prefixlen, but IPv4Interface doesn't.
+            # Should we add it to IPv4Interface too? (bpo-36392)
 
     def test_split_netmask(self):
         addr = "1.2.3.4/32/24"
@@ -541,6 +548,15 @@ class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
 class NetmaskTestMixin_v6(CommonTestMixin_v6):
     """Input validation on interfaces and networks is very similar"""
 
+    def test_no_mask(self):
+        for address in ('::1', 1, b'\x00'*15 + b'\x01'):
+            net = self.factory(address)
+            self.assertEqual(str(net), '::1/128')
+            self.assertEqual(str(net.netmask), 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
+            self.assertEqual(str(net.hostmask), '::')
+            # IPv6Network has prefixlen, but IPv6Interface doesn't.
+            # Should we add it to IPv4Interface too? (bpo-36392)
+
     def test_split_netmask(self):
         addr = "cafe:cafe::/128/190"
         with self.assertAddressError("Only one '/' permitted in %r" % addr):
@@ -664,20 +680,6 @@ class FactoryFunctionErrors(BaseTestCase):
         self.assertFactoryError(ipaddress.ip_network, "network")
 
 
-@functools.total_ordering
-class LargestObject:
-    def __eq__(self, other):
-        return isinstance(other, LargestObject)
-    def __lt__(self, other):
-        return False
-
-@functools.total_ordering
-class SmallestObject:
-    def __eq__(self, other):
-        return isinstance(other, SmallestObject)
-    def __gt__(self, other):
-        return False
-
 class ComparisonTests(unittest.TestCase):
 
     v4addr = ipaddress.IPv4Address(1)
@@ -766,8 +768,6 @@ class ComparisonTests(unittest.TestCase):
 
     def test_foreign_type_ordering(self):
         other = object()
-        smallest = SmallestObject()
-        largest = LargestObject()
         for obj in self.objects:
             with self.assertRaises(TypeError):
                 obj < other
@@ -777,14 +777,14 @@ class ComparisonTests(unittest.TestCase):
                 obj <= other
             with self.assertRaises(TypeError):
                 obj >= other
-            self.assertTrue(obj < largest)
-            self.assertFalse(obj > largest)
-            self.assertTrue(obj <= largest)
-            self.assertFalse(obj >= largest)
-            self.assertFalse(obj < smallest)
-            self.assertTrue(obj > smallest)
-            self.assertFalse(obj <= smallest)
-            self.assertTrue(obj >= smallest)
+            self.assertTrue(obj < LARGEST)
+            self.assertFalse(obj > LARGEST)
+            self.assertTrue(obj <= LARGEST)
+            self.assertFalse(obj >= LARGEST)
+            self.assertFalse(obj < SMALLEST)
+            self.assertTrue(obj > SMALLEST)
+            self.assertFalse(obj <= SMALLEST)
+            self.assertTrue(obj >= SMALLEST)
 
     def test_mixed_type_key(self):
         # with get_mixed_type_key, you can sort addresses and network.
index cbbb4c4f71d3b8d2e8fad564078ee14b0c467291..721a17556f7ed7da349e1034c08dd17c2ad6ff99 100644 (file)
@@ -11,6 +11,7 @@ import pickle
 from functools import reduce
 import sys
 import struct
+import threading
 maxsize = support.MAX_Py_ssize_t
 minsize = -maxsize-1
 
@@ -1476,6 +1477,42 @@ class TestBasicOps(unittest.TestCase):
             del forward, backward
             raise
 
+    def test_tee_reenter(self):
+        class I:
+            first = True
+            def __iter__(self):
+                return self
+            def __next__(self):
+                first = self.first
+                self.first = False
+                if first:
+                    return next(b)
+
+        a, b = tee(I())
+        with self.assertRaisesRegex(RuntimeError, "tee"):
+            next(a)
+
+    def test_tee_concurrent(self):
+        start = threading.Event()
+        finish = threading.Event()
+        class I:
+            def __iter__(self):
+                return self
+            def __next__(self):
+                start.set()
+                finish.wait()
+
+        a, b = tee(I())
+        thread = threading.Thread(target=next, args=[a])
+        thread.start()
+        try:
+            start.wait()
+            with self.assertRaisesRegex(RuntimeError, "tee"):
+                next(b)
+        finally:
+            finish.set()
+            thread.join()
+
     def test_StopIteration(self):
         self.assertRaises(StopIteration, next, zip())
 
index fd0d86b392cee9ef2db2175fc0b0768d09e71d8b..13b40020781bae33ea47c8ff5446030e7f348677 100644 (file)
@@ -12,6 +12,16 @@ class TestDump:
     def test_dumps(self):
         self.assertEqual(self.dumps({}), '{}')
 
+    def test_dump_skipkeys(self):
+        v = {b'invalid_key': False, 'valid_key': True}
+        with self.assertRaises(TypeError):
+            self.json.dumps(v)
+
+        s = self.json.dumps(v, skipkeys=True)
+        o = self.json.loads(s)
+        self.assertIn('valid_key', o)
+        self.assertNotIn(b'invalid_key', o)
+
     def test_encode_truefalse(self):
         self.assertEqual(self.dumps(
                  {True: False, False: True}, sort_keys=True),
index def4badbf5578e85b0facd46bc516e3219f34c1c..5078d4bc1ced56064e96ba26fe65926f28661605 100644 (file)
@@ -149,6 +149,11 @@ class ListTest(list_tests.CommonTest):
             a[:] = data
             self.assertEqual(list(it), [])
 
+    def test_step_overflow(self):
+        a = [0, 1, 2, 3, 4]
+        a[1::sys.maxsize] = [0]
+        self.assertEqual(a[3::sys.maxsize], [3])
+
     def test_no_comdat_folding(self):
         # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding
         # optimization causes failures in code that relies on distinct
index e2c2178ae6cc30103549c8dfb601d32dcb5e1ac6..9a05029b42a4fc2b1656db4d1529d870f2be3bcc 100644 (file)
@@ -493,6 +493,42 @@ class NormalizeTest(unittest.TestCase):
 
 
 class TestMiscellaneous(unittest.TestCase):
+    def test_defaults_UTF8(self):
+        # Issue #18378: on (at least) macOS setting LC_CTYPE to "UTF-8" is
+        # valid. Futhermore LC_CTYPE=UTF is used by the UTF-8 locale coercing
+        # during interpreter startup (on macOS).
+        import _locale
+        import os
+
+        self.assertEqual(locale._parse_localename('UTF-8'), (None, 'UTF-8'))
+
+        if hasattr(_locale, '_getdefaultlocale'):
+            orig_getlocale = _locale._getdefaultlocale
+            del _locale._getdefaultlocale
+        else:
+            orig_getlocale = None
+
+        orig_env = {}
+        try:
+            for key in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
+                if key in os.environ:
+                    orig_env[key] = os.environ[key]
+                    del os.environ[key]
+
+            os.environ['LC_CTYPE'] = 'UTF-8'
+
+            self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8'))
+
+        finally:
+            for k in orig_env:
+                os.environ[k] = orig_env[k]
+
+            if 'LC_CTYPE' not in orig_env:
+                del os.environ['LC_CTYPE']
+
+            if orig_getlocale is not None:
+                _locale._getdefaultlocale = orig_getlocale
+
     def test_getpreferredencoding(self):
         # Invoke getpreferredencoding to make sure it does not cause exceptions.
         enc = locale.getpreferredencoding()
index 97c13a4c521483489650ff1794413a56a61d9e98..546cea98c1ea4ca36cc37707b4cee7442a0d854f 100644 (file)
@@ -3877,6 +3877,37 @@ class ModuleLevelMiscTest(BaseTest):
         logging.setLoggerClass(logging.Logger)
         self.assertEqual(logging.getLoggerClass(), logging.Logger)
 
+    def test_subclass_logger_cache(self):
+        # bpo-37258
+        message = []
+
+        class MyLogger(logging.getLoggerClass()):
+            def __init__(self, name='MyLogger', level=logging.NOTSET):
+                super().__init__(name, level)
+                message.append('initialized')
+
+        logging.setLoggerClass(MyLogger)
+        logger = logging.getLogger('just_some_logger')
+        self.assertEqual(message, ['initialized'])
+        stream = io.StringIO()
+        h = logging.StreamHandler(stream)
+        logger.addHandler(h)
+        try:
+            logger.setLevel(logging.DEBUG)
+            logger.debug("hello")
+            self.assertEqual(stream.getvalue().strip(), "hello")
+
+            stream.truncate(0)
+            stream.seek(0)
+
+            logger.setLevel(logging.INFO)
+            logger.debug("hello")
+            self.assertEqual(stream.getvalue(), "")
+        finally:
+            logger.removeHandler(h)
+            h.close()
+            logging.setLoggerClass(logging.Logger)
+
     @support.requires_type_collecting
     def test_logging_at_shutdown(self):
         # Issue #20037
@@ -3989,7 +4020,7 @@ class BasicConfigTest(unittest.TestCase):
         logging._handlers.clear()
         logging._handlers.update(self.saved_handlers)
         logging._handlerList[:] = self.saved_handler_list
-        logging.root.level = self.original_logging_level
+        logging.root.setLevel(self.original_logging_level)
 
     def test_no_kwargs(self):
         logging.basicConfig()
index 3dc2c1e7e3b779e3e54ad598aba15d2a41444dcf..49758ac7e7808b2c869315e7f7b13d09a4031453 100644 (file)
@@ -1195,6 +1195,36 @@ class FileTestCase(unittest.TestCase):
         f.close()
         self.assertRaises(ValueError, f.tell)
 
+    def test_issue21872(self):
+        # sometimes decompress data incompletely
+
+        # ---------------------
+        # when max_length == -1
+        # ---------------------
+        d1 = LZMADecompressor()
+        entire = d1.decompress(ISSUE_21872_DAT, max_length=-1)
+        self.assertEqual(len(entire), 13160)
+        self.assertTrue(d1.eof)
+
+        # ---------------------
+        # when max_length > 0
+        # ---------------------
+        d2 = LZMADecompressor()
+
+        # When this value of max_length is used, the input and output
+        # buffers are exhausted at the same time, and lzs's internal
+        # state still have 11 bytes can be output.
+        out1 = d2.decompress(ISSUE_21872_DAT, max_length=13149)
+        self.assertFalse(d2.needs_input) # ensure needs_input mechanism works
+        self.assertFalse(d2.eof)
+
+        # simulate needs_input mechanism
+        # output internal state's 11 bytes
+        out2 = d2.decompress(b'')
+        self.assertEqual(len(out2), 11)
+        self.assertTrue(d2.eof)
+        self.assertEqual(out1 + out2, entire)
+
 
 class OpenTestCase(unittest.TestCase):
 
@@ -1761,6 +1791,139 @@ COMPRESSED_RAW_4 = (
     b"\x00"
 )
 
+ISSUE_21872_DAT = (
+    b']\x00\x00@\x00h3\x00\x00\x00\x00\x00\x00\x00\x00`D\x0c\x99\xc8'
+    b'\xd1\xbbZ^\xc43+\x83\xcd\xf1\xc6g\xec-\x061F\xb1\xbb\xc7\x17%-\xea'
+    b'\xfap\xfb\x8fs\x128\xb2,\x88\xe4\xc0\x12|*x\xd0\xa2\xc4b\x1b!\x02c'
+    b'\xab\xd9\x87U\xb8n \xfaVJ\x9a"\xb78\xff%_\x17`?@*\xc2\x82'
+    b"\xf2^\x1b\xb8\x04&\xc0\xbb\x03g\x9d\xca\xe9\xa4\xc9\xaf'\xe5\x8e}"
+    b'F\xdd\x11\xf3\x86\xbe\x1fN\x95\\\xef\xa2Mz-\xcb\x9a\xe3O@'
+    b"\x19\x07\xf6\xee\x9e\x9ag\xc6\xa5w\rnG'\x99\xfd\xfeGI\xb0"
+    b'\xbb\xf9\xc2\xe1\xff\xc5r\xcf\x85y[\x01\xa1\xbd\xcc/\xa3\x1b\x83\xaa'
+    b'\xc6\xf9\x99\x0c\xb6_\xc9MQ+x\xa2F\xda]\xdd\xe8\xfb\x1a&'
+    b',\xc4\x19\x1df\x81\x1e\x90\xf3\xb8Hgr\x85v\xbe\xa3qx\x01Y\xb5\x9fF'
+    b"\x13\x18\x01\xe69\x9b\xc8'\x1e\x9d\xd6\xe4F\x84\xac\xf8d<\x11\xd5"
+    b'\\\x0b\xeb\x0e\x82\xab\xb1\xe6\x1fka\xe1i\xc4 C\xb1"4)\xd6\xa7`\x02'
+    b'\xec\x11\x8c\xf0\x14\xb0\x1d\x1c\xecy\xf0\xb7|\x11j\x85X\xb2!\x1c'
+    b'\xac\xb5N\xc7\x85j\x9ev\xf5\xe6\x0b\xc1]c\xc15\x16\x9f\xd5\x99'
+    b"\xfei^\xd2G\x9b\xbdl\xab:\xbe,\xa9'4\x82\xe5\xee\xb3\xc1"
+    b'$\x93\x95\xa8Y\x16\xf5\xbf\xacw\x91\x04\x1d\x18\x06\xe9\xc5\xfdk\x06'
+    b'\xe8\xfck\xc5\x86>\x8b~\xa4\xcb\xf1\xb3\x04\xf1\x04G5\xe2\xcc]'
+    b'\x16\xbf\x140d\x18\xe2\xedw#(3\xca\xa1\x80bX\x7f\xb3\x84'
+    b'\x9d\xdb\xe7\x08\x97\xcd\x16\xb9\xf1\xd5r+m\x1e\xcb3q\xc5\x9e\x92'
+    b"\x7f\x8e*\xc7\xde\xe9\xe26\xcds\xb1\x10-\xf6r\x02?\x9d\xddCgJN'"
+    b'\x11M\xfa\nQ\n\xe6`m\xb8N\xbbq\x8el\x0b\x02\xc7:q\x04G\xa1T'
+    b'\xf1\xfe!0\x85~\xe5\x884\xe9\x89\xfb\x13J8\x15\xe42\xb6\xad'
+    b'\x877A\x9a\xa6\xbft]\xd0\xe35M\xb0\x0cK\xc8\xf6\x88\xae\xed\xa9,j7'
+    b'\x81\x13\xa0(\xcb\xe1\xe9l2\x7f\xcd\xda\x95(\xa70B\xbd\xf4\xe3'
+    b'hp\x94\xbdJ\xd7\t\xc7g\xffo?\x89?\xf8}\x7f\xbc\x1c\x87'
+    b'\x14\xc0\xcf\x8cV:\x9a\x0e\xd0\xb2\x1ck\xffk\xb9\xe0=\xc7\x8d/'
+    b'\xb8\xff\x7f\x1d\x87`\x19.\x98X*~\xa7j\xb9\x0b"\xf4\xe4;V`\xb9\xd7'
+    b'\x03\x1e\xd0t0\xd3\xde\x1fd\xb9\xe2)\x16\x81}\xb1\\b\x7fJ'
+    b'\x92\xf4\xff\n+V!\xe9\xde\x98\xa0\x8fK\xdf7\xb9\xc0\x12\x1f\xe2'
+    b'\xe9\xb0`\xae\x14\r\xa7\xc4\x81~\xd8\x8d\xc5\x06\xd8m\xb0Y\x8a)'
+    b'\x06/\xbb\xf9\xac\xeaP\xe0\x91\x05m[\xe5z\xe6Z\xf3\x9f\xc7\xd0'
+    b'\xd3\x8b\xf3\x8a\x1b\xfa\xe4Pf\xbc0\x17\x10\xa9\xd0\x95J{\xb3\xc3'
+    b'\xfdW\x9bop\x0f\xbe\xaee\xa3]\x93\x9c\xda\xb75<\xf6g!\xcc\xb1\xfc\\'
+    b'7\x152Mc\x17\x84\x9d\xcd35\r0\xacL-\xf3\xfb\xcb\x96\x1e\xe9U\x7f'
+    b'\xd7\xca\xb0\xcc\x89\x0c*\xce\x14\xd1P\xf1\x03\xb6.~9o?\xe8'
+    b'\r\x86\xe0\x92\x87}\xa3\x84\x03P\xe0\xc2\x7f\n;m\x9d\x9e\xb4|'
+    b'\x8c\x18\xc0#0\xfe3\x07<\xda\xd8\xcf^\xd4Hi\xd6\xb3\x0bT'
+    b'\x1dF\x88\x85q}\x02\xc6&\xc4\xae\xce\x9cU\xfa\x0f\xcc\xb6\x1f\x11'
+    b'drw\x9eN\x19\xbd\xffz\x0f\xf0\x04s\xadR\xc1\xc0\xbfl\xf1\xba\xf95^'
+    b'e\xb1\xfbVY\xd9\x9f\x1c\xbf*\xc4\xa86\x08+\xd6\x88[\xc4_rc\xf0f'
+    b'\xb8\xd4\xec\x1dx\x19|\xbf\xa7\xe0\x82\x0b\x8c~\x10L/\x90\xd6\xfb'
+    b'\x81\xdb\x98\xcc\x02\x14\xa5C\xb2\xa7i\xfd\xcd\x1fO\xf7\xe9\x89t\xf0'
+    b'\x17\xa5\x1c\xad\xfe<Q`%\x075k\n7\x9eI\x82<#)&\x04\xc2\xf0C\xd4`!'
+    b'\xcb\xa9\xf9\xb3F\x86\xb5\xc3M\xbeu\x12\xb2\xca\x95e\x10\x0b\xb1\xcc'
+    b'\x01b\x9bXa\x1b[B\x8c\x07\x11Of;\xeaC\xebr\x8eb\xd9\x9c\xe4i]<z\x9a'
+    b'\x03T\x8b9pF\x10\x8c\x84\xc7\x0e\xeaPw\xe5\xa0\x94\x1f\x84\xdd'
+    b'a\xe8\x85\xc2\x00\xebq\xe7&Wo5q8\xc2t\x98\xab\xb7\x7f\xe64-H'
+    b'\t\xb4d\xbe\x06\xe3Q\x8b\xa9J\xb0\x00\xd7s.\x85"\xc0p\x05'
+    b'\x1c\x06N\x87\xa5\xf8\xc3g\x1b}\x0f\x0f\xc3|\x90\xea\xefd3X'
+    b'[\xab\x04E\xf2\xf2\xc9\x08\x8a\xa8+W\xa2v\xec\x15G\x08/I<L\\1'
+    b'\xff\x15O\xaa\x89{\xd1mW\x13\xbd~\xe1\x90^\xc4@\r\xed\xb5D@\xb4\x08'
+    b'A\x90\xe69;\xc7BO\xdb\xda\xebu\x9e\xa9tN\xae\x8aJ5\xcd\x11\x1d\xea'
+    b"\xe5\xa7\x04\xe6\x82Z\xc7O\xe46[7\xdco*[\xbe\x0b\xc9\xb7a\xab'\xf6"
+    b"\xd1u\xdb\xd9q\xf5+y\x1b\x00\xb4\xf3a\xae\xf1M\xc4\xbc\xd00'\x06pQ"
+    b'\x8dH\xaa\xaa\xc4\xd2K\x9b\xc0\xe9\xec=n\xa9\x1a\x8a\xc2\xe8\x18\xbc'
+    b'\x93\xb8F\xa1\x8fOY\xe7\xda\xcf0\t\xff|\xd9\xe5\xcf\xe7\xf6\xbe'
+    b'\xf8\x04\x17\xf2\xe5P\xa7y~\xce\x11h0\x81\x80d[\x00_v\xbbc\xdbI'
+    b'3\xbc`W\xc0yrkB\xf5\x9f\xe9i\xc5\x8a^\x8d\xd4\x81\xd9\x05\xc1\xfc>'
+    b'"\xd1v`\x82\xd5$\x89\xcf^\xd52.\xafd\xe8d@\xaa\xd5Y|\x90\x84'
+    b'j\xdb}\x84riV\x8e\xf0X4rB\xf2NPS[\x8e\x88\xd4\x0fI\xb8'
+    b'\xdd\xcb\x1d\xf2(\xdf;9\x9e|\xef^0;.*[\x9fl\x7f\xa2_X\xaff!\xbb\x03'
+    b'\xff\x19\x8f\x88\xb5\xb6\x884\xa3\x05\xde3D{\xe3\xcb\xce\xe4t]'
+    b'\x875\xe3Uf\xae\xea\x88\x1c\x03b\n\xb1,Q\xec\xcf\x08\t\xde@\x83\xaa<'
+    b',-\xe4\xee\x9b\x843\xe5\x007\tK\xac\x057\xd6*X\xa3\xc6~\xba\xe6O'
+    b'\x81kz"\xbe\xe43sL\xf1\xfa;\xf4^\x1e\xb4\x80\xe2\xbd\xaa\x17Z\xe1f'
+    b'\xda\xa6\xb9\x07:]}\x9fa\x0b?\xba\xe7\xf15\x04M\xe3\n}M\xa4\xcb\r'
+    b'2\x8a\x88\xa9\xa7\x92\x93\x84\x81Yo\x00\xcc\xc4\xab\x9aT\x96\x0b\xbe'
+    b'U\xac\x1d\x8d\x1b\x98"\xf8\x8f\xf1u\xc1n\xcc\xfcA\xcc\x90\xb7i'
+    b'\x83\x9c\x9c~\x1d4\xa2\xf0*J\xe7t\x12\xb4\xe3\xa0u\xd7\x95Z'
+    b'\xf7\xafG\x96~ST,\xa7\rC\x06\xf4\xf0\xeb`2\x9e>Q\x0e\xf6\xf5\xc5'
+    b'\x9b\xb5\xaf\xbe\xa3\x8f\xc0\xa3hu\x14\x12 \x97\x99\x04b\x8e\xc7\x1b'
+    b'VKc\xc1\xf3 \xde\x85-:\xdc\x1f\xac\xce*\x06\xb3\x80;`'
+    b'\xdb\xdd\x97\xfdg\xbf\xe7\xa8S\x08}\xf55e7\xb8/\xf0!\xc8'
+    b"Y\xa8\x9a\x07'\xe2\xde\r\x02\xe1\xb2\x0c\xf4C\xcd\xf9\xcb(\xe8\x90"
+    b'\xd3bTD\x15_\xf6\xc3\xfb\xb3E\xfc\xd6\x98{\xc6\\fz\x81\xa99\x85\xcb'
+    b'\xa5\xb1\x1d\x94bqW\x1a!;z~\x18\x88\xe8i\xdb\x1b\x8d\x8d'
+    b'\x06\xaa\x0e\x99s+5k\x00\xe4\xffh\xfe\xdbt\xa6\x1bU\xde\xa3'
+    b'\xef\xcb\x86\x9e\x81\x16j\n\x9d\xbc\xbbC\x80?\x010\xc7Jj;'
+    b'\xc4\xe5\x86\xd5\x0e0d#\xc6;\xb8\xd1\xc7c\xb5&8?\xd9J\xe5\xden\xb9'
+    b'\xe9cb4\xbb\xe6\x14\xe0\xe7l\x1b\x85\x94\x1fh\xf1n\xdeZ\xbe'
+    b'\x88\xff\xc2e\xca\xdc,B-\x8ac\xc9\xdf\xf5|&\xe4LL\xf0\x1f\xaa8\xbd'
+    b'\xc26\x94bVi\xd3\x0c\x1c\xb6\xbb\x99F\x8f\x0e\xcc\x8e4\xc6/^W\xf5?'
+    b'\xdc\x84(\x14dO\x9aD6\x0f4\xa3,\x0c\x0bS\x9fJ\xe1\xacc^\x8a0\t\x80D['
+    b'\xb8\xe6\x86\xb0\xe8\xd4\xf9\x1en\xf1\xf5^\xeb\xb8\xb8\xf8'
+    b')\xa8\xbf\xaa\x84\x86\xb1a \x95\x16\x08\x1c\xbb@\xbd+\r/\xfb'
+    b'\x92\xfbh\xf1\x8d3\xf9\x92\xde`\xf1\x86\x03\xaa+\xd9\xd9\xc6P\xaf'
+    b'\xe3-\xea\xa5\x0fB\xca\xde\xd5n^\xe3/\xbf\xa6w\xc8\x0e<M'
+    b'\xc2\x1e!\xd4\xc6E\xf2\xad\x0c\xbc\x1d\x88Y\x03\x98<\x92\xd9\xa6B'
+    b'\xc7\x83\xb5"\x97D|&\xc4\xd4\xfad\x0e\xde\x06\xa3\xc2\x9c`\xf2'
+    b'7\x03\x1a\xed\xd80\x10\xe9\x0co\x10\xcf\x18\x16\xa7\x1c'
+    b"\xe5\x96\xa4\xd9\xe1\xa5v;]\xb7\xa9\xdc'hA\xe3\x9c&\x98\x0b9\xdf~@"
+    b'\xf8\xact\x87<\xf94\x0c\x9d\x93\xb0)\xe1\xa2\x0f\x1e=:&\xd56\xa5A+'
+    b'\xab\xc4\x00\x8d\x81\x93\xd4\xd8<\x82k\\d\xd8v\xab\xbd^l5C?\xd4\xa0'
+    b'M\x12C\xc8\x80\r\xc83\xe8\xc0\xf5\xdf\xca\x05\xf4BPjy\xbe\x91\x9bzE'
+    b"\xd8[\x93oT\r\x13\x16'\x1a\xbd*H\xd6\xfe\r\xf3\x91M\x8b\xee\x8f7f"
+    b"\x0b;\xaa\x85\xf2\xdd'\x0fwM \xbd\x13\xb9\xe5\xb8\xb7 D+P\x1c\xe4g"
+    b'n\xd2\xf1kc\x15\xaf\xc6\x90V\x03\xc2UovfZ\xcc\xd23^\xb3\xe7\xbf'
+    b'\xacv\x1d\x82\xedx\xa3J\xa9\xb7\xcf\x0c\xe6j\x96n*o\x18>'
+    b'\xc6\xfd\x97_+D{\x03\x15\xe8s\xb1\xc8HAG\xcf\xf4\x1a\xdd'
+    b'\xad\x11\xbf\x157q+\xdeW\x89g"X\x82\xfd~\xf7\xab4\xf6`\xab\xf1q'
+    b')\x82\x10K\xe9sV\xfe\xe45\xafs*\x14\xa7;\xac{\x06\x9d<@\x93G'
+    b'j\x1d\xefL\xe9\xd8\x92\x19&\xa1\x16\x19\x04\tu5\x01]\xf6\xf4'
+    b'\xcd\\\xd8A|I\xd4\xeb\x05\x88C\xc6e\xacQ\xe9*\x97~\x9au\xf8Xy'
+    b"\x17P\x10\x9f\n\x8c\xe2fZEu>\x9b\x1e\x91\x0b'`\xbd\xc0\xa8\x86c\x1d"
+    b'Z\xe2\xdc8j\x95\xffU\x90\x1e\xf4o\xbc\xe5\xe3e>\xd2R\xc0b#\xbc\x15'
+    b'H-\xb9!\xde\x9d\x90k\xdew\x9b{\x99\xde\xf7/K)A\xfd\xf5\xe6:\xda'
+    b'UM\xcc\xbb\xa2\x0b\x9a\x93\xf5{9\xc0 \xd2((6i\xc0\xbbu\xd8\x9e\x8d'
+    b'\xf8\x04q\x10\xd4\x14\x9e7-\xb9B\xea\x01Q8\xc8v\x9a\x12A\x88Cd\x92'
+    b"\x1c\x8c!\xf4\x94\x87'\xe3\xcd\xae\xf7\xd8\x93\xfa\xde\xa8b\x9e\xee2"
+    b'K\xdb\x00l\x9d\t\xb1|D\x05U\xbb\xf4>\xf1w\x887\xd1}W\x9d|g|1\xb0\x13'
+    b"\xa3 \xe5\xbfm@\xc06+\xb7\t\xcf\x15D\x9a \x1fM\x1f\xd2\xb5'\xa9\xbb"
+    b'~Co\x82\xfa\xc2\t\xe6f\xfc\xbeI\xae1\x8e\xbe\xb8\xcf\x86\x17'
+    b'\x9f\xe2`\xbd\xaf\xba\xb9\xbc\x1b\xa3\xcd\x82\x8fwc\xefd\xa9\xd5\x14'
+    b'\xe2C\xafUE\xb6\x11MJH\xd0=\x05\xd4*I\xff"\r\x1b^\xcaS6=\xec@\xd5'
+    b'\x11,\xe0\x87Gr\xaa[\xb8\xbc>n\xbd\x81\x0c\x07<\xe9\x92('
+    b'\xb2\xff\xac}\xe7\xb6\x15\x90\x9f~4\x9a\xe6\xd6\xd8s\xed\x99tf'
+    b'\xa0f\xf8\xf1\x87\t\x96/)\x85\xb6\n\xd7\xb2w\x0b\xbc\xba\x99\xee'
+    b'Q\xeen\x1d\xad\x03\xc3s\xd1\xfd\xa2\xc6\xb7\x9a\x9c(G<6\xad[~H '
+    b'\x16\x89\x89\xd0\xc3\xd2\xca~\xac\xea\xa5\xed\xe5\xfb\r:'
+    b'\x8e\xa6\xf1e\xbb\xba\xbd\xe0(\xa3\x89_\x01(\xb5c\xcc\x9f\x1fg'
+    b'v\xfd\x17\xb3\x08S=S\xee\xfc\x85>\x91\x8d\x8d\nYR\xb3G\xd1A\xa2\xb1'
+    b'\xec\xb0\x01\xd2\xcd\xf9\xfe\x82\x06O\xb3\xecd\xa9c\xe0\x8eP\x90\xce'
+    b'\xe0\xcd\xd8\xd8\xdc\x9f\xaa\x01"[Q~\xe4\x88\xa1#\xc1\x12C\xcf'
+    b'\xbe\x80\x11H\xbf\x86\xd8\xbem\xcfWFQ(X\x01DK\xdfB\xaa\x10.-'
+    b'\xd5\x9e|\x86\x15\x86N]\xc7Z\x17\xcd=\xd7)M\xde\x15\xa4LTi\xa0\x15'
+    b'\xd1\xe7\xbdN\xa4?\xd1\xe7\x02\xfe4\xe4O\x89\x98&\x96\x0f\x02\x9c'
+    b'\x9e\x19\xaa\x13u7\xbd0\xdc\xd8\x93\xf4BNE\x1d\x93\x82\x81\x16'
+    b'\xe5y\xcf\x98D\xca\x9a\xe2\xfd\xcdL\xcc\xd1\xfc_\x0b\x1c\xa0]\xdc'
+    b'\xa91 \xc9c\xd8\xbf\x97\xcfp\xe6\x19-\xad\xff\xcc\xd1N(\xe8'
+    b'\xeb#\x182\x96I\xf7l\xf3r\x00'
+)
+
 
 def test_main():
     run_unittest(
index 4e2c9089b5737c2e7f07621d1fe9f174dcfecfcc..adbec8dab4266ea8002dc7f282c937de06a73571 100644 (file)
@@ -1,6 +1,7 @@
 import io
 import locale
 import mimetypes
+import pathlib
 import sys
 import unittest
 
@@ -77,6 +78,80 @@ class MimeTypesTestCase(unittest.TestCase):
                                           strict=True)
         self.assertEqual(exts, ['.g3', '.g\xb3'])
 
+    def test_init_reinitializes(self):
+        # Issue 4936: make sure an init starts clean
+        # First, put some poison into the types table
+        mimetypes.add_type('foo/bar', '.foobar')
+        self.assertEqual(mimetypes.guess_extension('foo/bar'), '.foobar')
+        # Reinitialize
+        mimetypes.init()
+        # Poison should be gone.
+        self.assertEqual(mimetypes.guess_extension('foo/bar'), None)
+
+    def test_preferred_extension(self):
+        def check_extensions():
+            self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin')
+            self.assertEqual(mimetypes.guess_extension('application/postscript'), '.ps')
+            self.assertEqual(mimetypes.guess_extension('application/vnd.apple.mpegurl'), '.m3u')
+            self.assertEqual(mimetypes.guess_extension('application/vnd.ms-excel'), '.xls')
+            self.assertEqual(mimetypes.guess_extension('application/vnd.ms-powerpoint'), '.ppt')
+            self.assertEqual(mimetypes.guess_extension('application/x-texinfo'), '.texi')
+            self.assertEqual(mimetypes.guess_extension('application/x-troff'), '.roff')
+            self.assertEqual(mimetypes.guess_extension('application/xml'), '.xsl')
+            self.assertEqual(mimetypes.guess_extension('audio/mpeg'), '.mp3')
+            self.assertEqual(mimetypes.guess_extension('image/jpeg'), '.jpg')
+            self.assertEqual(mimetypes.guess_extension('image/tiff'), '.tiff')
+            self.assertEqual(mimetypes.guess_extension('message/rfc822'), '.eml')
+            self.assertEqual(mimetypes.guess_extension('text/html'), '.html')
+            self.assertEqual(mimetypes.guess_extension('text/plain'), '.txt')
+            self.assertEqual(mimetypes.guess_extension('video/mpeg'), '.mpeg')
+            self.assertEqual(mimetypes.guess_extension('video/quicktime'), '.mov')
+
+        check_extensions()
+        mimetypes.init()
+        check_extensions()
+
+    def test_init_stability(self):
+        mimetypes.init()
+
+        suffix_map = mimetypes.suffix_map
+        encodings_map = mimetypes.encodings_map
+        types_map = mimetypes.types_map
+        common_types = mimetypes.common_types
+
+        mimetypes.init()
+        self.assertIsNot(suffix_map, mimetypes.suffix_map)
+        self.assertIsNot(encodings_map, mimetypes.encodings_map)
+        self.assertIsNot(types_map, mimetypes.types_map)
+        self.assertIsNot(common_types, mimetypes.common_types)
+        self.assertEqual(suffix_map, mimetypes.suffix_map)
+        self.assertEqual(encodings_map, mimetypes.encodings_map)
+        self.assertEqual(types_map, mimetypes.types_map)
+        self.assertEqual(common_types, mimetypes.common_types)
+
+    def test_path_like_ob(self):
+        filename = "LICENSE.txt"
+        filepath = pathlib.Path(filename)
+        filepath_with_abs_dir = pathlib.Path('/dir/'+filename)
+        filepath_relative = pathlib.Path('../dir/'+filename)
+        path_dir = pathlib.Path('./')
+
+        expected = self.db.guess_type(filename)
+
+        self.assertEqual(self.db.guess_type(filepath), expected)
+        self.assertEqual(self.db.guess_type(
+            filepath_with_abs_dir), expected)
+        self.assertEqual(self.db.guess_type(filepath_relative), expected)
+        self.assertEqual(self.db.guess_type(path_dir), (None, None))
+
+    def test_keywords_args_api(self):
+        self.assertEqual(self.db.guess_type(
+            url="foo.html", strict=True), ("text/html", None))
+        self.assertEqual(self.db.guess_all_extensions(
+            type='image/jpg', strict=True), [])
+        self.assertEqual(self.db.guess_extension(
+            type='image/jpg', strict=False), '.jpg')
+
 
 @unittest.skipUnless(sys.platform.startswith("win"), "Windows only")
 class Win32MimeTypesTestCase(unittest.TestCase):
index 265eaea59b5f4bb4837426572ea0d08b7192b78f..392886c6a967c2f18acaa7e150ab26e7e736e74a 100644 (file)
@@ -86,6 +86,7 @@ class MsiDatabaseTestCase(unittest.TestCase):
     def test_directory_start_component_keyfile(self):
         db, db_path = init_database()
         self.addCleanup(db.Close)
+        self.addCleanup(msilib._directories.clear)
         feature = msilib.Feature(db, 0, 'Feature', 'A feature', 'Python')
         cab = msilib.CAB('CAB')
         dir = msilib.Directory(db, cab, None, TESTFN, 'TARGETDIR',
index 6e31b644112215e97ef88f794dc8eb2e717dd39a..89b0d5303db5a3e5f5ff794f2a805960f4c5ec6e 100644 (file)
@@ -14,10 +14,19 @@ except ImportError:
     # but for those that require it we import here.
     nt = None
 
+
+def _norm(path):
+    if isinstance(path, (bytes, str, os.PathLike)):
+        return ntpath.normcase(os.fsdecode(path))
+    elif hasattr(path, "__iter__"):
+        return tuple(ntpath.normcase(os.fsdecode(p)) for p in path)
+    return path
+
+
 def tester(fn, wantResult):
     fn = fn.replace("\\", "\\\\")
     gotResult = eval(fn)
-    if wantResult != gotResult:
+    if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
         raise TestFailed("%s should return: %s but returned: %s" \
               %(str(fn), str(wantResult), str(gotResult)))
 
@@ -33,18 +42,22 @@ def tester(fn, wantResult):
     with warnings.catch_warnings():
         warnings.simplefilter("ignore", DeprecationWarning)
         gotResult = eval(fn)
-    if isinstance(wantResult, str):
-        wantResult = os.fsencode(wantResult)
-    elif isinstance(wantResult, tuple):
-        wantResult = tuple(os.fsencode(r) for r in wantResult)
-
-    gotResult = eval(fn)
-    if wantResult != gotResult:
+    if _norm(wantResult) != _norm(gotResult):
         raise TestFailed("%s should return: %s but returned: %s" \
               %(str(fn), str(wantResult), repr(gotResult)))
 
 
-class TestNtpath(unittest.TestCase):
+class NtpathTestCase(unittest.TestCase):
+    def assertPathEqual(self, path1, path2):
+        if path1 == path2 or _norm(path1) == _norm(path2):
+            return
+        self.assertEqual(path1, path2)
+
+    def assertPathIn(self, path, pathset):
+        self.assertIn(_norm(path), _norm(pathset))
+
+
+class TestNtpath(NtpathTestCase):
     def test_splitext(self):
         tester('ntpath.splitext("foo.ext")', ('foo', '.ext'))
         tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
@@ -461,7 +474,7 @@ class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
     attributes = ['relpath']
 
 
-class PathLikeTests(unittest.TestCase):
+class PathLikeTests(NtpathTestCase):
 
     path = ntpath
 
@@ -472,67 +485,67 @@ class PathLikeTests(unittest.TestCase):
         with open(self.file_name, 'xb', 0) as file:
             file.write(b"test_ntpath.PathLikeTests")
 
-    def assertPathEqual(self, func):
-        self.assertEqual(func(self.file_path), func(self.file_name))
+    def _check_function(self, func):
+        self.assertPathEqual(func(self.file_path), func(self.file_name))
 
     def test_path_normcase(self):
-        self.assertPathEqual(self.path.normcase)
+        self._check_function(self.path.normcase)
 
     def test_path_isabs(self):
-        self.assertPathEqual(self.path.isabs)
+        self._check_function(self.path.isabs)
 
     def test_path_join(self):
         self.assertEqual(self.path.join('a', FakePath('b'), 'c'),
                          self.path.join('a', 'b', 'c'))
 
     def test_path_split(self):
-        self.assertPathEqual(self.path.split)
+        self._check_function(self.path.split)
 
     def test_path_splitext(self):
-        self.assertPathEqual(self.path.splitext)
+        self._check_function(self.path.splitext)
 
     def test_path_splitdrive(self):
-        self.assertPathEqual(self.path.splitdrive)
+        self._check_function(self.path.splitdrive)
 
     def test_path_basename(self):
-        self.assertPathEqual(self.path.basename)
+        self._check_function(self.path.basename)
 
     def test_path_dirname(self):
-        self.assertPathEqual(self.path.dirname)
+        self._check_function(self.path.dirname)
 
     def test_path_islink(self):
-        self.assertPathEqual(self.path.islink)
+        self._check_function(self.path.islink)
 
     def test_path_lexists(self):
-        self.assertPathEqual(self.path.lexists)
+        self._check_function(self.path.lexists)
 
     def test_path_ismount(self):
-        self.assertPathEqual(self.path.ismount)
+        self._check_function(self.path.ismount)
 
     def test_path_expanduser(self):
-        self.assertPathEqual(self.path.expanduser)
+        self._check_function(self.path.expanduser)
 
     def test_path_expandvars(self):
-        self.assertPathEqual(self.path.expandvars)
+        self._check_function(self.path.expandvars)
 
     def test_path_normpath(self):
-        self.assertPathEqual(self.path.normpath)
+        self._check_function(self.path.normpath)
 
     def test_path_abspath(self):
-        self.assertPathEqual(self.path.abspath)
+        self._check_function(self.path.abspath)
 
     def test_path_realpath(self):
-        self.assertPathEqual(self.path.realpath)
+        self._check_function(self.path.realpath)
 
     def test_path_relpath(self):
-        self.assertPathEqual(self.path.relpath)
+        self._check_function(self.path.relpath)
 
     def test_path_commonpath(self):
         common_path = self.path.commonpath([self.file_path, self.file_name])
-        self.assertEqual(common_path, self.file_name)
+        self.assertPathEqual(common_path, self.file_name)
 
     def test_path_isdir(self):
-        self.assertPathEqual(self.path.isdir)
+        self._check_function(self.path.isdir)
 
 
 if __name__ == "__main__":
index a9170504004d6ca2e8d278c45db696cbcc110557..df4bad7a8cf7d587523e75935289477aad1838f0 100644 (file)
@@ -41,15 +41,6 @@ try:
     import _winapi
 except ImportError:
     _winapi = None
-try:
-    import grp
-    groups = [g.gr_gid for g in grp.getgrall() if getpass.getuser() in g.gr_mem]
-    if hasattr(os, 'getgid'):
-        process_gid = os.getgid()
-        if process_gid not in groups:
-            groups.append(process_gid)
-except ImportError:
-    groups = []
 try:
     import pwd
     all_users = [u.pw_uid for u in pwd.getpwall()]
@@ -1238,13 +1229,19 @@ class ChownFileTests(unittest.TestCase):
         self.assertIsNone(os.chown(support.TESTFN, uid, gid))
         self.assertIsNone(os.chown(support.TESTFN, -1, -1))
 
-    @unittest.skipUnless(len(groups) > 1, "test needs more than one group")
-    def test_chown(self):
+    @unittest.skipUnless(hasattr(os, 'getgroups'), 'need os.getgroups')
+    def test_chown_gid(self):
+        groups = os.getgroups()
+        if len(groups) < 2:
+            self.skipTest("test needs at least 2 groups")
+
         gid_1, gid_2 = groups[:2]
         uid = os.stat(support.TESTFN).st_uid
+
         os.chown(support.TESTFN, uid, gid_1)
         gid = os.stat(support.TESTFN).st_gid
         self.assertEqual(gid, gid_1)
+
         os.chown(support.TESTFN, uid, gid_2)
         gid = os.stat(support.TESTFN).st_gid
         self.assertEqual(gid, gid_2)
@@ -3240,6 +3237,11 @@ class FDInheritanceTests(unittest.TestCase):
         self.addCleanup(os.close, fd2)
         self.assertEqual(os.get_inheritable(fd2), False)
 
+    def test_dup_standard_stream(self):
+        fd = os.dup(1)
+        self.addCleanup(os.close, fd)
+        self.assertGreater(fd, 0)
+
     @unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
     def test_dup_nul(self):
         # os.dup() was creating inheritable fds for character files.
index f7ed1d1e48fb8fc7c1e8d322de292a93af2c924e..9c82c6451479c03e1e092757a3b9b0aa37ac30b0 100644 (file)
@@ -1271,10 +1271,13 @@ class _BasePathTest(object):
             func(*args, **kwargs)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
 
+    def assertEqualNormCase(self, path_a, path_b):
+        self.assertEqual(os.path.normcase(path_a), os.path.normcase(path_b))
+
     def _test_cwd(self, p):
         q = self.cls(os.getcwd())
         self.assertEqual(p, q)
-        self.assertEqual(str(p), str(q))
+        self.assertEqualNormCase(str(p), str(q))
         self.assertIs(type(p), type(q))
         self.assertTrue(p.is_absolute())
 
@@ -1285,7 +1288,7 @@ class _BasePathTest(object):
     def _test_home(self, p):
         q = self.cls(os.path.expanduser('~'))
         self.assertEqual(p, q)
-        self.assertEqual(str(p), str(q))
+        self.assertEqualNormCase(str(p), str(q))
         self.assertIs(type(p), type(q))
         self.assertTrue(p.is_absolute())
 
@@ -1491,15 +1494,15 @@ class _BasePathTest(object):
             p.resolve(strict=True)
         self.assertEqual(cm.exception.errno, errno.ENOENT)
         # Non-strict
-        self.assertEqual(str(p.resolve(strict=False)),
-                         os.path.join(BASE, 'foo'))
+        self.assertEqualNormCase(str(p.resolve(strict=False)),
+                                 os.path.join(BASE, 'foo'))
         p = P(BASE, 'foo', 'in', 'spam')
-        self.assertEqual(str(p.resolve(strict=False)),
-                         os.path.join(BASE, 'foo', 'in', 'spam'))
+        self.assertEqualNormCase(str(p.resolve(strict=False)),
+                                 os.path.join(BASE, 'foo', 'in', 'spam'))
         p = P(BASE, '..', 'foo', 'in', 'spam')
-        self.assertEqual(str(p.resolve(strict=False)),
-                         os.path.abspath(os.path.join('foo', 'in', 'spam')))
-        # These are all relative symlinks
+        self.assertEqualNormCase(str(p.resolve(strict=False)),
+                                 os.path.abspath(os.path.join('foo', 'in', 'spam')))
+        # These are all relative symlinks.
         p = P(BASE, 'dirB', 'fileB')
         self._check_resolve_relative(p, p)
         p = P(BASE, 'linkA')
@@ -1996,16 +1999,16 @@ class _BasePathTest(object):
         # Resolve absolute paths
         p = (P / 'link0').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
         p = (P / 'link1').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
         p = (P / 'link2').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
         p = (P / 'link3').resolve()
         self.assertEqual(p, P)
-        self.assertEqual(str(p), BASE)
+        self.assertEqualNormCase(str(p), BASE)
 
         # Resolve relative paths
         old_path = os.getcwd()
@@ -2013,16 +2016,16 @@ class _BasePathTest(object):
         try:
             p = self.cls('link0').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
             p = self.cls('link1').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
             p = self.cls('link2').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
             p = self.cls('link3').resolve()
             self.assertEqual(p, P)
-            self.assertEqual(str(p), BASE)
+            self.assertEqualNormCase(str(p), BASE)
         finally:
             os.chdir(old_path)
 
index de6c651b370a60d23a9fd8d5255021304fada046..63909e21f246d457b8ce0c47d0897d288bcf1bfe 100644 (file)
@@ -1350,6 +1350,19 @@ class PdbTestCase(unittest.TestCase):
             if save_home is not None:
                 os.environ['HOME'] = save_home
 
+    def test_readrc_homedir(self):
+        save_home = os.environ.pop("HOME", None)
+        with support.temp_dir() as temp_dir, patch("os.path.expanduser"):
+            rc_path = os.path.join(temp_dir, ".pdbrc")
+            os.path.expanduser.return_value = rc_path
+            try:
+                with open(rc_path, "w") as f:
+                    f.write("invalid")
+                self.assertEqual(pdb.Pdb().rcLines[0], "invalid")
+            finally:
+                if save_home is not None:
+                    os.environ["HOME"] = save_home
+
     def test_header(self):
         stdout = StringIO()
         header = 'Nobody expects... blah, blah, blah'
index 233fea4d57bbb0810343bab4a5309f99a0dc1777..1cd9e567b36e56ff0be7245a27bb93f8dd3aa8fa 100644 (file)
@@ -1375,6 +1375,7 @@ class PosixTester(unittest.TestCase):
         self.assertEqual(posix.sched_getaffinity(0), mask)
         self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
         self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
+        self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
         self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
         self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
 
index f0822cddec86100fc44b4e51573ec9e558b9a7e8..6b9e90594cb29879873bbb4bf9a6a4acee14aa43 100644 (file)
@@ -228,7 +228,7 @@ class TestBasicOps:
             choices([], cum_weights=[], k=5)
 
     def test_choices_subnormal(self):
-        # Subnormal weights would occassionally trigger an IndexError
+        # Subnormal weights would occasionally trigger an IndexError
         # in choices() when the value returned by random() was large
         # enough to make `random() * total` round up to the total.
         # See https://bugs.python.org/msg275594 for more detail.
index 4c6152153668d500854d4123f7810e2428bd7ba3..7336adc4f1b8bfdbbf33b8a014c0595573c008f3 100644 (file)
@@ -1121,6 +1121,48 @@ class ArgsTestCase(BaseTestCase):
                                   env_changed=[testname],
                                   fail_env_changed=True)
 
+    def test_multiprocessing_timeout(self):
+        code = textwrap.dedent(r"""
+            import time
+            import unittest
+            try:
+                import faulthandler
+            except ImportError:
+                faulthandler = None
+
+            class Tests(unittest.TestCase):
+                # test hangs and so should be stopped by the timeout
+                def test_sleep(self):
+                    # we want to test regrtest multiprocessing timeout,
+                    # not faulthandler timeout
+                    if faulthandler is not None:
+                        faulthandler.cancel_dump_traceback_later()
+
+                    time.sleep(60 * 5)
+        """)
+        testname = self.create_test(code=code)
+
+        output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=2)
+        self.check_executed_tests(output, [testname],
+                                  failed=testname)
+        self.assertRegex(output,
+                         re.compile('%s timed out' % testname, re.MULTILINE))
+
+    def test_cleanup(self):
+        dirname = os.path.join(self.tmptestdir, "test_python_123")
+        os.mkdir(dirname)
+        filename = os.path.join(self.tmptestdir, "test_python_456")
+        open(filename, "wb").close()
+        names = [dirname, filename]
+
+        cmdargs = ['-m', 'test',
+                   '--tempdir=%s' % self.tmptestdir,
+                   '--cleanup']
+        self.run_python(cmdargs)
+
+        for name in names:
+            self.assertFalse(os.path.exists(name), name)
+
 
 class TestUtils(unittest.TestCase):
     def test_format_duration(self):
index fd35788e81b27203b9a5825f498fff74cf7c79aa..6d4627d7f4eab2ca6aecf6035c57d0291fa4cd5c 100644 (file)
@@ -308,6 +308,14 @@ class ShlexTest(unittest.TestCase):
             self.assertEqual(shlex.quote("test%s'name'" % u),
                              "'test%s'\"'\"'name'\"'\"''" % u)
 
+    def testPunctuationCharsReadOnly(self):
+        punctuation_chars = "/|$%^"
+        shlex_instance = shlex.shlex(punctuation_chars=punctuation_chars)
+        self.assertEqual(shlex_instance.punctuation_chars, punctuation_chars)
+        with self.assertRaises(AttributeError):
+            shlex_instance.punctuation_chars = False
+
+
 # Allow this test to be used with old shlex.py
 if not getattr(shlex, "split", None):
     for methname in dir(ShlexTest):
index 38734009c0085248de1b92841d787b79715415b6..a0bd741c36ac296453300929a47472b025bb2b8b 100644 (file)
@@ -31,7 +31,7 @@ class MiscSourceEncodingTest(unittest.TestCase):
         try:
             compile(b"# coding: cp932\nprint '\x94\x4e'", "dummy", "exec")
         except SyntaxError as v:
-            self.assertEqual(v.text, "print '\u5e74'\n")
+            self.assertEqual(v.text.rstrip('\n'), "print '\u5e74'")
         else:
             self.fail()
 
index 4a61711f0ee6c43901e2d5194e9a5f583e2b65b0..e21e7e07455cccd2aa7b517bce1507e160d978d4 100644 (file)
@@ -19,6 +19,7 @@ import weakref
 import platform
 import functools
 import sysconfig
+import functools
 try:
     import ctypes
 except ImportError:
@@ -142,6 +143,87 @@ OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
 OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
 
 
+def has_tls_protocol(protocol):
+    """Check if a TLS protocol is available and enabled
+
+    :param protocol: enum ssl._SSLMethod member or name
+    :return: bool
+    """
+    if isinstance(protocol, str):
+        assert protocol.startswith('PROTOCOL_')
+        protocol = getattr(ssl, protocol, None)
+        if protocol is None:
+            return False
+    if protocol in {
+        ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS_SERVER,
+        ssl.PROTOCOL_TLS_CLIENT
+    }:
+        # auto-negotiate protocols are always available
+        return True
+    name = protocol.name
+    return has_tls_version(name[len('PROTOCOL_'):])
+
+
+@functools.lru_cache()
+def has_tls_version(version):
+    """Check if a TLS/SSL version is enabled
+
+    :param version: TLS version name or ssl.TLSVersion member
+    :return: bool
+    """
+    if version == "SSLv2":
+        # never supported and not even in TLSVersion enum
+        return False
+
+    if isinstance(version, str):
+        version = ssl.TLSVersion.__members__[version]
+
+    # check compile time flags like ssl.HAS_TLSv1_2
+    if not getattr(ssl, f'HAS_{version.name}'):
+        return False
+
+    # check runtime and dynamic crypto policy settings. A TLS version may
+    # be compiled in but disabled by a policy or config option.
+    ctx = ssl.SSLContext()
+    if (
+            hasattr(ctx, 'minimum_version') and
+            ctx.minimum_version != ssl.TLSVersion.MINIMUM_SUPPORTED and
+            version < ctx.minimum_version
+    ):
+        return False
+    if (
+        hasattr(ctx, 'maximum_version') and
+        ctx.maximum_version != ssl.TLSVersion.MAXIMUM_SUPPORTED and
+        version > ctx.maximum_version
+    ):
+        return False
+
+    return True
+
+
+def requires_tls_version(version):
+    """Decorator to skip tests when a required TLS version is not available
+
+    :param version: TLS version name or ssl.TLSVersion member
+    :return:
+    """
+    def decorator(func):
+        @functools.wraps(func)
+        def wrapper(*args, **kw):
+            if not has_tls_version(version):
+                raise unittest.SkipTest(f"{version} is not available.")
+            else:
+                return func(*args, **kw)
+        return wrapper
+    return decorator
+
+
+requires_minimum_version = unittest.skipUnless(
+    hasattr(ssl.SSLContext, 'minimum_version'),
+    "required OpenSSL >= 1.1.0g"
+)
+
+
 def handle_error(prefix):
     exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
     if support.verbose:
@@ -849,8 +931,8 @@ class BasicSocketTests(unittest.TestCase):
                 cert, enc, trust = element
                 self.assertIsInstance(cert, bytes)
                 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
-                self.assertIsInstance(trust, (set, bool))
-                if isinstance(trust, set):
+                self.assertIsInstance(trust, (frozenset, set, bool))
+                if isinstance(trust, (frozenset, set)):
                     trust_oids.update(trust)
 
         serverAuth = "1.3.6.1.5.5.7.3.1"
@@ -1124,19 +1206,23 @@ class ContextTests(unittest.TestCase):
             with self.assertRaises(AttributeError):
                 ctx.hostname_checks_common_name = True
 
-    @unittest.skipUnless(hasattr(ssl.SSLContext, 'minimum_version'),
-                         "required OpenSSL 1.1.0g")
+    @requires_minimum_version
+    @unittest.skipIf(IS_LIBRESSL, "see bpo-34001")
     def test_min_max_version(self):
         ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
         # OpenSSL default is MINIMUM_SUPPORTED, however some vendors like
         # Fedora override the setting to TLS 1.0.
+        minimum_range = {
+            # stock OpenSSL
+            ssl.TLSVersion.MINIMUM_SUPPORTED,
+            # Fedora 29 uses TLS 1.0 by default
+            ssl.TLSVersion.TLSv1,
+            # RHEL 8 uses TLS 1.2 by default
+            ssl.TLSVersion.TLSv1_2
+        }
+
         self.assertIn(
-            ctx.minimum_version,
-            {ssl.TLSVersion.MINIMUM_SUPPORTED,
-             # Fedora 29 uses TLS 1.0 by default
-             ssl.TLSVersion.TLSv1,
-             # RHEL 8 uses TLS 1.2 by default
-             ssl.TLSVersion.TLSv1_2}
+            ctx.minimum_version, minimum_range
         )
         self.assertEqual(
             ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED
@@ -1182,8 +1268,8 @@ class ContextTests(unittest.TestCase):
 
         ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1)
 
-        self.assertEqual(
-            ctx.minimum_version, ssl.TLSVersion.MINIMUM_SUPPORTED
+        self.assertIn(
+            ctx.minimum_version, minimum_range
         )
         self.assertEqual(
             ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED
@@ -2723,6 +2809,8 @@ class ThreadedTests(unittest.TestCase):
         for protocol in PROTOCOLS:
             if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}:
                 continue
+            if not has_tls_protocol(protocol):
+                continue
             with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
                 context = ssl.SSLContext(protocol)
                 context.load_cert_chain(CERTFILE)
@@ -3014,7 +3102,7 @@ class ThreadedTests(unittest.TestCase):
             else:
                 self.fail("Use of invalid cert should have failed!")
 
-    @unittest.skipUnless(ssl.HAS_TLSv1_3, "Test needs TLS 1.3")
+    @requires_tls_version('TLSv1_3')
     def test_wrong_cert_tls13(self):
         client_context, server_context, hostname = testing_context()
         # load client cert that is not signed by trusted CA
@@ -3109,9 +3197,7 @@ class ThreadedTests(unittest.TestCase):
                     self.assertIn(msg, repr(e))
                     self.assertIn('certificate verify failed', repr(e))
 
-    @skip_if_broken_ubuntu_ssl
-    @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
-                         "OpenSSL is compiled without SSLv2 support")
+    @requires_tls_version('SSLv2')
     def test_protocol_sslv2(self):
         """Connecting to an SSLv2 server with various client options"""
         if support.verbose:
@@ -3120,7 +3206,7 @@ class ThreadedTests(unittest.TestCase):
         try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
         try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
         try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False)
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
         try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
         # SSLv23 client with specific SSL options
@@ -3138,7 +3224,7 @@ class ThreadedTests(unittest.TestCase):
         """Connecting to an SSLv23 server with various client options"""
         if support.verbose:
             sys.stdout.write("\n")
-        if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        if has_tls_version('SSLv2'):
             try:
                 try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv2, True)
             except OSError as x:
@@ -3147,35 +3233,36 @@ class ThreadedTests(unittest.TestCase):
                     sys.stdout.write(
                         " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
                         % str(x))
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False)
         try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True)
-        try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1')
+        if has_tls_version('TLSv1'):
+            try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1')
 
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
         try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True, ssl.CERT_OPTIONAL)
-        try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
+        if has_tls_version('TLSv1'):
+            try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
 
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
         try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True, ssl.CERT_REQUIRED)
-        try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
+        if has_tls_version('TLSv1'):
+            try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
 
         # Server with specific SSL options
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False,
                            server_options=ssl.OP_NO_SSLv3)
         # Will choose TLSv1
         try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True,
                            server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
-        try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, False,
-                           server_options=ssl.OP_NO_TLSv1)
-
+        if has_tls_version('TLSv1'):
+            try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1, False,
+                               server_options=ssl.OP_NO_TLSv1)
 
-    @skip_if_broken_ubuntu_ssl
-    @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
-                         "OpenSSL is compiled without SSLv3 support")
+    @requires_tls_version('SSLv3')
     def test_protocol_sslv3(self):
         """Connecting to an SSLv3 server with various client options"""
         if support.verbose:
@@ -3183,7 +3270,7 @@ class ThreadedTests(unittest.TestCase):
         try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
         try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
         try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
-        if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        if has_tls_version('SSLv2'):
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
         try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLS, False,
                            client_options=ssl.OP_NO_SSLv3)
@@ -3193,7 +3280,7 @@ class ThreadedTests(unittest.TestCase):
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLS,
                                False, client_options=ssl.OP_NO_SSLv2)
 
-    @skip_if_broken_ubuntu_ssl
+    @requires_tls_version('TLSv1')
     def test_protocol_tlsv1(self):
         """Connecting to a TLSv1 server with various client options"""
         if support.verbose:
@@ -3201,36 +3288,32 @@ class ThreadedTests(unittest.TestCase):
         try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
         try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
         try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
-        if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        if has_tls_version('SSLv2'):
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
         try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLS, False,
                            client_options=ssl.OP_NO_TLSv1)
 
-    @skip_if_broken_ubuntu_ssl
-    @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
-                         "TLS version 1.1 not supported.")
+    @requires_tls_version('TLSv1_1')
     def test_protocol_tlsv1_1(self):
         """Connecting to a TLSv1.1 server with various client options.
            Testing against older TLS versions."""
         if support.verbose:
             sys.stdout.write("\n")
         try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
-        if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        if has_tls_version('SSLv2'):
             try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
         try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLS, False,
                            client_options=ssl.OP_NO_TLSv1_1)
 
         try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
-        try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
-        try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
+        try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
+        try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
 
-    @skip_if_broken_ubuntu_ssl
-    @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
-                         "TLS version 1.2 not supported.")
+    @requires_tls_version('TLSv1_2')
     def test_protocol_tlsv1_2(self):
         """Connecting to a TLSv1.2 server with various client options.
            Testing against older TLS versions."""
@@ -3239,9 +3322,9 @@ class ThreadedTests(unittest.TestCase):
         try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
                            server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
                            client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
-        if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        if has_tls_version('SSLv2'):
             try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
-        if hasattr(ssl, 'PROTOCOL_SSLv3'):
+        if has_tls_version('SSLv3'):
             try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
         try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLS, False,
                            client_options=ssl.OP_NO_TLSv1_2)
@@ -3684,7 +3767,7 @@ class ThreadedTests(unittest.TestCase):
                 self.assertIs(s.version(), None)
                 self.assertIs(s._sslobj, None)
                 s.connect((HOST, server.port))
-                if IS_OPENSSL_1_1_1 and ssl.HAS_TLSv1_3:
+                if IS_OPENSSL_1_1_1 and has_tls_version('TLSv1_3'):
                     self.assertEqual(s.version(), 'TLSv1.3')
                 elif ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
                     self.assertEqual(s.version(), 'TLSv1.2')
@@ -3693,8 +3776,7 @@ class ThreadedTests(unittest.TestCase):
             self.assertIs(s._sslobj, None)
             self.assertIs(s.version(), None)
 
-    @unittest.skipUnless(ssl.HAS_TLSv1_3,
-                         "test requires TLSv1.3 enabled OpenSSL")
+    @requires_tls_version('TLSv1_3')
     def test_tls1_3(self):
         context = ssl.SSLContext(ssl.PROTOCOL_TLS)
         context.load_cert_chain(CERTFILE)
@@ -3711,9 +3793,9 @@ class ThreadedTests(unittest.TestCase):
                 })
                 self.assertEqual(s.version(), 'TLSv1.3')
 
-    @unittest.skipUnless(hasattr(ssl.SSLContext, 'minimum_version'),
-                         "required OpenSSL 1.1.0g")
-    def test_min_max_version(self):
+    @requires_minimum_version
+    @requires_tls_version('TLSv1_2')
+    def test_min_max_version_tlsv1_2(self):
         client_context, server_context, hostname = testing_context()
         # client TLSv1.0 to 1.2
         client_context.minimum_version = ssl.TLSVersion.TLSv1
@@ -3728,7 +3810,13 @@ class ThreadedTests(unittest.TestCase):
                 s.connect((HOST, server.port))
                 self.assertEqual(s.version(), 'TLSv1.2')
 
+    @requires_minimum_version
+    @requires_tls_version('TLSv1_1')
+    def test_min_max_version_tlsv1_1(self):
+        client_context, server_context, hostname = testing_context()
         # client 1.0 to 1.2, server 1.0 to 1.1
+        client_context.minimum_version = ssl.TLSVersion.TLSv1
+        client_context.maximum_version = ssl.TLSVersion.TLSv1_2
         server_context.minimum_version = ssl.TLSVersion.TLSv1
         server_context.maximum_version = ssl.TLSVersion.TLSv1_1
 
@@ -3738,6 +3826,10 @@ class ThreadedTests(unittest.TestCase):
                 s.connect((HOST, server.port))
                 self.assertEqual(s.version(), 'TLSv1.1')
 
+    @requires_minimum_version
+    @requires_tls_version('TLSv1_2')
+    def test_min_max_version_mismatch(self):
+        client_context, server_context, hostname = testing_context()
         # client 1.0, server 1.2 (mismatch)
         server_context.minimum_version = ssl.TLSVersion.TLSv1_2
         server_context.maximum_version = ssl.TLSVersion.TLSv1_2
@@ -3750,10 +3842,8 @@ class ThreadedTests(unittest.TestCase):
                     s.connect((HOST, server.port))
                 self.assertIn("alert", str(e.exception))
 
-
-    @unittest.skipUnless(hasattr(ssl.SSLContext, 'minimum_version'),
-                         "required OpenSSL 1.1.0g")
-    @unittest.skipUnless(ssl.HAS_SSLv3, "requires SSLv3 support")
+    @requires_minimum_version
+    @requires_tls_version('SSLv3')
     def test_min_max_version_sslv3(self):
         client_context, server_context, hostname = testing_context()
         server_context.minimum_version = ssl.TLSVersion.SSLv3
@@ -4272,7 +4362,7 @@ class ThreadedTests(unittest.TestCase):
                                  'Session refers to a different SSLContext.')
 
 
-@unittest.skipUnless(ssl.HAS_TLSv1_3, "Test needs TLS 1.3")
+@unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3")
 class TestPostHandshakeAuth(unittest.TestCase):
     def test_pha_setter(self):
         protocols = [
index 8419061b2a901346a6613dcbe950844ac733144c..9f494dab408ca6393fad130d9af7af43eeb6b87d 100644 (file)
@@ -11,6 +11,7 @@ import os
 import errno
 import tempfile
 import time
+import traceback
 import selectors
 import sysconfig
 import select
@@ -59,10 +60,14 @@ class BaseTestCase(unittest.TestCase):
         support.reap_children()
 
     def tearDown(self):
-        for inst in subprocess._active:
-            inst.wait()
-        subprocess._cleanup()
-        self.assertFalse(subprocess._active, "subprocess._active not empty")
+        if not mswindows:
+            # subprocess._active is not used on Windows and is set to None.
+            for inst in subprocess._active:
+                inst.wait()
+            subprocess._cleanup()
+            self.assertFalse(
+                subprocess._active, "subprocess._active not empty"
+            )
         self.doCleanups()
         support.reap_children()
 
@@ -1504,6 +1509,26 @@ class RunFuncTestCase(BaseTestCase):
         self.assertIn('stderr', c.exception.args[0])
         self.assertIn('capture_output', c.exception.args[0])
 
+    # This test _might_ wind up a bit fragile on loaded build+test machines
+    # as it depends on the timing with wide enough margins for normal situations
+    # but does assert that it happened "soon enough" to believe the right thing
+    # happened.
+    @unittest.skipIf(mswindows, "requires posix like 'sleep' shell command")
+    def test_run_with_shell_timeout_and_capture_output(self):
+        """Output capturing after a timeout mustn't hang forever on open filehandles."""
+        before_secs = time.monotonic()
+        try:
+            subprocess.run('sleep 3', shell=True, timeout=0.1,
+                           capture_output=True)  # New session unspecified.
+        except subprocess.TimeoutExpired as exc:
+            after_secs = time.monotonic()
+            stacks = traceback.format_exc()  # assertRaises doesn't give this.
+        else:
+            self.fail("TimeoutExpired not raised.")
+        self.assertLess(after_secs - before_secs, 1.5,
+                        msg="TimeoutExpired was delayed! Bad traceback:\n```\n"
+                        f"{stacks}```")
+
 
 @unittest.skipIf(mswindows, "POSIX specific tests")
 class POSIXProcessTestCase(BaseTestCase):
@@ -2622,8 +2647,12 @@ class POSIXProcessTestCase(BaseTestCase):
         with support.check_warnings(('', ResourceWarning)):
             p = None
 
-        # check that p is in the active processes list
-        self.assertIn(ident, [id(o) for o in subprocess._active])
+        if mswindows:
+            # subprocess._active is not used on Windows and is set to None.
+            self.assertIsNone(subprocess._active)
+        else:
+            # check that p is in the active processes list
+            self.assertIn(ident, [id(o) for o in subprocess._active])
 
     def test_leak_fast_process_del_killed(self):
         # Issue #12650: on Unix, if Popen.__del__() was called before the
@@ -2644,8 +2673,12 @@ class POSIXProcessTestCase(BaseTestCase):
             p = None
 
         os.kill(pid, signal.SIGKILL)
-        # check that p is in the active processes list
-        self.assertIn(ident, [id(o) for o in subprocess._active])
+        if mswindows:
+            # subprocess._active is not used on Windows and is set to None.
+            self.assertIsNone(subprocess._active)
+        else:
+            # check that p is in the active processes list
+            self.assertIn(ident, [id(o) for o in subprocess._active])
 
         # let some time for the process to exit, and create a new Popen: this
         # should trigger the wait() of p
@@ -2657,7 +2690,11 @@ class POSIXProcessTestCase(BaseTestCase):
                 pass
         # p should have been wait()ed on, and removed from the _active list
         self.assertRaises(OSError, os.waitpid, pid, 0)
-        self.assertNotIn(ident, [id(o) for o in subprocess._active])
+        if mswindows:
+            # subprocess._active is not used on Windows and is set to None.
+            self.assertIsNone(subprocess._active)
+        else:
+            self.assertNotIn(ident, [id(o) for o in subprocess._active])
 
     def test_close_fds_after_preexec(self):
         fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
index ef3fee13b96100a37dc2cd6d413e0e55d38d1c84..84927a393f17593620d67bc7eff5219409dfb0f2 100644 (file)
-import unittest, test.support
+from test import support
 from test.support.script_helper import assert_python_ok, assert_python_failure
-import sys, io, os
+import builtins
+import codecs
+import gc
+import locale
+import operator
+import os
 import struct
 import subprocess
+import sys
+import sysconfig
+import test.support
 import textwrap
+import unittest
 import warnings
-import operator
-import codecs
-import gc
-import sysconfig
-import locale
-import threading
+
 
 # count the number of test runs, used to create unique
 # strings to intern in test_intern()
-numruns = 0
+INTERN_NUMRUNS = 0
 
 
-class SysModuleTest(unittest.TestCase):
+class DisplayHookTest(unittest.TestCase):
 
-    def setUp(self):
-        self.orig_stdout = sys.stdout
-        self.orig_stderr = sys.stderr
-        self.orig_displayhook = sys.displayhook
+    def test_original_displayhook(self):
+        dh = sys.__displayhook__
 
-    def tearDown(self):
-        sys.stdout = self.orig_stdout
-        sys.stderr = self.orig_stderr
-        sys.displayhook = self.orig_displayhook
-        test.support.reap_children()
+        with support.captured_stdout() as out:
+            dh(42)
 
-    def test_original_displayhook(self):
-        import builtins
-        out = io.StringIO()
-        sys.stdout = out
+        self.assertEqual(out.getvalue(), "42\n")
+        self.assertEqual(builtins._, 42)
 
-        dh = sys.__displayhook__
+        del builtins._
 
-        self.assertRaises(TypeError, dh)
-        if hasattr(builtins, "_"):
-            del builtins._
+        with support.captured_stdout() as out:
+            dh(None)
 
-        dh(None)
         self.assertEqual(out.getvalue(), "")
         self.assertTrue(not hasattr(builtins, "_"))
-        dh(42)
-        self.assertEqual(out.getvalue(), "42\n")
-        self.assertEqual(builtins._, 42)
 
-        del sys.stdout
-        self.assertRaises(RuntimeError, dh, 42)
+        # sys.displayhook() requires arguments
+        self.assertRaises(TypeError, dh)
+
+        stdout = sys.stdout
+        try:
+            del sys.stdout
+            self.assertRaises(RuntimeError, dh, 42)
+        finally:
+            sys.stdout = stdout
 
     def test_lost_displayhook(self):
-        del sys.displayhook
-        code = compile("42", "<string>", "single")
-        self.assertRaises(RuntimeError, eval, code)
+        displayhook = sys.displayhook
+        try:
+            del sys.displayhook
+            code = compile("42", "<string>", "single")
+            self.assertRaises(RuntimeError, eval, code)
+        finally:
+            sys.displayhook = displayhook
 
     def test_custom_displayhook(self):
         def baddisplayhook(obj):
             raise ValueError
-        sys.displayhook = baddisplayhook
-        code = compile("42", "<string>", "single")
-        self.assertRaises(ValueError, eval, code)
 
-    def test_original_excepthook(self):
-        err = io.StringIO()
-        sys.stderr = err
+        with support.swap_attr(sys, 'displayhook', baddisplayhook):
+            code = compile("42", "<string>", "single")
+            self.assertRaises(ValueError, eval, code)
+
 
-        eh = sys.__excepthook__
+class ExceptHookTest(unittest.TestCase):
 
-        self.assertRaises(TypeError, eh)
+    def test_original_excepthook(self):
         try:
             raise ValueError(42)
         except ValueError as exc:
-            eh(*sys.exc_info())
+            with support.captured_stderr() as err:
+                sys.__excepthook__(*sys.exc_info())
 
         self.assertTrue(err.getvalue().endswith("ValueError: 42\n"))
 
+        self.assertRaises(TypeError, sys.__excepthook__)
+
+    def test_excepthook_bytes_filename(self):
+        # bpo-37467: sys.excepthook() must not crash if a filename
+        # is a bytes string
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', BytesWarning)
+
+            try:
+                raise SyntaxError("msg", (b"bytes_filename", 123, 0, "text"))
+            except SyntaxError as exc:
+                with support.captured_stderr() as err:
+                    sys.__excepthook__(*sys.exc_info())
+
+        err = err.getvalue()
+        self.assertIn("""  File "b'bytes_filename'", line 123\n""", err)
+        self.assertIn("""    text\n""", err)
+        self.assertTrue(err.endswith("SyntaxError: msg\n"))
+
     def test_excepthook(self):
         with test.support.captured_output("stderr") as stderr:
             sys.excepthook(1, '1', 1)
@@ -86,6 +107,12 @@ class SysModuleTest(unittest.TestCase):
     # FIXME: testing the code for a lost or replaced excepthook in
     # Python/pythonrun.c::PyErr_PrintEx() is tricky.
 
+
+class SysModuleTest(unittest.TestCase):
+
+    def tearDown(self):
+        test.support.reap_children()
+
     def test_exit(self):
         # call with two arguments
         self.assertRaises(TypeError, sys.exit, 42, 42)
@@ -502,10 +529,10 @@ class SysModuleTest(unittest.TestCase):
         self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
 
     def test_intern(self):
-        global numruns
-        numruns += 1
+        global INTERN_NUMRUNS
+        INTERN_NUMRUNS += 1
         self.assertRaises(TypeError, sys.intern)
-        s = "never interned before" + str(numruns)
+        s = "never interned before" + str(INTERN_NUMRUNS)
         self.assertTrue(sys.intern(s) is s)
         s2 = s.swapcase().swapcase()
         self.assertTrue(sys.intern(s2) is s)
index 710756bde64c04fd2758e38c545043e2e2726e8a..931312831616c2aed8dccf8090b60b08136a1636 100644 (file)
@@ -3,6 +3,7 @@ import tempfile
 import errno
 import io
 import os
+import pathlib
 import signal
 import sys
 import re
@@ -61,6 +62,9 @@ class TestLowLevelInternals(unittest.TestCase):
         with self.assertRaises(TypeError):
             tempfile._infer_return_type(b'', None, '')
 
+    def test_infer_return_type_pathlib(self):
+        self.assertIs(str, tempfile._infer_return_type(pathlib.Path('/')))
+
 
 # Common functionality.
 
@@ -84,8 +88,13 @@ class BaseTestCase(unittest.TestCase):
         nsuf  = nbase[len(nbase)-len(suf):]
 
         if dir is not None:
-            self.assertIs(type(name), str if type(dir) is str else bytes,
-                          "unexpected return type")
+            self.assertIs(
+                type(name),
+                str
+                if type(dir) is str or isinstance(dir, os.PathLike) else
+                bytes,
+                "unexpected return type",
+            )
         if pre is not None:
             self.assertIs(type(name), str if type(pre) is str else bytes,
                           "unexpected return type")
@@ -430,6 +439,7 @@ class TestMkstempInner(TestBadTempdir, BaseTestCase):
         dir = tempfile.mkdtemp()
         try:
             self.do_create(dir=dir).write(b"blat")
+            self.do_create(dir=pathlib.Path(dir)).write(b"blat")
         finally:
             os.rmdir(dir)
 
@@ -666,6 +676,7 @@ class TestMkstemp(BaseTestCase):
         dir = tempfile.mkdtemp()
         try:
             self.do_create(dir=dir)
+            self.do_create(dir=pathlib.Path(dir))
         finally:
             os.rmdir(dir)
 
@@ -735,6 +746,7 @@ class TestMkdtemp(TestBadTempdir, BaseTestCase):
         dir = tempfile.mkdtemp()
         try:
             os.rmdir(self.do_create(dir=dir))
+            os.rmdir(self.do_create(dir=pathlib.Path(dir)))
         finally:
             os.rmdir(dir)
 
index b54fc826ae0aa70c7875ca67e3f52cc43f14f1f4..b07c07cbfc4df6c1bc6521855852f4517ef3a123 100644 (file)
@@ -150,6 +150,7 @@ class TCPTimeoutTestCase(TimeoutTestCase):
     def tearDown(self):
         self.sock.close()
 
+    @unittest.skipIf(True, 'need to replace these hosts; see bpo-35518')
     def testConnectTimeout(self):
         # Testing connect timeout is tricky: we need to have IP connectivity
         # to a host that silently drops our packets.  We can't simulate this
index b396283a02ee32a41031a9fe5695f9d362c77801..4871fb7c4ddc3f3db6f6a13353299ee6ac94391a 100644 (file)
@@ -2536,6 +2536,34 @@ class XMethBad2(NamedTuple):
         with self.assertRaises(TypeError):
             NamedTuple('Name', x=1, y='a')
 
+    def test_namedtuple_special_keyword_names(self):
+        NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list)
+        self.assertEqual(NT.__name__, 'NT')
+        self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields'))
+        a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)])
+        self.assertEqual(a.cls, str)
+        self.assertEqual(a.self, 42)
+        self.assertEqual(a.typename, 'foo')
+        self.assertEqual(a.fields, [('bar', tuple)])
+
+    def test_namedtuple_errors(self):
+        with self.assertRaises(TypeError):
+            NamedTuple.__new__()
+        with self.assertRaises(TypeError):
+            NamedTuple()
+        with self.assertRaises(TypeError):
+            NamedTuple('Emp', [('name', str)], None)
+        with self.assertRaises(ValueError):
+            NamedTuple('Emp', [('_name', str)])
+
+        Emp = NamedTuple(typename='Emp', name=str, id=int)
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp._fields, ('name', 'id'))
+
+        Emp = NamedTuple('Emp', fields=[('name', str), ('id', int)])
+        self.assertEqual(Emp.__name__, 'Emp')
+        self.assertEqual(Emp._fields, ('name', 'id'))
+
     def test_pickle(self):
         global Emp  # pickle wants to reference the class by name
         Emp = NamedTuple('Emp', [('name', str), ('id', int)])
index 1aad9334074c5cc22af16414826d8db67292e0f5..4ebd82d3e0c2f131d74ffd132c4bf7ecad7706b0 100644 (file)
@@ -11,6 +11,7 @@ import itertools
 import operator
 import struct
 import sys
+import unicodedata
 import unittest
 import warnings
 from test import support, string_tests
@@ -615,11 +616,21 @@ class UnicodeTest(string_tests.CommonTest,
         self.checkequalnofix(True, '\u2000', 'isspace')
         self.checkequalnofix(True, '\u200a', 'isspace')
         self.checkequalnofix(False, '\u2014', 'isspace')
-        # apparently there are no non-BMP spaces chars in Unicode 6
+        # There are no non-BMP whitespace chars as of Unicode 12.
         for ch in ['\U00010401', '\U00010427', '\U00010429', '\U0001044E',
                    '\U0001F40D', '\U0001F46F']:
             self.assertFalse(ch.isspace(), '{!a} is not space.'.format(ch))
 
+    @support.requires_resource('cpu')
+    def test_isspace_invariant(self):
+        for codepoint in range(sys.maxunicode + 1):
+            char = chr(codepoint)
+            bidirectional = unicodedata.bidirectional(char)
+            category = unicodedata.category(char)
+            self.assertEqual(char.isspace(),
+                             (bidirectional in ('WS', 'B', 'S')
+                              or category == 'Zs'))
+
     def test_isalnum(self):
         super().test_isalnum()
         for ch in ['\U00010401', '\U00010427', '\U00010429', '\U0001044E',
index 554abfab3163159ea021c6d181bcef8374bffa56..06fe1979ddcc70504a033d793ee88c9cd7d6f8bd 100644 (file)
@@ -228,6 +228,8 @@ class UTF8ModeTests(unittest.TestCase):
 
         if sys.platform == 'darwin' or support.is_android:
             c_arg = arg_utf8
+        elif sys.platform.startswith("aix"):
+            c_arg = arg.decode('iso-8859-1')
         else:
             c_arg = arg_ascii
         for loc in POSIX_LOCALES:
index 67f9f46e65e08c53cbc0ccae09fb906ef63f352b..9cfd72f8b1fd12bca59706a6f08d30d2329de61d 100644 (file)
@@ -9,6 +9,7 @@ import ensurepip
 import os
 import os.path
 import re
+import shutil
 import struct
 import subprocess
 import sys
@@ -325,6 +326,25 @@ class BasicTest(BaseTest):
             'pool.terminate()'])
         self.assertEqual(out.strip(), "python".encode())
 
+    @unittest.skipIf(os.name == 'nt', 'not relevant on Windows')
+    def test_deactivate_with_strict_bash_opts(self):
+        bash = shutil.which("bash")
+        if bash is None:
+            self.skipTest("bash required for this test")
+        rmtree(self.env_dir)
+        builder = venv.EnvBuilder(clear=True)
+        builder.create(self.env_dir)
+        activate = os.path.join(self.env_dir, self.bindir, "activate")
+        test_script = os.path.join(self.env_dir, "test_strict.sh")
+        with open(test_script, "w") as f:
+            f.write("set -euo pipefail\n"
+                    f"source {activate}\n"
+                    "deactivate\n")
+        out, err = check_output([bash, test_script])
+        self.assertEqual(out, "".encode())
+        self.assertEqual(err, "".encode())
+
+
 @requireVenvCreate
 class EnsurePipTest(BaseTest):
     """Test venv module installation of pip."""
@@ -438,8 +458,9 @@ class EnsurePipTest(BaseTest):
         #    Please check the permissions and owner of that directory. If
         #    executing pip with sudo, you may want sudo's -H flag."
         # where $HOME is replaced by the HOME environment variable.
-        err = re.sub("^The directory .* or its parent directory is not owned "
-                     "by the current user .*$", "", err, flags=re.MULTILINE)
+        err = re.sub("^(WARNING: )?The directory .* or its parent directory "
+                     "is not owned by the current user .*$", "",
+                     err, flags=re.MULTILINE)
         self.assertEqual(err.rstrip(), "")
         # Being fairly specific regarding the expected behaviour for the
         # initial bundling phase in Python 3.4. If the output changes in
index ad7a6acfcc7d0bea01d7e59a0b0c4aca68d7550f..d3396fc9cf90ced651450f8df3e82ed59e14698a 100644 (file)
@@ -1770,6 +1770,11 @@ class MappingTestCase(TestBase):
         # copying should not result in a crash.
         self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True)
 
+    @support.cpython_only
+    def test_remove_closure(self):
+        d = weakref.WeakValueDictionary()
+        self.assertIsNone(d._remove.__closure__)
+
 
 from test import mapping_tests
 
index 11d054e16cdbfaa9a7dbacdcfaa8d80e9f9095ee..be9313db7855983481fa3b0393d2aedd44a01144 100644 (file)
@@ -41,6 +41,7 @@ test_data = [
     ("String Val",    "A string value",                        REG_SZ),
     ("StringExpand",  "The path is %path%",                    REG_EXPAND_SZ),
     ("Multi-string",  ["Lots", "of", "string", "values"],      REG_MULTI_SZ),
+    ("Multi-nul",     ["", "", "", ""],                        REG_MULTI_SZ),
     ("Raw Data",      b"binary\x00data",                       REG_BINARY),
     ("Big String",    "x"*(2**14-1),                           REG_SZ),
     ("Big Binary",    b"x"*(2**14),                            REG_BINARY),
index 7650e1392c5702a549358dc1adc827cd21e6e08d..da9481f839bf600ee00187db064c09698794f266 100644 (file)
@@ -540,32 +540,62 @@ class TestHandler(ErrorHandler):
 
 
 class HandlerTests(TestCase):
-
-    def checkEnvironAttrs(self, handler):
-        env = handler.environ
-        for attr in [
-            'version','multithread','multiprocess','run_once','file_wrapper'
-        ]:
-            if attr=='file_wrapper' and handler.wsgi_file_wrapper is None:
-                continue
-            self.assertEqual(getattr(handler,'wsgi_'+attr),env['wsgi.'+attr])
-
-    def checkOSEnviron(self,handler):
-        empty = {}; setup_testing_defaults(empty)
-        env = handler.environ
-        from os import environ
-        for k,v in environ.items():
-            if k not in empty:
-                self.assertEqual(env[k],v)
-        for k,v in empty.items():
-            self.assertIn(k, env)
+    # testEnviron() can produce long error message
+    maxDiff = 80 * 50
 
     def testEnviron(self):
-        h = TestHandler(X="Y")
-        h.setup_environ()
-        self.checkEnvironAttrs(h)
-        self.checkOSEnviron(h)
-        self.assertEqual(h.environ["X"],"Y")
+        os_environ = {
+            # very basic environment
+            'HOME': '/my/home',
+            'PATH': '/my/path',
+            'LANG': 'fr_FR.UTF-8',
+
+            # set some WSGI variables
+            'SCRIPT_NAME': 'test_script_name',
+            'SERVER_NAME': 'test_server_name',
+        }
+
+        with support.swap_attr(TestHandler, 'os_environ', os_environ):
+            # override X and HOME variables
+            handler = TestHandler(X="Y", HOME="/override/home")
+            handler.setup_environ()
+
+        # Check that wsgi_xxx attributes are copied to wsgi.xxx variables
+        # of handler.environ
+        for attr in ('version', 'multithread', 'multiprocess', 'run_once',
+                     'file_wrapper'):
+            self.assertEqual(getattr(handler, 'wsgi_' + attr),
+                             handler.environ['wsgi.' + attr])
+
+        # Test handler.environ as a dict
+        expected = {}
+        setup_testing_defaults(expected)
+        # Handler inherits os_environ variables which are not overriden
+        # by SimpleHandler.add_cgi_vars() (SimpleHandler.base_env)
+        for key, value in os_environ.items():
+            if key not in expected:
+                expected[key] = value
+        expected.update({
+            # X doesn't exist in os_environ
+            "X": "Y",
+            # HOME is overriden by TestHandler
+            'HOME': "/override/home",
+
+            # overriden by setup_testing_defaults()
+            "SCRIPT_NAME": "",
+            "SERVER_NAME": "127.0.0.1",
+
+            # set by BaseHandler.setup_environ()
+            'wsgi.input': handler.get_stdin(),
+            'wsgi.errors': handler.get_stderr(),
+            'wsgi.version': (1, 0),
+            'wsgi.run_once': False,
+            'wsgi.url_scheme': 'http',
+            'wsgi.multithread': True,
+            'wsgi.multiprocess': True,
+            'wsgi.file_wrapper': util.FileWrapper,
+        })
+        self.assertDictEqual(handler.environ, expected)
 
     def testCGIEnviron(self):
         h = BaseCGIHandler(None,None,None,{})
index 8103f347452d35b273f56ee9c280080becbc6205..30e693c8de03548344a038d0dc946e1d3a3ca8d0 100644 (file)
@@ -420,9 +420,9 @@ def dedent(text):
 
     Note that tabs and spaces are both treated as whitespace, but they
     are not equal: the lines "  hello" and "\\thello" are
-    considered to have no common leading whitespace.  (This behaviour is
-    new in Python 2.5; older versions of this module incorrectly
-    expanded tabs before searching for common leading whitespace.)
+    considered to have no common leading whitespace.
+
+    Entirely blank lines are normalized to a newline character.
     """
     # Look for the longest leading string of spaces and tabs common to
     # all lines.
index 0fb3bdd55cd76a1c9a59b5d9b8f146988aa26acf..b597336a150677ef07598d218a2744ae570f405d 100644 (file)
@@ -1122,8 +1122,7 @@ class Thread:
         main thread is not a daemon thread and therefore all threads created in
         the main thread default to daemon = False.
 
-        The entire Python program exits when no alive non-daemon threads are
-        left.
+        The entire Python program exits when only daemon threads are left.
 
         """
         assert self._initialized, "Thread.__init__() not called"
index 9851cb4c7ebd6f8a21a856090f9a87c482e8c531..021ef9552e6529bbd0082611b4b3d3f5dcb3fd44 100644 (file)
@@ -1405,13 +1405,36 @@ class NamedTuple(metaclass=NamedTupleMeta):
     """
     _root = True
 
-    def __new__(self, typename, fields=None, **kwargs):
+    def __new__(*args, **kwargs):
+        if not args:
+            raise TypeError('NamedTuple.__new__(): not enough arguments')
+        cls, *args = args  # allow the "cls" keyword be passed
+        if args:
+            typename, *args = args # allow the "typename" keyword be passed
+        elif 'typename' in kwargs:
+            typename = kwargs.pop('typename')
+        else:
+            raise TypeError("NamedTuple.__new__() missing 1 required positional "
+                            "argument: 'typename'")
+        if args:
+            try:
+                fields, = args # allow the "fields" keyword be passed
+            except ValueError:
+                raise TypeError(f'NamedTuple.__new__() takes from 2 to 3 '
+                                f'positional arguments but {len(args) + 2} '
+                                f'were given') from None
+        elif 'fields' in kwargs and len(kwargs) == 1:
+            fields = kwargs.pop('fields')
+        else:
+            fields = None
+
         if fields is None:
             fields = kwargs.items()
         elif kwargs:
             raise TypeError("Either list of fields or keywords"
                             " can be provided to NamedTuple, not both")
         return _make_nmtuple(typename, fields)
+    __new__.__text_signature__ = '($cls, typename, fields=None, /, **kwargs)'
 
 
 def NewType(name, tp):
index 569a5146c8c12915fa4cefa54083a91fbd9cffc2..2b9e7f14a7563586430dd4be3e6ded615516b53e 100644 (file)
@@ -62,6 +62,15 @@ def _is_exception(obj):
     )
 
 
+def _extract_mock(obj):
+    # Autospecced functions will return a FunctionType with "mock" attribute
+    # which is the actual mock object that needs to be used.
+    if isinstance(obj, FunctionTypes) and hasattr(obj, 'mock'):
+        return obj.mock
+    else:
+        return obj
+
+
 def _get_signature_object(func, as_instance, eat_self):
     """
     Given an arbitrary, possibly callable object, try to create a suitable
@@ -323,13 +332,7 @@ class _CallList(list):
 
 
 def _check_and_set_parent(parent, value, name, new_name):
-    # function passed to create_autospec will have mock
-    # attribute attached to which parent must be set
-    if isinstance(value, FunctionTypes):
-        try:
-            value = value.mock
-        except AttributeError:
-            pass
+    value = _extract_mock(value)
 
     if not _is_instance_mock(value):
         return False
@@ -433,10 +436,12 @@ class NonCallableMock(Base):
         Attach a mock as an attribute of this one, replacing its name and
         parent. Calls to the attached mock will be recorded in the
         `method_calls` and `mock_calls` attributes of this one."""
-        mock._mock_parent = None
-        mock._mock_new_parent = None
-        mock._mock_name = ''
-        mock._mock_new_name = None
+        inner_mock = _extract_mock(mock)
+
+        inner_mock._mock_parent = None
+        inner_mock._mock_new_parent = None
+        inner_mock._mock_name = ''
+        inner_mock._mock_new_name = None
 
         setattr(self, attribute, mock)
 
@@ -766,6 +771,35 @@ class NonCallableMock(Base):
         return message % (expected_string, actual_string)
 
 
+    def _get_call_signature_from_name(self, name):
+        """
+        * If call objects are asserted against a method/function like obj.meth1
+        then there could be no name for the call object to lookup. Hence just
+        return the spec_signature of the method/function being asserted against.
+        * If the name is not empty then remove () and split by '.' to get
+        list of names to iterate through the children until a potential
+        match is found. A child mock is created only during attribute access
+        so if we get a _SpecState then no attributes of the spec were accessed
+        and can be safely exited.
+        """
+        if not name:
+            return self._spec_signature
+
+        sig = None
+        names = name.replace('()', '').split('.')
+        children = self._mock_children
+
+        for name in names:
+            child = children.get(name)
+            if child is None or isinstance(child, _SpecState):
+                break
+            else:
+                children = child._mock_children
+                sig = child._spec_signature
+
+        return sig
+
+
     def _call_matcher(self, _call):
         """
         Given a call (or simply an (args, kwargs) tuple), return a
@@ -773,7 +807,12 @@ class NonCallableMock(Base):
         This is a best effort method which relies on the spec's signature,
         if available, or falls back on the arguments themselves.
         """
-        sig = self._spec_signature
+
+        if isinstance(_call, tuple) and len(_call) > 2:
+            sig = self._get_call_signature_from_name(_call[0])
+        else:
+            sig = self._spec_signature
+
         if sig is not None:
             if len(_call) == 2:
                 name = ''
@@ -856,13 +895,20 @@ class NonCallableMock(Base):
         If `any_order` is True then the calls can be in any order, but
         they must all appear in `mock_calls`."""
         expected = [self._call_matcher(c) for c in calls]
-        cause = expected if isinstance(expected, Exception) else None
+        cause = next((e for e in expected if isinstance(e, Exception)), None)
         all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
         if not any_order:
             if expected not in all_calls:
+                if cause is None:
+                    problem = 'Calls not found.'
+                else:
+                    problem = ('Error processing expected calls.\n'
+                               'Errors: {}').format(
+                                   [e if isinstance(e, Exception) else None
+                                    for e in expected])
                 raise AssertionError(
-                    'Calls not found.\nExpected: %r\n'
-                    'Actual: %r' % (_CallList(calls), self.mock_calls)
+                    '%s\nExpected: %r\nActual: %r' % (
+                        problem, _CallList(calls), self.mock_calls)
                 ) from cause
             return
 
@@ -1837,10 +1883,10 @@ def _set_return_value(mock, method, name):
         method.return_value = fixed
         return
 
-    return_calulator = _calculate_return_value.get(name)
-    if return_calulator is not None:
+    return_calculator = _calculate_return_value.get(name)
+    if return_calculator is not None:
         try:
-            return_value = return_calulator(mock)
+            return_value = return_calculator(mock)
         except AttributeError:
             # XXXX why do we return AttributeError here?
             #      set it as a side_effect instead?
index f92b921fe664aaa202ec1c378d6b7318b4208d23..3046d4cfe639385ffab4ea84f38322ce08dc7bca 100644 (file)
@@ -1,4 +1,5 @@
 import copy
+import re
 import sys
 import tempfile
 
@@ -39,6 +40,9 @@ class Something(object):
         pass
 
 
+def something(a): pass
+
+
 class MockTest(unittest.TestCase):
 
     def test_all(self):
@@ -1311,6 +1315,54 @@ class MockTest(unittest.TestCase):
                         )
 
 
+    def test_assert_has_calls_nested_spec(self):
+        class Something:
+
+            def __init__(self): pass
+            def meth(self, a, b, c, d=None): pass
+
+            class Foo:
+
+                def __init__(self, a): pass
+                def meth1(self, a, b): pass
+
+        mock_class = create_autospec(Something)
+
+        for m in [mock_class, mock_class()]:
+            m.meth(1, 2, 3, d=1)
+            m.assert_has_calls([call.meth(1, 2, 3, d=1)])
+            m.assert_has_calls([call.meth(1, 2, 3, 1)])
+
+        mock_class.reset_mock()
+
+        for m in [mock_class, mock_class()]:
+            self.assertRaises(AssertionError, m.assert_has_calls, [call.Foo()])
+            m.Foo(1).meth1(1, 2)
+            m.assert_has_calls([call.Foo(1), call.Foo(1).meth1(1, 2)])
+            m.Foo.assert_has_calls([call(1), call().meth1(1, 2)])
+
+        mock_class.reset_mock()
+
+        invalid_calls = [call.meth(1),
+                         call.non_existent(1),
+                         call.Foo().non_existent(1),
+                         call.Foo().meth(1, 2, 3, 4)]
+
+        for kall in invalid_calls:
+            self.assertRaises(AssertionError,
+                              mock_class.assert_has_calls,
+                              [kall]
+            )
+
+
+    def test_assert_has_calls_nested_without_spec(self):
+        m = MagicMock()
+        m().foo().bar().baz()
+        m.one().two().three()
+        calls = call.one().two().three().call_list()
+        m.assert_has_calls(calls)
+
+
     def test_assert_has_calls_with_function_spec(self):
         def f(a, b, c, d=None):
             pass
@@ -1343,6 +1395,32 @@ class MockTest(unittest.TestCase):
             mock.assert_has_calls(calls[:-1])
         mock.assert_has_calls(calls[:-1], any_order=True)
 
+    def test_assert_has_calls_not_matching_spec_error(self):
+        def f(x=None): pass
+
+        mock = Mock(spec=f)
+        mock(1)
+
+        with self.assertRaisesRegex(
+                AssertionError,
+                '^{}$'.format(
+                    re.escape('Calls not found.\n'
+                              'Expected: [call()]\n'
+                              'Actual: [call(1)]'))) as cm:
+            mock.assert_has_calls([call()])
+        self.assertIsNone(cm.exception.__cause__)
+
+
+        with self.assertRaisesRegex(
+                AssertionError,
+                '^{}$'.format(
+                    re.escape(
+                        'Error processing expected calls.\n'
+                        "Errors: [None, TypeError('too many positional arguments')]\n"
+                        "Expected: [call(), call(1, 2)]\n"
+                        'Actual: [call(1)]'))) as cm:
+            mock.assert_has_calls([call(), call(1, 2)])
+        self.assertIsInstance(cm.exception.__cause__, TypeError)
 
     def test_assert_any_call(self):
         mock = Mock()
@@ -1765,6 +1843,26 @@ class MockTest(unittest.TestCase):
                 self.assertEqual(m.mock_calls, call().foo().call_list())
 
 
+    def test_attach_mock_patch_autospec(self):
+        parent = Mock()
+
+        with mock.patch(f'{__name__}.something', autospec=True) as mock_func:
+            self.assertEqual(mock_func.mock._extract_mock_name(), 'something')
+            parent.attach_mock(mock_func, 'child')
+            parent.child(1)
+            something(2)
+            mock_func(3)
+
+            parent_calls = [call.child(1), call.child(2), call.child(3)]
+            child_calls = [call(1), call(2), call(3)]
+            self.assertEqual(parent.mock_calls, parent_calls)
+            self.assertEqual(parent.child.mock_calls, child_calls)
+            self.assertEqual(something.mock_calls, child_calls)
+            self.assertEqual(mock_func.mock_calls, child_calls)
+            self.assertIn('mock.child', repr(parent.child.mock))
+            self.assertEqual(mock_func.mock._extract_mock_name(), 'mock.child')
+
+
     def test_attribute_deletion(self):
         for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
                      NonCallableMock()):
@@ -1849,6 +1947,20 @@ class MockTest(unittest.TestCase):
 
         self.assertRaises(TypeError, mock.child, 1)
         self.assertEqual(mock.mock_calls, [call.child(1, 2)])
+        self.assertIn('mock.child', repr(mock.child.mock))
+
+    def test_parent_propagation_with_autospec_attach_mock(self):
+
+        def foo(a, b): pass
+
+        parent = Mock()
+        parent.attach_mock(create_autospec(foo, name='bar'), 'child')
+        parent.child(1, 2)
+
+        self.assertRaises(TypeError, parent.child, 1)
+        self.assertEqual(parent.child.mock_calls, [call.child(1, 2)])
+        self.assertIn('mock.child', repr(parent.child.mock))
+
 
     def test_isinstance_under_settrace(self):
         # bpo-36593 : __class__ is not set for a class that has __class__
index 26faa1accd09e66120945f612e7fd8a42c78b720..b1abfe315d562b88e81fb4968bca3e0a80d98fca 100644 (file)
@@ -205,12 +205,14 @@ class UUID:
         self.__dict__['is_safe'] = is_safe
 
     def __getstate__(self):
-        state = self.__dict__
+        state = self.__dict__.copy()
         if self.is_safe != SafeUUID.unknown:
             # is_safe is a SafeUUID instance.  Return just its value, so that
             # it can be un-pickled in older Python versions without SafeUUID.
-            state = state.copy()
             state['is_safe'] = self.is_safe.value
+        else:
+            # omit is_safe when it is "unknown"
+            del state['is_safe']
         return state
 
     def __setstate__(self, state):
index fff0765af53b82d550d55833e98a72dbdc457ddb..b9d498fb2ef04f7d4a0474d2392086ce4f754477 100644 (file)
@@ -28,7 +28,7 @@ deactivate () {
     fi
 
     unset VIRTUAL_ENV
-    if [ ! "$1" = "nondestructive" ] ; then
+    if [ ! "${1:-}" = "nondestructive" ] ; then
     # Self destruct!
         unset -f deactivate
     fi
index 14ffb2cf781e2960907a8b00f0ba2e61b78d2768..f61413e232334a455885782d0bb124a33a300923 100644 (file)
@@ -2,44 +2,32 @@
 \r
 rem This file is UTF-8 encoded, so we need to update the current code page while executing it\r
 for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do (\r
-    set "_OLD_CODEPAGE=%%a"\r
+    set _OLD_CODEPAGE=%%a\r
 )\r
 if defined _OLD_CODEPAGE (\r
     "%SystemRoot%\System32\chcp.com" 65001 > nul\r
 )\r
 \r
-set "VIRTUAL_ENV=__VENV_DIR__"\r
+set VIRTUAL_ENV=__VENV_DIR__\r
 \r
-if not defined PROMPT (\r
-    set "PROMPT=$P$G"\r
-)\r
-\r
-if defined _OLD_VIRTUAL_PROMPT (\r
-    set "PROMPT=%_OLD_VIRTUAL_PROMPT%"\r
-)\r
+if not defined PROMPT set PROMPT=$P$G\r
 \r
-if defined _OLD_VIRTUAL_PYTHONHOME (\r
-    set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"\r
-)\r
+if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT%\r
+if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%\r
 \r
-set "_OLD_VIRTUAL_PROMPT=%PROMPT%"\r
-set "PROMPT=__VENV_PROMPT__%PROMPT%"\r
+set _OLD_VIRTUAL_PROMPT=%PROMPT%\r
+set PROMPT=__VENV_PROMPT__%PROMPT%\r
 \r
-if defined PYTHONHOME (\r
-    set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%"\r
-    set PYTHONHOME=\r
-)\r
+if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%\r
+set PYTHONHOME=\r
 \r
-if defined _OLD_VIRTUAL_PATH (\r
-    set "PATH=%_OLD_VIRTUAL_PATH%"\r
-) else (\r
-    set "_OLD_VIRTUAL_PATH=%PATH%"\r
-)\r
+if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%\r
+if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%\r
 \r
-set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%"\r
+set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%\r
 \r
 :END\r
 if defined _OLD_CODEPAGE (\r
     "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul\r
-    set "_OLD_CODEPAGE="\r
+    set _OLD_CODEPAGE=\r
 )\r
index 59b3aa5621a33fc74473073c736018ff4bb0b72e..461c997a1293aedadf92c0d9686f405a5f9bc0cf 100644 (file)
@@ -114,12 +114,12 @@ class WeakValueDictionary(_collections_abc.MutableMapping):
                 else:
                     # Atomic removal is necessary since this function
                     # can be called asynchronously by the GC
-                    _atomic_removal(d, wr.key)
+                    _atomic_removal(self.data, wr.key)
         self._remove = remove
         # A list of keys to be removed
         self._pending_removals = []
         self._iterating = set()
-        self.data = d = {}
+        self.data = {}
         self.update(*args, **kw)
 
     def _commit_removals(self):
index f1c467eb1b2b87c2e76a46b745985831d67c7acb..32aba4df4c7eb5edc473b0a5cba6068ca3f61ee0 100644 (file)
@@ -108,6 +108,7 @@ from xmlrpc.client import Fault, dumps, loads, gzip_encode, gzip_decode
 from http.server import BaseHTTPRequestHandler
 from functools import partial
 from inspect import signature
+import html
 import http.server
 import socketserver
 import sys
@@ -894,7 +895,7 @@ class XMLRPCDocGenerator:
                                 methods
                             )
 
-        return documenter.page(self.server_title, documentation)
+        return documenter.page(html.escape(self.server_title), documentation)
 
 class DocXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
     """XML-RPC and documentation request handler class.
diff --git a/Mac/BuildScript/README.rst b/Mac/BuildScript/README.rst
new file mode 100644 (file)
index 0000000..f8b25fa
--- /dev/null
@@ -0,0 +1,222 @@
+Building a Python Mac OS X distribution
+=======================================
+
+The ``build-install.py`` script creates Python distributions, including
+certain third-party libraries as necessary.  It builds a complete
+framework-based Python out-of-tree, installs it in a funny place with
+$DESTROOT, massages that installation to remove .pyc files and such, creates
+an Installer package from the installation plus other files in ``resources``
+and ``scripts`` and placed that on a ``.dmg`` disk image.
+
+For Python 3.4.0, PSF practice is to build two installer variants
+for each release.
+
+1.  32-bit-only, i386 and PPC universal, capable on running on all machines
+    supported by Mac OS X 10.5 through (at least) 10.9::
+
+        /path/to/bootstrap/python2.7 build-installer.py \
+            --sdk-path=/Developer/SDKs/MacOSX10.5.sdk \
+            --universal-archs=32-bit \
+            --dep-target=10.5
+
+    - builds the following third-party libraries
+
+        * NCurses 5.9 (http://bugs.python.org/issue15037)
+        * SQLite 3.8.11
+        * XZ 5.0.5
+
+    - uses system-supplied versions of third-party libraries
+
+        * readline module links with Apple BSD editline (libedit)
+
+    - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.20) to be installed for building
+
+    - recommended build environment:
+
+        * Mac OS X 10.5.8 Intel or PPC
+        * Xcode 3.1.4
+        * ``MacOSX10.5`` SDK
+        * ``MACOSX_DEPLOYMENT_TARGET=10.5``
+        * Apple ``gcc-4.2``
+        * bootstrap non-framework Python 2.7 for documentation build with
+          Sphinx (as of 3.4.1)
+
+    - alternate build environments:
+
+        * Mac OS X 10.6.8 with Xcode 3.2.6
+            - need to change ``/System/Library/Frameworks/{Tcl,Tk}.framework/Version/Current`` to ``8.4``
+        * Note Xcode 4.* does not support building for PPC so cannot be used for this build
+
+2.  64-bit / 32-bit, x86_64 and i386 universal, for OS X 10.6 (and later)::
+
+        /path/to/bootstrap/python2.7 build-installer.py \
+            --sdk-path=/Developer/SDKs/MacOSX10.6.sdk \
+            --universal-archs=intel \
+            --dep-target=10.6
+
+    - builds the following third-party libraries
+
+        * NCurses 5.9 (http://bugs.python.org/issue15037)
+        * SQLite 3.8.11
+        * XZ 5.0.5
+
+    - uses system-supplied versions of third-party libraries
+
+        * readline module links with Apple BSD editline (libedit)
+
+    - requires ActiveState Tcl/Tk 8.5.15.1 (or later) to be installed for building
+
+    - recommended build environment:
+
+        * Mac OS X 10.6.8 (or later)
+        * Xcode 3.2.6
+        * ``MacOSX10.6`` SDK
+        * ``MACOSX_DEPLOYMENT_TARGET=10.6``
+        * Apple ``gcc-4.2``
+        * bootstrap non-framework Python 2.7 for documentation build with
+          Sphinx (as of 3.4.1)
+
+    - alternate build environments:
+
+        * none.  Xcode 4.x currently supplies two C compilers.
+          ``llvm-gcc-4.2.1`` has been found to miscompile Python 3.3.x and
+          produce a non-functional Python executable.  As it appears to be
+          considered a migration aid by Apple and is not likely to be fixed,
+          its use should be avoided.  The other compiler, ``clang``, has been
+          undergoing rapid development.  While it appears to have become
+          production-ready in the most recent Xcode 5 releases, the versions
+          available on the deprecated Xcode 4.x for 10.6 were early releases
+          and did not receive the level of exposure in production environments
+          that the Xcode 3 gcc-4.2 compiler has had.
+
+
+*   For Python 2.7.x and 3.2.x, the 32-bit-only installer was configured to
+    support Mac OS X 10.3.9 through (at least) 10.6.  Because it is
+    believed that there are few systems still running OS X 10.3 or 10.4
+    and because it has become increasingly difficult to test and
+    support the differences in these earlier systems, as of Python 3.3.0 the PSF
+    32-bit installer no longer supports them.  For reference in building such
+    an installer yourself, the details are::
+
+        /usr/bin/python build-installer.py \
+            --sdk-path=/Developer/SDKs/MacOSX10.4u.sdk \
+            --universal-archs=32-bit \
+            --dep-target=10.3
+
+    - builds the following third-party libraries
+
+        * Bzip2
+        * NCurses
+        * GNU Readline (GPL)
+        * SQLite 3
+        * XZ
+        * Zlib 1.2.3
+        * Oracle Sleepycat DB 4.8 (Python 2.x only)
+
+    - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.20) to be installed for building
+
+    - recommended build environment:
+
+        * Mac OS X 10.5.8 PPC or Intel
+        * Xcode 3.1.4 (or later)
+        * ``MacOSX10.4u`` SDK (later SDKs do not support PPC G3 processors)
+        * ``MACOSX_DEPLOYMENT_TARGET=10.3``
+        * Apple ``gcc-4.0``
+        * system Python 2.5 for documentation build with Sphinx
+
+    - alternate build environments:
+
+        * Mac OS X 10.6.8 with Xcode 3.2.6
+            - need to change ``/System/Library/Frameworks/{Tcl,Tk}.framework/Version/Current`` to ``8.4``
+
+
+
+General Prerequisites
+---------------------
+
+* No Fink (in ``/sw``) or MacPorts (in ``/opt/local``) or other local
+  libraries or utilities (in ``/usr/local``) as they could
+  interfere with the build.
+
+* The documentation for the release is built using Sphinx
+  because it is included in the installer.  For 2.7.x and 3.x.x up to and
+  including 3.4.0, the ``Doc/Makefile`` uses ``svn`` to download repos of
+  ``Sphinx`` and its dependencies.  Beginning with 3.4.1, the ``Doc/Makefile``
+  assumes there is an externally-provided ``sphinx-build`` and requires at
+  least Python 2.6 to run.  Because of this, it is no longer possible to
+  build a 3.4.1 or later installer on OS X 10.5 using the Apple-supplied
+  Python 2.5.
+
+* It is safest to start each variant build with an empty source directory
+  populated with a fresh copy of the untarred source.
+
+* It is recommended that you remove any existing installed version of the
+  Python being built::
+
+      sudo rm -rf /Library/Frameworks/Python.framework/Versions/n.n
+
+
+The Recipe
+----------
+
+Here are the steps you need to follow to build a Python installer:
+
+* Run ``build-installer.py``. Optionally you can pass a number of arguments
+  to specify locations of various files. Please see the top of
+  ``build-installer.py`` for its usage.
+
+  Running this script takes some time, it will not only build Python itself
+  but also some 3th-party libraries that are needed for extensions.
+
+* When done the script will tell you where the DMG image is (by default
+  somewhere in ``/tmp/_py``).
+
+Building other universal installers
+...................................
+
+It is also possible to build a 4-way universal installer that runs on
+OS X 10.5 Leopard or later::
+
+    /usr/bin/python /build-installer.py \
+        --dep-target=10.5
+        --universal-archs=all
+        --sdk-path=/Developer/SDKs/MacOSX10.5.sdk
+
+This requires that the deployment target is 10.5, and hence
+also that you are building on at least OS X 10.5.  4-way includes
+``i386``, ``x86_64``, ``ppc``, and ``ppc64`` (G5).  ``ppc64`` executable
+variants can only be run on G5 machines running 10.5.  Note that,
+while OS X 10.6 is only supported on Intel-based machines, it is possible
+to run ``ppc`` (32-bit) executables unmodified thanks to the Rosetta ppc
+emulation in OS X 10.5 and 10.6.  The 4-way installer variant must be
+built with Xcode 3.  It is not regularly built or tested.
+
+Other ``--universal-archs`` options are ``64-bit`` (``x86_64``, ``ppc64``),
+and ``3-way`` (``ppc``, ``i386``, ``x86_64``).  None of these options
+are regularly exercised; use at your own risk.
+
+
+Testing
+-------
+
+Ideally, the resulting binaries should be installed and the test suite run
+on all supported OS X releases and architectures.  As a practical matter,
+that is generally not possible.  At a minimum, variant 1 should be run on
+a PPC G4 system with OS X 10.5 and at least one Intel system running OS X
+10.9, 10.8, 10.7, 10.6, or 10.5.  Variant 2 should be run on 10.9, 10.8,
+10.7, and 10.6 systems in both 32-bit and 64-bit modes.::
+
+    /usr/local/bin/pythonn.n -m test -w -u all,-largefile
+    /usr/local/bin/pythonn.n-32 -m test -w -u all
+
+Certain tests will be skipped and some cause the interpreter to fail
+which will likely generate ``Python quit unexpectedly`` alert messages
+to be generated at several points during a test run.  These are normal
+during testing and can be ignored.
+
+It is also recommend to launch IDLE and verify that it is at least
+functional.  Double-click on the IDLE app icon in ``/Applications/Python n.n``.
+It should also be tested from the command line::
+
+    /usr/local/bin/idlen.n
+
diff --git a/Mac/BuildScript/README.txt b/Mac/BuildScript/README.txt
deleted file mode 100644 (file)
index f8b25fa..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-Building a Python Mac OS X distribution
-=======================================
-
-The ``build-install.py`` script creates Python distributions, including
-certain third-party libraries as necessary.  It builds a complete
-framework-based Python out-of-tree, installs it in a funny place with
-$DESTROOT, massages that installation to remove .pyc files and such, creates
-an Installer package from the installation plus other files in ``resources``
-and ``scripts`` and placed that on a ``.dmg`` disk image.
-
-For Python 3.4.0, PSF practice is to build two installer variants
-for each release.
-
-1.  32-bit-only, i386 and PPC universal, capable on running on all machines
-    supported by Mac OS X 10.5 through (at least) 10.9::
-
-        /path/to/bootstrap/python2.7 build-installer.py \
-            --sdk-path=/Developer/SDKs/MacOSX10.5.sdk \
-            --universal-archs=32-bit \
-            --dep-target=10.5
-
-    - builds the following third-party libraries
-
-        * NCurses 5.9 (http://bugs.python.org/issue15037)
-        * SQLite 3.8.11
-        * XZ 5.0.5
-
-    - uses system-supplied versions of third-party libraries
-
-        * readline module links with Apple BSD editline (libedit)
-
-    - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.20) to be installed for building
-
-    - recommended build environment:
-
-        * Mac OS X 10.5.8 Intel or PPC
-        * Xcode 3.1.4
-        * ``MacOSX10.5`` SDK
-        * ``MACOSX_DEPLOYMENT_TARGET=10.5``
-        * Apple ``gcc-4.2``
-        * bootstrap non-framework Python 2.7 for documentation build with
-          Sphinx (as of 3.4.1)
-
-    - alternate build environments:
-
-        * Mac OS X 10.6.8 with Xcode 3.2.6
-            - need to change ``/System/Library/Frameworks/{Tcl,Tk}.framework/Version/Current`` to ``8.4``
-        * Note Xcode 4.* does not support building for PPC so cannot be used for this build
-
-2.  64-bit / 32-bit, x86_64 and i386 universal, for OS X 10.6 (and later)::
-
-        /path/to/bootstrap/python2.7 build-installer.py \
-            --sdk-path=/Developer/SDKs/MacOSX10.6.sdk \
-            --universal-archs=intel \
-            --dep-target=10.6
-
-    - builds the following third-party libraries
-
-        * NCurses 5.9 (http://bugs.python.org/issue15037)
-        * SQLite 3.8.11
-        * XZ 5.0.5
-
-    - uses system-supplied versions of third-party libraries
-
-        * readline module links with Apple BSD editline (libedit)
-
-    - requires ActiveState Tcl/Tk 8.5.15.1 (or later) to be installed for building
-
-    - recommended build environment:
-
-        * Mac OS X 10.6.8 (or later)
-        * Xcode 3.2.6
-        * ``MacOSX10.6`` SDK
-        * ``MACOSX_DEPLOYMENT_TARGET=10.6``
-        * Apple ``gcc-4.2``
-        * bootstrap non-framework Python 2.7 for documentation build with
-          Sphinx (as of 3.4.1)
-
-    - alternate build environments:
-
-        * none.  Xcode 4.x currently supplies two C compilers.
-          ``llvm-gcc-4.2.1`` has been found to miscompile Python 3.3.x and
-          produce a non-functional Python executable.  As it appears to be
-          considered a migration aid by Apple and is not likely to be fixed,
-          its use should be avoided.  The other compiler, ``clang``, has been
-          undergoing rapid development.  While it appears to have become
-          production-ready in the most recent Xcode 5 releases, the versions
-          available on the deprecated Xcode 4.x for 10.6 were early releases
-          and did not receive the level of exposure in production environments
-          that the Xcode 3 gcc-4.2 compiler has had.
-
-
-*   For Python 2.7.x and 3.2.x, the 32-bit-only installer was configured to
-    support Mac OS X 10.3.9 through (at least) 10.6.  Because it is
-    believed that there are few systems still running OS X 10.3 or 10.4
-    and because it has become increasingly difficult to test and
-    support the differences in these earlier systems, as of Python 3.3.0 the PSF
-    32-bit installer no longer supports them.  For reference in building such
-    an installer yourself, the details are::
-
-        /usr/bin/python build-installer.py \
-            --sdk-path=/Developer/SDKs/MacOSX10.4u.sdk \
-            --universal-archs=32-bit \
-            --dep-target=10.3
-
-    - builds the following third-party libraries
-
-        * Bzip2
-        * NCurses
-        * GNU Readline (GPL)
-        * SQLite 3
-        * XZ
-        * Zlib 1.2.3
-        * Oracle Sleepycat DB 4.8 (Python 2.x only)
-
-    - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.20) to be installed for building
-
-    - recommended build environment:
-
-        * Mac OS X 10.5.8 PPC or Intel
-        * Xcode 3.1.4 (or later)
-        * ``MacOSX10.4u`` SDK (later SDKs do not support PPC G3 processors)
-        * ``MACOSX_DEPLOYMENT_TARGET=10.3``
-        * Apple ``gcc-4.0``
-        * system Python 2.5 for documentation build with Sphinx
-
-    - alternate build environments:
-
-        * Mac OS X 10.6.8 with Xcode 3.2.6
-            - need to change ``/System/Library/Frameworks/{Tcl,Tk}.framework/Version/Current`` to ``8.4``
-
-
-
-General Prerequisites
----------------------
-
-* No Fink (in ``/sw``) or MacPorts (in ``/opt/local``) or other local
-  libraries or utilities (in ``/usr/local``) as they could
-  interfere with the build.
-
-* The documentation for the release is built using Sphinx
-  because it is included in the installer.  For 2.7.x and 3.x.x up to and
-  including 3.4.0, the ``Doc/Makefile`` uses ``svn`` to download repos of
-  ``Sphinx`` and its dependencies.  Beginning with 3.4.1, the ``Doc/Makefile``
-  assumes there is an externally-provided ``sphinx-build`` and requires at
-  least Python 2.6 to run.  Because of this, it is no longer possible to
-  build a 3.4.1 or later installer on OS X 10.5 using the Apple-supplied
-  Python 2.5.
-
-* It is safest to start each variant build with an empty source directory
-  populated with a fresh copy of the untarred source.
-
-* It is recommended that you remove any existing installed version of the
-  Python being built::
-
-      sudo rm -rf /Library/Frameworks/Python.framework/Versions/n.n
-
-
-The Recipe
-----------
-
-Here are the steps you need to follow to build a Python installer:
-
-* Run ``build-installer.py``. Optionally you can pass a number of arguments
-  to specify locations of various files. Please see the top of
-  ``build-installer.py`` for its usage.
-
-  Running this script takes some time, it will not only build Python itself
-  but also some 3th-party libraries that are needed for extensions.
-
-* When done the script will tell you where the DMG image is (by default
-  somewhere in ``/tmp/_py``).
-
-Building other universal installers
-...................................
-
-It is also possible to build a 4-way universal installer that runs on
-OS X 10.5 Leopard or later::
-
-    /usr/bin/python /build-installer.py \
-        --dep-target=10.5
-        --universal-archs=all
-        --sdk-path=/Developer/SDKs/MacOSX10.5.sdk
-
-This requires that the deployment target is 10.5, and hence
-also that you are building on at least OS X 10.5.  4-way includes
-``i386``, ``x86_64``, ``ppc``, and ``ppc64`` (G5).  ``ppc64`` executable
-variants can only be run on G5 machines running 10.5.  Note that,
-while OS X 10.6 is only supported on Intel-based machines, it is possible
-to run ``ppc`` (32-bit) executables unmodified thanks to the Rosetta ppc
-emulation in OS X 10.5 and 10.6.  The 4-way installer variant must be
-built with Xcode 3.  It is not regularly built or tested.
-
-Other ``--universal-archs`` options are ``64-bit`` (``x86_64``, ``ppc64``),
-and ``3-way`` (``ppc``, ``i386``, ``x86_64``).  None of these options
-are regularly exercised; use at your own risk.
-
-
-Testing
--------
-
-Ideally, the resulting binaries should be installed and the test suite run
-on all supported OS X releases and architectures.  As a practical matter,
-that is generally not possible.  At a minimum, variant 1 should be run on
-a PPC G4 system with OS X 10.5 and at least one Intel system running OS X
-10.9, 10.8, 10.7, 10.6, or 10.5.  Variant 2 should be run on 10.9, 10.8,
-10.7, and 10.6 systems in both 32-bit and 64-bit modes.::
-
-    /usr/local/bin/pythonn.n -m test -w -u all,-largefile
-    /usr/local/bin/pythonn.n-32 -m test -w -u all
-
-Certain tests will be skipped and some cause the interpreter to fail
-which will likely generate ``Python quit unexpectedly`` alert messages
-to be generated at several points during a test run.  These are normal
-during testing and can be ignored.
-
-It is also recommend to launch IDLE and verify that it is at least
-functional.  Double-click on the IDLE app icon in ``/Applications/Python n.n``.
-It should also be tested from the command line::
-
-    /usr/local/bin/idlen.n
-
index 024ec910ab0a2d4dcc733320e104351aa3ff8047..6c6c5d2048d19bf56f5f8e33ad7d07697ff4a2b3 100755 (executable)
@@ -215,9 +215,9 @@ def library_recipes():
 
     result.extend([
           dict(
-              name="OpenSSL 1.1.1c",
-              url="https://www.openssl.org/source/openssl-1.1.1c.tar.gz",
-              checksum='15e21da6efe8aa0e0768ffd8cd37a5f6',
+              name="OpenSSL 1.1.1d",
+              url="https://www.openssl.org/source/openssl-1.1.1d.tar.gz",
+              checksum='3be209000dbc7e1b95bcdf47980a3baa',
               buildrecipe=build_universal_openssl,
               configure=None,
               install=None,
index 20982a46cc36a918791bd703562c417de685a638..86e54f6662a201e00d6851c508b994c57b97e0c7 100644 (file)
@@ -1,16 +1,17 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160
-{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPS-BoldMT;\f2\fmodern\fcharset0 CourierNewPSMT;
-}
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
+{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fmodern\fcharset0 CourierNewPS-BoldMT;
+\f3\fmodern\fcharset0 CourierNewPSMT;}
 {\colortbl;\red255\green255\blue255;}
+{\*\expandedcolortbl;;}
 \margl1440\margr1440\vieww14620\viewh13380\viewkind0
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
 
 \f0\b\fs36 \cf0 \ul \ulc0 HISTORY AND LICENSE\
 
 \fs24 \
 HISTORY OF THE SOFTWARE\
 
-\b0 \ulnone \
+\f1\b0 \ulnone \
 Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others.\
 \
 In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software.\
@@ -20,10 +21,10 @@ In May 2000, Guido and the Python core development team moved to BeOpen.com to f
 All Python releases are Open Source (see http://www.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.\
 \
 
-\f1\b Release         Derived     Year        Owner       GPL-\
+\f2\b Release         Derived     Year        Owner       GPL-\
                 from                                compatible?\
 
-\f2\b0 \
+\f3\b0 \
 0.9.0 thru 1.2  n/a         1991-1995   CWI         yes\
 1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes\
 1.6             1.5.2       2000        CNRI        no\
@@ -36,25 +37,25 @@ All Python releases are Open Source (see http://www.opensource.org for the Open
 2.1.3           2.1.2       2002        PSF         yes\
 2.2 and above   2.1.1       2001-now    PSF         yes\
 
-\f0 \
+\f1 \
 
-\b Note:  
-\b0 GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't.\
+\f0\b Note:  
+\f1\b0 GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't.\
 \
 Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible.\
 \
 \
 
-\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\
+\f0\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\
 
-\b0 \ulnone \
+\f1\b0 \ulnone \
 
-\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\
+\f0\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\
 
-\b0 \
+\f1\b0 \
 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation.\
 \
-2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, 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, 2014, 2015, 2016 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\
+2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, 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, 2014, 2015, 2016, 2017, 2018, 2019 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 the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.\
 \
@@ -70,9 +71,9 @@ Thanks to the many outside volunteers who have worked under Guido's direction to
 \
 \
 
-\b BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0\
+\f0\b BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0\
 
-\b0 \
+\f1\b0 \
 BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\
 \
 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software").\
@@ -91,9 +92,9 @@ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\
 \
 \
 
-\b CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1\
+\f0\b CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1\
 
-\b0 \
+\f1\b0 \
 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation.\
 \
 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013".\
@@ -114,9 +115,9 @@ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\
 \
 \
 
-\b CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2\
+\f0\b CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2\
 
-\b0 \
+\f1\b0 \
 Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved.\
 \
 Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.\
@@ -125,16 +126,16 @@ STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFT
 \
 \
 
-\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\
+\f0\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\
 
-\b0 \ulnone \
+\f1\b0 \ulnone \
 This installer incorporates portions of the following third-party software:\
 \
 
-\f2 $THIRD_PARTY_LIBS\
+\f3 $THIRD_PARTY_LIBS\
 \
 
-\f0 For licenses and acknowledgements for these and other third-party software incorporated in this Python distribution, please refer to the on-line documentation {\field{\*\fldinst{HYPERLINK "https://docs.python.org/$VERSION/license.html#licenses-and-acknowledgements-for-incorporated-software"}}{\fldrslt here}}.\
+\f1 For licenses and acknowledgements for these and other third-party software incorporated in this Python distribution, please refer to the on-line documentation {\field{\*\fldinst{HYPERLINK "https://docs.python.org/$VERSION/license.html#licenses-and-acknowledgements-for-incorporated-software"}}{\fldrslt here}}.\
 \
 \
 \
index 476d531167592eb4286792c9cdbaf325931d9ff9..b71bd642902a2d619f0fbb7b3339edd7d0b52d0f 100644 (file)
@@ -1,4 +1,4 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf500
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
 {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique;
 \f3\fmodern\fcharset0 CourierNewPSMT;}
 {\colortbl;\red255\green255\blue255;}
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
 
 \f0\fs24 \cf0 This package will install Python $FULL_VERSION for macOS $MACOSX_DEPLOYMENT_TARGET for the following architecture(s): $ARCHITECTURES.\
-\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
-
-\f1\b \cf0 \ul \ulc0 Which installer variant should I use?
-\f0\b0 \ulnone \
-\
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
-
-\f1\b \cf0 CHANGED in 3.7.4: 
-\f0\b0  The 
-\f1\b 10.6+ 64-/32-bit installer variant  is being deprecated
-\f0\b0 .  
-\f1\b Python 3.8.0
-\f0\b0  will 
-\f1\b not
-\f0\b0  include a binary installer for 10.6+ and 
-\f1\b future bugfix releases of 3.7.x
-\f0\b0  may not, either.  Mac OS X 10.6 Snow Leopard was released in 2009 and has not been supported by Apple for many years including lack of security updates.  It is becoming increasingly difficult to ensure new Python features and bug fixes are compatible with such old systems especially with Apple's deprecation and removal of 32-bit support in recent and upcoming macOS releases.  We believe that there is now very little usage of this installer variant and so we would like to focus our resources on supporting newer systems.  We do not plan to intentionally break Python support on 10.6 and we will consider bug fixes for problems found when building from source on 10.6. \
-\
+\cf0 \
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
-\cf0 For Python.3.7, python.org currently provides two installer variants for download: one that installs a 
-\f2\i 64-bit-only 
-\f0\i0 Python capable of running on 
-\f2\i macOS 10.9 (Mavericks)
-\f0\i0  or later; and one that installs a 
-\f2\i 64-bit/32-bit Intel
-\f0\i0  Python capable of running on 
-\f2\i macOS 10.6 (Snow Leopard)
-\f0\i0  or later.  (This ReadMe was installed with the 
-\f2\i $MACOSX_DEPLOYMENT_TARGET
-\f0\i0  variant.)  If you are running on macOS 10.9 or later and if you have no need for compatibility with older systems, use the 10.9 variant.  Use the 10.6 variant if you are running on macOS 10.6 through 10.8 or if you want to produce standalone applications that can run on systems from 10.6.  The Pythons installed by these installers are built with private copies of some third-party libraries not included with or newer than those in macOS itself.  The list of these libraries varies by installer variant and is included at the end of the License.rtf file.
-\f1\b \ul \
-\
-Certificate verification and OpenSSL\
+
+\f1\b \cf0 \ul Certificate verification and OpenSSL\
 
 \f0\b0 \ulnone \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
-\cf0 This variant of Python 3.7 includes its own private copy of OpenSSL 1.1.1.  The deprecated Apple-supplied OpenSSL libraries are no longer used.  This means that the trust certificates in system and user keychains managed by the 
+This package includes its own private copy of OpenSSL 1.1.1.   The trust certificates in system and user keychains managed by the 
 \f2\i Keychain Access 
 \f0\i0 application and the 
 \f2\i security
-\f0\i0  command line utility are no longer used as defaults by the Python 
+\f0\i0  command line utility are not used as defaults by the Python 
 \f3 ssl
 \f0  module.  A sample command script is included in 
 \f3 /Applications/Python 3.7
 \f0  to install a curated bundle of default root certificates from the third-party 
 \f3 certifi
-\f0  package ({\field{\*\fldinst{HYPERLINK "https://pypi.org/project/certifi/"}}{\fldrslt https://pypi.org/project/certifi/}}).  If you choose to use 
-\f3 certifi
-\f0 , you should consider subscribing to the{\field{\*\fldinst{HYPERLINK "https://certifi.io/en/latest/"}}{\fldrslt  project's email update service}} to be notified when the certificate bundle is updated.\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
-\cf0 \
+\f0  package ({\field{\*\fldinst{HYPERLINK "https://pypi.org/project/certifi/"}}{\fldrslt https://pypi.org/project/certifi/}}).  Double-click on 
+\f3 Install Certificates
+\f0  to run it.\
+\
 The bundled 
 \f3 pip
-\f0  included with this installer has its own default certificate store for verifying download connections.\
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
+\f0  has its own default certificate store for verifying download connections.\
+\
 
-\f1\b \cf0 \
-CHANGED in 3.7.4: 
-\f0\b0  OpenSSL has been updated from 1.1.0 to 1.1.1.\
+\f1\b \ul Which installer variant should I use?
+\f0\b0 \ulnone \
+\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
+\cf0 In almost all cases, you should use the 
+\f1\b macOS 64-bit installer for OS X 10.9 and later
+\f0\b0 .\
+\
+The legacy 
+\f1\b macOS 64-bit/32-bit installer for Mac OS X 10.6 and later 
+\f0\b0 variant  is now deprecated.  
+\f1\b Python 3.8.0
+\f0\b0  will 
+\f1\b not
+\f0\b0  include a binary installer for the 10.6+ variant and 
+\f1\b future bugfix releases of 3.7.x
+\f0\b0  may not, either.  macOS 10.6 Snow Leopard was released in 2009 and has not been supported by Apple for many years including lack of security updates.  It is becoming increasingly difficult to ensure new Python features and bug fixes are compatible with such old systems.  Note that, due to recent Apple installer packaging changes, the 10.6+ installer pkg we provide can no longer be opened by the Apple system installer application on 10.6;  10.7 and 10.8 are not affected.  We believe that there is now very little usage of this installer variant and so we would like to focus our resources on supporting newer systems.  We do not plan to intentionally break Python support on 10.6 through 10.8 and we will consider bug fixes for problems found when building from source on those systems.  
+\f1\b macOS 10.15 Catalina
+\f0\b0  removes support for running 32-bit architecture programs; we do not recommend trying to use the 10.6+ variant on it and it may not install on 10.15 systems without intervention. \
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
-\cf0 \
 
-\f1\b \ul Using IDLE or other Tk applications 
+\f1\b \cf0 \ul \
+Using IDLE or other Tk applications 
 \f0\b0 \ulnone \
 \
-Both installer variants now come with their own private version of Tcl/Tk 8.6. They no longer use system-supplied or third-party supplied versions of Tcl/Tk as in previous releases.\
+This package includes its own private version of Tcl/Tk 8.6. It does not use any system-supplied or third-party supplied versions of Tcl/Tk.\
+\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
+\cf0 Due to new security checks on macOS 10.15 Catalina, when launching IDLE macOS may open a window with a message 
+\f1\b "Python" would like to access files in your Documents folder
+\f0\b0 .  This is normal as IDLE uses your 
+\f1\b Documents
+\f0\b0  folder as its default when opening and saving files; you can still choose other locations in the 
+\f1\b Open
+\f0\b0  and 
+\f1\b Save
+\f0\b0  file dialog windows.  Click on the 
+\f1\b OK
+\f0\b0  button to proceed.\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
 
-\f1\b \ul \
+\f1\b \cf0 \ul \ulc0 \
 Other changes\
 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
-\cf0 \ulnone CHANGED in 3.7.4: 
-\f0\b0  SQLite has been updated from 3.22.0 to 3.28.0
-\f1\b \ul \ulc0 \
-\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
 
-\f0\b0 \cf0 \ulnone \
-For other changes in this release, see the 
+\f0\b0 \ulnone For other changes in this release, see the 
 \f2\i What's new
 \f0\i0  section in the {\field{\*\fldinst{HYPERLINK "https://www.python.org/doc/"}}{\fldrslt Documentation Set}} for this release and its 
 \f2\i Release Notes
 \f0\i0  link at {\field{\*\fldinst{HYPERLINK "https://www.python.org/downloads/"}}{\fldrslt https://www.python.org/downloads/}}.\
-
-\f1\b \ul \
-Python 3 and Python 2 Co-existence\
-
-\f0\b0 \ulnone \
-Python.org Python $VERSION and 2.7.x versions can both be installed on your system and will not conflict. Command names for Python 3 contain a 3 in them, 
-\f3 python3
-\f0  (or
-\f3  python$VERSION
-\f0 ), 
-\f3 idle3
-\f0  (or i
-\f3 dle$VERSION
-\f0 ), 
-\f3 pip3
-\f0  (or 
-\f3 pip$VERSION
-\f0 ), etc.  Python 2.7 command names contain a 2 or no digit: 
-\f3 python2
-\f0  (or 
-\f3 python2.7
-\f0  or 
-\f3 python
-\f0 ), 
-\f3 idle2
-\f0  (or 
-\f3 idle2.7
-\f0  or 
-\f3 idle
-\f0 ), etc.\
 }
\ No newline at end of file
index fd0170d2764306e3e97c7e77537b3692c7ef73d8..410ad425516f165a8bac1bc0304697c3b31f6bce 100644 (file)
@@ -1,9 +1,9 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf500
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
 \cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT;
 }
 {\colortbl;\red255\green255\blue255;}
 {\*\expandedcolortbl;;}
-\paperw11905\paperh16837\margl1440\margr1440\vieww12200\viewh10880\viewkind0
+\paperw11905\paperh16837\margl1440\margr1440\vieww12380\viewh10900\viewkind0
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
 
 \f0\fs24 \cf0 This package will install 
 \
 
 \f1\b Python for macOS
-\f0\b0  consists of the Python programming language interpreter, plus a set of programs to allow easy access to it for macOS users including an integrated development environment 
+\f0\b0  consists of the {\field{\*\fldinst{HYPERLINK "https://www.python.org"}}{\fldrslt Python}} programming language interpreter and its batteries-included standard library to allow easy access to macOS features.  It also includes the Python integrated development environment, 
 \f1\b IDLE
-\f0\b0 .\
+\f0\b0 .  You can also use the included 
+\f1\b pip
+\f0\b0  to download and install third-party packages from the {\field{\*\fldinst{HYPERLINK "https://pypi.org"}}{\fldrslt Python Package Index}}. \
 \
 At the end of this install, click on 
 \f2 Install Certificates
-\f0  for SSL root certificates\
-\
-
-\f1\b NEW in 3.7.0: 
-\f0\b0 two installer variants (10.9+ 64-bit-only, 10.6+ 64-/32-bit), built-in Tcl/Tk 8.6 support (no additional third-party downloads!), OpenSSL 1.1, and more!\
-
-\f1\b \
-CHANGED in 3.7.4: 
-\f0\b0 OpenSSL 1.1.1, SQLite 3.28.0, 10.6+ 64-/32-bit installer variant deprecated\
+\f0  to install a set of current SSL root certificates.\
 }
\ No newline at end of file
diff --git a/Mac/README b/Mac/README
deleted file mode 100644 (file)
index d419474..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-=========================
-Python on Mac OS X README
-=========================
-
-:Authors:
-    Jack Jansen (2004-07),
-    Ronald Oussoren (2010-04),
-    Ned Deily (2012-06)
-
-:Version: 3.4.0
-
-This document provides a quick overview of some Mac OS X specific features in
-the Python distribution.
-
-OS X specific arguments to configure
-====================================
-
-* ``--enable-framework[=DIR]``
-
-  If this argument is specified the build will create a Python.framework rather
-  than a traditional Unix install. See the section
-  _`Building and using a framework-based Python on Mac OS X` for more
-  information on frameworks.
-
-  If the optional directory argument is specified the framework is installed
-  into that directory. This can be used to install a python framework into
-  your home directory::
-
-     $ ./configure --enable-framework=/Users/ronald/Library/Frameworks
-     $ make && make install
-
-  This will install the framework itself in ``/Users/ronald/Library/Frameworks``,
-  the applications in a subdirectory of ``/Users/ronald/Applications`` and the
-  command-line tools in ``/Users/ronald/bin``.
-
-* ``--with-framework-name=NAME``
-
-  Specify the name for the python framework, defaults to ``Python``. This option
-  is only valid when ``--enable-framework`` is specified.
-
-* ``--enable-universalsdk[=PATH]``
-
-  Create a universal binary build of Python. This can be used with both
-  regular and framework builds.
-
-  The optional argument specifies which OS X SDK should be used to perform the
-  build.  If xcodebuild is available and configured, this defaults to
-  the Xcode default MacOS X SDK, otherwise ``/Developer/SDKs/MacOSX.10.4u.sdk``
-  if available or ``/`` if not.  When building on OS X 10.5 or later, you can
-  specify ``/`` to use the installed system headers rather than an SDK.  As of
-  OS X 10.9, you should install the optional system headers from the Command
-  Line Tools component using ``xcode-select``::
-
-     $ sudo xcode-select --install
-
-  See the section _`Building and using a universal binary of Python on Mac OS X`
-  for more information.
-
-* ``--with-universal-archs=VALUE``
-
-  Specify the kind of universal binary that should be created. This option is
-  only valid when ``--enable-universalsdk`` is specified.  The default is
-  ``32-bit`` if a building with a SDK that supports PPC, otherwise defaults
-  to ``intel``.
-
-
-Building and using a universal binary of Python on Mac OS X
-===========================================================
-
-1. What is a universal binary
------------------------------
-
-A universal binary build of Python contains object code for more than one
-CPU architecture.  A universal OS X executable file or library combines the
-architecture-specific code into one file and can therefore run at native
-speed on all supported architectures.  Universal files were introduced in
-OS X 10.4 to add support for Intel-based Macs to the existing PowerPC (PPC)
-machines.  In OS X 10.5 support was extended to 64-bit Intel and 64-bit PPC
-architectures.  It is possible to build Python with various combinations
-of architectures depending on the build tools and OS X version in use.
-
-2. How do I build a universal binary
-------------------------------------
-
-You can enable universal binaries by specifying the "--enable-universalsdk"
-flag to configure::
-
-  $ ./configure --enable-universalsdk
-  $ make
-  $ make install
-
-This flag can be used with a framework build of python, but also with a classic
-unix build. Universal builds were first supported with OS X 10.4 with Xcode 2.1
-and the 10.4u SDK.  Starting with Xcode 3 and OS X 10.5, more configurations are
-available.
-
-In general, universal builds depend on specific features provided by the
-Apple-supplied compilers and other build tools included in Apple's Xcode
-development tools.  You should install Xcode and the command line tools
-component appropriate for the OS X release you are running on.  See the
-Python Developer's Guide (https://devguide.python.org/setup/)
-for more information.
-
-2.1 Flavors of universal binaries
-.................................
-
-It is possible to build a number of flavors of the universal binary build,
-the default is a 32-bit only binary (i386 and ppc) in build environments that
-support ppc (10.4 with Xcode 2, 10.5 and 10.6 with Xcode 3) or an
-Intel-32/-64-bit binary (i386 and X86_64) in build environments that do not
-support ppc (Xcode 4 on 10.6 and later systems).  The flavor can be specified
-using the configure option ``--with-universal-archs=VALUE``. The following
-values are available:
-
-  * ``intel``:   ``i386``, ``x86_64``
-
-  * ``intel-32``: ``i386``
-
-  * ``32-bit``:   ``ppc``, ``i386``
-
-  * ``3-way``:   ``i386``, ``x86_64``, ``ppc``
-
-  * ``64-bit``:   ``ppc64``, ``x86_64``
-
-  * ``all``:      ``ppc``, ``ppc64``, ``i386``, ``x86_64``
-
-To build a universal binary that includes a 64-bit architecture, you must build
-on a system running OS X 10.5 or later.  The ``all`` and ``64-bit`` flavors can
-only be built with a 10.5 SDK because ``ppc64`` support was only included with
-OS X 10.5.  Although legacy ``ppc`` support was included with Xcode 3 on OS X
-10.6, it was removed in Xcode 4, versions of which were released on OS X 10.6
-and which is the standard for OS X 10.7.  To summarize, the
-following combinations of SDKs and universal-archs flavors are available:
-
-  * 10.4u SDK with Xcode 2 supports ``32-bit`` only
-
-  * 10.5 SDK with Xcode 3.1.x supports all flavors
-
-  * 10.6 SDK with Xcode 3.2.x supports ``intel``, ``3-way``, and ``32-bit``
-
-  * 10.6 SDK with Xcode 4 supports ``intel`` only
-
-  * 10.7 and 10.8 SDKs with Xcode 4 support ``intel`` only
-
-  * 10.8 and 10.9 SDKs with Xcode 5 support ``intel`` only
-
-The makefile for a framework build will also install ``python3.4-32``
-binaries when the universal architecture includes at least one 32-bit
-architecture (that is, for all flavors but ``64-bit``).
-
-Running a specific architecture
-...............................
-
-You can run code using a specific architecture using the ``arch`` command::
-
-   $ arch -i386 python
-
-Or to explicitly run in 32-bit mode, regardless of the machine hardware::
-
-   $ arch -i386 -ppc python
-
-NOTE: When you're using a framework install of Python this requires at least
-Python 2.7 or 3.2, in earlier versions the python (and pythonw) commands are
-wrapper tools that execute the real interpreter without ensuring that the
-real interpreter runs with the same architecture.
-
-Using ``arch`` is not a perfect solution as the selected architecture will
-not automatically carry through to subprocesses launched by programs and tests
-under that Python.  If you want to ensure that Python interpreters launched in
-subprocesses also run in 32-bit-mode if the main interpreter does, use
-a ``python3.4-32`` binary and use the value of ``sys.executable`` as the
-``subprocess`` ``Popen`` executable value.
-
-Building and using a framework-based Python on Mac OS X.
-========================================================
-
-
-1. Why would I want a framework Python instead of a normal static Python?
---------------------------------------------------------------------------
-
-The main reason is because you want to create GUI programs in Python. With the
-exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run
-from a Mac OS X application bundle (".app").
-
-While it is technically possible to create a .app without using frameworks you
-will have to do the work yourself if you really want this.
-
-A second reason for using frameworks is that they put Python-related items in
-only two places: "/Library/Framework/Python.framework" and
-"/Applications/Python <VERSION>" where ``<VERSION>`` can be e.g. "3.4",
-"2.7", etc.  This simplifies matters for users installing
-Python from a binary distribution if they want to get rid of it again. Moreover,
-due to the way frameworks work, a user without admin privileges can install a
-binary distribution in his or her home directory without recompilation.
-
-2. How does a framework Python differ from a normal static Python?
-------------------------------------------------------------------
-
-In everyday use there is no difference, except that things are stored in
-a different place. If you look in /Library/Frameworks/Python.framework
-you will see lots of relative symlinks, see the Apple documentation for
-details. If you are used to a normal unix Python file layout go down to
-Versions/Current and you will see the familiar bin and lib directories.
-
-3. Do I need extra packages?
-----------------------------
-
-Yes, probably.  If you want Tkinter support you need to get the OS X AquaTk
-distribution, this is installed by default on Mac OS X 10.4 or later.  Be
-aware, though, that the Cocoa-based AquaTk's supplied starting with OS X
-10.6 have proven to be unstable.  If possible, you should consider
-installing a newer version before building on OS X 10.6 or later, such as
-the ActiveTcl 8.5.  See http://www.python.org/download/mac/tcltk/.  If you
-are building with an SDK, ensure that the newer Tcl and Tk frameworks are
-seen in the SDK's ``Library/Frameworks`` directory; you may need to
-manually create symlinks to their installed location, ``/Library/Frameworks``.
-If you want wxPython you need to get that.
-If you want Cocoa you need to get PyObjC.
-
-4. How do I build a framework Python?
--------------------------------------
-
-This directory contains a Makefile that will create a couple of python-related
-applications (full-blown OS X .app applications, that is) in
-"/Applications/Python <VERSION>", and a hidden helper application Python.app
-inside the Python.framework, and unix tools including "python" into
-/usr/local/bin.  In addition it has a target "installmacsubtree" that installs
-the relevant portions of the Mac subtree into the Python.framework.
-
-It is normally invoked indirectly through the main Makefile, as the last step
-in the sequence
-
- 1. ./configure --enable-framework
-
- 2. make
-
- 3. make install
-
-This sequence will put the framework in ``/Library/Framework/Python.framework``,
-the applications in ``/Applications/Python <VERSION>`` and the unix tools in
-``/usr/local/bin``.
-
-Installing in another place, for instance ``$HOME/Library/Frameworks`` if you
-have no admin privileges on your machine, is possible. This can be accomplished
-by configuring with ``--enable-framework=$HOME/Library/Frameworks``.
-The other two directories will then also be installed in your home directory,
-at ``$HOME/Applications/Python-<VERSION>`` and ``$HOME/bin``.
-
-If you want to install some part, but not all, read the main Makefile. The
-frameworkinstall is composed of a couple of sub-targets that install the
-framework itself, the Mac subtree, the applications and the unix tools.
-
-There is an extra target frameworkinstallextras that is not part of the
-normal frameworkinstall which installs the Tools directory into
-"/Applications/Python <VERSION>", this is useful for binary
-distributions.
-
-What do all these programs do?
-===============================
-
-"IDLE.app" is an integrated development environment for Python: editor,
-debugger, etc.
-
-"Python Launcher.app" is a helper application that will handle things when you
-double-click a .py, .pyc or .pyw file. For the first two it creates a Terminal
-window and runs the scripts with the normal command-line Python. For the
-latter it runs the script in the Python.app interpreter so the script can do
-GUI-things. Keep the ``Option`` key depressed while dragging or double-clicking
-a script to set runtime options. These options can be set persistently
-through Python Launcher's preferences dialog.
-
-The program ``pythonx.x`` runs python scripts from the command line.
-Previously, various compatibility aliases were also installed, including
-``pythonwx.x`` which in early releases of Python on OS X was required to run
-GUI programs.  As of 3.4.0, the ``pythonwx.x`` aliases are no longer installed.
-
-How do I create a binary distribution?
-======================================
-
-Download and unpack the source release from http://www.python.org/download/.
-Go to the directory ``Mac/BuildScript``. There you will find a script
-``build-installer.py`` that does all the work. This will download and build
-a number of 3rd-party libaries, configures and builds a framework Python,
-installs it, creates the installer package files and then packs this in a
-DMG image.  The script also builds an HTML copy of the current Python
-documentation set for this release for inclusion in the framework.  The
-installer package will create links to the documentation for use by IDLE,
-pydoc, shell users, and Finder user.
-
-The script will build a universal binary so you'll therefore have to run this
-script on Mac OS X 10.4 or later and with Xcode 2.1 or later installed.
-However, the Python build process itself has several build dependencies not
-available out of the box with OS X 10.4 so you may have to install
-additional software beyond what is provided with Xcode 2.  OS X 10.5
-provides a recent enough system Python (in ``/usr/bin``) to build
-the Python documentation set.  It should be possible to use SDKs and/or older
-versions of Xcode to build installers that are compatible with older systems
-on a newer system but this may not be completely foolproof so the resulting
-executables, shared libraries, and ``.so`` bundles should be carefully
-examined and tested on all supported systems for proper dynamic linking
-dependencies.  It is safest to build the distribution on a system running the
-minimum OS X version supported.
-
-All of this is normally done completely isolated in /tmp/_py, so it does not
-use your normal build directory nor does it install into /.
-
-Because of the way the script locates the files it needs you have to run it
-from within the BuildScript directory. The script accepts a number of
-command-line arguments, run it with --help for more information.
-
-Configure warnings
-==================
-
-The configure script sometimes emits warnings like the one below::
-
-   configure: WARNING: libintl.h: present but cannot be compiled
-   configure: WARNING: libintl.h:     check for missing prerequisite headers?
-   configure: WARNING: libintl.h: see the Autoconf documentation
-   configure: WARNING: libintl.h:     section "Present But Cannot Be Compiled"
-   configure: WARNING: libintl.h: proceeding with the preprocessor's result
-   configure: WARNING: libintl.h: in the future, the compiler will take precedence
-   configure: WARNING:     ## -------------------------------------- ##
-   configure: WARNING:     ## Report this to http://bugs.python.org/ ##
-   configure: WARNING:     ## -------------------------------------- ##
-
-This almost always means you are trying to build a universal binary for
-Python and have libraries in ``/usr/local`` that don't contain the required
-architectures. Temporarily move ``/usr/local`` aside to finish the build.
-
-
-Uninstalling a framework install, including the binary installer
-================================================================
-
-Uninstalling a framework can be done by manually removing all bits that got installed.
-That's true for both installations from source and installations using the binary installer.
-OS X does not provide a central uninstaller.
-
-The main bit of a framework install is the framework itself, installed in
-``/Library/Frameworks/Python.framework``. This can contain multiple versions
-of Python, if you want to remove just one version you have to remove the
-version-specific subdirectory: ``/Library/Frameworks/Python.framework/Versions/X.Y``.
-If you do that, ensure that ``/Library/Frameworks/Python.framework/Versions/Current``
-is a symlink that points to an installed version of Python.
-
-A framework install also installs some applications in ``/Applications/Python X.Y``,
-
-And lastly a framework installation installs files in ``/usr/local/bin``, all of
-them symbolic links to files in ``/Library/Frameworks/Python.framework/Versions/X.Y/bin``.
-
-
-Resources
-=========
-
-  *  http://www.python.org/download/mac/
-
-  *  http://www.python.org/community/sigs/current/pythonmac-sig/
-
-  *  https://devguide.python.org/
diff --git a/Mac/README.rst b/Mac/README.rst
new file mode 100644 (file)
index 0000000..4f2e2ce
--- /dev/null
@@ -0,0 +1,363 @@
+======================
+Python on macOS README
+======================
+
+:Authors:
+    Jack Jansen (2004-07),
+    Ronald Oussoren (2010-04),
+    Ned Deily (2012-06)
+
+This document provides a quick overview of some macOS specific features in
+the Python distribution.
+
+macOS specific arguments to configure
+=====================================
+
+* ``--enable-framework[=DIR]``
+
+  If this argument is specified the build will create a Python.framework rather
+  than a traditional Unix install. See the section
+  _`Building and using a framework-based Python on macOS` for more
+  information on frameworks.
+
+  If the optional directory argument is specified the framework is installed
+  into that directory. This can be used to install a python framework into
+  your home directory::
+
+     $ ./configure --enable-framework=/Users/ronald/Library/Frameworks
+     $ make && make install
+
+  This will install the framework itself in ``/Users/ronald/Library/Frameworks``,
+  the applications in a subdirectory of ``/Users/ronald/Applications`` and the
+  command-line tools in ``/Users/ronald/bin``.
+
+* ``--with-framework-name=NAME``
+
+  Specify the name for the python framework, defaults to ``Python``. This option
+  is only valid when ``--enable-framework`` is specified.
+
+* ``--enable-universalsdk[=PATH]``
+
+  Create a universal binary build of Python. This can be used with both
+  regular and framework builds.
+
+  The optional argument specifies which macOS SDK should be used to perform the
+  build.  In most cases on current systems, you do not need to specify PATH or
+  you can just use ``/``; the default MacOSX SDK for the active Xcode or Command
+  Line Tools developer directory will be used.  See the macOS ``xcrun`` man page
+  for more information.  Current versions of macOS and Xcode no longer install
+  system header files in their traditional locations, like ``/usr/include`` and
+  ``/System/Library/Frameworks``; instead they are found within a MacOSX SDK.
+  The Apple-supplied build tools handle this transparently and current
+  versiona of Python now handle this as well.  So it is no longer necessary,
+  and since macOS 10.14, no longer possible to force the installation of system
+  headers with ``xcode-select``.
+
+* ``--with-universal-archs=VALUE``
+
+  Specify the kind of universal binary that should be created. This option is
+  only valid when ``--enable-universalsdk`` is specified.  The default is
+  ``32-bit`` if building with a SDK that supports PPC, otherwise defaults
+  to ``intel``.  Note that ``intel`` means a universal build of both 32-bit
+  and 64-bit binaries and that may not be what you want; for example,
+  as of macOS 10.15 Catalina, 32-bit execution is no longer supported by
+  the operating system.  Thus it is best to either explicitly specify
+  values for ``--with-universal-archs``:
+
+      ``--enable-universalsdk --with-universal-archs=intel-64``
+
+  or avoid using either.
+
+
+Building and using a universal binary of Python on macOS
+========================================================
+
+1. What is a universal binary
+-----------------------------
+
+A universal binary build of Python contains object code for more than one
+CPU architecture.  A universal macOS executable file or library combines the
+architecture-specific code into one file and can therefore run at native
+speed on all supported architectures.  Universal files were introduced in
+macOS 10.4 to add support for Intel-based Macs to the existing PowerPC (PPC)
+machines.  In macOS 10.5 support was extended to 64-bit Intel and 64-bit PPC
+architectures.  It is possible to build Python with various combinations
+of architectures depending on the build tools and macOS version in use.
+Note that PPC support was removed in macOS 10.7 and 32-bit Intel support
+was removed in macOS 10.15.  So currently as of macOS 10.15, macOS only
+supports one execution architecture, 64-bit Intel (``x86_64``).
+
+2. How do I build a universal binary
+------------------------------------
+
+You can enable universal binaries by specifying the "--enable-universalsdk"
+flag to configure::
+
+  $ ./configure --enable-universalsdk
+  $ make
+  $ make install
+
+This flag can be used with a framework build of python, but also with a classic
+unix build. Universal builds were first supported with macOS 10.4 with Xcode 2.1
+and the 10.4u SDK.  Starting with Xcode 3 and macOS 10.5, more configurations are
+available.
+
+In general, universal builds depend on specific features provided by the
+Apple-supplied compilers and other build tools included in Apple's Xcode
+development tools.  You should install Xcode or the command line tools
+component appropriate for the macOS release you are running on.  See the
+Python Developer's Guide (https://devguide.python.org/setup/)
+for more information.
+
+2.1 Flavors of universal binaries
+.................................
+
+It is possible to build a number of flavors of the universal binary build,
+the default is a 32-bit only binary (i386 and ppc) in build environments that
+support ppc (10.4 with Xcode 2, 10.5 and 10.6 with Xcode 3) or an
+Intel-32/-64-bit binary (i386 and X86_64) in build environments that do not
+support ppc (Xcode 4 on 10.6 and later systems).  The flavor can be specified
+using the configure option ``--with-universal-archs=VALUE``. The following
+values are available:
+
+  * ``intel``:   ``i386``, ``x86_64``
+
+  * ``intel-32``: ``i386``
+
+  * ``intel-64``: ``x86_64``
+
+  * ``32-bit``:   ``ppc``, ``i386``
+
+  * ``3-way``:   ``i386``, ``x86_64``, ``ppc``
+
+  * ``64-bit``:   ``ppc64``, ``x86_64``
+
+  * ``all``:      ``ppc``, ``ppc64``, ``i386``, ``x86_64``
+
+To build a universal binary that includes a 64-bit architecture, you must build
+on a system running macOS 10.5 or later.  The ``all`` and ``64-bit`` flavors can
+only be built with a 10.5 SDK because ``ppc64`` support was only included with
+macOS 10.5.  Although legacy ``ppc`` support was included with Xcode 3 on macOS
+10.6, it was removed in Xcode 4, versions of which were released on macOS 10.6
+and which is the standard for macOS 10.7.  To summarize, the
+following combinations of SDKs and universal-archs flavors are available:
+
+  * 10.4u SDK with Xcode 2 supports ``32-bit`` only
+
+  * 10.5 SDK with Xcode 3.1.x supports all flavors
+
+  * 10.6 SDK with Xcode 3.2.x supports ``intel``, ``intel-32``,
+    ``intel-64``, ``3-way``, and ``32-bit``
+
+  * 10.6 SDK with Xcode 4 supports ``intel``, ``intel-32``, and ``intel-64``
+
+  * 10.7 through 10.14 SDKs support ``intel``, ``intel-32``, and ``intel-64``
+
+  * 10.15 and later SDKs support ``intel-64`` only
+
+The makefile for a framework build will also install ``python3.x-32``
+binaries when the universal architecture includes at least one 32-bit
+architecture (that is, for all flavors but ``64-bit`` and ``intel-64``).
+
+Running a specific architecture
+...............................
+
+You can run code using a specific architecture using the ``arch`` command::
+
+   $ arch -i386 python
+
+Or to explicitly run in 32-bit mode, regardless of the machine hardware::
+
+   $ arch -i386 -ppc python
+
+Using ``arch`` is not a perfect solution as the selected architecture will
+not automatically carry through to subprocesses launched by programs and tests
+under that Python.  If you want to ensure that Python interpreters launched in
+subprocesses also run in 32-bit-mode if the main interpreter does, use
+a ``python3.x-32`` binary and use the value of ``sys.executable`` as the
+``subprocess`` ``Popen`` executable value.
+
+Building and using a framework-based Python on macOS
+====================================================
+
+
+1. Why would I want a framework Python instead of a normal static Python?
+--------------------------------------------------------------------------
+
+The main reason is because you want to create GUI programs in Python. With the
+exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run
+from a macOS application bundle (".app").
+
+While it is technically possible to create a .app without using frameworks you
+will have to do the work yourself if you really want this.
+
+A second reason for using frameworks is that they put Python-related items in
+only two places: "/Library/Framework/Python.framework" and
+"/Applications/Python <VERSION>" where ``<VERSION>`` can be e.g. "3.8",
+"2.7", etc.  This simplifies matters for users installing
+Python from a binary distribution if they want to get rid of it again. Moreover,
+due to the way frameworks work, usera without admin privileges can install a
+binary distribution in their home directory without recompilation.
+
+2. How does a framework Python differ from a normal static Python?
+------------------------------------------------------------------
+
+In everyday use there is no difference, except that things are stored in
+a different place. If you look in /Library/Frameworks/Python.framework
+you will see lots of relative symlinks, see the Apple documentation for
+details. If you are used to a normal unix Python file layout go down to
+Versions/Current and you will see the familiar bin and lib directories.
+
+3. Do I need extra packages?
+----------------------------
+
+Yes, probably.  If you want Tkinter support you need to get the macOS AquaTk
+distribution, this is installed by default on macOS 10.4 or later.  Be
+aware, though, that the Cocoa-based AquaTk's supplied starting with macOS
+10.6 have proven to be unstable.  If possible, you should consider
+installing a newer version before building on macOS 10.6 or later, such as
+the ActiveTcl 8.6.  See http://www.python.org/download/mac/tcltk/.  If you
+are building with an SDK, ensure that the newer Tcl and Tk frameworks are
+seen in the SDK's ``Library/Frameworks`` directory; you may need to
+manually create symlinks to their installed location, ``/Library/Frameworks``.
+If you want wxPython you need to get that.
+If you want Cocoa you need to get PyObjC.
+
+4. How do I build a framework Python?
+-------------------------------------
+
+This directory contains a Makefile that will create a couple of python-related
+applications (full-blown macOS .app applications, that is) in
+"/Applications/Python <VERSION>", and a hidden helper application Python.app
+inside the Python.framework, and unix tools including "python" into
+/usr/local/bin.  In addition it has a target "installmacsubtree" that installs
+the relevant portions of the Mac subtree into the Python.framework.
+
+It is normally invoked indirectly through the main Makefile, as the last step
+in the sequence
+
+ 1. ./configure --enable-framework
+
+ 2. make
+
+ 3. make install
+
+This sequence will put the framework in ``/Library/Framework/Python.framework``,
+the applications in ``/Applications/Python <VERSION>`` and the unix tools in
+``/usr/local/bin``.
+
+Installing in another place, for instance ``$HOME/Library/Frameworks`` if you
+have no admin privileges on your machine, is possible. This can be accomplished
+by configuring with ``--enable-framework=$HOME/Library/Frameworks``.
+The other two directories will then also be installed in your home directory,
+at ``$HOME/Applications/Python-<VERSION>`` and ``$HOME/bin``.
+
+If you want to install some part, but not all, read the main Makefile. The
+frameworkinstall is composed of a couple of sub-targets that install the
+framework itself, the Mac subtree, the applications and the unix tools.
+
+There is an extra target frameworkinstallextras that is not part of the
+normal frameworkinstall which installs the Tools directory into
+"/Applications/Python <VERSION>", this is useful for binary
+distributions.
+
+What do all these programs do?
+===============================
+
+"IDLE.app" is an integrated development environment for Python: editor,
+debugger, etc.
+
+"Python Launcher.app" is a helper application that will handle things when you
+double-click a .py, .pyc or .pyw file. For the first two it creates a Terminal
+window and runs the scripts with the normal command-line Python. For the
+latter it runs the script in the Python.app interpreter so the script can do
+GUI-things. Keep the ``Option`` key depressed while dragging or double-clicking
+a script to set runtime options. These options can be set persistently
+through Python Launcher's preferences dialog.
+
+The program ``pythonx.x`` runs python scripts from the command line.
+Previously, various compatibility aliases were also installed, including
+``pythonwx.x`` which in early releases of Python on macOS was required to run
+GUI programs.  As of 3.4.0, the ``pythonwx.x`` aliases are no longer installed.
+
+How do I create a binary distribution?
+======================================
+
+Download and unpack the source release from http://www.python.org/download/.
+Go to the directory ``Mac/BuildScript``. There you will find a script
+``build-installer.py`` that does all the work. This will download and build
+a number of 3rd-party libaries, configures and builds a framework Python,
+installs it, creates the installer package files and then packs this in a
+DMG image.  The script also builds an HTML copy of the current Python
+documentation set for this release for inclusion in the framework.  The
+installer package will create links to the documentation for use by IDLE,
+pydoc, shell users, and Finder user.
+
+The script will build a universal binary so you'll therefore have to run this
+script on macOS 10.4 or later and with Xcode 2.1 or later installed.
+However, the Python build process itself has several build dependencies not
+available out of the box with macOS 10.4 so you may have to install
+additional software beyond what is provided with Xcode 2.
+It should be possible to use SDKs and/or older
+versions of Xcode to build installers that are compatible with older systems
+on a newer system but this may not be completely foolproof so the resulting
+executables, shared libraries, and ``.so`` bundles should be carefully
+examined and tested on all supported systems for proper dynamic linking
+dependencies.  It is safest to build the distribution on a system running the
+minimum macOS version supported.
+
+All of this is normally done completely isolated in /tmp/_py, so it does not
+use your normal build directory nor does it install into /.
+
+Because of the way the script locates the files it needs you have to run it
+from within the BuildScript directory. The script accepts a number of
+command-line arguments, run it with --help for more information.
+
+Configure warnings
+==================
+
+The configure script sometimes emits warnings like the one below::
+
+   configure: WARNING: libintl.h: present but cannot be compiled
+   configure: WARNING: libintl.h:     check for missing prerequisite headers?
+   configure: WARNING: libintl.h: see the Autoconf documentation
+   configure: WARNING: libintl.h:     section "Present But Cannot Be Compiled"
+   configure: WARNING: libintl.h: proceeding with the preprocessor's result
+   configure: WARNING: libintl.h: in the future, the compiler will take precedence
+   configure: WARNING:     ## -------------------------------------- ##
+   configure: WARNING:     ## Report this to http://bugs.python.org/ ##
+   configure: WARNING:     ## -------------------------------------- ##
+
+This almost always means you are trying to build a universal binary for
+Python and have libraries in ``/usr/local`` that don't contain the required
+architectures. Temporarily move ``/usr/local`` aside to finish the build.
+
+
+Uninstalling a framework install, including the binary installer
+================================================================
+
+Uninstalling a framework can be done by manually removing all bits that got installed.
+That's true for both installations from source and installations using the binary installer.
+macOS does not provide a central uninstaller.
+
+The main bit of a framework install is the framework itself, installed in
+``/Library/Frameworks/Python.framework``. This can contain multiple versions
+of Python, if you want to remove just one version you have to remove the
+version-specific subdirectory: ``/Library/Frameworks/Python.framework/Versions/X.Y``.
+If you do that, ensure that ``/Library/Frameworks/Python.framework/Versions/Current``
+is a symlink that points to an installed version of Python.
+
+A framework install also installs some applications in ``/Applications/Python X.Y``,
+
+And lastly a framework installation installs files in ``/usr/local/bin``, all of
+them symbolic links to files in ``/Library/Frameworks/Python.framework/Versions/X.Y/bin``.
+
+
+Resources
+=========
+
+  *  http://www.python.org/download/mac/
+
+  *  http://www.python.org/community/sigs/current/pythonmac-sig/
+
+  *  https://devguide.python.org/
index babe4e0416818b23923bb87110dd446afb1d6a8e..beaccf589488094d6d23569be104751e23b46f5f 100644 (file)
@@ -321,8 +321,9 @@ PGOBJS=             \
                Parser/pgenmain.o
 
 PARSER_HEADERS= \
-               $(srcdir)/Parser/parser.h \
+               $(srcdir)/Include/grammar.h \
                $(srcdir)/Include/parsetok.h \
+               $(srcdir)/Parser/parser.h \
                $(srcdir)/Parser/tokenizer.h
 
 PGENOBJS=      $(POBJS) $(PGOBJS)
@@ -856,7 +857,7 @@ regen-opcode:
                $(srcdir)/Include/opcode.h.new
        $(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new
 
-Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h
+Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o Python/future.o Parser/parsetok.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h
 
 Python/getplatform.o: $(srcdir)/Python/getplatform.c
                $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c
@@ -951,11 +952,11 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/accu.h \
                $(srcdir)/Include/asdl.h \
                $(srcdir)/Include/ast.h \
-               $(srcdir)/Include/bltinmodule.h \
                $(srcdir)/Include/bitset.h \
+               $(srcdir)/Include/bltinmodule.h \
                $(srcdir)/Include/boolobject.h \
-               $(srcdir)/Include/bytes_methods.h \
                $(srcdir)/Include/bytearrayobject.h \
+               $(srcdir)/Include/bytes_methods.h \
                $(srcdir)/Include/bytesobject.h \
                $(srcdir)/Include/cellobject.h \
                $(srcdir)/Include/ceval.h \
@@ -964,6 +965,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/codecs.h \
                $(srcdir)/Include/compile.h \
                $(srcdir)/Include/complexobject.h \
+               $(srcdir)/Include/context.h \
                $(srcdir)/Include/descrobject.h \
                $(srcdir)/Include/dictobject.h \
                $(srcdir)/Include/dtoa.h \
@@ -993,6 +995,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/node.h \
                $(srcdir)/Include/object.h \
                $(srcdir)/Include/objimpl.h \
+               $(srcdir)/Include/odictobject.h \
                $(srcdir)/Include/opcode.h \
                $(srcdir)/Include/osdefs.h \
                $(srcdir)/Include/osmodule.h \
@@ -1009,15 +1012,15 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/pyfpe.h \
                $(srcdir)/Include/pyhash.h \
                $(srcdir)/Include/pylifecycle.h \
-               $(srcdir)/Include/pymath.h \
+               $(srcdir)/Include/pymacconfig.h \
                $(srcdir)/Include/pymacro.h \
+               $(srcdir)/Include/pymath.h \
                $(srcdir)/Include/pymem.h \
                $(srcdir)/Include/pyport.h \
                $(srcdir)/Include/pystate.h \
-               $(srcdir)/Include/context.h \
                $(srcdir)/Include/pystrcmp.h \
-               $(srcdir)/Include/pystrtod.h \
                $(srcdir)/Include/pystrhex.h \
+               $(srcdir)/Include/pystrtod.h \
                $(srcdir)/Include/pythonrun.h \
                $(srcdir)/Include/pythread.h \
                $(srcdir)/Include/pytime.h \
@@ -1028,6 +1031,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/structseq.h \
                $(srcdir)/Include/symtable.h \
                $(srcdir)/Include/sysmodule.h \
+               $(srcdir)/Include/token.h \
                $(srcdir)/Include/traceback.h \
                $(srcdir)/Include/tupleobject.h \
                $(srcdir)/Include/ucnhash.h \
@@ -1058,6 +1062,11 @@ TESTTIMEOUT=     1200
 
 .PHONY: test testall testuniversal buildbottest pythoninfo
 
+# Remove "test_python_*" directories of previous failed test jobs.
+# Pass TESTOPTS options because it can contain --tempdir option.
+cleantest: build_all
+       $(TESTRUNNER) $(TESTOPTS) --cleanup
+
 # Run a basic set of regression tests.
 # This excludes some tests that are particularly resource-intensive.
 test:          @DEF_MAKE_RULE@ platform
index f7fc70afd173a79b78f724b6cf6d7cd051c63b40..7afc92e7bb767f2b81a4c1f04648312d8239447a 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -58,6 +58,7 @@ Jon Anglin
 Michele Angrisano
 Ankur Ankan
 Heidi Annexstad
+David Antonini
 Ramchandra Apte
 Éric Araujo
 Alexandru Ardelean
@@ -160,6 +161,7 @@ Roy Bixler
 Daniel Black
 Jonathan Black
 Renaud Blanch
+Justin Blanchard
 Mike Bland
 Martin Bless
 Pablo Bleyer
@@ -815,6 +817,7 @@ Lawrence Kesteloot
 Garvit Khatri
 Vivek Khera
 Dhiru Kholia
+Artem Khramov
 Akshit Khurana
 Sanyam Khurana
 Mads Kiilerich
@@ -947,6 +950,7 @@ Alain Leufroy
 Mark Levinson
 Mark Levitt
 Ivan Levkivskyi
+Ben Lewis
 William Lewis
 Akira Li
 Robert Li
@@ -1305,6 +1309,7 @@ Burton Radons
 Abhilash Raj
 Shorya Raj
 Dhushyanth Ramasamy
+Ashwin Ramaswami
 Jeff Ramnani
 Bayard Randel
 Varpu Rantala
@@ -1509,6 +1514,7 @@ Ng Pheng Siong
 Yann Sionneau
 George Sipe
 J. Sipprell
+Ngalim Siregar
 Kragen Sitaker
 Kaartic Sivaraam
 Ville Skyttä
@@ -1582,6 +1588,7 @@ Kalle Svensson
 Andrew Svetlov
 Paul Swartz
 Al Sweigart
+Sviatoslav Sydorenko
 Thenault Sylvain
 Péter Szabó
 John Szakmeister
@@ -1670,6 +1677,7 @@ Michael Urman
 Hector Urtubia
 Lukas Vacek
 Ville Vainio
+Yann Vaginay
 Andi Vajda
 Case Van Horsen
 John Mark Vandenberg
@@ -1824,6 +1832,7 @@ Nickolai Zeldovich
 Yuxiao Zeng
 Uwe Zessin
 Cheng Zhang
+George Zhang
 Kai Zhu
 Tarek Ziadé
 Jelle Zijlstra
@@ -1832,3 +1841,4 @@ Doug Zongker
 Peter Åstrand
 Zheao Li
 Geoff Shannon
+Ngalim Siregar
index 7c2b0dca08ebc3dba95205c655090b2f2a58cb41..af08260b970d316705d74324928b27f37a77f971 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,497 @@
 Python News
 +++++++++++
 
+What's New in Python 3.7.5 final?
+=================================
+
+*Release date: 2019-10-14*
+
+Library
+-------
+
+- bpo-38368: Prevent ctypes crash when handling arrays in structs/unions.
+
+- bpo-38449: Revert GH-15522, which introduces a regression in
+  :meth:`mimetypes.guess_type` due to improper handling of filenames as
+  urls.
+
+Windows
+-------
+
+- bpo-38344: Fix syntax in activate.bat.
+
+
+What's New in Python 3.7.5 release candidate 1?
+===============================================
+
+*Release date: 2019-10-01*
+
+Security
+--------
+
+- bpo-38243: Escape the server title of
+  :class:`xmlrpc.server.DocXMLRPCServer` when rendering the document page as
+  HTML. (Contributed by Dong-hee Na in :issue:`38243`.)
+
+- bpo-38174: Update vendorized expat library version to 2.2.8, which
+  resolves CVE-2019-15903.
+
+- bpo-37764: Fixes email._header_value_parser.get_unstructured going into an
+  infinite loop for a specific case in which the email header does not have
+  trailing whitespace, and the case in which it contains an invalid encoded
+  word. Patch by Ashwin Ramaswami.
+
+- bpo-37461: Fix an infinite loop when parsing specially crafted email
+  headers. Patch by Abhilash Raj.
+
+- bpo-34155: Fix parsing of invalid email addresses with more than one ``@``
+  (e.g. a@b@c.com.) to not return the part before 2nd ``@`` as valid email
+  address. Patch by maxking & jpic.
+
+Core and Builtins
+-----------------
+
+- bpo-36871: Improve error handling for the assert_has_calls method of
+  mocks. Fixed a bug where any errors encountered while binding the expected
+  calls to the mock's spec were silently swallowed, leading to misleading
+  error output.
+
+- bpo-38013: Allow to call ``async_generator_athrow().throw(...)`` even for
+  non-started async generator helper. It fixes annoying warning at the end
+  of :func:`asyncio.run` call.
+
+- bpo-38124: Fix an off-by-one error in PyState_AddModule that could cause
+  out-of-bounds memory access.
+
+- bpo-36946: Fix possible signed integer overflow when handling slices.
+  Patch by hongweipeng.
+
+- bpo-37409: Ensure explicit relative imports from interactive sessions and
+  scripts (having no parent package) always raise ImportError, rather than
+  treating the current module as the package. Patch by Ben Lewis.
+
+- bpo-36311: Decoding bytes objects larger than 2GiB is faster and no longer
+  fails when a multibyte characters spans a chunk boundary.
+
+- bpo-37467: Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a
+  filename is a bytes string. For example, for a SyntaxError exception where
+  the filename attribute is a bytes string.
+
+- bpo-37417: :meth:`bytearray.extend` now correctly handles errors that
+  arise during iteration. Patch by Brandt Bucher.
+
+- bpo-20523: ``pdb.Pdb`` supports ~/.pdbrc in Windows 7. Patch by Tim Hopper
+  and Dan Lidral-Porter.
+
+Library
+-------
+
+- bpo-38019: Correctly handle pause/resume reading of closed asyncio unix
+  pipe.
+
+- bpo-38216: Allow the rare code that wants to send invalid http requests
+  from the `http.client` library a way to do so.  The fixes for bpo-30458
+  led to breakage for some projects that were relying on this ability to
+  test their own behavior in the face of bad requests.
+
+- bpo-38191: Constructor of :class:`~typing.NamedTuple` type now accepts
+  arbitrary keyword argument names, including "cls", "self", "typename" and
+  "fields".
+
+- bpo-38185: Fixed case-insensitive string comparison in
+  :class:`sqlite3.Row` indexing.
+
+- bpo-38175: Fix a memory leak in comparison of :class:`sqlite3.Row`
+  objects.
+
+- bpo-33936: _hashlib no longer calls obsolete OpenSSL initialization
+  function with OpenSSL 1.1.0+.
+
+- bpo-34706: Preserve subclassing in inspect.Signature.from_callable.
+
+- bpo-38059: inspect.py now uses sys.exit() instead of exit()
+
+- bpo-38006: weakref.WeakValueDictionary defines a local remove() function
+  used as callback for weak references. This function was created with a
+  closure. Modify the implementation to avoid the closure.
+
+- bpo-34410: Fixed a crash in the :func:`tee` iterator when re-enter it.
+  RuntimeError is now raised in this case.
+
+- bpo-37965: Fix C compiler warning caused by
+  distutils.ccompiler.CCompiler.has_function.
+
+- bpo-36205: Fix the rusage implementation of time.process_time() to
+  correctly report the sum of the system and user CPU time.
+
+- bpo-22347: Update mimetypes.guess_type to allow proper parsing of URLs
+  with only a host name. Patch by Dong-hee Na.
+
+- bpo-37950: Fix :func:`ast.dump` when call with incompletely initialized
+  node.
+
+- bpo-37915: Fix a segmentation fault that appeared when comparing instances
+  of ``datetime.timezone`` and ``datetime.tzinfo`` objects. Patch by Pablo
+  Galindo.
+
+- bpo-37885: venv: Don't generate unset variable warning on deactivate.
+
+- bpo-37868: Fix dataclasses.is_dataclass when given an instance that never
+  raises AttributeError in __getattr__.  That is, an object that returns
+  something for __dataclass_fields__ even if it's not a dataclass.
+
+- bpo-37811: Fix ``socket`` module's ``socket.connect(address)`` function
+  being unable to establish connection in case of interrupted system call.
+  The problem was observed on all OSes which ``poll(2)`` system call can
+  take only non-negative integers and -1 as a timeout value.
+
+- bpo-21131: Fix ``faulthandler.register(chain=True)`` stack. faulthandler
+  now allocates a dedicated stack of ``SIGSTKSZ*2`` bytes, instead of just
+  ``SIGSTKSZ`` bytes. Calling the previous signal handler in faulthandler
+  signal handler uses more than ``SIGSTKSZ`` bytes of stack memory on some
+  platforms.
+
+- bpo-34621: Fixed unpickle-ability in older Python versions (<3.7) of UUID
+  objects with ``is_safe`` set to ``SafeUUID.unknown``.
+
+- bpo-37738: Fix the implementation of curses ``addch(str, color_pair)``:
+  pass the color pair to ``setcchar()``, instead of always passing 0 as the
+  color pair.
+
+- bpo-37723: Fix performance regression on regular expression parsing with
+  huge character sets. Patch by Yann Vaginay.
+
+- bpo-32178: Fix IndexError in :mod:`email` package when trying to parse
+  invalid address fields starting with ``:``.
+
+- bpo-37685: Fixed comparisons of :class:`datetime.timedelta` and
+  :class:`datetime.timezone`.
+
+- bpo-37695: Correct :func:`curses.unget_wch` error message.  Patch by
+  Anthony Sottile.
+
+- bpo-29553: Fixed :meth:`argparse.ArgumentParser.format_usage` for mutually
+  exclusive groups. Patch by Andrew Nester.
+
+- bpo-37664: Update wheels bundled with ensurepip (pip 19.2.3 and setuptools
+  41.2.0)
+
+- bpo-37642: Allowed the pure Python implementation of
+  :class:`datetime.timezone` to represent sub-minute offsets close to
+  minimum and maximum boundaries, specifically in the ranges (23:59, 24:00)
+  and (-23:59, 24:00). Patch by Ngalim Siregar
+
+- bpo-37491: Fix ``IndexError`` when parsing email headers with unexpectedly
+  ending bare-quoted string value. Patch by Abhilash Raj.
+
+- bpo-18378: Recognize "UTF-8" as a valid value for LC_CTYPE in
+  locale._parse_localename.
+
+- bpo-37579: Return :exc:`NotImplemented` in Python implementation of
+  ``__eq__`` for :class:`~datetime.timedelta` and :class:`~datetime.time`
+  when the other object being compared is not of the same type to match C
+  implementation. Patch by Karthikeyan Singaravelan.
+
+- bpo-21478: Record calls to parent when autospecced object is attached to a
+  mock using :func:`unittest.mock.attach_mock`. Patch by Karthikeyan
+  Singaravelan.
+
+- bpo-37531: "python3 -m test -jN --timeout=TIMEOUT" now kills a worker
+  process if it runs longer than *TIMEOUT* seconds.
+
+- bpo-37482: Fix serialization of display name in originator or destination
+  address fields with both encoded words and special chars.
+
+- bpo-37424: Fixes a possible hang when using a timeout on
+  `subprocess.run()` while capturing output.  If the child process spawned
+  its own children or otherwise connected its stdout or stderr handles with
+  another process, we could hang after the timeout was reached and our child
+  was killed when attempting to read final output from the pipes.
+
+- bpo-37421: Fix :func:`multiprocessing.util.get_temp_dir` finalizer: clear
+  also the 'tempdir' configuration of the current process, so next call to
+  ``get_temp_dir()`` will create a new temporary directory, rather than
+  reusing the removed temporary directory.
+
+- bpo-37420: :func:`os.sched_setaffinity` now correctly handles errors that
+  arise during iteration over its ``mask`` argument. Patch by Brandt Bucher.
+
+- bpo-29412: Fix IndexError in parsing a header value ending unexpectedly.
+  Patch by Abhilash Raj.
+
+- bpo-37372: Fix error unpickling datetime.time objects from Python 2 with
+  seconds>=24. Patch by Justin Blanchard.
+
+- bpo-27860: Fix ``IPv4Interface`` and ``IPv6Interface`` didn't accept
+  string mask when the argument is tuple.
+
+- bpo-33972: Email with single part but content-type set to ``multipart/*``
+  doesn't raise AttributeError anymore.
+
+- bpo-21872: Fix :mod:`lzma`: module decompresses data incompletely. When
+  decompressing a FORMAT_ALONE format file, and it doesn't have the end
+  marker, sometimes the last one to dozens bytes can't be output. Patch by
+  Ma Lin.
+
+- bpo-12144: Ensure cookies with ``expires`` attribute are handled in
+  :meth:`CookieJar.make_cookies`.
+
+- bpo-37163: :func:`dataclasses.replace` now supports the field named "obj".
+
+- bpo-36871: Ensure method signature is used instead of constructor
+  signature of a class while asserting mock object against method calls.
+  Patch by Karthikeyan Singaravelan.
+
+- bpo-36564: Fix infinite loop in email header folding logic that would be
+  triggered when an email policy's max_line_length is not long enough to
+  include the required markup and any values in the message. Patch by Paul
+  Ganssle
+
+- bpo-35168: :attr:`shlex.shlex.punctuation_chars` is now a read-only
+  property.
+
+- bpo-20504: Fixes a bug in :mod:`cgi` module when a multipart/form-data
+  request has no `Content-Length` header.
+
+- bpo-4963: Fixed non-deterministic behavior related to mimetypes extension
+  mapping and module reinitialization.
+
+Documentation
+-------------
+
+- bpo-26868: Fix example usage of :c:func:`PyModule_AddObject` to properly
+  handle errors.
+
+- bpo-37979: Added a link to dateutil.parser.isoparse in the
+  datetime.fromisoformat documentation. Patch by Paul Ganssle
+
+- bpo-37937: Mention ``frame.f_trace`` in :func:`sys.settrace` docs.
+
+- bpo-37726: Stop recommending getopt in the tutorial for command line
+  argument parsing and promote argparse.
+
+- bpo-32910: Remove implementation-specific behaviour of how venv's
+  Deactivate works.
+
+- bpo-37256: Fix wording of arguments for :class:`Request` in
+  :mod:`urllib.request`
+
+- bpo-37284: Add a brief note to indicate that any new
+  ``sys.implementation`` required attributes must go through the PEP
+  process.
+
+- bpo-30088: Documented that :class:`mailbox.Maildir` constructor doesn't
+  attempt to verify the maildir folder layout correctness. Patch by
+  Sviatoslav Sydorenko.
+
+- bpo-37487: Fix PyList_GetItem index description to include 0.
+
+- bpo-37478: Added possible exceptions to the description of os.chdir().
+
+- bpo-37004: In the documentation for difflib, a note was added explicitly
+  warning that the results of SequenceMatcher's ratio method may depend on
+  the order of the input strings.
+
+- bpo-35803: Document and test that ``tempfile`` functions may accept a
+  :term:`path-like object` for the ``dir`` argument.  Patch by Anthony
+  Sottile.
+
+- bpo-34293: Fix the Doc/Makefile regarding PAPER environment variable and
+  PDF builds
+
+Tests
+-----
+
+- bpo-38239: Fix test_gdb for Link Time Optimization (LTO) builds.
+
+- bpo-38275: test_ssl now handles disabled TLS/SSL versions better.
+  OpenSSL's crypto policy and run-time settings are recognized and tests for
+  disabled versions are skipped. Tests also accept more TLS minimum_versions
+  for platforms that override OpenSSL's default with strict settings.
+
+- bpo-38271: The private keys for test_ssl were encrypted with 3DES in
+  traditional PKCS#5 format. 3DES and the digest algorithm of PKCS#5 are
+  blocked by some strict crypto policies. Use PKCS#8 format with AES256
+  encryption instead.
+
+- bpo-37123: Multiprocessing test test_mymanager() now also expects
+  -SIGTERM, not only exitcode 0. BaseManager._finalize_manager() sends
+  SIGTERM to the manager process if it takes longer than 1 second to stop,
+  which happens on slow buildbots.
+
+- bpo-38212: Multiprocessing tests: increase
+  test_queue_feeder_donot_stop_onexc() timeout from 1 to 60 seconds.
+
+- bpo-38117: Test with OpenSSL 1.1.1d
+
+- bpo-37805: Add tests for json.dump(..., skipkeys=True). Patch by Dong-hee
+  Na.
+
+- bpo-37531: Enhance regrtest multiprocess timeout: write a message when
+  killing a worker process, catch popen.kill() and popen.wait() exceptions,
+  put a timeout on the second call to popen.communicate().
+
+- bpo-37335: Improve locale coercion tests by using codec lookup instead of
+  more fragile replace().
+
+- bpo-37411: Fix test_wsgiref.testEnviron() to no longer depend on the
+  environment variables (don't fail if "X" variable is set).
+
+- bpo-37400: Fix test_os.test_chown(): use os.getgroups() rather than
+  grp.getgrall() to get groups. Rename also the test to test_chown_gid().
+
+- bpo-37359: Add --cleanup option to python3 -m test to remove
+  ``test_python_*`` directories of previous failed jobs. Add "make
+  cleantest" to run ``python3 -m test --cleanup``.
+
+- bpo-37362: test_gdb no longer fails if it gets an "unexpected" message on
+  stderr: it now ignores stderr. The purpose of test_gdb is to test that
+  python-gdb.py commands work as expected, not to test gdb.
+
+- bpo-36919: Make ``test_source_encoding.test_issue2301`` implementation
+  independent. The test will work now for both CPython and IronPython.
+
+- bpo-34720: Assert m_state != NULL to mimic GC traversal functions that do
+  not correctly handle module creation when the module state has not been
+  created.
+
+- bpo-34347: Fix ``test_utf8_mode.test_cmd_line`` for AIX.  Patch by M. Felt
+
+Build
+-----
+
+- bpo-38301: In Solaris family, we must be sure to use ``-D_REENTRANT``.
+  Patch by Jesús Cea Avión.
+
+- bpo-36002: Locate ``llvm-profdata`` and ``llvm-ar`` binaries using
+  ``AC_PATH_TOOL`` rather than ``AC_PATH_TARGET_TOOL``.
+
+- bpo-37936: The :file:`.gitignore` file no longer applies to any files that
+  are in fact tracked in the Git repository.  Patch by Greg Price.
+
+Windows
+-------
+
+- bpo-38117: Update bundled OpenSSL to 1.1.1d
+
+- bpo-36634: venv activate.bat now works when the existing variables contain
+  double quote characters.
+
+- bpo-38087: Fix case sensitivity in test_pathlib and test_ntpath.
+
+- bpo-38088: Fixes distutils not finding vcruntime140.dll with only the v142
+  toolset installed.
+
+- bpo-37283: Ensure command-line and unattend.xml setting override
+  previously detected states in Windows installer.
+
+- bpo-37705: Improve the implementation of ``winerror_to_errno()``.
+
+- bpo-37549: :func:`os.dup` no longer fails for standard streams on Windows
+  7.
+
+- bpo-37702: Fix memory leak on Windows in creating an SSLContext object or
+  running urllib.request.urlopen('https://...').
+
+- bpo-10945: Officially drop support for creating bdist_wininst installers
+  on non-Windows systems.
+
+- bpo-37445: Include the ``FORMAT_MESSAGE_IGNORE_INSERTS`` flag in
+  ``FormatMessageW()`` calls.
+
+- bpo-37380: Don't collect unfinished processes with ``subprocess._active``
+  on Windows to cleanup later. Patch by Ruslan Kuprieiev.
+
+- bpo-32587: Make :data:`winreg.REG_MULTI_SZ` support zero-length strings.
+
+macOS
+-----
+
+- bpo-38117: Updated OpenSSL to 1.1.1d in macOS installer.
+
+- bpo-38089: Move Azure Pipelines to latest VM versions and make macOS tests
+  optional
+
+IDLE
+----
+
+- bpo-35379: When exiting IDLE, catch any AttributeError.  One happens when
+  EditorWindow.close is called twice.  Printing a traceback, when IDLE is
+  run from a terminal, is useless and annoying.
+
+- bpo-38183: To avoid problems, test_idle ignores the user config directory.
+  It no longer tries to create or access .idlerc or any files within. Users
+  must run IDLE to discover problems with saving settings.
+
+- bpo-38077: IDLE no longer adds 'argv' to the user namespace when
+  initializing it.  This bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4.
+
+- bpo-38041: Shell restart lines now fill the window width, always start
+  with '=', and avoid wrapping unnecessarily. The line will still wrap if
+  the included file name is long relative to the width.
+
+- bpo-35771: To avoid occasional spurious test_idle failures on slower
+  machines, increase the ``hover_delay`` in test_tooltip.
+
+- bpo-37824: Properly handle user input warnings in IDLE shell. Cease
+  turning SyntaxWarnings into SyntaxErrors.
+
+- bpo-37929: IDLE Settings dialog now closes properly when there is no shell
+  window.
+
+- bpo-37902: Add mousewheel scrolling for IDLE module, path, and stack
+  browsers. Patch by George Zhang.
+
+- bpo-37849: Fixed completions list appearing too high or low when shown
+  above the current line.
+
+- bpo-36419: Refactor IDLE autocomplete and improve testing.
+
+- bpo-37748: Reorder the Run menu.  Put the most common choice, Run Module,
+  at the top.
+
+- bpo-37692: Improve highlight config sample with example shell interaction
+  and better labels for shell elements.
+
+- bpo-37628: Settings dialog no longer expands with font size.
+
+- bpo-37627: Initialize the Customize Run dialog with the command line
+  arguments most recently entered before.  The user can optionally edit
+  before submitting them.
+
+- bpo-33610: Fix code context not showing the correct context when first
+  toggled on.
+
+- bpo-37530: Optimize code context to reduce unneeded background activity.
+  Font and highlight changes now occur along with text changes instead of
+  after a random delay.
+
+- bpo-27452: Cleanup ``config.py`` by inlining ``RemoveFile`` and
+  simplifying the handling of ``file`` in ``CreateConfigHandlers``.
+
+- bpo-37325: Fix tab focus traversal order for help source and custom run
+  dialogs.
+
+- bpo-17535: Add optional line numbers for IDLE editor windows.  Windows
+  open without line numbers unless set otherwise in the General tab of the
+  configuration dialog.
+
+- bpo-26806: To compensate for stack frames added by IDLE and avoid possible
+  problems with low recursion limits, add 30 to limits in the user code
+  execution process.  Subtract 30 when reporting recursion limits to make
+  this addition mostly transparent.
+
+- bpo-36390: Gather Format menu functions into format.py.  Combine
+  paragraph.py, rstrip.py, and format methods from editor.py.
+
+Tools/Demos
+-----------
+
+- bpo-37803: pdb's ``--help`` and ``--version`` long options now work.
+
+- bpo-37675: 2to3 now works when run from a zipped standard library.
+
+
 What's New in Python 3.7.4 final?
 =================================
 
@@ -8220,9 +8711,8 @@ IDLE
   '<<force-open-calltip>>', '<<flash-paren>>', '<<format-paragraph>>',
   '<<run-module>>', '<<check-module>>', and '<<zoom-height>>'.  Any (global)
   customizations made before 3.6.3 will not affect their keyset-specific
-  customization after 3.6.3. and vice versa.
-
-  Inital patch by Charles Wohlganger.
+  customization after 3.6.3. and vice versa. Initial patch by Charles
+  Wohlganger.
 
 - bpo-31206: IDLE: Factor HighPage(Frame) class from ConfigDialog. Patch by
   Cheryl Sabella.
@@ -12190,7 +12680,7 @@ Build
 - bpo-26624: Adds validation of ucrtbase[d].dll version with warning for old
   versions.
 
-- bpo-17603: Avoid error about nonexistant fileblocks.o file by using a
+- bpo-17603: Avoid error about nonexistent fileblocks.o file by using a
   lower-level check for st_blocks in struct stat.
 
 - bpo-26079: Fixing the build output folder for tix-8.4.3.6. Patch by Bjoern
@@ -14171,7 +14661,7 @@ Build
 - bpo-26624: Adds validation of ucrtbase[d].dll version with warning for old
   versions.
 
-- bpo-17603: Avoid error about nonexistant fileblocks.o file by using a
+- bpo-17603: Avoid error about nonexistent fileblocks.o file by using a
   lower-level check for st_blocks in struct stat.
 
 - bpo-26079: Fixing the build output folder for tix-8.4.3.6. Patch by Bjoern
index dd0b3c8107eb6eadde052266645269fb27372520..6f7becfa886146260422b88e9c173e57e5c76d56 100644 (file)
@@ -825,7 +825,7 @@ Reader_iternext(ReaderObj *self)
             if (c == '\0') {
                 Py_DECREF(lineobj);
                 PyErr_Format(_csvstate_global->error_obj,
-                             "line contains NULL byte");
+                             "line contains NUL");
                 goto err;
             }
             if (parse_process_char(self, c) < 0) {
index 8fa6627552619ec389f0369fd3d4fbf11ebfa803..f186e5082afbf289425ac844d5bacad966db4a05 100644 (file)
@@ -1094,7 +1094,11 @@ PyCPointerType_from_param(PyObject *type, PyObject *value)
         */
         StgDictObject *v = PyObject_stgdict(value);
         assert(v); /* Cannot be NULL for pointer or array objects */
-        if (PyObject_IsSubclass(v->proto, typedict->proto)) {
+        int ret = PyObject_IsSubclass(v->proto, typedict->proto);
+        if (ret < 0) {
+            return NULL;
+        }
+        if (ret) {
             Py_INCREF(value);
             return value;
         }
@@ -5019,7 +5023,8 @@ Pointer_subscript(PyObject *myself, PyObject *item)
         PyObject *np;
         StgDictObject *stgdict, *itemdict;
         PyObject *proto;
-        Py_ssize_t i, len, cur;
+        Py_ssize_t i, len;
+        size_t cur;
 
         /* Since pointers have no length, and we want to apply
            different semantics to negative indices than normal
index 0152945ca1ad50c9f453e4cd0240b28cee020a93..f59abcc451591fc28d9c4bd262c43a8a8bd84729 100644 (file)
@@ -74,6 +74,66 @@ _testfunc_reg_struct_update_value(TestReg in)
     ((volatile TestReg *)&in)->second = 0x0badf00d;
 }
 
+/*
+ * See bpo-22273. Structs containing arrays should work on Linux 64-bit.
+ */
+
+typedef struct {
+    unsigned char data[16];
+} Test2;
+
+EXPORT(int)
+_testfunc_array_in_struct1(Test2 in)
+{
+    int result = 0;
+
+    for (unsigned i = 0; i < 16; i++)
+        result += in.data[i];
+    /* As the structure is passed by value, changes to it shouldn't be
+     * reflected in the caller.
+     */
+    memset(in.data, 0, sizeof(in.data));
+    return result;
+}
+
+typedef struct {
+    double data[2];
+} Test3;
+
+typedef struct {
+    float data[2];
+    float more_data[2];
+} Test3B;
+
+EXPORT(double)
+_testfunc_array_in_struct2(Test3 in)
+{
+    double result = 0;
+
+    for (unsigned i = 0; i < 2; i++)
+        result += in.data[i];
+    /* As the structure is passed by value, changes to it shouldn't be
+     * reflected in the caller.
+     */
+    memset(in.data, 0, sizeof(in.data));
+    return result;
+}
+
+EXPORT(double)
+_testfunc_array_in_struct2a(Test3B in)
+{
+    double result = 0;
+
+    for (unsigned i = 0; i < 2; i++)
+        result += in.data[i];
+    for (unsigned i = 0; i < 2; i++)
+        result += in.more_data[i];
+    /* As the structure is passed by value, changes to it shouldn't be
+     * reflected in the caller.
+     */
+    memset(in.data, 0, sizeof(in.data));
+    return result;
+}
 
 EXPORT(void)testfunc_array(int values[4])
 {
index 5a8303fba290cbf32f525464b9c0023f51f4ad6d..a3d1c386b724a07277befaab5b7241a5bb49f6ed 100644 (file)
@@ -417,8 +417,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
 static void LoadPython(void)
 {
     if (!Py_IsInitialized()) {
-        PyEval_InitThreads();
         Py_Initialize();
+        PyEval_InitThreads();
     }
 }
 
index ec854c864cc20f357f7c67221bbddf9ca90931ce..5861042398d403e373eab6886a35e094bf0e3275 100644 (file)
@@ -239,7 +239,9 @@ static WCHAR *FormatError(DWORD code)
 {
     WCHAR *lpMsgBuf;
     DWORD n;
-    n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+    n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                       FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
                        NULL,
                        code,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
index 25656ff878759cf3d3a89850414d823ccc5cabbf..af12d314ab98f55f510f6bd791417f3fda9e9b35 100644 (file)
@@ -344,6 +344,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
     int pack = 0;
     Py_ssize_t ffi_ofs;
     int big_endian;
+    int arrays_seen = 0;
 
     /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to
        be a way to use the old, broken sematics: _fields_ are not extended
@@ -468,6 +469,8 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
             Py_XDECREF(pair);
             return -1;
         }
+        if (PyCArrayTypeObject_Check(desc))
+            arrays_seen = 1;
         dict = PyType_stgdict(desc);
         if (dict == NULL) {
             Py_DECREF(pair);
@@ -608,6 +611,240 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
     stgdict->align = total_align;
     stgdict->length = len;      /* ADD ffi_ofs? */
 
+#define MAX_STRUCT_SIZE 16
+
+    if (arrays_seen && (size <= MAX_STRUCT_SIZE)) {
+        /*
+         * See bpo-22273. Arrays are normally treated as pointers, which is
+         * fine when an array name is being passed as parameter, but not when
+         * passing structures by value that contain arrays. On 64-bit Linux,
+         * small structures passed by value are passed in registers, and in
+         * order to do this, libffi needs to know the true type of the array
+         * members of structs. Treating them as pointers breaks things.
+         *
+         * By small structures, we mean ones that are 16 bytes or less. In that
+         * case, there can't be more than 16 elements after unrolling arrays,
+         * as we (will) disallow bitfields. So we can collect the true ffi_type
+         * values in a fixed-size local array on the stack and, if any arrays
+         * were seen, replace the ffi_type_pointer.elements with a more
+         * accurate set, to allow libffi to marshal them into registers
+         * correctly. It means one more loop over the fields, but if we got
+         * here, the structure is small, so there aren't too many of those.
+         *
+         * Although the passing in registers is specific to 64-bit Linux, the
+         * array-in-struct vs. pointer problem is general. But we restrict the
+         * type transformation to small structs nonetheless.
+         *
+         * Note that although a union may be small in terms of memory usage, it
+         * could contain many overlapping declarations of arrays, e.g.
+         *
+         * union {
+         *     unsigned int_8 foo [16];
+         *     unsigned uint_8 bar [16];
+         *     unsigned int_16 baz[8];
+         *     unsigned uint_16 bozz[8];
+         *     unsigned int_32 fizz[4];
+         *     unsigned uint_32 buzz[4];
+         * }
+         *
+         * which is still only 16 bytes in size. We need to convert this into
+         * the following equivalent for libffi:
+         *
+         * union {
+         *     struct { int_8 e1; int_8 e2; ... int_8 e_16; } f1;
+         *     struct { uint_8 e1; uint_8 e2; ... uint_8 e_16; } f2;
+         *     struct { int_16 e1; int_16 e2; ... int_16 e_8; } f3;
+         *     struct { uint_16 e1; uint_16 e2; ... uint_16 e_8; } f4;
+         *     struct { int_32 e1; int_32 e2; ... int_32 e_4; } f5;
+         *     struct { uint_32 e1; uint_32 e2; ... uint_32 e_4; } f6;
+         * }
+         *
+         * So the struct/union needs setting up as follows: all non-array
+         * elements copied across as is, and all array elements replaced with
+         * an equivalent struct which has as many fields as the array has
+         * elements, plus one NULL pointer.
+         */
+
+        Py_ssize_t num_ffi_type_pointers = 0;  /* for the dummy fields */
+        Py_ssize_t num_ffi_types = 0;  /* for the dummy structures */
+        size_t alloc_size;  /* total bytes to allocate */
+        void *type_block;  /* to hold all the type information needed */
+        ffi_type **element_types;  /* of this struct/union */
+        ffi_type **dummy_types;  /* of the dummy struct elements */
+        ffi_type *structs;  /* point to struct aliases of arrays */
+        Py_ssize_t element_index;  /* index into element_types for this */
+        Py_ssize_t dummy_index = 0; /* index into dummy field pointers */
+        Py_ssize_t struct_index = 0; /* index into dummy structs */
+
+        /* first pass to see how much memory to allocate */
+        for (i = 0; i < len; ++i) {
+            PyObject *name, *desc;
+            PyObject *pair = PySequence_GetItem(fields, i);
+            StgDictObject *dict;
+            int bitsize = 0;
+
+            if (pair == NULL) {
+                return -1;
+            }
+            if (!PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) {
+                PyErr_SetString(PyExc_TypeError,
+                    "'_fields_' must be a sequence of (name, C type) pairs");
+                Py_DECREF(pair);
+                return -1;
+            }
+            dict = PyType_stgdict(desc);
+            if (dict == NULL) {
+                Py_DECREF(pair);
+                PyErr_Format(PyExc_TypeError,
+                    "second item in _fields_ tuple (index %zd) must be a C type",
+                    i);
+                return -1;
+            }
+            if (!PyCArrayTypeObject_Check(desc)) {
+                /* Not an array. Just need an ffi_type pointer. */
+                num_ffi_type_pointers++;
+            }
+            else {
+                /* It's an array. */
+                Py_ssize_t length = dict->length;
+                StgDictObject *edict;
+
+                edict = PyType_stgdict(dict->proto);
+                if (edict == NULL) {
+                    Py_DECREF(pair);
+                    PyErr_Format(PyExc_TypeError,
+                        "second item in _fields_ tuple (index %zd) must be a C type",
+                        i);
+                    return -1;
+                }
+                /*
+                 * We need one extra ffi_type to hold the struct, and one
+                 * ffi_type pointer per array element + one for a NULL to
+                 * mark the end.
+                 */
+                num_ffi_types++;
+                num_ffi_type_pointers += length + 1;
+            }
+            Py_DECREF(pair);
+        }
+
+        /*
+         * At this point, we know we need storage for some ffi_types and some
+         * ffi_type pointers. We'll allocate these in one block.
+         * There are three sub-blocks of information: the ffi_type pointers to
+         * this structure/union's elements, the ffi_type_pointers to the
+         * dummy fields standing in for array elements, and the
+         * ffi_types representing the dummy structures.
+         */
+        alloc_size = (ffi_ofs + 1 + len + num_ffi_type_pointers) * sizeof(ffi_type *) +
+                        num_ffi_types * sizeof(ffi_type);
+        type_block = PyMem_Malloc(alloc_size);
+
+        if (type_block == NULL) {
+            PyErr_NoMemory();
+            return -1;
+        }
+        /*
+         * the first block takes up ffi_ofs + len + 1 which is the pointers *
+         * for this struct/union. The second block takes up
+         * num_ffi_type_pointers, so the sum of these is ffi_ofs + len + 1 +
+         * num_ffi_type_pointers as allocated above. The last bit is the
+         * num_ffi_types structs.
+         */
+        element_types = (ffi_type **) type_block;
+        dummy_types = &element_types[ffi_ofs + len + 1];
+        structs = (ffi_type *) &dummy_types[num_ffi_type_pointers];
+
+        if (num_ffi_types > 0) {
+            memset(structs, 0, num_ffi_types * sizeof(ffi_type));
+        }
+        if (ffi_ofs && (basedict != NULL)) {
+            memcpy(element_types,
+                basedict->ffi_type_pointer.elements,
+                ffi_ofs * sizeof(ffi_type *));
+        }
+        element_index = ffi_ofs;
+
+        /* second pass to actually set the type pointers */
+        for (i = 0; i < len; ++i) {
+            PyObject *name, *desc;
+            PyObject *pair = PySequence_GetItem(fields, i);
+            StgDictObject *dict;
+            int bitsize = 0;
+
+            if (pair == NULL) {
+                PyMem_Free(type_block);
+                return -1;
+            }
+            /* In theory, we made this call in the first pass, so it *shouldn't*
+             * fail. However, you never know, and the code above might change
+             * later - keeping the check in here is a tad defensive but it
+             * will affect program size only slightly and performance hardly at
+             * all.
+             */
+            if (!PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) {
+                PyErr_SetString(PyExc_TypeError,
+                                "'_fields_' must be a sequence of (name, C type) pairs");
+                Py_DECREF(pair);
+                PyMem_Free(type_block);
+                return -1;
+            }
+            dict = PyType_stgdict(desc);
+            /* Possibly this check could be avoided, but see above comment. */
+            if (dict == NULL) {
+                Py_DECREF(pair);
+                PyMem_Free(type_block);
+                PyErr_Format(PyExc_TypeError,
+                             "second item in _fields_ tuple (index %zd) must be a C type",
+                             i);
+                return -1;
+            }
+            assert(element_index < (ffi_ofs + len)); /* will be used below */
+            if (!PyCArrayTypeObject_Check(desc)) {
+                /* Not an array. Just copy over the element ffi_type. */
+                element_types[element_index++] = &dict->ffi_type_pointer;
+            }
+            else {
+                int length = dict->length;
+                StgDictObject *edict;
+
+                edict = PyType_stgdict(dict->proto);
+                if (edict == NULL) {
+                    Py_DECREF(pair);
+                    PyMem_Free(type_block);
+                    PyErr_Format(PyExc_TypeError,
+                                 "second item in _fields_ tuple (index %zd) must be a C type",
+                                 i);
+                    return -1;
+                }
+                element_types[element_index++] = &structs[struct_index];
+                structs[struct_index].size = length * edict->ffi_type_pointer.size;
+                structs[struct_index].alignment = edict->ffi_type_pointer.alignment;
+                structs[struct_index].type = FFI_TYPE_STRUCT;
+                structs[struct_index].elements = &dummy_types[dummy_index];
+                ++struct_index;
+                /* Copy over the element's type, length times. */
+                while (length > 0) {
+                    assert(dummy_index < (num_ffi_type_pointers));
+                    dummy_types[dummy_index++] = &edict->ffi_type_pointer;
+                    length--;
+                }
+                assert(dummy_index < (num_ffi_type_pointers));
+                dummy_types[dummy_index++] = NULL;
+            }
+            Py_DECREF(pair);
+        }
+
+        element_types[element_index] = NULL;
+        /*
+         * Replace the old elements with the new, taking into account
+         * base class elements where necessary.
+         */
+        assert(stgdict->ffi_type_pointer.elements);
+        PyMem_Free(stgdict->ffi_type_pointer.elements);
+        stgdict->ffi_type_pointer.elements = element_types;
+    }
+
     /* We did check that this flag was NOT set above, it must not
        have been set until now. */
     if (stgdict->flags & DICTFLAG_FINAL) {
index 931c5ceed062f5b98b72d52acd96e778b35f3cc2..b0be6bb30b8f015af2445bc3c4bc3a0f18f40aca 100644 (file)
@@ -178,6 +178,18 @@ static char *screen_encoding = NULL;
 
 /* Utility Functions */
 
+static inline int
+color_pair_to_attr(short color_number)
+{
+    return ((int)color_number << 8);
+}
+
+static inline short
+attr_to_color_pair(int attr)
+{
+    return (short)((attr & A_COLOR) >> 8);
+}
+
 /*
  * Check the return code from a curses function and return None
  * or raise an exception as appropriate.  These are exported using the
@@ -614,7 +626,7 @@ curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y,
     if (type == 2) {
         funcname = "add_wch";
         wstr[1] = L'\0';
-        setcchar(&wcval, wstr, attr, 0, NULL);
+        setcchar(&wcval, wstr, attr, attr_to_color_pair(attr), NULL);
         if (coordinates_group)
             rtn = mvwadd_wch(cwself->win,y,x, &wcval);
         else {
@@ -2204,7 +2216,7 @@ PyCurses_color_pair(PyObject *self, PyObject *args)
     PyCursesInitialisedColor;
 
     if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL;
-    return PyLong_FromLong((long) (n << 8));
+    return PyLong_FromLong(color_pair_to_attr(n));
 }
 
 static PyObject *
@@ -2802,7 +2814,7 @@ PyCurses_pair_number(PyObject *self, PyObject *args)
         return NULL;
     }
 
-    return PyLong_FromLong((long) ((n & A_COLOR) >> 8));
+    return PyLong_FromLong(attr_to_color_pair(n));
 }
 
 static PyObject *
@@ -3120,7 +3132,7 @@ PyCurses_ConvertToWchar_t(PyObject *obj,
         wchar_t buffer[2];
         if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
             PyErr_Format(PyExc_TypeError,
-                         "expect bytes or str of length 1, or int, "
+                         "expect str of length 1 or int, "
                          "got a str of length %zi",
                          PyUnicode_GET_LENGTH(obj));
             return 0;
@@ -3147,7 +3159,7 @@ PyCurses_ConvertToWchar_t(PyObject *obj,
     }
     else {
         PyErr_Format(PyExc_TypeError,
-                     "expect bytes or str of length 1, or int, got %s",
+                     "expect str of length 1 or int, got %s",
                      Py_TYPE(obj)->tp_name);
         return 0;
     }
index 9405b4610dfcdb037ea4ca8595c38100ceeef7c1..42caf08262028b8566efad5a6adbaff38b4103c2 100644 (file)
@@ -20,6 +20,8 @@
 #include "datetime.h"
 #undef Py_BUILD_CORE
 
+#define PyTimezone_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeZoneType)
+
 /*[clinic input]
 module datetime
 class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType"
@@ -1085,7 +1087,9 @@ new_timezone(PyObject *offset, PyObject *name)
         Py_INCREF(PyDateTime_TimeZone_UTC);
         return PyDateTime_TimeZone_UTC;
     }
-    if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
+    if ((GET_TD_DAYS(offset) == -1 &&
+            GET_TD_SECONDS(offset) == 0 &&
+            GET_TD_MICROSECONDS(offset) < 1) ||
         GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
         PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
                      " strictly between -timedelta(hours=24) and"
@@ -1155,7 +1159,9 @@ call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg)
     if (offset == Py_None || offset == NULL)
         return offset;
     if (PyDelta_Check(offset)) {
-        if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) ||
+        if ((GET_TD_DAYS(offset) == -1 &&
+                GET_TD_SECONDS(offset) == 0 &&
+                GET_TD_MICROSECONDS(offset) < 1) ||
             GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) {
             Py_DECREF(offset);
             PyErr_Format(PyExc_ValueError, "offset must be a timedelta"
@@ -3644,11 +3650,8 @@ 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 (!PyTimezone_Check(other)) {
+        Py_RETURN_NOTIMPLEMENTED;
     }
     return delta_richcompare(self->offset, other->offset, op);
 }
@@ -3979,7 +3982,7 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
                 return NULL;
             }
             if (PyUnicode_GET_LENGTH(state) == _PyDateTime_TIME_DATASIZE &&
-                (0x7F & PyUnicode_READ_CHAR(state, 2)) < 24)
+                (0x7F & PyUnicode_READ_CHAR(state, 0)) < 24)
             {
                 state = PyUnicode_AsLatin1String(state);
                 if (state == NULL) {
@@ -6386,6 +6389,9 @@ PyInit__datetime(void)
     PyDateTime_TimeZone_UTC = x;
     CAPI.TimeZone_UTC = PyDateTime_TimeZone_UTC;
 
+    /* bpo-37642: These attributes are rounded to the nearest minute for backwards
+     * compatibility, even though the constructor will accept a wider range of
+     * values. This may change in the future.*/
     delta = new_delta(-1, 60, 0, 1); /* -23:59 */
     if (delta == NULL)
         return NULL;
index b69f16c61a506b775dbc959abf1d89dd1393191a..b13ade6049614825b51a8afe2f84bbd76175a323 100644 (file)
@@ -1073,7 +1073,7 @@ PyInit__hashlib(void)
 {
     PyObject *m, *openssl_md_meth_names;
 
-#ifndef OPENSSL_VERSION_1_1
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
     /* Load all digest algorithms and initialize cpuid */
     OPENSSL_add_all_algorithms_noconf();
     ERR_load_crypto_strings();
index f93c6c668e5d0486dc8dcf9157afecddac6a13ee..ec370897495083c9d75524d965cc0328623f435b 100644 (file)
@@ -881,9 +881,6 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length)
     PyObject *result;
     lzma_stream *lzs = &d->lzs;
 
-    if (lzs->avail_in == 0)
-        return PyBytes_FromStringAndSize(NULL, 0);
-
     if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE)
         result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
     else
@@ -900,7 +897,10 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length)
         Py_BEGIN_ALLOW_THREADS
         lzret = lzma_code(lzs, LZMA_RUN);
         data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result);
+        if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0)
+            lzret = LZMA_OK; /* That wasn't a real error */
         Py_END_ALLOW_THREADS
+
         if (catch_lzma_error(lzret))
             goto error;
         if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK)
@@ -908,15 +908,19 @@ decompress_buf(Decompressor *d, Py_ssize_t max_length)
         if (lzret == LZMA_STREAM_END) {
             d->eof = 1;
             break;
-        } else if (lzs->avail_in == 0) {
-            break;
         } else if (lzs->avail_out == 0) {
+            /* Need to check lzs->avail_out before lzs->avail_in.
+               Maybe lzs's internal state still have a few bytes
+               can be output, grow the output buffer and continue
+               if max_lengh < 0. */
             if (data_size == max_length)
                 break;
             if (grow_buffer(&result, max_length) == -1)
                 goto error;
             lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size;
             lzs->avail_out = PyBytes_GET_SIZE(result) - data_size;
+        } else if (lzs->avail_in == 0) {
+            break;
         }
     }
     if (data_size != PyBytes_GET_SIZE(result))
@@ -999,7 +1003,19 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
     }
     else if (lzs->avail_in == 0) {
         lzs->next_in = NULL;
-        d->needs_input = 1;
+
+        if (lzs->avail_out == 0) {
+            /* (avail_in==0 && avail_out==0)
+               Maybe lzs's internal state still have a few bytes can
+               be output, try to output them next time. */
+            d->needs_input = 0;
+
+            /* if max_length < 0, lzs->avail_out always > 0 */
+            assert(max_length >= 0);
+        } else {
+            /* Input buffer exhausted, output buffer has space. */
+            d->needs_input = 1;
+        }
     }
     else {
         d->needs_input = 0;
index 9a6207b519fafc514e42bd462b534c5ed4bc9129..dd45772595bc9d6f548b2459dbe798c06e91efd3 100644 (file)
@@ -1999,7 +1999,7 @@ save_long(PicklerObject *self, PyObject *obj)
         /* How many bytes do we need?  There are nbits >> 3 full
          * bytes of data, and nbits & 7 leftover bits.  If there
          * are any leftover bits, then we clearly need another
-         * byte.  Wnat's not so obvious is that we *probably*
+         * byte.  What's not so obvious is that we *probably*
          * need another byte even if there aren't any leftovers:
          * the most-significant bit of the most-significant byte
          * acts like a sign bit, and it's usually got a sense
index 122bee05f57096f0ffd2551fde022095db4ebd66..7c85ae22f94343f46c33478fd51fad1a57dc253d 100644 (file)
@@ -76,16 +76,38 @@ PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
    return item;
 }
 
+static int
+equal_ignore_case(PyObject *left, PyObject *right)
+{
+    int eq = PyObject_RichCompareBool(left, right, Py_EQ);
+    if (eq) { /* equal or error */
+        return eq;
+    }
+    if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) {
+        return 0;
+    }
+    if (!PyUnicode_IS_ASCII(left) || !PyUnicode_IS_ASCII(right)) {
+        return 0;
+    }
+
+    Py_ssize_t len = PyUnicode_GET_LENGTH(left);
+    if (PyUnicode_GET_LENGTH(right) != len) {
+        return 0;
+    }
+    const Py_UCS1 *p1 = PyUnicode_1BYTE_DATA(left);
+    const Py_UCS1 *p2 = PyUnicode_1BYTE_DATA(right);
+    for (; len; len--, p1++, p2++) {
+        if (Py_TOLOWER(*p1) != Py_TOLOWER(*p2)) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
 PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
 {
     Py_ssize_t _idx;
-    const char *key;
     Py_ssize_t nitems, i;
-    const char *compare_key;
-
-    const char *p1;
-    const char *p2;
-
     PyObject* item;
 
     if (PyLong_Check(idx)) {
@@ -98,44 +120,22 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx)
         Py_XINCREF(item);
         return item;
     } else if (PyUnicode_Check(idx)) {
-        key = PyUnicode_AsUTF8(idx);
-        if (key == NULL)
-            return NULL;
-
         nitems = PyTuple_Size(self->description);
 
         for (i = 0; i < nitems; i++) {
             PyObject *obj;
             obj = PyTuple_GET_ITEM(self->description, i);
             obj = PyTuple_GET_ITEM(obj, 0);
-            compare_key = PyUnicode_AsUTF8(obj);
-            if (!compare_key) {
+            int eq = equal_ignore_case(idx, obj);
+            if (eq < 0) {
                 return NULL;
             }
-
-            p1 = key;
-            p2 = compare_key;
-
-            while (1) {
-                if ((*p1 == (char)0) || (*p2 == (char)0)) {
-                    break;
-                }
-
-                if ((*p1 | 0x20) != (*p2 | 0x20)) {
-                    break;
-                }
-
-                p1++;
-                p2++;
-            }
-
-            if ((*p1 == (char)0) && (*p2 == (char)0)) {
+            if (eq) {
                 /* found item */
                 item = PyTuple_GetItem(self->data, i);
                 Py_INCREF(item);
                 return item;
             }
-
         }
 
         PyErr_SetString(PyExc_IndexError, "No item with that key");
@@ -197,14 +197,16 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
     if (opid != Py_EQ && opid != Py_NE)
         Py_RETURN_NOTIMPLEMENTED;
 
-    if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
+    if (PyObject_TypeCheck(_other, &pysqlite_RowType)) {
         pysqlite_Row *other = (pysqlite_Row *)_other;
-        PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
-        if ((opid == Py_EQ && res == Py_True)
-            || (opid == Py_NE && res == Py_False)) {
-            Py_DECREF(res);
+        int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
+        if (eq < 0) {
+            return NULL;
+        }
+        if (eq) {
             return PyObject_RichCompare(self->data, other->data, opid);
         }
+        return PyBool_FromLong(opid != Py_EQ);
     }
     Py_RETURN_NOTIMPLEMENTED;
 }
index e8955eedfa53ad569222ac8e97f8025fb3a1f8c5..a94dbbaec8493539684e37adb17b183401ab9211 100644 (file)
@@ -1789,7 +1789,7 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path)
         goto fail0;
     }
 
-    x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);
+    x = PEM_read_bio_X509(cert, NULL, NULL, NULL);
     if (x == NULL) {
         PyErr_SetString(PySSLErrorObject,
                         "Error decoding PEM-encoded file");
@@ -5384,7 +5384,7 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags)
         }
         return PyErr_SetFromWindowsErr(error);
     }
-    retval = PySet_New(NULL);
+    retval = PyFrozenSet_New(NULL);
     if (retval == NULL) {
         goto error;
     }
@@ -5448,6 +5448,7 @@ ssl_collect_certificates(const char *store_name)
             if (result) {
                 ++storesAdded;
             }
+            CertCloseStore(hSystemStore, 0);  /* flag must be 0 */
         }
     }
     if (storesAdded == 0) {
@@ -5458,20 +5459,6 @@ ssl_collect_certificates(const char *store_name)
     return hCollectionStore;
 }
 
-/* code from Objects/listobject.c */
-
-static int
-list_contains(PyListObject *a, PyObject *el)
-{
-    Py_ssize_t i;
-    int cmp;
-
-    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
-        cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
-                                           Py_EQ);
-    return cmp;
-}
-
 /*[clinic input]
 _ssl.enum_certificates
     store_name: str
@@ -5494,7 +5481,7 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name)
     PyObject *keyusage = NULL, *cert = NULL, *enc = NULL, *tup = NULL;
     PyObject *result = NULL;
 
-    result = PyList_New(0);
+    result = PySet_New(NULL);
     if (result == NULL) {
         return NULL;
     }
@@ -5534,11 +5521,10 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name)
         enc = NULL;
         PyTuple_SET_ITEM(tup, 2, keyusage);
         keyusage = NULL;
-        if (!list_contains((PyListObject*)result, tup)) {
-            if (PyList_Append(result, tup) < 0) {
-                Py_CLEAR(result);
-                break;
-            }
+        if (PySet_Add(result, tup) == -1) {
+            Py_CLEAR(result);
+            Py_CLEAR(tup);
+            break;
         }
         Py_CLEAR(tup);
     }
@@ -5562,7 +5548,14 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name)
         return PyErr_SetFromWindowsErr(GetLastError());
     }
 
-    return result;
+    /* convert set to list */
+    if (result == NULL) {
+        return NULL;
+    } else {
+        PyObject *lst = PySequence_List(result);
+        Py_DECREF(result);
+        return lst;
+    }
 }
 
 /*[clinic input]
@@ -5586,7 +5579,7 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name)
     PyObject *crl = NULL, *enc = NULL, *tup = NULL;
     PyObject *result = NULL;
 
-    result = PyList_New(0);
+    result = PySet_New(NULL);
     if (result == NULL) {
         return NULL;
     }
@@ -5616,11 +5609,10 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name)
         PyTuple_SET_ITEM(tup, 1, enc);
         enc = NULL;
 
-        if (!list_contains((PyListObject*)result, tup)) {
-            if (PyList_Append(result, tup) < 0) {
-                Py_CLEAR(result);
-                break;
-            }
+        if (PySet_Add(result, tup) == -1) {
+            Py_CLEAR(result);
+            Py_CLEAR(tup);
+            break;
         }
         Py_CLEAR(tup);
     }
@@ -5642,7 +5634,14 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name)
         Py_XDECREF(result);
         return PyErr_SetFromWindowsErr(GetLastError());
     }
-    return result;
+    /* convert set to list */
+    if (result == NULL) {
+        return NULL;
+    } else {
+        PyObject *lst = PySequence_List(result);
+        Py_DECREF(result);
+        return lst;
+    }
 }
 
 #endif /* _MSC_VER */
index 5776df7d765db96dd6bb338e6fe096b562a813f1..c6dfc2f01dc069bfe032599ca32a550cb983b27d 100644 (file)
@@ -624,6 +624,14 @@ bad_traverse(PyObject *self, visitproc visit, void *arg) {
     testmultiphase_state *m_state;
 
     m_state = PyModule_GetState(self);
+
+    /* The following assertion mimics any traversal function that doesn't correctly handle
+     * the case during module creation where the module state hasn't been created yet.
+     *
+     * The check that it is used to test only runs in debug mode, so it is OK that the
+     * assert() will get compiled out in fully optimised release builds.
+     */
+    assert(m_state != NULL);
     Py_VISIT(m_state->integer);
     return 0;
 }
index 2f59fd92906537bdeebdae27a5f7d033f95c45b8..63b1d1b4482efa86406a54dd421e59f04f8c725f 100644 (file)
 */
 
 /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+    /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+    /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+    /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+    /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+    /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+    /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+    /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+    /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+    /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+    /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+    /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+    /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+    /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+    /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+    /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+    /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+    /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
index c050f1d918cef04b8b28f3aeea06e43f38a538c4..6c8eb1fda4a30c3ea1bc4893f4865d79f74325f1 100644 (file)
 #ifndef Expat_INCLUDED
 #define Expat_INCLUDED 1
 
-#ifdef __VMS
-/*      0        1         2         3      0        1         2         3
-        1234567890123456789012345678901     1234567890123456789012345678901 */
-#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
-#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler
-#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler
-#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg
-#endif
-
 #include <stdlib.h>
 #include "expat_external.h"
 
@@ -53,8 +44,8 @@ struct XML_ParserStruct;
 typedef struct XML_ParserStruct *XML_Parser;
 
 typedef unsigned char XML_Bool;
-#define XML_TRUE   ((XML_Bool) 1)
-#define XML_FALSE  ((XML_Bool) 0)
+#define XML_TRUE ((XML_Bool)1)
+#define XML_FALSE ((XML_Bool)0)
 
 /* The XML_Status enum gives the possible return values for several
    API functions.  The preprocessor #defines are included so this
@@ -164,25 +155,23 @@ enum XML_Content_Quant {
 typedef struct XML_cp XML_Content;
 
 struct XML_cp {
-  enum XML_Content_Type         type;
-  enum XML_Content_Quant        quant;
-  XML_Char *                    name;
-  unsigned int                  numchildren;
-  XML_Content *                 children;
+  enum XML_Content_Type type;
+  enum XML_Content_Quant quant;
+  XML_Char *name;
+  unsigned int numchildren;
+  XML_Content *children;
 };
 
-
 /* This is called for an element declaration. See above for
    description of the model argument. It's the caller's responsibility
    to free model when finished with it.
 */
-typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
-                                                const XML_Char *name,
-                                                XML_Content *model);
+typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData,
+                                              const XML_Char *name,
+                                              XML_Content *model);
 
 XMLPARSEAPI(void)
-XML_SetElementDeclHandler(XML_Parser parser,
-                          XML_ElementDeclHandler eldecl);
+XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl);
 
 /* The Attlist declaration handler is called for *each* attribute. So
    a single Attlist declaration with multiple attributes declared will
@@ -192,17 +181,12 @@ XML_SetElementDeclHandler(XML_Parser parser,
    value will be NULL in the case of "#REQUIRED". If "isrequired" is
    true and default is non-NULL, then this is a "#FIXED" default.
 */
-typedef void (XMLCALL *XML_AttlistDeclHandler) (
-                                    void            *userData,
-                                    const XML_Char  *elname,
-                                    const XML_Char  *attname,
-                                    const XML_Char  *att_type,
-                                    const XML_Char  *dflt,
-                                    int              isrequired);
+typedef void(XMLCALL *XML_AttlistDeclHandler)(
+    void *userData, const XML_Char *elname, const XML_Char *attname,
+    const XML_Char *att_type, const XML_Char *dflt, int isrequired);
 
 XMLPARSEAPI(void)
-XML_SetAttlistDeclHandler(XML_Parser parser,
-                          XML_AttlistDeclHandler attdecl);
+XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl);
 
 /* The XML declaration handler is called for *both* XML declarations
    and text declarations. The way to distinguish is that the version
@@ -212,15 +196,13 @@ XML_SetAttlistDeclHandler(XML_Parser parser,
    was no standalone parameter in the declaration, that it was given
    as no, or that it was given as yes.
 */
-typedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData,
-                                            const XML_Char *version,
-                                            const XML_Char *encoding,
-                                            int             standalone);
+typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData,
+                                          const XML_Char *version,
+                                          const XML_Char *encoding,
+                                          int standalone);
 
 XMLPARSEAPI(void)
-XML_SetXmlDeclHandler(XML_Parser parser,
-                      XML_XmlDeclHandler xmldecl);
-
+XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl);
 
 typedef struct {
   void *(*malloc_fcn)(size_t size);
@@ -248,7 +230,6 @@ XML_ParserCreate(const XML_Char *encoding);
 XMLPARSEAPI(XML_Parser)
 XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
 
-
 /* Constructs a new parser using the memory management suite referred to
    by memsuite. If memsuite is NULL, then use the standard library memory
    suite. If namespaceSeparator is non-NULL it creates a parser with
@@ -278,31 +259,27 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
 /* atts is array of name/value pairs, terminated by 0;
    names and values are 0 terminated.
 */
-typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
-                                                 const XML_Char *name,
-                                                 const XML_Char **atts);
-
-typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
-                                               const XML_Char *name);
+typedef void(XMLCALL *XML_StartElementHandler)(void *userData,
+                                               const XML_Char *name,
+                                               const XML_Char **atts);
 
+typedef void(XMLCALL *XML_EndElementHandler)(void *userData,
+                                             const XML_Char *name);
 
 /* s is not 0 terminated. */
-typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
-                                                  const XML_Char *s,
-                                                  int len);
+typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData,
+                                                const XML_Char *s, int len);
 
 /* target and data are 0 terminated */
-typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
-                                                void *userData,
-                                                const XML_Char *target,
-                                                const XML_Char *data);
+typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData,
+                                                        const XML_Char *target,
+                                                        const XML_Char *data);
 
 /* data is 0 terminated */
-typedef void (XMLCALL *XML_CommentHandler) (void *userData,
-                                            const XML_Char *data);
+typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data);
 
-typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
-typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData);
+typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData);
 
 /* This is called for any characters in the XML document for which
    there is no applicable handler.  This includes both characters that
@@ -317,25 +294,23 @@ typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
    default handler: for example, a comment might be split between
    multiple calls.
 */
-typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
-                                            const XML_Char *s,
-                                            int len);
+typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s,
+                                          int len);
 
 /* This is called for the start of the DOCTYPE declaration, before
    any DTD or internal subset is parsed.
 */
-typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
-                                            void *userData,
-                                            const XML_Char *doctypeName,
-                                            const XML_Char *sysid,
-                                            const XML_Char *pubid,
-                                            int has_internal_subset);
+typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData,
+                                                   const XML_Char *doctypeName,
+                                                   const XML_Char *sysid,
+                                                   const XML_Char *pubid,
+                                                   int has_internal_subset);
 
 /* This is called for the start of the DOCTYPE declaration when the
    closing > is encountered, but after processing any external
    subset.
 */
-typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
 
 /* This is called for entity declarations. The is_parameter_entity
    argument will be non-zero if the entity is a parameter entity, zero
@@ -355,20 +330,14 @@ typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
    Note that is_parameter_entity can't be changed to XML_Bool, since
    that would break binary compatibility.
 */
-typedef void (XMLCALL *XML_EntityDeclHandler) (
-                              void *userData,
-                              const XML_Char *entityName,
-                              int is_parameter_entity,
-                              const XML_Char *value,
-                              int value_length,
-                              const XML_Char *base,
-                              const XML_Char *systemId,
-                              const XML_Char *publicId,
-                              const XML_Char *notationName);
+typedef void(XMLCALL *XML_EntityDeclHandler)(
+    void *userData, const XML_Char *entityName, int is_parameter_entity,
+    const XML_Char *value, int value_length, const XML_Char *base,
+    const XML_Char *systemId, const XML_Char *publicId,
+    const XML_Char *notationName);
 
 XMLPARSEAPI(void)
-XML_SetEntityDeclHandler(XML_Parser parser,
-                         XML_EntityDeclHandler handler);
+XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler);
 
 /* OBSOLETE -- OBSOLETE -- OBSOLETE
    This handler has been superseded by the EntityDeclHandler above.
@@ -379,24 +348,20 @@ XML_SetEntityDeclHandler(XML_Parser parser,
    entityName, systemId and notationName arguments will never be
    NULL. The other arguments may be.
 */
-typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
-                                    void *userData,
-                                    const XML_Char *entityName,
-                                    const XML_Char *base,
-                                    const XML_Char *systemId,
-                                    const XML_Char *publicId,
-                                    const XML_Char *notationName);
+typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)(
+    void *userData, const XML_Char *entityName, const XML_Char *base,
+    const XML_Char *systemId, const XML_Char *publicId,
+    const XML_Char *notationName);
 
 /* This is called for a declaration of notation.  The base argument is
    whatever was set by XML_SetBase. The notationName will never be
    NULL.  The other arguments can be.
 */
-typedef void (XMLCALL *XML_NotationDeclHandler) (
-                                    void *userData,
-                                    const XML_Char *notationName,
-                                    const XML_Char *base,
-                                    const XML_Char *systemId,
-                                    const XML_Char *publicId);
+typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData,
+                                               const XML_Char *notationName,
+                                               const XML_Char *base,
+                                               const XML_Char *systemId,
+                                               const XML_Char *publicId);
 
 /* When namespace processing is enabled, these are called once for
    each namespace declaration. The call to the start and end element
@@ -404,14 +369,12 @@ typedef void (XMLCALL *XML_NotationDeclHandler) (
    declaration handlers. For an xmlns attribute, prefix will be
    NULL.  For an xmlns="" attribute, uri will be NULL.
 */
-typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
-                                    void *userData,
-                                    const XML_Char *prefix,
-                                    const XML_Char *uri);
+typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData,
+                                                     const XML_Char *prefix,
+                                                     const XML_Char *uri);
 
-typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
-                                    void *userData,
-                                    const XML_Char *prefix);
+typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData,
+                                                   const XML_Char *prefix);
 
 /* This is called if the document is not standalone, that is, it has an
    external subset or a reference to a parameter entity, but does not
@@ -422,7 +385,7 @@ typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
    conditions above this handler will only be called if the referenced
    entity was actually read.
 */
-typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData);
 
 /* This is called for a reference to an external parsed general
    entity.  The referenced entity is not automatically parsed.  The
@@ -458,12 +421,11 @@ typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
    Note that unlike other handlers the first argument is the parser,
    not userData.
 */
-typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
-                                    XML_Parser parser,
-                                    const XML_Char *context,
-                                    const XML_Char *base,
-                                    const XML_Char *systemId,
-                                    const XML_Char *publicId);
+typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser,
+                                                   const XML_Char *context,
+                                                   const XML_Char *base,
+                                                   const XML_Char *systemId,
+                                                   const XML_Char *publicId);
 
 /* This is called in two situations:
    1) An entity reference is encountered for which no declaration
@@ -475,10 +437,9 @@ typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
          the event would be out of sync with the reporting of the
          declarations or attribute values
 */
-typedef void (XMLCALL *XML_SkippedEntityHandler) (
-                                    void *userData,
-                                    const XML_Char *entityName,
-                                    int is_parameter_entity);
+typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData,
+                                                const XML_Char *entityName,
+                                                int is_parameter_entity);
 
 /* This structure is filled in by the XML_UnknownEncodingHandler to
    provide information to the parser about encodings that are unknown
@@ -535,8 +496,8 @@ typedef void (XMLCALL *XML_SkippedEntityHandler) (
 typedef struct {
   int map[256];
   void *data;
-  int (XMLCALL *convert)(void *data, const char *s);
-  void (XMLCALL *release)(void *data);
+  int(XMLCALL *convert)(void *data, const char *s);
+  void(XMLCALL *release)(void *data);
 } XML_Encoding;
 
 /* This is called for an encoding that is unknown to the parser.
@@ -554,23 +515,19 @@ typedef struct {
    If info does not describe a suitable encoding, then the parser will
    return an XML_UNKNOWN_ENCODING error.
 */
-typedef int (XMLCALL *XML_UnknownEncodingHandler) (
-                                    void *encodingHandlerData,
-                                    const XML_Char *name,
-                                    XML_Encoding *info);
+typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData,
+                                                 const XML_Char *name,
+                                                 XML_Encoding *info);
 
 XMLPARSEAPI(void)
-XML_SetElementHandler(XML_Parser parser,
-                      XML_StartElementHandler start,
+XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
                       XML_EndElementHandler end);
 
 XMLPARSEAPI(void)
-XML_SetStartElementHandler(XML_Parser parser,
-                           XML_StartElementHandler handler);
+XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler);
 
 XMLPARSEAPI(void)
-XML_SetEndElementHandler(XML_Parser parser,
-                         XML_EndElementHandler handler);
+XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler);
 
 XMLPARSEAPI(void)
 XML_SetCharacterDataHandler(XML_Parser parser,
@@ -580,8 +537,7 @@ XMLPARSEAPI(void)
 XML_SetProcessingInstructionHandler(XML_Parser parser,
                                     XML_ProcessingInstructionHandler handler);
 XMLPARSEAPI(void)
-XML_SetCommentHandler(XML_Parser parser,
-                      XML_CommentHandler handler);
+XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler);
 
 XMLPARSEAPI(void)
 XML_SetCdataSectionHandler(XML_Parser parser,
@@ -601,20 +557,17 @@ XML_SetEndCdataSectionHandler(XML_Parser parser,
    default handler, or to the skipped entity handler, if one is set.
 */
 XMLPARSEAPI(void)
-XML_SetDefaultHandler(XML_Parser parser,
-                      XML_DefaultHandler handler);
+XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler);
 
 /* This sets the default handler but does not inhibit expansion of
    internal entities.  The entity reference will not be passed to the
    default handler.
 */
 XMLPARSEAPI(void)
-XML_SetDefaultHandlerExpand(XML_Parser parser,
-                            XML_DefaultHandler handler);
+XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler);
 
 XMLPARSEAPI(void)
-XML_SetDoctypeDeclHandler(XML_Parser parser,
-                          XML_StartDoctypeDeclHandler start,
+XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
                           XML_EndDoctypeDeclHandler end);
 
 XMLPARSEAPI(void)
@@ -622,16 +575,14 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser,
                                XML_StartDoctypeDeclHandler start);
 
 XMLPARSEAPI(void)
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
-                             XML_EndDoctypeDeclHandler end);
+XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end);
 
 XMLPARSEAPI(void)
 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
                                  XML_UnparsedEntityDeclHandler handler);
 
 XMLPARSEAPI(void)
-XML_SetNotationDeclHandler(XML_Parser parser,
-                           XML_NotationDeclHandler handler);
+XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler);
 
 XMLPARSEAPI(void)
 XML_SetNamespaceDeclHandler(XML_Parser parser,
@@ -659,8 +610,7 @@ XML_SetExternalEntityRefHandler(XML_Parser parser,
    instead of the parser object.
 */
 XMLPARSEAPI(void)
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
-                                   void *arg);
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg);
 
 XMLPARSEAPI(void)
 XML_SetSkippedEntityHandler(XML_Parser parser,
@@ -740,7 +690,6 @@ XML_UseParserAsHandlerArg(XML_Parser parser);
 XMLPARSEAPI(enum XML_Error)
 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
 
-
 /* Sets the base to be used for resolving relative URIs in system
    identifiers in declarations.  Resolving relative identifiers is
    left to the application: this value will be passed through as the
@@ -780,10 +729,10 @@ XML_GetIdAttributeIndex(XML_Parser parser);
    info->valueEnd - info->valueStart = 4 bytes.
 */
 typedef struct {
-  XML_Index  nameStart;  /* Offset to beginning of the attribute name. */
-  XML_Index  nameEnd;    /* Offset after the attribute name's last byte. */
-  XML_Index  valueStart; /* Offset to beginning of the attribute value. */
-  XML_Index  valueEnd;   /* Offset after the attribute value's last byte. */
+  XML_Index nameStart;  /* Offset to beginning of the attribute name. */
+  XML_Index nameEnd;    /* Offset after the attribute name's last byte. */
+  XML_Index valueStart; /* Offset to beginning of the attribute value. */
+  XML_Index valueEnd;   /* Offset after the attribute value's last byte. */
 } XML_AttrInfo;
 
 /* Returns an array of XML_AttrInfo structures for the attribute/value pairs
@@ -819,20 +768,20 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
    (resumable = 0) an already suspended parser. Some call-backs may
    still follow because they would otherwise get lost. Examples:
    - endElementHandler() for empty elements when stopped in
-     startElementHandler(), 
-   - endNameSpaceDeclHandler() when stopped in endElementHandler(), 
+     startElementHandler(),
+   - endNameSpaceDeclHandler() when stopped in endElementHandler(),
    and possibly others.
 
    Can be called from most handlers, including DTD related call-backs,
    except when parsing an external parameter entity and resumable != 0.
    Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
-   Possible error codes: 
+   Possible error codes:
    - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
    - XML_ERROR_FINISHED: when the parser has already finished.
    - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
 
-   When resumable != 0 (true) then parsing is suspended, that is, 
-   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. 
+   When resumable != 0 (true) then parsing is suspended, that is,
+   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
    Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
    return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
 
@@ -843,7 +792,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
    the externalEntityRefHandler() to call XML_StopParser() on the parent
    parser (recursively), if one wants to stop parsing altogether.
 
-   When suspended, parsing can be resumed by calling XML_ResumeParser(). 
+   When suspended, parsing can be resumed by calling XML_ResumeParser().
 */
 XMLPARSEAPI(enum XML_Status)
 XML_StopParser(XML_Parser parser, XML_Bool resumable);
@@ -851,7 +800,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable);
 /* Resumes parsing after it has been suspended with XML_StopParser().
    Must not be called from within a handler call-back. Returns same
    status codes as XML_Parse() or XML_ParseBuffer().
-   Additional error code XML_ERROR_NOT_SUSPENDED possible.   
+   Additional error code XML_ERROR_NOT_SUSPENDED possible.
 
    *Note*:
    This must be called on the most deeply nested child parser instance
@@ -863,12 +812,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable);
 XMLPARSEAPI(enum XML_Status)
 XML_ResumeParser(XML_Parser parser);
 
-enum XML_Parsing {
-  XML_INITIALIZED,
-  XML_PARSING,
-  XML_FINISHED,
-  XML_SUSPENDED
-};
+enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED };
 
 typedef struct {
   enum XML_Parsing parsing;
@@ -900,8 +844,7 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
    Otherwise returns a new XML_Parser object.
 */
 XMLPARSEAPI(XML_Parser)
-XML_ExternalEntityParserCreate(XML_Parser parser,
-                               const XML_Char *context,
+XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context,
                                const XML_Char *encoding);
 
 enum XML_ParamEntityParsing {
@@ -945,8 +888,7 @@ XML_SetParamEntityParsing(XML_Parser parser,
    Note: If parser == NULL, the function will do nothing and return 0.
 */
 XMLPARSEAPI(int)
-XML_SetHashSalt(XML_Parser parser,
-                unsigned long hash_salt);
+XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
 
 /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
    XML_GetErrorCode returns information about the error.
@@ -963,7 +905,7 @@ XML_GetErrorCode(XML_Parser parser);
    be within the relevant markup.  When called outside of the callback
    functions, the position indicated will be just past the last parse
    event (regardless of whether there was an associated callback).
-   
+
    They may also be called after returning from a call to XML_Parse
    or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
    the location is the location of the character at which the error
@@ -995,14 +937,12 @@ XML_GetCurrentByteCount(XML_Parser parser);
    the handler that makes the call.
 */
 XMLPARSEAPI(const char *)
-XML_GetInputContext(XML_Parser parser,
-                    int *offset,
-                    int *size);
+XML_GetInputContext(XML_Parser parser, int *offset, int *size);
 
 /* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
 #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
 
 /* Frees the content model passed to the element declaration handler */
 XMLPARSEAPI(void)
@@ -1062,21 +1002,20 @@ enum XML_FeatureEnum {
 };
 
 typedef struct {
-  enum XML_FeatureEnum  feature;
-  const XML_LChar       *name;
-  long int              value;
+  enum XML_FeatureEnum feature;
+  const XML_LChar *name;
+  long int value;
 } XML_Feature;
 
 XMLPARSEAPI(const XML_Feature *)
 XML_GetFeatureList(void);
 
-
 /* Expat follows the semantic versioning convention.
    See http://semver.org.
 */
 #define XML_MAJOR_VERSION 2
 #define XML_MINOR_VERSION 2
-#define XML_MICRO_VERSION 7
+#define XML_MICRO_VERSION 8
 
 #ifdef __cplusplus
 }
index fc63c2228d3e69c3c9ecd8b25d051091739e7431..f2b75dda8e27987444b24e831e232a61e7f6318e 100644 (file)
 
 /* External API definitions */
 
-#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
-# define XML_USE_MSC_EXTENSIONS 1
-#endif
-
 /* Expat tries very hard to make the API boundary very specifically
    defined.  There are two macros defined to control this boundary;
    each of these can be defined before including this header to
    compiled with the cdecl calling convention as the default since
    system headers may assume the cdecl convention.
 */
+
+/* Namespace external symbols to allow multiple libexpat version to
+   co-exist. */
+#include "pyexpatns.h"
+
 #ifndef XMLCALL
-# if defined(_MSC_VER)
-#  define XMLCALL __cdecl
-# elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
-#  define XMLCALL __attribute__((cdecl))
-# else
+#  if defined(_MSC_VER)
+#    define XMLCALL __cdecl
+#  elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
+#    define XMLCALL __attribute__((cdecl))
+#  else
 /* For any platform which uses this definition and supports more than
    one calling convention, we need to extend this definition to
    declare the convention used on that platform, if it's possible to
    pre-processor and how to specify the same calling convention as the
    platform's malloc() implementation.
 */
-#  define XMLCALL
-# endif
-#endif  /* not defined XMLCALL */
-
-/* Namespace external symbols to allow multiple libexpat version to
-   co-exist. */
-#include "pyexpatns.h"
-
+#    define XMLCALL
+#  endif
+#endif /* not defined XMLCALL */
 
-#if !defined(XML_STATIC) && !defined(XMLIMPORT)
-# ifndef XML_BUILDING_EXPAT
+#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
+#  ifndef XML_BUILDING_EXPAT
 /* using Expat from an application */
 
-#  ifdef XML_USE_MSC_EXTENSIONS
-#   define XMLIMPORT __declspec(dllimport)
-#  endif
+#    if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
+#      define XMLIMPORT __declspec(dllimport)
+#    endif
 
-# endif
-#endif  /* not defined XML_STATIC */
+#  endif
+#endif /* not defined XML_STATIC */
 
 #ifndef XML_ENABLE_VISIBILITY
-# define XML_ENABLE_VISIBILITY 0
+#  define XML_ENABLE_VISIBILITY 0
 #endif
 
-#if !defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
-# define XMLIMPORT __attribute__ ((visibility ("default")))
+#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
+#  define XMLIMPORT __attribute__((visibility("default")))
 #endif
 
 /* If we didn't define it above, define it away: */
 #ifndef XMLIMPORT
-# define XMLIMPORT
+#  define XMLIMPORT
 #endif
 
-#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
-# define XML_ATTR_MALLOC __attribute__((__malloc__))
+#if defined(__GNUC__)                                                          \
+    && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#  define XML_ATTR_MALLOC __attribute__((__malloc__))
 #else
-# define XML_ATTR_MALLOC
+#  define XML_ATTR_MALLOC
 #endif
 
-#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
-# define XML_ATTR_ALLOC_SIZE(x)  __attribute__((__alloc_size__(x)))
+#if defined(__GNUC__)                                                          \
+    && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#  define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
 #else
-# define XML_ATTR_ALLOC_SIZE(x)
+#  define XML_ATTR_ALLOC_SIZE(x)
 #endif
 
 #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
@@ -129,35 +127,30 @@ extern "C" {
 #endif
 
 #ifdef XML_UNICODE_WCHAR_T
-# ifndef XML_UNICODE
-#  define XML_UNICODE
-# endif
-# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
-#  error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
-# endif
+#  ifndef XML_UNICODE
+#    define XML_UNICODE
+#  endif
+#  if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+#    error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+#  endif
 #endif
 
-#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
-# ifdef XML_UNICODE_WCHAR_T
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+#  ifdef XML_UNICODE_WCHAR_T
 typedef wchar_t XML_Char;
 typedef wchar_t XML_LChar;
-# else
+#  else
 typedef unsigned short XML_Char;
 typedef char XML_LChar;
-# endif /* XML_UNICODE_WCHAR_T */
-#else                  /* Information is UTF-8 encoded. */
+#  endif /* XML_UNICODE_WCHAR_T */
+#else    /* Information is UTF-8 encoded. */
 typedef char XML_Char;
 typedef char XML_LChar;
-#endif /* XML_UNICODE */
+#endif   /* XML_UNICODE */
 
-#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */
-# if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
-typedef __int64 XML_Index; 
-typedef unsigned __int64 XML_Size;
-# else
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
 typedef long long XML_Index;
 typedef unsigned long long XML_Size;
-# endif
 #else
 typedef long XML_Index;
 typedef unsigned long XML_Size;
index ce4a4bf7edef533e5944fec5d932f374555cb89f..ea97cfcf678e06d3f6030892a8ee04acbb310d7e 100644 (file)
 
 /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
 /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+    /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+    /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+    /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+    /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+    /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+    /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+    /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+    /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+    /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+    /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+    /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+    /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+    /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+    /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+    /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+    /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+    /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
index dc4ef0c7e2588c2d79c68b6fd62e805f7fbff77a..60913dab762f8f06312259271a7c45b8cc4f51fe 100644 (file)
@@ -49,7 +49,7 @@
    USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
+#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__)
 /* We'll use this version by default only where we know it helps.
 
    regparm() generates warnings on Solaris boxes.   See SF bug #692878.
@@ -59,8 +59,8 @@
    #define FASTCALL __attribute__((stdcall, regparm(3)))
    and let's try this:
 */
-#define FASTCALL __attribute__((regparm(3)))
-#define PTRFASTCALL __attribute__((regparm(3)))
+#  define FASTCALL __attribute__((regparm(3)))
+#  define PTRFASTCALL __attribute__((regparm(3)))
 #endif
 
 /* Using __fastcall seems to have an unexpected negative effect under
 /* Make sure all of these are defined if they aren't already. */
 
 #ifndef FASTCALL
-#define FASTCALL
+#  define FASTCALL
 #endif
 
 #ifndef PTRCALL
-#define PTRCALL
+#  define PTRCALL
 #endif
 
 #ifndef PTRFASTCALL
-#define PTRFASTCALL
+#  define PTRFASTCALL
 #endif
 
 #ifndef XML_MIN_SIZE
-#if !defined(__cplusplus) && !defined(inline)
-#ifdef __GNUC__
-#define inline __inline
-#endif /* __GNUC__ */
-#endif
+#  if ! defined(__cplusplus) && ! defined(inline)
+#    ifdef __GNUC__
+#      define inline __inline
+#    endif /* __GNUC__ */
+#  endif
 #endif /* XML_MIN_SIZE */
 
 #ifdef __cplusplus
-#define inline inline
+#  define inline inline
 #else
-#ifndef inline
-#define inline
-#endif
+#  ifndef inline
+#    define inline
+#  endif
 #endif
 
 #ifndef UNUSED_P
-# ifdef __GNUC__
-#  define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
-# else
-#  define UNUSED_P(p) UNUSED_ ## p
-# endif
+#  define UNUSED_P(p) (void)p
 #endif
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-
 #ifdef XML_ENABLE_VISIBILITY
-#if XML_ENABLE_VISIBILITY
-__attribute__ ((visibility ("default")))
-#endif
+#  if XML_ENABLE_VISIBILITY
+__attribute__((visibility("default")))
+#  endif
 #endif
 void
-_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef);
-
+_INTERNAL_trim_to_complete_utf8_characters(const char *from,
+                                           const char **fromLimRef);
 
 #ifdef __cplusplus
 }
index 95dfa52b1fbebba89611157548985a8feab873a6..6f916041355a86ed3a6ce0ca09487a7c8bfa7ae6 100644 (file)
 */
 
 /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
-/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+    /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+    /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+    /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+    /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+    /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+    /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+    /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/Modules/expat/loadlibrary.c b/Modules/expat/loadlibrary.c
deleted file mode 100644 (file)
index 35fdf98..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2017, Expat development team
- *
- * All rights reserved.
- * Licensed under the MIT license:
- *
- * Permission to  use, copy,  modify, and distribute  this software  for any
- * purpose with  or without fee is  hereby granted, provided that  the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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 OF
- * THIRD PARTY RIGHTS. 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.
- *
- * Except as contained in this notice,  the name of a copyright holder shall
- * not be used in advertising or otherwise to promote the sale, use or other
- * dealings  in this  Software without  prior written  authorization of  the
- * copyright holder.
- *
- ***************************************************************************/
-
-#if defined(_WIN32)
-
-#include <windows.h>
-#include <tchar.h>
-
-
-HMODULE _Expat_LoadLibrary(LPCTSTR filename);
-
-
-#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
-#define LOAD_WITH_ALTERED_SEARCH_PATH  0x00000008
-#endif
-
-#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
-#define LOAD_LIBRARY_SEARCH_SYSTEM32   0x00000800
-#endif
-
-/* We use our own typedef here since some headers might lack these */
-typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
-
-/* See function definitions in winbase.h */
-#ifdef UNICODE
-#  ifdef _WIN32_WCE
-#    define LOADLIBARYEX  L"LoadLibraryExW"
-#  else
-#    define LOADLIBARYEX  "LoadLibraryExW"
-#  endif
-#else
-#  define LOADLIBARYEX    "LoadLibraryExA"
-#endif
-
-
-/*
- * _Expat_LoadLibrary()
- *
- * This is used to dynamically load DLLs using the most secure method available
- * for the version of Windows that we are running on.
- *
- * Parameters:
- *
- * filename  [in] - The filename or full path of the DLL to load. If only the
- *                  filename is passed then the DLL will be loaded from the
- *                  Windows system directory.
- *
- * Returns the handle of the module on success; otherwise NULL.
- */
-HMODULE _Expat_LoadLibrary(LPCTSTR filename)
-{
-  HMODULE hModule = NULL;
-  LOADLIBRARYEX_FN pLoadLibraryEx = NULL;
-
-  /* Get a handle to kernel32 so we can access it's functions at runtime */
-  HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
-  if(!hKernel32)
-    return NULL;  /* LCOV_EXCL_LINE */
-
-  /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
-     and above */
-  pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
-
-  /* Detect if there's already a path in the filename and load the library if
-     there is. Note: Both back slashes and forward slashes have been supported
-     since the earlier days of DOS at an API level although they are not
-     supported by command prompt */
-  if(_tcspbrk(filename, TEXT("\\/"))) {
-    /** !checksrc! disable BANNEDFUNC 1 **/
-    hModule = pLoadLibraryEx ?
-      pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
-      LoadLibrary(filename);
-  }
-  /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only
-     supported on Windows Vista, Windows Server 2008, Windows 7 and Windows
-     Server 2008 R2 with this patch or natively on Windows 8 and above */
-  else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) {
-    /* Load the DLL from the Windows system directory */
-    hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
-  }
-  else {
-    /* Attempt to get the Windows system path */
-    UINT systemdirlen = GetSystemDirectory(NULL, 0);
-    if(systemdirlen) {
-      /* Allocate space for the full DLL path (Room for the null terminator
-         is included in systemdirlen) */
-      size_t filenamelen = _tcslen(filename);
-      TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen));
-      if(path && GetSystemDirectory(path, systemdirlen)) {
-        /* Calculate the full DLL path */
-        _tcscpy(path + _tcslen(path), TEXT("\\"));
-        _tcscpy(path + _tcslen(path), filename);
-
-        /* Load the DLL from the Windows system directory */
-        /** !checksrc! disable BANNEDFUNC 1 **/
-        hModule = pLoadLibraryEx ?
-          pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
-          LoadLibrary(path);
-
-      }
-      free(path);
-    }
-  }
-
-  return hModule;
-}
-
-#else /* defined(_WIN32) */
-
-/* ISO C requires a translation unit to contain at least one declaration
-   [-Wempty-translation-unit] */
-typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY;
-
-#endif /* defined(_WIN32) */
index bfa2bd38cd95cddbaf8a25f54826d8d0a58e10ee..3681df348eebd66dabf75a77039c8c4a885c3a46 100644 (file)
 */
 
 static const unsigned namingBitmap[] = {
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
-0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
-0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
-0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
-0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
-0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
-0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
-0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
-0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
-0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
-0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
-0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
-0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
-0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
-0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
-0x40000000, 0xF580C900, 0x00000007, 0x02010800,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
-0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
-0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
-0x00000000, 0x00004C40, 0x00000000, 0x00000000,
-0x00000007, 0x00000000, 0x00000000, 0x00000000,
-0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
-0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
-0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
-0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
-0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
-0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
-0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
-0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
-0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
-0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
-0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
-0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
-0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
-0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
-0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
-0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000,
+    0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+    0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+    0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF,
+    0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+    0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE,
+    0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+    0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF,
+    0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+    0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF,
+    0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+    0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF,
+    0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF,
+    0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+    0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000,
+    0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+    0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40,
+    0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000,
+    0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE,
+    0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F,
+    0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+    0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000,
+    0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+    0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB,
+    0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+    0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000,
+    0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+    0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF,
+    0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+    0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF,
+    0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+    0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718,
+    0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+    0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF,
+    0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE,
+    0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+    0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+    0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE,
+    0xFFFFFFFF, 0x77FFFFFF,
 };
 static const unsigned char nmstrtPages[] = {
-0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
-0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B,
+    0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
 };
 static const unsigned char namePages[] = {
-0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
-0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21,
+    0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
 };
index 4d6786d7839a2c1a99989930afec3dbe8789a2bc..bfee65a332f1bfeca053116925099ba7064f28d4 100644 (file)
  * --------------------------------------------------------------------------
  * HISTORY:
  *
+ * 2019-08-03  (Sebastian Pipping)
+ *   - Mark part of sip24_valid as to be excluded from clang-format
+ *   - Re-format code using clang-format 9
+ *
  * 2018-07-08  (Anton Maklakov)
  *   - Add "fall through" markers for GCC's -Wimplicit-fallthrough
  *
 #include <stddef.h> /* size_t */
 
 #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
-  /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */
-  typedef unsigned __int8   uint8_t;
-  typedef unsigned __int32 uint32_t;
-  typedef unsigned __int64 uint64_t;
+/* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
 #else
- #include <stdint.h> /* uint64_t uint32_t uint8_t */
+#  include <stdint.h> /* uint64_t uint32_t uint8_t */
 #endif
 
-
 /*
  * Workaround to not require a C++11 compiler for using ULL suffix
  * if this code is included and compiled as C++; related GCC warning is:
  * warning: use of C++11 long long integer constant [-Wlong-long]
  */
-#define _SIP_ULL(high, low)  (((uint64_t)high << 32) | low)
-
-
-#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))
+#define _SIP_ULL(high, low) (((uint64_t)high << 32) | low)
 
-#define SIP_U32TO8_LE(p, v) \
-       (p)[0] = (uint8_t)((v) >>  0); (p)[1] = (uint8_t)((v) >>  8); \
-       (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);
+#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
 
-#define SIP_U64TO8_LE(p, v) \
-       SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >>  0)); \
-       SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
+#define SIP_U32TO8_LE(p, v)                                                    \
+  (p)[0] = (uint8_t)((v) >> 0);                                                \
+  (p)[1] = (uint8_t)((v) >> 8);                                                \
+  (p)[2] = (uint8_t)((v) >> 16);                                               \
+  (p)[3] = (uint8_t)((v) >> 24);
 
-#define SIP_U8TO64_LE(p) \
-       (((uint64_t)((p)[0]) <<  0) | \
-        ((uint64_t)((p)[1]) <<  8) | \
-        ((uint64_t)((p)[2]) << 16) | \
-        ((uint64_t)((p)[3]) << 24) | \
-        ((uint64_t)((p)[4]) << 32) | \
-        ((uint64_t)((p)[5]) << 40) | \
-        ((uint64_t)((p)[6]) << 48) | \
-        ((uint64_t)((p)[7]) << 56))
+#define SIP_U64TO8_LE(p, v)                                                    \
+  SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0));                                \
+  SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
 
+#define SIP_U8TO64_LE(p)                                                       \
+  (((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8)                       \
+   | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24)                   \
+   | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40)                   \
+   | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
 
-#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }
+#define SIPHASH_INITIALIZER                                                    \
+  { 0, 0, 0, 0, {0}, 0, 0 }
 
 struct siphash {
-       uint64_t v0, v1, v2, v3;
+  uint64_t v0, v1, v2, v3;
 
-       unsigned char buf[8], *p;
-       uint64_t c;
+  unsigned char buf[8], *p;
+  uint64_t c;
 }; /* struct siphash */
 
-
 #define SIP_KEYLEN 16
 
 struct sipkey {
-       uint64_t k[2];
+  uint64_t k[2];
 }; /* struct sipkey */
 
-#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))
+#define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k))
 
-static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {
-       key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
-       key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
-       return key;
+static struct sipkey *
+sip_tokey(struct sipkey *key, const void *src) {
+  key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
+  key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
+  return key;
 } /* sip_tokey() */
 
-
 #ifdef SIPHASH_TOBIN
 
-#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))
+#  define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v))
 
-static void *sip_tobin(void *dst, uint64_t u64) {
-       SIP_U64TO8_LE((unsigned char *)dst, u64);
-       return dst;
+static void *
+sip_tobin(void *dst, uint64_t u64) {
+  SIP_U64TO8_LE((unsigned char *)dst, u64);
+  return dst;
 } /* sip_tobin() */
 
-#endif  /* SIPHASH_TOBIN */
-
+#endif /* SIPHASH_TOBIN */
 
-static void sip_round(struct siphash *H, const int rounds) {
-       int i;
+static void
+sip_round(struct siphash *H, const int rounds) {
+  int i;
 
-       for (i = 0; i < rounds; i++) {
-               H->v0 += H->v1;
-               H->v1 = SIP_ROTL(H->v1, 13);
-               H->v1 ^= H->v0;
-               H->v0 = SIP_ROTL(H->v0, 32);
+  for (i = 0; i < rounds; i++) {
+    H->v0 += H->v1;
+    H->v1 = SIP_ROTL(H->v1, 13);
+    H->v1 ^= H->v0;
+    H->v0 = SIP_ROTL(H->v0, 32);
 
-               H->v2 += H->v3;
-               H->v3 = SIP_ROTL(H->v3, 16);
-               H->v3 ^= H->v2;
+    H->v2 += H->v3;
+    H->v3 = SIP_ROTL(H->v3, 16);
+    H->v3 ^= H->v2;
 
-               H->v0 += H->v3;
-               H->v3 = SIP_ROTL(H->v3, 21);
-               H->v3 ^= H->v0;
+    H->v0 += H->v3;
+    H->v3 = SIP_ROTL(H->v3, 21);
+    H->v3 ^= H->v0;
 
-               H->v2 += H->v1;
-               H->v1 = SIP_ROTL(H->v1, 17);
-               H->v1 ^= H->v2;
-               H->v2 = SIP_ROTL(H->v2, 32);
-       }
+    H->v2 += H->v1;
+    H->v1 = SIP_ROTL(H->v1, 17);
+    H->v1 ^= H->v2;
+    H->v2 = SIP_ROTL(H->v2, 32);
+  }
 } /* sip_round() */
 
+static struct siphash *
+sip24_init(struct siphash *H, const struct sipkey *key) {
+  H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
+  H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
+  H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
+  H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
 
-static struct siphash *sip24_init(struct siphash *H,
-               const struct sipkey *key) {
-       H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
-       H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
-       H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
-       H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
+  H->p = H->buf;
+  H->c = 0;
 
-       H->p = H->buf;
-       H->c = 0;
-
-       return H;
+  return H;
 } /* sip24_init() */
 
+#define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)])
 
-#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])
-
-static struct siphash *sip24_update(struct siphash *H, const void *src,
-               size_t len) {
-       const unsigned char *p = (const unsigned char *)src, *pe = p + len;
-       uint64_t m;
+static struct siphash *
+sip24_update(struct siphash *H, const void *src, size_t len) {
+  const unsigned char *p = (const unsigned char *)src, *pe = p + len;
+  uint64_t m;
 
-       do {
-               while (p < pe && H->p < sip_endof(H->buf))
-                       *H->p++ = *p++;
+  do {
+    while (p < pe && H->p < sip_endof(H->buf))
+      *H->p++ = *p++;
 
-               if (H->p < sip_endof(H->buf))
-                       break;
+    if (H->p < sip_endof(H->buf))
+      break;
 
-               m = SIP_U8TO64_LE(H->buf);
-               H->v3 ^= m;
-               sip_round(H, 2);
-               H->v0 ^= m;
+    m = SIP_U8TO64_LE(H->buf);
+    H->v3 ^= m;
+    sip_round(H, 2);
+    H->v0 ^= m;
 
-               H->p = H->buf;
-               H->c += 8;
-       } while (p < pe);
+    H->p = H->buf;
+    H->c += 8;
+  } while (p < pe);
 
-       return H;
+  return H;
 } /* sip24_update() */
 
-
-static uint64_t sip24_final(struct siphash *H) {
-       const char left = (char)(H->p - H->buf);
-       uint64_t b = (H->c + left) << 56;
-
-       switch (left) {
-       case 7: b |= (uint64_t)H->buf[6] << 48;
-               /* fall through */
-       case 6: b |= (uint64_t)H->buf[5] << 40;
-               /* fall through */
-       case 5: b |= (uint64_t)H->buf[4] << 32;
-               /* fall through */
-       case 4: b |= (uint64_t)H->buf[3] << 24;
-               /* fall through */
-       case 3: b |= (uint64_t)H->buf[2] << 16;
-               /* fall through */
-       case 2: b |= (uint64_t)H->buf[1] << 8;
-               /* fall through */
-       case 1: b |= (uint64_t)H->buf[0] << 0;
-               /* fall through */
-       case 0: break;
-       }
-
-       H->v3 ^= b;
-       sip_round(H, 2);
-       H->v0 ^= b;
-       H->v2 ^= 0xff;
-       sip_round(H, 4);
-
-       return H->v0 ^ H->v1 ^ H->v2  ^ H->v3;
+static uint64_t
+sip24_final(struct siphash *H) {
+  const char left = (char)(H->p - H->buf);
+  uint64_t b = (H->c + left) << 56;
+
+  switch (left) {
+  case 7:
+    b |= (uint64_t)H->buf[6] << 48;
+    /* fall through */
+  case 6:
+    b |= (uint64_t)H->buf[5] << 40;
+    /* fall through */
+  case 5:
+    b |= (uint64_t)H->buf[4] << 32;
+    /* fall through */
+  case 4:
+    b |= (uint64_t)H->buf[3] << 24;
+    /* fall through */
+  case 3:
+    b |= (uint64_t)H->buf[2] << 16;
+    /* fall through */
+  case 2:
+    b |= (uint64_t)H->buf[1] << 8;
+    /* fall through */
+  case 1:
+    b |= (uint64_t)H->buf[0] << 0;
+    /* fall through */
+  case 0:
+    break;
+  }
+
+  H->v3 ^= b;
+  sip_round(H, 2);
+  H->v0 ^= b;
+  H->v2 ^= 0xff;
+  sip_round(H, 4);
+
+  return H->v0 ^ H->v1 ^ H->v2 ^ H->v3;
 } /* sip24_final() */
 
-
-static uint64_t siphash24(const void *src, size_t len,
-               const struct sipkey *key) {
-       struct siphash state = SIPHASH_INITIALIZER;
-       return sip24_final(sip24_update(sip24_init(&state, key), src, len));
+static uint64_t
+siphash24(const void *src, size_t len, const struct sipkey *key) {
+  struct siphash state = SIPHASH_INITIALIZER;
+  return sip24_final(sip24_update(sip24_init(&state, key), src, len));
 } /* siphash24() */
 
-
 /*
  * SipHash-2-4 output with
  * k = 00 01 02 ...
@@ -285,107 +289,110 @@ static uint64_t siphash24(const void *src, size_t len,
  * ...
  * in = 00 01 02 ... 3e (63 bytes)
  */
-static int sip24_valid(void) {
-       static const unsigned char vectors[64][8] = {
-               { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
-               { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
-               { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
-               { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
-               { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
-               { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
-               { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
-               { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
-               { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
-               { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
-               { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
-               { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
-               { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
-               { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
-               { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
-               { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
-               { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
-               { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
-               { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
-               { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
-               { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
-               { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
-               { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
-               { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
-               { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
-               { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
-               { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
-               { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
-               { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
-               { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
-               { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
-               { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
-               { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
-               { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
-               { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
-               { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
-               { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
-               { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
-               { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
-               { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
-               { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
-               { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
-               { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
-               { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
-               { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
-               { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
-               { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
-               { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
-               { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
-               { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
-               { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
-               { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
-               { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
-               { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
-               { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
-               { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
-               { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
-               { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
-               { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
-               { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
-               { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
-               { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
-               { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
-               { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
-       };
-       unsigned char in[64];
-       struct sipkey k;
-       size_t i;
-
-       sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
-                       "\012\013\014\015\016\017");
-
-       for (i = 0; i < sizeof in; ++i) {
-               in[i] = (unsigned char)i;
-
-               if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
-                       return 0;
-       }
-
-       return 1;
+static int
+sip24_valid(void) {
+  /* clang-format off */
+  static const unsigned char vectors[64][8] = {
+    { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
+    { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
+    { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
+    { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
+    { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
+    { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
+    { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
+    { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
+    { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
+    { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
+    { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
+    { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
+    { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
+    { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
+    { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
+    { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
+    { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
+    { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
+    { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
+    { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
+    { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
+    { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
+    { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
+    { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
+    { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
+    { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
+    { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
+    { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
+    { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
+    { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
+    { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
+    { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
+    { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
+    { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
+    { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
+    { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
+    { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
+    { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
+    { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
+    { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
+    { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
+    { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
+    { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
+    { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
+    { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
+    { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
+    { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
+    { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
+    { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
+    { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
+    { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
+    { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
+    { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
+    { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
+    { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
+    { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
+    { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
+    { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
+    { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
+    { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
+    { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
+    { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
+    { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
+    { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
+  };
+  /* clang-format on */
+
+  unsigned char in[64];
+  struct sipkey k;
+  size_t i;
+
+  sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
+                "\012\013\014\015\016\017");
+
+  for (i = 0; i < sizeof in; ++i) {
+    in[i] = (unsigned char)i;
+
+    if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
+      return 0;
+  }
+
+  return 1;
 } /* sip24_valid() */
 
-
 #ifdef SIPHASH_MAIN
 
-#include <stdio.h>
+#  include <stdio.h>
 
-int main(void) {
-       const int ok = sip24_valid();
+int
+main(void) {
+  const int ok = sip24_valid();
 
-       if (ok)
-               puts("OK");
-       else
-               puts("FAIL");
+  if (ok)
+    puts("OK");
+  else
+    puts("FAIL");
 
-       return !ok;
+  return ! ok;
 } /* main() */
 
 #endif /* SIPHASH_MAIN */
 
-
 #endif /* SIPHASH_H */
index fa0bed6f5d751d070144e47efb4af938e90dc7cc..a22986acbb9526b34c33a4ffa8a0f74c5ef36d15 100644 (file)
 */
 
 /* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
-/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
+    /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+    /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+    /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+    /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+    /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+    /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+    /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+    /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+    /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
index 28a043c6044ca4b1f88d356b49de632dace6ce2a..562a4a82dc1d638b2cc84282ee9be29de00fc801 100644 (file)
 #include <memory.h>
 #include <string.h>
 
+#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */
+#  include <expat_config.h>
+#else /* !defined(HAVE_EXPAT_CONFIG_H) */
 
-#if defined(HAVE_EXPAT_CONFIG_H)  /* e.g. MinGW */
-# include <expat_config.h>
-#else  /* !defined(HAVE_EXPAT_CONFIG_H) */
-
-
-#define XML_NS 1
-#define XML_DTD 1
-#define XML_CONTEXT_BYTES 1024
+#  define XML_NS 1
+#  define XML_DTD 1
+#  define XML_CONTEXT_BYTES 1024
 
 /* we will assume all Windows platforms are little endian */
-#define BYTEORDER 1234
+#  define BYTEORDER 1234
 
 #endif /* !defined(HAVE_EXPAT_CONFIG_H) */
 
-
 #endif /* ndef WINCONFIG_H */
index 9c0987f4f6d8749d2d3a0885219e366c1ac67393..e740f0e19c7d4a1b7a36b46491a2157da334f408 100644 (file)
@@ -1,4 +1,4 @@
-/* 69df5be70289a11fb834869ce4a91c23c1d9dd04baffcbd10e86742d149a080c (2.2.7+)
+/* f2d0ab6d1d4422a08cf1cf3bbdfba96b49dea42fb5ff4615e03a2a25c306e769 (2.2.8+)
                             __  __            _
                          ___\ \/ /_ __   __ _| |_
                         / _ \\  /| '_ \ / _` | __|
    USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#if !defined(_GNU_SOURCE)
-# define _GNU_SOURCE 1                  /* syscall prototype */
+#if ! defined(_GNU_SOURCE)
+#  define _GNU_SOURCE 1 /* syscall prototype */
+#endif
+
+#ifdef _WIN32
+/* force stdlib to define rand_s() */
+#  define _CRT_RAND_S
 #endif
 
 #include <stddef.h>
-#include <string.h>                     /* memset(), memcpy() */
+#include <string.h> /* memset(), memcpy() */
 #include <assert.h>
-#include <limits.h>                     /* UINT_MAX */
-#include <stdio.h>                      /* fprintf */
-#include <stdlib.h>                     /* getenv */
+#include <limits.h> /* UINT_MAX */
+#include <stdio.h>  /* fprintf */
+#include <stdlib.h> /* getenv, rand_s */
 
 #ifdef _WIN32
-#define getpid GetCurrentProcessId
+#  define getpid GetCurrentProcessId
 #else
-#include <sys/time.h>                   /* gettimeofday() */
-#include <sys/types.h>                  /* getpid() */
-#include <unistd.h>                     /* getpid() */
-#include <fcntl.h>                      /* O_RDONLY */
-#include <errno.h>
+#  include <sys/time.h>  /* gettimeofday() */
+#  include <sys/types.h> /* getpid() */
+#  include <unistd.h>    /* getpid() */
+#  include <fcntl.h>     /* O_RDONLY */
+#  include <errno.h>
 #endif
 
 #define XML_BUILDING_EXPAT 1
 
 #ifdef _WIN32
-#include "winconfig.h"
+#  include "winconfig.h"
 #elif defined(HAVE_EXPAT_CONFIG_H)
-#include <expat_config.h>
+#  include <expat_config.h>
 #endif /* ndef _WIN32 */
 
 #include "ascii.h"
 #include "siphash.h"
 
 #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
-# if defined(HAVE_GETRANDOM)
-#  include <sys/random.h>    /* getrandom */
-# else
-#  include <unistd.h>        /* syscall */
-#  include <sys/syscall.h>   /* SYS_getrandom */
-# endif
-# if ! defined(GRND_NONBLOCK)
-#  define GRND_NONBLOCK  0x0001
-# endif  /* defined(GRND_NONBLOCK) */
-#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
-
-#if defined(HAVE_LIBBSD) \
+#  if defined(HAVE_GETRANDOM)
+#    include <sys/random.h> /* getrandom */
+#  else
+#    include <unistd.h>      /* syscall */
+#    include <sys/syscall.h> /* SYS_getrandom */
+#  endif
+#  if ! defined(GRND_NONBLOCK)
+#    define GRND_NONBLOCK 0x0001
+#  endif /* defined(GRND_NONBLOCK) */
+#endif   /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+#if defined(HAVE_LIBBSD)                                                       \
     && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
-# include <bsd/stdlib.h>
+#  include <bsd/stdlib.h>
 #endif
 
-#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
-# define LOAD_LIBRARY_SEARCH_SYSTEM32  0x00000800
+#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
+#  define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
 #endif
 
-#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \
-    && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \
-    && !defined(XML_DEV_URANDOM) \
-    && !defined(_WIN32) \
-    && !defined(XML_POOR_ENTROPY)
-# error  \
-    You do not have support for any sources of high quality entropy \
+#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM)             \
+    && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)            \
+    && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32)                         \
+    && ! defined(XML_POOR_ENTROPY)
+#  error You do not have support for any sources of high quality entropy \
     enabled.  For end user security, that is probably not what you want. \
     \
     Your options include: \
       * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
       * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
       * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
-      * Windows (RtlGenRandom): _WIN32. \
+      * Windows (rand_s): _WIN32. \
     \
     If insist on not using any of these, bypass this error by defining \
     XML_POOR_ENTROPY; you have been warned. \
     to the build system, please open a bug.  Thank you!
 #endif
 
-
 #ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
+#  define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#  define XmlConvert XmlUtf16Convert
+#  define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#  define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#  define XmlEncode XmlUtf16Encode
 /* Using pointer subtraction to convert to integer type. */
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
+#  define MUST_CONVERT(enc, s)                                                 \
+    (! (enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
 typedef unsigned short ICHAR;
 #else
-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
-#define XmlConvert XmlUtf8Convert
-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
-#define XmlEncode XmlUtf8Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+#  define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#  define XmlConvert XmlUtf8Convert
+#  define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#  define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#  define XmlEncode XmlUtf8Encode
+#  define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
 typedef char ICHAR;
 #endif
 
-
 #ifndef XML_NS
 
-#define XmlInitEncodingNS XmlInitEncoding
-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
-#undef XmlGetInternalEncodingNS
-#define XmlGetInternalEncodingNS XmlGetInternalEncoding
-#define XmlParseXmlDeclNS XmlParseXmlDecl
+#  define XmlInitEncodingNS XmlInitEncoding
+#  define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#  undef XmlGetInternalEncodingNS
+#  define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#  define XmlParseXmlDeclNS XmlParseXmlDecl
 
 #endif
 
 #ifdef XML_UNICODE
 
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) (const wchar_t)x
-#define XML_L(x) L ## x
-#else
-#define XML_T(x) (const unsigned short)x
-#define XML_L(x) x
-#endif
+#  ifdef XML_UNICODE_WCHAR_T
+#    define XML_T(x) (const wchar_t) x
+#    define XML_L(x) L##x
+#  else
+#    define XML_T(x) (const unsigned short)x
+#    define XML_L(x) x
+#  endif
 
 #else
 
-#define XML_T(x) x
-#define XML_L(x) x
+#  define XML_T(x) x
+#  define XML_L(x) x
 
 #endif
 
 /* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
 
 /* Do safe (NULL-aware) pointer arithmetic */
 #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
@@ -182,11 +184,9 @@ typedef struct {
   const XML_Memory_Handling_Suite *mem;
 } HASH_TABLE;
 
-static size_t
-keylen(KEY s);
+static size_t keylen(KEY s);
 
-static void
-copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
+static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
 
 /* For probing (after a collision) we need a step size relative prime
    to the hash table size, which is a power of 2. We use double-hashing,
@@ -196,9 +196,9 @@ copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
    We limit the maximum step size to table->size / 4 (mask >> 2) and make
    it odd, since odd numbers are always relative prime to a power of 2.
 */
-#define SECOND_HASH(hash, mask, power) \
-  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
-#define PROBE_STEP(hash, mask, power) \
+#define SECOND_HASH(hash, mask, power)                                         \
+  ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power)                                          \
   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
 
 typedef struct {
@@ -206,7 +206,7 @@ typedef struct {
   NAMED **end;
 } HASH_TABLE_ITER;
 
-#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
+#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
 #define INIT_DATA_BUF_SIZE 1024
 #define INIT_ATTS_SIZE 16
 #define INIT_ATTS_VERSION 0xFFFFFFFF
@@ -253,20 +253,20 @@ typedef struct {
    TAG objects in a free list.
 */
 typedef struct tag {
-  struct tag *parent;           /* parent of this element */
-  const char *rawName;          /* tagName in the original encoding */
+  struct tag *parent;  /* parent of this element */
+  const char *rawName; /* tagName in the original encoding */
   int rawNameLength;
-  TAG_NAME name;                /* tagName in the API encoding */
-  char *buf;                    /* buffer for name components */
-  char *bufEnd;                 /* end of the buffer */
+  TAG_NAME name; /* tagName in the API encoding */
+  char *buf;     /* buffer for name components */
+  char *bufEnd;  /* end of the buffer */
   BINDING *bindings;
 } TAG;
 
 typedef struct {
   const XML_Char *name;
   const XML_Char *textPtr;
-  int textLen;                  /* length in XML_Chars */
-  int processed;                /* # of processed bytes - when suspended */
+  int textLen;   /* length in XML_Chars */
+  int processed; /* # of processed bytes - when suspended */
   const XML_Char *systemId;
   const XML_Char *base;
   const XML_Char *publicId;
@@ -277,13 +277,13 @@ typedef struct {
 } ENTITY;
 
 typedef struct {
-  enum XML_Content_Type         type;
-  enum XML_Content_Quant        quant;
-  const XML_Char *              name;
-  int                           firstchild;
-  int                           lastchild;
-  int                           childcnt;
-  int                           nextsib;
+  enum XML_Content_Type type;
+  enum XML_Content_Quant quant;
+  const XML_Char *name;
+  int firstchild;
+  int lastchild;
+  int childcnt;
+  int nextsib;
 } CONTENT_SCAFFOLD;
 
 #define INIT_SCAFFOLD_ELEMENTS 32
@@ -371,10 +371,8 @@ typedef struct open_internal_entity {
   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
 } OPEN_INTERNAL_ENTITY;
 
-typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
-                                         const char *start,
-                                         const char *end,
-                                         const char **endPtr);
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
+                                         const char *end, const char **endPtr);
 
 static Processor prologProcessor;
 static Processor prologInitProcessor;
@@ -395,118 +393,101 @@ static Processor externalEntityInitProcessor3;
 static Processor externalEntityContentProcessor;
 static Processor internalEntityProcessor;
 
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
-               const char *s, const char *next);
-static enum XML_Error
-initializeEncoding(XML_Parser parser);
-static enum XML_Error
-doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
-         const char *end, int tok, const char *next, const char **nextPtr,
-         XML_Bool haveMore);
-static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity,
-                      XML_Bool betweenDecl);
-static enum XML_Error
-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-          const char *start, const char *end, const char **endPtr,
-          XML_Bool haveMore);
-static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
-               const char *end, const char **nextPtr, XML_Bool haveMore);
+static enum XML_Error handleUnknownEncoding(XML_Parser parser,
+                                            const XML_Char *encodingName);
+static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+                                     const char *s, const char *next);
+static enum XML_Error initializeEncoding(XML_Parser parser);
+static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
+                               const char *s, const char *end, int tok,
+                               const char *next, const char **nextPtr,
+                               XML_Bool haveMore, XML_Bool allowClosingDoctype);
+static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
+                                            XML_Bool betweenDecl);
+static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
+                                const ENCODING *enc, const char *start,
+                                const char *end, const char **endPtr,
+                                XML_Bool haveMore);
+static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
+                                     const char **startPtr, const char *end,
+                                     const char **nextPtr, XML_Bool haveMore);
 #ifdef XML_DTD
-static enum XML_Error
-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
-                const char *end, const char **nextPtr, XML_Bool haveMore);
+static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
+                                      const char **startPtr, const char *end,
+                                      const char **nextPtr, XML_Bool haveMore);
 #endif /* XML_DTD */
 
-static void
-freeBindings(XML_Parser parser, BINDING *bindings);
-static enum XML_Error
-storeAtts(XML_Parser parser, const ENCODING *, const char *s,
-          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static enum XML_Error
-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
-           const XML_Char *uri, BINDING **bindingsPtr);
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
-                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
-                    const char *, const char *, STRING_POOL *);
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
-                     const char *, const char *, STRING_POOL *);
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
-               const char *end);
-static int
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
-static enum XML_Error
-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
-                 const char *end);
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
-                            const char *start, const char *end);
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
-              const char *end);
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
-              const char *end);
-
-static const XML_Char * getContext(XML_Parser parser);
-static XML_Bool
-setContext(XML_Parser parser, const XML_Char *context);
+static void freeBindings(XML_Parser parser, BINDING *bindings);
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
+                                const char *s, TAG_NAME *tagNamePtr,
+                                BINDING **bindingsPtr);
+static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
+                                 const ATTRIBUTE_ID *attId, const XML_Char *uri,
+                                 BINDING **bindingsPtr);
+static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
+                           XML_Bool isId, const XML_Char *dfltValue,
+                           XML_Parser parser);
+static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
+                                          XML_Bool isCdata, const char *,
+                                          const char *, STRING_POOL *);
+static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
+                                           XML_Bool isCdata, const char *,
+                                           const char *, STRING_POOL *);
+static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
+                                    const char *start, const char *end);
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
+                                       const char *start, const char *end);
+static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+                                       const char *start, const char *end);
+static int reportComment(XML_Parser parser, const ENCODING *enc,
+                         const char *start, const char *end);
+static void reportDefault(XML_Parser parser, const ENCODING *enc,
+                          const char *start, const char *end);
+
+static const XML_Char *getContext(XML_Parser parser);
+static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
 
 static void FASTCALL normalizePublicId(XML_Char *s);
 
-static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
+static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
 /* do not call if m_parentParser != NULL */
 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
-static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
-static int
-dtdCopy(XML_Parser oldParser,
-        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
-static int
-copyEntityTable(XML_Parser oldParser,
-                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
-static NAMED *
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
-static void FASTCALL
-hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
+                       const XML_Memory_Handling_Suite *ms);
+static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
+                   const XML_Memory_Handling_Suite *ms);
+static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
+                           const HASH_TABLE *);
+static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
+                     size_t createSize);
+static void FASTCALL hashTableInit(HASH_TABLE *,
+                                   const XML_Memory_Handling_Suite *ms);
 static void FASTCALL hashTableClear(HASH_TABLE *);
 static void FASTCALL hashTableDestroy(HASH_TABLE *);
-static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
+static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
 
-static void FASTCALL
-poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolInit(STRING_POOL *,
+                              const XML_Memory_Handling_Suite *ms);
 static void FASTCALL poolClear(STRING_POOL *);
 static void FASTCALL poolDestroy(STRING_POOL *);
-static XML_Char *
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
-           const char *ptr, const char *end);
-static XML_Char *
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-                const char *ptr, const char *end);
+static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+                            const char *ptr, const char *end);
+static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                                 const char *ptr, const char *end);
 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
+                                               const XML_Char *s);
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
+                                       int n);
+static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
+                                                 const XML_Char *s);
 
 static int FASTCALL nextScaffoldPart(XML_Parser parser);
-static XML_Content * build_model(XML_Parser parser);
-static ELEMENT_TYPE *
-getElementType(XML_Parser parser, const ENCODING *enc,
-               const char *ptr, const char *end);
+static XML_Content *build_model(XML_Parser parser);
+static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
+                                    const char *ptr, const char *end);
 
 static XML_Char *copyString(const XML_Char *s,
                             const XML_Memory_Handling_Suite *memsuite);
@@ -514,14 +495,11 @@ static XML_Char *copyString(const XML_Char *s,
 static unsigned long generate_hash_secret_salt(XML_Parser parser);
 static XML_Bool startParsing(XML_Parser parser);
 
-static XML_Parser
-parserCreate(const XML_Char *encodingName,
-             const XML_Memory_Handling_Suite *memsuite,
-             const XML_Char *nameSep,
-             DTD *dtd);
+static XML_Parser parserCreate(const XML_Char *encodingName,
+                               const XML_Memory_Handling_Suite *memsuite,
+                               const XML_Char *nameSep, DTD *dtd);
 
-static void
-parserInit(XML_Parser parser, const XML_Char *encodingName);
+static void parserInit(XML_Parser parser, const XML_Char *encodingName);
 
 #define poolStart(pool) ((pool)->start)
 #define poolEnd(pool) ((pool)->ptr)
@@ -530,10 +508,10 @@ parserInit(XML_Parser parser, const XML_Char *encodingName);
 #define poolLastChar(pool) (((pool)->ptr)[-1])
 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
-#define poolAppendChar(pool, c) \
-  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
-   ? 0 \
-   : ((*((pool)->ptr)++ = c), 1))
+#define poolAppendChar(pool, c)                                                \
+  (((pool)->ptr == (pool)->end && ! poolGrow(pool))                            \
+       ? 0                                                                     \
+       : ((*((pool)->ptr)++ = c), 1))
 
 struct XML_ParserStruct {
   /* The first member must be m_userData so that the XML_GetUserData
@@ -584,7 +562,7 @@ struct XML_ParserStruct {
   void *m_unknownEncodingMem;
   void *m_unknownEncodingData;
   void *m_unknownEncodingHandlerData;
-  void (XMLCALL *m_unknownEncodingRelease)(void *);
+  void(XMLCALL *m_unknownEncodingRelease)(void *);
   PROLOG_STATE m_prologState;
   Processor *m_processor;
   enum XML_Error m_errorCode;
@@ -638,57 +616,55 @@ struct XML_ParserStruct {
   unsigned long m_hash_secret_salt;
 };
 
-#define MALLOC(parser, s)      (parser->m_mem.malloc_fcn((s)))
-#define REALLOC(parser, p, s)  (parser->m_mem.realloc_fcn((p),(s)))
-#define FREE(parser, p)        (parser->m_mem.free_fcn((p)))
-
+#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
+#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
 
 XML_Parser XMLCALL
-XML_ParserCreate(const XML_Char *encodingName)
-{
+XML_ParserCreate(const XML_Char *encodingName) {
   return XML_ParserCreate_MM(encodingName, NULL, NULL);
 }
 
 XML_Parser XMLCALL
-XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
-{
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
   XML_Char tmp[2];
   *tmp = nsSep;
   return XML_ParserCreate_MM(encodingName, NULL, tmp);
 }
 
-static const XML_Char implicitContext[] = {
-  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
-  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
-  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
-  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
-  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
-  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
-};
-
+static const XML_Char implicitContext[]
+    = {ASCII_x,     ASCII_m,     ASCII_l,      ASCII_EQUALS, ASCII_h,
+       ASCII_t,     ASCII_t,     ASCII_p,      ASCII_COLON,  ASCII_SLASH,
+       ASCII_SLASH, ASCII_w,     ASCII_w,      ASCII_w,      ASCII_PERIOD,
+       ASCII_w,     ASCII_3,     ASCII_PERIOD, ASCII_o,      ASCII_r,
+       ASCII_g,     ASCII_SLASH, ASCII_X,      ASCII_M,      ASCII_L,
+       ASCII_SLASH, ASCII_1,     ASCII_9,      ASCII_9,      ASCII_8,
+       ASCII_SLASH, ASCII_n,     ASCII_a,      ASCII_m,      ASCII_e,
+       ASCII_s,     ASCII_p,     ASCII_a,      ASCII_c,      ASCII_e,
+       '\0'};
 
 /* To avoid warnings about unused functions: */
 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
 
-#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+#  if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
 
 /* Obtain entropy on Linux 3.17+ */
 static int
-writeRandomBytes_getrandom_nonblock(void * target, size_t count) {
-  int success = 0;  /* full count bytes written? */
+writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
+  int success = 0; /* full count bytes written? */
   size_t bytesWrittenTotal = 0;
   const unsigned int getrandomFlags = GRND_NONBLOCK;
 
   do {
-    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+    void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
     const size_t bytesToWrite = count - bytesWrittenTotal;
 
     const int bytesWrittenMore =
-#if defined(HAVE_GETRANDOM)
+#    if defined(HAVE_GETRANDOM)
         getrandom(currentTarget, bytesToWrite, getrandomFlags);
-#else
+#    else
         syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
-#endif
+#    endif
 
     if (bytesWrittenMore > 0) {
       bytesWrittenTotal += bytesWrittenMore;
@@ -700,15 +676,14 @@ writeRandomBytes_getrandom_nonblock(void * target, size_t count) {
   return success;
 }
 
-#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
-
+#  endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
 
-#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+#  if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
 
 /* Extract entropy from /dev/urandom */
 static int
-writeRandomBytes_dev_urandom(void * target, size_t count) {
-  int success = 0;  /* full count bytes written? */
+writeRandomBytes_dev_urandom(void *target, size_t count) {
+  int success = 0; /* full count bytes written? */
   size_t bytesWrittenTotal = 0;
 
   const int fd = open("/dev/urandom", O_RDONLY);
@@ -717,7 +692,7 @@ writeRandomBytes_dev_urandom(void * target, size_t count) {
   }
 
   do {
-    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+    void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
     const size_t bytesToWrite = count - bytesWrittenTotal;
 
     const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
@@ -733,15 +708,14 @@ writeRandomBytes_dev_urandom(void * target, size_t count) {
   return success;
 }
 
-#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
-
-#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
+#  endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
 
+#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
 
 #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
 
 static void
-writeRandomBytes_arc4random(void * target, size_t count) {
+writeRandomBytes_arc4random(void *target, size_t count) {
   size_t bytesWrittenTotal = 0;
 
   while (bytesWrittenTotal < count) {
@@ -749,93 +723,82 @@ writeRandomBytes_arc4random(void * target, size_t count) {
     size_t i = 0;
 
     for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
-        i++, bytesWrittenTotal++) {
+         i++, bytesWrittenTotal++) {
       const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
       ((uint8_t *)target)[bytesWrittenTotal] = random8;
     }
   }
 }
 
-#endif  /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
-
+#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
 
 #ifdef _WIN32
 
-typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
-HMODULE _Expat_LoadLibrary(LPCTSTR filename);  /* see loadlibrary.c */
-
-/* Obtain entropy on Windows XP / Windows Server 2003 and later.
- * Hint on RtlGenRandom and the following article from libsodium.
- *
- * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
- * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
+/* Obtain entropy on Windows using the rand_s() function which
+ * generates cryptographically secure random numbers.  Internally it
+ * uses RtlGenRandom API which is present in Windows XP and later.
  */
 static int
-writeRandomBytes_RtlGenRandom(void * target, size_t count) {
-  int success = 0;  /* full count bytes written? */
-  const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL"));
-
-  if (advapi32) {
-    const RTLGENRANDOM_FUNC RtlGenRandom
-        = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
-    if (RtlGenRandom) {
-      if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
-        success = 1;
-      }
+writeRandomBytes_rand_s(void *target, size_t count) {
+  size_t bytesWrittenTotal = 0;
+
+  while (bytesWrittenTotal < count) {
+    unsigned int random32 = 0;
+    size_t i = 0;
+
+    if (rand_s(&random32))
+      return 0; /* failure */
+
+    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
+         i++, bytesWrittenTotal++) {
+      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
+      ((uint8_t *)target)[bytesWrittenTotal] = random8;
     }
-    FreeLibrary(advapi32);
   }
-
-  return success;
+  return 1; /* success */
 }
 
 #endif /* _WIN32 */
 
-
 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
 
 static unsigned long
-gather_time_entropy(void)
-{
-#ifdef _WIN32
+gather_time_entropy(void) {
+#  ifdef _WIN32
   FILETIME ft;
   GetSystemTimeAsFileTime(&ft); /* never fails */
   return ft.dwHighDateTime ^ ft.dwLowDateTime;
-#else
+#  else
   struct timeval tv;
   int gettimeofday_res;
 
   gettimeofday_res = gettimeofday(&tv, NULL);
 
-#if defined(NDEBUG)
+#    if defined(NDEBUG)
   (void)gettimeofday_res;
-#else
-  assert (gettimeofday_res == 0);
-#endif  /* defined(NDEBUG) */
+#    else
+  assert(gettimeofday_res == 0);
+#    endif /* defined(NDEBUG) */
 
   /* Microseconds time is <20 bits entropy */
   return tv.tv_usec;
-#endif
+#  endif
 }
 
-#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
-
+#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
 
 static unsigned long
-ENTROPY_DEBUG(const char * label, unsigned long entropy) {
-  const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
+ENTROPY_DEBUG(const char *label, unsigned long entropy) {
+  const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
   if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
-    fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
-        label,
-        (int)sizeof(entropy) * 2, entropy,
-        (unsigned long)sizeof(entropy));
+    fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
+            (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
   }
   return entropy;
 }
 
 static unsigned long
-generate_hash_secret_salt(XML_Parser parser)
-{
+generate_hash_secret_salt(XML_Parser parser) {
   unsigned long entropy;
   (void)parser;
 
@@ -848,20 +811,20 @@ generate_hash_secret_salt(XML_Parser parser)
   return ENTROPY_DEBUG("arc4random", entropy);
 #else
   /* Try high quality providers first .. */
-#ifdef _WIN32
-  if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
-    return ENTROPY_DEBUG("RtlGenRandom", entropy);
+#  ifdef _WIN32
+  if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
+    return ENTROPY_DEBUG("rand_s", entropy);
   }
-#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+#  elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
   if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
     return ENTROPY_DEBUG("getrandom", entropy);
   }
-#endif
-#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+#  endif
+#  if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
   if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
     return ENTROPY_DEBUG("/dev/urandom", entropy);
   }
-#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
+#  endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
   /* .. and self-made low quality for backup: */
 
   /* Process ID is 0 bits entropy if attacker has local access */
@@ -872,7 +835,7 @@ generate_hash_secret_salt(XML_Parser parser)
     return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
   } else {
     return ENTROPY_DEBUG("fallback(8)",
-        entropy * (unsigned long)2305843009213693951ULL);
+                         entropy * (unsigned long)2305843009213693951ULL);
   }
 #endif
 }
@@ -884,49 +847,43 @@ get_hash_secret_salt(XML_Parser parser) {
   return parser->m_hash_secret_salt;
 }
 
-static XML_Bool  /* only valid for root parser */
-startParsing(XML_Parser parser)
-{
-    /* hash functions must be initialized before setContext() is called */
-    if (parser->m_hash_secret_salt == 0)
-      parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
-    if (parser->m_ns) {
-      /* implicit context only set for root parser, since child
-         parsers (i.e. external entity parsers) will inherit it
-      */
-      return setContext(parser, implicitContext);
-    }
-    return XML_TRUE;
+static XML_Bool /* only valid for root parser */
+startParsing(XML_Parser parser) {
+  /* hash functions must be initialized before setContext() is called */
+  if (parser->m_hash_secret_salt == 0)
+    parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
+  if (parser->m_ns) {
+    /* implicit context only set for root parser, since child
+       parsers (i.e. external entity parsers) will inherit it
+    */
+    return setContext(parser, implicitContext);
+  }
+  return XML_TRUE;
 }
 
 XML_Parser XMLCALL
 XML_ParserCreate_MM(const XML_Char *encodingName,
                     const XML_Memory_Handling_Suite *memsuite,
-                    const XML_Char *nameSep)
-{
+                    const XML_Char *nameSep) {
   return parserCreate(encodingName, memsuite, nameSep, NULL);
 }
 
 static XML_Parser
 parserCreate(const XML_Char *encodingName,
-             const XML_Memory_Handling_Suite *memsuite,
-             const XML_Char *nameSep,
-             DTD *dtd)
-{
+             const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
+             DTD *dtd) {
   XML_Parser parser;
 
   if (memsuite) {
     XML_Memory_Handling_Suite *mtemp;
-    parser = (XML_Parser)
-      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+    parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
     if (parser != NULL) {
       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
       mtemp->malloc_fcn = memsuite->malloc_fcn;
       mtemp->realloc_fcn = memsuite->realloc_fcn;
       mtemp->free_fcn = memsuite->free_fcn;
     }
-  }
-  else {
+  } else {
     XML_Memory_Handling_Suite *mtemp;
     parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
     if (parser != NULL) {
@@ -937,27 +894,30 @@ parserCreate(const XML_Char *encodingName,
     }
   }
 
-  if (!parser)
+  if (! parser)
     return parser;
 
   parser->m_buffer = NULL;
   parser->m_bufferLim = NULL;
 
   parser->m_attsSize = INIT_ATTS_SIZE;
-  parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
+  parser->m_atts
+      = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
   if (parser->m_atts == NULL) {
     FREE(parser, parser);
     return NULL;
   }
 #ifdef XML_ATTR_INFO
-  parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo));
+  parser->m_attInfo = (XML_AttrInfo *)MALLOC(
+      parser, parser->m_attsSize * sizeof(XML_AttrInfo));
   if (parser->m_attInfo == NULL) {
     FREE(parser, parser->m_atts);
     FREE(parser, parser);
     return NULL;
   }
 #endif
-  parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  parser->m_dataBuf
+      = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
   if (parser->m_dataBuf == NULL) {
     FREE(parser, parser->m_atts);
 #ifdef XML_ATTR_INFO
@@ -1007,7 +967,7 @@ parserCreate(const XML_Char *encodingName,
   poolInit(&parser->m_temp2Pool, &(parser->m_mem));
   parserInit(parser, encodingName);
 
-  if (encodingName && !parser->m_protocolEncodingName) {
+  if (encodingName && ! parser->m_protocolEncodingName) {
     XML_ParserFree(parser);
     return NULL;
   }
@@ -1016,8 +976,7 @@ parserCreate(const XML_Char *encodingName,
     parser->m_ns = XML_TRUE;
     parser->m_internalEncoding = XmlGetInternalEncodingNS();
     parser->m_namespaceSeparator = *nameSep;
-  }
-  else {
+  } else {
     parser->m_internalEncoding = XmlGetInternalEncoding();
   }
 
@@ -1025,8 +984,7 @@ parserCreate(const XML_Char *encodingName,
 }
 
 static void
-parserInit(XML_Parser parser, const XML_Char *encodingName)
-{
+parserInit(XML_Parser parser, const XML_Char *encodingName) {
   parser->m_processor = prologInitProcessor;
   XmlPrologStateInit(&parser->m_prologState);
   if (encodingName != NULL) {
@@ -1099,8 +1057,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName)
 
 /* moves list of bindings to m_freeBindingList */
 static void FASTCALL
-moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
-{
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
   while (bindings) {
     BINDING *b = bindings;
     bindings = bindings->nextTagBinding;
@@ -1110,13 +1067,12 @@ moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
 }
 
 XML_Bool XMLCALL
-XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
-{
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
   TAG *tStk;
   OPEN_INTERNAL_ENTITY *openEntityList;
 
   if (parser == NULL)
-      return XML_FALSE;
+    return XML_FALSE;
 
   if (parser->m_parentParser)
     return XML_FALSE;
@@ -1152,15 +1108,15 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
 }
 
 enum XML_Status XMLCALL
-XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
   if (parser == NULL)
-      return XML_STATUS_ERROR;
+    return XML_STATUS_ERROR;
   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
      XXX There's no way for the caller to determine which of the
      XXX possible error cases caused the XML_STATUS_ERROR return.
   */
-  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parser->m_parsingStatus.parsing == XML_PARSING
+      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
     return XML_STATUS_ERROR;
 
   /* Get rid of any previous encoding name */
@@ -1172,17 +1128,15 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
   else {
     /* Copy the new encoding name into allocated memory */
     parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
-    if (!parser->m_protocolEncodingName)
+    if (! parser->m_protocolEncodingName)
       return XML_STATUS_ERROR;
   }
   return XML_STATUS_OK;
 }
 
 XML_Parser XMLCALL
-XML_ExternalEntityParserCreate(XML_Parser oldParser,
-                               const XML_Char *context,
-                               const XML_Char *encodingName)
-{
+XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
+                               const XML_Char *encodingName) {
   XML_Parser parser = oldParser;
   DTD *newDtd = NULL;
   DTD *oldDtd;
@@ -1206,7 +1160,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
   XML_AttlistDeclHandler oldAttlistDeclHandler;
   XML_EntityDeclHandler oldEntityDeclHandler;
   XML_XmlDeclHandler oldXmlDeclHandler;
-  ELEMENT_TYPE * oldDeclElementType;
+  ELEMENT_TYPE *oldDeclElementType;
 
   void *oldUserData;
   void *oldHandlerArg;
@@ -1269,7 +1223,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
   oldhash_secret_salt = parser->m_hash_secret_salt;
 
 #ifdef XML_DTD
-  if (!context)
+  if (! context)
     newDtd = oldDtd;
 #endif /* XML_DTD */
 
@@ -1282,12 +1236,11 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
     XML_Char tmp[2];
     *tmp = parser->m_namespaceSeparator;
     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
-  }
-  else {
+  } else {
     parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
   }
 
-  if (!parser)
+  if (! parser)
     return NULL;
 
   parser->m_startElementHandler = oldStartElementHandler;
@@ -1327,21 +1280,20 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
   parser->m_prologState.inEntityValue = oldInEntityValue;
   if (context) {
 #endif /* XML_DTD */
-    if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
-      || !setContext(parser, context)) {
+    if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
+        || ! setContext(parser, context)) {
       XML_ParserFree(parser);
       return NULL;
     }
     parser->m_processor = externalEntityInitProcessor;
 #ifdef XML_DTD
-  }
-  else {
-    /* The DTD instance referenced by parser->m_dtd is shared between the document's
-       root parser and external PE parsers, therefore one does not need to
-       call setContext. In addition, one also *must* not call setContext,
-       because this would overwrite existing prefix->binding pointers in
-       parser->m_dtd with ones that get destroyed with the external PE parser.
-       This would leave those prefixes with dangling pointers.
+  } else {
+    /* The DTD instance referenced by parser->m_dtd is shared between the
+       document's root parser and external PE parsers, therefore one does not
+       need to call setContext. In addition, one also *must* not call
+       setContext, because this would overwrite existing prefix->binding
+       pointers in parser->m_dtd with ones that get destroyed with the external
+       PE parser. This would leave those prefixes with dangling pointers.
     */
     parser->m_isParamEntity = XML_TRUE;
     XmlPrologStateInitExternalEntity(&parser->m_prologState);
@@ -1352,11 +1304,10 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
 }
 
 static void FASTCALL
-destroyBindings(BINDING *bindings, XML_Parser parser)
-{
+destroyBindings(BINDING *bindings, XML_Parser parser) {
   for (;;) {
     BINDING *b = bindings;
-    if (!b)
+    if (! b)
       break;
     bindings = b->nextTagBinding;
     FREE(parser, b->uri);
@@ -1365,8 +1316,7 @@ destroyBindings(BINDING *bindings, XML_Parser parser)
 }
 
 void XMLCALL
-XML_ParserFree(XML_Parser parser)
-{
+XML_ParserFree(XML_Parser parser) {
   TAG *tagList;
   OPEN_INTERNAL_ENTITY *entityList;
   if (parser == NULL)
@@ -1411,11 +1361,12 @@ XML_ParserFree(XML_Parser parser)
   /* external parameter entity parsers share the DTD structure
      parser->m_dtd with the root parser, so we must not destroy it
   */
-  if (!parser->m_isParamEntity && parser->m_dtd)
+  if (! parser->m_isParamEntity && parser->m_dtd)
 #else
   if (parser->m_dtd)
 #endif /* XML_DTD */
-    dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem);
+    dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
+               &parser->m_mem);
   FREE(parser, (void *)parser->m_atts);
 #ifdef XML_ATTR_INFO
   FREE(parser, (void *)parser->m_attInfo);
@@ -1431,20 +1382,19 @@ XML_ParserFree(XML_Parser parser)
 }
 
 void XMLCALL
-XML_UseParserAsHandlerArg(XML_Parser parser)
-{
+XML_UseParserAsHandlerArg(XML_Parser parser) {
   if (parser != NULL)
     parser->m_handlerArg = parser;
 }
 
 enum XML_Error XMLCALL
-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
-{
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
   if (parser == NULL)
     return XML_ERROR_INVALID_ARGUMENT;
 #ifdef XML_DTD
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parser->m_parsingStatus.parsing == XML_PARSING
+      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
   parser->m_useForeignDTD = useDTD;
   return XML_ERROR_NONE;
@@ -1454,19 +1404,18 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
 }
 
 void XMLCALL
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
-{
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
   if (parser == NULL)
     return;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parser->m_parsingStatus.parsing == XML_PARSING
+      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
     return;
   parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
 }
 
 void XMLCALL
-XML_SetUserData(XML_Parser parser, void *p)
-{
+XML_SetUserData(XML_Parser parser, void *p) {
   if (parser == NULL)
     return;
   if (parser->m_handlerArg == parser->m_userData)
@@ -1476,49 +1425,43 @@ XML_SetUserData(XML_Parser parser, void *p)
 }
 
 enum XML_Status XMLCALL
-XML_SetBase(XML_Parser parser, const XML_Char *p)
-{
+XML_SetBase(XML_Parser parser, const XML_Char *p) {
   if (parser == NULL)
     return XML_STATUS_ERROR;
   if (p) {
     p = poolCopyString(&parser->m_dtd->pool, p);
-    if (!p)
+    if (! p)
       return XML_STATUS_ERROR;
     parser->m_curBase = p;
-  }
-  else
+  } else
     parser->m_curBase = NULL;
   return XML_STATUS_OK;
 }
 
-const XML_Char * XMLCALL
-XML_GetBase(XML_Parser parser)
-{
+const XML_Char *XMLCALL
+XML_GetBase(XML_Parser parser) {
   if (parser == NULL)
     return NULL;
   return parser->m_curBase;
 }
 
 int XMLCALL
-XML_GetSpecifiedAttributeCount(XML_Parser parser)
-{
+XML_GetSpecifiedAttributeCount(XML_Parser parser) {
   if (parser == NULL)
     return -1;
   return parser->m_nSpecifiedAtts;
 }
 
 int XMLCALL
-XML_GetIdAttributeIndex(XML_Parser parser)
-{
+XML_GetIdAttributeIndex(XML_Parser parser) {
   if (parser == NULL)
     return -1;
   return parser->m_idAttIndex;
 }
 
 #ifdef XML_ATTR_INFO
-const XML_AttrInfo * XMLCALL
-XML_GetAttributeInfo(XML_Parser parser)
-{
+const XML_AttrInfo *XMLCALL
+XML_GetAttributeInfo(XML_Parser parser) {
   if (parser == NULL)
     return NULL;
   return parser->m_attInfo;
@@ -1526,10 +1469,8 @@ XML_GetAttributeInfo(XML_Parser parser)
 #endif
 
 void XMLCALL
-XML_SetElementHandler(XML_Parser parser,
-                      XML_StartElementHandler start,
-                      XML_EndElementHandler end)
-{
+XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
+                      XML_EndElementHandler end) {
   if (parser == NULL)
     return;
   parser->m_startElementHandler = start;
@@ -1537,39 +1478,33 @@ XML_SetElementHandler(XML_Parser parser,
 }
 
 void XMLCALL
-XML_SetStartElementHandler(XML_Parser parser,
-                           XML_StartElementHandler start) {
+XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
   if (parser != NULL)
     parser->m_startElementHandler = start;
 }
 
 void XMLCALL
-XML_SetEndElementHandler(XML_Parser parser,
-                         XML_EndElementHandler end) {
+XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
   if (parser != NULL)
     parser->m_endElementHandler = end;
 }
 
 void XMLCALL
 XML_SetCharacterDataHandler(XML_Parser parser,
-                            XML_CharacterDataHandler handler)
-{
+                            XML_CharacterDataHandler handler) {
   if (parser != NULL)
     parser->m_characterDataHandler = handler;
 }
 
 void XMLCALL
 XML_SetProcessingInstructionHandler(XML_Parser parser,
-                                    XML_ProcessingInstructionHandler handler)
-{
+                                    XML_ProcessingInstructionHandler handler) {
   if (parser != NULL)
     parser->m_processingInstructionHandler = handler;
 }
 
 void XMLCALL
-XML_SetCommentHandler(XML_Parser parser,
-                      XML_CommentHandler handler)
-{
+XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
   if (parser != NULL)
     parser->m_commentHandler = handler;
 }
@@ -1577,8 +1512,7 @@ XML_SetCommentHandler(XML_Parser parser,
 void XMLCALL
 XML_SetCdataSectionHandler(XML_Parser parser,
                            XML_StartCdataSectionHandler start,
-                           XML_EndCdataSectionHandler end)
-{
+                           XML_EndCdataSectionHandler end) {
   if (parser == NULL)
     return;
   parser->m_startCdataSectionHandler = start;
@@ -1600,9 +1534,7 @@ XML_SetEndCdataSectionHandler(XML_Parser parser,
 }
 
 void XMLCALL
-XML_SetDefaultHandler(XML_Parser parser,
-                      XML_DefaultHandler handler)
-{
+XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
   if (parser == NULL)
     return;
   parser->m_defaultHandler = handler;
@@ -1610,9 +1542,7 @@ XML_SetDefaultHandler(XML_Parser parser,
 }
 
 void XMLCALL
-XML_SetDefaultHandlerExpand(XML_Parser parser,
-                            XML_DefaultHandler handler)
-{
+XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
   if (parser == NULL)
     return;
   parser->m_defaultHandler = handler;
@@ -1620,10 +1550,8 @@ XML_SetDefaultHandlerExpand(XML_Parser parser,
 }
 
 void XMLCALL
-XML_SetDoctypeDeclHandler(XML_Parser parser,
-                          XML_StartDoctypeDeclHandler start,
-                          XML_EndDoctypeDeclHandler end)
-{
+XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end) {
   if (parser == NULL)
     return;
   parser->m_startDoctypeDeclHandler = start;
@@ -1638,24 +1566,20 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser,
 }
 
 void XMLCALL
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
-                             XML_EndDoctypeDeclHandler end) {
+XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
   if (parser != NULL)
     parser->m_endDoctypeDeclHandler = end;
 }
 
 void XMLCALL
 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-                                 XML_UnparsedEntityDeclHandler handler)
-{
+                                 XML_UnparsedEntityDeclHandler handler) {
   if (parser != NULL)
     parser->m_unparsedEntityDeclHandler = handler;
 }
 
 void XMLCALL
-XML_SetNotationDeclHandler(XML_Parser parser,
-                           XML_NotationDeclHandler handler)
-{
+XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
   if (parser != NULL)
     parser->m_notationDeclHandler = handler;
 }
@@ -1663,8 +1587,7 @@ XML_SetNotationDeclHandler(XML_Parser parser,
 void XMLCALL
 XML_SetNamespaceDeclHandler(XML_Parser parser,
                             XML_StartNamespaceDeclHandler start,
-                            XML_EndNamespaceDeclHandler end)
-{
+                            XML_EndNamespaceDeclHandler end) {
   if (parser == NULL)
     return;
   parser->m_startNamespaceDeclHandler = start;
@@ -1687,23 +1610,20 @@ XML_SetEndNamespaceDeclHandler(XML_Parser parser,
 
 void XMLCALL
 XML_SetNotStandaloneHandler(XML_Parser parser,
-                            XML_NotStandaloneHandler handler)
-{
+                            XML_NotStandaloneHandler handler) {
   if (parser != NULL)
     parser->m_notStandaloneHandler = handler;
 }
 
 void XMLCALL
 XML_SetExternalEntityRefHandler(XML_Parser parser,
-                                XML_ExternalEntityRefHandler handler)
-{
+                                XML_ExternalEntityRefHandler handler) {
   if (parser != NULL)
     parser->m_externalEntityRefHandler = handler;
 }
 
 void XMLCALL
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
-{
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
   if (parser == NULL)
     return;
   if (arg)
@@ -1714,17 +1634,14 @@ XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
 
 void XMLCALL
 XML_SetSkippedEntityHandler(XML_Parser parser,
-                            XML_SkippedEntityHandler handler)
-{
+                            XML_SkippedEntityHandler handler) {
   if (parser != NULL)
     parser->m_skippedEntityHandler = handler;
 }
 
 void XMLCALL
 XML_SetUnknownEncodingHandler(XML_Parser parser,
-                              XML_UnknownEncodingHandler handler,
-                              void *data)
-{
+                              XML_UnknownEncodingHandler handler, void *data) {
   if (parser == NULL)
     return;
   parser->m_unknownEncodingHandler = handler;
@@ -1732,44 +1649,37 @@ XML_SetUnknownEncodingHandler(XML_Parser parser,
 }
 
 void XMLCALL
-XML_SetElementDeclHandler(XML_Parser parser,
-                          XML_ElementDeclHandler eldecl)
-{
+XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
   if (parser != NULL)
     parser->m_elementDeclHandler = eldecl;
 }
 
 void XMLCALL
-XML_SetAttlistDeclHandler(XML_Parser parser,
-                          XML_AttlistDeclHandler attdecl)
-{
+XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
   if (parser != NULL)
     parser->m_attlistDeclHandler = attdecl;
 }
 
 void XMLCALL
-XML_SetEntityDeclHandler(XML_Parser parser,
-                         XML_EntityDeclHandler handler)
-{
+XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
   if (parser != NULL)
     parser->m_entityDeclHandler = handler;
 }
 
 void XMLCALL
-XML_SetXmlDeclHandler(XML_Parser parser,
-                      XML_XmlDeclHandler handler) {
+XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
   if (parser != NULL)
     parser->m_xmlDeclHandler = handler;
 }
 
 int XMLCALL
 XML_SetParamEntityParsing(XML_Parser parser,
-                          enum XML_ParamEntityParsing peParsing)
-{
+                          enum XML_ParamEntityParsing peParsing) {
   if (parser == NULL)
     return 0;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parser->m_parsingStatus.parsing == XML_PARSING
+      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
     return 0;
 #ifdef XML_DTD
   parser->m_paramEntityParsing = peParsing;
@@ -1780,23 +1690,21 @@ XML_SetParamEntityParsing(XML_Parser parser,
 }
 
 int XMLCALL
-XML_SetHashSalt(XML_Parser parser,
-                unsigned long hash_salt)
-{
+XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
   if (parser == NULL)
     return 0;
   if (parser->m_parentParser)
     return XML_SetHashSalt(parser->m_parentParser, hash_salt);
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parser->m_parsingStatus.parsing == XML_PARSING
+      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
     return 0;
   parser->m_hash_secret_salt = hash_salt;
   return 1;
 }
 
 enum XML_Status XMLCALL
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
-{
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
   if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
     if (parser != NULL)
       parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
@@ -1810,7 +1718,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
     parser->m_errorCode = XML_ERROR_FINISHED;
     return XML_STATUS_ERROR;
   case XML_INITIALIZED:
-    if (parser->m_parentParser == NULL && !startParsing(parser)) {
+    if (parser->m_parentParser == NULL && ! startParsing(parser)) {
       parser->m_errorCode = XML_ERROR_NO_MEMORY;
       return XML_STATUS_ERROR;
     }
@@ -1821,7 +1729,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
 
   if (len == 0) {
     parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
-    if (!isFinal)
+    if (! isFinal)
       return XML_STATUS_OK;
     parser->m_positionPtr = parser->m_bufferPtr;
     parser->m_parseEndPtr = parser->m_bufferEnd;
@@ -1830,7 +1738,9 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
        data are the final chunk of input, then we have to check them again
        to detect errors based on that fact.
     */
-    parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
+    parser->m_errorCode
+        = parser->m_processor(parser, parser->m_bufferPtr,
+                              parser->m_parseEndPtr, &parser->m_bufferPtr);
 
     if (parser->m_errorCode == XML_ERROR_NONE) {
       switch (parser->m_parsingStatus.parsing) {
@@ -1847,7 +1757,8 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
          *
          * LCOV_EXCL_START
          */
-        XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
+        XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+                          parser->m_bufferPtr, &parser->m_position);
         parser->m_positionPtr = parser->m_bufferPtr;
         return XML_STATUS_SUSPENDED;
         /* LCOV_EXCL_STOP */
@@ -1870,23 +1781,23 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
     enum XML_Status result;
     /* Detect overflow (a+b > MAX <==> b > MAX-a) */
     if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
-       parser->m_errorCode = XML_ERROR_NO_MEMORY;
-       parser->m_eventPtr = parser->m_eventEndPtr = NULL;
-       parser->m_processor = errorProcessor;
-       return XML_STATUS_ERROR;
+      parser->m_errorCode = XML_ERROR_NO_MEMORY;
+      parser->m_eventPtr = parser->m_eventEndPtr = NULL;
+      parser->m_processor = errorProcessor;
+      return XML_STATUS_ERROR;
     }
     parser->m_parseEndByteIndex += len;
     parser->m_positionPtr = s;
     parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
 
-    parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
+    parser->m_errorCode
+        = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
 
     if (parser->m_errorCode != XML_ERROR_NONE) {
       parser->m_eventEndPtr = parser->m_eventPtr;
       parser->m_processor = errorProcessor;
       return XML_STATUS_ERROR;
-    }
-    else {
+    } else {
       switch (parser->m_parsingStatus.parsing) {
       case XML_SUSPENDED:
         result = XML_STATUS_SUSPENDED;
@@ -1903,10 +1814,12 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
       }
     }
 
-    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position);
+    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
+                      &parser->m_position);
     nLeftOver = s + len - end;
     if (nLeftOver) {
-      if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
+      if (parser->m_buffer == NULL
+          || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
         /* avoid _signed_ integer overflow */
         char *temp = NULL;
         const int bytesToAllocate = (int)((unsigned)len * 2U);
@@ -1932,7 +1845,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
     parser->m_eventEndPtr = parser->m_bufferPtr;
     return result;
   }
-#endif  /* not defined XML_CONTEXT_BYTES */
+#endif /* not defined XML_CONTEXT_BYTES */
   else {
     void *buff = XML_GetBuffer(parser, len);
     if (buff == NULL)
@@ -1945,8 +1858,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
 }
 
 enum XML_Status XMLCALL
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
-{
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
   const char *start;
   enum XML_Status result = XML_STATUS_OK;
 
@@ -1960,7 +1872,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
     parser->m_errorCode = XML_ERROR_FINISHED;
     return XML_STATUS_ERROR;
   case XML_INITIALIZED:
-    if (parser->m_parentParser == NULL && !startParsing(parser)) {
+    if (parser->m_parentParser == NULL && ! startParsing(parser)) {
       parser->m_errorCode = XML_ERROR_NO_MEMORY;
       return XML_STATUS_ERROR;
     }
@@ -1976,14 +1888,14 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
   parser->m_parseEndByteIndex += len;
   parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
 
-  parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
+  parser->m_errorCode = parser->m_processor(
+      parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
 
   if (parser->m_errorCode != XML_ERROR_NONE) {
     parser->m_eventEndPtr = parser->m_eventPtr;
     parser->m_processor = errorProcessor;
     return XML_STATUS_ERROR;
-  }
-  else {
+  } else {
     switch (parser->m_parsingStatus.parsing) {
     case XML_SUSPENDED:
       result = XML_STATUS_SUSPENDED;
@@ -1994,18 +1906,18 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
         parser->m_parsingStatus.parsing = XML_FINISHED;
         return result;
       }
-    default: ;  /* should not happen */
+    default:; /* should not happen */
     }
   }
 
-  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
+  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+                    parser->m_bufferPtr, &parser->m_position);
   parser->m_positionPtr = parser->m_bufferPtr;
   return result;
 }
 
-void * XMLCALL
-XML_GetBuffer(XML_Parser parser, int len)
-{
+void *XMLCALL
+XML_GetBuffer(XML_Parser parser, int len) {
   if (parser == NULL)
     return NULL;
   if (len < 0) {
@@ -2019,17 +1931,17 @@ XML_GetBuffer(XML_Parser parser, int len)
   case XML_FINISHED:
     parser->m_errorCode = XML_ERROR_FINISHED;
     return NULL;
-  default: ;
+  default:;
   }
 
   if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
 #ifdef XML_CONTEXT_BYTES
     int keep;
-#endif  /* defined XML_CONTEXT_BYTES */
+#endif /* defined XML_CONTEXT_BYTES */
     /* Do not invoke signed arithmetic overflow: */
-    int neededSize = (int) ((unsigned)len +
-                            (unsigned)EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd,
-                                                          parser->m_bufferPtr));
+    int neededSize = (int)((unsigned)len
+                           + (unsigned)EXPAT_SAFE_PTR_DIFF(
+                               parser->m_bufferEnd, parser->m_bufferPtr));
     if (neededSize < 0) {
       parser->m_errorCode = XML_ERROR_NO_MEMORY;
       return NULL;
@@ -2039,13 +1951,18 @@ XML_GetBuffer(XML_Parser parser, int len)
     if (keep > XML_CONTEXT_BYTES)
       keep = XML_CONTEXT_BYTES;
     neededSize += keep;
-#endif  /* defined XML_CONTEXT_BYTES */
-    if (neededSize <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
+#endif /* defined XML_CONTEXT_BYTES */
+    if (neededSize
+        <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
 #ifdef XML_CONTEXT_BYTES
       if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
-          int offset = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) - keep;
-        /* The buffer pointers cannot be NULL here; we have at least some bytes in the buffer */
-        memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep);
+        int offset
+            = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
+              - keep;
+        /* The buffer pointers cannot be NULL here; we have at least some bytes
+         * in the buffer */
+        memmove(parser->m_buffer, &parser->m_buffer[offset],
+                parser->m_bufferEnd - parser->m_bufferPtr + keep);
         parser->m_bufferEnd -= offset;
         parser->m_bufferPtr -= offset;
       }
@@ -2053,20 +1970,21 @@ XML_GetBuffer(XML_Parser parser, int len)
       if (parser->m_buffer && parser->m_bufferPtr) {
         memmove(parser->m_buffer, parser->m_bufferPtr,
                 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
-        parser->m_bufferEnd = parser->m_buffer +
-            EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
+        parser->m_bufferEnd
+            = parser->m_buffer
+              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
         parser->m_bufferPtr = parser->m_buffer;
       }
-#endif  /* not defined XML_CONTEXT_BYTES */
-    }
-    else {
+#endif /* not defined XML_CONTEXT_BYTES */
+    } else {
       char *newBuf;
-      int bufferSize = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
+      int bufferSize
+          = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
       if (bufferSize == 0)
         bufferSize = INIT_BUFFER_SIZE;
       do {
         /* Do not invoke signed arithmetic overflow: */
-        bufferSize = (int) (2U * (unsigned) bufferSize);
+        bufferSize = (int)(2U * (unsigned)bufferSize);
       } while (bufferSize < neededSize && bufferSize > 0);
       if (bufferSize <= 0) {
         parser->m_errorCode = XML_ERROR_NO_MEMORY;
@@ -2080,18 +1998,17 @@ XML_GetBuffer(XML_Parser parser, int len)
       parser->m_bufferLim = newBuf + bufferSize;
 #ifdef XML_CONTEXT_BYTES
       if (parser->m_bufferPtr) {
-        int keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
-        if (keep > XML_CONTEXT_BYTES)
-          keep = XML_CONTEXT_BYTES;
         memcpy(newBuf, &parser->m_bufferPtr[-keep],
-               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep);
+               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
+                   + keep);
         FREE(parser, parser->m_buffer);
         parser->m_buffer = newBuf;
-        parser->m_bufferEnd = parser->m_buffer +
-            EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + keep;
+        parser->m_bufferEnd
+            = parser->m_buffer
+              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
+              + keep;
         parser->m_bufferPtr = parser->m_buffer + keep;
-      }
-      else {
+      } else {
         /* This must be a brand new buffer with no data in it yet */
         parser->m_bufferEnd = newBuf;
         parser->m_bufferPtr = parser->m_buffer = newBuf;
@@ -2101,15 +2018,15 @@ XML_GetBuffer(XML_Parser parser, int len)
         memcpy(newBuf, parser->m_bufferPtr,
                EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
         FREE(parser, parser->m_buffer);
-        parser->m_bufferEnd = newBuf +
-            EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
-      }
-      else {
+        parser->m_bufferEnd
+            = newBuf
+              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
+      else {
         /* This must be a brand new buffer with no data in it yet */
         parser->m_bufferEnd = newBuf;
       }
       parser->m_bufferPtr = parser->m_buffer = newBuf;
-#endif  /* not defined XML_CONTEXT_BYTES */
+#endif /* not defined XML_CONTEXT_BYTES */
     }
     parser->m_eventPtr = parser->m_eventEndPtr = NULL;
     parser->m_positionPtr = NULL;
@@ -2118,8 +2035,7 @@ XML_GetBuffer(XML_Parser parser, int len)
 }
 
 enum XML_Status XMLCALL
-XML_StopParser(XML_Parser parser, XML_Bool resumable)
-{
+XML_StopParser(XML_Parser parser, XML_Bool resumable) {
   if (parser == NULL)
     return XML_STATUS_ERROR;
   switch (parser->m_parsingStatus.parsing) {
@@ -2142,16 +2058,14 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable)
       }
 #endif
       parser->m_parsingStatus.parsing = XML_SUSPENDED;
-    }
-    else
+    } else
       parser->m_parsingStatus.parsing = XML_FINISHED;
   }
   return XML_STATUS_OK;
 }
 
 enum XML_Status XMLCALL
-XML_ResumeParser(XML_Parser parser)
-{
+XML_ResumeParser(XML_Parser parser) {
   enum XML_Status result = XML_STATUS_OK;
 
   if (parser == NULL)
@@ -2162,14 +2076,14 @@ XML_ResumeParser(XML_Parser parser)
   }
   parser->m_parsingStatus.parsing = XML_PARSING;
 
-  parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
+  parser->m_errorCode = parser->m_processor(
+      parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
 
   if (parser->m_errorCode != XML_ERROR_NONE) {
     parser->m_eventEndPtr = parser->m_eventPtr;
     parser->m_processor = errorProcessor;
     return XML_STATUS_ERROR;
-  }
-  else {
+  } else {
     switch (parser->m_parsingStatus.parsing) {
     case XML_SUSPENDED:
       result = XML_STATUS_SUSPENDED;
@@ -2180,18 +2094,18 @@ XML_ResumeParser(XML_Parser parser)
         parser->m_parsingStatus.parsing = XML_FINISHED;
         return result;
       }
-    default: ;
+    default:;
     }
   }
 
-  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
+  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+                    parser->m_bufferPtr, &parser->m_position);
   parser->m_positionPtr = parser->m_bufferPtr;
   return result;
 }
 
 void XMLCALL
-XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
-{
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
   if (parser == NULL)
     return;
   assert(status != NULL);
@@ -2199,26 +2113,24 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
 }
 
 enum XML_Error XMLCALL
-XML_GetErrorCode(XML_Parser parser)
-{
+XML_GetErrorCode(XML_Parser parser) {
   if (parser == NULL)
     return XML_ERROR_INVALID_ARGUMENT;
   return parser->m_errorCode;
 }
 
 XML_Index XMLCALL
-XML_GetCurrentByteIndex(XML_Parser parser)
-{
+XML_GetCurrentByteIndex(XML_Parser parser) {
   if (parser == NULL)
     return -1;
   if (parser->m_eventPtr)
-    return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr));
+    return (XML_Index)(parser->m_parseEndByteIndex
+                       - (parser->m_parseEndPtr - parser->m_eventPtr));
   return -1;
 }
 
 int XMLCALL
-XML_GetCurrentByteCount(XML_Parser parser)
-{
+XML_GetCurrentByteCount(XML_Parser parser) {
   if (parser == NULL)
     return 0;
   if (parser->m_eventEndPtr && parser->m_eventPtr)
@@ -2226,9 +2138,8 @@ XML_GetCurrentByteCount(XML_Parser parser)
   return 0;
 }
 
-const char * XMLCALL
-XML_GetInputContext(XML_Parser parser, int *offset, int *size)
-{
+const char *XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
 #ifdef XML_CONTEXT_BYTES
   if (parser == NULL)
     return NULL;
@@ -2236,7 +2147,7 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size)
     if (offset != NULL)
       *offset = (int)(parser->m_eventPtr - parser->m_buffer);
     if (size != NULL)
-      *size   = (int)(parser->m_bufferEnd - parser->m_buffer);
+      *size = (int)(parser->m_bufferEnd - parser->m_buffer);
     return parser->m_buffer;
   }
 #else
@@ -2244,82 +2155,76 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size)
   (void)offset;
   (void)size;
 #endif /* defined XML_CONTEXT_BYTES */
-  return (char *) 0;
+  return (char *)0;
 }
 
 XML_Size XMLCALL
-XML_GetCurrentLineNumber(XML_Parser parser)
-{
+XML_GetCurrentLineNumber(XML_Parser parser) {
   if (parser == NULL)
     return 0;
   if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
-    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
+    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+                      parser->m_eventPtr, &parser->m_position);
     parser->m_positionPtr = parser->m_eventPtr;
   }
   return parser->m_position.lineNumber + 1;
 }
 
 XML_Size XMLCALL
-XML_GetCurrentColumnNumber(XML_Parser parser)
-{
+XML_GetCurrentColumnNumber(XML_Parser parser) {
   if (parser == NULL)
     return 0;
   if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
-    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
+    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+                      parser->m_eventPtr, &parser->m_position);
     parser->m_positionPtr = parser->m_eventPtr;
   }
   return parser->m_position.columnNumber;
 }
 
 void XMLCALL
-XML_FreeContentModel(XML_Parser parser, XML_Content *model)
-{
+XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
   if (parser != NULL)
     FREE(parser, model);
 }
 
-void * XMLCALL
-XML_MemMalloc(XML_Parser parser, size_t size)
-{
+void *XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size) {
   if (parser == NULL)
     return NULL;
   return MALLOC(parser, size);
 }
 
-void * XMLCALL
-XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
-{
+void *XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
   if (parser == NULL)
     return NULL;
   return REALLOC(parser, ptr, size);
 }
 
 void XMLCALL
-XML_MemFree(XML_Parser parser, void *ptr)
-{
+XML_MemFree(XML_Parser parser, void *ptr) {
   if (parser != NULL)
     FREE(parser, ptr);
 }
 
 void XMLCALL
-XML_DefaultCurrent(XML_Parser parser)
-{
+XML_DefaultCurrent(XML_Parser parser) {
   if (parser == NULL)
     return;
   if (parser->m_defaultHandler) {
     if (parser->m_openInternalEntities)
-      reportDefault(parser,
-                    parser->m_internalEncoding,
+      reportDefault(parser, parser->m_internalEncoding,
                     parser->m_openInternalEntities->internalEventPtr,
                     parser->m_openInternalEntities->internalEventEndPtr);
     else
-      reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr);
+      reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
+                    parser->m_eventEndPtr);
   }
 }
 
-const XML_LChar * XMLCALL
-XML_ErrorString(enum XML_Error code)
-{
+const XML_LChar *XMLCALL
+XML_ErrorString(enum XML_Error code) {
   switch (code) {
   case XML_ERROR_NONE:
     return NULL;
@@ -2401,21 +2306,22 @@ XML_ErrorString(enum XML_Error code)
     return XML_L("cannot suspend in external parameter entity");
   /* Added in 2.0.0. */
   case XML_ERROR_RESERVED_PREFIX_XML:
-    return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name");
+    return XML_L(
+        "reserved prefix (xml) must not be undeclared or bound to another namespace name");
   case XML_ERROR_RESERVED_PREFIX_XMLNS:
     return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
   case XML_ERROR_RESERVED_NAMESPACE_URI:
-    return XML_L("prefix must not be bound to one of the reserved namespace names");
+    return XML_L(
+        "prefix must not be bound to one of the reserved namespace names");
   /* Added in 2.2.5. */
-  case XML_ERROR_INVALID_ARGUMENT:  /* Constant added in 2.2.1, already */
+  case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
     return XML_L("invalid argument");
   }
   return NULL;
 }
 
-const XML_LChar * XMLCALL
+const XML_LChar *XMLCALL
 XML_ExpatVersion(void) {
-
   /* V1 is used to string-ize the version number. However, it would
      string-ize the actual version macro *names* unless we get them
      substituted before being passed to V1. CPP is defined to expand
@@ -2424,8 +2330,8 @@ XML_ExpatVersion(void) {
      with the correct numerals. */
   /* ### I'm assuming cpp is portable in this respect... */
 
-#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
-#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
+#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
 
   return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
 
@@ -2434,8 +2340,7 @@ XML_ExpatVersion(void) {
 }
 
 XML_Expat_Version XMLCALL
-XML_ExpatVersionInfo(void)
-{
+XML_ExpatVersionInfo(void) {
   XML_Expat_Version version;
 
   version.major = XML_MAJOR_VERSION;
@@ -2445,41 +2350,39 @@ XML_ExpatVersionInfo(void)
   return version;
 }
 
-const XML_Feature * XMLCALL
-XML_GetFeatureList(void)
-{
-  static const XML_Feature features[] = {
-    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
-     sizeof(XML_Char)},
-    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
-     sizeof(XML_LChar)},
+const XML_Feature *XMLCALL
+XML_GetFeatureList(void) {
+  static const XML_Feature features[]
+      = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
+          sizeof(XML_Char)},
+         {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
+          sizeof(XML_LChar)},
 #ifdef XML_UNICODE
-    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
+         {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
 #endif
 #ifdef XML_UNICODE_WCHAR_T
-    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
+         {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
 #endif
 #ifdef XML_DTD
-    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
+         {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
 #endif
 #ifdef XML_CONTEXT_BYTES
-    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
-     XML_CONTEXT_BYTES},
+         {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
+          XML_CONTEXT_BYTES},
 #endif
 #ifdef XML_MIN_SIZE
-    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
+         {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
 #endif
 #ifdef XML_NS
-    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
+         {XML_FEATURE_NS, XML_L("XML_NS"), 0},
 #endif
 #ifdef XML_LARGE_SIZE
-    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
+         {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
 #endif
 #ifdef XML_ATTR_INFO
-    {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
+         {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
 #endif
-    {XML_FEATURE_END,              NULL, 0}
-  };
+         {XML_FEATURE_END, NULL, 0}};
 
   return features;
 }
@@ -2490,8 +2393,7 @@ XML_GetFeatureList(void)
    permanent location, since the parse buffer is about to be discarded.
 */
 static XML_Bool
-storeRawNames(XML_Parser parser)
-{
+storeRawNames(XML_Parser parser) {
   TAG *tag = parser->m_tagStack;
   while (tag) {
     int bufSize;
@@ -2521,8 +2423,8 @@ storeRawNames(XML_Parser parser)
          then update it as well, since it will always point into tag->buf
       */
       if (tag->name.localPart)
-        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
-                                                  (XML_Char *)tag->buf);
+        tag->name.localPart
+            = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
       tag->buf = temp;
       tag->bufEnd = temp + bufSize;
       rawNameBuf = temp + nameLen;
@@ -2535,26 +2437,21 @@ storeRawNames(XML_Parser parser)
 }
 
 static enum XML_Error PTRCALL
-contentProcessor(XML_Parser parser,
-                 const char *start,
-                 const char *end,
-                 const char **endPtr)
-{
-  enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end,
-                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+contentProcessor(XML_Parser parser, const char *start, const char *end,
+                 const char **endPtr) {
+  enum XML_Error result
+      = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
+                  (XML_Bool)! parser->m_parsingStatus.finalBuffer);
   if (result == XML_ERROR_NONE) {
-    if (!storeRawNames(parser))
+    if (! storeRawNames(parser))
       return XML_ERROR_NO_MEMORY;
   }
   return result;
 }
 
 static enum XML_Error PTRCALL
-externalEntityInitProcessor(XML_Parser parser,
-                            const char *start,
-                            const char *end,
-                            const char **endPtr)
-{
+externalEntityInitProcessor(XML_Parser parser, const char *start,
+                            const char *end, const char **endPtr) {
   enum XML_Error result = initializeEncoding(parser);
   if (result != XML_ERROR_NONE)
     return result;
@@ -2563,11 +2460,8 @@ externalEntityInitProcessor(XML_Parser parser,
 }
 
 static enum XML_Error PTRCALL
-externalEntityInitProcessor2(XML_Parser parser,
-                             const char *start,
-                             const char *end,
-                             const char **endPtr)
-{
+externalEntityInitProcessor2(XML_Parser parser, const char *start,
+                             const char *end, const char **endPtr) {
   const char *next = start; /* XmlContentTok doesn't always set the last arg */
   int tok = XmlContentTok(parser->m_encoding, start, end, &next);
   switch (tok) {
@@ -2577,21 +2471,21 @@ externalEntityInitProcessor2(XML_Parser parser,
        doContent (by detecting XML_TOK_NONE) without processing any xml text
        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
     */
-    if (next == end && !parser->m_parsingStatus.finalBuffer) {
+    if (next == end && ! parser->m_parsingStatus.finalBuffer) {
       *endPtr = next;
       return XML_ERROR_NONE;
     }
     start = next;
     break;
   case XML_TOK_PARTIAL:
-    if (!parser->m_parsingStatus.finalBuffer) {
+    if (! parser->m_parsingStatus.finalBuffer) {
       *endPtr = start;
       return XML_ERROR_NONE;
     }
     parser->m_eventPtr = start;
     return XML_ERROR_UNCLOSED_TOKEN;
   case XML_TOK_PARTIAL_CHAR:
-    if (!parser->m_parsingStatus.finalBuffer) {
+    if (! parser->m_parsingStatus.finalBuffer) {
       *endPtr = start;
       return XML_ERROR_NONE;
     }
@@ -2603,11 +2497,8 @@ externalEntityInitProcessor2(XML_Parser parser,
 }
 
 static enum XML_Error PTRCALL
-externalEntityInitProcessor3(XML_Parser parser,
-                             const char *start,
-                             const char *end,
-                             const char **endPtr)
-{
+externalEntityInitProcessor3(XML_Parser parser, const char *start,
+                             const char *end, const char **endPtr) {
   int tok;
   const char *next = start; /* XmlContentTok doesn't always set the last arg */
   parser->m_eventPtr = start;
@@ -2615,31 +2506,29 @@ externalEntityInitProcessor3(XML_Parser parser,
   parser->m_eventEndPtr = next;
 
   switch (tok) {
-  case XML_TOK_XML_DECL:
-    {
-      enum XML_Error result;
-      result = processXmlDecl(parser, 1, start, next);
-      if (result != XML_ERROR_NONE)
-        return result;
-      switch (parser->m_parsingStatus.parsing) {
-      case XML_SUSPENDED:
-        *endPtr = next;
-        return XML_ERROR_NONE;
-      case XML_FINISHED:
-        return XML_ERROR_ABORTED;
-      default:
-        start = next;
-      }
+  case XML_TOK_XML_DECL: {
+    enum XML_Error result;
+    result = processXmlDecl(parser, 1, start, next);
+    if (result != XML_ERROR_NONE)
+      return result;
+    switch (parser->m_parsingStatus.parsing) {
+    case XML_SUSPENDED:
+      *endPtr = next;
+      return XML_ERROR_NONE;
+    case XML_FINISHED:
+      return XML_ERROR_ABORTED;
+    default:
+      start = next;
     }
-    break;
+  } break;
   case XML_TOK_PARTIAL:
-    if (!parser->m_parsingStatus.finalBuffer) {
+    if (! parser->m_parsingStatus.finalBuffer) {
       *endPtr = start;
       return XML_ERROR_NONE;
     }
     return XML_ERROR_UNCLOSED_TOKEN;
   case XML_TOK_PARTIAL_CHAR:
-    if (!parser->m_parsingStatus.finalBuffer) {
+    if (! parser->m_parsingStatus.finalBuffer) {
       *endPtr = start;
       return XML_ERROR_NONE;
     }
@@ -2651,39 +2540,31 @@ externalEntityInitProcessor3(XML_Parser parser,
 }
 
 static enum XML_Error PTRCALL
-externalEntityContentProcessor(XML_Parser parser,
-                               const char *start,
-                               const char *end,
-                               const char **endPtr)
-{
-  enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end,
-                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+externalEntityContentProcessor(XML_Parser parser, const char *start,
+                               const char *end, const char **endPtr) {
+  enum XML_Error result
+      = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
+                  (XML_Bool)! parser->m_parsingStatus.finalBuffer);
   if (result == XML_ERROR_NONE) {
-    if (!storeRawNames(parser))
+    if (! storeRawNames(parser))
       return XML_ERROR_NO_MEMORY;
   }
   return result;
 }
 
 static enum XML_Error
-doContent(XML_Parser parser,
-          int startTagLevel,
-          const ENCODING *enc,
-          const char *s,
-          const char *end,
-          const char **nextPtr,
-          XML_Bool haveMore)
-{
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+          const char *s, const char *end, const char **nextPtr,
+          XML_Bool haveMore) {
   /* save one level of indirection */
-  DTD * const dtd = parser->m_dtd;
+  DTD *const dtd = parser->m_dtd;
 
   const char **eventPP;
   const char **eventEndPP;
   if (enc == parser->m_encoding) {
     eventPP = &parser->m_eventPtr;
     eventEndPP = &parser->m_eventEndPtr;
-  }
-  else {
+  } else {
     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
   }
@@ -2703,8 +2584,7 @@ doContent(XML_Parser parser,
       if (parser->m_characterDataHandler) {
         XML_Char c = 0xA;
         parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
-      }
-      else if (parser->m_defaultHandler)
+      } else if (parser->m_defaultHandler)
         reportDefault(parser, enc, s, end);
       /* We are at the end of the final buffer, should we check for
          XML_SUSPENDED, XML_FINISHED?
@@ -2742,185 +2622,178 @@ doContent(XML_Parser parser,
         return XML_ERROR_NONE;
       }
       return XML_ERROR_PARTIAL_CHAR;
-    case XML_TOK_ENTITY_REF:
-      {
-        const XML_Char *name;
-        ENTITY *entity;
-        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
-                                              s + enc->minBytesPerChar,
-                                              next - enc->minBytesPerChar);
-        if (ch) {
-          if (parser->m_characterDataHandler)
-            parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
-          else if (parser->m_defaultHandler)
-            reportDefault(parser, enc, s, next);
-          break;
-        }
-        name = poolStoreString(&dtd->pool, enc,
-                                s + enc->minBytesPerChar,
-                                next - enc->minBytesPerChar);
-        if (!name)
-          return XML_ERROR_NO_MEMORY;
-        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
-        poolDiscard(&dtd->pool);
-        /* First, determine if a check for an existing declaration is needed;
-           if yes, check that the entity exists, and that it is internal,
-           otherwise call the skipped entity or default handler.
-        */
-        if (!dtd->hasParamEntityRefs || dtd->standalone) {
-          if (!entity)
-            return XML_ERROR_UNDEFINED_ENTITY;
-          else if (!entity->is_internal)
-            return XML_ERROR_ENTITY_DECLARED_IN_PE;
-        }
-        else if (!entity) {
+    case XML_TOK_ENTITY_REF: {
+      const XML_Char *name;
+      ENTITY *entity;
+      XML_Char ch = (XML_Char)XmlPredefinedEntityName(
+          enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
+      if (ch) {
+        if (parser->m_characterDataHandler)
+          parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
+        else if (parser->m_defaultHandler)
+          reportDefault(parser, enc, s, next);
+        break;
+      }
+      name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+                             next - enc->minBytesPerChar);
+      if (! name)
+        return XML_ERROR_NO_MEMORY;
+      entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
+      poolDiscard(&dtd->pool);
+      /* First, determine if a check for an existing declaration is needed;
+         if yes, check that the entity exists, and that it is internal,
+         otherwise call the skipped entity or default handler.
+      */
+      if (! dtd->hasParamEntityRefs || dtd->standalone) {
+        if (! entity)
+          return XML_ERROR_UNDEFINED_ENTITY;
+        else if (! entity->is_internal)
+          return XML_ERROR_ENTITY_DECLARED_IN_PE;
+      } else if (! entity) {
+        if (parser->m_skippedEntityHandler)
+          parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
+        else if (parser->m_defaultHandler)
+          reportDefault(parser, enc, s, next);
+        break;
+      }
+      if (entity->open)
+        return XML_ERROR_RECURSIVE_ENTITY_REF;
+      if (entity->notation)
+        return XML_ERROR_BINARY_ENTITY_REF;
+      if (entity->textPtr) {
+        enum XML_Error result;
+        if (! parser->m_defaultExpandInternalEntities) {
           if (parser->m_skippedEntityHandler)
-            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
+            parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
+                                           0);
           else if (parser->m_defaultHandler)
             reportDefault(parser, enc, s, next);
           break;
         }
-        if (entity->open)
-          return XML_ERROR_RECURSIVE_ENTITY_REF;
-        if (entity->notation)
-          return XML_ERROR_BINARY_ENTITY_REF;
-        if (entity->textPtr) {
-          enum XML_Error result;
-          if (!parser->m_defaultExpandInternalEntities) {
-            if (parser->m_skippedEntityHandler)
-              parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0);
-            else if (parser->m_defaultHandler)
-              reportDefault(parser, enc, s, next);
-            break;
-          }
-          result = processInternalEntity(parser, entity, XML_FALSE);
-          if (result != XML_ERROR_NONE)
-            return result;
-        }
-        else if (parser->m_externalEntityRefHandler) {
-          const XML_Char *context;
-          entity->open = XML_TRUE;
-          context = getContext(parser);
-          entity->open = XML_FALSE;
-          if (!context)
-            return XML_ERROR_NO_MEMORY;
-          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
-                                        context,
-                                        entity->base,
-                                        entity->systemId,
-                                        entity->publicId))
-            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-          poolDiscard(&parser->m_tempPool);
-        }
-        else if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-        break;
-      }
+        result = processInternalEntity(parser, entity, XML_FALSE);
+        if (result != XML_ERROR_NONE)
+          return result;
+      } else if (parser->m_externalEntityRefHandler) {
+        const XML_Char *context;
+        entity->open = XML_TRUE;
+        context = getContext(parser);
+        entity->open = XML_FALSE;
+        if (! context)
+          return XML_ERROR_NO_MEMORY;
+        if (! parser->m_externalEntityRefHandler(
+                parser->m_externalEntityRefHandlerArg, context, entity->base,
+                entity->systemId, entity->publicId))
+          return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+        poolDiscard(&parser->m_tempPool);
+      } else if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+      break;
+    }
     case XML_TOK_START_TAG_NO_ATTS:
       /* fall through */
-    case XML_TOK_START_TAG_WITH_ATTS:
-      {
-        TAG *tag;
-        enum XML_Error result;
-        XML_Char *toPtr;
-        if (parser->m_freeTagList) {
-          tag = parser->m_freeTagList;
-          parser->m_freeTagList = parser->m_freeTagList->parent;
+    case XML_TOK_START_TAG_WITH_ATTS: {
+      TAG *tag;
+      enum XML_Error result;
+      XML_Char *toPtr;
+      if (parser->m_freeTagList) {
+        tag = parser->m_freeTagList;
+        parser->m_freeTagList = parser->m_freeTagList->parent;
+      } else {
+        tag = (TAG *)MALLOC(parser, sizeof(TAG));
+        if (! tag)
+          return XML_ERROR_NO_MEMORY;
+        tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
+        if (! tag->buf) {
+          FREE(parser, tag);
+          return XML_ERROR_NO_MEMORY;
         }
-        else {
-          tag = (TAG *)MALLOC(parser, sizeof(TAG));
-          if (!tag)
-            return XML_ERROR_NO_MEMORY;
-          tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
-          if (!tag->buf) {
-            FREE(parser, tag);
-            return XML_ERROR_NO_MEMORY;
+        tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+      }
+      tag->bindings = NULL;
+      tag->parent = parser->m_tagStack;
+      parser->m_tagStack = tag;
+      tag->name.localPart = NULL;
+      tag->name.prefix = NULL;
+      tag->rawName = s + enc->minBytesPerChar;
+      tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+      ++parser->m_tagLevel;
+      {
+        const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+        const char *fromPtr = tag->rawName;
+        toPtr = (XML_Char *)tag->buf;
+        for (;;) {
+          int bufSize;
+          int convLen;
+          const enum XML_Convert_Result convert_res
+              = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
+                           (ICHAR *)tag->bufEnd - 1);
+          convLen = (int)(toPtr - (XML_Char *)tag->buf);
+          if ((fromPtr >= rawNameEnd)
+              || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
+            tag->name.strLen = convLen;
+            break;
           }
-          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
-        }
-        tag->bindings = NULL;
-        tag->parent = parser->m_tagStack;
-        parser->m_tagStack = tag;
-        tag->name.localPart = NULL;
-        tag->name.prefix = NULL;
-        tag->rawName = s + enc->minBytesPerChar;
-        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
-        ++parser->m_tagLevel;
-        {
-          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
-          const char *fromPtr = tag->rawName;
-          toPtr = (XML_Char *)tag->buf;
-          for (;;) {
-            int bufSize;
-            int convLen;
-            const enum XML_Convert_Result convert_res = XmlConvert(enc,
-                       &fromPtr, rawNameEnd,
-                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
-            convLen = (int)(toPtr - (XML_Char *)tag->buf);
-            if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
-              tag->name.strLen = convLen;
-              break;
-            }
-            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
-            {
-              char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
-              if (temp == NULL)
-                return XML_ERROR_NO_MEMORY;
-              tag->buf = temp;
-              tag->bufEnd = temp + bufSize;
-              toPtr = (XML_Char *)temp + convLen;
-            }
+          bufSize = (int)(tag->bufEnd - tag->buf) << 1;
+          {
+            char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
+            if (temp == NULL)
+              return XML_ERROR_NO_MEMORY;
+            tag->buf = temp;
+            tag->bufEnd = temp + bufSize;
+            toPtr = (XML_Char *)temp + convLen;
           }
         }
-        tag->name.str = (XML_Char *)tag->buf;
-        *toPtr = XML_T('\0');
-        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
-        if (result)
-          return result;
-        if (parser->m_startElementHandler)
-          parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
-                              (const XML_Char **)parser->m_atts);
-        else if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-        poolClear(&parser->m_tempPool);
-        break;
       }
+      tag->name.str = (XML_Char *)tag->buf;
+      *toPtr = XML_T('\0');
+      result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+      if (result)
+        return result;
+      if (parser->m_startElementHandler)
+        parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
+                                      (const XML_Char **)parser->m_atts);
+      else if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+      poolClear(&parser->m_tempPool);
+      break;
+    }
     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
       /* fall through */
-    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
-      {
-        const char *rawName = s + enc->minBytesPerChar;
-        enum XML_Error result;
-        BINDING *bindings = NULL;
-        XML_Bool noElmHandlers = XML_TRUE;
-        TAG_NAME name;
-        name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
-                                   rawName + XmlNameLength(enc, rawName));
-        if (!name.str)
-          return XML_ERROR_NO_MEMORY;
-        poolFinish(&parser->m_tempPool);
-        result = storeAtts(parser, enc, s, &name, &bindings);
-        if (result != XML_ERROR_NONE) {
-          freeBindings(parser, bindings);
-          return result;
-        }
-        poolFinish(&parser->m_tempPool);
-        if (parser->m_startElementHandler) {
-          parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts);
-          noElmHandlers = XML_FALSE;
-        }
-        if (parser->m_endElementHandler) {
-          if (parser->m_startElementHandler)
-            *eventPP = *eventEndPP;
-          parser->m_endElementHandler(parser->m_handlerArg, name.str);
-          noElmHandlers = XML_FALSE;
-        }
-        if (noElmHandlers && parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-        poolClear(&parser->m_tempPool);
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
+      const char *rawName = s + enc->minBytesPerChar;
+      enum XML_Error result;
+      BINDING *bindings = NULL;
+      XML_Bool noElmHandlers = XML_TRUE;
+      TAG_NAME name;
+      name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
+                                 rawName + XmlNameLength(enc, rawName));
+      if (! name.str)
+        return XML_ERROR_NO_MEMORY;
+      poolFinish(&parser->m_tempPool);
+      result = storeAtts(parser, enc, s, &name, &bindings);
+      if (result != XML_ERROR_NONE) {
         freeBindings(parser, bindings);
+        return result;
+      }
+      poolFinish(&parser->m_tempPool);
+      if (parser->m_startElementHandler) {
+        parser->m_startElementHandler(parser->m_handlerArg, name.str,
+                                      (const XML_Char **)parser->m_atts);
+        noElmHandlers = XML_FALSE;
+      }
+      if (parser->m_endElementHandler) {
+        if (parser->m_startElementHandler)
+          *eventPP = *eventEndPP;
+        parser->m_endElementHandler(parser->m_handlerArg, name.str);
+        noElmHandlers = XML_FALSE;
       }
-      if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
+      if (noElmHandlers && parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+      poolClear(&parser->m_tempPool);
+      freeBindings(parser, bindings);
+    }
+      if ((parser->m_tagLevel == 0)
+          && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
         if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
           parser->m_processor = epilogProcessor;
         else
@@ -2937,7 +2810,7 @@ doContent(XML_Parser parser,
         parser->m_tagStack = tag->parent;
         tag->parent = parser->m_freeTagList;
         parser->m_freeTagList = tag;
-        rawName = s + enc->minBytesPerChar*2;
+        rawName = s + enc->minBytesPerChar * 2;
         len = XmlNameLength(enc, rawName);
         if (len != tag->rawNameLength
             || memcmp(tag->rawName, rawName, len) != 0) {
@@ -2957,86 +2830,89 @@ doContent(XML_Parser parser,
             */
             uri = (XML_Char *)tag->name.str + tag->name.uriLen;
             /* don't need to check for space - already done in storeAtts() */
-            while (*localPart) *uri++ = *localPart++;
+            while (*localPart)
+              *uri++ = *localPart++;
             prefix = (XML_Char *)tag->name.prefix;
             if (parser->m_ns_triplets && prefix) {
               *uri++ = parser->m_namespaceSeparator;
-              while (*prefix) *uri++ = *prefix++;
-             }
+              while (*prefix)
+                *uri++ = *prefix++;
+            }
             *uri = XML_T('\0');
           }
           parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
-        }
-        else if (parser->m_defaultHandler)
+        } else if (parser->m_defaultHandler)
           reportDefault(parser, enc, s, next);
         while (tag->bindings) {
           BINDING *b = tag->bindings;
           if (parser->m_endNamespaceDeclHandler)
-            parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
+            parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
+                                              b->prefix->name);
           tag->bindings = tag->bindings->nextTagBinding;
           b->nextTagBinding = parser->m_freeBindingList;
           parser->m_freeBindingList = b;
           b->prefix->binding = b->prevPrefixBinding;
         }
-        if (parser->m_tagLevel == 0)
-          return epilogProcessor(parser, next, end, nextPtr);
-      }
-      break;
-    case XML_TOK_CHAR_REF:
-      {
-        int n = XmlCharRefNumber(enc, s);
-        if (n < 0)
-          return XML_ERROR_BAD_CHAR_REF;
-        if (parser->m_characterDataHandler) {
-          XML_Char buf[XML_ENCODE_MAX];
-          parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+        if ((parser->m_tagLevel == 0)
+            && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
+          if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
+            parser->m_processor = epilogProcessor;
+          else
+            return epilogProcessor(parser, next, end, nextPtr);
         }
-        else if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
       }
       break;
+    case XML_TOK_CHAR_REF: {
+      int n = XmlCharRefNumber(enc, s);
+      if (n < 0)
+        return XML_ERROR_BAD_CHAR_REF;
+      if (parser->m_characterDataHandler) {
+        XML_Char buf[XML_ENCODE_MAX];
+        parser->m_characterDataHandler(parser->m_handlerArg, buf,
+                                       XmlEncode(n, (ICHAR *)buf));
+      } else if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+    } break;
     case XML_TOK_XML_DECL:
       return XML_ERROR_MISPLACED_XML_PI;
     case XML_TOK_DATA_NEWLINE:
       if (parser->m_characterDataHandler) {
         XML_Char c = 0xA;
         parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
-      }
-      else if (parser->m_defaultHandler)
+      } else if (parser->m_defaultHandler)
         reportDefault(parser, enc, s, next);
       break;
-    case XML_TOK_CDATA_SECT_OPEN:
-      {
-        enum XML_Error result;
-        if (parser->m_startCdataSectionHandler)
-          parser->m_startCdataSectionHandler(parser->m_handlerArg);
-/* BEGIN disabled code */
-        /* Suppose you doing a transformation on a document that involves
-           changing only the character data.  You set up a defaultHandler
-           and a characterDataHandler.  The defaultHandler simply copies
-           characters through.  The characterDataHandler does the
-           transformation and writes the characters out escaping them as
-           necessary.  This case will fail to work if we leave out the
-           following two lines (because & and < inside CDATA sections will
-           be incorrectly escaped).
-
-           However, now we have a start/endCdataSectionHandler, so it seems
-           easier to let the user deal with this.
-        */
-        else if (0 && parser->m_characterDataHandler)
-          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
-/* END disabled code */
-        else if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
-        if (result != XML_ERROR_NONE)
-          return result;
-        else if (!next) {
-          parser->m_processor = cdataSectionProcessor;
-          return result;
-        }
+    case XML_TOK_CDATA_SECT_OPEN: {
+      enum XML_Error result;
+      if (parser->m_startCdataSectionHandler)
+        parser->m_startCdataSectionHandler(parser->m_handlerArg);
+      /* BEGIN disabled code */
+      /* Suppose you doing a transformation on a document that involves
+         changing only the character data.  You set up a defaultHandler
+         and a characterDataHandler.  The defaultHandler simply copies
+         characters through.  The characterDataHandler does the
+         transformation and writes the characters out escaping them as
+         necessary.  This case will fail to work if we leave out the
+         following two lines (because & and < inside CDATA sections will
+         be incorrectly escaped).
+
+         However, now we have a start/endCdataSectionHandler, so it seems
+         easier to let the user deal with this.
+      */
+      else if (0 && parser->m_characterDataHandler)
+        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+                                       0);
+      /* END disabled code */
+      else if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+      result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
+      if (result != XML_ERROR_NONE)
+        return result;
+      else if (! next) {
+        parser->m_processor = cdataSectionProcessor;
+        return result;
       }
-      break;
+    } break;
     case XML_TOK_TRAILING_RSQB:
       if (haveMore) {
         *nextPtr = s;
@@ -3046,15 +2922,14 @@ doContent(XML_Parser parser,
         if (MUST_CONVERT(enc, s)) {
           ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
-          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
-                               (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
-        }
-        else
-          parser->m_characterDataHandler(parser->m_handlerArg,
-                               (XML_Char *)s,
-                               (int)((XML_Char *)end - (XML_Char *)s));
-      }
-      else if (parser->m_defaultHandler)
+          parser->m_characterDataHandler(
+              parser->m_handlerArg, parser->m_dataBuf,
+              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+        } else
+          parser->m_characterDataHandler(
+              parser->m_handlerArg, (XML_Char *)s,
+              (int)((XML_Char *)end - (XML_Char *)s));
+      } else if (parser->m_defaultHandler)
         reportDefault(parser, enc, s, end);
       /* We are at the end of the final buffer, should we check for
          XML_SUSPENDED, XML_FINISHED?
@@ -3069,37 +2944,34 @@ doContent(XML_Parser parser,
       }
       *nextPtr = end;
       return XML_ERROR_NONE;
-    case XML_TOK_DATA_CHARS:
-      {
-        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
-        if (charDataHandler) {
-          if (MUST_CONVERT(enc, s)) {
-            for (;;) {
-              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
-              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
-              *eventEndPP = s;
-              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
-                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
-              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
-                break;
-              *eventPP = s;
-            }
+    case XML_TOK_DATA_CHARS: {
+      XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
+      if (charDataHandler) {
+        if (MUST_CONVERT(enc, s)) {
+          for (;;) {
+            ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
+            const enum XML_Convert_Result convert_res = XmlConvert(
+                enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
+            *eventEndPP = s;
+            charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+                            (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+            if ((convert_res == XML_CONVERT_COMPLETED)
+                || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+              break;
+            *eventPP = s;
           }
-          else
-            charDataHandler(parser->m_handlerArg,
-                            (XML_Char *)s,
-                            (int)((XML_Char *)next - (XML_Char *)s));
-        }
-        else if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-      }
-      break;
+        } else
+          charDataHandler(parser->m_handlerArg, (XML_Char *)s,
+                          (int)((XML_Char *)next - (XML_Char *)s));
+      } else if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+    } break;
     case XML_TOK_PI:
-      if (!reportProcessingInstruction(parser, enc, s, next))
+      if (! reportProcessingInstruction(parser, enc, s, next))
         return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_COMMENT:
-      if (!reportComment(parser, enc, s, next))
+      if (! reportComment(parser, enc, s, next))
         return XML_ERROR_NO_MEMORY;
       break;
     default:
@@ -3122,7 +2994,7 @@ doContent(XML_Parser parser,
       return XML_ERROR_NONE;
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
-    default: ;
+    default:;
     }
   }
   /* not reached */
@@ -3133,8 +3005,7 @@ doContent(XML_Parser parser,
  * reused as appropriate.
  */
 static void
-freeBindings(XML_Parser parser, BINDING *bindings)
-{
+freeBindings(XML_Parser parser, BINDING *bindings) {
   while (bindings) {
     BINDING *b = bindings;
 
@@ -3142,7 +3013,7 @@ freeBindings(XML_Parser parser, BINDING *bindings)
      * binding in addBindings(), so call the end handler now.
      */
     if (parser->m_endNamespaceDeclHandler)
-        parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
+      parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
 
     bindings = bindings->nextTagBinding;
     b->nextTagBinding = parser->m_freeBindingList;
@@ -3162,14 +3033,12 @@ freeBindings(XML_Parser parser, BINDING *bindings)
    - generate namespace aware element name (URI, prefix)
 */
 static enum XML_Error
-storeAtts(XML_Parser parser, const ENCODING *enc,
-          const char *attStr, TAG_NAME *tagNamePtr,
-          BINDING **bindingsPtr)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+          TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   ELEMENT_TYPE *elementType;
   int nDefaultAtts;
-  const XML_Char **appAtts;   /* the attribute list for the application */
+  const XML_Char **appAtts; /* the attribute list for the application */
   int attIndex = 0;
   int prefixLen;
   int i;
@@ -3180,16 +3049,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
   const XML_Char *localPart;
 
   /* lookup the element type name */
-  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
-  if (!elementType) {
+  elementType
+      = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
+  if (! elementType) {
     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
-    if (!name)
+    if (! name)
       return XML_ERROR_NO_MEMORY;
     elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
                                          sizeof(ELEMENT_TYPE));
-    if (!elementType)
+    if (! elementType)
       return XML_ERROR_NO_MEMORY;
-    if (parser->m_ns && !setElementTypePrefix(parser, elementType))
+    if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
       return XML_ERROR_NO_MEMORY;
   }
   nDefaultAtts = elementType->nDefaultAtts;
@@ -3203,14 +3073,16 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
     XML_AttrInfo *temp2;
 #endif
     parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
-    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE));
+    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
+                                parser->m_attsSize * sizeof(ATTRIBUTE));
     if (temp == NULL) {
       parser->m_attsSize = oldAttsSize;
       return XML_ERROR_NO_MEMORY;
     }
     parser->m_atts = temp;
 #ifdef XML_ATTR_INFO
-    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
+    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
+                                    parser->m_attsSize * sizeof(XML_AttrInfo));
     if (temp2 == NULL) {
       parser->m_attsSize = oldAttsSize;
       return XML_ERROR_NO_MEMORY;
@@ -3228,18 +3100,20 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
     XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
 #endif
     /* add the name and value to the attribute list */
-    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
-                                         currAtt->name
-                                         + XmlNameLength(enc, currAtt->name));
-    if (!attId)
+    ATTRIBUTE_ID *attId
+        = getAttributeId(parser, enc, currAtt->name,
+                         currAtt->name + XmlNameLength(enc, currAtt->name));
+    if (! attId)
       return XML_ERROR_NO_MEMORY;
 #ifdef XML_ATTR_INFO
-    currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
-    currAttInfo->nameEnd = currAttInfo->nameStart +
-                           XmlNameLength(enc, currAtt->name);
-    currAttInfo->valueStart = parser->m_parseEndByteIndex -
-                            (parser->m_parseEndPtr - currAtt->valuePtr);
-    currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd);
+    currAttInfo->nameStart
+        = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
+    currAttInfo->nameEnd
+        = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
+    currAttInfo->valueStart = parser->m_parseEndByteIndex
+                              - (parser->m_parseEndPtr - currAtt->valuePtr);
+    currAttInfo->valueEnd = parser->m_parseEndByteIndex
+                            - (parser->m_parseEndPtr - currAtt->valueEnd);
 #endif
     /* Detect duplicate attributes by their QNames. This does not work when
        namespace processing is turned on and different prefixes for the same
@@ -3252,7 +3126,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
     }
     (attId->name)[-1] = 1;
     appAtts[attIndex++] = attId->name;
-    if (!parser->m_atts[i].normalized) {
+    if (! parser->m_atts[i].normalized) {
       enum XML_Error result;
       XML_Bool isCdata = XML_TRUE;
 
@@ -3268,17 +3142,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
       }
 
       /* normalize the attribute value */
-      result = storeAttributeValue(parser, enc, isCdata,
-                                   parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd,
-                                   &parser->m_tempPool);
+      result = storeAttributeValue(
+          parser, enc, isCdata, parser->m_atts[i].valuePtr,
+          parser->m_atts[i].valueEnd, &parser->m_tempPool);
       if (result)
         return result;
       appAtts[attIndex] = poolStart(&parser->m_tempPool);
       poolFinish(&parser->m_tempPool);
-    }
-    else {
+    } else {
       /* the value did not need normalizing */
-      appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr,
+      appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
+                                          parser->m_atts[i].valuePtr,
                                           parser->m_atts[i].valueEnd);
       if (appAtts[attIndex] == 0)
         return XML_ERROR_NO_MEMORY;
@@ -3293,15 +3167,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
         if (result)
           return result;
         --attIndex;
-      }
-      else {
+      } else {
         /* deal with other prefixed names later */
         attIndex++;
         nPrefixes++;
         (attId->name)[-1] = 2;
       }
-    }
-    else
+    } else
       attIndex++;
   }
 
@@ -3313,29 +3185,26 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
         parser->m_idAttIndex = i;
         break;
       }
-  }
-  else
+  } else
     parser->m_idAttIndex = -1;
 
   /* do attribute defaulting */
   for (i = 0; i < nDefaultAtts; i++) {
     const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
-    if (!(da->id->name)[-1] && da->value) {
+    if (! (da->id->name)[-1] && da->value) {
       if (da->id->prefix) {
         if (da->id->xmlns) {
           enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
                                              da->value, bindingsPtr);
           if (result)
             return result;
-        }
-        else {
+        } else {
           (da->id->name)[-1] = 2;
           nPrefixes++;
           appAtts[attIndex++] = da->id->name;
           appAtts[attIndex++] = da->value;
         }
-      }
-      else {
+      } else {
         (da->id->name)[-1] = 1;
         appAtts[attIndex++] = da->id->name;
         appAtts[attIndex++] = da->value;
@@ -3348,31 +3217,34 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
      and clear flags that say whether attributes were specified */
   i = 0;
   if (nPrefixes) {
-    int j;  /* hash table index */
+    int j; /* hash table index */
     unsigned long version = parser->m_nsAttsVersion;
     int nsAttsSize = (int)1 << parser->m_nsAttsPower;
     unsigned char oldNsAttsPower = parser->m_nsAttsPower;
     /* size of hash table must be at least 2 * (# of prefixed attributes) */
-    if ((nPrefixes << 1) >> parser->m_nsAttsPower) {  /* true for m_nsAttsPower = 0 */
+    if ((nPrefixes << 1)
+        >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
       NS_ATT *temp;
       /* hash table size must also be a power of 2 and >= 8 */
-      while (nPrefixes >> parser->m_nsAttsPower++);
+      while (nPrefixes >> parser->m_nsAttsPower++)
+        ;
       if (parser->m_nsAttsPower < 3)
         parser->m_nsAttsPower = 3;
       nsAttsSize = (int)1 << parser->m_nsAttsPower;
-      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT));
-      if (!temp) {
+      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
+                               nsAttsSize * sizeof(NS_ATT));
+      if (! temp) {
         /* Restore actual size of memory in m_nsAtts */
         parser->m_nsAttsPower = oldNsAttsPower;
         return XML_ERROR_NO_MEMORY;
       }
       parser->m_nsAtts = temp;
-      version = 0;  /* force re-initialization of m_nsAtts hash table */
+      version = 0; /* force re-initialization of m_nsAtts hash table */
     }
     /* using a version flag saves us from initializing m_nsAtts every time */
-    if (!version) {  /* initialize version flags when version wraps around */
+    if (! version) { /* initialize version flags when version wraps around */
       version = INIT_ATTS_VERSION;
-      for (j = nsAttsSize; j != 0; )
+      for (j = nsAttsSize; j != 0;)
         parser->m_nsAtts[--j].version = version;
     }
     parser->m_nsAttsVersion = --version;
@@ -3380,7 +3252,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
     /* expand prefixed names and check for duplicates */
     for (; i < attIndex; i += 2) {
       const XML_Char *s = appAtts[i];
-      if (s[-1] == 2) {  /* prefixed */
+      if (s[-1] == 2) { /* prefixed */
         ATTRIBUTE_ID *id;
         const BINDING *b;
         unsigned long uriHash;
@@ -3390,9 +3262,9 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
         copy_salt_to_sipkey(parser, &sip_key);
         sip24_init(&sip_state, &sip_key);
 
-        ((XML_Char *)s)[-1] = 0;  /* clear flag */
+        ((XML_Char *)s)[-1] = 0; /* clear flag */
         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
-        if (!id || !id->prefix) {
+        if (! id || ! id->prefix) {
           /* This code is walking through the appAtts array, dealing
            * with (in this case) a prefixed attribute name.  To be in
            * the array, the attribute must have already been bound, so
@@ -3410,12 +3282,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
           return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
         }
         b = id->prefix->binding;
-        if (!b)
+        if (! b)
           return XML_ERROR_UNBOUND_PREFIX;
 
         for (j = 0; j < b->uriLen; j++) {
           const XML_Char c = b->uri[j];
-          if (!poolAppendChar(&parser->m_tempPool, c))
+          if (! poolAppendChar(&parser->m_tempPool, c))
             return XML_ERROR_NO_MEMORY;
         }
 
@@ -3426,8 +3298,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
 
         sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
 
-        do {  /* copies null terminator */
-          if (!poolAppendChar(&parser->m_tempPool, *s))
+        do { /* copies null terminator */
+          if (! poolAppendChar(&parser->m_tempPool, *s))
             return XML_ERROR_NO_MEMORY;
         } while (*s++);
 
@@ -3438,28 +3310,29 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
           */
           unsigned char step = 0;
           unsigned long mask = nsAttsSize - 1;
-          j = uriHash & mask;  /* index into hash table */
+          j = uriHash & mask; /* index into hash table */
           while (parser->m_nsAtts[j].version == version) {
             /* for speed we compare stored hash values first */
             if (uriHash == parser->m_nsAtts[j].hash) {
               const XML_Char *s1 = poolStart(&parser->m_tempPool);
               const XML_Char *s2 = parser->m_nsAtts[j].uriName;
               /* s1 is null terminated, but not s2 */
-              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+              for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
+                ;
               if (*s1 == 0)
                 return XML_ERROR_DUPLICATE_ATTRIBUTE;
             }
-            if (!step)
+            if (! step)
               step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
             j < step ? (j += nsAttsSize - step) : (j -= step);
           }
         }
 
-        if (parser->m_ns_triplets) {  /* append namespace separator and prefix */
+        if (parser->m_ns_triplets) { /* append namespace separator and prefix */
           parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
           s = b->prefix->name;
           do {
-            if (!poolAppendChar(&parser->m_tempPool, *s))
+            if (! poolAppendChar(&parser->m_tempPool, *s))
               return XML_ERROR_NO_MEMORY;
           } while (*s++);
         }
@@ -3474,13 +3347,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
         parser->m_nsAtts[j].hash = uriHash;
         parser->m_nsAtts[j].uriName = s;
 
-        if (!--nPrefixes) {
+        if (! --nPrefixes) {
           i += 2;
           break;
         }
-      }
-      else  /* not prefixed */
-        ((XML_Char *)s)[-1] = 0;  /* clear flag */
+      } else                     /* not prefixed */
+        ((XML_Char *)s)[-1] = 0; /* clear flag */
     }
   }
   /* clear flags for the remaining attributes */
@@ -3489,40 +3361,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
     binding->attId->name[-1] = 0;
 
-  if (!parser->m_ns)
+  if (! parser->m_ns)
     return XML_ERROR_NONE;
 
   /* expand the element type name */
   if (elementType->prefix) {
     binding = elementType->prefix->binding;
-    if (!binding)
+    if (! binding)
       return XML_ERROR_UNBOUND_PREFIX;
     localPart = tagNamePtr->str;
     while (*localPart++ != XML_T(ASCII_COLON))
       ;
-  }
-  else if (dtd->defaultPrefix.binding) {
+  } else if (dtd->defaultPrefix.binding) {
     binding = dtd->defaultPrefix.binding;
     localPart = tagNamePtr->str;
-  }
-  else
+  } else
     return XML_ERROR_NONE;
   prefixLen = 0;
   if (parser->m_ns_triplets && binding->prefix->name) {
     for (; binding->prefix->name[prefixLen++];)
-      ;  /* prefixLen includes null terminator */
+      ; /* prefixLen includes null terminator */
   }
   tagNamePtr->localPart = localPart;
   tagNamePtr->uriLen = binding->uriLen;
   tagNamePtr->prefix = binding->prefix->name;
   tagNamePtr->prefixLen = prefixLen;
   for (i = 0; localPart[i++];)
-    ;  /* i includes null terminator */
+    ; /* i includes null terminator */
   n = i + binding->uriLen + prefixLen;
   if (n > binding->uriAlloc) {
     TAG *p;
     uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
-    if (!uri)
+    if (! uri)
       return XML_ERROR_NO_MEMORY;
     binding->uriAlloc = n + EXPAND_SPARE;
     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
@@ -3538,7 +3408,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
   /* we always have a namespace separator between localPart and prefix */
   if (prefixLen) {
     uri += i - 1;
-    *uri = parser->m_namespaceSeparator;  /* replace null terminator */
+    *uri = parser->m_namespaceSeparator; /* replace null terminator */
     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
   }
   tagNamePtr->str = binding->uri;
@@ -3550,27 +3420,25 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
 */
 static enum XML_Error
 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
-           const XML_Char *uri, BINDING **bindingsPtr)
-{
-  static const XML_Char xmlNamespace[] = {
-    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
-    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
-    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
-    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
-    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
-    ASCII_e, '\0'
-  };
-  static const int xmlLen =
-    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
-  static const XML_Char xmlnsNamespace[] = {
-    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
-    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
-    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
-    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
-    ASCII_SLASH, '\0'
-  };
-  static const int xmlnsLen =
-    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
+           const XML_Char *uri, BINDING **bindingsPtr) {
+  static const XML_Char xmlNamespace[]
+      = {ASCII_h,      ASCII_t,     ASCII_t,     ASCII_p,      ASCII_COLON,
+         ASCII_SLASH,  ASCII_SLASH, ASCII_w,     ASCII_w,      ASCII_w,
+         ASCII_PERIOD, ASCII_w,     ASCII_3,     ASCII_PERIOD, ASCII_o,
+         ASCII_r,      ASCII_g,     ASCII_SLASH, ASCII_X,      ASCII_M,
+         ASCII_L,      ASCII_SLASH, ASCII_1,     ASCII_9,      ASCII_9,
+         ASCII_8,      ASCII_SLASH, ASCII_n,     ASCII_a,      ASCII_m,
+         ASCII_e,      ASCII_s,     ASCII_p,     ASCII_a,      ASCII_c,
+         ASCII_e,      '\0'};
+  static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
+  static const XML_Char xmlnsNamespace[]
+      = {ASCII_h,     ASCII_t,      ASCII_t, ASCII_p, ASCII_COLON,  ASCII_SLASH,
+         ASCII_SLASH, ASCII_w,      ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
+         ASCII_3,     ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,      ASCII_SLASH,
+         ASCII_2,     ASCII_0,      ASCII_0, ASCII_0, ASCII_SLASH,  ASCII_x,
+         ASCII_m,     ASCII_l,      ASCII_n, ASCII_s, ASCII_SLASH,  '\0'};
+  static const int xmlnsLen
+      = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
 
   XML_Bool mustBeXML = XML_FALSE;
   XML_Bool isXML = XML_TRUE;
@@ -3583,14 +3451,11 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   if (*uri == XML_T('\0') && prefix->name)
     return XML_ERROR_UNDECLARING_PREFIX;
 
-  if (prefix->name
-      && prefix->name[0] == XML_T(ASCII_x)
+  if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
       && prefix->name[1] == XML_T(ASCII_m)
       && prefix->name[2] == XML_T(ASCII_l)) {
-
     /* Not allowed to bind xmlns */
-    if (prefix->name[3] == XML_T(ASCII_n)
-        && prefix->name[4] == XML_T(ASCII_s)
+    if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s)
         && prefix->name[5] == XML_T('\0'))
       return XML_ERROR_RESERVED_PREFIX_XMLNS;
 
@@ -3602,7 +3467,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
       isXML = XML_FALSE;
 
-    if (!mustBeXML && isXMLNS
+    if (! mustBeXML && isXMLNS
         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
       isXMLNS = XML_FALSE;
   }
@@ -3621,21 +3486,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   if (parser->m_freeBindingList) {
     b = parser->m_freeBindingList;
     if (len > b->uriAlloc) {
-      XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri,
-                          sizeof(XML_Char) * (len + EXPAND_SPARE));
+      XML_Char *temp = (XML_Char *)REALLOC(
+          parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
       if (temp == NULL)
         return XML_ERROR_NO_MEMORY;
       b->uri = temp;
       b->uriAlloc = len + EXPAND_SPARE;
     }
     parser->m_freeBindingList = b->nextTagBinding;
-  }
-  else {
+  } else {
     b = (BINDING *)MALLOC(parser, sizeof(BINDING));
-    if (!b)
+    if (! b)
       return XML_ERROR_NO_MEMORY;
-    b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
-    if (!b->uri) {
+    b->uri
+        = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
+    if (! b->uri) {
       FREE(parser, b);
       return XML_ERROR_NO_MEMORY;
     }
@@ -3658,7 +3523,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   /* if attId == NULL then we are not starting a namespace scope */
   if (attId && parser->m_startNamespaceDeclHandler)
     parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
-                              prefix->binding ? uri : 0);
+                                        prefix->binding ? uri : 0);
   return XML_ERROR_NONE;
 }
 
@@ -3666,21 +3531,18 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
    the whole file is parsed with one call.
 */
 static enum XML_Error PTRCALL
-cdataSectionProcessor(XML_Parser parser,
-                      const char *start,
-                      const char *end,
-                      const char **endPtr)
-{
-  enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end,
-                                         endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
+                      const char **endPtr) {
+  enum XML_Error result
+      = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
+                       (XML_Bool)! parser->m_parsingStatus.finalBuffer);
   if (result != XML_ERROR_NONE)
     return result;
   if (start) {
-    if (parser->m_parentParser) {  /* we are parsing an external entity */
+    if (parser->m_parentParser) { /* we are parsing an external entity */
       parser->m_processor = externalEntityContentProcessor;
       return externalEntityContentProcessor(parser, start, end, endPtr);
-    }
-    else {
+    } else {
       parser->m_processor = contentProcessor;
       return contentProcessor(parser, start, end, endPtr);
     }
@@ -3692,13 +3554,8 @@ cdataSectionProcessor(XML_Parser parser,
    the section is not yet closed.
 */
 static enum XML_Error
-doCdataSection(XML_Parser parser,
-               const ENCODING *enc,
-               const char **startPtr,
-               const char *end,
-               const char **nextPtr,
-               XML_Bool haveMore)
-{
+doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
+               const char *end, const char **nextPtr, XML_Bool haveMore) {
   const char *s = *startPtr;
   const char **eventPP;
   const char **eventEndPP;
@@ -3706,8 +3563,7 @@ doCdataSection(XML_Parser parser,
     eventPP = &parser->m_eventPtr;
     *eventPP = s;
     eventEndPP = &parser->m_eventEndPtr;
-  }
-  else {
+  } else {
     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
   }
@@ -3722,11 +3578,12 @@ doCdataSection(XML_Parser parser,
     case XML_TOK_CDATA_SECT_CLOSE:
       if (parser->m_endCdataSectionHandler)
         parser->m_endCdataSectionHandler(parser->m_handlerArg);
-/* BEGIN disabled code */
+      /* BEGIN disabled code */
       /* see comment under XML_TOK_CDATA_SECT_OPEN */
       else if (0 && parser->m_characterDataHandler)
-        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
-/* END disabled code */
+        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+                                       0);
+      /* END disabled code */
       else if (parser->m_defaultHandler)
         reportDefault(parser, enc, s, next);
       *startPtr = next;
@@ -3739,35 +3596,31 @@ doCdataSection(XML_Parser parser,
       if (parser->m_characterDataHandler) {
         XML_Char c = 0xA;
         parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
-      }
-      else if (parser->m_defaultHandler)
+      } else if (parser->m_defaultHandler)
         reportDefault(parser, enc, s, next);
       break;
-    case XML_TOK_DATA_CHARS:
-      {
-        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
-        if (charDataHandler) {
-          if (MUST_CONVERT(enc, s)) {
-            for (;;) {
-              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
-              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
-              *eventEndPP = next;
-              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
-                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
-              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
-                break;
-              *eventPP = s;
-            }
+    case XML_TOK_DATA_CHARS: {
+      XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
+      if (charDataHandler) {
+        if (MUST_CONVERT(enc, s)) {
+          for (;;) {
+            ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
+            const enum XML_Convert_Result convert_res = XmlConvert(
+                enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
+            *eventEndPP = next;
+            charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+                            (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+            if ((convert_res == XML_CONVERT_COMPLETED)
+                || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+              break;
+            *eventPP = s;
           }
-          else
-            charDataHandler(parser->m_handlerArg,
-                            (XML_Char *)s,
-                            (int)((XML_Char *)next - (XML_Char *)s));
-        }
-        else if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-      }
-      break;
+        } else
+          charDataHandler(parser->m_handlerArg, (XML_Char *)s,
+                          (int)((XML_Char *)next - (XML_Char *)s));
+      } else if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+    } break;
     case XML_TOK_INVALID:
       *eventPP = next;
       return XML_ERROR_INVALID_TOKEN;
@@ -3791,7 +3644,7 @@ doCdataSection(XML_Parser parser,
        * statistics.
        *
        * LCOV_EXCL_START
-      */
+       */
       *eventPP = next;
       return XML_ERROR_UNEXPECTED_STATE;
       /* LCOV_EXCL_STOP */
@@ -3804,7 +3657,7 @@ doCdataSection(XML_Parser parser,
       return XML_ERROR_NONE;
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
-    default: ;
+    default:;
     }
   }
   /* not reached */
@@ -3816,13 +3669,11 @@ doCdataSection(XML_Parser parser,
    the whole file is parsed with one call.
 */
 static enum XML_Error PTRCALL
-ignoreSectionProcessor(XML_Parser parser,
-                       const char *start,
-                       const char *end,
-                       const char **endPtr)
-{
-  enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end,
-                                          endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
+                       const char **endPtr) {
+  enum XML_Error result
+      = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
+                        (XML_Bool)! parser->m_parsingStatus.finalBuffer);
   if (result != XML_ERROR_NONE)
     return result;
   if (start) {
@@ -3836,13 +3687,8 @@ ignoreSectionProcessor(XML_Parser parser,
    if the section is not yet closed.
 */
 static enum XML_Error
-doIgnoreSection(XML_Parser parser,
-                const ENCODING *enc,
-                const char **startPtr,
-                const char *end,
-                const char **nextPtr,
-                XML_Bool haveMore)
-{
+doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
+                const char *end, const char **nextPtr, XML_Bool haveMore) {
   const char *next;
   int tok;
   const char *s = *startPtr;
@@ -3852,8 +3698,7 @@ doIgnoreSection(XML_Parser parser,
     eventPP = &parser->m_eventPtr;
     *eventPP = s;
     eventEndPP = &parser->m_eventEndPtr;
-  }
-  else {
+  } else {
     /* It's not entirely clear, but it seems the following two lines
      * of code cannot be executed.  The only occasions on which 'enc'
      * is not 'encoding' are when this function is called
@@ -3917,13 +3762,12 @@ doIgnoreSection(XML_Parser parser,
 #endif /* XML_DTD */
 
 static enum XML_Error
-initializeEncoding(XML_Parser parser)
-{
+initializeEncoding(XML_Parser parser) {
   const char *s;
 #ifdef XML_UNICODE
   char encodingBuf[128];
   /* See comments abount `protoclEncodingName` in parserInit() */
-  if (!parser->m_protocolEncodingName)
+  if (! parser->m_protocolEncodingName)
     s = NULL;
   else {
     int i;
@@ -3941,15 +3785,15 @@ initializeEncoding(XML_Parser parser)
 #else
   s = parser->m_protocolEncodingName;
 #endif
-  if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s))
+  if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
+          &parser->m_initEncoding, &parser->m_encoding, s))
     return XML_ERROR_NONE;
   return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
 }
 
 static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
-               const char *s, const char *next)
-{
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
+               const char *next) {
   const char *encodingName = NULL;
   const XML_Char *storedEncName = NULL;
   const ENCODING *newEncoding = NULL;
@@ -3957,52 +3801,41 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
   const char *versionend;
   const XML_Char *storedversion = NULL;
   int standalone = -1;
-  if (!(parser->m_ns
-        ? XmlParseXmlDeclNS
-        : XmlParseXmlDecl)(isGeneralTextEntity,
-                           parser->m_encoding,
-                           s,
-                           next,
-                           &parser->m_eventPtr,
-                           &version,
-                           &versionend,
-                           &encodingName,
-                           &newEncoding,
-                           &standalone)) {
+  if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
+          isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
+          &version, &versionend, &encodingName, &newEncoding, &standalone)) {
     if (isGeneralTextEntity)
       return XML_ERROR_TEXT_DECL;
     else
       return XML_ERROR_XML_DECL;
   }
-  if (!isGeneralTextEntity && standalone == 1) {
+  if (! isGeneralTextEntity && standalone == 1) {
     parser->m_dtd->standalone = XML_TRUE;
 #ifdef XML_DTD
-    if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+    if (parser->m_paramEntityParsing
+        == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
       parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
 #endif /* XML_DTD */
   }
   if (parser->m_xmlDeclHandler) {
     if (encodingName != NULL) {
-      storedEncName = poolStoreString(&parser->m_temp2Pool,
-                                      parser->m_encoding,
-                                      encodingName,
-                                      encodingName
-                                      + XmlNameLength(parser->m_encoding, encodingName));
-      if (!storedEncName)
-              return XML_ERROR_NO_MEMORY;
+      storedEncName = poolStoreString(
+          &parser->m_temp2Pool, parser->m_encoding, encodingName,
+          encodingName + XmlNameLength(parser->m_encoding, encodingName));
+      if (! storedEncName)
+        return XML_ERROR_NO_MEMORY;
       poolFinish(&parser->m_temp2Pool);
     }
     if (version) {
-      storedversion = poolStoreString(&parser->m_temp2Pool,
-                                      parser->m_encoding,
-                                      version,
-                                      versionend - parser->m_encoding->minBytesPerChar);
-      if (!storedversion)
+      storedversion
+          = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
+                            versionend - parser->m_encoding->minBytesPerChar);
+      if (! storedversion)
         return XML_ERROR_NO_MEMORY;
     }
-    parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone);
-  }
-  else if (parser->m_defaultHandler)
+    parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
+                             standalone);
+  else if (parser->m_defaultHandler)
     reportDefault(parser, parser->m_encoding, s, next);
   if (parser->m_protocolEncodingName == NULL) {
     if (newEncoding) {
@@ -4012,20 +3845,19 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
        * this is UTF-16, is it the same endianness?
        */
       if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
-          || (newEncoding->minBytesPerChar == 2 &&
-              newEncoding != parser->m_encoding)) {
+          || (newEncoding->minBytesPerChar == 2
+              && newEncoding != parser->m_encoding)) {
         parser->m_eventPtr = encodingName;
         return XML_ERROR_INCORRECT_ENCODING;
       }
       parser->m_encoding = newEncoding;
-    }
-    else if (encodingName) {
+    } else if (encodingName) {
       enum XML_Error result;
-      if (!storedEncName) {
+      if (! storedEncName) {
         storedEncName = poolStoreString(
-          &parser->m_temp2Pool, parser->m_encoding, encodingName,
-          encodingName + XmlNameLength(parser->m_encoding, encodingName));
-        if (!storedEncName)
+            &parser->m_temp2Pool, parser->m_encoding, encodingName,
+            encodingName + XmlNameLength(parser->m_encoding, encodingName));
+        if (! storedEncName)
           return XML_ERROR_NO_MEMORY;
       }
       result = handleUnknownEncoding(parser, storedEncName);
@@ -4043,8 +3875,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
 }
 
 static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
   if (parser->m_unknownEncodingHandler) {
     XML_Encoding info;
     int i;
@@ -4053,21 +3884,17 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
     info.convert = NULL;
     info.data = NULL;
     info.release = NULL;
-    if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName,
-                               &info)) {
+    if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
+                                         encodingName, &info)) {
       ENCODING *enc;
       parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
-      if (!parser->m_unknownEncodingMem) {
+      if (! parser->m_unknownEncodingMem) {
         if (info.release)
           info.release(info.data);
         return XML_ERROR_NO_MEMORY;
       }
-      enc = (parser->m_ns
-             ? XmlInitUnknownEncodingNS
-             : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem,
-                                       info.map,
-                                       info.convert,
-                                       info.data);
+      enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
+          parser->m_unknownEncodingMem, info.map, info.convert, info.data);
       if (enc) {
         parser->m_unknownEncodingData = info.data;
         parser->m_unknownEncodingRelease = info.release;
@@ -4082,11 +3909,8 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
 }
 
 static enum XML_Error PTRCALL
-prologInitProcessor(XML_Parser parser,
-                    const char *s,
-                    const char *end,
-                    const char **nextPtr)
-{
+prologInitProcessor(XML_Parser parser, const char *s, const char *end,
+                    const char **nextPtr) {
   enum XML_Error result = initializeEncoding(parser);
   if (result != XML_ERROR_NONE)
     return result;
@@ -4097,11 +3921,8 @@ prologInitProcessor(XML_Parser parser,
 #ifdef XML_DTD
 
 static enum XML_Error PTRCALL
-externalParEntInitProcessor(XML_Parser parser,
-                            const char *s,
-                            const char *end,
-                            const char **nextPtr)
-{
+externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
+                            const char **nextPtr) {
   enum XML_Error result = initializeEncoding(parser);
   if (result != XML_ERROR_NONE)
     return result;
@@ -4113,19 +3934,15 @@ externalParEntInitProcessor(XML_Parser parser,
   if (parser->m_prologState.inEntityValue) {
     parser->m_processor = entityValueInitProcessor;
     return entityValueInitProcessor(parser, s, end, nextPtr);
-  }
-  else {
+  } else {
     parser->m_processor = externalParEntProcessor;
     return externalParEntProcessor(parser, s, end, nextPtr);
   }
 }
 
 static enum XML_Error PTRCALL
-entityValueInitProcessor(XML_Parser parser,
-                         const char *s,
-                         const char *end,
-                         const char **nextPtr)
-{
+entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
+                         const char **nextPtr) {
   int tok;
   const char *start = s;
   const char *next = start;
@@ -4135,7 +3952,7 @@ entityValueInitProcessor(XML_Parser parser,
     tok = XmlPrologTok(parser->m_encoding, start, end, &next);
     parser->m_eventEndPtr = next;
     if (tok <= 0) {
-      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
+      if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
         *nextPtr = s;
         return XML_ERROR_NONE;
       }
@@ -4146,22 +3963,21 @@ entityValueInitProcessor(XML_Parser parser,
         return XML_ERROR_UNCLOSED_TOKEN;
       case XML_TOK_PARTIAL_CHAR:
         return XML_ERROR_PARTIAL_CHAR;
-      case XML_TOK_NONE:   /* start == end */
+      case XML_TOK_NONE: /* start == end */
       default:
         break;
       }
       /* found end of entity value - can store it now */
       return storeEntityValue(parser, parser->m_encoding, s, end);
-    }
-    else if (tok == XML_TOK_XML_DECL) {
+    } else if (tok == XML_TOK_XML_DECL) {
       enum XML_Error result;
       result = processXmlDecl(parser, 0, start, next);
       if (result != XML_ERROR_NONE)
         return result;
-      /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For that
-       * to happen, a parameter entity parsing handler must have
-       * attempted to suspend the parser, which fails and raises an
-       * error.  The parser can be aborted, but can't be suspended.
+      /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For
+       * that to happen, a parameter entity parsing handler must have attempted
+       * to suspend the parser, which fails and raises an error.  The parser can
+       * be aborted, but can't be suspended.
        */
       if (parser->m_parsingStatus.parsing == XML_FINISHED)
         return XML_ERROR_ABORTED;
@@ -4177,7 +3993,8 @@ entityValueInitProcessor(XML_Parser parser,
        then, when this routine is entered the next time, XmlPrologTok will
        return XML_TOK_INVALID, since the BOM is still in the buffer
     */
-    else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) {
+    else if (tok == XML_TOK_BOM && next == end
+             && ! parser->m_parsingStatus.finalBuffer) {
       *nextPtr = next;
       return XML_ERROR_NONE;
     }
@@ -4195,17 +4012,14 @@ entityValueInitProcessor(XML_Parser parser,
 }
 
 static enum XML_Error PTRCALL
-externalParEntProcessor(XML_Parser parser,
-                        const char *s,
-                        const char *end,
-                        const char **nextPtr)
-{
+externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
+                        const char **nextPtr) {
   const char *next = s;
   int tok;
 
   tok = XmlPrologTok(parser->m_encoding, s, end, &next);
   if (tok <= 0) {
-    if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
+    if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
       *nextPtr = s;
       return XML_ERROR_NONE;
     }
@@ -4216,7 +4030,7 @@ externalParEntProcessor(XML_Parser parser,
       return XML_ERROR_UNCLOSED_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
       return XML_ERROR_PARTIAL_CHAR;
-    case XML_TOK_NONE:   /* start == end */
+    case XML_TOK_NONE: /* start == end */
     default:
       break;
     }
@@ -4231,16 +4045,13 @@ externalParEntProcessor(XML_Parser parser,
   }
 
   parser->m_processor = prologProcessor;
-  return doProlog(parser, parser->m_encoding, s, end, tok, next,
-                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+  return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
+                  (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
 }
 
 static enum XML_Error PTRCALL
-entityValueProcessor(XML_Parser parser,
-                     const char *s,
-                     const char *end,
-                     const char **nextPtr)
-{
+entityValueProcessor(XML_Parser parser, const char *s, const char *end,
+                     const char **nextPtr) {
   const char *start = s;
   const char *next = s;
   const ENCODING *enc = parser->m_encoding;
@@ -4249,7 +4060,7 @@ entityValueProcessor(XML_Parser parser,
   for (;;) {
     tok = XmlPrologTok(enc, start, end, &next);
     if (tok <= 0) {
-      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
+      if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
         *nextPtr = s;
         return XML_ERROR_NONE;
       }
@@ -4260,7 +4071,7 @@ entityValueProcessor(XML_Parser parser,
         return XML_ERROR_UNCLOSED_TOKEN;
       case XML_TOK_PARTIAL_CHAR:
         return XML_ERROR_PARTIAL_CHAR;
-      case XML_TOK_NONE:   /* start == end */
+      case XML_TOK_NONE: /* start == end */
       default:
         break;
       }
@@ -4274,52 +4085,46 @@ entityValueProcessor(XML_Parser parser,
 #endif /* XML_DTD */
 
 static enum XML_Error PTRCALL
-prologProcessor(XML_Parser parser,
-                const char *s,
-                const char *end,
-                const char **nextPtr)
-{
+prologProcessor(XML_Parser parser, const char *s, const char *end,
+                const char **nextPtr) {
   const char *next = s;
   int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
-  return doProlog(parser, parser->m_encoding, s, end, tok, next,
-                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+  return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
+                  (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
 }
 
 static enum XML_Error
-doProlog(XML_Parser parser,
-         const ENCODING *enc,
-         const char *s,
-         const char *end,
-         int tok,
-         const char *next,
-         const char **nextPtr,
-         XML_Bool haveMore)
-{
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
+         int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
+         XML_Bool allowClosingDoctype) {
 #ifdef XML_DTD
-  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
+  static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
 #endif /* XML_DTD */
-  static const XML_Char atypeCDATA[] =
-      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
-  static const XML_Char atypeIDREF[] =
-      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
-  static const XML_Char atypeIDREFS[] =
-      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
-  static const XML_Char atypeENTITY[] =
-      { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
-  static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
-      ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
-  static const XML_Char atypeNMTOKEN[] = {
-      ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
-  static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
-      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
-  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
-      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
-  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
-  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
+  static const XML_Char atypeCDATA[]
+      = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+  static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
+  static const XML_Char atypeIDREF[]
+      = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
+  static const XML_Char atypeIDREFS[]
+      = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
+  static const XML_Char atypeENTITY[]
+      = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
+  static const XML_Char atypeENTITIES[]
+      = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
+         ASCII_I, ASCII_E, ASCII_S, '\0'};
+  static const XML_Char atypeNMTOKEN[]
+      = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
+  static const XML_Char atypeNMTOKENS[]
+      = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
+         ASCII_E, ASCII_N, ASCII_S, '\0'};
+  static const XML_Char notationPrefix[]
+      = {ASCII_N, ASCII_O, ASCII_T, ASCII_A,      ASCII_T,
+         ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
+  static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
+  static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
 
   /* save one level of indirection */
-  DTD * const dtd = parser->m_dtd;
+  DTD *const dtd = parser->m_dtd;
 
   const char **eventPP;
   const char **eventEndPP;
@@ -4328,8 +4133,7 @@ doProlog(XML_Parser parser,
   if (enc == parser->m_encoding) {
     eventPP = &parser->m_eventPtr;
     eventEndPP = &parser->m_eventEndPtr;
-  }
-  else {
+  } else {
     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
   }
@@ -4358,7 +4162,8 @@ doProlog(XML_Parser parser,
       case XML_TOK_NONE:
 #ifdef XML_DTD
         /* for internal PE NOT referenced between declarations */
-        if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) {
+        if (enc != parser->m_encoding
+            && ! parser->m_openInternalEntities->betweenDecl) {
           *nextPtr = s;
           return XML_ERROR_NONE;
         }
@@ -4383,19 +4188,18 @@ doProlog(XML_Parser parser,
     }
     role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
     switch (role) {
-    case XML_ROLE_XML_DECL:
-      {
-        enum XML_Error result = processXmlDecl(parser, 0, s, next);
-        if (result != XML_ERROR_NONE)
-          return result;
-        enc = parser->m_encoding;
-        handleDefault = XML_FALSE;
-      }
-      break;
+    case XML_ROLE_XML_DECL: {
+      enum XML_Error result = processXmlDecl(parser, 0, s, next);
+      if (result != XML_ERROR_NONE)
+        return result;
+      enc = parser->m_encoding;
+      handleDefault = XML_FALSE;
+    } break;
     case XML_ROLE_DOCTYPE_NAME:
       if (parser->m_startDoctypeDeclHandler) {
-        parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next);
-        if (!parser->m_doctypeName)
+        parser->m_doctypeName
+            = poolStoreString(&parser->m_tempPool, enc, s, next);
+        if (! parser->m_doctypeName)
           return XML_ERROR_NO_MEMORY;
         poolFinish(&parser->m_tempPool);
         parser->m_doctypePubid = NULL;
@@ -4405,43 +4209,40 @@ doProlog(XML_Parser parser,
       break;
     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
       if (parser->m_startDoctypeDeclHandler) {
-        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
-                                parser->m_doctypePubid, 1);
+        parser->m_startDoctypeDeclHandler(
+            parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
+            parser->m_doctypePubid, 1);
         parser->m_doctypeName = NULL;
         poolClear(&parser->m_tempPool);
         handleDefault = XML_FALSE;
       }
       break;
 #ifdef XML_DTD
-    case XML_ROLE_TEXT_DECL:
-      {
-        enum XML_Error result = processXmlDecl(parser, 1, s, next);
-        if (result != XML_ERROR_NONE)
-          return result;
-        enc = parser->m_encoding;
-        handleDefault = XML_FALSE;
-      }
-      break;
+    case XML_ROLE_TEXT_DECL: {
+      enum XML_Error result = processXmlDecl(parser, 1, s, next);
+      if (result != XML_ERROR_NONE)
+        return result;
+      enc = parser->m_encoding;
+      handleDefault = XML_FALSE;
+    } break;
 #endif /* XML_DTD */
     case XML_ROLE_DOCTYPE_PUBLIC_ID:
 #ifdef XML_DTD
       parser->m_useForeignDTD = XML_FALSE;
-      parser->m_declEntity = (ENTITY *)lookup(parser,
-                                    &dtd->paramEntities,
-                                    externalSubsetName,
-                                    sizeof(ENTITY));
-      if (!parser->m_declEntity)
+      parser->m_declEntity = (ENTITY *)lookup(
+          parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
+      if (! parser->m_declEntity)
         return XML_ERROR_NO_MEMORY;
 #endif /* XML_DTD */
       dtd->hasParamEntityRefs = XML_TRUE;
       if (parser->m_startDoctypeDeclHandler) {
         XML_Char *pubId;
-        if (!XmlIsPublicId(enc, s, next, eventPP))
+        if (! XmlIsPublicId(enc, s, next, eventPP))
           return XML_ERROR_PUBLICID;
         pubId = poolStoreString(&parser->m_tempPool, enc,
                                 s + enc->minBytesPerChar,
                                 next - enc->minBytesPerChar);
-        if (!pubId)
+        if (! pubId)
           return XML_ERROR_NO_MEMORY;
         normalizePublicId(pubId);
         poolFinish(&parser->m_tempPool);
@@ -4451,15 +4252,14 @@ doProlog(XML_Parser parser,
       }
       /* fall through */
     case XML_ROLE_ENTITY_PUBLIC_ID:
-      if (!XmlIsPublicId(enc, s, next, eventPP))
+      if (! XmlIsPublicId(enc, s, next, eventPP))
         return XML_ERROR_PUBLICID;
     alreadyChecked:
       if (dtd->keepProcessing && parser->m_declEntity) {
-        XML_Char *tem = poolStoreString(&dtd->pool,
-                                        enc,
-                                        s + enc->minBytesPerChar,
-                                        next - enc->minBytesPerChar);
-        if (!tem)
+        XML_Char *tem
+            = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar);
+        if (! tem)
           return XML_ERROR_NO_MEMORY;
         normalizePublicId(tem);
         parser->m_declEntity->publicId = tem;
@@ -4472,9 +4272,15 @@ doProlog(XML_Parser parser,
       }
       break;
     case XML_ROLE_DOCTYPE_CLOSE:
+      if (allowClosingDoctype != XML_TRUE) {
+        /* Must not close doctype from within expanded parameter entities */
+        return XML_ERROR_INVALID_TOKEN;
+      }
+
       if (parser->m_doctypeName) {
-        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName,
-                                parser->m_doctypeSysid, parser->m_doctypePubid, 0);
+        parser->m_startDoctypeDeclHandler(
+            parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
+            parser->m_doctypePubid, 0);
         poolClear(&parser->m_tempPool);
         handleDefault = XML_FALSE;
       }
@@ -4486,12 +4292,11 @@ doProlog(XML_Parser parser,
       if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
         dtd->hasParamEntityRefs = XML_TRUE;
-        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
-          ENTITY *entity = (ENTITY *)lookup(parser,
-                                            &dtd->paramEntities,
-                                            externalSubsetName,
-                                            sizeof(ENTITY));
-          if (!entity) {
+        if (parser->m_paramEntityParsing
+            && parser->m_externalEntityRefHandler) {
+          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
+                                            externalSubsetName, sizeof(ENTITY));
+          if (! entity) {
             /* The external subset name "#" will have already been
              * inserted into the hash table at the start of the
              * external entity parsing, so no allocation will happen
@@ -4502,22 +4307,19 @@ doProlog(XML_Parser parser,
           if (parser->m_useForeignDTD)
             entity->base = parser->m_curBase;
           dtd->paramEntityRead = XML_FALSE;
-          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
-                                        0,
-                                        entity->base,
-                                        entity->systemId,
-                                        entity->publicId))
+          if (! parser->m_externalEntityRefHandler(
+                  parser->m_externalEntityRefHandlerArg, 0, entity->base,
+                  entity->systemId, entity->publicId))
             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
           if (dtd->paramEntityRead) {
-            if (!dtd->standalone &&
-                parser->m_notStandaloneHandler &&
-                !parser->m_notStandaloneHandler(parser->m_handlerArg))
+            if (! dtd->standalone && parser->m_notStandaloneHandler
+                && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
               return XML_ERROR_NOT_STANDALONE;
           }
           /* if we didn't read the foreign DTD then this means that there
              is no external subset and we must reset dtd->hasParamEntityRefs
           */
-          else if (!parser->m_doctypeSysid)
+          else if (! parser->m_doctypeSysid)
             dtd->hasParamEntityRefs = hadParamEntityRefs;
           /* end of DTD - no need to update dtd->keepProcessing */
         }
@@ -4537,24 +4339,21 @@ doProlog(XML_Parser parser,
       if (parser->m_useForeignDTD) {
         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
         dtd->hasParamEntityRefs = XML_TRUE;
-        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
+        if (parser->m_paramEntityParsing
+            && parser->m_externalEntityRefHandler) {
           ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
-                                            externalSubsetName,
-                                            sizeof(ENTITY));
-          if (!entity)
+                                            externalSubsetName, sizeof(ENTITY));
+          if (! entity)
             return XML_ERROR_NO_MEMORY;
           entity->base = parser->m_curBase;
           dtd->paramEntityRead = XML_FALSE;
-          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
-                                        0,
-                                        entity->base,
-                                        entity->systemId,
-                                        entity->publicId))
+          if (! parser->m_externalEntityRefHandler(
+                  parser->m_externalEntityRefHandlerArg, 0, entity->base,
+                  entity->systemId, entity->publicId))
             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
           if (dtd->paramEntityRead) {
-            if (!dtd->standalone &&
-                parser->m_notStandaloneHandler &&
-                !parser->m_notStandaloneHandler(parser->m_handlerArg))
+            if (! dtd->standalone && parser->m_notStandaloneHandler
+                && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
               return XML_ERROR_NOT_STANDALONE;
           }
           /* if we didn't read the foreign DTD then this means that there
@@ -4570,12 +4369,12 @@ doProlog(XML_Parser parser,
       return contentProcessor(parser, s, end, nextPtr);
     case XML_ROLE_ATTLIST_ELEMENT_NAME:
       parser->m_declElementType = getElementType(parser, enc, s, next);
-      if (!parser->m_declElementType)
+      if (! parser->m_declElementType)
         return XML_ERROR_NO_MEMORY;
       goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_NAME:
       parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
-      if (!parser->m_declAttributeId)
+      if (! parser->m_declAttributeId)
         return XML_ERROR_NO_MEMORY;
       parser->m_declAttributeIsCdata = XML_FALSE;
       parser->m_declAttributeType = NULL;
@@ -4616,15 +4415,13 @@ doProlog(XML_Parser parser,
         const XML_Char *prefix;
         if (parser->m_declAttributeType) {
           prefix = enumValueSep;
+        } else {
+          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
+                                                              : enumValueStart);
         }
-        else {
-          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
-                    ? notationPrefix
-                    : enumValueStart);
-        }
-        if (!poolAppendString(&parser->m_tempPool, prefix))
+        if (! poolAppendString(&parser->m_tempPool, prefix))
           return XML_ERROR_NO_MEMORY;
-        if (!poolAppend(&parser->m_tempPool, enc, s, next))
+        if (! poolAppend(&parser->m_tempPool, enc, s, next))
           return XML_ERROR_NO_MEMORY;
         parser->m_declAttributeType = parser->m_tempPool.start;
         handleDefault = XML_FALSE;
@@ -4633,25 +4430,27 @@ doProlog(XML_Parser parser,
     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
       if (dtd->keepProcessing) {
-        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
-                             parser->m_declAttributeIsCdata, parser->m_declAttributeIsId,
-                             0, parser))
+        if (! defineAttribute(parser->m_declElementType,
+                              parser->m_declAttributeId,
+                              parser->m_declAttributeIsCdata,
+                              parser->m_declAttributeIsId, 0, parser))
           return XML_ERROR_NO_MEMORY;
         if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
           if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
               || (*parser->m_declAttributeType == XML_T(ASCII_N)
                   && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
             /* Enumerated or Notation type */
-            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
-                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
+            if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
+                || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
               return XML_ERROR_NO_MEMORY;
             parser->m_declAttributeType = parser->m_tempPool.start;
             poolFinish(&parser->m_tempPool);
           }
           *eventEndPP = s;
-          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
-                             parser->m_declAttributeId->name, parser->m_declAttributeType,
-                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+          parser->m_attlistDeclHandler(
+              parser->m_handlerArg, parser->m_declElementType->name,
+              parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
+              role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
           poolClear(&parser->m_tempPool);
           handleDefault = XML_FALSE;
         }
@@ -4661,35 +4460,34 @@ doProlog(XML_Parser parser,
     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
       if (dtd->keepProcessing) {
         const XML_Char *attVal;
-        enum XML_Error result =
-          storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata,
-                              s + enc->minBytesPerChar,
-                              next - enc->minBytesPerChar,
-                              &dtd->pool);
+        enum XML_Error result = storeAttributeValue(
+            parser, enc, parser->m_declAttributeIsCdata,
+            s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
         if (result)
           return result;
         attVal = poolStart(&dtd->pool);
         poolFinish(&dtd->pool);
         /* ID attributes aren't allowed to have a default */
-        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
-                             parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
+        if (! defineAttribute(
+                parser->m_declElementType, parser->m_declAttributeId,
+                parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
           return XML_ERROR_NO_MEMORY;
         if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
           if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
               || (*parser->m_declAttributeType == XML_T(ASCII_N)
                   && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
             /* Enumerated or Notation type */
-            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
-                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
+            if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
+                || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
               return XML_ERROR_NO_MEMORY;
             parser->m_declAttributeType = parser->m_tempPool.start;
             poolFinish(&parser->m_tempPool);
           }
           *eventEndPP = s;
-          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
-                             parser->m_declAttributeId->name, parser->m_declAttributeType,
-                             attVal,
-                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+          parser->m_attlistDeclHandler(
+              parser->m_handlerArg, parser->m_declElementType->name,
+              parser->m_declAttributeId->name, parser->m_declAttributeType,
+              attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
           poolClear(&parser->m_tempPool);
           handleDefault = XML_FALSE;
         }
@@ -4697,25 +4495,22 @@ doProlog(XML_Parser parser,
       break;
     case XML_ROLE_ENTITY_VALUE:
       if (dtd->keepProcessing) {
-        enum XML_Error result = storeEntityValue(parser, enc,
-                                            s + enc->minBytesPerChar,
-                                            next - enc->minBytesPerChar);
+        enum XML_Error result = storeEntityValue(
+            parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
         if (parser->m_declEntity) {
           parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
-          parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
+          parser->m_declEntity->textLen
+              = (int)(poolLength(&dtd->entityValuePool));
           poolFinish(&dtd->entityValuePool);
           if (parser->m_entityDeclHandler) {
             *eventEndPP = s;
-            parser->m_entityDeclHandler(parser->m_handlerArg,
-                              parser->m_declEntity->name,
-                              parser->m_declEntity->is_param,
-                              parser->m_declEntity->textPtr,
-                              parser->m_declEntity->textLen,
-                              parser->m_curBase, 0, 0, 0);
+            parser->m_entityDeclHandler(
+                parser->m_handlerArg, parser->m_declEntity->name,
+                parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
+                parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
             handleDefault = XML_FALSE;
           }
-        }
-        else
+        } else
           poolDiscard(&dtd->entityValuePool);
         if (result != XML_ERROR_NONE)
           return result;
@@ -4728,8 +4523,8 @@ doProlog(XML_Parser parser,
       dtd->hasParamEntityRefs = XML_TRUE;
       if (parser->m_startDoctypeDeclHandler) {
         parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
-                                       s + enc->minBytesPerChar,
-                                       next - enc->minBytesPerChar);
+                                                 s + enc->minBytesPerChar,
+                                                 next - enc->minBytesPerChar);
         if (parser->m_doctypeSysid == NULL)
           return XML_ERROR_NO_MEMORY;
         poolFinish(&parser->m_tempPool);
@@ -4741,22 +4536,20 @@ doProlog(XML_Parser parser,
            for the case where no parser->m_startDoctypeDeclHandler is set */
         parser->m_doctypeSysid = externalSubsetName;
 #endif /* XML_DTD */
-      if (!dtd->standalone
+      if (! dtd->standalone
 #ifdef XML_DTD
-          && !parser->m_paramEntityParsing
+          && ! parser->m_paramEntityParsing
 #endif /* XML_DTD */
           && parser->m_notStandaloneHandler
-          && !parser->m_notStandaloneHandler(parser->m_handlerArg))
+          && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
         return XML_ERROR_NOT_STANDALONE;
 #ifndef XML_DTD
       break;
-#else /* XML_DTD */
-      if (!parser->m_declEntity) {
-        parser->m_declEntity = (ENTITY *)lookup(parser,
-                                      &dtd->paramEntities,
-                                      externalSubsetName,
-                                      sizeof(ENTITY));
-        if (!parser->m_declEntity)
+#else  /* XML_DTD */
+      if (! parser->m_declEntity) {
+        parser->m_declEntity = (ENTITY *)lookup(
+            parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
+        if (! parser->m_declEntity)
           return XML_ERROR_NO_MEMORY;
         parser->m_declEntity->publicId = NULL;
       }
@@ -4764,10 +4557,10 @@ doProlog(XML_Parser parser,
       /* fall through */
     case XML_ROLE_ENTITY_SYSTEM_ID:
       if (dtd->keepProcessing && parser->m_declEntity) {
-        parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc,
-                                               s + enc->minBytesPerChar,
-                                               next - enc->minBytesPerChar);
-        if (!parser->m_declEntity->systemId)
+        parser->m_declEntity->systemId
+            = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar);
+        if (! parser->m_declEntity->systemId)
           return XML_ERROR_NO_MEMORY;
         parser->m_declEntity->base = parser->m_curBase;
         poolFinish(&dtd->pool);
@@ -4779,115 +4572,103 @@ doProlog(XML_Parser parser,
       }
       break;
     case XML_ROLE_ENTITY_COMPLETE:
-      if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) {
+      if (dtd->keepProcessing && parser->m_declEntity
+          && parser->m_entityDeclHandler) {
         *eventEndPP = s;
-        parser->m_entityDeclHandler(parser->m_handlerArg,
-                          parser->m_declEntity->name,
-                          parser->m_declEntity->is_param,
-                          0,0,
-                          parser->m_declEntity->base,
-                          parser->m_declEntity->systemId,
-                          parser->m_declEntity->publicId,
-                          0);
+        parser->m_entityDeclHandler(
+            parser->m_handlerArg, parser->m_declEntity->name,
+            parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
+            parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
         handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_ENTITY_NOTATION_NAME:
       if (dtd->keepProcessing && parser->m_declEntity) {
-        parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
-        if (!parser->m_declEntity->notation)
+        parser->m_declEntity->notation
+            = poolStoreString(&dtd->pool, enc, s, next);
+        if (! parser->m_declEntity->notation)
           return XML_ERROR_NO_MEMORY;
         poolFinish(&dtd->pool);
         if (parser->m_unparsedEntityDeclHandler) {
           *eventEndPP = s;
-          parser->m_unparsedEntityDeclHandler(parser->m_handlerArg,
-                                    parser->m_declEntity->name,
-                                    parser->m_declEntity->base,
-                                    parser->m_declEntity->systemId,
-                                    parser->m_declEntity->publicId,
-                                    parser->m_declEntity->notation);
+          parser->m_unparsedEntityDeclHandler(
+              parser->m_handlerArg, parser->m_declEntity->name,
+              parser->m_declEntity->base, parser->m_declEntity->systemId,
+              parser->m_declEntity->publicId, parser->m_declEntity->notation);
           handleDefault = XML_FALSE;
-        }
-        else if (parser->m_entityDeclHandler) {
+        } else if (parser->m_entityDeclHandler) {
           *eventEndPP = s;
-          parser->m_entityDeclHandler(parser->m_handlerArg,
-                            parser->m_declEntity->name,
-                            0,0,0,
-                            parser->m_declEntity->base,
-                            parser->m_declEntity->systemId,
-                            parser->m_declEntity->publicId,
-                            parser->m_declEntity->notation);
+          parser->m_entityDeclHandler(
+              parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
+              parser->m_declEntity->base, parser->m_declEntity->systemId,
+              parser->m_declEntity->publicId, parser->m_declEntity->notation);
           handleDefault = XML_FALSE;
         }
       }
       break;
-    case XML_ROLE_GENERAL_ENTITY_NAME:
-      {
-        if (XmlPredefinedEntityName(enc, s, next)) {
-          parser->m_declEntity = NULL;
-          break;
-        }
-        if (dtd->keepProcessing) {
-          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
-          if (!name)
-            return XML_ERROR_NO_MEMORY;
-          parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
-                                        sizeof(ENTITY));
-          if (!parser->m_declEntity)
-            return XML_ERROR_NO_MEMORY;
-          if (parser->m_declEntity->name != name) {
-            poolDiscard(&dtd->pool);
-            parser->m_declEntity = NULL;
-          }
-          else {
-            poolFinish(&dtd->pool);
-            parser->m_declEntity->publicId = NULL;
-            parser->m_declEntity->is_param = XML_FALSE;
-            /* if we have a parent parser or are reading an internal parameter
-               entity, then the entity declaration is not considered "internal"
-            */
-            parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
-            if (parser->m_entityDeclHandler)
-              handleDefault = XML_FALSE;
-          }
-        }
-        else {
+    case XML_ROLE_GENERAL_ENTITY_NAME: {
+      if (XmlPredefinedEntityName(enc, s, next)) {
+        parser->m_declEntity = NULL;
+        break;
+      }
+      if (dtd->keepProcessing) {
+        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+        if (! name)
+          return XML_ERROR_NO_MEMORY;
+        parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
+                                                name, sizeof(ENTITY));
+        if (! parser->m_declEntity)
+          return XML_ERROR_NO_MEMORY;
+        if (parser->m_declEntity->name != name) {
           poolDiscard(&dtd->pool);
           parser->m_declEntity = NULL;
+        } else {
+          poolFinish(&dtd->pool);
+          parser->m_declEntity->publicId = NULL;
+          parser->m_declEntity->is_param = XML_FALSE;
+          /* if we have a parent parser or are reading an internal parameter
+             entity, then the entity declaration is not considered "internal"
+          */
+          parser->m_declEntity->is_internal
+              = ! (parser->m_parentParser || parser->m_openInternalEntities);
+          if (parser->m_entityDeclHandler)
+            handleDefault = XML_FALSE;
         }
+      } else {
+        poolDiscard(&dtd->pool);
+        parser->m_declEntity = NULL;
       }
-      break;
+    } break;
     case XML_ROLE_PARAM_ENTITY_NAME:
 #ifdef XML_DTD
       if (dtd->keepProcessing) {
         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
-        if (!name)
+        if (! name)
           return XML_ERROR_NO_MEMORY;
         parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
-                                           name, sizeof(ENTITY));
-        if (!parser->m_declEntity)
+                                                name, sizeof(ENTITY));
+        if (! parser->m_declEntity)
           return XML_ERROR_NO_MEMORY;
         if (parser->m_declEntity->name != name) {
           poolDiscard(&dtd->pool);
           parser->m_declEntity = NULL;
-        }
-        else {
+        } else {
           poolFinish(&dtd->pool);
           parser->m_declEntity->publicId = NULL;
           parser->m_declEntity->is_param = XML_TRUE;
           /* if we have a parent parser or are reading an internal parameter
              entity, then the entity declaration is not considered "internal"
           */
-          parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
+          parser->m_declEntity->is_internal
+              = ! (parser->m_parentParser || parser->m_openInternalEntities);
           if (parser->m_entityDeclHandler)
             handleDefault = XML_FALSE;
         }
-      }
-      else {
+      } else {
         poolDiscard(&dtd->pool);
         parser->m_declEntity = NULL;
       }
-#else /* not XML_DTD */
+#else  /* not XML_DTD */
       parser->m_declEntity = NULL;
 #endif /* XML_DTD */
       break;
@@ -4895,22 +4676,23 @@ doProlog(XML_Parser parser,
       parser->m_declNotationPublicId = NULL;
       parser->m_declNotationName = NULL;
       if (parser->m_notationDeclHandler) {
-        parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next);
-        if (!parser->m_declNotationName)
+        parser->m_declNotationName
+            = poolStoreString(&parser->m_tempPool, enc, s, next);
+        if (! parser->m_declNotationName)
           return XML_ERROR_NO_MEMORY;
         poolFinish(&parser->m_tempPool);
         handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_NOTATION_PUBLIC_ID:
-      if (!XmlIsPublicId(enc, s, next, eventPP))
+      if (! XmlIsPublicId(enc, s, next, eventPP))
         return XML_ERROR_PUBLICID;
-      if (parser->m_declNotationName) {  /* means m_notationDeclHandler != NULL */
-        XML_Char *tem = poolStoreString(&parser->m_tempPool,
-                                        enc,
+      if (parser
+              ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
+        XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
                                         s + enc->minBytesPerChar,
                                         next - enc->minBytesPerChar);
-        if (!tem)
+        if (! tem)
           return XML_ERROR_NO_MEMORY;
         normalizePublicId(tem);
         parser->m_declNotationPublicId = tem;
@@ -4920,18 +4702,15 @@ doProlog(XML_Parser parser,
       break;
     case XML_ROLE_NOTATION_SYSTEM_ID:
       if (parser->m_declNotationName && parser->m_notationDeclHandler) {
-        const XML_Char *systemId
-          = poolStoreString(&parser->m_tempPool, enc,
-                            s + enc->minBytesPerChar,
-                            next - enc->minBytesPerChar);
-        if (!systemId)
+        const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
+                                                   s + enc->minBytesPerChar,
+                                                   next - enc->minBytesPerChar);
+        if (! systemId)
           return XML_ERROR_NO_MEMORY;
         *eventEndPP = s;
-        parser->m_notationDeclHandler(parser->m_handlerArg,
-                            parser->m_declNotationName,
-                            parser->m_curBase,
-                            systemId,
-                            parser->m_declNotationPublicId);
+        parser->m_notationDeclHandler(
+            parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
+            systemId, parser->m_declNotationPublicId);
         handleDefault = XML_FALSE;
       }
       poolClear(&parser->m_tempPool);
@@ -4939,11 +4718,9 @@ doProlog(XML_Parser parser,
     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
       if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
         *eventEndPP = s;
-        parser->m_notationDeclHandler(parser->m_handlerArg,
-                            parser->m_declNotationName,
-                            parser->m_curBase,
-                            0,
-                            parser->m_declNotationPublicId);
+        parser->m_notationDeclHandler(
+            parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
+            0, parser->m_declNotationPublicId);
         handleDefault = XML_FALSE;
       }
       poolClear(&parser->m_tempPool);
@@ -4960,42 +4737,44 @@ doProlog(XML_Parser parser,
         return XML_ERROR_SYNTAX;
       }
 #ifdef XML_DTD
-    case XML_ROLE_IGNORE_SECT:
-      {
-        enum XML_Error result;
-        if (parser->m_defaultHandler)
-          reportDefault(parser, enc, s, next);
-        handleDefault = XML_FALSE;
-        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
-        if (result != XML_ERROR_NONE)
-          return result;
-        else if (!next) {
-          parser->m_processor = ignoreSectionProcessor;
-          return result;
-        }
+    case XML_ROLE_IGNORE_SECT: {
+      enum XML_Error result;
+      if (parser->m_defaultHandler)
+        reportDefault(parser, enc, s, next);
+      handleDefault = XML_FALSE;
+      result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
+      if (result != XML_ERROR_NONE)
+        return result;
+      else if (! next) {
+        parser->m_processor = ignoreSectionProcessor;
+        return result;
       }
-      break;
+    } break;
 #endif /* XML_DTD */
     case XML_ROLE_GROUP_OPEN:
       if (parser->m_prologState.level >= parser->m_groupSize) {
         if (parser->m_groupSize) {
-          char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2);
-          if (temp == NULL) {
-            parser->m_groupSize /= 2;
-            return XML_ERROR_NO_MEMORY;
+          {
+            char *const new_connector = (char *)REALLOC(
+                parser, parser->m_groupConnector, parser->m_groupSize *= 2);
+            if (new_connector == NULL) {
+              parser->m_groupSize /= 2;
+              return XML_ERROR_NO_MEMORY;
+            }
+            parser->m_groupConnector = new_connector;
           }
-          parser->m_groupConnector = temp;
+
           if (dtd->scaffIndex) {
-            int *temp = (int *)REALLOC(parser, dtd->scaffIndex,
-                          parser->m_groupSize * sizeof(int));
-            if (temp == NULL)
+            int *const new_scaff_index = (int *)REALLOC(
+                parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
+            if (new_scaff_index == NULL)
               return XML_ERROR_NO_MEMORY;
-            dtd->scaffIndex = temp;
+            dtd->scaffIndex = new_scaff_index;
           }
-        }
-        else {
-          parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32);
-          if (!parser->m_groupConnector) {
+        } else {
+          parser->m_groupConnector
+              = (char *)MALLOC(parser, parser->m_groupSize = 32);
+          if (! parser->m_groupConnector) {
             parser->m_groupSize = 0;
             return XML_ERROR_NO_MEMORY;
           }
@@ -5006,6 +4785,7 @@ doProlog(XML_Parser parser,
         int myindex = nextScaffoldPart(parser);
         if (myindex < 0)
           return XML_ERROR_NO_MEMORY;
+        assert(dtd->scaffIndex != NULL);
         dtd->scaffIndex[dtd->scaffLevel] = myindex;
         dtd->scaffLevel++;
         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
@@ -5024,10 +4804,9 @@ doProlog(XML_Parser parser,
       if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
         return XML_ERROR_SYNTAX;
       if (dtd->in_eldecl
-          && !parser->m_groupConnector[parser->m_prologState.level]
+          && ! parser->m_groupConnector[parser->m_prologState.level]
           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
-              != XML_CTYPE_MIXED)
-          ) {
+              != XML_CTYPE_MIXED)) {
         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
             = XML_CTYPE_CHOICE;
         if (parser->m_elementDeclHandler)
@@ -5039,15 +4818,14 @@ doProlog(XML_Parser parser,
 #ifdef XML_DTD
     case XML_ROLE_INNER_PARAM_ENTITY_REF:
       dtd->hasParamEntityRefs = XML_TRUE;
-      if (!parser->m_paramEntityParsing)
+      if (! parser->m_paramEntityParsing)
         dtd->keepProcessing = dtd->standalone;
       else {
         const XML_Char *name;
         ENTITY *entity;
-        name = poolStoreString(&dtd->pool, enc,
-                                s + enc->minBytesPerChar,
-                                next - enc->minBytesPerChar);
-        if (!name)
+        name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+        if (! name)
           return XML_ERROR_NO_MEMORY;
         entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
         poolDiscard(&dtd->pool);
@@ -5055,13 +4833,12 @@ doProlog(XML_Parser parser,
            if yes, check that the entity exists, and that it is internal,
            otherwise call the skipped entity handler
         */
-        if (parser->m_prologState.documentEntity &&
-            (dtd->standalone
-             ? !parser->m_openInternalEntities
-             : !dtd->hasParamEntityRefs)) {
-          if (!entity)
+        if (parser->m_prologState.documentEntity
+            && (dtd->standalone ? ! parser->m_openInternalEntities
+                                : ! dtd->hasParamEntityRefs)) {
+          if (! entity)
             return XML_ERROR_UNDEFINED_ENTITY;
-          else if (!entity->is_internal) {
+          else if (! entity->is_internal) {
             /* It's hard to exhaustively search the code to be sure,
              * but there doesn't seem to be a way of executing the
              * following line.  There are two cases:
@@ -5084,11 +4861,11 @@ doProlog(XML_Parser parser,
              */
             return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
           }
-        }
-        else if (!entity) {
+        } else if (! entity) {
           dtd->keepProcessing = dtd->standalone;
           /* cannot report skipped entities in declarations */
-          if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) {
+          if ((role == XML_ROLE_PARAM_ENTITY_REF)
+              && parser->m_skippedEntityHandler) {
             parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
             handleDefault = XML_FALSE;
           }
@@ -5098,8 +4875,8 @@ doProlog(XML_Parser parser,
           return XML_ERROR_RECURSIVE_ENTITY_REF;
         if (entity->textPtr) {
           enum XML_Error result;
-          XML_Bool betweenDecl =
-            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
+          XML_Bool betweenDecl
+              = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
           result = processInternalEntity(parser, entity, betweenDecl);
           if (result != XML_ERROR_NONE)
             return result;
@@ -5109,39 +4886,35 @@ doProlog(XML_Parser parser,
         if (parser->m_externalEntityRefHandler) {
           dtd->paramEntityRead = XML_FALSE;
           entity->open = XML_TRUE;
-          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
-                                        0,
-                                        entity->base,
-                                        entity->systemId,
-                                        entity->publicId)) {
+          if (! parser->m_externalEntityRefHandler(
+                  parser->m_externalEntityRefHandlerArg, 0, entity->base,
+                  entity->systemId, entity->publicId)) {
             entity->open = XML_FALSE;
             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
           }
           entity->open = XML_FALSE;
           handleDefault = XML_FALSE;
-          if (!dtd->paramEntityRead) {
+          if (! dtd->paramEntityRead) {
             dtd->keepProcessing = dtd->standalone;
             break;
           }
-        }
-        else {
+        } else {
           dtd->keepProcessing = dtd->standalone;
           break;
         }
       }
 #endif /* XML_DTD */
-      if (!dtd->standalone &&
-          parser->m_notStandaloneHandler &&
-          !parser->m_notStandaloneHandler(parser->m_handlerArg))
+      if (! dtd->standalone && parser->m_notStandaloneHandler
+          && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
         return XML_ERROR_NOT_STANDALONE;
       break;
 
-    /* Element declaration stuff */
+      /* Element declaration stuff */
 
     case XML_ROLE_ELEMENT_NAME:
       if (parser->m_elementDeclHandler) {
         parser->m_declElementType = getElementType(parser, enc, s, next);
-        if (!parser->m_declElementType)
+        if (! parser->m_declElementType)
           return XML_ERROR_NO_MEMORY;
         dtd->scaffLevel = 0;
         dtd->scaffCount = 0;
@@ -5154,18 +4927,19 @@ doProlog(XML_Parser parser,
     case XML_ROLE_CONTENT_EMPTY:
       if (dtd->in_eldecl) {
         if (parser->m_elementDeclHandler) {
-          XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content));
-          if (!content)
+          XML_Content *content
+              = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
+          if (! content)
             return XML_ERROR_NO_MEMORY;
           content->quant = XML_CQUANT_NONE;
           content->name = NULL;
           content->numchildren = 0;
           content->children = NULL;
-          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
-                           XML_CTYPE_ANY :
-                           XML_CTYPE_EMPTY);
+          content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
+                                                          : XML_CTYPE_EMPTY);
           *eventEndPP = s;
-          parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content);
+          parser->m_elementDeclHandler(
+              parser->m_handlerArg, parser->m_declElementType->name, content);
           handleDefault = XML_FALSE;
         }
         dtd->in_eldecl = XML_FALSE;
@@ -5197,22 +4971,22 @@ doProlog(XML_Parser parser,
         ELEMENT_TYPE *el;
         const XML_Char *name;
         int nameLen;
-        const char *nxt = (quant == XML_CQUANT_NONE
-                           ? next
-                           : next - enc->minBytesPerChar);
+        const char *nxt
+            = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
         int myindex = nextScaffoldPart(parser);
         if (myindex < 0)
           return XML_ERROR_NO_MEMORY;
         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
         dtd->scaffold[myindex].quant = quant;
         el = getElementType(parser, enc, s, nxt);
-        if (!el)
+        if (! el)
           return XML_ERROR_NO_MEMORY;
         name = el->name;
         dtd->scaffold[myindex].name = name;
         nameLen = 0;
-        for (; name[nameLen++]; );
-        dtd->contentStringLen +=  nameLen;
+        for (; name[nameLen++];)
+          ;
+        dtd->contentStringLen += nameLen;
         if (parser->m_elementDeclHandler)
           handleDefault = XML_FALSE;
       }
@@ -5236,12 +5010,13 @@ doProlog(XML_Parser parser,
         dtd->scaffLevel--;
         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
         if (dtd->scaffLevel == 0) {
-          if (!handleDefault) {
+          if (! handleDefault) {
             XML_Content *model = build_model(parser);
-            if (!model)
+            if (! model)
               return XML_ERROR_NO_MEMORY;
             *eventEndPP = s;
-            parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model);
+            parser->m_elementDeclHandler(
+                parser->m_handlerArg, parser->m_declElementType->name, model);
           }
           dtd->in_eldecl = XML_FALSE;
           dtd->contentStringLen = 0;
@@ -5251,12 +5026,12 @@ doProlog(XML_Parser parser,
       /* End element declaration stuff */
 
     case XML_ROLE_PI:
-      if (!reportProcessingInstruction(parser, enc, s, next))
+      if (! reportProcessingInstruction(parser, enc, s, next))
         return XML_ERROR_NO_MEMORY;
       handleDefault = XML_FALSE;
       break;
     case XML_ROLE_COMMENT:
-      if (!reportComment(parser, enc, s, next))
+      if (! reportComment(parser, enc, s, next))
         return XML_ERROR_NO_MEMORY;
       handleDefault = XML_FALSE;
       break;
@@ -5307,11 +5082,8 @@ doProlog(XML_Parser parser,
 }
 
 static enum XML_Error PTRCALL
-epilogProcessor(XML_Parser parser,
-                const char *s,
-                const char *end,
-                const char **nextPtr)
-{
+epilogProcessor(XML_Parser parser, const char *s, const char *end,
+                const char **nextPtr) {
   parser->m_processor = epilogProcessor;
   parser->m_eventPtr = s;
   for (;;) {
@@ -5336,24 +5108,24 @@ epilogProcessor(XML_Parser parser,
         reportDefault(parser, parser->m_encoding, s, next);
       break;
     case XML_TOK_PI:
-      if (!reportProcessingInstruction(parser, parser->m_encoding, s, next))
+      if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
         return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_COMMENT:
-      if (!reportComment(parser, parser->m_encoding, s, next))
+      if (! reportComment(parser, parser->m_encoding, s, next))
         return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_INVALID:
       parser->m_eventPtr = next;
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL:
-      if (!parser->m_parsingStatus.finalBuffer) {
+      if (! parser->m_parsingStatus.finalBuffer) {
         *nextPtr = s;
         return XML_ERROR_NONE;
       }
       return XML_ERROR_UNCLOSED_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
-      if (!parser->m_parsingStatus.finalBuffer) {
+      if (! parser->m_parsingStatus.finalBuffer) {
         *nextPtr = s;
         return XML_ERROR_NONE;
       }
@@ -5368,15 +5140,13 @@ epilogProcessor(XML_Parser parser,
       return XML_ERROR_NONE;
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
-    default: ;
+    default:;
     }
   }
 }
 
 static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity,
-                      XML_Bool betweenDecl)
-{
+processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
   const char *textStart, *textEnd;
   const char *next;
   enum XML_Error result;
@@ -5385,10 +5155,10 @@ processInternalEntity(XML_Parser parser, ENTITY *entity,
   if (parser->m_freeInternalEntities) {
     openEntity = parser->m_freeInternalEntities;
     parser->m_freeInternalEntities = openEntity->next;
-  }
-  else {
-    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
-    if (!openEntity)
+  } else {
+    openEntity
+        = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
+    if (! openEntity)
       return XML_ERROR_NO_MEMORY;
   }
   entity->open = XML_TRUE;
@@ -5407,21 +5177,20 @@ processInternalEntity(XML_Parser parser, ENTITY *entity,
 
 #ifdef XML_DTD
   if (entity->is_param) {
-    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
-    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
-                      next, &next, XML_FALSE);
-  }
-  else
+    int tok
+        = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
+    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
+                      tok, next, &next, XML_FALSE, XML_FALSE);
+  else
 #endif /* XML_DTD */
-    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart,
-                       textEnd, &next, XML_FALSE);
+    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
+                       textStart, textEnd, &next, XML_FALSE);
 
   if (result == XML_ERROR_NONE) {
     if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
       entity->processed = (int)(next - textStart);
       parser->m_processor = internalEntityProcessor;
-    }
-    else {
+    } else {
       entity->open = XML_FALSE;
       parser->m_openInternalEntities = openEntity->next;
       /* put openEntity back in list of free instances */
@@ -5433,17 +5202,14 @@ processInternalEntity(XML_Parser parser, ENTITY *entity,
 }
 
 static enum XML_Error PTRCALL
-internalEntityProcessor(XML_Parser parser,
-                        const char *s,
-                        const char *end,
-                        const char **nextPtr)
-{
+internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
+                        const char **nextPtr) {
   ENTITY *entity;
   const char *textStart, *textEnd;
   const char *next;
   enum XML_Error result;
   OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
-  if (!openEntity)
+  if (! openEntity)
     return XML_ERROR_UNEXPECTED_STATE;
 
   entity = openEntity->entity;
@@ -5454,22 +5220,23 @@ internalEntityProcessor(XML_Parser parser,
 
 #ifdef XML_DTD
   if (entity->is_param) {
-    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
-    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
-                      next, &next, XML_FALSE);
-  }
-  else
+    int tok
+        = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
+    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
+                      tok, next, &next, XML_FALSE, XML_TRUE);
+  else
 #endif /* XML_DTD */
-    result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding,
-                       textStart, textEnd, &next, XML_FALSE);
+    result = doContent(parser, openEntity->startTagLevel,
+                       parser->m_internalEncoding, textStart, textEnd, &next,
+                       XML_FALSE);
 
   if (result != XML_ERROR_NONE)
     return result;
-  else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
+  else if (textEnd != next
+           && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
     entity->processed = (int)(next - (char *)entity->textPtr);
     return result;
-  }
-  else {
+  } else {
     entity->open = XML_FALSE;
     parser->m_openInternalEntities = openEntity->next;
     /* put openEntity back in list of free instances */
@@ -5483,49 +5250,45 @@ internalEntityProcessor(XML_Parser parser,
     parser->m_processor = prologProcessor;
     tok = XmlPrologTok(parser->m_encoding, s, end, &next);
     return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-                    (XML_Bool)!parser->m_parsingStatus.finalBuffer);
-  }
-  else
+                    (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
+  } else
 #endif /* XML_DTD */
   {
     parser->m_processor = contentProcessor;
     /* see externalEntityContentProcessor vs contentProcessor */
-    return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end,
-                     nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
+    return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
+                     s, end, nextPtr,
+                     (XML_Bool)! parser->m_parsingStatus.finalBuffer);
   }
 }
 
 static enum XML_Error PTRCALL
-errorProcessor(XML_Parser parser,
-               const char *UNUSED_P(s),
-               const char *UNUSED_P(end),
-               const char **UNUSED_P(nextPtr))
-{
+errorProcessor(XML_Parser parser, const char *s, const char *end,
+               const char **nextPtr) {
+  UNUSED_P(s);
+  UNUSED_P(end);
+  UNUSED_P(nextPtr);
   return parser->m_errorCode;
 }
 
 static enum XML_Error
 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-                    const char *ptr, const char *end,
-                    STRING_POOL *pool)
-{
-  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
-                                               end, pool);
+                    const char *ptr, const char *end, STRING_POOL *pool) {
+  enum XML_Error result
+      = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
   if (result)
     return result;
-  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+  if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
     poolChop(pool);
-  if (!poolAppendChar(pool, XML_T('\0')))
+  if (! poolAppendChar(pool, XML_T('\0')))
     return XML_ERROR_NO_MEMORY;
   return XML_ERROR_NONE;
 }
 
 static enum XML_Error
 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-                     const char *ptr, const char *end,
-                     STRING_POOL *pool)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+                     const char *ptr, const char *end, STRING_POOL *pool) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   for (;;) {
     const char *next;
     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
@@ -5540,38 +5303,35 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
       if (enc == parser->m_encoding)
         parser->m_eventPtr = ptr;
       return XML_ERROR_INVALID_TOKEN;
-    case XML_TOK_CHAR_REF:
-      {
-        XML_Char buf[XML_ENCODE_MAX];
-        int i;
-        int n = XmlCharRefNumber(enc, ptr);
-        if (n < 0) {
-          if (enc == parser->m_encoding)
-            parser->m_eventPtr = ptr;
-          return XML_ERROR_BAD_CHAR_REF;
-        }
-        if (!isCdata
-            && n == 0x20 /* space */
-            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-          break;
-        n = XmlEncode(n, (ICHAR *)buf);
-        /* The XmlEncode() functions can never return 0 here.  That
-         * error return happens if the code point passed in is either
-         * negative or greater than or equal to 0x110000.  The
-         * XmlCharRefNumber() functions will all return a number
-         * strictly less than 0x110000 or a negative value if an error
-         * occurred.  The negative value is intercepted above, so
-         * XmlEncode() is never passed a value it might return an
-         * error for.
-         */
-        for (i = 0; i < n; i++) {
-          if (!poolAppendChar(pool, buf[i]))
-            return XML_ERROR_NO_MEMORY;
-        }
+    case XML_TOK_CHAR_REF: {
+      XML_Char buf[XML_ENCODE_MAX];
+      int i;
+      int n = XmlCharRefNumber(enc, ptr);
+      if (n < 0) {
+        if (enc == parser->m_encoding)
+          parser->m_eventPtr = ptr;
+        return XML_ERROR_BAD_CHAR_REF;
       }
-      break;
+      if (! isCdata && n == 0x20 /* space */
+          && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+        break;
+      n = XmlEncode(n, (ICHAR *)buf);
+      /* The XmlEncode() functions can never return 0 here.  That
+       * error return happens if the code point passed in is either
+       * negative or greater than or equal to 0x110000.  The
+       * XmlCharRefNumber() functions will all return a number
+       * strictly less than 0x110000 or a negative value if an error
+       * occurred.  The negative value is intercepted above, so
+       * XmlEncode() is never passed a value it might return an
+       * error for.
+       */
+      for (i = 0; i < n; i++) {
+        if (! poolAppendChar(pool, buf[i]))
+          return XML_ERROR_NO_MEMORY;
+      }
+    } break;
     case XML_TOK_DATA_CHARS:
-      if (!poolAppend(pool, enc, ptr, next))
+      if (! poolAppend(pool, enc, ptr, next))
         return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_TRAILING_CR:
@@ -5579,109 +5339,103 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
       /* fall through */
     case XML_TOK_ATTRIBUTE_VALUE_S:
     case XML_TOK_DATA_NEWLINE:
-      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+      if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
         break;
-      if (!poolAppendChar(pool, 0x20))
+      if (! poolAppendChar(pool, 0x20))
         return XML_ERROR_NO_MEMORY;
       break;
-    case XML_TOK_ENTITY_REF:
-      {
-        const XML_Char *name;
-        ENTITY *entity;
-        char checkEntityDecl;
-        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
-                                              ptr + enc->minBytesPerChar,
-                                              next - enc->minBytesPerChar);
-        if (ch) {
-          if (!poolAppendChar(pool, ch))
-                return XML_ERROR_NO_MEMORY;
-          break;
-        }
-        name = poolStoreString(&parser->m_temp2Pool, enc,
-                               ptr + enc->minBytesPerChar,
-                               next - enc->minBytesPerChar);
-        if (!name)
+    case XML_TOK_ENTITY_REF: {
+      const XML_Char *name;
+      ENTITY *entity;
+      char checkEntityDecl;
+      XML_Char ch = (XML_Char)XmlPredefinedEntityName(
+          enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
+      if (ch) {
+        if (! poolAppendChar(pool, ch))
           return XML_ERROR_NO_MEMORY;
-        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
-        poolDiscard(&parser->m_temp2Pool);
-        /* First, determine if a check for an existing declaration is needed;
-           if yes, check that the entity exists, and that it is internal.
-        */
-        if (pool == &dtd->pool)  /* are we called from prolog? */
-          checkEntityDecl =
+        break;
+      }
+      name = poolStoreString(&parser->m_temp2Pool, enc,
+                             ptr + enc->minBytesPerChar,
+                             next - enc->minBytesPerChar);
+      if (! name)
+        return XML_ERROR_NO_MEMORY;
+      entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
+      poolDiscard(&parser->m_temp2Pool);
+      /* First, determine if a check for an existing declaration is needed;
+         if yes, check that the entity exists, and that it is internal.
+      */
+      if (pool == &dtd->pool) /* are we called from prolog? */
+        checkEntityDecl =
 #ifdef XML_DTD
-              parser->m_prologState.documentEntity &&
+            parser->m_prologState.documentEntity &&
 #endif /* XML_DTD */
-              (dtd->standalone
-               ? !parser->m_openInternalEntities
-               : !dtd->hasParamEntityRefs);
-        else /* if (pool == &parser->m_tempPool): we are called from content */
-          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
-        if (checkEntityDecl) {
-          if (!entity)
-            return XML_ERROR_UNDEFINED_ENTITY;
-          else if (!entity->is_internal)
-            return XML_ERROR_ENTITY_DECLARED_IN_PE;
-        }
-        else if (!entity) {
-          /* Cannot report skipped entity here - see comments on
-             parser->m_skippedEntityHandler.
-          if (parser->m_skippedEntityHandler)
-            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
-          */
-          /* Cannot call the default handler because this would be
-             out of sync with the call to the startElementHandler.
-          if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
-            reportDefault(parser, enc, ptr, next);
-          */
-          break;
-        }
-        if (entity->open) {
-          if (enc == parser->m_encoding) {
-            /* It does not appear that this line can be executed.
-             *
-             * The "if (entity->open)" check catches recursive entity
-             * definitions.  In order to be called with an open
-             * entity, it must have gone through this code before and
-             * been through the recursive call to
-             * appendAttributeValue() some lines below.  That call
-             * sets the local encoding ("enc") to the parser's
-             * internal encoding (internal_utf8 or internal_utf16),
-             * which can never be the same as the principle encoding.
-             * It doesn't appear there is another code path that gets
-             * here with entity->open being TRUE.
-             *
-             * Since it is not certain that this logic is watertight,
-             * we keep the line and merely exclude it from coverage
-             * tests.
-             */
-            parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
-          }
-          return XML_ERROR_RECURSIVE_ENTITY_REF;
-        }
-        if (entity->notation) {
-          if (enc == parser->m_encoding)
-            parser->m_eventPtr = ptr;
-          return XML_ERROR_BINARY_ENTITY_REF;
-        }
-        if (!entity->textPtr) {
-          if (enc == parser->m_encoding)
-            parser->m_eventPtr = ptr;
-          return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
-        }
-        else {
-          enum XML_Error result;
-          const XML_Char *textEnd = entity->textPtr + entity->textLen;
-          entity->open = XML_TRUE;
-          result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata,
-                                        (char *)entity->textPtr,
-                                        (char *)textEnd, pool);
-          entity->open = XML_FALSE;
-          if (result)
-            return result;
+            (dtd->standalone ? ! parser->m_openInternalEntities
+                             : ! dtd->hasParamEntityRefs);
+      else /* if (pool == &parser->m_tempPool): we are called from content */
+        checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
+      if (checkEntityDecl) {
+        if (! entity)
+          return XML_ERROR_UNDEFINED_ENTITY;
+        else if (! entity->is_internal)
+          return XML_ERROR_ENTITY_DECLARED_IN_PE;
+      } else if (! entity) {
+        /* Cannot report skipped entity here - see comments on
+           parser->m_skippedEntityHandler.
+        if (parser->m_skippedEntityHandler)
+          parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
+        */
+        /* Cannot call the default handler because this would be
+           out of sync with the call to the startElementHandler.
+        if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
+          reportDefault(parser, enc, ptr, next);
+        */
+        break;
+      }
+      if (entity->open) {
+        if (enc == parser->m_encoding) {
+          /* It does not appear that this line can be executed.
+           *
+           * The "if (entity->open)" check catches recursive entity
+           * definitions.  In order to be called with an open
+           * entity, it must have gone through this code before and
+           * been through the recursive call to
+           * appendAttributeValue() some lines below.  That call
+           * sets the local encoding ("enc") to the parser's
+           * internal encoding (internal_utf8 or internal_utf16),
+           * which can never be the same as the principle encoding.
+           * It doesn't appear there is another code path that gets
+           * here with entity->open being TRUE.
+           *
+           * Since it is not certain that this logic is watertight,
+           * we keep the line and merely exclude it from coverage
+           * tests.
+           */
+          parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
         }
+        return XML_ERROR_RECURSIVE_ENTITY_REF;
       }
-      break;
+      if (entity->notation) {
+        if (enc == parser->m_encoding)
+          parser->m_eventPtr = ptr;
+        return XML_ERROR_BINARY_ENTITY_REF;
+      }
+      if (! entity->textPtr) {
+        if (enc == parser->m_encoding)
+          parser->m_eventPtr = ptr;
+        return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+      } else {
+        enum XML_Error result;
+        const XML_Char *textEnd = entity->textPtr + entity->textLen;
+        entity->open = XML_TRUE;
+        result = appendAttributeValue(parser, parser->m_internalEncoding,
+                                      isCdata, (char *)entity->textPtr,
+                                      (char *)textEnd, pool);
+        entity->open = XML_FALSE;
+        if (result)
+          return result;
+      }
+    } break;
     default:
       /* The only token returned by XmlAttributeValueTok() that does
        * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
@@ -5705,12 +5459,9 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
 }
 
 static enum XML_Error
-storeEntityValue(XML_Parser parser,
-                 const ENCODING *enc,
-                 const char *entityTextPtr,
-                 const char *entityTextEnd)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+storeEntityValue(XML_Parser parser, const ENCODING *enc,
+                 const char *entityTextPtr, const char *entityTextEnd) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   STRING_POOL *pool = &(dtd->entityValuePool);
   enum XML_Error result = XML_ERROR_NONE;
 #ifdef XML_DTD
@@ -5720,8 +5471,8 @@ storeEntityValue(XML_Parser parser,
   /* never return Null for the value argument in EntityDeclHandler,
      since this would indicate an external entity; therefore we
      have to make sure that entityValuePool.start is not null */
-  if (!pool->blocks) {
-    if (!poolGrow(pool))
+  if (! pool->blocks) {
+    if (! poolGrow(pool))
       return XML_ERROR_NO_MEMORY;
   }
 
@@ -5737,13 +5488,13 @@ storeEntityValue(XML_Parser parser,
         name = poolStoreString(&parser->m_tempPool, enc,
                                entityTextPtr + enc->minBytesPerChar,
                                next - enc->minBytesPerChar);
-        if (!name) {
+        if (! name) {
           result = XML_ERROR_NO_MEMORY;
           goto endEntityValue;
         }
         entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
         poolDiscard(&parser->m_tempPool);
-        if (!entity) {
+        if (! entity) {
           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
           /* cannot report skipped entity here - see comments on
              parser->m_skippedEntityHandler
@@ -5763,29 +5514,23 @@ storeEntityValue(XML_Parser parser,
           if (parser->m_externalEntityRefHandler) {
             dtd->paramEntityRead = XML_FALSE;
             entity->open = XML_TRUE;
-            if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
-                                          0,
-                                          entity->base,
-                                          entity->systemId,
-                                          entity->publicId)) {
+            if (! parser->m_externalEntityRefHandler(
+                    parser->m_externalEntityRefHandlerArg, 0, entity->base,
+                    entity->systemId, entity->publicId)) {
               entity->open = XML_FALSE;
               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
               goto endEntityValue;
             }
             entity->open = XML_FALSE;
-            if (!dtd->paramEntityRead)
+            if (! dtd->paramEntityRead)
               dtd->keepProcessing = dtd->standalone;
-          }
-          else
+          } else
             dtd->keepProcessing = dtd->standalone;
-        }
-        else {
+        } else {
           entity->open = XML_TRUE;
-          result = storeEntityValue(parser,
-                                    parser->m_internalEncoding,
-                                    (char *)entity->textPtr,
-                                    (char *)(entity->textPtr
-                                             + entity->textLen));
+          result = storeEntityValue(
+              parser, parser->m_internalEncoding, (char *)entity->textPtr,
+              (char *)(entity->textPtr + entity->textLen));
           entity->open = XML_FALSE;
           if (result)
             goto endEntityValue;
@@ -5803,7 +5548,7 @@ storeEntityValue(XML_Parser parser,
       goto endEntityValue;
     case XML_TOK_ENTITY_REF:
     case XML_TOK_DATA_CHARS:
-      if (!poolAppend(pool, enc, entityTextPtr, next)) {
+      if (! poolAppend(pool, enc, entityTextPtr, next)) {
         result = XML_ERROR_NO_MEMORY;
         goto endEntityValue;
       }
@@ -5812,42 +5557,40 @@ storeEntityValue(XML_Parser parser,
       next = entityTextPtr + enc->minBytesPerChar;
       /* fall through */
     case XML_TOK_DATA_NEWLINE:
-      if (pool->end == pool->ptr && !poolGrow(pool)) {
-              result = XML_ERROR_NO_MEMORY;
+      if (pool->end == pool->ptr && ! poolGrow(pool)) {
+        result = XML_ERROR_NO_MEMORY;
         goto endEntityValue;
       }
       *(pool->ptr)++ = 0xA;
       break;
-    case XML_TOK_CHAR_REF:
-      {
-        XML_Char buf[XML_ENCODE_MAX];
-        int i;
-        int n = XmlCharRefNumber(enc, entityTextPtr);
-        if (n < 0) {
-          if (enc == parser->m_encoding)
-            parser->m_eventPtr = entityTextPtr;
-          result = XML_ERROR_BAD_CHAR_REF;
+    case XML_TOK_CHAR_REF: {
+      XML_Char buf[XML_ENCODE_MAX];
+      int i;
+      int n = XmlCharRefNumber(enc, entityTextPtr);
+      if (n < 0) {
+        if (enc == parser->m_encoding)
+          parser->m_eventPtr = entityTextPtr;
+        result = XML_ERROR_BAD_CHAR_REF;
+        goto endEntityValue;
+      }
+      n = XmlEncode(n, (ICHAR *)buf);
+      /* The XmlEncode() functions can never return 0 here.  That
+       * error return happens if the code point passed in is either
+       * negative or greater than or equal to 0x110000.  The
+       * XmlCharRefNumber() functions will all return a number
+       * strictly less than 0x110000 or a negative value if an error
+       * occurred.  The negative value is intercepted above, so
+       * XmlEncode() is never passed a value it might return an
+       * error for.
+       */
+      for (i = 0; i < n; i++) {
+        if (pool->end == pool->ptr && ! poolGrow(pool)) {
+          result = XML_ERROR_NO_MEMORY;
           goto endEntityValue;
         }
-        n = XmlEncode(n, (ICHAR *)buf);
-        /* The XmlEncode() functions can never return 0 here.  That
-         * error return happens if the code point passed in is either
-         * negative or greater than or equal to 0x110000.  The
-         * XmlCharRefNumber() functions will all return a number
-         * strictly less than 0x110000 or a negative value if an error
-         * occurred.  The negative value is intercepted above, so
-         * XmlEncode() is never passed a value it might return an
-         * error for.
-         */
-        for (i = 0; i < n; i++) {
-          if (pool->end == pool->ptr && !poolGrow(pool)) {
-            result = XML_ERROR_NO_MEMORY;
-            goto endEntityValue;
-          }
-          *(pool->ptr)++ = buf[i];
-        }
+        *(pool->ptr)++ = buf[i];
       }
-      break;
+    } break;
     case XML_TOK_PARTIAL:
       if (enc == parser->m_encoding)
         parser->m_eventPtr = entityTextPtr;
@@ -5882,8 +5625,7 @@ endEntityValue:
 }
 
 static void FASTCALL
-normalizeLines(XML_Char *s)
-{
+normalizeLines(XML_Char *s) {
   XML_Char *p;
   for (;; s++) {
     if (*s == XML_T('\0'))
@@ -5897,8 +5639,7 @@ normalizeLines(XML_Char *s)
       *p++ = 0xA;
       if (*++s == 0xA)
         s++;
-    }
-    else
+    } else
       *p++ = *s++;
   } while (*s);
   *p = XML_T('\0');
@@ -5906,12 +5647,11 @@ normalizeLines(XML_Char *s)
 
 static int
 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
-                            const char *start, const char *end)
-{
+                            const char *start, const char *end) {
   const XML_Char *target;
   XML_Char *data;
   const char *tem;
-  if (!parser->m_processingInstructionHandler) {
+  if (! parser->m_processingInstructionHandler) {
     if (parser->m_defaultHandler)
       reportDefault(parser, enc, start, end);
     return 1;
@@ -5919,13 +5659,12 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
   start += enc->minBytesPerChar * 2;
   tem = start + XmlNameLength(enc, start);
   target = poolStoreString(&parser->m_tempPool, enc, start, tem);
-  if (!target)
+  if (! target)
     return 0;
   poolFinish(&parser->m_tempPool);
-  data = poolStoreString(&parser->m_tempPool, enc,
-                        XmlSkipS(enc, tem),
-                        end - enc->minBytesPerChar*2);
-  if (!data)
+  data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
+                         end - enc->minBytesPerChar * 2);
+  if (! data)
     return 0;
   normalizeLines(data);
   parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
@@ -5934,20 +5673,18 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
 }
 
 static int
-reportComment(XML_Parser parser, const ENCODING *enc,
-              const char *start, const char *end)
-{
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end) {
   XML_Char *data;
-  if (!parser->m_commentHandler) {
+  if (! parser->m_commentHandler) {
     if (parser->m_defaultHandler)
       reportDefault(parser, enc, start, end);
     return 1;
   }
-  data = poolStoreString(&parser->m_tempPool,
-                         enc,
+  data = poolStoreString(&parser->m_tempPool, enc,
                          start + enc->minBytesPerChar * 4,
                          end - enc->minBytesPerChar * 3);
-  if (!data)
+  if (! data)
     return 0;
   normalizeLines(data);
   parser->m_commentHandler(parser->m_handlerArg, data);
@@ -5956,9 +5693,8 @@ reportComment(XML_Parser parser, const ENCODING *enc,
 }
 
 static void
-reportDefault(XML_Parser parser, const ENCODING *enc,
-              const char *s, const char *end)
-{
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
+              const char *end) {
   if (MUST_CONVERT(enc, s)) {
     enum XML_Convert_Result convert_res;
     const char **eventPP;
@@ -5966,8 +5702,7 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
     if (enc == parser->m_encoding) {
       eventPP = &parser->m_eventPtr;
       eventEndPP = &parser->m_eventEndPtr;
-    }
-    else {
+    } else {
       /* To get here, two things must be true; the parser must be
        * using a character encoding that is not the same as the
        * encoding passed in, and the encoding passed in must need
@@ -5990,21 +5725,22 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
     }
     do {
       ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
-      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
+      convert_res
+          = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
       *eventEndPP = s;
-      parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+      parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
+                               (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
       *eventPP = s;
-    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
-  }
-  else
-    parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
+    } while ((convert_res != XML_CONVERT_COMPLETED)
+             && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
+  } else
+    parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
+                             (int)((XML_Char *)end - (XML_Char *)s));
 }
 
-
 static int
 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
-                XML_Bool isId, const XML_Char *value, XML_Parser parser)
-{
+                XML_Bool isId, const XML_Char *value, XML_Parser parser) {
   DEFAULT_ATTRIBUTE *att;
   if (value || isId) {
     /* The handling of default attributes gets messed up if we have
@@ -6013,24 +5749,23 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
     for (i = 0; i < type->nDefaultAtts; i++)
       if (attId == type->defaultAtts[i].id)
         return 1;
-    if (isId && !type->idAtt && !attId->xmlns)
+    if (isId && ! type->idAtt && ! attId->xmlns)
       type->idAtt = attId;
   }
   if (type->nDefaultAtts == type->allocDefaultAtts) {
     if (type->allocDefaultAtts == 0) {
       type->allocDefaultAtts = 8;
-      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts
-                            * sizeof(DEFAULT_ATTRIBUTE));
-      if (!type->defaultAtts) {
+      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
+          parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (! type->defaultAtts) {
         type->allocDefaultAtts = 0;
         return 0;
       }
-    }
-    else {
+    } else {
       DEFAULT_ATTRIBUTE *temp;
       int count = type->allocDefaultAtts * 2;
-      temp = (DEFAULT_ATTRIBUTE *)
-        REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+      temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
+                                          (count * sizeof(DEFAULT_ATTRIBUTE)));
       if (temp == NULL)
         return 0;
       type->allocDefaultAtts = count;
@@ -6041,30 +5776,29 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
   att->id = attId;
   att->value = value;
   att->isCdata = isCdata;
-  if (!isCdata)
+  if (! isCdata)
     attId->maybeTokenized = XML_TRUE;
   type->nDefaultAtts += 1;
   return 1;
 }
 
 static int
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   const XML_Char *name;
   for (name = elementType->name; *name; name++) {
     if (*name == XML_T(ASCII_COLON)) {
       PREFIX *prefix;
       const XML_Char *s;
       for (s = elementType->name; s != name; s++) {
-        if (!poolAppendChar(&dtd->pool, *s))
+        if (! poolAppendChar(&dtd->pool, *s))
           return 0;
       }
-      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+      if (! poolAppendChar(&dtd->pool, XML_T('\0')))
         return 0;
       prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
                                 sizeof(PREFIX));
-      if (!prefix)
+      if (! prefix)
         return 0;
       if (prefix->name == poolStart(&dtd->pool))
         poolFinish(&dtd->pool);
@@ -6078,55 +5812,53 @@ setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
 }
 
 static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc,
-               const char *start, const char *end)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+               const char *end) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   ATTRIBUTE_ID *id;
   const XML_Char *name;
-  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+  if (! poolAppendChar(&dtd->pool, XML_T('\0')))
     return NULL;
   name = poolStoreString(&dtd->pool, enc, start, end);
-  if (!name)
+  if (! name)
     return NULL;
   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
   ++name;
-  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
-  if (!id)
+  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
+                              sizeof(ATTRIBUTE_ID));
+  if (! id)
     return NULL;
   if (id->name != name)
     poolDiscard(&dtd->pool);
   else {
     poolFinish(&dtd->pool);
-    if (!parser->m_ns)
+    if (! parser->m_ns)
       ;
-    else if (name[0] == XML_T(ASCII_x)
-        && name[1] == XML_T(ASCII_m)
-        && name[2] == XML_T(ASCII_l)
-        && name[3] == XML_T(ASCII_n)
-        && name[4] == XML_T(ASCII_s)
-        && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
+    else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
+             && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
+             && name[4] == XML_T(ASCII_s)
+             && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
       if (name[5] == XML_T('\0'))
         id->prefix = &dtd->defaultPrefix;
       else
-        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
+        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
+                                      sizeof(PREFIX));
       id->xmlns = XML_TRUE;
-    }
-    else {
+    } else {
       int i;
       for (i = 0; name[i]; i++) {
         /* attributes without prefix are *not* in the default namespace */
         if (name[i] == XML_T(ASCII_COLON)) {
           int j;
           for (j = 0; j < i; j++) {
-            if (!poolAppendChar(&dtd->pool, name[j]))
+            if (! poolAppendChar(&dtd->pool, name[j]))
               return NULL;
           }
-          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+          if (! poolAppendChar(&dtd->pool, XML_T('\0')))
             return NULL;
-          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
-                                        sizeof(PREFIX));
-          if (!id->prefix)
+          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
+                                        poolStart(&dtd->pool), sizeof(PREFIX));
+          if (! id->prefix)
             return NULL;
           if (id->prefix->name == poolStart(&dtd->pool))
             poolFinish(&dtd->pool);
@@ -6143,22 +5875,22 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
 #define CONTEXT_SEP XML_T(ASCII_FF)
 
 static const XML_Char *
-getContext(XML_Parser parser)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+getContext(XML_Parser parser) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   HASH_TABLE_ITER iter;
   XML_Bool needSep = XML_FALSE;
 
   if (dtd->defaultPrefix.binding) {
     int i;
     int len;
-    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
+    if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
       return NULL;
     len = dtd->defaultPrefix.binding->uriLen;
     if (parser->m_namespaceSeparator)
       len--;
     for (i = 0; i < len; i++) {
-      if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) {
+      if (! poolAppendChar(&parser->m_tempPool,
+                           dtd->defaultPrefix.binding->uri[i])) {
         /* Because of memory caching, I don't believe this line can be
          * executed.
          *
@@ -6190,9 +5922,9 @@ getContext(XML_Parser parser)
     int len;
     const XML_Char *s;
     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
-    if (!prefix)
+    if (! prefix)
       break;
-    if (!prefix->binding) {
+    if (! prefix->binding) {
       /* This test appears to be (justifiable) paranoia.  There does
        * not seem to be a way of injecting a prefix without a binding
        * that doesn't get errored long before this function is called.
@@ -6201,98 +5933,96 @@ getContext(XML_Parser parser)
        */
       continue; /* LCOV_EXCL_LINE */
     }
-    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
+    if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
       return NULL;
     for (s = prefix->name; *s; s++)
-      if (!poolAppendChar(&parser->m_tempPool, *s))
+      if (! poolAppendChar(&parser->m_tempPool, *s))
         return NULL;
-    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
+    if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
       return NULL;
     len = prefix->binding->uriLen;
     if (parser->m_namespaceSeparator)
       len--;
     for (i = 0; i < len; i++)
-      if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
+      if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
         return NULL;
     needSep = XML_TRUE;
   }
 
-
   hashTableIterInit(&iter, &(dtd->generalEntities));
   for (;;) {
     const XML_Char *s;
     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
-    if (!e)
+    if (! e)
       break;
-    if (!e->open)
+    if (! e->open)
       continue;
-    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
+    if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
       return NULL;
     for (s = e->name; *s; s++)
-      if (!poolAppendChar(&parser->m_tempPool, *s))
+      if (! poolAppendChar(&parser->m_tempPool, *s))
         return 0;
     needSep = XML_TRUE;
   }
 
-  if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
+  if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
     return NULL;
   return parser->m_tempPool.start;
 }
 
 static XML_Bool
-setContext(XML_Parser parser, const XML_Char *context)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+setContext(XML_Parser parser, const XML_Char *context) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   const XML_Char *s = context;
 
   while (*context != XML_T('\0')) {
     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
       ENTITY *e;
-      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
+      if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
         return XML_FALSE;
-      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0);
+      e = (ENTITY *)lookup(parser, &dtd->generalEntities,
+                           poolStart(&parser->m_tempPool), 0);
       if (e)
         e->open = XML_TRUE;
       if (*s != XML_T('\0'))
         s++;
       context = s;
       poolDiscard(&parser->m_tempPool);
-    }
-    else if (*s == XML_T(ASCII_EQUALS)) {
+    } else if (*s == XML_T(ASCII_EQUALS)) {
       PREFIX *prefix;
       if (poolLength(&parser->m_tempPool) == 0)
         prefix = &dtd->defaultPrefix;
       else {
-        if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
+        if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
           return XML_FALSE;
-        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool),
-                                  sizeof(PREFIX));
-        if (!prefix)
+        prefix
+            = (PREFIX *)lookup(parser, &dtd->prefixes,
+                               poolStart(&parser->m_tempPool), sizeof(PREFIX));
+        if (! prefix)
           return XML_FALSE;
         if (prefix->name == poolStart(&parser->m_tempPool)) {
           prefix->name = poolCopyString(&dtd->pool, prefix->name);
-          if (!prefix->name)
+          if (! prefix->name)
             return XML_FALSE;
         }
         poolDiscard(&parser->m_tempPool);
       }
-      for (context = s + 1;
-           *context != CONTEXT_SEP && *context != XML_T('\0');
+      for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
            context++)
-        if (!poolAppendChar(&parser->m_tempPool, *context))
+        if (! poolAppendChar(&parser->m_tempPool, *context))
           return XML_FALSE;
-      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
+      if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
         return XML_FALSE;
       if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
-                     &parser->m_inheritedBindings) != XML_ERROR_NONE)
+                     &parser->m_inheritedBindings)
+          != XML_ERROR_NONE)
         return XML_FALSE;
       poolDiscard(&parser->m_tempPool);
       if (*context != XML_T('\0'))
         ++context;
       s = context;
-    }
-    else {
-      if (!poolAppendChar(&parser->m_tempPool, *s))
+    } else {
+      if (! poolAppendChar(&parser->m_tempPool, *s))
         return XML_FALSE;
       s++;
     }
@@ -6301,8 +6031,7 @@ setContext(XML_Parser parser, const XML_Char *context)
 }
 
 static void FASTCALL
-normalizePublicId(XML_Char *publicId)
-{
+normalizePublicId(XML_Char *publicId) {
   XML_Char *p = publicId;
   XML_Char *s;
   for (s = publicId; *s; s++) {
@@ -6323,8 +6052,7 @@ normalizePublicId(XML_Char *publicId)
 }
 
 static DTD *
-dtdCreate(const XML_Memory_Handling_Suite *ms)
-{
+dtdCreate(const XML_Memory_Handling_Suite *ms) {
   DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
   if (p == NULL)
     return p;
@@ -6356,13 +6084,12 @@ dtdCreate(const XML_Memory_Handling_Suite *ms)
 }
 
 static void
-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
-{
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
   HASH_TABLE_ITER iter;
   hashTableIterInit(&iter, &(p->elementTypes));
   for (;;) {
     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-    if (!e)
+    if (! e)
       break;
     if (e->allocDefaultAtts != 0)
       ms->free_fcn(e->defaultAtts);
@@ -6398,13 +6125,12 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
 }
 
 static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
-{
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
   HASH_TABLE_ITER iter;
   hashTableIterInit(&iter, &(p->elementTypes));
   for (;;) {
     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-    if (!e)
+    if (! e)
       break;
     if (e->allocDefaultAtts != 0)
       ms->free_fcn(e->defaultAtts);
@@ -6429,8 +6155,8 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
    The new DTD has already been initialized.
 */
 static int
-dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
-{
+dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
+        const XML_Memory_Handling_Suite *ms) {
   HASH_TABLE_ITER iter;
 
   /* Copy the prefix table. */
@@ -6439,12 +6165,12 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
   for (;;) {
     const XML_Char *name;
     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
-    if (!oldP)
+    if (! oldP)
       break;
     name = poolCopyString(&(newDtd->pool), oldP->name);
-    if (!name)
+    if (! name)
       return 0;
-    if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
+    if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
       return 0;
   }
 
@@ -6457,18 +6183,18 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
     const XML_Char *name;
     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
 
-    if (!oldA)
+    if (! oldA)
       break;
     /* Remember to allocate the scratch byte before the name. */
-    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+    if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
       return 0;
     name = poolCopyString(&(newDtd->pool), oldA->name);
-    if (!name)
+    if (! name)
       return 0;
     ++name;
     newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
                                   sizeof(ATTRIBUTE_ID));
-    if (!newA)
+    if (! newA)
       return 0;
     newA->maybeTokenized = oldA->maybeTokenized;
     if (oldA->prefix) {
@@ -6490,57 +6216,52 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
     ELEMENT_TYPE *newE;
     const XML_Char *name;
     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-    if (!oldE)
+    if (! oldE)
       break;
     name = poolCopyString(&(newDtd->pool), oldE->name);
-    if (!name)
+    if (! name)
       return 0;
     newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
                                   sizeof(ELEMENT_TYPE));
-    if (!newE)
+    if (! newE)
       return 0;
     if (oldE->nDefaultAtts) {
-      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
-          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
-      if (!newE->defaultAtts) {
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
+          oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (! newE->defaultAtts) {
         return 0;
       }
     }
     if (oldE->idAtt)
-      newE->idAtt = (ATTRIBUTE_ID *)
-          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
+      newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
+                                           oldE->idAtt->name, 0);
     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
     if (oldE->prefix)
       newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
                                       oldE->prefix->name, 0);
     for (i = 0; i < newE->nDefaultAtts; i++) {
-      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
-          lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
+          oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
       if (oldE->defaultAtts[i].value) {
         newE->defaultAtts[i].value
             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
-        if (!newE->defaultAtts[i].value)
+        if (! newE->defaultAtts[i].value)
           return 0;
-      }
-      else
+      } else
         newE->defaultAtts[i].value = NULL;
     }
   }
 
   /* Copy the entity tables. */
-  if (!copyEntityTable(oldParser,
-                       &(newDtd->generalEntities),
-                       &(newDtd->pool),
-                       &(oldDtd->generalEntities)))
-      return 0;
+  if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
+                        &(oldDtd->generalEntities)))
+    return 0;
 
 #ifdef XML_DTD
-  if (!copyEntityTable(oldParser,
-                       &(newDtd->paramEntities),
-                       &(newDtd->pool),
-                       &(oldDtd->paramEntities)))
-      return 0;
+  if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
+                        &(oldDtd->paramEntities)))
+    return 0;
   newDtd->paramEntityRead = oldDtd->paramEntityRead;
 #endif /* XML_DTD */
 
@@ -6557,14 +6278,11 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
   newDtd->scaffIndex = oldDtd->scaffIndex;
 
   return 1;
-}  /* End dtdCopy */
+} /* End dtdCopy */
 
 static int
-copyEntityTable(XML_Parser oldParser,
-                HASH_TABLE *newTable,
-                STRING_POOL *newPool,
-                const HASH_TABLE *oldTable)
-{
+copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
+                STRING_POOL *newPool, const HASH_TABLE *oldTable) {
   HASH_TABLE_ITER iter;
   const XML_Char *cachedOldBase = NULL;
   const XML_Char *cachedNewBase = NULL;
@@ -6575,17 +6293,17 @@ copyEntityTable(XML_Parser oldParser,
     ENTITY *newE;
     const XML_Char *name;
     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
-    if (!oldE)
+    if (! oldE)
       break;
     name = poolCopyString(newPool, oldE->name);
-    if (!name)
+    if (! name)
       return 0;
     newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
-    if (!newE)
+    if (! newE)
       return 0;
     if (oldE->systemId) {
       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
-      if (!tem)
+      if (! tem)
         return 0;
       newE->systemId = tem;
       if (oldE->base) {
@@ -6594,29 +6312,28 @@ copyEntityTable(XML_Parser oldParser,
         else {
           cachedOldBase = oldE->base;
           tem = poolCopyString(newPool, cachedOldBase);
-          if (!tem)
+          if (! tem)
             return 0;
           cachedNewBase = newE->base = tem;
         }
       }
       if (oldE->publicId) {
         tem = poolCopyString(newPool, oldE->publicId);
-        if (!tem)
+        if (! tem)
           return 0;
         newE->publicId = tem;
       }
-    }
-    else {
-      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
-                                            oldE->textLen);
-      if (!tem)
+    } else {
+      const XML_Char *tem
+          = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+      if (! tem)
         return 0;
       newE->textPtr = tem;
       newE->textLen = oldE->textLen;
     }
     if (oldE->notation) {
       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
-      if (!tem)
+      if (! tem)
         return 0;
       newE->notation = tem;
     }
@@ -6629,8 +6346,7 @@ copyEntityTable(XML_Parser oldParser,
 #define INIT_POWER 6
 
 static XML_Bool FASTCALL
-keyeq(KEY s1, KEY s2)
-{
+keyeq(KEY s1, KEY s2) {
   for (; *s1 == *s2; s1++, s2++)
     if (*s1 == 0)
       return XML_TRUE;
@@ -6638,23 +6354,21 @@ keyeq(KEY s1, KEY s2)
 }
 
 static size_t
-keylen(KEY s)
-{
+keylen(KEY s) {
   size_t len = 0;
-  for (; *s; s++, len++);
+  for (; *s; s++, len++)
+    ;
   return len;
 }
 
 static void
-copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
-{
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
   key->k[0] = 0;
   key->k[1] = get_hash_secret_salt(parser);
 }
 
 static unsigned long FASTCALL
-hash(XML_Parser parser, KEY s)
-{
+hash(XML_Parser parser, KEY s) {
   struct siphash state;
   struct sipkey key;
   (void)sip24_valid;
@@ -6665,26 +6379,24 @@ hash(XML_Parser parser, KEY s)
 }
 
 static NAMED *
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
-{
+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
   size_t i;
   if (table->size == 0) {
     size_t tsize;
-    if (!createSize)
+    if (! createSize)
       return NULL;
     table->power = INIT_POWER;
     /* table->size is a power of 2 */
     table->size = (size_t)1 << INIT_POWER;
     tsize = table->size * sizeof(NAMED *);
     table->v = (NAMED **)table->mem->malloc_fcn(tsize);
-    if (!table->v) {
+    if (! table->v) {
       table->size = 0;
       return NULL;
     }
     memset(table->v, 0, tsize);
     i = hash(parser, name) & ((unsigned long)table->size - 1);
-  }
-  else {
+  } else {
     unsigned long h = hash(parser, name);
     unsigned long mask = (unsigned long)table->size - 1;
     unsigned char step = 0;
@@ -6692,11 +6404,11 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
     while (table->v[i]) {
       if (keyeq(name, table->v[i]->name))
         return table->v[i];
-      if (!step)
+      if (! step)
         step = PROBE_STEP(h, mask, table->power);
       i < step ? (i += table->size - step) : (i -= step);
     }
-    if (!createSize)
+    if (! createSize)
       return NULL;
 
     /* check for overflow (table is half full) */
@@ -6706,7 +6418,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
       unsigned long newMask = (unsigned long)newSize - 1;
       size_t tsize = newSize * sizeof(NAMED *);
       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
-      if (!newV)
+      if (! newV)
         return NULL;
       memset(newV, 0, tsize);
       for (i = 0; i < table->size; i++)
@@ -6715,7 +6427,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
           size_t j = newHash & newMask;
           step = 0;
           while (newV[j]) {
-            if (!step)
+            if (! step)
               step = PROBE_STEP(newHash, newMask, newPower);
             j < step ? (j += newSize - step) : (j -= step);
           }
@@ -6728,14 +6440,14 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
       i = h & newMask;
       step = 0;
       while (table->v[i]) {
-        if (!step)
+        if (! step)
           step = PROBE_STEP(h, newMask, newPower);
         i < step ? (i += newSize - step) : (i -= step);
       }
     }
   }
   table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
-  if (!table->v[i])
+  if (! table->v[i])
     return NULL;
   memset(table->v[i], 0, createSize);
   table->v[i]->name = name;
@@ -6744,8 +6456,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
 }
 
 static void FASTCALL
-hashTableClear(HASH_TABLE *table)
-{
+hashTableClear(HASH_TABLE *table) {
   size_t i;
   for (i = 0; i < table->size; i++) {
     table->mem->free_fcn(table->v[i]);
@@ -6755,8 +6466,7 @@ hashTableClear(HASH_TABLE *table)
 }
 
 static void FASTCALL
-hashTableDestroy(HASH_TABLE *table)
-{
+hashTableDestroy(HASH_TABLE *table) {
   size_t i;
   for (i = 0; i < table->size; i++)
     table->mem->free_fcn(table->v[i]);
@@ -6764,8 +6474,7 @@ hashTableDestroy(HASH_TABLE *table)
 }
 
 static void FASTCALL
-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
-{
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
   p->power = 0;
   p->size = 0;
   p->used = 0;
@@ -6774,15 +6483,13 @@ hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
 }
 
 static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
-{
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
   iter->p = table->v;
   iter->end = iter->p + table->size;
 }
 
-static NAMED * FASTCALL
-hashTableIterNext(HASH_TABLE_ITER *iter)
-{
+static NAMED *FASTCALL
+hashTableIterNext(HASH_TABLE_ITER *iter) {
   while (iter->p != iter->end) {
     NAMED *tem = *(iter->p)++;
     if (tem)
@@ -6792,8 +6499,7 @@ hashTableIterNext(HASH_TABLE_ITER *iter)
 }
 
 static void FASTCALL
-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
-{
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
   pool->blocks = NULL;
   pool->freeBlocks = NULL;
   pool->start = NULL;
@@ -6803,9 +6509,8 @@ poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
 }
 
 static void FASTCALL
-poolClear(STRING_POOL *pool)
-{
-  if (!pool->freeBlocks)
+poolClear(STRING_POOL *pool) {
+  if (! pool->freeBlocks)
     pool->freeBlocks = pool->blocks;
   else {
     BLOCK *p = pool->blocks;
@@ -6823,8 +6528,7 @@ poolClear(STRING_POOL *pool)
 }
 
 static void FASTCALL
-poolDestroy(STRING_POOL *pool)
-{
+poolDestroy(STRING_POOL *pool) {
   BLOCK *p = pool->blocks;
   while (p) {
     BLOCK *tem = p->next;
@@ -6840,26 +6544,26 @@ poolDestroy(STRING_POOL *pool)
 }
 
 static XML_Char *
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
-           const char *ptr, const char *end)
-{
-  if (!pool->ptr && !poolGrow(pool))
+poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
+           const char *end) {
+  if (! pool->ptr && ! poolGrow(pool))
     return NULL;
   for (;;) {
-    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
-    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+    const enum XML_Convert_Result convert_res = XmlConvert(
+        enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+    if ((convert_res == XML_CONVERT_COMPLETED)
+        || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
       break;
-    if (!poolGrow(pool))
+    if (! poolGrow(pool))
       return NULL;
   }
   return pool->start;
 }
 
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s)
-{
+static const XML_Char *FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s) {
   do {
-    if (!poolAppendChar(pool, *s))
+    if (! poolAppendChar(pool, *s))
       return NULL;
   } while (*s++);
   s = pool->start;
@@ -6868,9 +6572,8 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s)
 }
 
 static const XML_Char *
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
-{
-  if (!pool->ptr && !poolGrow(pool)) {
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
+  if (! pool->ptr && ! poolGrow(pool)) {
     /* The following line is unreachable given the current usage of
      * poolCopyStringN().  Currently it is called from exactly one
      * place to copy the text of a simple general entity.  By that
@@ -6885,7 +6588,7 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
     return NULL; /* LCOV_EXCL_LINE */
   }
   for (; n > 0; --n, s++) {
-    if (!poolAppendChar(pool, *s))
+    if (! poolAppendChar(pool, *s))
       return NULL;
   }
   s = pool->start;
@@ -6893,11 +6596,10 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
   return s;
 }
 
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s)
-{
+static const XML_Char *FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s) {
   while (*s) {
-    if (!poolAppendChar(pool, *s))
+    if (! poolAppendChar(pool, *s))
       return NULL;
     s++;
   }
@@ -6905,20 +6607,18 @@ poolAppendString(STRING_POOL *pool, const XML_Char *s)
 }
 
 static XML_Char *
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-                const char *ptr, const char *end)
-{
-  if (!poolAppend(pool, enc, ptr, end))
+poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
+                const char *end) {
+  if (! poolAppend(pool, enc, ptr, end))
     return NULL;
-  if (pool->ptr == pool->end && !poolGrow(pool))
+  if (pool->ptr == pool->end && ! poolGrow(pool))
     return NULL;
   *(pool->ptr)++ = 0;
   return pool->start;
 }
 
 static size_t
-poolBytesToAllocateFor(int blockSize)
-{
+poolBytesToAllocateFor(int blockSize) {
   /* Unprotected math would be:
   ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
   **
@@ -6926,7 +6626,7 @@ poolBytesToAllocateFor(int blockSize)
   ** For a + b * c we check b * c in isolation first, so that addition of a
   ** on top has no chance of making us accept a small non-negative number
   */
-  const size_t stretch = sizeof(XML_Char);  /* can be 4 bytes */
+  const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
 
   if (blockSize <= 0)
     return 0;
@@ -6936,8 +6636,8 @@ poolBytesToAllocateFor(int blockSize)
 
   {
     const int stretchedBlockSize = blockSize * (int)stretch;
-    const int bytesToAllocate = (int)(
-        offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
+    const int bytesToAllocate
+        = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
     if (bytesToAllocate < 0)
       return 0;
 
@@ -6946,8 +6646,7 @@ poolBytesToAllocateFor(int blockSize)
 }
 
 static XML_Bool FASTCALL
-poolGrow(STRING_POOL *pool)
-{
+poolGrow(STRING_POOL *pool) {
   if (pool->freeBlocks) {
     if (pool->start == 0) {
       pool->blocks = pool->freeBlocks;
@@ -6973,7 +6672,7 @@ poolGrow(STRING_POOL *pool)
   }
   if (pool->blocks && pool->start == pool->blocks->s) {
     BLOCK *temp;
-    int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
+    int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
     size_t bytesToAllocate;
 
     /* NOTE: Needs to be calculated prior to calling `realloc`
@@ -6994,8 +6693,8 @@ poolGrow(STRING_POOL *pool)
     if (bytesToAllocate == 0)
       return XML_FALSE;
 
-    temp = (BLOCK *)
-      pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
+    temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
+                                           (unsigned)bytesToAllocate);
     if (temp == NULL)
       return XML_FALSE;
     pool->blocks = temp;
@@ -7003,8 +6702,7 @@ poolGrow(STRING_POOL *pool)
     pool->ptr = pool->blocks->s + offsetInsideBlock;
     pool->start = pool->blocks->s;
     pool->end = pool->start + blockSize;
-  }
-  else {
+  } else {
     BLOCK *tem;
     int blockSize = (int)(pool->end - pool->start);
     size_t bytesToAllocate;
@@ -7019,7 +6717,7 @@ poolGrow(STRING_POOL *pool)
        * function).  Either way it isn't readily testable, so we
        * exclude it from the coverage statistics.
        */
-      return XML_FALSE;  /* LCOV_EXCL_LINE */
+      return XML_FALSE; /* LCOV_EXCL_LINE */
     }
 
     if (blockSize < INIT_BLOCK_SIZE)
@@ -7037,14 +6735,13 @@ poolGrow(STRING_POOL *pool)
       return XML_FALSE;
 
     tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
-    if (!tem)
+    if (! tem)
       return XML_FALSE;
     tem->size = blockSize;
     tem->next = pool->blocks;
     pool->blocks = tem;
     if (pool->ptr != pool->start)
-      memcpy(tem->s, pool->start,
-             (pool->ptr - pool->start) * sizeof(XML_Char));
+      memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
     pool->ptr = tem->s + (pool->ptr - pool->start);
     pool->start = tem->s;
     pool->end = tem->s + blockSize;
@@ -7053,15 +6750,14 @@ poolGrow(STRING_POOL *pool)
 }
 
 static int FASTCALL
-nextScaffoldPart(XML_Parser parser)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
-  CONTENT_SCAFFOLD * me;
+nextScaffoldPart(XML_Parser parser) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
+  CONTENT_SCAFFOLD *me;
   int next;
 
-  if (!dtd->scaffIndex) {
+  if (! dtd->scaffIndex) {
     dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
-    if (!dtd->scaffIndex)
+    if (! dtd->scaffIndex)
       return -1;
     dtd->scaffIndex[0] = 0;
   }
@@ -7069,15 +6765,14 @@ nextScaffoldPart(XML_Parser parser)
   if (dtd->scaffCount >= dtd->scaffSize) {
     CONTENT_SCAFFOLD *temp;
     if (dtd->scaffold) {
-      temp = (CONTENT_SCAFFOLD *)
-        REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+      temp = (CONTENT_SCAFFOLD *)REALLOC(
+          parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
       if (temp == NULL)
         return -1;
       dtd->scaffSize *= 2;
-    }
-    else {
+    } else {
       temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
-                                        * sizeof(CONTENT_SCAFFOLD));
+                                                    * sizeof(CONTENT_SCAFFOLD));
       if (temp == NULL)
         return -1;
       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
@@ -7087,11 +6782,12 @@ nextScaffoldPart(XML_Parser parser)
   next = dtd->scaffCount++;
   me = &dtd->scaffold[next];
   if (dtd->scaffLevel) {
-    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
+    CONTENT_SCAFFOLD *parent
+        = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
     if (parent->lastchild) {
       dtd->scaffold[parent->lastchild].nextsib = next;
     }
-    if (!parent->childcnt)
+    if (! parent->childcnt)
       parent->firstchild = next;
     parent->lastchild = next;
     parent->childcnt++;
@@ -7101,13 +6797,9 @@ nextScaffoldPart(XML_Parser parser)
 }
 
 static void
-build_node(XML_Parser parser,
-           int src_node,
-           XML_Content *dest,
-           XML_Content **contpos,
-           XML_Char **strpos)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+build_node(XML_Parser parser, int src_node, XML_Content *dest,
+           XML_Content **contpos, XML_Char **strpos) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   dest->type = dtd->scaffold[src_node].type;
   dest->quant = dtd->scaffold[src_node].quant;
   if (dest->type == XML_CTYPE_NAME) {
@@ -7116,21 +6808,19 @@ build_node(XML_Parser parser,
     src = dtd->scaffold[src_node].name;
     for (;;) {
       *(*strpos)++ = *src;
-      if (!*src)
+      if (! *src)
         break;
       src++;
     }
     dest->numchildren = 0;
     dest->children = NULL;
-  }
-  else {
+  } else {
     unsigned int i;
     int cn;
     dest->numchildren = dtd->scaffold[src_node].childcnt;
     dest->children = *contpos;
     *contpos += dest->numchildren;
-    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
-         i < dest->numchildren;
+    for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
          i++, cn = dtd->scaffold[cn].nextsib) {
       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
     }
@@ -7139,20 +6829,19 @@ build_node(XML_Parser parser,
 }
 
 static XML_Content *
-build_model (XML_Parser parser)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+build_model(XML_Parser parser) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   XML_Content *ret;
   XML_Content *cpos;
-  XML_Char * str;
+  XML_Char *str;
   int allocsize = (dtd->scaffCount * sizeof(XML_Content)
                    + (dtd->contentStringLen * sizeof(XML_Char)));
 
   ret = (XML_Content *)MALLOC(parser, allocsize);
-  if (!ret)
+  if (! ret)
     return NULL;
 
-  str =  (XML_Char *) (&ret[dtd->scaffCount]);
+  str = (XML_Char *)(&ret[dtd->scaffCount]);
   cpos = &ret[1];
 
   build_node(parser, 0, ret, &cpos, &str);
@@ -7160,49 +6849,45 @@ build_model (XML_Parser parser)
 }
 
 static ELEMENT_TYPE *
-getElementType(XML_Parser parser,
-               const ENCODING *enc,
-               const char *ptr,
-               const char *end)
-{
-  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
+getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
+               const char *end) {
+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
   ELEMENT_TYPE *ret;
 
-  if (!name)
+  if (! name)
     return NULL;
-  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
-  if (!ret)
+  ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
+                               sizeof(ELEMENT_TYPE));
+  if (! ret)
     return NULL;
   if (ret->name != name)
     poolDiscard(&dtd->pool);
   else {
     poolFinish(&dtd->pool);
-    if (!setElementTypePrefix(parser, ret))
+    if (! setElementTypePrefix(parser, ret))
       return NULL;
   }
   return ret;
 }
 
 static XML_Char *
-copyString(const XML_Char *s,
-           const XML_Memory_Handling_Suite *memsuite)
-{
-    int charsRequired = 0;
-    XML_Char *result;
-
-    /* First determine how long the string is */
-    while (s[charsRequired] != 0) {
-      charsRequired++;
-    }
-    /* Include the terminator */
+copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
+  int charsRequired = 0;
+  XML_Char *result;
+
+  /* First determine how long the string is */
+  while (s[charsRequired] != 0) {
     charsRequired++;
+  }
+  /* Include the terminator */
+  charsRequired++;
 
-    /* Now allocate space for the copy */
-    result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
-    if (result == NULL)
-        return NULL;
-    /* Copy the original into place */
-    memcpy(result, s, charsRequired * sizeof(XML_Char));
-    return result;
+  /* Now allocate space for the copy */
+  result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
+  if (result == NULL)
+    return NULL;
+  /* Copy the original into place */
+  memcpy(result, s, charsRequired * sizeof(XML_Char));
+  return result;
 }
index 708507d575be8494da7126a39d1dcea573c8e22d..4d3e3e86e9e864dd64f9f184c9467b05659d299e 100644 (file)
 #include <stddef.h>
 
 #ifdef _WIN32
-#include "winconfig.h"
+#  include "winconfig.h"
 #else
-#ifdef HAVE_EXPAT_CONFIG_H
-#include <expat_config.h>
-#endif
+#  ifdef HAVE_EXPAT_CONFIG_H
+#    include <expat_config.h>
+#  endif
 #endif /* ndef _WIN32 */
 
 #include "expat_external.h"
 
 */
 
-static const char KW_ANY[] = {
-    ASCII_A, ASCII_N, ASCII_Y, '\0' };
-static const char KW_ATTLIST[] = {
-    ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
-static const char KW_CDATA[] = {
-    ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_DOCTYPE[] = {
-    ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
-static const char KW_ELEMENT[] = {
-    ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
-static const char KW_EMPTY[] = {
-    ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
-static const char KW_ENTITIES[] = {
-    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
-    '\0' };
-static const char KW_ENTITY[] = {
-    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
-static const char KW_FIXED[] = {
-    ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
-static const char KW_ID[] = {
-    ASCII_I, ASCII_D, '\0' };
-static const char KW_IDREF[] = {
-    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
-static const char KW_IDREFS[] = {
-    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'};
+static const char KW_ATTLIST[]
+    = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'};
+static const char KW_CDATA[]
+    = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+static const char KW_DOCTYPE[]
+    = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'};
+static const char KW_ELEMENT[]
+    = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'};
+static const char KW_EMPTY[]
+    = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'};
+static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
+                                   ASCII_I, ASCII_E, ASCII_S, '\0'};
+static const char KW_ENTITY[]
+    = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
+static const char KW_FIXED[]
+    = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'};
+static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'};
+static const char KW_IDREF[]
+    = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
+static const char KW_IDREFS[]
+    = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
 #ifdef XML_DTD
-static const char KW_IGNORE[] = {
-    ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IGNORE[]
+    = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'};
 #endif
-static const char KW_IMPLIED[] = {
-    ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_IMPLIED[]
+    = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'};
 #ifdef XML_DTD
-static const char KW_INCLUDE[] = {
-    ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_INCLUDE[]
+    = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'};
 #endif
-static const char KW_NDATA[] = {
-    ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_NMTOKEN[] = {
-    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
-static const char KW_NMTOKENS[] = {
-    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
-    '\0' };
-static const char KW_NOTATION[] =
-    { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
-      '\0' };
-static const char KW_PCDATA[] = {
-    ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_PUBLIC[] = {
-    ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
-static const char KW_REQUIRED[] = {
-    ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
-    '\0' };
-static const char KW_SYSTEM[] = {
-    ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+static const char KW_NDATA[]
+    = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+static const char KW_NMTOKEN[]
+    = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
+static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
+                                   ASCII_E, ASCII_N, ASCII_S, '\0'};
+static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
+                                   ASCII_I, ASCII_O, ASCII_N, '\0'};
+static const char KW_PCDATA[]
+    = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+static const char KW_PUBLIC[]
+    = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'};
+static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I,
+                                   ASCII_R, ASCII_E, ASCII_D, '\0'};
+static const char KW_SYSTEM[]
+    = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'};
 
 #ifndef MIN_BYTES_PER_CHAR
-#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#  define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
 #endif
 
 #ifdef XML_DTD
-#define setTopLevel(state) \
-  ((state)->handler = ((state)->documentEntity \
-                       ? internalSubset \
-                       : externalSubset1))
+#  define setTopLevel(state)                                                   \
+    ((state)->handler                                                          \
+     = ((state)->documentEntity ? internalSubset : externalSubset1))
 #else /* not XML_DTD */
-#define setTopLevel(state) ((state)->handler = internalSubset)
+#  define setTopLevel(state) ((state)->handler = internalSubset)
 #endif /* not XML_DTD */
 
-typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
-                                   int tok,
-                                   const char *ptr,
-                                   const char *end,
+typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok,
+                                   const char *ptr, const char *end,
                                    const ENCODING *enc);
 
-static PROLOG_HANDLER
-  prolog0, prolog1, prolog2,
-  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
-  internalSubset,
-  entity0, entity1, entity2, entity3, entity4, entity5, entity6,
-  entity7, entity8, entity9, entity10,
-  notation0, notation1, notation2, notation3, notation4,
-  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
-  attlist7, attlist8, attlist9,
-  element0, element1, element2, element3, element4, element5, element6,
-  element7,
+static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2,
+    doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2,
+    entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10,
+    notation0, notation1, notation2, notation3, notation4, attlist0, attlist1,
+    attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8,
+    attlist9, element0, element1, element2, element3, element4, element5,
+    element6, element7,
 #ifdef XML_DTD
-  externalSubset0, externalSubset1,
-  condSect0, condSect1, condSect2,
+    externalSubset0, externalSubset1, condSect0, condSect1, condSect2,
 #endif /* XML_DTD */
-  declClose,
-  error;
+    declClose, error;
 
 static int FASTCALL common(PROLOG_STATE *state, int tok);
 
 static int PTRCALL
-prolog0(PROLOG_STATE *state,
-        int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
-{
+prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     state->handler = prolog1;
@@ -169,10 +150,8 @@ prolog0(PROLOG_STATE *state,
   case XML_TOK_BOM:
     return XML_ROLE_NONE;
   case XML_TOK_DECL_OPEN:
-    if (!XmlNameMatchesAscii(enc,
-                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                             end,
-                             KW_DOCTYPE))
+    if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
+                              KW_DOCTYPE))
       break;
     state->handler = doctype0;
     return XML_ROLE_DOCTYPE_NONE;
@@ -184,12 +163,8 @@ prolog0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-prolog1(PROLOG_STATE *state,
-        int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
-{
+prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
@@ -207,10 +182,8 @@ prolog1(PROLOG_STATE *state,
      */
     return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
   case XML_TOK_DECL_OPEN:
-    if (!XmlNameMatchesAscii(enc,
-                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                             end,
-                             KW_DOCTYPE))
+    if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
+                              KW_DOCTYPE))
       break;
     state->handler = doctype0;
     return XML_ROLE_DOCTYPE_NONE;
@@ -222,12 +195,11 @@ prolog1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-prolog2(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
@@ -243,12 +215,11 @@ prolog2(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-doctype0(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_DOCTYPE_NONE;
@@ -261,12 +232,8 @@ doctype0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-doctype1(PROLOG_STATE *state,
-         int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
-{
+doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_DOCTYPE_NONE;
@@ -291,12 +258,11 @@ doctype1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-doctype2(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_DOCTYPE_NONE;
@@ -308,12 +274,11 @@ doctype2(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-doctype3(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_DOCTYPE_NONE;
@@ -325,12 +290,11 @@ doctype3(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-doctype4(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_DOCTYPE_NONE;
@@ -345,12 +309,11 @@ doctype4(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-doctype5(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_DOCTYPE_NONE;
@@ -362,40 +325,28 @@ doctype5(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-internalSubset(PROLOG_STATE *state,
-               int tok,
-               const char *ptr,
-               const char *end,
-               const ENCODING *enc)
-{
+internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+               const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
   case XML_TOK_DECL_OPEN:
-    if (XmlNameMatchesAscii(enc,
-                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
                             KW_ENTITY)) {
       state->handler = entity0;
       return XML_ROLE_ENTITY_NONE;
     }
-    if (XmlNameMatchesAscii(enc,
-                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
                             KW_ATTLIST)) {
       state->handler = attlist0;
       return XML_ROLE_ATTLIST_NONE;
     }
-    if (XmlNameMatchesAscii(enc,
-                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
                             KW_ELEMENT)) {
       state->handler = element0;
       return XML_ROLE_ELEMENT_NONE;
     }
-    if (XmlNameMatchesAscii(enc,
-                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
                             KW_NOTATION)) {
       state->handler = notation0;
       return XML_ROLE_NOTATION_NONE;
@@ -419,12 +370,8 @@ internalSubset(PROLOG_STATE *state,
 #ifdef XML_DTD
 
 static int PTRCALL
-externalSubset0(PROLOG_STATE *state,
-                int tok,
-                const char *ptr,
-                const char *end,
-                const ENCODING *enc)
-{
+externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+                const ENCODING *enc) {
   state->handler = externalSubset1;
   if (tok == XML_TOK_XML_DECL)
     return XML_ROLE_TEXT_DECL;
@@ -432,12 +379,8 @@ externalSubset0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-externalSubset1(PROLOG_STATE *state,
-                int tok,
-                const char *ptr,
-                const char *end,
-                const ENCODING *enc)
-{
+externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+                const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_COND_SECT_OPEN:
     state->handler = condSect0;
@@ -464,12 +407,11 @@ externalSubset1(PROLOG_STATE *state,
 #endif /* XML_DTD */
 
 static int PTRCALL
-entity0(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -484,12 +426,11 @@ entity0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity1(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -501,12 +442,8 @@ entity1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity2(PROLOG_STATE *state,
-        int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
-{
+entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -529,12 +466,11 @@ entity2(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity3(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -546,12 +482,11 @@ entity3(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity4(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -563,12 +498,8 @@ entity4(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity5(PROLOG_STATE *state,
-        int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
-{
+entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -586,12 +517,11 @@ entity5(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity6(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -604,12 +534,8 @@ entity6(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity7(PROLOG_STATE *state,
-        int tok,
-        const char *ptr,
-        const char *end,
-        const ENCODING *enc)
-{
+entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -632,12 +558,11 @@ entity7(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity8(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -649,12 +574,11 @@ entity8(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity9(PROLOG_STATE *state,
-        int tok,
-        const char *UNUSED_P(ptr),
-        const char *UNUSED_P(end),
-        const ENCODING *UNUSED_P(enc))
-{
+entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+        const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -666,12 +590,11 @@ entity9(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-entity10(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ENTITY_NONE;
@@ -683,12 +606,11 @@ entity10(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-notation0(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NOTATION_NONE;
@@ -700,12 +622,8 @@ notation0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-notation1(PROLOG_STATE *state,
-          int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
-{
+notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NOTATION_NONE;
@@ -724,12 +642,11 @@ notation1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-notation2(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NOTATION_NONE;
@@ -741,12 +658,11 @@ notation2(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-notation3(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NOTATION_NONE;
@@ -759,12 +675,11 @@ notation3(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-notation4(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NOTATION_NONE;
@@ -780,12 +695,11 @@ notation4(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist0(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -798,12 +712,11 @@ attlist0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist1(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -819,34 +732,23 @@ attlist1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist2(PROLOG_STATE *state,
-         int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
-{
+attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
-  case XML_TOK_NAME:
-    {
-      static const char * const types[] = {
-        KW_CDATA,
-        KW_ID,
-        KW_IDREF,
-        KW_IDREFS,
-        KW_ENTITY,
-        KW_ENTITIES,
-        KW_NMTOKEN,
-        KW_NMTOKENS,
-      };
-      int i;
-      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
-        if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
-          state->handler = attlist8;
-          return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
-        }
-    }
+  case XML_TOK_NAME: {
+    static const char *const types[] = {
+        KW_CDATA,  KW_ID,       KW_IDREF,   KW_IDREFS,
+        KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS,
+    };
+    int i;
+    for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++)
+      if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+        state->handler = attlist8;
+        return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+      }
+  }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
       state->handler = attlist5;
       return XML_ROLE_ATTLIST_NONE;
@@ -860,12 +762,11 @@ attlist2(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist3(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -879,12 +780,11 @@ attlist3(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist4(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -899,12 +799,11 @@ attlist4(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist5(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -916,12 +815,11 @@ attlist5(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist6(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -933,12 +831,11 @@ attlist6(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist7(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -954,33 +851,23 @@ attlist7(PROLOG_STATE *state,
 
 /* default value */
 static int PTRCALL
-attlist8(PROLOG_STATE *state,
-         int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
-{
+attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_POUND_NAME:
-    if (XmlNameMatchesAscii(enc,
-                            ptr + MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
                             KW_IMPLIED)) {
       state->handler = attlist1;
       return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
     }
-    if (XmlNameMatchesAscii(enc,
-                            ptr + MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
                             KW_REQUIRED)) {
       state->handler = attlist1;
       return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
     }
-    if (XmlNameMatchesAscii(enc,
-                            ptr + MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
                             KW_FIXED)) {
       state->handler = attlist9;
       return XML_ROLE_ATTLIST_NONE;
@@ -994,12 +881,11 @@ attlist8(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-attlist9(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ATTLIST_NONE;
@@ -1011,12 +897,11 @@ attlist9(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element0(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1029,12 +914,8 @@ element0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element1(PROLOG_STATE *state,
-         int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
-{
+element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1059,19 +940,13 @@ element1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element2(PROLOG_STATE *state,
-         int tok,
-         const char *ptr,
-         const char *end,
-         const ENCODING *enc)
-{
+element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_POUND_NAME:
-    if (XmlNameMatchesAscii(enc,
-                            ptr + MIN_BYTES_PER_CHAR(enc),
-                            end,
+    if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
                             KW_PCDATA)) {
       state->handler = element3;
       return XML_ROLE_CONTENT_PCDATA;
@@ -1099,12 +974,11 @@ element2(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element3(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1124,12 +998,11 @@ element3(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element4(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1142,12 +1015,11 @@ element4(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element5(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1163,12 +1035,11 @@ element5(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element6(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1193,12 +1064,11 @@ element6(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-element7(PROLOG_STATE *state,
-         int tok,
-         const char *UNUSED_P(ptr),
-         const char *UNUSED_P(end),
-         const ENCODING *UNUSED_P(enc))
-{
+element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+         const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_ELEMENT_NONE;
@@ -1243,12 +1113,8 @@ element7(PROLOG_STATE *state,
 #ifdef XML_DTD
 
 static int PTRCALL
-condSect0(PROLOG_STATE *state,
-          int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
-{
+condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
@@ -1267,12 +1133,11 @@ condSect0(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-condSect1(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
@@ -1285,12 +1150,11 @@ condSect1(PROLOG_STATE *state,
 }
 
 static int PTRCALL
-condSect2(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
@@ -1304,12 +1168,11 @@ condSect2(PROLOG_STATE *state,
 #endif /* XML_DTD */
 
 static int PTRCALL
-declClose(PROLOG_STATE *state,
-          int tok,
-          const char *UNUSED_P(ptr),
-          const char *UNUSED_P(end),
-          const ENCODING *UNUSED_P(enc))
-{
+declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+          const ENCODING *enc) {
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return state->role_none;
@@ -1341,21 +1204,21 @@ declClose(PROLOG_STATE *state,
  * LCOV_EXCL_START
  */
 static int PTRCALL
-error(PROLOG_STATE *UNUSED_P(state),
-      int UNUSED_P(tok),
-      const char *UNUSED_P(ptr),
-      const char *UNUSED_P(end),
-      const ENCODING *UNUSED_P(enc))
-{
+error(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+      const ENCODING *enc) {
+  UNUSED_P(state);
+  UNUSED_P(tok);
+  UNUSED_P(ptr);
+  UNUSED_P(end);
+  UNUSED_P(enc);
   return XML_ROLE_NONE;
 }
 /* LCOV_EXCL_STOP */
 
 static int FASTCALL
-common(PROLOG_STATE *state, int tok)
-{
+common(PROLOG_STATE *state, int tok) {
 #ifdef XML_DTD
-  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+  if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
     return XML_ROLE_INNER_PARAM_ENTITY_REF;
 #endif
   state->handler = error;
@@ -1363,8 +1226,7 @@ common(PROLOG_STATE *state, int tok)
 }
 
 void
-XmlPrologStateInit(PROLOG_STATE *state)
-{
+XmlPrologStateInit(PROLOG_STATE *state) {
   state->handler = prolog0;
 #ifdef XML_DTD
   state->documentEntity = 1;
@@ -1376,8 +1238,7 @@ XmlPrologStateInit(PROLOG_STATE *state)
 #ifdef XML_DTD
 
 void
-XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
-{
+XmlPrologStateInitExternalEntity(PROLOG_STATE *state) {
   state->handler = externalSubset0;
   state->documentEntity = 0;
   state->includeLevel = 0;
index e5f048eab55c6e47c87dbe95f35132a98f3ee1c2..036aba64fd29c6950b7007d62c16448f71ab732b 100644 (file)
@@ -36,7 +36,7 @@
 #ifdef __VMS
 /*      0        1         2         3      0        1         2         3
         1234567890123456789012345678901     1234567890123456789012345678901 */
-#define XmlPrologStateInitExternalEntity    XmlPrologStateInitExternalEnt
+#  define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
 #endif
 
 #include "xmltok.h"
@@ -113,11 +113,8 @@ enum {
 };
 
 typedef struct prolog_state {
-  int (PTRCALL *handler) (struct prolog_state *state,
-                          int tok,
-                          const char *ptr,
-                          const char *end,
-                          const ENCODING *enc);
+  int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr,
+                        const char *end, const ENCODING *enc);
   unsigned level;
   int role_none;
 #ifdef XML_DTD
@@ -132,8 +129,8 @@ void XmlPrologStateInit(PROLOG_STATE *);
 void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
 #endif /* XML_DTD */
 
-#define XmlTokenRole(state, tok, ptr, end, enc) \
- (((state)->handler)(state, tok, ptr, end, enc))
+#define XmlTokenRole(state, tok, ptr, end, enc)                                \
 (((state)->handler)(state, tok, ptr, end, enc))
 
 #ifdef __cplusplus
 }
index 6b415d83972ca605a97c27eb36f75cdab37165c1..11e9d1ccdad423e1845dc8d0e23da877c784a6fa 100644 (file)
 */
 
 #include <stddef.h>
-#include <string.h>  /* memcpy */
+#include <string.h> /* memcpy */
 
 #if defined(_MSC_VER) && (_MSC_VER <= 1700)
-  /* for vs2012/11.0/1700 and earlier Visual Studio compilers */
-# define bool   int
-# define false  0
-# define true   1
+/* for vs2012/11.0/1700 and earlier Visual Studio compilers */
+#  define bool int
+#  define false 0
+#  define true 1
 #else
-# include <stdbool.h>
+#  include <stdbool.h>
 #endif
 
-
 #ifdef _WIN32
-#include "winconfig.h"
+#  include "winconfig.h"
 #else
-#ifdef HAVE_EXPAT_CONFIG_H
-#include <expat_config.h>
-#endif
+#  ifdef HAVE_EXPAT_CONFIG_H
+#    include <expat_config.h>
+#  endif
 #endif /* ndef _WIN32 */
 
 #include "expat_external.h"
 #include "nametab.h"
 
 #ifdef XML_DTD
-#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#  define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
 #else
-#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#  define IGNORE_SECTION_TOK_VTABLE /* as nothing */
 #endif
 
-#define VTABLE1 \
-  { PREFIX(prologTok), PREFIX(contentTok), \
-    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
-  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
-  PREFIX(nameMatchesAscii), \
-  PREFIX(nameLength), \
-  PREFIX(skipS), \
-  PREFIX(getAtts), \
-  PREFIX(charRefNumber), \
-  PREFIX(predefinedEntityName), \
-  PREFIX(updatePosition), \
-  PREFIX(isPublicId)
+#define VTABLE1                                                                \
+  {PREFIX(prologTok), PREFIX(contentTok),                                      \
+   PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE},                         \
+      {PREFIX(attributeValueTok), PREFIX(entityValueTok)},                     \
+      PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS),             \
+      PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName),    \
+      PREFIX(updatePosition), PREFIX(isPublicId)
 
 #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
 
-#define UCS2_GET_NAMING(pages, hi, lo) \
-   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
+#define UCS2_GET_NAMING(pages, hi, lo)                                         \
+  (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo)&0x1F)))
 
 /* A 2 byte UTF-8 representation splits the characters 11 bits between
    the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
    pages, 3 bits to add to that index and 5 bits to generate the mask.
 */
-#define UTF8_GET_NAMING2(pages, byte) \
-    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
-                      + ((((byte)[0]) & 3) << 1) \
-                      + ((((byte)[1]) >> 5) & 1)] \
-         & (1u << (((byte)[1]) & 0x1F)))
+#define UTF8_GET_NAMING2(pages, byte)                                          \
+  (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3)                         \
+                + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)]         \
+   & (1u << (((byte)[1]) & 0x1F)))
 
 /* A 3 byte UTF-8 representation splits the characters 16 bits between
    the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index
    into pages, 3 bits to add to that index and 5 bits to generate the
    mask.
 */
-#define UTF8_GET_NAMING3(pages, byte) \
-  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
-                             + ((((byte)[1]) >> 2) & 0xF)] \
-                       << 3) \
-                      + ((((byte)[1]) & 3) << 1) \
-                      + ((((byte)[2]) >> 5) & 1)] \
-         & (1u << (((byte)[2]) & 0x1F)))
-
-#define UTF8_GET_NAMING(pages, p, n) \
-  ((n) == 2 \
-  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
-  : ((n) == 3 \
-     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
-     : 0))
+#define UTF8_GET_NAMING3(pages, byte)                                          \
+  (namingBitmap                                                                \
+       [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)]      \
+         << 3)                                                                 \
+        + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)]                 \
+   & (1u << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n)                                           \
+  ((n) == 2                                                                    \
+       ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p))                   \
+       : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0))
 
 /* Detection of invalid UTF-8 sequences is based on Table 3.1B
    of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
      (A & 0xC0) == 0xC0  means A > 0xBF
 */
 
-#define UTF8_INVALID2(p) \
+#define UTF8_INVALID2(p)                                                       \
   ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
 
-#define UTF8_INVALID3(p) \
-  (((p)[2] & 0x80) == 0 \
-  || \
-  ((*p) == 0xEF && (p)[1] == 0xBF \
-    ? \
-    (p)[2] > 0xBD \
-    : \
-    ((p)[2] & 0xC0) == 0xC0) \
-  || \
-  ((*p) == 0xE0 \
-    ? \
-    (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
-    : \
-    ((p)[1] & 0x80) == 0 \
-    || \
-    ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
-
-#define UTF8_INVALID4(p) \
-  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
-  || \
-  ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
-  || \
-  ((*p) == 0xF0 \
-    ? \
-    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
-    : \
-    ((p)[1] & 0x80) == 0 \
-    || \
-    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
+#define UTF8_INVALID3(p)                                                       \
+  (((p)[2] & 0x80) == 0                                                        \
+   || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD                          \
+                                      : ((p)[2] & 0xC0) == 0xC0)               \
+   || ((*p) == 0xE0                                                            \
+           ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0                          \
+           : ((p)[1] & 0x80) == 0                                              \
+                 || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
+
+#define UTF8_INVALID4(p)                                                       \
+  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0     \
+   || ((p)[2] & 0xC0) == 0xC0                                                  \
+   || ((*p) == 0xF0                                                            \
+           ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0                          \
+           : ((p)[1] & 0x80) == 0                                              \
+                 || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
 
 static int PTRFASTCALL
-isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
-{
+isNever(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  UNUSED_P(p);
   return 0;
 }
 
 static int PTRFASTCALL
-utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isName2(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isName3(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
 }
 
 #define utf8_isName4 isNever
 
 static int PTRFASTCALL
-utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isNmstrt2(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isNmstrt3(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
 }
 
 #define utf8_isNmstrt4 isNever
 
 static int PTRFASTCALL
-utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isInvalid2(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_INVALID2((const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isInvalid3(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_INVALID3((const unsigned char *)p);
 }
 
 static int PTRFASTCALL
-utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isInvalid4(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return UTF8_INVALID4((const unsigned char *)p);
 }
 
@@ -209,61 +187,44 @@ struct normal_encoding {
   ENCODING enc;
   unsigned char type[256];
 #ifdef XML_MIN_SIZE
-  int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
-  int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
-  int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
+  int(PTRFASTCALL *byteType)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
+  int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
+  int(PTRCALL *charMatches)(const ENCODING *, const char *, int);
 #endif /* XML_MIN_SIZE */
-  int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
-  int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isName2)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isName3)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isName4)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
+  int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
 };
 
-#define AS_NORMAL_ENCODING(enc)   ((const struct normal_encoding *) (enc))
+#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
 
 #ifdef XML_MIN_SIZE
 
-#define STANDARD_VTABLE(E) \
- E ## byteType, \
- E ## isNameMin, \
- E ## isNmstrtMin, \
- E ## byteToAscii, \
- E ## charMatches,
+#  define STANDARD_VTABLE(E)                                                   \
+    E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches,
 
 #else
 
-#define STANDARD_VTABLE(E) /* as nothing */
+#  define STANDARD_VTABLE(E) /* as nothing */
 
 #endif
 
-#define NORMAL_VTABLE(E) \
- E ## isName2, \
- E ## isName3, \
- E ## isName4, \
- E ## isNmstrt2, \
- E ## isNmstrt3, \
- E ## isNmstrt4, \
- E ## isInvalid2, \
- E ## isInvalid3, \
- E ## isInvalid4
-
-#define NULL_VTABLE \
- /* isName2 */ NULL, \
- /* isName3 */ NULL, \
- /* isName4 */ NULL, \
- /* isNmstrt2 */ NULL, \
- /* isNmstrt3 */ NULL, \
- /* isNmstrt4 */ NULL, \
- /* isInvalid2 */ NULL, \
- /* isInvalid3 */ NULL, \
- /* isInvalid4 */ NULL
+#define NORMAL_VTABLE(E)                                                       \
+  E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3,              \
+      E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4
+
+#define NULL_VTABLE                                                            \
+  /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL,                  \
+      /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL,        \
+      /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
 
 static int FASTCALL checkCharRefNumber(int);
 
@@ -271,75 +232,70 @@ static int FASTCALL checkCharRefNumber(int);
 #include "ascii.h"
 
 #ifdef XML_MIN_SIZE
-#define sb_isNameMin isNever
-#define sb_isNmstrtMin isNever
+#  define sb_isNameMin isNever
+#  define sb_isNmstrtMin isNever
 #endif
 
 #ifdef XML_MIN_SIZE
-#define MINBPC(enc) ((enc)->minBytesPerChar)
+#  define MINBPC(enc) ((enc)->minBytesPerChar)
 #else
 /* minimum bytes per character */
-#define MINBPC(enc) 1
+#  define MINBPC(enc) 1
 #endif
 
-#define SB_BYTE_TYPE(enc, p) \
+#define SB_BYTE_TYPE(enc, p)                                                   \
   (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
 
 #ifdef XML_MIN_SIZE
 static int PTRFASTCALL
-sb_byteType(const ENCODING *enc, const char *p)
-{
+sb_byteType(const ENCODING *enc, const char *p) {
   return SB_BYTE_TYPE(enc, p);
 }
-#define BYTE_TYPE(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
+#  define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
 #else
-#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#  define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
 #endif
 
 #ifdef XML_MIN_SIZE
-#define BYTE_TO_ASCII(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
+#  define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
 static int PTRFASTCALL
-sb_byteToAscii(const ENCODING *enc, const char *p)
-{
+sb_byteToAscii(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
   return *p;
 }
 #else
-#define BYTE_TO_ASCII(enc, p) (*(p))
+#  define BYTE_TO_ASCII(enc, p) (*(p))
 #endif
 
-#define IS_NAME_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
-#define IS_NMSTRT_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
-#define IS_INVALID_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
+#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n)                                             \
+  (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
 
 #ifdef XML_MIN_SIZE
-#define IS_NAME_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
+#  define IS_NAME_CHAR_MINBPC(enc, p)                                          \
   (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
+#  define IS_NMSTRT_CHAR_MINBPC(enc, p)                                        \
   (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
 #else
-#define IS_NAME_CHAR_MINBPC(enc, p) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#  define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#  define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
 #endif
 
 #ifdef XML_MIN_SIZE
-#define CHAR_MATCHES(enc, p, c) \
- (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
+#  define CHAR_MATCHES(enc, p, c)                                              \
   (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
 static int PTRCALL
-sb_charMatches(const ENCODING *enc, const char *p, int c)
-{
+sb_charMatches(const ENCODING *enc, const char *p, int c) {
+  UNUSED_P(enc);
   return *p == c;
 }
 #else
 /* c is an ASCII character */
-#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#  define CHAR_MATCHES(enc, p, c) (*(p) == c)
 #endif
 
-#define PREFIX(ident) normal_ ## ident
+#define PREFIX(ident) normal_##ident
 #define XML_TOK_IMPL_C
 #include "xmltok_impl.c"
 #undef XML_TOK_IMPL_C
@@ -354,42 +310,46 @@ sb_charMatches(const ENCODING *enc, const char *p, int c)
 #undef IS_NMSTRT_CHAR_MINBPC
 #undef IS_INVALID_CHAR
 
-enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
-  UTF8_cval1 = 0x00,
-  UTF8_cval2 = 0xc0,
-  UTF8_cval3 = 0xe0,
-  UTF8_cval4 = 0xf0
+enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
+       UTF8_cval1 = 0x00,
+       UTF8_cval2 = 0xc0,
+       UTF8_cval3 = 0xe0,
+       UTF8_cval4 = 0xf0
 };
 
 void
-_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef)
-{
-  const char * fromLim = *fromLimRef;
+_INTERNAL_trim_to_complete_utf8_characters(const char *from,
+                                           const char **fromLimRef) {
+  const char *fromLim = *fromLimRef;
   size_t walked = 0;
   for (; fromLim > from; fromLim--, walked++) {
     const unsigned char prev = (unsigned char)fromLim[-1];
-    if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
+    if ((prev & 0xf8u)
+        == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
       if (walked + 1 >= 4) {
         fromLim += 4 - 1;
         break;
       } else {
         walked = 0;
       }
-    } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
+    } else if ((prev & 0xf0u)
+               == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
       if (walked + 1 >= 3) {
         fromLim += 3 - 1;
         break;
       } else {
         walked = 0;
       }
-    } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
+    } else if ((prev & 0xe0u)
+               == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
       if (walked + 1 >= 2) {
         fromLim += 2 - 1;
         break;
       } else {
         walked = 0;
       }
-    } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
+    } else if ((prev & 0x80u)
+               == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
       break;
     }
   }
@@ -397,16 +357,15 @@ _INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** from
 }
 
 static enum XML_Convert_Result PTRCALL
-utf8_toUtf8(const ENCODING *UNUSED_P(enc),
-            const char **fromP, const char *fromLim,
-            char **toP, const char *toLim)
-{
+utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+            char **toP, const char *toLim) {
   bool input_incomplete = false;
   bool output_exhausted = false;
 
   /* Avoid copying partial characters (due to limited space). */
   const ptrdiff_t bytesAvailable = fromLim - *fromP;
   const ptrdiff_t bytesStorable = toLim - *toP;
+  UNUSED_P(enc);
   if (bytesAvailable > bytesStorable) {
     fromLim = *fromP + bytesStorable;
     output_exhausted = true;
@@ -414,7 +373,7 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc),
 
   /* Avoid copying partial characters (from incomplete input). */
   {
-    const char * const fromLimBefore = fromLim;
+    const char *const fromLimBefore = fromLim;
     _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
     if (fromLim < fromLimBefore) {
       input_incomplete = true;
@@ -428,7 +387,7 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc),
     *toP += bytesToCopy;
   }
 
-  if (output_exhausted)  /* needs to go first */
+  if (output_exhausted) /* needs to go first */
     return XML_CONVERT_OUTPUT_EXHAUSTED;
   else if (input_incomplete)
     return XML_CONVERT_INPUT_INCOMPLETE;
@@ -437,10 +396,8 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc),
 }
 
 static enum XML_Convert_Result PTRCALL
-utf8_toUtf16(const ENCODING *enc,
-             const char **fromP, const char *fromLim,
-             unsigned short **toP, const unsigned short *toLim)
-{
+utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
+             unsigned short **toP, const unsigned short *toLim) {
   enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
   unsigned short *to = *toP;
   const char *from = *fromP;
@@ -459,30 +416,28 @@ utf8_toUtf16(const ENCODING *enc,
         res = XML_CONVERT_INPUT_INCOMPLETE;
         goto after;
       }
-      *to++ = (unsigned short)(((from[0] & 0xf) << 12)
-                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
+      *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6)
+                               | (from[2] & 0x3f));
       from += 3;
       break;
-    case BT_LEAD4:
-      {
-        unsigned long n;
-        if (toLim - to < 2) {
-          res = XML_CONVERT_OUTPUT_EXHAUSTED;
-          goto after;
-        }
-        if (fromLim - from < 4) {
-          res = XML_CONVERT_INPUT_INCOMPLETE;
-          goto after;
-        }
-        n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
-            | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
-        n -= 0x10000;
-        to[0] = (unsigned short)((n >> 10) | 0xD800);
-        to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
-        to += 2;
-        from += 4;
+    case BT_LEAD4: {
+      unsigned long n;
+      if (toLim - to < 2) {
+        res = XML_CONVERT_OUTPUT_EXHAUSTED;
+        goto after;
       }
-      break;
+      if (fromLim - from < 4) {
+        res = XML_CONVERT_INPUT_INCOMPLETE;
+        goto after;
+      }
+      n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
+          | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+      n -= 0x10000;
+      to[0] = (unsigned short)((n >> 10) | 0xD800);
+      to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+      to += 2;
+      from += 4;
+    } break;
     default:
       *to++ = *from++;
       break;
@@ -497,56 +452,51 @@ after:
 }
 
 #ifdef XML_NS
-static const struct normal_encoding utf8_encoding_ns = {
-  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-  {
-#include "asciitab.h"
-#include "utf8tab.h"
-  },
-  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+static const struct normal_encoding utf8_encoding_ns
+    = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+       {
+#  include "asciitab.h"
+#  include "utf8tab.h"
+       },
+       STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 #endif
 
-static const struct normal_encoding utf8_encoding = {
-  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-  {
+static const struct normal_encoding utf8_encoding
+    = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+       {
 #define BT_COLON BT_NMSTRT
 #include "asciitab.h"
 #undef BT_COLON
 #include "utf8tab.h"
-  },
-  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+       },
+       STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
 #ifdef XML_NS
 
-static const struct normal_encoding internal_utf8_encoding_ns = {
-  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-  {
-#include "iasciitab.h"
-#include "utf8tab.h"
-  },
-  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+static const struct normal_encoding internal_utf8_encoding_ns
+    = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+       {
+#  include "iasciitab.h"
+#  include "utf8tab.h"
+       },
+       STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
 #endif
 
-static const struct normal_encoding internal_utf8_encoding = {
-  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-  {
+static const struct normal_encoding internal_utf8_encoding
+    = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+       {
 #define BT_COLON BT_NMSTRT
 #include "iasciitab.h"
 #undef BT_COLON
 #include "utf8tab.h"
-  },
-  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+       },
+       STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
 static enum XML_Convert_Result PTRCALL
-latin1_toUtf8(const ENCODING *UNUSED_P(enc),
-              const char **fromP, const char *fromLim,
-              char **toP, const char *toLim)
-{
+latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+              char **toP, const char *toLim) {
+  UNUSED_P(enc);
   for (;;) {
     unsigned char c;
     if (*fromP == fromLim)
@@ -558,8 +508,7 @@ latin1_toUtf8(const ENCODING *UNUSED_P(enc),
       *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
       *(*toP)++ = (char)((c & 0x3f) | 0x80);
       (*fromP)++;
-    }
-    else {
+    } else {
       if (*toP == toLim)
         return XML_CONVERT_OUTPUT_EXHAUSTED;
       *(*toP)++ = *(*fromP)++;
@@ -568,10 +517,9 @@ latin1_toUtf8(const ENCODING *UNUSED_P(enc),
 }
 
 static enum XML_Convert_Result PTRCALL
-latin1_toUtf16(const ENCODING *UNUSED_P(enc),
-               const char **fromP, const char *fromLim,
-               unsigned short **toP, const unsigned short *toLim)
-{
+latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
+               unsigned short **toP, const unsigned short *toLim) {
+  UNUSED_P(enc);
   while (*fromP < fromLim && *toP < toLim)
     *(*toP)++ = (unsigned char)*(*fromP)++;
 
@@ -583,33 +531,30 @@ latin1_toUtf16(const ENCODING *UNUSED_P(enc),
 
 #ifdef XML_NS
 
-static const struct normal_encoding latin1_encoding_ns = {
-  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
-  {
-#include "asciitab.h"
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+static const struct normal_encoding latin1_encoding_ns
+    = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
+       {
+#  include "asciitab.h"
+#  include "latin1tab.h"
+       },
+       STANDARD_VTABLE(sb_) NULL_VTABLE};
 
 #endif
 
-static const struct normal_encoding latin1_encoding = {
-  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
-  {
+static const struct normal_encoding latin1_encoding
+    = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
+       {
 #define BT_COLON BT_NMSTRT
 #include "asciitab.h"
 #undef BT_COLON
 #include "latin1tab.h"
-  },
-  STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+       },
+       STANDARD_VTABLE(sb_) NULL_VTABLE};
 
 static enum XML_Convert_Result PTRCALL
-ascii_toUtf8(const ENCODING *UNUSED_P(enc),
-             const char **fromP, const char *fromLim,
-             char **toP, const char *toLim)
-{
+ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+             char **toP, const char *toLim) {
+  UNUSED_P(enc);
   while (*fromP < fromLim && *toP < toLim)
     *(*toP)++ = *(*fromP)++;
 
@@ -621,40 +566,45 @@ ascii_toUtf8(const ENCODING *UNUSED_P(enc),
 
 #ifdef XML_NS
 
-static const struct normal_encoding ascii_encoding_ns = {
-  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
-  {
-#include "asciitab.h"
-/* BT_NONXML == 0 */
-  },
-  STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+static const struct normal_encoding ascii_encoding_ns
+    = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
+       {
+#  include "asciitab.h"
+           /* BT_NONXML == 0 */
+       },
+       STANDARD_VTABLE(sb_) NULL_VTABLE};
 
 #endif
 
-static const struct normal_encoding ascii_encoding = {
-  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
-  {
+static const struct normal_encoding ascii_encoding
+    = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
+       {
 #define BT_COLON BT_NMSTRT
 #include "asciitab.h"
 #undef BT_COLON
-/* BT_NONXML == 0 */
-  },
-  STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+           /* BT_NONXML == 0 */
+       },
+       STANDARD_VTABLE(sb_) NULL_VTABLE};
 
 static int PTRFASTCALL
-unicode_byte_type(char hi, char lo)
-{
+unicode_byte_type(char hi, char lo) {
   switch ((unsigned char)hi) {
-  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+  /* 0xD800–0xDBFF first 16-bit code unit or high surrogate (W1) */
+  case 0xD8:
+  case 0xD9:
+  case 0xDA:
+  case 0xDB:
     return BT_LEAD4;
-  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+  /* 0xDC00–0xDFFF second 16-bit code unit or low surrogate (W2) */
+  case 0xDC:
+  case 0xDD:
+  case 0xDE:
+  case 0xDF:
     return BT_TRAIL;
   case 0xFF:
     switch ((unsigned char)lo) {
-    case 0xFF:
-    case 0xFE:
+    case 0xFF: /* noncharacter-FFFF */
+    case 0xFE: /* noncharacter-FFFE */
       return BT_NONXML;
     }
     break;
@@ -662,102 +612,105 @@ unicode_byte_type(char hi, char lo)
   return BT_NONASCII;
 }
 
-#define DEFINE_UTF16_TO_UTF8(E) \
-static enum XML_Convert_Result  PTRCALL \
-E ## toUtf8(const ENCODING *UNUSED_P(enc), \
-            const char **fromP, const char *fromLim, \
-            char **toP, const char *toLim) \
-{ \
-  const char *from = *fromP; \
-  fromLim = from + (((fromLim - from) >> 1) << 1);  /* shrink to even */ \
-  for (; from < fromLim; from += 2) { \
-    int plane; \
-    unsigned char lo2; \
-    unsigned char lo = GET_LO(from); \
-    unsigned char hi = GET_HI(from); \
-    switch (hi) { \
-    case 0: \
-      if (lo < 0x80) { \
-        if (*toP == toLim) { \
-          *fromP = from; \
-          return XML_CONVERT_OUTPUT_EXHAUSTED; \
-        } \
-        *(*toP)++ = lo; \
-        break; \
-      } \
-      /* fall through */ \
-    case 0x1: case 0x2: case 0x3: \
-    case 0x4: case 0x5: case 0x6: case 0x7: \
-      if (toLim -  *toP < 2) { \
-        *fromP = from; \
-        return XML_CONVERT_OUTPUT_EXHAUSTED; \
-      } \
-      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
-      *(*toP)++ = ((lo & 0x3f) | 0x80); \
-      break; \
-    default: \
-      if (toLim -  *toP < 3)  { \
-        *fromP = from; \
-        return XML_CONVERT_OUTPUT_EXHAUSTED; \
-      } \
-      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
-      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
-      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
-      *(*toP)++ = ((lo & 0x3f) | 0x80); \
-      break; \
-    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
-      if (toLim -  *toP < 4) { \
-        *fromP = from; \
-        return XML_CONVERT_OUTPUT_EXHAUSTED; \
-      } \
-      if (fromLim - from < 4) { \
-        *fromP = from; \
-        return XML_CONVERT_INPUT_INCOMPLETE; \
-      } \
-      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
-      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
-      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
-      from += 2; \
-      lo2 = GET_LO(from); \
-      *(*toP)++ = (((lo & 0x3) << 4) \
-                   | ((GET_HI(from) & 0x3) << 2) \
-                   | (lo2 >> 6) \
-                   | 0x80); \
-      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
-      break; \
-    } \
-  } \
-  *fromP = from; \
-  if (from < fromLim) \
-    return XML_CONVERT_INPUT_INCOMPLETE; \
-  else \
-    return XML_CONVERT_COMPLETED; \
-}
+#define DEFINE_UTF16_TO_UTF8(E)                                                \
+  static enum XML_Convert_Result PTRCALL E##toUtf8(                            \
+      const ENCODING *enc, const char **fromP, const char *fromLim,            \
+      char **toP, const char *toLim) {                                         \
+    const char *from = *fromP;                                                 \
+    UNUSED_P(enc);                                                             \
+    fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */      \
+    for (; from < fromLim; from += 2) {                                        \
+      int plane;                                                               \
+      unsigned char lo2;                                                       \
+      unsigned char lo = GET_LO(from);                                         \
+      unsigned char hi = GET_HI(from);                                         \
+      switch (hi) {                                                            \
+      case 0:                                                                  \
+        if (lo < 0x80) {                                                       \
+          if (*toP == toLim) {                                                 \
+            *fromP = from;                                                     \
+            return XML_CONVERT_OUTPUT_EXHAUSTED;                               \
+          }                                                                    \
+          *(*toP)++ = lo;                                                      \
+          break;                                                               \
+        }                                                                      \
+        /* fall through */                                                     \
+      case 0x1:                                                                \
+      case 0x2:                                                                \
+      case 0x3:                                                                \
+      case 0x4:                                                                \
+      case 0x5:                                                                \
+      case 0x6:                                                                \
+      case 0x7:                                                                \
+        if (toLim - *toP < 2) {                                                \
+          *fromP = from;                                                       \
+          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
+        }                                                                      \
+        *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2);                      \
+        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
+        break;                                                                 \
+      default:                                                                 \
+        if (toLim - *toP < 3) {                                                \
+          *fromP = from;                                                       \
+          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
+        }                                                                      \
+        /* 16 bits divided 4, 6, 6 amongst 3 bytes */                          \
+        *(*toP)++ = ((hi >> 4) | UTF8_cval3);                                  \
+        *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80);                    \
+        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
+        break;                                                                 \
+      case 0xD8:                                                               \
+      case 0xD9:                                                               \
+      case 0xDA:                                                               \
+      case 0xDB:                                                               \
+        if (toLim - *toP < 4) {                                                \
+          *fromP = from;                                                       \
+          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
+        }                                                                      \
+        if (fromLim - from < 4) {                                              \
+          *fromP = from;                                                       \
+          return XML_CONVERT_INPUT_INCOMPLETE;                                 \
+        }                                                                      \
+        plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1;                   \
+        *(*toP)++ = (char)((plane >> 2) | UTF8_cval4);                         \
+        *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80);         \
+        from += 2;                                                             \
+        lo2 = GET_LO(from);                                                    \
+        *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2)           \
+                     | (lo2 >> 6) | 0x80);                                     \
+        *(*toP)++ = ((lo2 & 0x3f) | 0x80);                                     \
+        break;                                                                 \
+      }                                                                        \
+    }                                                                          \
+    *fromP = from;                                                             \
+    if (from < fromLim)                                                        \
+      return XML_CONVERT_INPUT_INCOMPLETE;                                     \
+    else                                                                       \
+      return XML_CONVERT_COMPLETED;                                            \
+  }
 
-#define DEFINE_UTF16_TO_UTF16(E) \
-static enum XML_Convert_Result  PTRCALL \
-E ## toUtf16(const ENCODING *UNUSED_P(enc), \
-             const char **fromP, const char *fromLim, \
-             unsigned short **toP, const unsigned short *toLim) \
-{ \
-  enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
-  fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1);  /* shrink to even */ \
-  /* Avoid copying first half only of surrogate */ \
-  if (fromLim - *fromP > ((toLim - *toP) << 1) \
-      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
-    fromLim -= 2; \
-    res = XML_CONVERT_INPUT_INCOMPLETE; \
-  } \
-  for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
-    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
-  if ((*toP == toLim) && (*fromP < fromLim)) \
-    return XML_CONVERT_OUTPUT_EXHAUSTED; \
-  else \
-    return res; \
-}
+#define DEFINE_UTF16_TO_UTF16(E)                                               \
+  static enum XML_Convert_Result PTRCALL E##toUtf16(                           \
+      const ENCODING *enc, const char **fromP, const char *fromLim,            \
+      unsigned short **toP, const unsigned short *toLim) {                     \
+    enum XML_Convert_Result res = XML_CONVERT_COMPLETED;                       \
+    UNUSED_P(enc);                                                             \
+    fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */  \
+    /* Avoid copying first half only of surrogate */                           \
+    if (fromLim - *fromP > ((toLim - *toP) << 1)                               \
+        && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) {                             \
+      fromLim -= 2;                                                            \
+      res = XML_CONVERT_INPUT_INCOMPLETE;                                      \
+    }                                                                          \
+    for (; *fromP < fromLim && *toP < toLim; *fromP += 2)                      \
+      *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP);                      \
+    if ((*toP == toLim) && (*fromP < fromLim))                                 \
+      return XML_CONVERT_OUTPUT_EXHAUSTED;                                     \
+    else                                                                       \
+      return res;                                                              \
+  }
 
-#define SET2(ptr, ch) \
-  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define SET2(ptr, ch) (((ptr)[0] = ((ch)&0xff)), ((ptr)[1] = ((ch) >> 8)))
 #define GET_LO(ptr) ((unsigned char)(ptr)[0])
 #define GET_HI(ptr) ((unsigned char)(ptr)[1])
 
@@ -768,8 +721,7 @@ DEFINE_UTF16_TO_UTF16(little2_)
 #undef GET_LO
 #undef GET_HI
 
-#define SET2(ptr, ch) \
-  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define SET2(ptr, ch) (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch)&0xFF)))
 #define GET_LO(ptr) ((unsigned char)(ptr)[1])
 #define GET_HI(ptr) ((unsigned char)(ptr)[0])
 
@@ -780,292 +732,279 @@ DEFINE_UTF16_TO_UTF16(big2_)
 #undef GET_LO
 #undef GET_HI
 
-#define LITTLE2_BYTE_TYPE(enc, p) \
- ((p)[1] == 0 \
-  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
-  : unicode_byte_type((p)[1], (p)[0]))
-#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
-#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
-#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+#define LITTLE2_BYTE_TYPE(enc, p)                                              \
+  ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]  \
+               : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(p)                                         \
   UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
-#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)                                       \
   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
 
 #ifdef XML_MIN_SIZE
 
 static int PTRFASTCALL
-little2_byteType(const ENCODING *enc, const char *p)
-{
+little2_byteType(const ENCODING *enc, const char *p) {
   return LITTLE2_BYTE_TYPE(enc, p);
 }
 
 static int PTRFASTCALL
-little2_byteToAscii(const ENCODING *enc, const char *p)
-{
-  return LITTLE2_BYTE_TO_ASCII(enc, p);
+little2_byteToAscii(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return LITTLE2_BYTE_TO_ASCII(p);
 }
 
 static int PTRCALL
-little2_charMatches(const ENCODING *enc, const char *p, int c)
-{
-  return LITTLE2_CHAR_MATCHES(enc, p, c);
+little2_charMatches(const ENCODING *enc, const char *p, int c) {
+  UNUSED_P(enc);
+  return LITTLE2_CHAR_MATCHES(p, c);
 }
 
 static int PTRFASTCALL
-little2_isNameMin(const ENCODING *enc, const char *p)
-{
-  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+little2_isNameMin(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return LITTLE2_IS_NAME_CHAR_MINBPC(p);
 }
 
 static int PTRFASTCALL
-little2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
-  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+little2_isNmstrtMin(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
 }
 
-#undef VTABLE
-#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+#  undef VTABLE
+#  define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
 
 #else /* not XML_MIN_SIZE */
 
-#undef PREFIX
-#define PREFIX(ident) little2_ ## ident
-#define MINBPC(enc) 2
+#  undef PREFIX
+#  define PREFIX(ident) little2_##ident
+#  define MINBPC(enc) 2
 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
+#  define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#  define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
+#  define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
+#  define IS_NAME_CHAR(enc, p, n) 0
+#  define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
+#  define IS_NMSTRT_CHAR(enc, p, n) (0)
+#  define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
+
+#  define XML_TOK_IMPL_C
+#  include "xmltok_impl.c"
+#  undef XML_TOK_IMPL_C
+
+#  undef MINBPC
+#  undef BYTE_TYPE
+#  undef BYTE_TO_ASCII
+#  undef CHAR_MATCHES
+#  undef IS_NAME_CHAR
+#  undef IS_NAME_CHAR_MINBPC
+#  undef IS_NMSTRT_CHAR
+#  undef IS_NMSTRT_CHAR_MINBPC
+#  undef IS_INVALID_CHAR
 
 #endif /* not XML_MIN_SIZE */
 
 #ifdef XML_NS
 
-static const struct normal_encoding little2_encoding_ns = {
-  { VTABLE, 2, 0,
-#if BYTEORDER == 1234
-    1
-#else
-    0
-#endif
-  },
-  {
-#include "asciitab.h"
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+static const struct normal_encoding little2_encoding_ns
+    = {{VTABLE, 2, 0,
+#  if BYTEORDER == 1234
+        1
+#  else
+        0
+#  endif
+       },
+       {
+#  include "asciitab.h"
+#  include "latin1tab.h"
+       },
+       STANDARD_VTABLE(little2_) NULL_VTABLE};
 
 #endif
 
-static const struct normal_encoding little2_encoding = {
-  VTABLE, 2, 0,
+static const struct normal_encoding little2_encoding
+    = {{VTABLE, 2, 0,
 #if BYTEORDER == 1234
-    1
+        1
 #else
-    0
+        0
 #endif
-  },
-  {
+       },
+       {
 #define BT_COLON BT_NMSTRT
 #include "asciitab.h"
 #undef BT_COLON
 #include "latin1tab.h"
-  },
-  STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+       },
+       STANDARD_VTABLE(little2_) NULL_VTABLE};
 
 #if BYTEORDER != 4321
 
-#ifdef XML_NS
+#  ifdef XML_NS
 
-static const struct normal_encoding internal_little2_encoding_ns = {
-  { VTABLE, 2, 0, 1 },
-  {
-#include "iasciitab.h"
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_little2_encoding_ns
+    = {{VTABLE, 2, 0, 1},
+       {
+#    include "iasciitab.h"
+#    include "latin1tab.h"
+       },
+       STANDARD_VTABLE(little2_) NULL_VTABLE};
 
-#endif
+#  endif
 
-static const struct normal_encoding internal_little2_encoding = {
-  { VTABLE, 2, 0, 1 },
-  {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_little2_encoding
+    = {{VTABLE, 2, 0, 1},
+       {
+#  define BT_COLON BT_NMSTRT
+#  include "iasciitab.h"
+#  undef BT_COLON
+#  include "latin1tab.h"
+       },
+       STANDARD_VTABLE(little2_) NULL_VTABLE};
 
 #endif
 
-
-#define BIG2_BYTE_TYPE(enc, p) \
- ((p)[0] == 0 \
-  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
-  : unicode_byte_type((p)[0], (p)[1]))
-#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
-#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
-#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+#define BIG2_BYTE_TYPE(enc, p)                                                 \
+  ((p)[0] == 0                                                                 \
+       ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]]        \
+       : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(p)                                            \
   UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
-#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(p)                                          \
   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
 
 #ifdef XML_MIN_SIZE
 
 static int PTRFASTCALL
-big2_byteType(const ENCODING *enc, const char *p)
-{
+big2_byteType(const ENCODING *enc, const char *p) {
   return BIG2_BYTE_TYPE(enc, p);
 }
 
 static int PTRFASTCALL
-big2_byteToAscii(const ENCODING *enc, const char *p)
-{
-  return BIG2_BYTE_TO_ASCII(enc, p);
+big2_byteToAscii(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return BIG2_BYTE_TO_ASCII(p);
 }
 
 static int PTRCALL
-big2_charMatches(const ENCODING *enc, const char *p, int c)
-{
-  return BIG2_CHAR_MATCHES(enc, p, c);
+big2_charMatches(const ENCODING *enc, const char *p, int c) {
+  UNUSED_P(enc);
+  return BIG2_CHAR_MATCHES(p, c);
 }
 
 static int PTRFASTCALL
-big2_isNameMin(const ENCODING *enc, const char *p)
-{
-  return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+big2_isNameMin(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return BIG2_IS_NAME_CHAR_MINBPC(p);
 }
 
 static int PTRFASTCALL
-big2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
-  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+big2_isNmstrtMin(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
 }
 
-#undef VTABLE
-#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+#  undef VTABLE
+#  define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
 
 #else /* not XML_MIN_SIZE */
 
-#undef PREFIX
-#define PREFIX(ident) big2_ ## ident
-#define MINBPC(enc) 2
+#  undef PREFIX
+#  define PREFIX(ident) big2_##ident
+#  define MINBPC(enc) 2
 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
+#  define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#  define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
+#  define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
+#  define IS_NAME_CHAR(enc, p, n) 0
+#  define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
+#  define IS_NMSTRT_CHAR(enc, p, n) (0)
+#  define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
+
+#  define XML_TOK_IMPL_C
+#  include "xmltok_impl.c"
+#  undef XML_TOK_IMPL_C
+
+#  undef MINBPC
+#  undef BYTE_TYPE
+#  undef BYTE_TO_ASCII
+#  undef CHAR_MATCHES
+#  undef IS_NAME_CHAR
+#  undef IS_NAME_CHAR_MINBPC
+#  undef IS_NMSTRT_CHAR
+#  undef IS_NMSTRT_CHAR_MINBPC
+#  undef IS_INVALID_CHAR
 
 #endif /* not XML_MIN_SIZE */
 
 #ifdef XML_NS
 
-static const struct normal_encoding big2_encoding_ns = {
-  { VTABLE, 2, 0,
-#if BYTEORDER == 4321
-  1
-#else
-  0
-#endif
-  },
-  {
-#include "asciitab.h"
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+static const struct normal_encoding big2_encoding_ns
+    = {{VTABLE, 2, 0,
+#  if BYTEORDER == 4321
+        1
+#  else
+        0
+#  endif
+       },
+       {
+#  include "asciitab.h"
+#  include "latin1tab.h"
+       },
+       STANDARD_VTABLE(big2_) NULL_VTABLE};
 
 #endif
 
-static const struct normal_encoding big2_encoding = {
-  VTABLE, 2, 0,
+static const struct normal_encoding big2_encoding
+    = {{VTABLE, 2, 0,
 #if BYTEORDER == 4321
-  1
+        1
 #else
-  0
+        0
 #endif
-  },
-  {
+       },
+       {
 #define BT_COLON BT_NMSTRT
 #include "asciitab.h"
 #undef BT_COLON
 #include "latin1tab.h"
-  },
-  STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+       },
+       STANDARD_VTABLE(big2_) NULL_VTABLE};
 
 #if BYTEORDER != 1234
 
-#ifdef XML_NS
+#  ifdef XML_NS
 
-static const struct normal_encoding internal_big2_encoding_ns = {
-  { VTABLE, 2, 0, 1 },
-  {
-#include "iasciitab.h"
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_big2_encoding_ns
+    = {{VTABLE, 2, 0, 1},
+       {
+#    include "iasciitab.h"
+#    include "latin1tab.h"
+       },
+       STANDARD_VTABLE(big2_) NULL_VTABLE};
 
-#endif
+#  endif
 
-static const struct normal_encoding internal_big2_encoding = {
-  { VTABLE, 2, 0, 1 },
-  {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-  },
-  STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_big2_encoding
+    = {{VTABLE, 2, 0, 1},
+       {
+#  define BT_COLON BT_NMSTRT
+#  include "iasciitab.h"
+#  undef BT_COLON
+#  include "latin1tab.h"
+       },
+       STANDARD_VTABLE(big2_) NULL_VTABLE};
 
 #endif
 
 #undef PREFIX
 
 static int FASTCALL
-streqci(const char *s1, const char *s2)
-{
+streqci(const char *s1, const char *s2) {
   for (;;) {
     char c1 = *s1++;
     char c2 = *s2++;
@@ -1079,22 +1018,21 @@ streqci(const char *s1, const char *s2)
       c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
     if (c1 != c2)
       return 0;
-    if (!c1)
+    if (! c1)
       break;
   }
   return 1;
 }
 
 static void PTRCALL
-initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
-                   const char *end, POSITION *pos)
-{
+initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
+                   POSITION *pos) {
+  UNUSED_P(enc);
   normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
 }
 
 static int
-toAscii(const ENCODING *enc, const char *ptr, const char *end)
-{
+toAscii(const ENCODING *enc, const char *ptr, const char *end) {
   char buf[1];
   char *p = buf;
   XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
@@ -1105,8 +1043,7 @@ toAscii(const ENCODING *enc, const char *ptr, const char *end)
 }
 
 static int FASTCALL
-isSpace(int c)
-{
+isSpace(int c) {
   switch (c) {
   case 0x20:
   case 0xD:
@@ -1121,21 +1058,16 @@ isSpace(int c)
    followed by name=val.
 */
 static int
-parsePseudoAttribute(const ENCODING *enc,
-                     const char *ptr,
-                     const char *end,
-                     const char **namePtr,
-                     const char **nameEndPtr,
-                     const char **valPtr,
-                     const char **nextTokPtr)
-{
+parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end,
+                     const char **namePtr, const char **nameEndPtr,
+                     const char **valPtr, const char **nextTokPtr) {
   int c;
   char open;
   if (ptr == end) {
     *namePtr = NULL;
     return 1;
   }
-  if (!isSpace(toAscii(enc, ptr, end))) {
+  if (! isSpace(toAscii(enc, ptr, end))) {
     *nextTokPtr = ptr;
     return 0;
   }
@@ -1191,12 +1123,9 @@ parsePseudoAttribute(const ENCODING *enc,
     c = toAscii(enc, ptr, end);
     if (c == open)
       break;
-    if (!(ASCII_a <= c && c <= ASCII_z)
-        && !(ASCII_A <= c && c <= ASCII_Z)
-        && !(ASCII_0 <= c && c <= ASCII_9)
-        && c != ASCII_PERIOD
-        && c != ASCII_MINUS
-        && c != ASCII_UNDERSCORE) {
+    if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)
+        && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD
+        && c != ASCII_MINUS && c != ASCII_UNDERSCORE) {
       *nextTokPtr = ptr;
       return 0;
     }
@@ -1205,68 +1134,52 @@ parsePseudoAttribute(const ENCODING *enc,
   return 1;
 }
 
-static const char KW_version[] = {
-  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
-};
+static const char KW_version[]
+    = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'};
 
-static const char KW_encoding[] = {
-  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
-};
+static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d,
+                                   ASCII_i, ASCII_n, ASCII_g, '\0'};
 
-static const char KW_standalone[] = {
-  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
-  ASCII_n, ASCII_e, '\0'
-};
+static const char KW_standalone[]
+    = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a,
+       ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'};
 
-static const char KW_yes[] = {
-  ASCII_y, ASCII_e, ASCII_s,  '\0'
-};
+static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'};
 
-static const char KW_no[] = {
-  ASCII_n, ASCII_o,  '\0'
-};
+static const char KW_no[] = {ASCII_n, ASCII_o, '\0'};
 
 static int
-doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
-                                                 const char *,
+doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *,
                                                  const char *),
-               int isGeneralTextEntity,
-               const ENCODING *enc,
-               const char *ptr,
-               const char *end,
-               const char **badPtr,
-               const char **versionPtr,
-               const char **versionEndPtr,
-               const char **encodingName,
-               const ENCODING **encoding,
-               int *standalone)
-{
+               int isGeneralTextEntity, const ENCODING *enc, const char *ptr,
+               const char *end, const char **badPtr, const char **versionPtr,
+               const char **versionEndPtr, const char **encodingName,
+               const ENCODING **encoding, int *standalone) {
   const char *val = NULL;
   const char *name = NULL;
   const char *nameEnd = NULL;
   ptr += 5 * enc->minBytesPerChar;
   end -= 2 * enc->minBytesPerChar;
-  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
-      || !name) {
+  if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
+      || ! name) {
     *badPtr = ptr;
     return 0;
   }
-  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
-    if (!isGeneralTextEntity) {
+  if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+    if (! isGeneralTextEntity) {
       *badPtr = name;
       return 0;
     }
-  }
-  else {
+  } else {
     if (versionPtr)
       *versionPtr = val;
     if (versionEndPtr)
       *versionEndPtr = ptr;
-    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+    if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
       *badPtr = ptr;
       return 0;
     }
-    if (!name) {
+    if (! name) {
       if (isGeneralTextEntity) {
         /* a TextDecl must have an EncodingDecl */
         *badPtr = ptr;
@@ -1277,7 +1190,7 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
   }
   if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
     int c = toAscii(enc, val, end);
-    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+    if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) {
       *badPtr = val;
       return 0;
     }
@@ -1285,14 +1198,14 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
       *encodingName = val;
     if (encoding)
       *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
-    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+    if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
       *badPtr = ptr;
       return 0;
     }
-    if (!name)
+    if (! name)
       return 1;
   }
-  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
+  if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
       || isGeneralTextEntity) {
     *badPtr = name;
     return 0;
@@ -1300,12 +1213,10 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
   if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
     if (standalone)
       *standalone = 1;
-  }
-  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+  } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
     if (standalone)
       *standalone = 0;
-  }
-  else {
+  } else {
     *badPtr = val;
     return 0;
   }
@@ -1319,11 +1230,16 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
 }
 
 static int FASTCALL
-checkCharRefNumber(int result)
-{
+checkCharRefNumber(int result) {
   switch (result >> 8) {
-  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
-  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+  case 0xD8:
+  case 0xD9:
+  case 0xDA:
+  case 0xDB:
+  case 0xDC:
+  case 0xDD:
+  case 0xDE:
+  case 0xDF:
     return -1;
   case 0:
     if (latin1_encoding.type[result] == BT_NONXML)
@@ -1338,8 +1254,7 @@ checkCharRefNumber(int result)
 }
 
 int FASTCALL
-XmlUtf8Encode(int c, char *buf)
-{
+XmlUtf8Encode(int c, char *buf) {
   enum {
     /* minN is minimum legal resulting value for N byte sequence */
     min2 = 0x80,
@@ -1375,8 +1290,7 @@ XmlUtf8Encode(int c, char *buf)
 }
 
 int FASTCALL
-XmlUtf16Encode(int charNum, unsigned short *buf)
-{
+XmlUtf16Encode(int charNum, unsigned short *buf) {
   if (charNum < 0)
     return 0;
   if (charNum < 0x10000) {
@@ -1400,17 +1314,15 @@ struct unknown_encoding {
   char utf8[256][4];
 };
 
-#define AS_UNKNOWN_ENCODING(enc)  ((const struct unknown_encoding *) (enc))
+#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc))
 
 int
-XmlSizeOfUnknownEncoding(void)
-{
+XmlSizeOfUnknownEncoding(void) {
   return sizeof(struct unknown_encoding);
 }
 
 static int PTRFASTCALL
-unknown_isName(const ENCODING *enc, const char *p)
-{
+unknown_isName(const ENCODING *enc, const char *p) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   int c = uenc->convert(uenc->userData, p);
   if (c & ~0xFFFF)
@@ -1419,8 +1331,7 @@ unknown_isName(const ENCODING *enc, const char *p)
 }
 
 static int PTRFASTCALL
-unknown_isNmstrt(const ENCODING *enc, const char *p)
-{
+unknown_isNmstrt(const ENCODING *enc, const char *p) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   int c = uenc->convert(uenc->userData, p);
   if (c & ~0xFFFF)
@@ -1429,18 +1340,15 @@ unknown_isNmstrt(const ENCODING *enc, const char *p)
 }
 
 static int PTRFASTCALL
-unknown_isInvalid(const ENCODING *enc, const char *p)
-{
+unknown_isInvalid(const ENCODING *enc, const char *p) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   int c = uenc->convert(uenc->userData, p);
   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
 }
 
 static enum XML_Convert_Result PTRCALL
-unknown_toUtf8(const ENCODING *enc,
-               const char **fromP, const char *fromLim,
-               char **toP, const char *toLim)
-{
+unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+               char **toP, const char *toLim) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   char buf[XML_UTF8_ENCODE_MAX];
   for (;;) {
@@ -1458,8 +1366,7 @@ unknown_toUtf8(const ENCODING *enc,
       utf8 = buf;
       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
                  - (BT_LEAD2 - 2));
-    }
-    else {
+    } else {
       if (n > toLim - *toP)
         return XML_CONVERT_OUTPUT_EXHAUSTED;
       (*fromP)++;
@@ -1470,20 +1377,16 @@ unknown_toUtf8(const ENCODING *enc,
 }
 
 static enum XML_Convert_Result PTRCALL
-unknown_toUtf16(const ENCODING *enc,
-                const char **fromP, const char *fromLim,
-                unsigned short **toP, const unsigned short *toLim)
-{
+unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
+                unsigned short **toP, const unsigned short *toLim) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   while (*fromP < fromLim && *toP < toLim) {
     unsigned short c = uenc->utf16[(unsigned char)**fromP];
     if (c == 0) {
-      c = (unsigned short)
-          uenc->convert(uenc->userData, *fromP);
+      c = (unsigned short)uenc->convert(uenc->userData, *fromP);
       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
                  - (BT_LEAD2 - 2));
-    }
-    else
+    } else
       (*fromP)++;
     *(*toP)++ = c;
   }
@@ -1495,19 +1398,14 @@ unknown_toUtf16(const ENCODING *enc,
 }
 
 ENCODING *
-XmlInitUnknownEncoding(void *mem,
-                       int *table,
-                       CONVERTER convert,
-                       void *userData)
-{
+XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
+                       void *userData) {
   int i;
   struct unknown_encoding *e = (struct unknown_encoding *)mem;
-  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
-    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+  memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding));
   for (i = 0; i < 128; i++)
     if (latin1_encoding.type[i] != BT_OTHER
-        && latin1_encoding.type[i] != BT_NONXML
-        && table[i] != i)
+        && latin1_encoding.type[i] != BT_NONXML && table[i] != i)
       return 0;
   for (i = 0; i < 256; i++) {
     int c = table[i];
@@ -1517,35 +1415,30 @@ XmlInitUnknownEncoding(void *mem,
       e->utf16[i] = 0xFFFF;
       e->utf8[i][0] = 1;
       e->utf8[i][1] = 0;
-    }
-    else if (c < 0) {
+    } else if (c < 0) {
       if (c < -4)
         return 0;
       /* Multi-byte sequences need a converter function */
-      if (!convert)
+      if (! convert)
         return 0;
       e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
       e->utf8[i][0] = 0;
       e->utf16[i] = 0;
-    }
-    else if (c < 0x80) {
+    } else if (c < 0x80) {
       if (latin1_encoding.type[c] != BT_OTHER
-          && latin1_encoding.type[c] != BT_NONXML
-          && c != i)
+          && latin1_encoding.type[c] != BT_NONXML && c != i)
         return 0;
       e->normal.type[i] = latin1_encoding.type[c];
       e->utf8[i][0] = 1;
       e->utf8[i][1] = (char)c;
       e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
-    }
-    else if (checkCharRefNumber(c) < 0) {
+    } else if (checkCharRefNumber(c) < 0) {
       e->normal.type[i] = BT_NONXML;
       /* This shouldn't really get used. */
       e->utf16[i] = 0xFFFF;
       e->utf8[i][0] = 1;
       e->utf8[i][1] = 0;
-    }
-    else {
+    } else {
       if (c > 0xFFFF)
         return 0;
       if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
@@ -1590,44 +1483,32 @@ enum {
   NO_ENC
 };
 
-static const char KW_ISO_8859_1[] = {
-  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
-  ASCII_MINUS, ASCII_1, '\0'
-};
-static const char KW_US_ASCII[] = {
-  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
-  '\0'
-};
-static const char KW_UTF_8[] =  {
-  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
-};
-static const char KW_UTF_16[] = {
-  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
-};
-static const char KW_UTF_16BE[] = {
-  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
-  '\0'
-};
-static const char KW_UTF_16LE[] = {
-  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
-  '\0'
-};
+static const char KW_ISO_8859_1[]
+    = {ASCII_I, ASCII_S, ASCII_O,     ASCII_MINUS, ASCII_8, ASCII_8,
+       ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1,     '\0'};
+static const char KW_US_ASCII[]
+    = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S,
+       ASCII_C, ASCII_I, ASCII_I,     '\0'};
+static const char KW_UTF_8[]
+    = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'};
+static const char KW_UTF_16[]
+    = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'};
+static const char KW_UTF_16BE[]
+    = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
+       ASCII_6, ASCII_B, ASCII_E, '\0'};
+static const char KW_UTF_16LE[]
+    = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
+       ASCII_6, ASCII_L, ASCII_E, '\0'};
 
 static int FASTCALL
-getEncodingIndex(const char *name)
-{
-  static const char * const encodingNames[] = {
-    KW_ISO_8859_1,
-    KW_US_ASCII,
-    KW_UTF_8,
-    KW_UTF_16,
-    KW_UTF_16BE,
-    KW_UTF_16LE,
+getEncodingIndex(const char *name) {
+  static const char *const encodingNames[] = {
+      KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE,
   };
   int i;
   if (name == NULL)
     return NO_ENC;
-  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+  for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++)
     if (streqci(name, encodingNames[i]))
       return i;
   return UNKNOWN_ENC;
@@ -1647,15 +1528,9 @@ getEncodingIndex(const char *name)
    XML_PROLOG_STATE otherwise.
 */
 
-
 static int
-initScan(const ENCODING * const *encodingTable,
-         const INIT_ENCODING *enc,
-         int state,
-         const char *ptr,
-         const char *end,
-         const char **nextTokPtr)
-{
+initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
+         int state, const char *ptr, const char *end, const char **nextTokPtr) {
   const ENCODING **encPtr;
 
   if (ptr >= end)
@@ -1680,20 +1555,17 @@ initScan(const ENCODING * const *encodingTable,
     case 0xFE:
     case 0xFF:
     case 0xEF: /* possibly first byte of UTF-8 BOM */
-      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-          && state == XML_CONTENT_STATE)
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
         break;
       /* fall through */
     case 0x00:
     case 0x3C:
       return XML_TOK_PARTIAL;
     }
-  }
-  else {
+  } else {
     switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
     case 0xFEFF:
-      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-          && state == XML_CONTENT_STATE)
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
         break;
       *nextTokPtr = ptr + 2;
       *encPtr = encodingTable[UTF_16BE_ENC];
@@ -1707,8 +1579,7 @@ initScan(const ENCODING * const *encodingTable,
       *encPtr = encodingTable[UTF_16LE_ENC];
       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
     case 0xFFFE:
-      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-          && state == XML_CONTENT_STATE)
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
         break;
       *nextTokPtr = ptr + 2;
       *encPtr = encodingTable[UTF_16LE_ENC];
@@ -1723,8 +1594,8 @@ initScan(const ENCODING * const *encodingTable,
       */
       if (state == XML_CONTENT_STATE) {
         int e = INIT_ENC_INDEX(enc);
-        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
-            || e == UTF_16LE_ENC || e == UTF_16_ENC)
+        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC
+            || e == UTF_16_ENC)
           break;
       }
       if (ptr + 2 == end)
@@ -1747,8 +1618,7 @@ initScan(const ENCODING * const *encodingTable,
           break;
         *encPtr = encodingTable[UTF_16BE_ENC];
         return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-      }
-      else if (ptr[1] == '\0') {
+      } else if (ptr[1] == '\0') {
         /* We could recover here in the case:
             - parsing an external entity
             - second byte is 0
@@ -1770,7 +1640,6 @@ initScan(const ENCODING * const *encodingTable,
   return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
 }
 
-
 #define NS(x) x
 #define ns(x) x
 #define XML_TOK_NS_C
@@ -1781,22 +1650,19 @@ initScan(const ENCODING * const *encodingTable,
 
 #ifdef XML_NS
 
-#define NS(x) x ## NS
-#define ns(x) x ## _ns
+#  define NS(x) x##NS
+#  define ns(x) x##_ns
 
-#define XML_TOK_NS_C
-#include "xmltok_ns.c"
-#undef XML_TOK_NS_C
+#  define XML_TOK_NS_C
+#  include "xmltok_ns.c"
+#  undef XML_TOK_NS_C
 
-#undef NS
-#undef ns
+#  undef NS
+#  undef ns
 
 ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
-                         int *table,
-                         CONVERTER convert,
-                         void *userData)
-{
+XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
+                         void *userData) {
   ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
   if (enc)
     ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
index 50926f38ab323ea24a6f6db451a0061bb743a062..2adbf5307befaedec56ade9cf65dbca3734b284e 100644 (file)
@@ -38,16 +38,18 @@ extern "C" {
 #endif
 
 /* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
-                                    start of illegal ]]> sequence */
+#define XML_TOK_TRAILING_RSQB                                                  \
+  -5 /* ] or ]] at the end of the scan; might be                               \
+        start of illegal ]]> sequence */
 /* The following tokens may be returned by both XmlPrologTok and
    XmlContentTok.
 */
-#define XML_TOK_NONE -4          /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3   /* A CR at the end of the scan;
-                                    might be part of CRLF sequence */
-#define XML_TOK_PARTIAL_CHAR -2  /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1       /* only part of a token */
+#define XML_TOK_NONE -4 /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR                                                    \
+  -3                            /* A CR at the end of the scan;                \
+                                   might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1      /* only part of a token */
 #define XML_TOK_INVALID 0
 
 /* The following tokens are returned by XmlContentTok; some are also
@@ -62,24 +64,24 @@ extern "C" {
 #define XML_TOK_DATA_NEWLINE 7
 #define XML_TOK_CDATA_SECT_OPEN 8
 #define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10               /* numeric character reference */
+#define XML_TOK_CHAR_REF 10 /* numeric character reference */
 
 /* The following tokens may be returned by both XmlPrologTok and
    XmlContentTok.
 */
-#define XML_TOK_PI 11                     /* processing instruction */
-#define XML_TOK_XML_DECL 12               /* XML decl or text decl */
+#define XML_TOK_PI 11       /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
 #define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14                    /* Byte order mark */
+#define XML_TOK_BOM 14 /* Byte order mark */
 
 /* The following tokens are returned only by XmlPrologTok */
 #define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16              /* <!foo */
-#define XML_TOK_DECL_CLOSE 17             /* > */
+#define XML_TOK_DECL_OPEN 16  /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
 #define XML_TOK_NAME 18
 #define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20             /* #name */
-#define XML_TOK_OR 21                     /* | */
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21         /* | */
 #define XML_TOK_PERCENT 22
 #define XML_TOK_OPEN_PAREN 23
 #define XML_TOK_CLOSE_PAREN 24
@@ -90,14 +92,14 @@ extern "C" {
 #define XML_TOK_INSTANCE_START 29
 
 /* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30          /* name? */
-#define XML_TOK_NAME_ASTERISK 31          /* name* */
-#define XML_TOK_NAME_PLUS 32              /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33         /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34        /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35   /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36   /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37       /* )+ */
+#define XML_TOK_NAME_QUESTION 30        /* name? */
+#define XML_TOK_NAME_ASTERISK 31        /* name* */
+#define XML_TOK_NAME_PLUS 32            /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33       /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34      /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37     /* )+ */
 #define XML_TOK_COMMA 38
 
 /* The following token is returned only by XmlAttributeValueTok */
@@ -112,20 +114,20 @@ extern "C" {
 #define XML_TOK_PREFIXED_NAME 41
 
 #ifdef XML_DTD
-#define XML_TOK_IGNORE_SECT 42
+#  define XML_TOK_IGNORE_SECT 42
 #endif /* XML_DTD */
 
 #ifdef XML_DTD
-#define XML_N_STATES 4
+#  define XML_N_STATES 4
 #else /* not XML_DTD */
-#define XML_N_STATES 3
+#  define XML_N_STATES 3
 #endif /* not XML_DTD */
 
 #define XML_PROLOG_STATE 0
 #define XML_CONTENT_STATE 1
 #define XML_CDATA_SECTION_STATE 2
 #ifdef XML_DTD
-#define XML_IGNORE_SECTION_STATE 3
+#  define XML_IGNORE_SECTION_STATE 3
 #endif /* XML_DTD */
 
 #define XML_N_LITERAL_TYPES 2
@@ -153,52 +155,41 @@ typedef struct {
 struct encoding;
 typedef struct encoding ENCODING;
 
-typedef int (PTRCALL *SCANNER)(const ENCODING *,
-                               const char *,
-                               const char *,
-                               const char **);
+typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
+                              const char **);
 
 enum XML_Convert_Result {
   XML_CONVERT_COMPLETED = 0,
   XML_CONVERT_INPUT_INCOMPLETE = 1,
-  XML_CONVERT_OUTPUT_EXHAUSTED = 2  /* and therefore potentially input remaining as well */
+  XML_CONVERT_OUTPUT_EXHAUSTED
+  = 2 /* and therefore potentially input remaining as well */
 };
 
 struct encoding {
   SCANNER scanners[XML_N_STATES];
   SCANNER literalScanners[XML_N_LITERAL_TYPES];
-  int (PTRCALL *nameMatchesAscii)(const ENCODING *,
-                                  const char *,
-                                  const char *,
-                                  const char *);
-  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+  int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *,
+                                 const char *);
+  int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
   const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
-  int (PTRCALL *getAtts)(const ENCODING *enc,
-                         const char *ptr,
-                         int attsMax,
-                         ATTRIBUTE *atts);
-  int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
-  int (PTRCALL *predefinedEntityName)(const ENCODING *,
-                                      const char *,
-                                      const char *);
-  void (PTRCALL *updatePosition)(const ENCODING *,
-                                 const char *ptr,
-                                 const char *end,
-                                 POSITION *);
-  int (PTRCALL *isPublicId)(const ENCODING *enc,
-                            const char *ptr,
-                            const char *end,
-                            const char **badPtr);
-  enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
-                              const char **fromP,
-                              const char *fromLim,
-                              char **toP,
-                              const char *toLim);
-  enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
-                               const char **fromP,
-                               const char *fromLim,
-                               unsigned short **toP,
-                               const unsigned short *toLim);
+  int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
+                        ATTRIBUTE *atts);
+  int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+  int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
+                                     const char *);
+  void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr,
+                                const char *end, POSITION *);
+  int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr,
+                           const char *end, const char **badPtr);
+  enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc,
+                                                const char **fromP,
+                                                const char *fromLim, char **toP,
+                                                const char *toLim);
+  enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc,
+                                                 const char **fromP,
+                                                 const char *fromLim,
+                                                 unsigned short **toP,
+                                                 const unsigned short *toLim);
   int minBytesPerChar;
   char isUtf8;
   char isUtf16;
@@ -225,66 +216,62 @@ struct encoding {
    the prolog outside literals, comments and processing instructions.
 */
 
-
-#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+#define XmlTok(enc, state, ptr, end, nextTokPtr)                               \
   (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
 
-#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+#define XmlPrologTok(enc, ptr, end, nextTokPtr)                                \
+  XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
 
-#define XmlContentTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+#define XmlContentTok(enc, ptr, end, nextTokPtr)                               \
+  XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
 
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr)                          \
+  XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
 
 #ifdef XML_DTD
 
-#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+#  define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr)                       \
+    XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
 
 #endif /* XML_DTD */
 
 /* This is used for performing a 2nd-level tokenization on the content
    of a literal that has already been returned by XmlTok.
 */
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr)                  \
   (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
 
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
-   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr)                        \
+  XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
 
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
-   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr)                           \
+  XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
 
-#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2)                             \
   (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
 
-#define XmlNameLength(enc, ptr) \
-  (((enc)->nameLength)(enc, ptr))
+#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
 
-#define XmlSkipS(enc, ptr) \
-  (((enc)->skipS)(enc, ptr))
+#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
 
-#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+#define XmlGetAttributes(enc, ptr, attsMax, atts)                              \
   (((enc)->getAtts)(enc, ptr, attsMax, atts))
 
-#define XmlCharRefNumber(enc, ptr) \
-  (((enc)->charRefNumber)(enc, ptr))
+#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
 
-#define XmlPredefinedEntityName(enc, ptr, end) \
+#define XmlPredefinedEntityName(enc, ptr, end)                                 \
   (((enc)->predefinedEntityName)(enc, ptr, end))
 
-#define XmlUpdatePosition(enc, ptr, end, pos) \
+#define XmlUpdatePosition(enc, ptr, end, pos)                                  \
   (((enc)->updatePosition)(enc, ptr, end, pos))
 
-#define XmlIsPublicId(enc, ptr, end, badPtr) \
+#define XmlIsPublicId(enc, ptr, end, badPtr)                                   \
   (((enc)->isPublicId)(enc, ptr, end, badPtr))
 
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim)                        \
   (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
 
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim)                       \
   (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
 
 typedef struct {
@@ -292,16 +279,11 @@ typedef struct {
   const ENCODING **encPtr;
 } INIT_ENCODING;
 
-int XmlParseXmlDecl(int isGeneralTextEntity,
-                    const ENCODING *enc,
-                    const char *ptr,
-                    const char *end,
-                    const char **badPtr,
-                    const char **versionPtr,
-                    const char **versionEndPtr,
+int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc,
+                    const char *ptr, const char *end, const char **badPtr,
+                    const char **versionPtr, const char **versionEndPtr,
                     const char **encodingNamePtr,
-                    const ENCODING **namedEncodingPtr,
-                    int *standalonePtr);
+                    const ENCODING **namedEncodingPtr, int *standalonePtr);
 
 int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
 const ENCODING *XmlGetUtf8InternalEncoding(void);
@@ -310,34 +292,22 @@ int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
 int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
 int XmlSizeOfUnknownEncoding(void);
 
+typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
 
-typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
-                       int *table,
-                       CONVERTER convert,
-                       void *userData);
+ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
+                                 void *userData);
 
-int XmlParseXmlDeclNS(int isGeneralTextEntity,
-                      const ENCODING *enc,
-                      const char *ptr,
-                      const char *end,
-                      const char **badPtr,
-                      const char **versionPtr,
-                      const char **versionEndPtr,
+int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
+                      const char *ptr, const char *end, const char **badPtr,
+                      const char **versionPtr, const char **versionEndPtr,
                       const char **encodingNamePtr,
-                      const ENCODING **namedEncodingPtr,
-                      int *standalonePtr);
+                      const ENCODING **namedEncodingPtr, int *standalonePtr);
 
 int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
 const ENCODING *XmlGetUtf8InternalEncodingNS(void);
 const ENCODING *XmlGetUtf16InternalEncodingNS(void);
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
-                         int *table,
-                         CONVERTER convert,
-                         void *userData);
+ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
+                                   void *userData);
 #ifdef __cplusplus
 }
 #endif
index 4d9ae7dc3896b8393f8b41eeb98becdcb3bcaa46..c209221cd79d135bfc034f0f67277261f6057fca 100644 (file)
 
 #ifdef XML_TOK_IMPL_C
 
-#ifndef IS_INVALID_CHAR
-#define IS_INVALID_CHAR(enc, ptr, n) (0)
-#endif
-
-#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n) \
-        return XML_TOK_PARTIAL_CHAR; \
-      if (IS_INVALID_CHAR(enc, ptr, n)) { \
-        *(nextTokPtr) = (ptr); \
-        return XML_TOK_INVALID; \
-      } \
-      ptr += n; \
-      break;
+#  ifndef IS_INVALID_CHAR
+#    define IS_INVALID_CHAR(enc, ptr, n) (0)
+#  endif
+
+#  define INVALID_LEAD_CASE(n, ptr, nextTokPtr)                                \
+  case BT_LEAD##n:                                                             \
+    if (end - ptr < n)                                                         \
+      return XML_TOK_PARTIAL_CHAR;                                             \
+    if (IS_INVALID_CHAR(enc, ptr, n)) {                                        \
+      *(nextTokPtr) = (ptr);                                                   \
+      return XML_TOK_INVALID;                                                  \
+    }                                                                          \
+    ptr += n;                                                                  \
+    break;
 
-#define INVALID_CASES(ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
-  case BT_NONXML: \
-  case BT_MALFORM: \
-  case BT_TRAIL: \
-    *(nextTokPtr) = (ptr); \
+#  define INVALID_CASES(ptr, nextTokPtr)                                       \
+    INVALID_LEAD_CASE(2, ptr, nextTokPtr)                                      \
+    INVALID_LEAD_CASE(3, ptr, nextTokPtr)                                      \
+    INVALID_LEAD_CASE(4, ptr, nextTokPtr)                                      \
+  case BT_NONXML:                                                              \
+  case BT_MALFORM:                                                             \
+  case BT_TRAIL:                                                               \
+    *(nextTokPtr) = (ptr);                                                     \
     return XML_TOK_INVALID;
 
-#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
-   case BT_LEAD ## n: \
-     if (end - ptr < n) \
-       return XML_TOK_PARTIAL_CHAR; \
-     if (!IS_NAME_CHAR(enc, ptr, n)) { \
-       *nextTokPtr = ptr; \
-       return XML_TOK_INVALID; \
-     } \
-     ptr += n; \
-     break;
-
-#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
-  case BT_NONASCII: \
-    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
-      *nextTokPtr = ptr; \
-      return XML_TOK_INVALID; \
-    } \
-    /* fall through */ \
-  case BT_NMSTRT: \
-  case BT_HEX: \
-  case BT_DIGIT: \
-  case BT_NAME: \
-  case BT_MINUS: \
-    ptr += MINBPC(enc); \
-    break; \
-  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
-  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
-  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
-
-#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
-   case BT_LEAD ## n: \
-     if (end - ptr < n) \
-       return XML_TOK_PARTIAL_CHAR; \
-     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
-       *nextTokPtr = ptr; \
-       return XML_TOK_INVALID; \
-     } \
-     ptr += n; \
-     break;
-
-#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
-  case BT_NONASCII: \
-    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
-      *nextTokPtr = ptr; \
-      return XML_TOK_INVALID; \
-    } \
-    /* fall through */ \
-  case BT_NMSTRT: \
-  case BT_HEX: \
-    ptr += MINBPC(enc); \
-    break; \
-  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
-  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
-  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
-
-#ifndef PREFIX
-#define PREFIX(ident) ident
-#endif
-
-
-#define HAS_CHARS(enc, ptr, end, count) \
-    (end - ptr >= count * MINBPC(enc))
+#  define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr)                        \
+  case BT_LEAD##n:                                                             \
+    if (end - ptr < n)                                                         \
+      return XML_TOK_PARTIAL_CHAR;                                             \
+    if (! IS_NAME_CHAR(enc, ptr, n)) {                                         \
+      *nextTokPtr = ptr;                                                       \
+      return XML_TOK_INVALID;                                                  \
+    }                                                                          \
+    ptr += n;                                                                  \
+    break;
 
-#define HAS_CHAR(enc, ptr, end) \
-    HAS_CHARS(enc, ptr, end, 1)
+#  define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)                          \
+  case BT_NONASCII:                                                            \
+    if (! IS_NAME_CHAR_MINBPC(enc, ptr)) {                                     \
+      *nextTokPtr = ptr;                                                       \
+      return XML_TOK_INVALID;                                                  \
+    }                                                                          \
+    /* fall through */                                                         \
+  case BT_NMSTRT:                                                              \
+  case BT_HEX:                                                                 \
+  case BT_DIGIT:                                                               \
+  case BT_NAME:                                                                \
+  case BT_MINUS:                                                               \
+    ptr += MINBPC(enc);                                                        \
+    break;                                                                     \
+    CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr)                              \
+    CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr)                              \
+    CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#  define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr)                      \
+  case BT_LEAD##n:                                                             \
+    if (end - ptr < n)                                                         \
+      return XML_TOK_PARTIAL_CHAR;                                             \
+    if (! IS_NMSTRT_CHAR(enc, ptr, n)) {                                       \
+      *nextTokPtr = ptr;                                                       \
+      return XML_TOK_INVALID;                                                  \
+    }                                                                          \
+    ptr += n;                                                                  \
+    break;
 
-#define REQUIRE_CHARS(enc, ptr, end, count) \
-    { \
-      if (! HAS_CHARS(enc, ptr, end, count)) { \
-        return XML_TOK_PARTIAL; \
-      } \
+#  define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)                        \
+  case BT_NONASCII:                                                            \
+    if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {                                   \
+      *nextTokPtr = ptr;                                                       \
+      return XML_TOK_INVALID;                                                  \
+    }                                                                          \
+    /* fall through */                                                         \
+  case BT_NMSTRT:                                                              \
+  case BT_HEX:                                                                 \
+    ptr += MINBPC(enc);                                                        \
+    break;                                                                     \
+    CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr)                            \
+    CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr)                            \
+    CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#  ifndef PREFIX
+#    define PREFIX(ident) ident
+#  endif
+
+#  define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc))
+
+#  define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1)
+
+#  define REQUIRE_CHARS(enc, ptr, end, count)                                  \
+    {                                                                          \
+      if (! HAS_CHARS(enc, ptr, end, count)) {                                 \
+        return XML_TOK_PARTIAL;                                                \
+      }                                                                        \
     }
 
-#define REQUIRE_CHAR(enc, ptr, end) \
-    REQUIRE_CHARS(enc, ptr, end, 1)
-
+#  define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1)
 
 /* ptr points to character following "<!-" */
 
 static int PTRCALL
-PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
-                    const char *end, const char **nextTokPtr)
-{
+PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr) {
   if (HAS_CHAR(enc, ptr, end)) {
-    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+    if (! CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
     }
     ptr += MINBPC(enc);
     while (HAS_CHAR(enc, ptr, end)) {
       switch (BYTE_TYPE(enc, ptr)) {
-      INVALID_CASES(ptr, nextTokPtr)
+        INVALID_CASES(ptr, nextTokPtr)
       case BT_MINUS:
         ptr += MINBPC(enc);
         REQUIRE_CHAR(enc, ptr, end);
         if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
           ptr += MINBPC(enc);
           REQUIRE_CHAR(enc, ptr, end);
-          if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+          if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
             *nextTokPtr = ptr;
             return XML_TOK_INVALID;
           }
@@ -175,9 +169,8 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
 /* ptr points to character following "<!" */
 
 static int PTRCALL
-PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
-                 const char *end, const char **nextTokPtr)
-{
+PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
+                 const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
   case BT_MINUS:
@@ -199,12 +192,17 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
       REQUIRE_CHARS(enc, ptr, end, 2);
       /* don't allow <!ENTITY% foo "whatever"> */
       switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
-      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+      case BT_S:
+      case BT_CR:
+      case BT_LF:
+      case BT_PERCNT:
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
       /* fall through */
-    case BT_S: case BT_CR: case BT_LF:
+    case BT_S:
+    case BT_CR:
+    case BT_LF:
       *nextTokPtr = ptr;
       return XML_TOK_DECL_OPEN;
     case BT_NMSTRT:
@@ -220,12 +218,12 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
 }
 
 static int PTRCALL
-PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
-                      const char *end, int *tokPtr)
-{
+PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end,
+                      int *tokPtr) {
   int upper = 0;
+  UNUSED_P(enc);
   *tokPtr = XML_TOK_PI;
-  if (end - ptr != MINBPC(enc)*3)
+  if (end - ptr != MINBPC(enc) * 3)
     return 1;
   switch (BYTE_TO_ASCII(enc, ptr)) {
   case ASCII_x:
@@ -265,30 +263,31 @@ PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
 /* ptr points to character following "<?" */
 
 static int PTRCALL
-PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
-               const char *end, const char **nextTokPtr)
-{
+PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
+               const char **nextTokPtr) {
   int tok;
   const char *target = ptr;
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
-  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+    CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   default:
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-    case BT_S: case BT_CR: case BT_LF:
-      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S:
+    case BT_CR:
+    case BT_LF:
+      if (! PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
       ptr += MINBPC(enc);
       while (HAS_CHAR(enc, ptr, end)) {
         switch (BYTE_TYPE(enc, ptr)) {
-        INVALID_CASES(ptr, nextTokPtr)
+          INVALID_CASES(ptr, nextTokPtr)
         case BT_QUEST:
           ptr += MINBPC(enc);
           REQUIRE_CHAR(enc, ptr, end);
@@ -304,7 +303,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
       }
       return XML_TOK_PARTIAL;
     case BT_QUEST:
-      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+      if (! PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
@@ -324,16 +323,16 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
 }
 
 static int PTRCALL
-PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
-                         const char *end, const char **nextTokPtr)
-{
-  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
-                                     ASCII_T, ASCII_A, ASCII_LSQB };
+PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
+                         const char **nextTokPtr) {
+  static const char CDATA_LSQB[]
+      = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB};
   int i;
+  UNUSED_P(enc);
   /* CDATA[ */
   REQUIRE_CHARS(enc, ptr, end, 6);
   for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
-    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+    if (! CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
     }
@@ -343,9 +342,8 @@ PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
 }
 
 static int PTRCALL
-PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
-                        const char *end, const char **nextTokPtr)
-{
+PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+                        const char **nextTokPtr) {
   if (ptr >= end)
     return XML_TOK_NONE;
   if (MINBPC(enc) > 1) {
@@ -361,11 +359,11 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
   case BT_RSQB:
     ptr += MINBPC(enc);
     REQUIRE_CHAR(enc, ptr, end);
-    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+    if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB))
       break;
     ptr += MINBPC(enc);
     REQUIRE_CHAR(enc, ptr, end);
-    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+    if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
       ptr -= MINBPC(enc);
       break;
     }
@@ -381,23 +379,25 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
   case BT_LF:
     *nextTokPtr = ptr + MINBPC(enc);
     return XML_TOK_DATA_NEWLINE;
-  INVALID_CASES(ptr, nextTokPtr)
+    INVALID_CASES(ptr, nextTokPtr)
   default:
     ptr += MINBPC(enc);
     break;
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-        *nextTokPtr = ptr; \
-        return XML_TOK_DATA_CHARS; \
-      } \
-      ptr += n; \
-      break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) {                       \
+      *nextTokPtr = ptr;                                                       \
+      return XML_TOK_DATA_CHARS;                                               \
+    }                                                                          \
+    ptr += n;                                                                  \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_NONXML:
     case BT_MALFORM:
     case BT_TRAIL:
@@ -418,23 +418,26 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
 /* ptr points to character following "</" */
 
 static int PTRCALL
-PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
-                   const char *end, const char **nextTokPtr)
-{
+PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
-  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+    CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   default:
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-    case BT_S: case BT_CR: case BT_LF:
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S:
+    case BT_CR:
+    case BT_LF:
       for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
         switch (BYTE_TYPE(enc, ptr)) {
-        case BT_S: case BT_CR: case BT_LF:
+        case BT_S:
+        case BT_CR:
+        case BT_LF:
           break;
         case BT_GT:
           *nextTokPtr = ptr + MINBPC(enc);
@@ -445,13 +448,13 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
         }
       }
       return XML_TOK_PARTIAL;
-#ifdef XML_NS
+#  ifdef XML_NS
     case BT_COLON:
       /* no need to check qname syntax here,
          since end-tag must match exactly */
       ptr += MINBPC(enc);
       break;
-#endif
+#  endif
     case BT_GT:
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_END_TAG;
@@ -466,9 +469,8 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
 /* ptr points to character following "&#X" */
 
 static int PTRCALL
-PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
-                       const char *end, const char **nextTokPtr)
-{
+PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr) {
   if (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_DIGIT:
@@ -498,9 +500,8 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
 /* ptr points to character following "&#" */
 
 static int PTRCALL
-PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
-                    const char *end, const char **nextTokPtr)
-{
+PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr) {
   if (HAS_CHAR(enc, ptr, end)) {
     if (CHAR_MATCHES(enc, ptr, ASCII_x))
       return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -531,11 +532,10 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
 
 static int PTRCALL
 PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
-                const char **nextTokPtr)
-{
+                const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
-  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+    CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   case BT_NUM:
     return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   default:
@@ -544,7 +544,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_SEMI:
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_ENTITY_REF;
@@ -560,15 +560,14 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
 
 static int PTRCALL
 PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
-                 const char **nextTokPtr)
-{
-#ifdef XML_NS
+                 const char **nextTokPtr) {
+#  ifdef XML_NS
   int hadColon = 0;
-#endif
+#  endif
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#  ifdef XML_NS
     case BT_COLON:
       if (hadColon) {
         *nextTokPtr = ptr;
@@ -578,14 +577,16 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
       ptr += MINBPC(enc);
       REQUIRE_CHAR(enc, ptr, end);
       switch (BYTE_TYPE(enc, ptr)) {
-      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
       default:
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
       break;
-#endif
-    case BT_S: case BT_CR: case BT_LF:
+#  endif
+    case BT_S:
+    case BT_CR:
+    case BT_LF:
       for (;;) {
         int t;
 
@@ -605,101 +606,101 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
         }
       }
       /* fall through */
-    case BT_EQUALS:
-      {
-        int open;
-#ifdef XML_NS
-        hadColon = 0;
-#endif
-        for (;;) {
-          ptr += MINBPC(enc);
-          REQUIRE_CHAR(enc, ptr, end);
-          open = BYTE_TYPE(enc, ptr);
-          if (open == BT_QUOT || open == BT_APOS)
-            break;
-          switch (open) {
-          case BT_S:
-          case BT_LF:
-          case BT_CR:
-            break;
-          default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-          }
-        }
+    case BT_EQUALS: {
+      int open;
+#  ifdef XML_NS
+      hadColon = 0;
+#  endif
+      for (;;) {
         ptr += MINBPC(enc);
-        /* in attribute value */
-        for (;;) {
-          int t;
-          REQUIRE_CHAR(enc, ptr, end);
-          t = BYTE_TYPE(enc, ptr);
-          if (t == open)
-            break;
-          switch (t) {
+        REQUIRE_CHAR(enc, ptr, end);
+        open = BYTE_TYPE(enc, ptr);
+        if (open == BT_QUOT || open == BT_APOS)
+          break;
+        switch (open) {
+        case BT_S:
+        case BT_LF:
+        case BT_CR:
+          break;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
+      }
+      ptr += MINBPC(enc);
+      /* in attribute value */
+      for (;;) {
+        int t;
+        REQUIRE_CHAR(enc, ptr, end);
+        t = BYTE_TYPE(enc, ptr);
+        if (t == open)
+          break;
+        switch (t) {
           INVALID_CASES(ptr, nextTokPtr)
-          case BT_AMP:
-            {
-              int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
-              if (tok <= 0) {
-                if (tok == XML_TOK_INVALID)
-                  *nextTokPtr = ptr;
-                return tok;
-              }
-              break;
-            }
-          case BT_LT:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-          default:
-            ptr += MINBPC(enc);
-            break;
+        case BT_AMP: {
+          int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+          if (tok <= 0) {
+            if (tok == XML_TOK_INVALID)
+              *nextTokPtr = ptr;
+            return tok;
           }
+          break;
+        }
+        case BT_LT:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        default:
+          ptr += MINBPC(enc);
+          break;
         }
+      }
+      ptr += MINBPC(enc);
+      REQUIRE_CHAR(enc, ptr, end);
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S:
+      case BT_CR:
+      case BT_LF:
+        break;
+      case BT_SOL:
+        goto sol;
+      case BT_GT:
+        goto gt;
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      /* ptr points to closing quote */
+      for (;;) {
         ptr += MINBPC(enc);
         REQUIRE_CHAR(enc, ptr, end);
         switch (BYTE_TYPE(enc, ptr)) {
+          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
         case BT_S:
         case BT_CR:
         case BT_LF:
-          break;
-        case BT_SOL:
-          goto sol;
+          continue;
         case BT_GT:
-          goto gt;
-        default:
-          *nextTokPtr = ptr;
-          return XML_TOK_INVALID;
-        }
-        /* ptr points to closing quote */
-        for (;;) {
+        gt:
+          *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_START_TAG_WITH_ATTS;
+        case BT_SOL:
+        sol:
           ptr += MINBPC(enc);
           REQUIRE_CHAR(enc, ptr, end);
-          switch (BYTE_TYPE(enc, ptr)) {
-          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-          case BT_S: case BT_CR: case BT_LF:
-            continue;
-          case BT_GT:
-          gt:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_START_TAG_WITH_ATTS;
-          case BT_SOL:
-          sol:
-            ptr += MINBPC(enc);
-            REQUIRE_CHAR(enc, ptr, end);
-            if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-              *nextTokPtr = ptr;
-              return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
-          default:
+          if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
             *nextTokPtr = ptr;
             return XML_TOK_INVALID;
           }
-          break;
+          *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
         }
         break;
       }
+      break;
+    }
     default:
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
@@ -712,14 +713,13 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
 
 static int PTRCALL
 PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
-               const char **nextTokPtr)
-{
-#ifdef XML_NS
+               const char **nextTokPtr) {
+#  ifdef XML_NS
   int hadColon;
-#endif
+#  endif
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
-  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+    CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   case BT_EXCL:
     ptr += MINBPC(enc);
     REQUIRE_CHAR(enc, ptr, end);
@@ -727,8 +727,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
     case BT_MINUS:
       return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
     case BT_LSQB:
-      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
-                                      end, nextTokPtr);
+      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
     }
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
@@ -740,14 +739,14 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
-#ifdef XML_NS
+#  ifdef XML_NS
   hadColon = 0;
-#endif
+#  endif
   /* we have a start-tag */
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#  ifdef XML_NS
     case BT_COLON:
       if (hadColon) {
         *nextTokPtr = ptr;
@@ -757,34 +756,37 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
       ptr += MINBPC(enc);
       REQUIRE_CHAR(enc, ptr, end);
       switch (BYTE_TYPE(enc, ptr)) {
-      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
       default:
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
       break;
-#endif
-    case BT_S: case BT_CR: case BT_LF:
-      {
-        ptr += MINBPC(enc);
-        while (HAS_CHAR(enc, ptr, end)) {
-          switch (BYTE_TYPE(enc, ptr)) {
+#  endif
+    case BT_S:
+    case BT_CR:
+    case BT_LF: {
+      ptr += MINBPC(enc);
+      while (HAS_CHAR(enc, ptr, end)) {
+        switch (BYTE_TYPE(enc, ptr)) {
           CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-          case BT_GT:
-            goto gt;
-          case BT_SOL:
-            goto sol;
-          case BT_S: case BT_CR: case BT_LF:
-            ptr += MINBPC(enc);
-            continue;
-          default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-          }
-          return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+        case BT_GT:
+          goto gt;
+        case BT_SOL:
+          goto sol;
+        case BT_S:
+        case BT_CR:
+        case BT_LF:
+          ptr += MINBPC(enc);
+          continue;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
         }
-        return XML_TOK_PARTIAL;
+        return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
       }
+      return XML_TOK_PARTIAL;
+    }
     case BT_GT:
     gt:
       *nextTokPtr = ptr + MINBPC(enc);
@@ -793,7 +795,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
     sol:
       ptr += MINBPC(enc);
       REQUIRE_CHAR(enc, ptr, end);
-      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
@@ -809,8 +811,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
 
 static int PTRCALL
 PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **nextTokPtr)
-{
+                   const char **nextTokPtr) {
   if (ptr >= end)
     return XML_TOK_NONE;
   if (MINBPC(enc) > 1) {
@@ -842,48 +843,50 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
     ptr += MINBPC(enc);
     if (! HAS_CHAR(enc, ptr, end))
       return XML_TOK_TRAILING_RSQB;
-    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+    if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB))
       break;
     ptr += MINBPC(enc);
     if (! HAS_CHAR(enc, ptr, end))
       return XML_TOK_TRAILING_RSQB;
-    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+    if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
       ptr -= MINBPC(enc);
       break;
     }
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
-  INVALID_CASES(ptr, nextTokPtr)
+    INVALID_CASES(ptr, nextTokPtr)
   default:
     ptr += MINBPC(enc);
     break;
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-        *nextTokPtr = ptr; \
-        return XML_TOK_DATA_CHARS; \
-      } \
-      ptr += n; \
-      break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) {                       \
+      *nextTokPtr = ptr;                                                       \
+      return XML_TOK_DATA_CHARS;                                               \
+    }                                                                          \
+    ptr += n;                                                                  \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_RSQB:
       if (HAS_CHARS(enc, ptr, end, 2)) {
-         if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
-           ptr += MINBPC(enc);
-           break;
-         }
-         if (HAS_CHARS(enc, ptr, end, 3)) {
-           if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
-             ptr += MINBPC(enc);
-             break;
-           }
-           *nextTokPtr = ptr + 2*MINBPC(enc);
-           return XML_TOK_INVALID;
-         }
+        if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+          ptr += MINBPC(enc);
+          break;
+        }
+        if (HAS_CHARS(enc, ptr, end, 3)) {
+          if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) {
+            ptr += MINBPC(enc);
+            break;
+          }
+          *nextTokPtr = ptr + 2 * MINBPC(enc);
+          return XML_TOK_INVALID;
+        }
       }
       /* fall through */
     case BT_AMP:
@@ -908,12 +911,14 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
 
 static int PTRCALL
 PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
-                    const char **nextTokPtr)
-{
+                    const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
-  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+    CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_S:
+  case BT_LF:
+  case BT_CR:
+  case BT_PERCNT:
     *nextTokPtr = ptr;
     return XML_TOK_PERCENT;
   default:
@@ -922,7 +927,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_SEMI:
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_PARAM_ENTITY_REF;
@@ -936,20 +941,24 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
 
 static int PTRCALL
 PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
-                      const char **nextTokPtr)
-{
+                      const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
   switch (BYTE_TYPE(enc, ptr)) {
-  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+    CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   default:
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-    case BT_CR: case BT_LF: case BT_S:
-    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_CR:
+    case BT_LF:
+    case BT_S:
+    case BT_RPAR:
+    case BT_GT:
+    case BT_PERCNT:
+    case BT_VERBAR:
       *nextTokPtr = ptr;
       return XML_TOK_POUND_NAME;
     default:
@@ -961,14 +970,12 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
 }
 
 static int PTRCALL
-PREFIX(scanLit)(int open, const ENCODING *enc,
-                const char *ptr, const char *end,
-                const char **nextTokPtr)
-{
+PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end,
+                const char **nextTokPtr) {
   while (HAS_CHAR(enc, ptr, end)) {
     int t = BYTE_TYPE(enc, ptr);
     switch (t) {
-    INVALID_CASES(ptr, nextTokPtr)
+      INVALID_CASES(ptr, nextTokPtr)
     case BT_QUOT:
     case BT_APOS:
       ptr += MINBPC(enc);
@@ -978,8 +985,12 @@ PREFIX(scanLit)(int open, const ENCODING *enc,
         return -XML_TOK_LITERAL;
       *nextTokPtr = ptr;
       switch (BYTE_TYPE(enc, ptr)) {
-      case BT_S: case BT_CR: case BT_LF:
-      case BT_GT: case BT_PERCNT: case BT_LSQB:
+      case BT_S:
+      case BT_CR:
+      case BT_LF:
+      case BT_GT:
+      case BT_PERCNT:
+      case BT_LSQB:
         return XML_TOK_LITERAL;
       default:
         return XML_TOK_INVALID;
@@ -994,8 +1005,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc,
 
 static int PTRCALL
 PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
-                  const char **nextTokPtr)
-{
+                  const char **nextTokPtr) {
   int tok;
   if (ptr >= end)
     return XML_TOK_NONE;
@@ -1013,27 +1023,26 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
     return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
   case BT_APOS:
     return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
-  case BT_LT:
-    {
-      ptr += MINBPC(enc);
-      REQUIRE_CHAR(enc, ptr, end);
-      switch (BYTE_TYPE(enc, ptr)) {
-      case BT_EXCL:
-        return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-      case BT_QUEST:
-        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-      case BT_NMSTRT:
-      case BT_HEX:
-      case BT_NONASCII:
-      case BT_LEAD2:
-      case BT_LEAD3:
-      case BT_LEAD4:
-        *nextTokPtr = ptr - MINBPC(enc);
-        return XML_TOK_INSTANCE_START;
-      }
-      *nextTokPtr = ptr;
-      return XML_TOK_INVALID;
+  case BT_LT: {
+    ptr += MINBPC(enc);
+    REQUIRE_CHAR(enc, ptr, end);
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_EXCL:
+      return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    case BT_QUEST:
+      return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    case BT_NMSTRT:
+    case BT_HEX:
+    case BT_NONASCII:
+    case BT_LEAD2:
+    case BT_LEAD3:
+    case BT_LEAD4:
+      *nextTokPtr = ptr - MINBPC(enc);
+      return XML_TOK_INSTANCE_START;
     }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
   case BT_CR:
     if (ptr + MINBPC(enc) == end) {
       *nextTokPtr = end;
@@ -1041,13 +1050,15 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
       return -XML_TOK_PROLOG_S;
     }
     /* fall through */
-  case BT_S: case BT_LF:
+  case BT_S:
+  case BT_LF:
     for (;;) {
       ptr += MINBPC(enc);
       if (! HAS_CHAR(enc, ptr, end))
         break;
       switch (BYTE_TYPE(enc, ptr)) {
-      case BT_S: case BT_LF:
+      case BT_S:
+      case BT_LF:
         break;
       case BT_CR:
         /* don't split CR/LF pair */
@@ -1076,7 +1087,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
     if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
       REQUIRE_CHARS(enc, ptr, end, 2);
       if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
-        *nextTokPtr = ptr + 2*MINBPC(enc);
+        *nextTokPtr = ptr + 2 * MINBPC(enc);
         return XML_TOK_COND_SECT_CLOSE;
       }
     }
@@ -1099,8 +1110,12 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
     case BT_PLUS:
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_CLOSE_PAREN_PLUS;
-    case BT_CR: case BT_LF: case BT_S:
-    case BT_GT: case BT_COMMA: case BT_VERBAR:
+    case BT_CR:
+    case BT_LF:
+    case BT_S:
+    case BT_GT:
+    case BT_COMMA:
+    case BT_VERBAR:
     case BT_RPAR:
       *nextTokPtr = ptr;
       return XML_TOK_CLOSE_PAREN;
@@ -1115,24 +1130,26 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
     return XML_TOK_DECL_CLOSE;
   case BT_NUM:
     return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-#define LEAD_CASE(n) \
-  case BT_LEAD ## n: \
-    if (end - ptr < n) \
-      return XML_TOK_PARTIAL_CHAR; \
-    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
-      ptr += n; \
-      tok = XML_TOK_NAME; \
-      break; \
-    } \
-    if (IS_NAME_CHAR(enc, ptr, n)) { \
-      ptr += n; \
-      tok = XML_TOK_NMTOKEN; \
-      break; \
-    } \
-    *nextTokPtr = ptr; \
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    if (end - ptr < n)                                                         \
+      return XML_TOK_PARTIAL_CHAR;                                             \
+    if (IS_NMSTRT_CHAR(enc, ptr, n)) {                                         \
+      ptr += n;                                                                \
+      tok = XML_TOK_NAME;                                                      \
+      break;                                                                   \
+    }                                                                          \
+    if (IS_NAME_CHAR(enc, ptr, n)) {                                           \
+      ptr += n;                                                                \
+      tok = XML_TOK_NMTOKEN;                                                   \
+      break;                                                                   \
+    }                                                                          \
+    *nextTokPtr = ptr;                                                         \
     return XML_TOK_INVALID;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+    LEAD_CASE(2)
+    LEAD_CASE(3)
+    LEAD_CASE(4)
+#  undef LEAD_CASE
   case BT_NMSTRT:
   case BT_HEX:
     tok = XML_TOK_NAME;
@@ -1141,9 +1158,9 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
   case BT_DIGIT:
   case BT_NAME:
   case BT_MINUS:
-#ifdef XML_NS
+#  ifdef XML_NS
   case BT_COLON:
-#endif
+#  endif
     tok = XML_TOK_NMTOKEN;
     ptr += MINBPC(enc);
     break;
@@ -1165,13 +1182,19 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-    case BT_GT: case BT_RPAR: case BT_COMMA:
-    case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
-    case BT_S: case BT_CR: case BT_LF:
+      CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_GT:
+    case BT_RPAR:
+    case BT_COMMA:
+    case BT_VERBAR:
+    case BT_LSQB:
+    case BT_PERCNT:
+    case BT_S:
+    case BT_CR:
+    case BT_LF:
       *nextTokPtr = ptr;
       return tok;
-#ifdef XML_NS
+#  ifdef XML_NS
     case BT_COLON:
       ptr += MINBPC(enc);
       switch (tok) {
@@ -1179,7 +1202,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
         REQUIRE_CHAR(enc, ptr, end);
         tok = XML_TOK_PREFIXED_NAME;
         switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+          CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
         default:
           tok = XML_TOK_NMTOKEN;
           break;
@@ -1190,23 +1213,23 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
         break;
       }
       break;
-#endif
+#  endif
     case BT_PLUS:
-      if (tok == XML_TOK_NMTOKEN)  {
+      if (tok == XML_TOK_NMTOKEN) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_NAME_PLUS;
     case BT_AST:
-      if (tok == XML_TOK_NMTOKEN)  {
+      if (tok == XML_TOK_NMTOKEN) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_NAME_ASTERISK;
     case BT_QUEST:
-      if (tok == XML_TOK_NMTOKEN)  {
+      if (tok == XML_TOK_NMTOKEN) {
         *nextTokPtr = ptr;
         return XML_TOK_INVALID;
       }
@@ -1221,9 +1244,8 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
 }
 
 static int PTRCALL
-PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
-                          const char *end, const char **nextTokPtr)
-{
+PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+                          const char **nextTokPtr) {
   const char *start;
   if (ptr >= end)
     return XML_TOK_NONE;
@@ -1238,10 +1260,14 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
   start = ptr;
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    ptr += n;                                                                  \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_AMP:
       if (ptr == start)
         return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -1287,9 +1313,8 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
 }
 
 static int PTRCALL
-PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
-                       const char *end, const char **nextTokPtr)
-{
+PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr) {
   const char *start;
   if (ptr >= end)
     return XML_TOK_NONE;
@@ -1304,10 +1329,14 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
   start = ptr;
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    ptr += n;                                                                  \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_AMP:
       if (ptr == start)
         return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -1315,8 +1344,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
       return XML_TOK_DATA_CHARS;
     case BT_PERCNT:
       if (ptr == start) {
-        int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
-                                       end, nextTokPtr);
+        int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
         return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
       }
       *nextTokPtr = ptr;
@@ -1349,12 +1377,11 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
   return XML_TOK_DATA_CHARS;
 }
 
-#ifdef XML_DTD
+#  ifdef XML_DTD
 
 static int PTRCALL
-PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
-                         const char *end, const char **nextTokPtr)
-{
+PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+                         const char **nextTokPtr) {
   int level = 0;
   if (MINBPC(enc) > 1) {
     size_t n = end - ptr;
@@ -1365,7 +1392,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
   }
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-    INVALID_CASES(ptr, nextTokPtr)
+      INVALID_CASES(ptr, nextTokPtr)
     case BT_LT:
       ptr += MINBPC(enc);
       REQUIRE_CHAR(enc, ptr, end);
@@ -1402,12 +1429,11 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
   return XML_TOK_PARTIAL;
 }
 
-#endif /* XML_DTD */
+#  endif /* XML_DTD */
 
 static int PTRCALL
 PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **badPtr)
-{
+                   const char **badPtr) {
   ptr += MINBPC(enc);
   end -= MINBPC(enc);
   for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
@@ -1430,9 +1456,9 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
     case BT_AST:
     case BT_PERCNT:
     case BT_NUM:
-#ifdef XML_NS
+#  ifdef XML_NS
     case BT_COLON:
-#endif
+#  endif
       break;
     case BT_S:
       if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
@@ -1442,7 +1468,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
       break;
     case BT_NAME:
     case BT_NMSTRT:
-      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+      if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f))
         break;
       /* fall through */
     default:
@@ -1466,9 +1492,8 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
 */
 
 static int PTRCALL
-PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
-                int attsMax, ATTRIBUTE *atts)
-{
+PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
+                ATTRIBUTE *atts) {
   enum { other, inName, inValue } state = inName;
   int nAtts = 0;
   int open = 0; /* defined when state == inValue;
@@ -1476,32 +1501,35 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
 
   for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define START_NAME \
-      if (state == other) { \
-        if (nAtts < attsMax) { \
-          atts[nAtts].name = ptr; \
-          atts[nAtts].normalized = 1; \
-        } \
-        state = inName; \
-      }
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define START_NAME                                                           \
+    if (state == other) {                                                      \
+      if (nAtts < attsMax) {                                                   \
+        atts[nAtts].name = ptr;                                                \
+        atts[nAtts].normalized = 1;                                            \
+      }                                                                        \
+      state = inName;                                                          \
+    }
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    START_NAME ptr += (n - MINBPC(enc));                                       \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_NONASCII:
     case BT_NMSTRT:
     case BT_HEX:
       START_NAME
       break;
-#undef START_NAME
+#  undef START_NAME
     case BT_QUOT:
       if (state != inValue) {
         if (nAtts < attsMax)
           atts[nAtts].valuePtr = ptr + MINBPC(enc);
         state = inValue;
         open = BT_QUOT;
-      }
-      else if (open == BT_QUOT) {
+      } else if (open == BT_QUOT) {
         state = other;
         if (nAtts < attsMax)
           atts[nAtts].valueEnd = ptr;
@@ -1514,8 +1542,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
           atts[nAtts].valuePtr = ptr + MINBPC(enc);
         state = inValue;
         open = BT_APOS;
-      }
-      else if (open == BT_APOS) {
+      } else if (open == BT_APOS) {
         state = other;
         if (nAtts < attsMax)
           atts[nAtts].valueEnd = ptr;
@@ -1529,16 +1556,15 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
     case BT_S:
       if (state == inName)
         state = other;
-      else if (state == inValue
-               && nAtts < attsMax
-               && atts[nAtts].normalized
+      else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized
                && (ptr == atts[nAtts].valuePtr
                    || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
                    || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
                    || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
         atts[nAtts].normalized = 0;
       break;
-    case BT_CR: case BT_LF:
+    case BT_CR:
+    case BT_LF:
       /* This case ensures that the first attribute name is counted
          Apart from that we could just change state on the quote. */
       if (state == inName)
@@ -1559,29 +1585,44 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
 }
 
 static int PTRFASTCALL
-PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
-{
+PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) {
   int result = 0;
   /* skip &# */
-  ptr += 2*MINBPC(enc);
+  UNUSED_P(enc);
+  ptr += 2 * MINBPC(enc);
   if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
-    for (ptr += MINBPC(enc);
-         !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
+    for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI);
          ptr += MINBPC(enc)) {
       int c = BYTE_TO_ASCII(enc, ptr);
       switch (c) {
-      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
-      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+      case ASCII_0:
+      case ASCII_1:
+      case ASCII_2:
+      case ASCII_3:
+      case ASCII_4:
+      case ASCII_5:
+      case ASCII_6:
+      case ASCII_7:
+      case ASCII_8:
+      case ASCII_9:
         result <<= 4;
         result |= (c - ASCII_0);
         break;
-      case ASCII_A: case ASCII_B: case ASCII_C:
-      case ASCII_D: case ASCII_E: case ASCII_F:
+      case ASCII_A:
+      case ASCII_B:
+      case ASCII_C:
+      case ASCII_D:
+      case ASCII_E:
+      case ASCII_F:
         result <<= 4;
         result += 10 + (c - ASCII_A);
         break;
-      case ASCII_a: case ASCII_b: case ASCII_c:
-      case ASCII_d: case ASCII_e: case ASCII_f:
+      case ASCII_a:
+      case ASCII_b:
+      case ASCII_c:
+      case ASCII_d:
+      case ASCII_e:
+      case ASCII_f:
         result <<= 4;
         result += 10 + (c - ASCII_a);
         break;
@@ -1589,9 +1630,8 @@ PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
       if (result >= 0x110000)
         return -1;
     }
-  }
-  else {
-    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+  } else {
+    for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
       int c = BYTE_TO_ASCII(enc, ptr);
       result *= 10;
       result += (c - ASCII_0);
@@ -1603,10 +1643,10 @@ PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
 }
 
 static int PTRCALL
-PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
-                             const char *end)
-{
-  switch ((end - ptr)/MINBPC(enc)) {
+PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+                             const char *end) {
+  UNUSED_P(enc);
+  switch ((end - ptr) / MINBPC(enc)) {
   case 2:
     if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
       switch (BYTE_TO_ASCII(enc, ptr)) {
@@ -1657,9 +1697,9 @@ PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
 }
 
 static int PTRCALL
-PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
-                         const char *end1, const char *ptr2)
-{
+PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+                         const char *end1, const char *ptr2) {
+  UNUSED_P(enc);
   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
     if (end1 - ptr1 < MINBPC(enc)) {
       /* This line cannot be executed.  The incoming data has already
@@ -1669,27 +1709,30 @@ PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
        */
       return 0; /* LCOV_EXCL_LINE */
     }
-    if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+    if (! CHAR_MATCHES(enc, ptr1, *ptr2))
       return 0;
   }
   return ptr1 == end1;
 }
 
 static int PTRFASTCALL
-PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
-{
+PREFIX(nameLength)(const ENCODING *enc, const char *ptr) {
   const char *start = ptr;
   for (;;) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    ptr += n;                                                                  \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_NONASCII:
     case BT_NMSTRT:
-#ifdef XML_NS
+#  ifdef XML_NS
     case BT_COLON:
-#endif
+#  endif
     case BT_HEX:
     case BT_DIGIT:
     case BT_NAME:
@@ -1702,9 +1745,8 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
   }
 }
 
-static const char * PTRFASTCALL
-PREFIX(skipS)(const ENCODING *enc, const char *ptr)
-{
+static const char *PTRFASTCALL
+PREFIX(skipS)(const ENCODING *enc, const char *ptr) {
   for (;;) {
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_LF:
@@ -1719,19 +1761,18 @@ PREFIX(skipS)(const ENCODING *enc, const char *ptr)
 }
 
 static void PTRCALL
-PREFIX(updatePosition)(const ENCODING *enc,
-                       const char *ptr,
-                       const char *end,
-                       POSITION *pos)
-{
+PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end,
+                       POSITION *pos) {
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      ptr += n; \
-      break;
-    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+#  define LEAD_CASE(n)                                                         \
+  case BT_LEAD##n:                                                             \
+    ptr += n;                                                                  \
+    break;
+      LEAD_CASE(2)
+      LEAD_CASE(3)
+      LEAD_CASE(4)
+#  undef LEAD_CASE
     case BT_LF:
       pos->columnNumber = (XML_Size)-1;
       pos->lineNumber++;
@@ -1752,12 +1793,12 @@ PREFIX(updatePosition)(const ENCODING *enc,
   }
 }
 
-#undef DO_LEAD_CASE
-#undef MULTIBYTE_CASES
-#undef INVALID_CASES
-#undef CHECK_NAME_CASE
-#undef CHECK_NAME_CASES
-#undef CHECK_NMSTRT_CASE
-#undef CHECK_NMSTRT_CASES
+#  undef DO_LEAD_CASE
+#  undef MULTIBYTE_CASES
+#  undef INVALID_CASES
+#  undef CHECK_NAME_CASE
+#  undef CHECK_NAME_CASES
+#  undef CHECK_NMSTRT_CASE
+#  undef CHECK_NMSTRT_CASES
 
 #endif /* XML_TOK_IMPL_C */
index a6420f48eedc047c369d8ff608d31fe1166d629f..e925dbc7e2c8337749ad3eeab84095e60e660fba 100644 (file)
 */
 
 enum {
-  BT_NONXML,
-  BT_MALFORM,
-  BT_LT,
-  BT_AMP,
-  BT_RSQB,
-  BT_LEAD2,
-  BT_LEAD3,
-  BT_LEAD4,
-  BT_TRAIL,
-  BT_CR,
-  BT_LF,
-  BT_GT,
-  BT_QUOT,
-  BT_APOS,
-  BT_EQUALS,
-  BT_QUEST,
-  BT_EXCL,
-  BT_SOL,
-  BT_SEMI,
-  BT_NUM,
-  BT_LSQB,
-  BT_S,
-  BT_NMSTRT,
-  BT_COLON,
-  BT_HEX,
-  BT_DIGIT,
-  BT_NAME,
-  BT_MINUS,
-  BT_OTHER, /* known not to be a name or name start character */
+  BT_NONXML,   /* e.g. noncharacter-FFFF */
+  BT_MALFORM,  /* illegal, with regard to encoding */
+  BT_LT,       /* less than = "<" */
+  BT_AMP,      /* ampersand = "&" */
+  BT_RSQB,     /* right square bracket = "[" */
+  BT_LEAD2,    /* lead byte of a 2-byte UTF-8 character */
+  BT_LEAD3,    /* lead byte of a 3-byte UTF-8 character */
+  BT_LEAD4,    /* lead byte of a 4-byte UTF-8 character */
+  BT_TRAIL,    /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */
+  BT_CR,       /* carriage return = "\r" */
+  BT_LF,       /* line feed = "\n" */
+  BT_GT,       /* greater than = ">" */
+  BT_QUOT,     /* quotation character = "\"" */
+  BT_APOS,     /* aposthrophe = "'" */
+  BT_EQUALS,   /* equal sign = "=" */
+  BT_QUEST,    /* question mark = "?" */
+  BT_EXCL,     /* exclamation mark = "!" */
+  BT_SOL,      /* solidus, slash = "/" */
+  BT_SEMI,     /* semicolon = ";" */
+  BT_NUM,      /* number sign = "#" */
+  BT_LSQB,     /* left square bracket = "[" */
+  BT_S,        /* white space, e.g. "\t", " "[, "\r"] */
+  BT_NMSTRT,   /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */
+  BT_COLON,    /* colon = ":" */
+  BT_HEX,      /* hex letter = "A".."F" + "a".."f" */
+  BT_DIGIT,    /* digit = "0".."9" */
+  BT_NAME,     /* dot and middle dot = "." + chr(0xb7) */
+  BT_MINUS,    /* minus = "-" */
+  BT_OTHER,    /* known not to be a name or name start character */
   BT_NONASCII, /* might be a name or name start character */
-  BT_PERCNT,
-  BT_LPAR,
-  BT_RPAR,
-  BT_AST,
-  BT_PLUS,
-  BT_COMMA,
-  BT_VERBAR
+  BT_PERCNT,   /* percent sign = "%" */
+  BT_LPAR,     /* left parenthesis = "(" */
+  BT_RPAR,     /* right parenthesis = "(" */
+  BT_AST,      /* asterisk = "*" */
+  BT_PLUS,     /* plus sign = "+" */
+  BT_COMMA,    /* comma = "," */
+  BT_VERBAR    /* vertical bar = "|" */
 };
 
 #include <stddef.h>
index 23d31e8e424916f0bc7c5d26fd241aa35f21c3ed..919c74e9f97fe8129aacc514217c94f89dd86109 100644 (file)
 #ifdef XML_TOK_NS_C
 
 const ENCODING *
-NS(XmlGetUtf8InternalEncoding)(void)
-{
+NS(XmlGetUtf8InternalEncoding)(void) {
   return &ns(internal_utf8_encoding).enc;
 }
 
 const ENCODING *
-NS(XmlGetUtf16InternalEncoding)(void)
-{
-#if BYTEORDER == 1234
+NS(XmlGetUtf16InternalEncoding)(void) {
+#  if BYTEORDER == 1234
   return &ns(internal_little2_encoding).enc;
-#elif BYTEORDER == 4321
+#  elif BYTEORDER == 4321
   return &ns(internal_big2_encoding).enc;
-#else
+#  else
   const short n = 1;
-  return (*(const char *)&n
-          ? &ns(internal_little2_encoding).enc
-          : &ns(internal_big2_encoding).enc);
-#endif
+  return (*(const char *)&n ? &ns(internal_little2_encoding).enc
+                            : &ns(internal_big2_encoding).enc);
+#  endif
 }
 
-static const ENCODING * const NS(encodings)[] = {
-  &ns(latin1_encoding).enc,
-  &ns(ascii_encoding).enc,
-  &ns(utf8_encoding).enc,
-  &ns(big2_encoding).enc,
-  &ns(big2_encoding).enc,
-  &ns(little2_encoding).enc,
-  &ns(utf8_encoding).enc /* NO_ENC */
+static const ENCODING *const NS(encodings)[] = {
+    &ns(latin1_encoding).enc, &ns(ascii_encoding).enc,
+    &ns(utf8_encoding).enc,   &ns(big2_encoding).enc,
+    &ns(big2_encoding).enc,   &ns(little2_encoding).enc,
+    &ns(utf8_encoding).enc /* NO_ENC */
 };
 
 static int PTRCALL
 NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **nextTokPtr)
-{
-  return initScan(NS(encodings), (const INIT_ENCODING *)enc,
-                  XML_PROLOG_STATE, ptr, end, nextTokPtr);
+                   const char **nextTokPtr) {
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE,
+                  ptr, end, nextTokPtr);
 }
 
 static int PTRCALL
 NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
-                    const char **nextTokPtr)
-{
-  return initScan(NS(encodings), (const INIT_ENCODING *)enc,
-                  XML_CONTENT_STATE, ptr, end, nextTokPtr);
+                    const char **nextTokPtr) {
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE,
+                  ptr, end, nextTokPtr);
 }
 
 int
 NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
-                    const char *name)
-{
+                    const char *name) {
   int i = getEncodingIndex(name);
   if (i == UNKNOWN_ENC)
     return 0;
@@ -96,9 +87,8 @@ NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
 }
 
 static const ENCODING *
-NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
-{
-#define ENCODING_MAX 128
+NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
+#  define ENCODING_MAX 128
   char buf[ENCODING_MAX];
   char *p = buf;
   int i;
@@ -115,28 +105,14 @@ NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
 }
 
 int
-NS(XmlParseXmlDecl)(int isGeneralTextEntity,
-                    const ENCODING *enc,
-                    const char *ptr,
-                    const char *end,
-                    const char **badPtr,
-                    const char **versionPtr,
-                    const char **versionEndPtr,
-                    const char **encodingName,
-                    const ENCODING **encoding,
-                    int *standalone)
-{
-  return doParseXmlDecl(NS(findEncoding),
-                        isGeneralTextEntity,
-                        enc,
-                        ptr,
-                        end,
-                        badPtr,
-                        versionPtr,
-                        versionEndPtr,
-                        encodingName,
-                        encoding,
-                        standalone);
+NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc,
+                    const char *ptr, const char *end, const char **badPtr,
+                    const char **versionPtr, const char **versionEndPtr,
+                    const char **encodingName, const ENCODING **encoding,
+                    int *standalone) {
+  return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end,
+                        badPtr, versionPtr, versionEndPtr, encodingName,
+                        encoding, standalone);
 }
 
 #endif /* XML_TOK_NS_C */
index 0dbd5a3342b013ee1013ab322a23a38eba6fe7f5..97c64f633091f227bcbc43dea27fb1359941f067 100644 (file)
@@ -1322,7 +1322,11 @@ _PyFaulthandler_Init(int enable)
      * be able to allocate memory on the stack, even on a stack overflow. If it
      * fails, ignore the error. */
     stack.ss_flags = 0;
-    stack.ss_size = SIGSTKSZ;
+    /* bpo-21131: allocate dedicated stack of SIGSTKSZ*2 bytes, instead of just
+       SIGSTKSZ bytes. Calling the previous signal handler in faulthandler
+       signal handler uses more than SIGSTKSZ bytes of stack memory on some
+       platforms. */
+    stack.ss_size = SIGSTKSZ * 2;
     stack.ss_sp = PyMem_Malloc(stack.ss_size);
     if (stack.ss_sp != NULL) {
         err = sigaltstack(&stack, &old_stack);
index bfb33316d969b9728602990855b42bccb6c90345..ba8d74b4a04272fffa8f2b94cee21f89a590739d 100644 (file)
@@ -909,7 +909,7 @@ calculate_init(PyCalculatePath *calculate,
         return DECODE_LOCALE_ERR("PREFIX define", len);
     }
     calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
-    if (!calculate->prefix) {
+    if (!calculate->exec_prefix) {
         return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
     }
     calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
index bff9df608304b67a69acb4c7d61d242f63be0a17..0ddd98dea124748c5bbdc6f6c6f632b59df16229 100644 (file)
@@ -395,6 +395,7 @@ typedef struct {
     PyObject_HEAD
     PyObject *it;
     int numread;                /* 0 <= numread <= LINKCELLS */
+    int running;
     PyObject *nextlink;
     PyObject *(values[LINKCELLS]);
 } teedataobject;
@@ -417,6 +418,7 @@ teedataobject_newinternal(PyObject *it)
     if (tdo == NULL)
         return NULL;
 
+    tdo->running = 0;
     tdo->numread = 0;
     tdo->nextlink = NULL;
     Py_INCREF(it);
@@ -445,7 +447,14 @@ teedataobject_getitem(teedataobject *tdo, int i)
     else {
         /* this is the lead iterator, so fetch more data */
         assert(i == tdo->numread);
+        if (tdo->running) {
+            PyErr_SetString(PyExc_RuntimeError,
+                            "cannot re-enter the tee iterator");
+            return NULL;
+        }
+        tdo->running = 1;
         value = PyIter_Next(tdo->it);
+        tdo->running = 0;
         if (value == NULL)
             return NULL;
         tdo->numread++;
index 223afacf3140f9e2f5c4a0e21bd34488b40bc480..37a5c3dade8edb0d0e419456d176e60a0bde4482 100644 (file)
@@ -1392,7 +1392,8 @@ static void
 setint(PyObject *d, const char *name, long value)
 {
     PyObject *o = PyLong_FromLong(value);
-    if (o && PyDict_SetItemString(d, name, o) == 0) {
+    if (o) {
+        PyDict_SetItemString(d, name, o);
         Py_DECREF(o);
     }
 }
index 7798856bee7304d12051b06b96a4aaa823bb8320..596ee33027ed97a286de25581ec419f7e9503aab 100644 (file)
@@ -486,7 +486,8 @@ overlapped_FormatMessage(PyObject *ignore, PyObject *args)
         return NULL;
 
     n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                       FORMAT_MESSAGE_FROM_SYSTEM,
+                       FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
                        NULL,
                        code,
                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
index b758e766a4d07a898957ef2b30a09f0e5f8ddf28..58cb9b0d468d2fadd2a2a8cbed1382957f14b7b9 100644 (file)
@@ -5809,6 +5809,9 @@ os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
         }
         CPU_SET_S(cpu, setsize, cpu_set);
     }
+    if (PyErr_Occurred()) {
+        goto error;
+    }
     Py_CLEAR(iterator);
 
     if (sched_setaffinity(pid, setsize, cpu_set)) {
index 65385e8974cf9cdc8ae6cbd6c4a9cd826bc08032..a9ef7e2083d58d20488f5f2a9f3ed5019f2d6854 100644 (file)
@@ -741,6 +741,17 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval,
     ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
     assert(ms <= INT_MAX);
 
+    /* On some OSes, typically BSD-based ones, the timeout parameter of the
+       poll() syscall, when negative, must be exactly INFTIM, where defined,
+       or -1. See issue 37811. */
+    if (ms < 0) {
+#ifdef INFTIM
+        ms = INFTIM;
+#else
+        ms = -1;
+#endif
+    }
+
     Py_BEGIN_ALLOW_THREADS;
     n = poll(&pollfd, 1, (int)ms);
     Py_END_ALLOW_THREADS;
index 4c8e2cb2344bcd27f021a894ecbb55c87833f27c..0ae4fcc32364ec990c688206f63e3e66b3e11ed0 100644 (file)
@@ -1189,7 +1189,7 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
             return -1;
         }
 
-        _PyTime_t total = utime + utime;
+        _PyTime_t total = utime + stime;
         *tp = total;
         return 0;
     }
index 8a0994ffa4ab09589c468a7797e6a2f43ca5b297..41de28d58b1a74d6d63d8b6b2131f81abc633820 100644 (file)
@@ -1689,6 +1689,10 @@ bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
     }
     Py_DECREF(bytearray_obj);
 
+    if (PyErr_Occurred()) {
+        return NULL;
+    }
+
     Py_RETURN_NONE;
 }
 
index eb635263b04cd129f40def977515edcb65e1411d..94374488490073f700341d4ac4095dd23c23a265 100644 (file)
@@ -39,7 +39,7 @@ Size of indices is dk_size.  Type of each index in indices is vary on dk_size:
 * int32 for 2**16 <= dk_size <= 2**31
 * int64 for 2**32 <= dk_size
 
-dk_entries is array of PyDictKeyEntry.  It's size is USABLE_FRACTION(dk_size).
+dk_entries is array of PyDictKeyEntry.  Its size is USABLE_FRACTION(dk_size).
 DK_ENTRIES(dk) can be used to get pointer to entries.
 
 NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of
index 67f9e5d5b4ef7a5855a59f0315c4b1724d8a17dc..b4b1e5cff6bc85302bec22ec8738897a4c5ce15d 100644 (file)
@@ -43,7 +43,7 @@ static PyTypeObject FloatInfoType;
 PyDoc_STRVAR(floatinfo__doc__,
 "sys.float_info\n\
 \n\
-A structseq holding information about the float type. It contains low level\n\
+A named tuple holding information about the float type. It contains low level\n\
 information about the precision and internal representation. Please study\n\
 your system's :file:`float.h` for more information.");
 
index b0e877072c7840fd61d92ef19e2bb9db0954df49..8a978b1a1fe02a1aaec84bcae5ddda9763f31d84 100644 (file)
@@ -1905,11 +1905,6 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
 {
     PyObject *retval;
 
-    if (o->agt_state == AWAITABLE_STATE_INIT) {
-        PyErr_SetString(PyExc_RuntimeError, NON_INIT_CORO_MSG);
-        return NULL;
-    }
-
     if (o->agt_state == AWAITABLE_STATE_CLOSED) {
         PyErr_SetNone(PyExc_StopIteration);
         return NULL;
index 78aa8dea08ac2fbfd90a14c31ef80d8622e1e412..c5e7553efcf90ce2b42d046a83f47e8dc688260c 100644 (file)
@@ -2729,7 +2729,8 @@ list_subscript(PyListObject* self, PyObject* item)
         return list_item(self, i);
     }
     else if (PySlice_Check(item)) {
-        Py_ssize_t start, stop, step, slicelength, cur, i;
+        Py_ssize_t start, stop, step, slicelength, i;
+        size_t cur;
         PyObject* result;
         PyObject* it;
         PyObject **src, **dest;
@@ -2865,7 +2866,8 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
             /* assign slice */
             PyObject *ins, *seq;
             PyObject **garbage, **seqitems, **selfitems;
-            Py_ssize_t cur, i;
+            Py_ssize_t i;
+            size_t cur;
 
             /* protect against a[::-1] = a */
             if (self == (PyListObject*)value) {
index 7628a114e3843038582b882aba913c9d675c7214..202f652fc6df1eeaac8140a29850c0fb62b4453d 100644 (file)
@@ -5424,7 +5424,7 @@ static PyTypeObject Int_InfoType;
 PyDoc_STRVAR(int_info__doc__,
 "sys.int_info\n\
 \n\
-A struct sequence that holds information about Python's\n\
+A named tuple that holds information about Python's\n\
 internal representation of integers.  The attributes are read only.");
 
 static PyStructSequence_Field int_info_fields[] = {
index 885ad537ad959d11fc64e4264c1c49aa3b6b3765..1248a3937e0d4258639a9512d748625615534c2d 100644 (file)
@@ -44,9 +44,9 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain);
 #    define _Py_NO_ADDRESS_SAFETY_ANALYSIS \
         __attribute__((no_address_safety_analysis))
 #  endif
-   // TSAN is supported since GCC 4.8, but __SANITIZE_THREAD__ macro
+   // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro
    // is provided only since GCC 7.
-#  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+#  if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)
 #    define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
 #  endif
 #endif
@@ -1377,13 +1377,13 @@ address_in_range(void *p, poolp pool)
    block allocations typically result in a couple of instructions).
    Unless the optimizer reorders everything, being too smart...
 
-   Return 1 if pymalloc allocated memory and wrote the pointer into *ptr_p.
+   Return a pointer to newly allocated memory if pymalloc allocated memory.
 
-   Return 0 if pymalloc failed to allocate the memory block: on bigger
+   Return NULL if pymalloc failed to allocate the memory block: on bigger
    requests, on error in the code below (as a last chance to serve the request)
    or when the max memory limit has been reached. */
-static int
-pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes)
+static void*
+pymalloc_alloc(void *ctx, size_t nbytes)
 {
     block *bp;
     poolp pool;
@@ -1395,15 +1395,15 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes)
         running_on_valgrind = RUNNING_ON_VALGRIND;
     }
     if (UNLIKELY(running_on_valgrind)) {
-        return 0;
+        return NULL;
     }
 #endif
 
     if (nbytes == 0) {
-        return 0;
+        return NULL;
     }
     if (nbytes > SMALL_REQUEST_THRESHOLD) {
-        return 0;
+        return NULL;
     }
 
     LOCK();
@@ -1564,20 +1564,19 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes)
 success:
     UNLOCK();
     assert(bp != NULL);
-    *ptr_p = (void *)bp;
-    return 1;
+    return (void *)bp;
 
 failed:
     UNLOCK();
-    return 0;
+    return NULL;
 }
 
 
 static void *
 _PyObject_Malloc(void *ctx, size_t nbytes)
 {
-    void* ptr;
-    if (pymalloc_alloc(ctx, &ptr, nbytes)) {
+    void* ptr = pymalloc_alloc(ctx, nbytes);
+    if (ptr != NULL) {
         _Py_AllocatedBlocks++;
         return ptr;
     }
@@ -1593,12 +1592,11 @@ _PyObject_Malloc(void *ctx, size_t nbytes)
 static void *
 _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize)
 {
-    void* ptr;
-
     assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize);
     size_t nbytes = nelem * elsize;
 
-    if (pymalloc_alloc(ctx, &ptr, nbytes)) {
+    void *ptr = pymalloc_alloc(ctx, nbytes);
+    if (ptr != NULL) {
         memset(ptr, 0, nbytes);
         _Py_AllocatedBlocks++;
         return ptr;
index e48165dcd0087f5c34c99a8947260ea04246681e..c71898fd79c0917d3832c86e4c51e7f4f91508aa 100644 (file)
@@ -1,5 +1,11 @@
-/* Implementation helper: a struct that looks like a tuple.  See timemodule
-   and posixmodule for example uses. */
+/* Implementation helper: a struct that looks like a tuple.
+   See timemodule and posixmodule for example uses.
+
+   The structseq helper is considered an internal CPython implementation
+   detail.  Docs for modules using structseqs should call them
+   "named tuples" (be sure to include a space between the two
+   words and add a link back to the term in Docs/glossary.rst).
+*/
 
 #include "Python.h"
 #include "structmember.h"
index c0e9c2d112ab6469d5f7a83bc1d71930404df12e..9e0731bf2ba2fa7bed6fa6a3fe29f433515b37e6 100644 (file)
@@ -7085,6 +7085,12 @@ PyUnicode_AsASCIIString(PyObject *unicode)
 #define NEED_RETRY
 #endif
 
+/* INT_MAX is the theoretical largest chunk (or INT_MAX / 2 when
+   transcoding from UTF-16), but INT_MAX / 4 perfoms better in
+   both cases also and avoids partial characters overrunning the
+   length limit in MultiByteToWideChar on Windows */
+#define DECODING_CHUNK_SIZE (INT_MAX/4)
+
 #ifndef WC_ERR_INVALID_CHARS
 #  define WC_ERR_INVALID_CHARS 0x0080
 #endif
@@ -7345,8 +7351,8 @@ decode_code_page_stateful(int code_page,
     do
     {
 #ifdef NEED_RETRY
-        if (size > INT_MAX) {
-            chunk_size = INT_MAX;
+        if (size > DECODING_CHUNK_SIZE) {
+            chunk_size = DECODING_CHUNK_SIZE;
             final = 0;
             done = 0;
         }
@@ -7748,10 +7754,8 @@ encode_code_page(int code_page,
     do
     {
 #ifdef NEED_RETRY
-        /* UTF-16 encoding may double the size, so use only INT_MAX/2
-           chunks. */
-        if (len > INT_MAX/2) {
-            chunk_len = INT_MAX/2;
+        if (len > DECODING_CHUNK_SIZE) {
+            chunk_len = DECODING_CHUNK_SIZE;
             done = 0;
         }
         else
index 04323ebd17068172fee46ba6185d31c21bba4fbb..7a0e2e8c5dd7ee6e6993b5547df40876fe1d9c76 100644 (file)
@@ -939,7 +939,8 @@ static BOOL SystemError(int error, char *msg)
         LPVOID lpMsgBuf;
         FormatMessage(
             FORMAT_MESSAGE_ALLOCATE_BUFFER |
-            FORMAT_MESSAGE_FROM_SYSTEM,
+            FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
             NULL,
             error,
             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
index 6a5f613808c2e7e8cc5a69d14b70554d8fe34ba7..e9df3675b146195a017723a8fa3a52ec690cbdc4 100644 (file)
@@ -1003,7 +1003,7 @@ PyDoc_STRVAR(winreg_DisableReflectionKey__doc__,
 "  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"
+"Will generally raise NotImplementedError 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"
@@ -1039,7 +1039,7 @@ PyDoc_STRVAR(winreg_EnableReflectionKey__doc__,
 "  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"
+"Will generally raise NotImplementedError if executed on a 32bit OS.\n"
 "Restoring reflection for a key does not affect reflection of any\n"
 "subkeys.");
 
@@ -1073,7 +1073,7 @@ PyDoc_STRVAR(winreg_QueryReflectionKey__doc__,
 "  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.");
+"Will generally raise NotImplementedError if executed on a 32bit OS.");
 
 #define WINREG_QUERYREFLECTIONKEY_METHODDEF    \
     {"QueryReflectionKey", (PyCFunction)winreg_QueryReflectionKey, METH_O, winreg_QueryReflectionKey__doc__},
@@ -1095,4 +1095,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=60c92ffc7438f8cf input=a9049054013a1b77]*/
+/*[clinic end generated code: output=696f627d310ac599 input=a9049054013a1b77]*/
index 985f673a4649c8690b3abebd28463c78056582b2..a7489ab75c65618c5486a9fb0b8c6f87fc88489c 100644 (file)
-/* Generated file. Do not edit. */
-int winerror_to_errno(int winerror)
+int
+winerror_to_errno(int winerror)
 {
-    switch(winerror) {
-        case 2: return 2;
-        case 3: return 2;
-        case 4: return 24;
-        case 5: return 13;
-        case 6: return 9;
-        case 7: return 12;
-        case 8: return 12;
-        case 9: return 12;
-        case 10: return 7;
-        case 11: return 8;
-        case 15: return 2;
-        case 16: return 13;
-        case 17: return 18;
-        case 18: return 2;
-        case 19: return 13;
-        case 20: return 13;
-        case 21: return 13;
-        case 22: return 13;
-        case 23: return 13;
-        case 24: return 13;
-        case 25: return 13;
-        case 26: return 13;
-        case 27: return 13;
-        case 28: return 13;
-        case 29: return 13;
-        case 30: return 13;
-        case 31: return 13;
-        case 32: return 13;
-        case 33: return 13;
-        case 34: return 13;
-        case 35: return 13;
-        case 36: return 13;
-        case 53: return 2;
-        case 65: return 13;
-        case 67: return 2;
-        case 80: return 17;
-        case 82: return 13;
-        case 83: return 13;
-        case 89: return 11;
-        case 108: return 13;
-        case 109: return 32;
-        case 112: return 28;
-        case 114: return 9;
-        case 128: return 10;
-        case 129: return 10;
-        case 130: return 9;
-        case 132: return 13;
-        case 145: return 41;
-        case 158: return 13;
-        case 161: return 2;
-        case 164: return 11;
-        case 167: return 13;
-        case 183: return 17;
-        case 188: return 8;
-        case 189: return 8;
-        case 190: return 8;
-        case 191: return 8;
-        case 192: return 8;
-        case 193: return 8;
-        case 194: return 8;
-        case 195: return 8;
-        case 196: return 8;
-        case 197: return 8;
-        case 198: return 8;
-        case 199: return 8;
-        case 200: return 8;
-        case 201: return 8;
-        case 202: return 8;
-        case 206: return 2;
-        case 215: return 11;
-        case 232: return 32;
-        case 267: return 20;
-        case 1816: return 12;
-        default: return EINVAL;
+    // Unwrap FACILITY_WIN32 HRESULT errors.
+    if ((winerror & 0xFFFF0000) == 0x80070000) {
+        winerror &= 0x0000FFFF;
+    }
+
+    // Winsock error codes (10000-11999) are errno values.
+    if (winerror >= 10000 && winerror < 12000) {
+        switch (winerror) {
+        case WSAEINTR:
+        case WSAEBADF:
+        case WSAEACCES:
+        case WSAEFAULT:
+        case WSAEINVAL:
+        case WSAEMFILE:
+            // Winsock definitions of errno values. See WinSock2.h
+            return winerror - 10000;
+        default:
+            return winerror;
+        }
+    }
+
+    switch (winerror) {
+    case ERROR_FILE_NOT_FOUND:            //    2
+    case ERROR_PATH_NOT_FOUND:            //    3
+    case ERROR_INVALID_DRIVE:             //   15
+    case ERROR_NO_MORE_FILES:             //   18
+    case ERROR_BAD_NETPATH:               //   53
+    case ERROR_BAD_NET_NAME:              //   67
+    case ERROR_BAD_PATHNAME:              //  161
+    case ERROR_FILENAME_EXCED_RANGE:      //  206
+        return ENOENT;
+
+    case ERROR_BAD_ENVIRONMENT:           //   10
+        return E2BIG;
+
+    case ERROR_BAD_FORMAT:                //   11
+    case ERROR_INVALID_STARTING_CODESEG:  //  188
+    case ERROR_INVALID_STACKSEG:          //  189
+    case ERROR_INVALID_MODULETYPE:        //  190
+    case ERROR_INVALID_EXE_SIGNATURE:     //  191
+    case ERROR_EXE_MARKED_INVALID:        //  192
+    case ERROR_BAD_EXE_FORMAT:            //  193
+    case ERROR_ITERATED_DATA_EXCEEDS_64k: //  194
+    case ERROR_INVALID_MINALLOCSIZE:      //  195
+    case ERROR_DYNLINK_FROM_INVALID_RING: //  196
+    case ERROR_IOPL_NOT_ENABLED:          //  197
+    case ERROR_INVALID_SEGDPL:            //  198
+    case ERROR_AUTODATASEG_EXCEEDS_64k:   //  199
+    case ERROR_RING2SEG_MUST_BE_MOVABLE:  //  200
+    case ERROR_RELOC_CHAIN_XEEDS_SEGLIM:  //  201
+    case ERROR_INFLOOP_IN_RELOC_CHAIN:    //  202
+        return ENOEXEC;
+
+    case ERROR_INVALID_HANDLE:            //    6
+    case ERROR_INVALID_TARGET_HANDLE:     //  114
+    case ERROR_DIRECT_ACCESS_HANDLE:      //  130
+        return EBADF;
+
+    case ERROR_WAIT_NO_CHILDREN:          //  128
+    case ERROR_CHILD_NOT_COMPLETE:        //  129
+        return ECHILD;
+
+    case ERROR_NO_PROC_SLOTS:             //   89
+    case ERROR_MAX_THRDS_REACHED:         //  164
+    case ERROR_NESTING_NOT_ALLOWED:       //  215
+        return EAGAIN;
+
+    case ERROR_ARENA_TRASHED:             //    7
+    case ERROR_NOT_ENOUGH_MEMORY:         //    8
+    case ERROR_INVALID_BLOCK:             //    9
+    case ERROR_NOT_ENOUGH_QUOTA:          // 1816
+        return ENOMEM;
+
+    case ERROR_ACCESS_DENIED:             //    5
+    case ERROR_CURRENT_DIRECTORY:         //   16
+    case ERROR_WRITE_PROTECT:             //   19
+    case ERROR_BAD_UNIT:                  //   20
+    case ERROR_NOT_READY:                 //   21
+    case ERROR_BAD_COMMAND:               //   22
+    case ERROR_CRC:                       //   23
+    case ERROR_BAD_LENGTH:                //   24
+    case ERROR_SEEK:                      //   25
+    case ERROR_NOT_DOS_DISK:              //   26
+    case ERROR_SECTOR_NOT_FOUND:          //   27
+    case ERROR_OUT_OF_PAPER:              //   28
+    case ERROR_WRITE_FAULT:               //   29
+    case ERROR_READ_FAULT:                //   30
+    case ERROR_GEN_FAILURE:               //   31
+    case ERROR_SHARING_VIOLATION:         //   32
+    case ERROR_LOCK_VIOLATION:            //   33
+    case ERROR_WRONG_DISK:                //   34
+    case ERROR_SHARING_BUFFER_EXCEEDED:   //   36
+    case ERROR_NETWORK_ACCESS_DENIED:     //   65
+    case ERROR_CANNOT_MAKE:               //   82
+    case ERROR_FAIL_I24:                  //   83
+    case ERROR_DRIVE_LOCKED:              //  108
+    case ERROR_SEEK_ON_DEVICE:            //  132
+    case ERROR_NOT_LOCKED:                //  158
+    case ERROR_LOCK_FAILED:               //  167
+    case 35:                              //   35 (undefined)
+        return EACCES;
+
+    case ERROR_FILE_EXISTS:               //   80
+    case ERROR_ALREADY_EXISTS:            //  183
+        return EEXIST;
+
+    case ERROR_NOT_SAME_DEVICE:           //   17
+        return EXDEV;
+
+    case ERROR_DIRECTORY:                 //  267 (bpo-12802)
+        return ENOTDIR;
+
+    case ERROR_TOO_MANY_OPEN_FILES:       //    4
+        return EMFILE;
+
+    case ERROR_DISK_FULL:                 //  112
+        return ENOSPC;
+
+    case ERROR_BROKEN_PIPE:               //  109
+    case ERROR_NO_DATA:                   //  232 (bpo-13063)
+        return EPIPE;
+
+    case ERROR_DIR_NOT_EMPTY:             //  145
+        return ENOTEMPTY;
+
+    case ERROR_NO_UNICODE_TRANSLATION:    // 1113
+        return EILSEQ;
+
+    case ERROR_INVALID_FUNCTION:          //    1
+    case ERROR_INVALID_ACCESS:            //   12
+    case ERROR_INVALID_DATA:              //   13
+    case ERROR_INVALID_PARAMETER:         //   87
+    case ERROR_NEGATIVE_SEEK:             //  131
+    default:
+        return EINVAL;
     }
 }
diff --git a/PC/generrmap.c b/PC/generrmap.c
deleted file mode 100644 (file)
index 953344c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <windows.h>
-#include <fcntl.h>
-#include <io.h>
-#include <stdio.h>
-#include <errno.h>
-
-/* Extract the mapping of Win32 error codes to errno */
-
-int main()
-{
-    int i;
-    _setmode(fileno(stdout), O_BINARY);
-    printf("/* Generated file. Do not edit. */\n");
-    printf("int winerror_to_errno(int winerror)\n");
-    printf("{\n    switch(winerror) {\n");
-    for(i=1; i < 65000; i++) {
-        _dosmaperr(i);
-        if (errno == EINVAL) {
-            /* Issue #12802 */
-            if (i == ERROR_DIRECTORY)
-                errno = ENOTDIR;
-            /* Issue #13063 */
-            else if (i == ERROR_NO_DATA)
-                errno = EPIPE;
-            else
-                continue;
-        }
-        printf("        case %d: return %d;\n", i, errno);
-    }
-    printf("        default: return EINVAL;\n");
-    printf("    }\n}\n");
-}
index 46fc84e92f29ec2bee62f01124c6f34ae947e997..6e33f12e0df62a4f25ae95264ec876c0f69e7575 100644 (file)
@@ -292,7 +292,7 @@ Py_NO_ENABLE_SHARED to find out.  Also support MS_NO_COREDLL for b/w compat */
 #       define SIZEOF_FPOS_T 8
 #       define SIZEOF_HKEY 8
 #       define SIZEOF_SIZE_T 8
-/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff HAVE_LONG_LONG,
+/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff
    sizeof(off_t) > sizeof(long), and sizeof(PY_LONG_LONG) >= sizeof(off_t).
    On Win64 the second condition is not true, but if fpos_t replaces off_t
    then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64
index 1021609e582f6af2897d12d124f60907bdaa0fb8..16a10c7232a17da9f157a452aec1fa09e9560dfa 100644 (file)
@@ -517,11 +517,18 @@ fixupMultiSZ(wchar_t **str, wchar_t *data, int len)
     int i;
     wchar_t *Q;
 
-    Q = data + len;
-    for (P = data, i = 0; P < Q && *P != '\0'; P++, i++) {
+    if (len > 0 && data[len - 1] == '\0') {
+        Q = data + len - 1;
+    }
+    else {
+        Q = data + len;
+    }
+
+    for (P = data, i = 0; P < Q; P++, i++) {
         str[i] = P;
-        for (; P < Q && *P != '\0'; P++)
+        for (; P < Q && *P != '\0'; P++) {
             ;
+        }
     }
 }
 
@@ -529,12 +536,20 @@ static int
 countStrings(wchar_t *data, int len)
 {
     int strings;
-    wchar_t *P;
-    wchar_t *Q = data + len;
+    wchar_t *P, *Q;
+
+    if (len > 0 && data[len - 1] == '\0') {
+        Q = data + len - 1;
+    }
+    else {
+        Q = data + len;
+    }
 
-    for (P = data, strings = 0; P < Q && *P != '\0'; P++, strings++)
-        for (; P < Q && *P != '\0'; P++)
+    for (P = data, strings = 0; P < Q; P++, strings++) {
+        for (; P < Q && *P != '\0'; P++) {
             ;
+        }
+    }
     return strings;
 }
 
@@ -749,21 +764,15 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ)
                 }
                 for (index = 0; index < s; index++)
                 {
-                    size_t len = wcslen(str[index]);
-                    if (len > INT_MAX) {
-                        PyErr_SetString(PyExc_OverflowError,
-                            "registry string is too long for a Python string");
-                        Py_DECREF(obData);
-                        PyMem_Free(str);
-                        return NULL;
-                    }
-                    PyObject *uni = PyUnicode_FromWideChar(str[index], len);
+                    size_t slen = wcsnlen(str[index], len);
+                    PyObject *uni = PyUnicode_FromWideChar(str[index], slen);
                     if (uni == NULL) {
                         Py_DECREF(obData);
                         PyMem_Free(str);
                         return NULL;
                     }
                     PyList_SET_ITEM(obData, index, uni);
+                    len -= Py_SAFE_DOWNCAST(slen + 1, size_t, int);
                 }
                 PyMem_Free(str);
 
@@ -1697,7 +1706,7 @@ winreg.DisableReflectionKey
 
 Disables registry reflection for 32bit processes running on a 64bit OS.
 
-Will generally raise NotImplemented if executed on a 32bit OS.
+Will generally raise NotImplementedError 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
@@ -1706,7 +1715,7 @@ of any subkeys.
 
 static PyObject *
 winreg_DisableReflectionKey_impl(PyObject *module, HKEY key)
-/*[clinic end generated code: output=830cce504cc764b4 input=a6c9e5ca5410193c]*/
+/*[clinic end generated code: output=830cce504cc764b4 input=70bece2dee02e073]*/
 {
     HMODULE hMod;
     typedef LONG (WINAPI *RDRKFunc)(HKEY);
@@ -1742,14 +1751,14 @@ winreg.EnableReflectionKey
 
 Restores registry reflection for the specified disabled key.
 
-Will generally raise NotImplemented if executed on a 32bit OS.
+Will generally raise NotImplementedError if executed on a 32bit OS.
 Restoring reflection for a key does not affect reflection of any
 subkeys.
 [clinic start generated code]*/
 
 static PyObject *
 winreg_EnableReflectionKey_impl(PyObject *module, HKEY key)
-/*[clinic end generated code: output=86fa1385fdd9ce57 input=7748abbacd1e166a]*/
+/*[clinic end generated code: output=86fa1385fdd9ce57 input=eeae770c6eb9f559]*/
 {
     HMODULE hMod;
     typedef LONG (WINAPI *RERKFunc)(HKEY);
@@ -1785,12 +1794,12 @@ winreg.QueryReflectionKey
 
 Returns the reflection state for the specified key as a bool.
 
-Will generally raise NotImplemented if executed on a 32bit OS.
+Will generally raise NotImplementedError if executed on a 32bit OS.
 [clinic start generated code]*/
 
 static PyObject *
 winreg_QueryReflectionKey_impl(PyObject *module, HKEY key)
-/*[clinic end generated code: output=4e774af288c3ebb9 input=9f325eacb5a65d88]*/
+/*[clinic end generated code: output=4e774af288c3ebb9 input=a98fa51d55ade186]*/
 {
     HMODULE hMod;
     typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *);
index 310458d524140f55d3fc7348793efb4abd86685e..4e054d85a3f46811f013f73e7edaf8c67b8b4f13 100644 (file)
@@ -84,7 +84,6 @@
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="..\Modules\_elementtree.c" />\r
-    <ClCompile Include="..\Modules\expat\loadlibrary.c" />\r
     <ClCompile Include="..\Modules\expat\xmlparse.c" />\r
     <ClCompile Include="..\Modules\expat\xmlrole.c" />\r
     <ClCompile Include="..\Modules\expat\xmltok.c" />\r
index 14fa41759a636bead64db3810c1843f97c8ccafb..48cb249295b51f08ea1e46be7ebb416588333894 100644 (file)
@@ -33,9 +33,6 @@
     <ClInclude Include="..\Modules\expat\latin1tab.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="..\Modules\expat\loadlibrary.c">\r
-      <Filter>Header Files</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="..\Modules\expat\macconfig.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
index 4b4ccf1bb3aae42b0d51cc3576e50aba520f0d2c..0414bc22394a3515f6260fe75063fd2c0ed5d29b 100644 (file)
@@ -49,7 +49,7 @@ echo.Fetching external libraries...
 \r
 set libraries=\r
 set libraries=%libraries%                                       bzip2-1.0.6\r
-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries%     openssl-1.1.1c\r
+if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries%     openssl-1.1.1d\r
 set libraries=%libraries%                                       sqlite-3.28.0.0\r
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0\r
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0\r
@@ -72,7 +72,7 @@ for %%e in (%libraries%) do (
 echo.Fetching external binaries...\r
 \r
 set binaries=\r
-if NOT "%IncludeSSL%"=="false"     set binaries=%binaries% openssl-bin-1.1.1c\r
+if NOT "%IncludeSSL%"=="false"     set binaries=%binaries% openssl-bin-1.1.1d\r
 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0\r
 if NOT "%IncludeSSLSrc%"=="false"  set binaries=%binaries% nasm-2.11.06\r
 \r
index cd3f6d174d445d2e55c06be451c7a14655362b96..d49f61d8bff27296844621e6a04ecaf3dca71189 100644 (file)
@@ -68,7 +68,6 @@
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="..\Modules\pyexpat.c" />\r
-    <ClCompile Include="..\Modules\expat\loadlibrary.c" />\r
     <ClCompile Include="..\Modules\expat\xmlparse.c" />\r
     <ClCompile Include="..\Modules\expat\xmlrole.c" />\r
     <ClCompile Include="..\Modules\expat\xmltok.c" />\r
index 2d41521937a039d9c5a1fb2321cfeae4a00b140b..d48df6ecbdaf11e5e8d89dbe4bb28af91f8ed838 100644 (file)
@@ -20,9 +20,6 @@
     <ClCompile Include="..\Modules\pyexpat.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\Modules\expat\loadlibrary.c">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="..\Modules\expat\xmlparse.c">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
index 617f402934e55ecdbb40cac8ea866bf1cdacfc56..bf9a438b04da3e9652d9c5d28f57078aab852078 100644 (file)
@@ -49,8 +49,8 @@
     <sqlite3Dir>$(ExternalsDir)sqlite-3.28.0.0\</sqlite3Dir>\r
     <bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>\r
     <lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>\r
-    <opensslDir>$(ExternalsDir)openssl-1.1.1c\</opensslDir>\r
-    <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1c\$(ArchName)\</opensslOutDir>\r
+    <opensslDir>$(ExternalsDir)openssl-1.1.1d\</opensslDir>\r
+    <opensslOutDir>$(ExternalsDir)openssl-bin-1.1.1d\$(ArchName)\</opensslOutDir>\r
     <opensslIncludeDir>$(opensslOutDir)include</opensslIncludeDir>\r
     <nasmDir>$(ExternalsDir)\nasm-2.11.06\</nasmDir>\r
     <zlibDir>$(ExternalsDir)\zlib-1.2.11\</zlibDir>\r
index 7b3842a7b7439796c1fcbd06d5ec9fba2df32a54..fb4e78a6767aacfec08c1f477bd16758d46b314b 100644 (file)
       <SubSystem>Console</SubSystem>\r
     </Link>\r
   </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="$(Configuration) != 'Debug'">\r
+    <ClCompile>\r
+      <RuntimeLibrary>Multithreaded</RuntimeLibrary>\r
+    </ClCompile>\r
+    <Link>\r
+      <AdditionalDependencies>ucrt.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+      <IgnoreSpecificDefaultLibraries>libucrt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
   <ItemGroup>\r
     <None Include="..\PC\pycon.ico" />\r
   </ItemGroup>\r
index e374c5a4aee615bd8bd7653b35bcf0f1b21c61d0..d720f19eca9db811681df25c1f2f970dc51bc360 100644 (file)
@@ -1890,7 +1890,7 @@ PyTokenizer_FindEncodingFilename(int fd, PyObject *filename)
     if (tok->encoding) {
         encoding = (char *)PyMem_MALLOC(strlen(tok->encoding) + 1);
         if (encoding)
-        strcpy(encoding, tok->encoding);
+            strcpy(encoding, tok->encoding);
     }
     PyTokenizer_Free(tok);
     return encoding;
index 80dca65fd353f84e2df2fe6ee4222fe028a19334..e86a582a01cf44f2137852c923d3d1fddff0e9f3 100644 (file)
@@ -1213,7 +1213,7 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro)
 }
 
 PyDoc_STRVAR(warn_explicit_doc,
-"Low-level inferface to warnings functionality.");
+"Low-level interface to warnings functionality.");
 
 static PyMethodDef warnings_functions[] = {
     WARNINGS_WARN_METHODDEF
index 8083ac961feb552173bb7dc2038b805708259b37..12def95971a7bebe5e9801c46a8ae3f82cd27f42 100644 (file)
@@ -2675,7 +2675,7 @@ static PyMethodDef zip_methods[] = {
 };
 
 PyDoc_STRVAR(zip_doc,
-"zip(iter1 [,iter2 [...]]) --> zip object\n\
+"zip(*iterables) --> zip object\n\
 \n\
 Return a zip object whose .__next__() method returns a tuple where\n\
 the i-th element comes from the i-th iterable argument.  The .__next__()\n\
index 5688ef8479c0de3e1872b3b92b08adbd6c636c06..32884be34de3c653d0ea54d8f9a881e957be520b 100644 (file)
@@ -1482,7 +1482,7 @@ compiler_body(struct compiler *c, asdl_seq *stmts)
     /* Set current line number to the line number of first statement.
        This way line number for SETUP_ANNOTATIONS will always
        coincide with the line number of first "real" statement in module.
-       If body is empy, then lineno will be set later in assemble. */
+       If body is empty, then lineno will be set later in assemble. */
     if (c->u->u_scope_type == COMPILER_SCOPE_MODULE &&
         !c->u->u_lineno && asdl_seq_LEN(stmts)) {
         st = (stmt_ty)asdl_seq_GET(stmts, 0);
index 951b8ad47f07beaafb79c39498128ca8341e59ec..802d53fbe69da55a4a607b22b8aa74cbff43c186 100644 (file)
@@ -194,7 +194,7 @@ _PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms)
          * just means an extra spurious wakeup for a waiting thread.
          * ('waiting' corresponds to the semaphore's "negative" count and
          * we may end up with e.g. (waiting == -1 && sem.count == 1).  When
-         * a new thread comes along, it will pass right throuhgh, having
+         * a new thread comes along, it will pass right through, having
          * adjusted it to (waiting == 0 && sem.count == 0).
          */
 
index 868fbf910312a1461baf7d7974414636c5a1ceb1..b2c634db23bf8fcb2b4036bf948b20c4978f3166 100644 (file)
@@ -1037,11 +1037,18 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
         flags = HANDLE_FLAG_INHERIT;
     else
         flags = 0;
-    if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
+
+    /* This check can be removed once support for Windows 7 ends. */
+#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \
+        GetFileType(handle) == FILE_TYPE_CHAR)
+
+    if (!CONSOLE_PSEUDOHANDLE(handle) &&
+        !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
         if (raise)
             PyErr_SetFromWindowsErr(0);
         return -1;
     }
+#undef CONSOLE_PSEUDOHANDLE
     return 0;
 
 #else
index 63c99ea5c1abc7e7f6a4dfaa595af54644de2a8e..edc59249622b18e1f87650cd5334c42e6bce0e5b 100644 (file)
@@ -1563,22 +1563,20 @@ resolve_name(PyObject *name, PyObject *globals, int level)
             if (dot == -2) {
                 goto error;
             }
-
-            if (dot >= 0) {
-                PyObject *substr = PyUnicode_Substring(package, 0, dot);
-                if (substr == NULL) {
-                    goto error;
-                }
-                Py_SETREF(package, substr);
+            else if (dot == -1) {
+                goto no_parent_error;
             }
+            PyObject *substr = PyUnicode_Substring(package, 0, dot);
+            if (substr == NULL) {
+                goto error;
+            }
+            Py_SETREF(package, substr);
         }
     }
 
     last_dot = PyUnicode_GET_LENGTH(package);
     if (last_dot == 0) {
-        PyErr_SetString(PyExc_ImportError,
-                "attempted relative import with no known parent package");
-        goto error;
+        goto no_parent_error;
     }
 
     for (level_up = 1; level_up < level; level_up += 1) {
@@ -1604,6 +1602,11 @@ resolve_name(PyObject *name, PyObject *globals, int level)
     Py_DECREF(base);
     return abs_name;
 
+  no_parent_error:
+    PyErr_SetString(PyExc_ImportError,
+                     "attempted relative import "
+                     "with no known parent package");
+
   error:
     Py_XDECREF(package);
     return NULL;
index fc695c62a3300ebfc989e5630d229846f79e48e4..90cd56bb05f4ee6b63a1f544a6a6dd44feaad0ad 100644 (file)
@@ -484,7 +484,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def)
         if (!state->modules_by_index)
             return -1;
     }
-    while(PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index)
+    while (PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index)
         if (PyList_Append(state->modules_by_index, Py_None) < 0)
             return -1;
     Py_INCREF(module);
@@ -502,13 +502,11 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def)
         return -1;
     }
     index = def->m_base.m_index;
-    if (state->modules_by_index) {
-        if(PyList_GET_SIZE(state->modules_by_index) >= index) {
-            if(module == PyList_GET_ITEM(state->modules_by_index, index)) {
-                Py_FatalError("PyState_AddModule: Module already added!");
-                return -1;
-            }
-        }
+    if (state->modules_by_index &&
+        index < PyList_GET_SIZE(state->modules_by_index) &&
+        module == PyList_GET_ITEM(state->modules_by_index, index)) {
+        Py_FatalError("PyState_AddModule: Module already added!");
+        return -1;
     }
     return _PyState_AddModule(module, def);
 }
index c4ec5ac66c47605d1999aceff82a1e6fb6c835cd..4c974cef39c78bc88a0952426ca3dd0682006e48 100644 (file)
@@ -750,7 +750,7 @@ print_exception(PyObject *f, PyObject *value)
             Py_DECREF(value);
             value = message;
 
-            line = PyUnicode_FromFormat("  File \"%U\", line %d\n",
+            line = PyUnicode_FromFormat("  File \"%S\", line %d\n",
                                           filename, lineno);
             Py_DECREF(filename);
             if (line != NULL) {
index 942a8b6becd9f09292c37e63592ac9e7bd8fa808..b953a0009775220d5d1cdceef1290413a0517899 100644 (file)
@@ -836,7 +836,7 @@ static PyTypeObject AsyncGenHooksType;
 PyDoc_STRVAR(asyncgen_hooks_doc,
 "asyncgen_hooks\n\
 \n\
-A struct sequence providing information about asynhronous\n\
+A named tuple providing information about asynchronous\n\
 generators hooks.  The attributes are read only.");
 
 static PyStructSequence_Field asyncgen_hooks_fields[] = {
@@ -943,7 +943,7 @@ static PyTypeObject Hash_InfoType;
 PyDoc_STRVAR(hash_info_doc,
 "hash_info\n\
 \n\
-A struct sequence providing parameters used for computing\n\
+A named tuple providing parameters used for computing\n\
 hashes. The attributes are read only.");
 
 static PyStructSequence_Field hash_info_fields[] = {
@@ -1967,17 +1967,17 @@ builtin_module_names -- tuple of module names built into this interpreter\n\
 copyright -- copyright notice pertaining to this interpreter\n\
 exec_prefix -- prefix used to find the machine-specific Python library\n\
 executable -- absolute path of the executable binary of the Python interpreter\n\
-float_info -- a struct sequence with information about the float implementation.\n\
+float_info -- a named tuple with information about the float implementation.\n\
 float_repr_style -- string indicating the style of repr() output for floats\n\
-hash_info -- a struct sequence with information about the hash algorithm.\n\
+hash_info -- a named tuple with information about the hash algorithm.\n\
 hexversion -- version information encoded as a single integer\n\
 implementation -- Python implementation information.\n\
-int_info -- a struct sequence with information about the int implementation.\n\
+int_info -- a named tuple with information about the int implementation.\n\
 maxsize -- the largest supported length of containers.\n\
 maxunicode -- the value of the largest Unicode code point\n\
 platform -- platform identifier\n\
 prefix -- prefix used to find the Python library\n\
-thread_info -- a struct sequence with information about the thread implementation.\n\
+thread_info -- a named tuple with information about the thread implementation.\n\
 version -- the version of this interpreter as a string\n\
 version_info -- version information as a named tuple\n\
 "
index 07743840693b37d33fe4ae95a014ca2a71d282f6..e0cbdeef8ba27b551513028652adac77f312fdb3 100644 (file)
@@ -147,7 +147,7 @@ PyThread_tss_is_created(Py_tss_t *key)
 PyDoc_STRVAR(threadinfo__doc__,
 "sys.thread_info\n\
 \n\
-A struct sequence holding information about the thread implementation.");
+A named tuple holding information about the thread implementation.");
 
 static PyStructSequence_Field threadinfo_fields[] = {
     {"name",    "name of the thread implementation"},
index b891925fccb0eab4626b864ed2b5f75c36a88b22..795b821dd076a96790e04c35c52b56051665560d 100644 (file)
@@ -1,21 +1,17 @@
-This is Python version 3.7.4
+This is Python version 3.7.5
 ============================
 
-.. image:: https://travis-ci.org/python/cpython.svg?branch=master
+.. image:: https://travis-ci.org/python/cpython.svg?branch=3.7
    :alt: CPython build status on Travis CI
-   :target: https://travis-ci.org/python/cpython
-
-.. image:: https://ci.appveyor.com/api/projects/status/4mew1a93xdkbf5ua/branch/master?svg=true
-   :alt: CPython build status on Appveyor
-   :target: https://ci.appveyor.com/project/python/cpython/branch/master
+   :target: https://travis-ci.org/python/cpython/branches
 
 .. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=3.7
    :alt: CPython build status on Azure Pipelines
    :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=3.7
 
-.. image:: https://codecov.io/gh/python/cpython/branch/master/graph/badge.svg
+.. image:: https://codecov.io/gh/python/cpython/branch/3.7/graph/badge.svg
    :alt: CPython code coverage on Codecov
-   :target: https://codecov.io/gh/python/cpython
+   :target: https://codecov.io/gh/python/cpython/branch/3.7
 
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation.  All
@@ -63,21 +59,23 @@ On Unix, Linux, BSD, macOS, and Cygwin::
 This will install Python as ``python3``.
 
 You can pass many options to the configure script; run ``./configure --help``
-to find out more.  On macOS and Cygwin, the executable is called ``python.exe``;
-elsewhere it's just ``python``.
+to find out more.  On macOS case-insensitive file systems and on Cygwin,
+the executable is called ``python.exe``; elsewhere it's just ``python``.
 
-If you are running on macOS with the latest updates installed, make sure to install
-openSSL or some other SSL software along with Homebrew or another package manager.
-If issues persist, see https://devguide.python.org/setup/#macos-and-os-x for more 
-information. 
+Building a complete Python installation requires the use of various
+additional third-party libraries, depending on your build platform and
+configure options.  Not all standard library modules are buildable or
+useable on all platforms.  Refer to the
+`Install dependencies <https://devguide.python.org/setup/#install-dependencies>`_
+section of the `Developer Guide`_ for current detailed information on
+dependencies for various Linux distributions and macOS.
 
-On macOS, if you have configured Python with ``--enable-framework``, you
-should use ``make frameworkinstall`` to do the installation.  Note that this
-installs the Python executable in a place that is not normally on your PATH,
-you may want to set up a symlink in ``/usr/local/bin``.
+On macOS, there are additional configure and build options related
+to macOS framework and universal builds.  Refer to `Mac/README.rst
+<https://github.com/python/cpython/blob/3.7/Mac/README.rst>`_.
 
 On Windows, see `PCbuild/readme.txt
-<https://github.com/python/cpython/blob/master/PCbuild/readme.txt>`_.
+<https://github.com/python/cpython/blob/3.7/PCbuild/readme.txt>`_.
 
 If you wish, you can create a subdirectory and invoke configure from there.
 For example::
@@ -139,9 +137,9 @@ What's New
 We have a comprehensive overview of the changes in the `What's New in Python
 3.7 <https://docs.python.org/3.7/whatsnew/3.7.html>`_ document.  For a more
 detailed change log, read `Misc/NEWS
-<https://github.com/python/cpython/blob/master/Misc/NEWS.d>`_, but a full
+<https://github.com/python/cpython/blob/3.7/Misc/NEWS.d>`_, but a full
 accounting of changes can only be gleaned from the `commit history
-<https://github.com/python/cpython/commits/master>`_.
+<https://github.com/python/cpython/commits/3.7>`_.
 
 If you want to install multiple versions of Python see the section below
 entitled "Installing multiple versions".
@@ -159,7 +157,7 @@ is primarily for documentation authors, translators, and people with special
 formatting requirements.
 
 For information about building Python's documentation, refer to `Doc/README.rst
-<https://github.com/python/cpython/blob/master/Doc/README.rst>`_.
+<https://github.com/python/cpython/blob/3.7/Doc/README.rst>`_.
 
 
 Converting From Python 2.x to 3.x
index 2e468b7e57b265318044e7410c8748590f17cd26..cd4a1f8feb1d4b2c9c893ff04b74e735d5fb6248 100644 (file)
@@ -727,9 +727,13 @@ public: // IBootstrapperApplication
                 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load AssociateFiles state: error code 0x%08X", hr);
             }
 
-            _engine->SetVariableNumeric(L"Include_launcher", 1);
+            LONGLONG includeLauncher;
+            if (FAILED(BalGetNumericVariable(L"Include_launcher", &includeLauncher))
+                || includeLauncher == -1) {
+                _engine->SetVariableNumeric(L"Include_launcher", 1);
+                _engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0);
+            }
             _engine->SetVariableNumeric(L"DetectedOldLauncher", 1);
-            _engine->SetVariableNumeric(L"InstallLauncherAllUsers", fPerMachine ? 1 : 0);
         }
         return CheckCanceled() ? IDCANCEL : IDNOACTION;
     }
@@ -796,6 +800,12 @@ public: // IBootstrapperApplication
             }
         }
 
+        LONGLONG includeLauncher;
+        if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher))
+            && includeLauncher != -1) {
+            detectedLauncher = FALSE;
+        }
+
         if (detectedLauncher) {
             /* When we detect the current version of the launcher. */
             _engine->SetVariableNumeric(L"Include_launcher", 1);
@@ -819,6 +829,14 @@ public: // IBootstrapperApplication
             _baFunction->OnDetectComplete();
         }
 
+        if (SUCCEEDED(hrStatus)) {
+            LONGLONG includeLauncher;
+            if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher))
+                && includeLauncher == -1) {
+                _engine->SetVariableNumeric(L"Include_launcher", 1);
+            }
+        }
+
         if (SUCCEEDED(hrStatus)) {
             hrStatus = EvaluateConditions();
         }
@@ -1451,6 +1469,10 @@ private:
         hr = ParseOverridableVariablesFromXml(pixdManifest);
         BalExitOnFailure(hr, "Failed to read overridable variables.");
 
+        if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) {
+            LoadOptionalFeatureStates(_engine);
+        }
+
         hr = ParseVariablesFromUnattendXml();
         ExitOnFailure(hr, "Failed to read unattend.ini file.");
 
@@ -1478,10 +1500,6 @@ private:
         hr = UpdateUIStrings(_command.action);
         BalExitOnFailure(hr, "Failed to load UI strings.");
 
-        if (_command.action == BOOTSTRAPPER_ACTION_MODIFY) {
-            LoadOptionalFeatureStates(_engine);
-        }
-
         GetBundleFileVersion();
         // don't fail if we couldn't get the version info; best-effort only
     LExit:
index f6cff6fc351dc1837e521ae2146109e92b0d5e0f..ddd6870f62552648a48954c26d9c29acde8cd255 100644 (file)
     <Variable Name="Include_tools" Value="1" bal:Overridable="yes" />
     <Variable Name="Include_tcltk" Value="1" bal:Overridable="yes" />
     <Variable Name="Include_pip" Value="1" bal:Overridable="yes" />
+    <Variable Name="Include_launcher" Value="-1" bal:Overridable="yes" />
     <?if "$(var.PyTestExt)"="" ?>
-    <Variable Name="Include_launcher" Value="1" bal:Overridable="yes" />
     <Variable Name="Include_launcherState" Value="enabled" bal:Overridable="yes" />
     <?else ?>
-    <Variable Name="Include_launcher" Value="0" />
     <Variable Name="Include_launcherState" Value="disable" />
     <?endif ?>
     <Variable Name="Include_symbols" Value="0" bal:Overridable="yes" />
index 07bd9b016d97f805a0e73d5ca8c51c80d7603f9f..d816810d57078d70307cd1a7ffc1d8db5e1c5a2e 100755 (executable)
@@ -45,16 +45,16 @@ OPENSSL_OLD_VERSIONS = [
 ]
 
 OPENSSL_RECENT_VERSIONS = [
-    "1.0.2s",
-    "1.1.0k",
-    "1.1.1c",
+    "1.0.2t",
+    "1.1.0l",
+    "1.1.1d",
 ]
 
 LIBRESSL_OLD_VERSIONS = [
 ]
 
 LIBRESSL_RECENT_VERSIONS = [
-    "2.7.4",
+    "2.9.2",
 ]
 
 # store files in ../multissl
index 2db11e6e86676fe4f2c770907298652bc9038082..0f466db4aa0a8249a1d0addda2ace396ae33e4df 100755 (executable)
--- a/configure
+++ b/configure
@@ -680,10 +680,6 @@ LLVM_PROF_MERGER
 PGO_PROF_USE_FLAG
 PGO_PROF_GEN_FLAG
 LLVM_AR_FOUND
-target_os
-target_vendor
-target_cpu
-target
 LLVM_AR
 DEF_MAKE_RULE
 DEF_MAKE_ALL_RULE
@@ -1459,7 +1455,6 @@ _ACEOF
 System types:
   --build=BUILD     configure for building on BUILD [guessed]
   --host=HOST       cross-compile to build programs to run on HOST [BUILD]
-  --target=TARGET   configure for building compilers for TARGET [HOST]
 _ACEOF
 fi
 
@@ -6486,47 +6481,9 @@ if test "$Py_LTO" = 'true' ; then
   case $CC in
     *clang*)
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
-$as_echo_n "checking target system type... " >&6; }
-if ${ac_cv_target+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$target_alias" = x; then
-  ac_cv_target=$ac_cv_host
-else
-  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
-$as_echo "$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
-  test "$program_prefix$program_suffix$program_transform_name" = \
-    NONENONEs,x,x, &&
-  program_prefix=${target_alias}-
-# Extract the first word of "$target_alias-llvm-ar", so it can be a program name with args.
-set dummy $target_alias-llvm-ar; ac_word=$2
+      if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}llvm-ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}llvm-ar; 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_path_LLVM_AR+:} false; then :
@@ -6565,10 +6522,10 @@ $as_echo "no" >&6; }
 fi
 
 
+fi
 if test -z "$ac_cv_path_LLVM_AR"; then
-  if test "$build" = "$target"; then
-    ac_pt_LLVM_AR=$LLVM_AR
-    # Extract the first word of "llvm-ar", so it can be a program name with args.
+  ac_pt_LLVM_AR=$LLVM_AR
+  # Extract the first word of "llvm-ar", so it can be a program name with args.
 set dummy llvm-ar; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
@@ -6595,7 +6552,6 @@ done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_ac_pt_LLVM_AR" && ac_cv_path_ac_pt_LLVM_AR="''"
   ;;
 esac
 fi
@@ -6608,9 +6564,16 @@ else
 $as_echo "no" >&6; }
 fi
 
-    LLVM_AR=$ac_pt_LLVM_AR
-  else
+  if test "x$ac_pt_LLVM_AR" = x; then
     LLVM_AR="''"
+  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
+    LLVM_AR=$ac_pt_LLVM_AR
   fi
 else
   LLVM_AR="$ac_cv_path_LLVM_AR"
@@ -6682,8 +6645,9 @@ fi
 
 
 
-# Extract the first word of "$target_alias-llvm-profdata", so it can be a program name with args.
-set dummy $target_alias-llvm-profdata; ac_word=$2
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}llvm-profdata", so it can be a program name with args.
+set dummy ${ac_tool_prefix}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_path_LLVM_PROFDATA+:} false; then :
@@ -6722,10 +6686,10 @@ $as_echo "no" >&6; }
 fi
 
 
+fi
 if test -z "$ac_cv_path_LLVM_PROFDATA"; then
-  if test "$build" = "$target"; then
-    ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA
-    # Extract the first word of "llvm-profdata", so it can be a program name with args.
+  ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA
+  # 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; }
@@ -6752,7 +6716,6 @@ done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_ac_pt_LLVM_PROFDATA" && ac_cv_path_ac_pt_LLVM_PROFDATA="''"
   ;;
 esac
 fi
@@ -6765,9 +6728,16 @@ else
 $as_echo "no" >&6; }
 fi
 
-    LLVM_PROFDATA=$ac_pt_LLVM_PROFDATA
-  else
+  if test "x$ac_pt_LLVM_PROFDATA" = x; then
     LLVM_PROFDATA="''"
+  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
+    LLVM_PROFDATA=$ac_pt_LLVM_PROFDATA
   fi
 else
   LLVM_PROFDATA="$ac_cv_path_LLVM_PROFDATA"
@@ -10519,6 +10489,9 @@ then
     $as_echo "#define _REENTRANT 1" >>confdefs.h
 
     posix_threads=yes
+    if test "$ac_sys_system" = "SunOS"; then
+        CFLAGS="$CFLAGS -D_REENTRANT"
+    fi
 elif test "$ac_cv_kpthread" = "yes"
 then
     CC="$CC -Kpthread"
index e5fb7e7b0b136e119fa87fb73de0df41d4049d8d..1ef0df70e686ae61165e231401785fab9691bd99 100644 (file)
@@ -1339,7 +1339,7 @@ if test "$Py_LTO" = 'true' ; then
   case $CC in
     *clang*)
       AC_SUBST(LLVM_AR)
-      AC_PATH_TARGET_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path})
+      AC_PATH_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path})
       AC_SUBST(LLVM_AR_FOUND)
       if test -n "${LLVM_AR}" -a -x "${LLVM_AR}"
       then
@@ -1405,7 +1405,7 @@ AC_SUBST(LLVM_PROF_MERGER)
 AC_SUBST(LLVM_PROF_FILE)
 AC_SUBST(LLVM_PROF_ERR)
 AC_SUBST(LLVM_PROFDATA)
-AC_PATH_TARGET_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path})
+AC_PATH_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path})
 AC_SUBST(LLVM_PROF_FOUND)
 if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}"
 then
@@ -2333,7 +2333,7 @@ if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \
        "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then
   AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1,
   [Defined to enable large file support when an off_t is bigger than a long
-   and long long is available and at least as big as an off_t. You may need
+   and long long is at least as big as an off_t. You may need
    to add some flags for configuration and compilation to enable this mode.
    (For Solaris and Linux, the necessary defines are already defined.)])
   AC_MSG_RESULT(yes)
@@ -3079,6 +3079,9 @@ then
     # Defining _REENTRANT on system with POSIX threads should not hurt.
     AC_DEFINE(_REENTRANT)
     posix_threads=yes
+    if test "$ac_sys_system" = "SunOS"; then
+        CFLAGS="$CFLAGS -D_REENTRANT"
+    fi
 elif test "$ac_cv_kpthread" = "yes"
 then
     CC="$CC -Kpthread"
index 4032fa519f8abb05ccc8c52b204e43baee73766a..d36fc933f48cc206c64b0bd0b98485ef4ccdbdd9 100644 (file)
 #undef HAVE_LANGINFO_H
 
 /* Defined to enable large file support when an off_t is bigger than a long
-   and long long is available and at least as big as an off_t. You may need to
-   add some flags for configuration and compilation to enable this mode. (For
-   Solaris and Linux, the necessary defines are already defined.) */
+   and long long is at least as big as an off_t. You may need to add some
+   flags for configuration and compilation to enable this mode. (For Solaris
+   and Linux, the necessary defines are already defined.) */
 #undef HAVE_LARGEFILE_SUPPORT
 
 /* Define to 1 if you have the 'lchflags' function. */