diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 110dfea8cb98abe..6a807085cc328f0 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -1106,7 +1106,7 @@ Finally it should be mentioned that Capsules offer additional functionality, which is especially useful for memory allocation and deallocation of the pointer stored in a Capsule. The details are described in the Python/C API Reference Manual in the section :ref:`capsules` and in the implementation of Capsules (files -:file:`Include/pycapsule.h` and :file:`Objects/pycapsule.c` in the Python source +:file:`Include/pycapsule.h` and :file:`Objects/capsule.c` in the Python source code distribution). .. rubric:: Footnotes diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 3a75d44f3f7d21b..5aa3d2b0adcbf6e 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1760,6 +1760,10 @@ Blob objects .. versionadded:: 3.11 + .. versionchanged:: next + :class:`Blob` now supports negative-step slices + (e.g. ``blob[9:0:-2]``) for both reading and writing. + A :class:`Blob` instance is a :term:`file-like object` that can read and write data in an SQLite :abbr:`BLOB (Binary Large OBject)`. Call :func:`len(blob) ` to get the size (number of bytes) of the blob. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index a2668a38c6b4a2f..b9781de77860bb2 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1941,7 +1941,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only The interpreter is about to execute a new line of code or re-execute the condition of a loop. The local trace function is called; *arg* is ``None``; the return value specifies the new local trace function. See - :file:`Objects/lnotab_notes.txt` for a detailed explanation of how this + :source:`InternalDocs/code_objects.md` for a detailed explanation of how this works. Per-line events may be disabled for a frame by setting :attr:`~frame.f_trace_lines` to :const:`False` on that diff --git a/Doc/using/android.rst b/Doc/using/android.rst index 60a135693181412..36d82c11d95307e 100644 --- a/Doc/using/android.rst +++ b/Doc/using/android.rst @@ -37,7 +37,7 @@ much easier experience: * `Termux `__ If you're sure you want to do all of this manually, read on. You can use the -:source:`testbed app ` as a guide; each step below contains a +:source:`testbed app ` as a guide; each step below contains a link to the relevant file. * First, acquire a build of Python for Android: @@ -47,10 +47,10 @@ link to the relevant file. mentioned below is at the top level of the package. * Or if you want to build it yourself, follow the instructions in - :source:`Android/README.md`. The ``prefix`` directory will be created under + :source:`Platforms/Android/README.md`. The ``prefix`` directory will be created under :samp:`cross-build/{HOST}`. -* Add code to your :source:`build.gradle ` +* Add code to your :source:`build.gradle ` file to copy the following items into your project. All except your own Python code can be copied from ``prefix/lib``: @@ -65,10 +65,10 @@ link to the relevant file. * ``python*.*/site-packages`` (your own Python code) * Add code to your app to :source:`extract the assets to the filesystem - `. + `. * Add code to your app to :source:`start Python in embedded mode - `. This will need to be C code + `. This will need to be C code called via JNI. Building a Python package for Android diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index fd20ff2cb898107..8b4940ceb9521a7 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -71,7 +71,8 @@ Dependencies to build optional modules are: * - Dependency - Minimum version - Python module - * - `libbz2 `_ + * - `libbz2 `_ or + `libbzip2-rs `_ [1]_ - - :mod:`bz2` * - `libffi `_ @@ -82,47 +83,54 @@ Dependencies to build optional modules are: - :mod:`lzma` * - `libmpdec `_ - 2.5.0 - - :mod:`decimal` [1]_ + - :mod:`decimal` [2]_ * - `libreadline `_ or - `libedit `_ [2]_ + `libedit `_ [3]_ - - :mod:`readline` * - `libuuid `_ - - - ``_uuid`` [3]_ - * - `ncurses `_ [4]_ + - ``_uuid`` [4]_ + * - `ncurses `_ [5]_ - - :mod:`curses` * - `OpenSSL `_ - | 3.0.18 recommended | (1.1.1 minimum) - - :mod:`ssl`, :mod:`hashlib` [5]_ + - :mod:`ssl`, :mod:`hashlib` [6]_ * - `SQLite `_ - 3.15.2 - :mod:`sqlite3` * - `Tcl/Tk `_ - 8.5.12 - :mod:`tkinter`, :ref:`IDLE `, :mod:`turtle` - * - `zlib `_ - - 1.2.2.1 + * - `zlib `_, + `zlib-ng `_, or + `zlib-rs `_ [7]_ + - | 1.2.2.1 (zlib, zlib-ng) + | 0.6.0 (zlib-rs) - :mod:`zlib`, :mod:`gzip`, :mod:`ensurepip` * - `zstd `_ - 1.4.5 - :mod:`compression.zstd` -.. [1] If *libmpdec* is not available, the :mod:`decimal` module will use +.. [1] See :option:`--with-bzip2` for choosing the backend for the + :mod:`bz2` module. +.. [2] If *libmpdec* is not available, the :mod:`decimal` module will use a pure-Python implementation. -.. [2] See :option:`--with-readline` for choosing the backend for the +.. [3] See :option:`--with-readline` for choosing the backend for the :mod:`readline` module. -.. [3] The :mod:`uuid` module uses ``_uuid`` to generate "safe" UUIDs. +.. [4] The :mod:`uuid` module uses ``_uuid`` to generate "safe" UUIDs. See the module documentation for details. -.. [4] The :mod:`curses` module requires the ``libncurses`` or ``libncursesw`` +.. [5] The :mod:`curses` module requires the ``libncurses`` or ``libncursesw`` library. The :mod:`curses.panel` module additionally requires the ``libpanel`` or ``libpanelw`` library. -.. [5] If OpenSSL is not available, the :mod:`hashlib` module will use +.. [6] If OpenSSL is not available, the :mod:`hashlib` module will use bundled implementations of several hash functions. See :option:`--with-builtin-hashlib-hashes` for *forcing* usage of OpenSSL. +.. [7] See :option:`--with-zlib` for choosing the backend for the + :mod:`zlib` module. Note that the table does not include all optional modules; in particular, platform-specific modules like :mod:`winreg` are not listed here. @@ -1113,6 +1121,54 @@ Libraries options .. versionadded:: next +.. option:: --with-zlib=zlib|zlib-ng|zlib-rs + + Designate the zlib implementation to build the :mod:`zlib` module against. + + * ``zlib``: Use the system zlib library, found via ``pkg-config`` or as + ``libz``. + * ``zlib-ng``: Same detection as ``zlib``, but fail unless the detected + library is `zlib-ng `__. + * ``zlib-rs``: Use `zlib-rs + `__, found via + ``pkg-config`` as ``libz_rs``. + + Without this option (or with ``--with-zlib=auto``, the default), the system + zlib is used when found; configure only fails when an implementation was + requested explicitly but cannot be found. + + .. versionadded:: next + +.. option:: --without-zlib + + Don't build the :mod:`zlib` module, even when a zlib library is present + (built by default when one is found). + + .. versionadded:: next + +.. option:: --with-bzip2=bzip2|bzip2-rs + + Designate the bzip2 implementation to build the :mod:`bz2` module against. + + * ``bzip2``: Use the system bzip2 library, found via ``pkg-config`` or as + ``libbz2``. + * ``bzip2-rs``: Use `libbzip2-rs + `__, found via + ``pkg-config`` as ``libbz2_rs``. + + Without this option (or with ``--with-bzip2=auto``, the default), the + system bzip2 is used when found; configure only fails when an + implementation was requested explicitly but cannot be found. + + .. versionadded:: next + +.. option:: --without-bzip2 + + Don't build the :mod:`bz2` module, even when a bzip2 library is present + (built by default when one is found). + + .. versionadded:: next + .. option:: --with-libm=STRING Override ``libm`` math library to *STRING* (default is system-dependent). @@ -1275,7 +1331,7 @@ See :source:`Mac/README.rst`. iOS Options ----------- -See :source:`iOS/README.rst`. +See :source:`Platforms/Apple/iOS/README.md`. .. option:: --enable-framework=INSTALLDIR diff --git a/Doc/using/ios.rst b/Doc/using/ios.rst index 5e4033fb6cec7a0..31d9e2f2c816e73 100644 --- a/Doc/using/ios.rst +++ b/Doc/using/ios.rst @@ -170,7 +170,7 @@ helpful. To add Python to an iOS Xcode project: 1. Build or obtain a Python ``XCFramework``. See the instructions in - :source:`Apple/iOS/README.md` (in the CPython source distribution) for details on + :source:`Platforms/Apple/iOS/README.md` (in the CPython source distribution) for details on how to build a Python ``XCFramework``. At a minimum, you will need a build that supports ``arm64-apple-ios``, plus one of either ``arm64-apple-ios-simulator`` or ``x86_64-apple-ios-simulator``. @@ -266,13 +266,13 @@ modules in your app, some additional steps will be required: Testing a Python package ------------------------ -The CPython source tree contains :source:`a testbed project ` that +The CPython source tree contains :source:`a testbed project ` that is used to run the CPython test suite on the iOS simulator. This testbed can also be used as a testbed project for running your Python library's test suite on iOS. -After building or obtaining an iOS XCFramework (see :source:`Apple/iOS/README.md` +After building or obtaining an iOS XCFramework (see :source:`Platforms/Apple/iOS/README.md` for details), create a clone of the Python iOS testbed project. If you used the -``Apple`` build script to build the XCframework, you can run: +``Platforms/Apple`` build script to build the XCframework, you can run: .. code-block:: bash @@ -282,7 +282,7 @@ Or, if you've sourced your own XCframework, by running: .. code-block:: bash - $ python Apple/testbed clone --platform iOS --framework --app --app app-testbed + $ python Platforms/Apple/testbed clone --platform iOS --framework --app --app app-testbed Any folders specified with the ``--app`` flag will be copied into the cloned testbed project. The resulting testbed will be created in the ``app-testbed`` diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index fc09afc96b16763..063755e1eadcb53 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -466,6 +466,13 @@ shlex a string, even if it is already safe for a shell without being quoted. (Contributed by Jay Berry in :gh:`148846`.) +sqlite3 +------- + +* :class:`sqlite3.Blob` now supports negative-step slices for reading and + writing (e.g. ``blob[9:0:-2]``). Previously, such slices would raise + :exc:`SystemError` or :exc:`ValueError`. + (Contributed by Jiseok CHOI in :gh:`150449`.) symtable -------- @@ -870,6 +877,18 @@ Build changes (Contributed by Serhiy Storchaka in :gh:`136687`.) +* Add the :option:`--with-zlib` and :option:`--with-bzip2` :program:`configure` + options to select the zlib and bzip2 implementations used to build the + :mod:`zlib` and :mod:`bz2` modules. In addition to the default system + libraries, they can build against `zlib-rs + `__ and `libbzip2-rs + `__, and + ``--with-zlib=zlib-ng`` verifies that the detected zlib is `zlib-ng + `__. :option:`--without-zlib` and + :option:`--without-bzip2` exclude the modules from the build. + + (Contributed by Stan Ulbrych in :gh:`139314`.) + C API changes ============= diff --git a/InternalDocs/code_objects.md b/InternalDocs/code_objects.md index cccbe71588622cf..98fa22d66a923c2 100644 --- a/InternalDocs/code_objects.md +++ b/InternalDocs/code_objects.md @@ -48,7 +48,7 @@ Note that traceback objects don't store all this information -- they store the s number, for backward compatibility, and the "last instruction" value. The rest can be computed from the last instruction (`tb_lasti`) with the help of the locations table. For Python code, there is a convenience method -(`codeobject.co_positions`)[https://docs.python.org/dev/reference/datamodel.html#codeobject.co_positions] +[`codeobject.co_positions`](https://docs.python.org/dev/reference/datamodel.html#codeobject.co_positions) which returns an iterator of `({line}, {endline}, {column}, {endcolumn})` tuples, one per instruction. There is also `co_lines()` which returns an iterator of `({start}, {end}, {line})` tuples, diff --git a/InternalDocs/jit.md b/InternalDocs/jit.md index 1345f2db8b34db9..8db5ba3c85ddda6 100644 --- a/InternalDocs/jit.md +++ b/InternalDocs/jit.md @@ -140,7 +140,7 @@ template file [`Tools/jit/template.c`](../Tools/jit/template.c). Each of the `.c` files is compiled by LLVM, to produce an object file that contains a function that executes the opcode. These compiled functions are used to generate the file -[`jit_stencils.h`](../jit_stencils.h), which contains the functions +`jit_stencils.h`, which contains the functions that the JIT can use to emit code for each of the bytecodes. For Python maintainers this means that changes to the bytecodes and diff --git a/Lib/imaplib.py b/Lib/imaplib.py index 139da1d3bb6fb86..24d3a27f21d2d19 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -168,6 +168,8 @@ def _seq_range(item): def _format_sequence_set(arg): + if isinstance(arg, (bytes, bytearray)): + return str(arg, 'ascii') if isinstance(arg, (int, str)): return str(arg) # A sequence of message numbers and ranges. diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 100791a9c3eb2c3..d97da398803681d 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -292,6 +292,8 @@ def test_sequence_set(self): # A scalar is passed through as a string. self.assertEqual(m._sequence_set(5), '5') self.assertEqual(m._sequence_set('1:3,7'), '1:3,7') + self.assertEqual(m._sequence_set(b'1:3,7'), '1:3,7') + self.assertEqual(m._sequence_set(bytearray(b'1:3,7')), '1:3,7') # A sequence of numbers and ranges is formatted as a sequence set. self.assertEqual(m._sequence_set([1, 2, 5]), '1,2,5') self.assertEqual(m._sequence_set([1, (3, 5), (8, '*')]), '1,3:5,8:*') @@ -333,6 +335,7 @@ def test_substitute(self): r'(\Seen \Answered)') # '?s' formats a message sequence set. self.assertEqual(sub('?s', [[1, (3, 5), (8, '*')]]), '1,3:5,8:*') + self.assertEqual(sub('?s', [b'1:3,7']), '1:3,7') # '??' is a literal '?'. self.assertEqual(sub('a?? b', []), 'a? b') @@ -1574,6 +1577,16 @@ def cmd_FETCH(self, tag, args): ]) self.assertEqual(server.args, ['2:4', '(FLAGS)']) + # A preformatted message set may be passed as bytes. + typ, data = client.fetch(b'2:4', '(FLAGS)') + self.assertEqual(typ, 'OK') + self.assertEqual(data, [ + br'2 (FLAGS (\Seen))', + br'3 (FLAGS (\Seen))', + br'4 (FLAGS (\Seen))', + ]) + self.assertEqual(server.args, ['2:4', '(FLAGS)']) + # A comma-separated set with an open range up to '*'. typ, data = client.fetch('1,3:*', '(FLAGS)') self.assertEqual(typ, 'OK') diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 2cf3556f66d9639..c21448a92361d7e 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -1390,6 +1390,19 @@ def test_blob_get_slice_negative_index(self): def test_blob_get_slice_with_skip(self): self.assertEqual(self.blob[0:10:2], b"ti lb") + def test_blob_get_slice_with_negative_step(self): + # gh-150449: negative-step slices must not crash + self.assertEqual(self.blob[9:0:-2], self.data[9:0:-2]) + self.assertEqual(self.blob[9::-2], self.data[9::-2]) + self.assertEqual(self.blob[::-1], self.data[::-1]) + # When start <= stop with a negative step the slice is empty; this + # must return b"" rather than crashing or raising an exception. + self.assertEqual(self.blob[3:8:-1], self.data[3:8:-1]) # b"" + self.assertEqual(self.blob[5:5:-1], self.data[5:5:-1]) # b"" + # Extreme step values: cur += (size_t)step must not overflow. + self.assertEqual(self.blob[5::sys.maxsize], self.data[5::sys.maxsize]) + self.assertEqual(self.blob[::-sys.maxsize - 1], self.data[::-sys.maxsize - 1]) + def test_blob_set_slice(self): self.blob[0:5] = b"12345" expected = b"12345" + self.data[5:] @@ -1430,6 +1443,43 @@ def test_blob_set_slice_with_skip(self): expected = b"1h2s3b4o5 " + self.data[10:] self.assertEqual(actual, expected) + def test_blob_set_slice_with_negative_step(self): + # gh-150449: negative-step slice assignment must not crash + expected = bytearray(self.data) + expected[9:0:-2] = b"12345" + self.blob[9:0:-2] = b"12345" + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, bytes(expected)) + + # Also verify a slice that includes index 0 + expected2 = bytearray(self.data) + expected2[9::-2] = b"12345" + self.blob[9::-2] = b"12345" + actual2 = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual2, bytes(expected2)) + + # When start <= stop with a negative step the slice is empty; + # assigning b"" to it must be a no-op (blob contents unchanged). + state_before = bytes(self.blob[:]) + self.blob[3:8:-1] = b"" + self.assertEqual(bytes(self.blob[:]), state_before) + + def test_blob_set_slice_with_extreme_positive_step(self): + expected = bytearray(self.data) + expected[5::sys.maxsize] = b"\xab" + self.blob[5::sys.maxsize] = b"\xab" + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, bytes(expected)) + self.assertEqual(actual[5], 0xab) + + def test_blob_set_slice_with_extreme_negative_step(self): + expected = bytearray(self.data) + expected[::-sys.maxsize - 1] = b"\xcd" + self.blob[::-sys.maxsize - 1] = b"\xcd" + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, bytes(expected)) + self.assertEqual(actual[-1], 0xcd) + def test_blob_mapping_invalid_index_type(self): msg = "indices must be integers" with self.assertRaisesRegex(TypeError, msg): diff --git a/Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst b/Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst new file mode 100644 index 000000000000000..afc78af0d28fc7a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-09-25-01-33-12.gh-issue-139314._m9BUl.rst @@ -0,0 +1,9 @@ +Add the :option:`--with-zlib` and :option:`--with-bzip2` :program:`configure` +options to select the zlib and bzip2 implementations used to build the +:mod:`zlib` and :mod:`bz2` modules. In addition to the default system +libraries, they can build against `zlib-rs +`__ and `libbzip2-rs +`__, and +``--with-zlib=zlib-ng`` verifies that the detected zlib is `zlib-ng +`__. :option:`--without-zlib` and +:option:`--without-bzip2` exclude the modules from the build. diff --git a/Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst b/Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst new file mode 100644 index 000000000000000..f849fe791356a1b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-26-15-53-50.gh-issue-150449.GfDWxl.rst @@ -0,0 +1,3 @@ +:class:`sqlite3.Blob` now supports negative-step slices for reading and +writing (e.g. ``blob[9:0:-2]``). Previously, such slices would raise +:exc:`SystemError` or :exc:`ValueError`. diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c index 53d28a06181a9c1..a9a98b40bf60b8f 100644 --- a/Modules/_sqlite/blob.c +++ b/Modules/_sqlite/blob.c @@ -454,7 +454,14 @@ subscript_slice(pysqlite_Blob *self, PyObject *item) return read_multiple(self, len, start); } - PyObject *blob = read_multiple(self, stop - start, start); + // Compute the contiguous blob region covering all slice elements, then + // copy each element using the standard size_t-cursor pattern that handles + // both positive and negative steps via unsigned arithmetic. + Py_ssize_t last = start + (len - 1) * step; + Py_ssize_t read_offset = Py_MIN(start, last); + Py_ssize_t read_length = Py_ABS(start - last) + 1; + + PyObject *blob = read_multiple(self, read_length, read_offset); if (blob == NULL) { return NULL; } @@ -465,10 +472,12 @@ subscript_slice(pysqlite_Blob *self, PyObject *item) return NULL; } char *res_buf = PyBytesWriter_GetData(writer); - char *blob_buf = PyBytes_AS_STRING(blob); - for (Py_ssize_t i = 0, j = 0; i < len; i++, j += step) { - res_buf[i] = blob_buf[j]; + + size_t cur; + Py_ssize_t i; + for (cur = (size_t)start, i = 0; i < len; cur += (size_t)step, i++) { + res_buf[i] = blob_buf[(Py_ssize_t)cur - read_offset]; } Py_DECREF(blob); return PyBytesWriter_Finish(writer); @@ -562,28 +571,31 @@ ass_subscript_slice(pysqlite_Blob *self, PyObject *item, PyObject *value) rc = inner_write(self, vbuf.buf, len, start); } else { - /* Read the affected region, patch it and write it back. The - object returned by read_multiple() cannot be used as the buffer, - because for a single byte it is an immortal singleton. */ - Py_ssize_t length = stop - start; - if (length <= 0) { - /* start > stop for a negative step; see gh-150449. */ - PyErr_SetString(PyExc_ValueError, "size must be >= 0"); + /* Compute the contiguous blob region covering all slice elements, + read it, patch each element and write it back. The object + returned by read_multiple() cannot be used as the buffer, because + for a single byte it is an immortal singleton. */ + Py_ssize_t last = start + (len - 1) * step; + Py_ssize_t write_offset = Py_MIN(start, last); + Py_ssize_t write_length = Py_ABS(start - last) + 1; + char *buf = PyMem_Malloc(write_length); + if (buf == NULL) { + PyErr_NoMemory(); } else { - char *buf = PyMem_Malloc(length); - if (buf == NULL) { - PyErr_NoMemory(); - } - else { - if (inner_read(self, buf, length, start) == 0) { - for (Py_ssize_t i = 0, j = 0; i < len; i++, j += step) { - buf[j] = ((char *)vbuf.buf)[i]; - } - rc = inner_write(self, buf, length, start); + if (inner_read(self, buf, write_length, write_offset) == 0) { + /* The size_t cursor handles both positive and negative steps + via unsigned arithmetic. */ + size_t cur; + Py_ssize_t i; + for (cur = (size_t)start, i = 0; i < len; + cur += (size_t)step, i++) { + buf[(Py_ssize_t)cur - write_offset] = + ((char *)vbuf.buf)[i]; } - PyMem_Free(buf); + rc = inner_write(self, buf, write_length, write_offset); } + PyMem_Free(buf); } } PyBuffer_Release(&vbuf); diff --git a/Modules/_zstd/_zstdmodule.c b/Modules/_zstd/_zstdmodule.c index 94246dd93b17de1..c9ed1ff22bdbd7f 100644 --- a/Modules/_zstd/_zstdmodule.c +++ b/Modules/_zstd/_zstdmodule.c @@ -274,7 +274,7 @@ _zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes, PyObject *samples_sizes, Py_ssize_t dict_size) /*[clinic end generated code: output=8e87fe43935e8f77 input=d20dedb21c72cb62]*/ { - PyObject *dst_dict_bytes = NULL; + PyBytesWriter *dst_dict_bytes = NULL; size_t *chunk_sizes = NULL; Py_ssize_t chunks_number; size_t zstd_ret; @@ -294,13 +294,13 @@ _zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes, } /* Allocate dict buffer */ - dst_dict_bytes = PyBytes_FromStringAndSize(NULL, dict_size); + dst_dict_bytes = PyBytesWriter_Create(dict_size); if (dst_dict_bytes == NULL) { goto error; } /* Train the dictionary */ - char *dst_dict_buffer = PyBytes_AS_STRING(dst_dict_bytes); + char *dst_dict_buffer = PyBytesWriter_GetData(dst_dict_bytes); const char *samples_buffer = PyBytes_AS_STRING(samples_bytes); Py_BEGIN_ALLOW_THREADS zstd_ret = ZDICT_trainFromBuffer(dst_dict_buffer, dict_size, @@ -315,19 +315,15 @@ _zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes, goto error; } - /* Resize dict_buffer */ - if (_PyBytes_Resize(&dst_dict_bytes, zstd_ret) < 0) { - goto error; - } + PyMem_Free(chunk_sizes); - goto success; + /* Resize dict_buffer */ + return PyBytesWriter_FinishWithSize(dst_dict_bytes, zstd_ret); error: - Py_CLEAR(dst_dict_bytes); - -success: + PyBytesWriter_Discard(dst_dict_bytes); PyMem_Free(chunk_sizes); - return dst_dict_bytes; + return NULL; } /*[clinic input] diff --git a/configure b/configure index 598a21fb31f7501..ea560d600722592 100755 --- a/configure +++ b/configure @@ -1142,6 +1142,8 @@ with_c_locale_coercion with_valgrind with_dtrace enable_epoll +with_zlib +with_bzip2 with_libm with_libc enable_big_digits @@ -1964,6 +1966,12 @@ Optional Packages: (default is yes) --with-valgrind enable Valgrind support (default is no) --with-dtrace enable DTrace support (default is no) + --with(out)-zlib[=zlib|zlib-ng|zlib-rs|no] + select the zlib implementation to link against, or + disable zlib support (default: auto) + --with(out)-bzip2[=bzip2|bzip2-rs|no] + select the bzip2 implementation to link against, or + disable bzip2 support (default: auto) --with-libm=STRING override libm math library to STRING (default is system-dependent) --with-libc=STRING override libc C library to STRING (default is @@ -22837,6 +22845,30 @@ fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-zlib" >&5 +printf %s "checking for --with-zlib... " >&6; } + +# Check whether --with-zlib was given. +if test ${with_zlib+y} +then : + withval=$with_zlib; case $with_zlib in #( + yes|auto) : + with_zlib=auto ;; #( + zlib|zlib-ng|zlib-rs|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-zlib[=zlib|zlib-ng|zlib-rs|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_zlib=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_zlib" >&5 +printf "%s\n" "$with_zlib" >&6; } + +case $with_zlib in #( + auto|zlib) : @@ -22849,23 +22881,47 @@ then : fi + ;; #( + *) : + ;; +esac + +if test "x$with_zlib" = xzlib-rs +then : + + zlib_name="libz_rs" + zlib_version="0.6.0" + zlib_libname="z_rs" +else case e in #( + e) + zlib_name="zlib" + zlib_version="1.2.2.1" + zlib_libname="z" + ;; +esac +fi +if test "x$with_zlib" = xno +then : + have_zlib=no +else case e in #( + e) pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib >= 1.2.2.1" >&5 -printf %s "checking for zlib >= 1.2.2.1... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $zlib_name >= $zlib_version" >&5 +printf %s "checking for $zlib_name >= $zlib_version... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.2.1\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.2.1") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$zlib_name >= \$zlib_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$zlib_name >= $zlib_version") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.2.1" 2>/dev/null` + pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "$zlib_name >= $zlib_version" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -22877,12 +22933,12 @@ if test -n "$ZLIB_LIBS"; then pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.2.1\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.2.1") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$zlib_name >= \$zlib_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$zlib_name >= $zlib_version") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.2.1" 2>/dev/null` + pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "$zlib_name >= $zlib_version" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -22903,9 +22959,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.2.1" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$zlib_name >= $zlib_version" 2>&1` else - ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.2.1" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$zlib_name >= $zlib_version" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ZLIB_PKG_ERRORS" >&5 @@ -22927,14 +22983,15 @@ then : printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 -printf %s "checking for gzread in -lz... " >&6; } -if test ${ac_cv_lib_z_gzread+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_gzread" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -l$zlib_libname" >&5 +printf %s "checking for gzread in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22958,9 +23015,9 @@ return gzread (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_gzread=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_gzread=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -22968,9 +23025,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 -printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } -if test "x$ac_cv_lib_z_gzread" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_zlib=yes else case e in #( @@ -22991,16 +23049,17 @@ done then : ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 -printf %s "checking for inflateCopy in -lz... " >&6; } -if test ${ac_cv_lib_z_inflateCopy+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_inflateCopy" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -l$zlib_libname" >&5 +printf %s "checking for inflateCopy in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23024,9 +23083,9 @@ return inflateCopy (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_inflateCopy=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_inflateCopy=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23034,9 +23093,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 -printf "%s\n" "$ac_cv_lib_z_inflateCopy" >&6; } -if test "x$ac_cv_lib_z_inflateCopy" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h @@ -23074,14 +23134,15 @@ then : printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 -printf %s "checking for gzread in -lz... " >&6; } -if test ${ac_cv_lib_z_gzread+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_gzread" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -l$zlib_libname" >&5 +printf %s "checking for gzread in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23105,9 +23166,9 @@ return gzread (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_gzread=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_gzread=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23115,9 +23176,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 -printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } -if test "x$ac_cv_lib_z_gzread" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_zlib=yes else case e in #( @@ -23138,16 +23200,17 @@ done then : ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} py_check_lib_save_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 -printf %s "checking for inflateCopy in -lz... " >&6; } -if test ${ac_cv_lib_z_inflateCopy+y} +as_ac_Lib=`printf "%s\n" "ac_cv_lib_$zlib_libname""_inflateCopy" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -l$zlib_libname" >&5 +printf %s "checking for inflateCopy in -l$zlib_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-l$zlib_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23171,9 +23234,9 @@ return inflateCopy (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_z_inflateCopy=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_z_inflateCopy=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23181,9 +23244,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 -printf "%s\n" "$ac_cv_lib_z_inflateCopy" >&6; } -if test "x$ac_cv_lib_z_inflateCopy" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h @@ -23211,8 +23275,53 @@ printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h +fi + ;; +esac fi +if test "x$with_zlib" = xzlib-ng +then : + if test "x$have_zlib" = xyes +then : + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + ac_fn_check_decl "$LINENO" "ZLIBNG_VERSION" "ac_cv_have_decl_ZLIBNG_VERSION" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ZLIBNG_VERSION" = xyes +then : + +else case e in #( + e) as_fn_error $? "--with-zlib=zlib-ng: the detected zlib library is not zlib-ng" "$LINENO" 5 ;; +esac +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi +fi + +case $with_zlib in #( + auto|no) : + ;; #( + *) : + if test "x$have_zlib" = xno +then : + as_fn_error $? "--with-zlib=$with_zlib requested but $zlib_name was not found" "$LINENO" 5 +fi ;; +esac + if test "x$have_zlib" = xyes then : @@ -23221,6 +23330,30 @@ then : fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-bzip2" >&5 +printf %s "checking for --with-bzip2... " >&6; } + +# Check whether --with-bzip2 was given. +if test ${with_bzip2+y} +then : + withval=$with_bzip2; case $with_bzip2 in #( + yes|auto) : + with_bzip2=auto ;; #( + bzip2|bzip2-rs|no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-bzip2[=bzip2|bzip2-rs|no]" "$LINENO" 5 ;; +esac +else case e in #( + e) with_bzip2=auto ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_bzip2" >&5 +printf "%s\n" "$with_bzip2" >&6; } + +case $with_bzip2 in #( + auto|bzip2) : @@ -23233,23 +23366,45 @@ then : fi + ;; #( + *) : + ;; +esac + +if test "x$with_bzip2" = xbzip2-rs +then : + + bzip2_name="libbz2_rs" + bzip2_libname="bz2_rs" +else case e in #( + e) + bzip2_name="bzip2" + bzip2_libname="bz2" + ;; +esac +fi +if test "x$with_bzip2" = xno +then : + have_bzip2=no +else case e in #( + e) pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bzip2" >&5 -printf %s "checking for bzip2... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $bzip2_name" >&5 +printf %s "checking for $bzip2_name... " >&6; } if test -n "$BZIP2_CFLAGS"; then pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 - ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$bzip2_name\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$bzip2_name") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "bzip2" 2>/dev/null` + pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "$bzip2_name" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -23261,12 +23416,12 @@ if test -n "$BZIP2_LIBS"; then pkg_cv_BZIP2_LIBS="$BZIP2_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 - ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$bzip2_name\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$bzip2_name") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "bzip2" 2>/dev/null` + pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "$bzip2_name" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -23287,9 +23442,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` + BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$bzip2_name" 2>&1` else - BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` + BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$bzip2_name" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$BZIP2_PKG_ERRORS" >&5 @@ -23310,14 +23465,15 @@ if test "x$ac_cv_header_bzlib_h" = xyes then : printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 -printf %s "checking for BZ2_bzCompress in -lbz2... " >&6; } -if test ${ac_cv_lib_bz2_BZ2_bzCompress+y} + as_ac_Lib=`printf "%s\n" "ac_cv_lib_$bzip2_libname""_BZ2_bzCompress" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -l$bzip2_libname" >&5 +printf %s "checking for BZ2_bzCompress in -l$bzip2_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" +LIBS="-l$bzip2_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23341,9 +23497,9 @@ return BZ2_bzCompress (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_bz2_BZ2_bzCompress=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_bz2_BZ2_bzCompress=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23351,9 +23507,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 -printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_bzip2=yes else case e in #( @@ -23372,7 +23529,7 @@ done then : BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} fi @@ -23402,14 +23559,15 @@ if test "x$ac_cv_header_bzlib_h" = xyes then : printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 -printf %s "checking for BZ2_bzCompress in -lbz2... " >&6; } -if test ${ac_cv_lib_bz2_BZ2_bzCompress+y} + as_ac_Lib=`printf "%s\n" "ac_cv_lib_$bzip2_libname""_BZ2_bzCompress" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -l$bzip2_libname" >&5 +printf %s "checking for BZ2_bzCompress in -l$bzip2_libname... " >&6; } +if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" +LIBS="-l$bzip2_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23433,9 +23591,9 @@ return BZ2_bzCompress (); _ACEOF if ac_fn_c_try_link "$LINENO" then : - ac_cv_lib_bz2_BZ2_bzCompress=yes + eval "$as_ac_Lib=yes" else case e in #( - e) ac_cv_lib_bz2_BZ2_bzCompress=no ;; + e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ @@ -23443,9 +23601,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$ac_check_lib_save_LIBS ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 -printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes +eval ac_res=\$$as_ac_Lib + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : have_bzip2=yes else case e in #( @@ -23464,7 +23623,7 @@ done then : BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} fi @@ -23482,6 +23641,19 @@ else printf "%s\n" "yes" >&6; } have_bzip2=yes fi + ;; +esac +fi + +case $with_bzip2 in #( + auto|no) : + ;; #( + *) : + if test "x$have_bzip2" = xno +then : + as_fn_error $? "--with-bzip2=$with_bzip2 requested but $bzip2_name was not found" "$LINENO" 5 +fi ;; +esac pkg_failed=no diff --git a/configure.ac b/configure.ac index 47c5f7e49422a5d..7dfc6ca29297a8b 100644 --- a/configure.ac +++ b/configure.ac @@ -5706,10 +5706,34 @@ fi dnl Check for compression libraries AH_TEMPLATE([HAVE_ZLIB_COPY], [Define if the zlib library has inflateCopy]) +AC_MSG_CHECKING([for --with-zlib]) +AC_ARG_WITH( + [zlib], + [AS_HELP_STRING([--with(out)-zlib@<:@=zlib|zlib-ng|zlib-rs|no@:>@], + [select the zlib implementation to link against, or disable + zlib support (default: auto)])], + [AS_CASE([$with_zlib], + [yes|auto], [with_zlib=auto], + [zlib|zlib-ng|zlib-rs|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-zlib@<:@=zlib|zlib-ng|zlib-rs|no@:>@])])], + [with_zlib=auto]) +AC_MSG_RESULT([$with_zlib]) + dnl detect zlib from Emscripten emport -PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB]) +AS_CASE([$with_zlib], [auto|zlib], [PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB])]) + +AS_VAR_IF([with_zlib], [zlib-rs], [ + AS_VAR_SET([zlib_name], ["libz_rs"]) + AS_VAR_SET([zlib_version], ["0.6.0"]) + AS_VAR_SET([zlib_libname], ["z_rs"]) +], [ + AS_VAR_SET([zlib_name], ["zlib"]) + AS_VAR_SET([zlib_version], ["1.2.2.1"]) + AS_VAR_SET([zlib_libname], ["z"]) +]) -PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.2.1], [ +AS_VAR_IF([with_zlib], [no], [have_zlib=no], [ +PKG_CHECK_MODULES([ZLIB], [$zlib_name >= $zlib_version], [ have_zlib=yes dnl zlib 1.2.0 (2003) added inflateCopy AC_DEFINE([HAVE_ZLIB_COPY], [1]) @@ -5718,15 +5742,30 @@ PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.2.1], [ CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" LIBS="$LIBS $ZLIB_LIBS" AC_CHECK_HEADERS([zlib.h], [ - PY_CHECK_LIB([z], [gzread], [have_zlib=yes], [have_zlib=no]) + PY_CHECK_LIB([$zlib_libname], [gzread], [have_zlib=yes], [have_zlib=no]) ], [have_zlib=no]) AS_VAR_IF([have_zlib], [yes], [ ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} - PY_CHECK_LIB([z], [inflateCopy], [AC_DEFINE([HAVE_ZLIB_COPY], [1])]) + ZLIB_LIBS=${ZLIB_LIBS-"-l$zlib_libname"} + PY_CHECK_LIB([$zlib_libname], [inflateCopy], [AC_DEFINE([HAVE_ZLIB_COPY], [1])]) ]) ]) ]) +]) + +AS_VAR_IF([with_zlib], [zlib-ng], [AS_VAR_IF([have_zlib], [yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + AC_CHECK_DECL([ZLIBNG_VERSION], [], + [AC_MSG_ERROR([--with-zlib=zlib-ng: the detected zlib library is not zlib-ng])], + [@%:@include ]) + ]) +])]) + +AS_CASE([$with_zlib], + [auto|no], [], + [AS_VAR_IF([have_zlib], [no], + [AC_MSG_ERROR([--with-zlib=$with_zlib requested but $zlib_name was not found])])]) dnl binascii can use zlib for optimized crc32. AS_VAR_IF([have_zlib], [yes], [ @@ -5734,22 +5773,50 @@ AS_VAR_IF([have_zlib], [yes], [ BINASCII_LIBS="$ZLIB_LIBS" ]) +AC_MSG_CHECKING([for --with-bzip2]) +AC_ARG_WITH( + [bzip2], + [AS_HELP_STRING([--with(out)-bzip2@<:@=bzip2|bzip2-rs|no@:>@], + [select the bzip2 implementation to link against, or disable + bzip2 support (default: auto)])], + [AS_CASE([$with_bzip2], + [yes|auto], [with_bzip2=auto], + [bzip2|bzip2-rs|no], [], + [AC_MSG_ERROR([proper usage is --with(out)-bzip2@<:@=bzip2|bzip2-rs|no@:>@])])], + [with_bzip2=auto]) +AC_MSG_RESULT([$with_bzip2]) + dnl detect bzip2 from Emscripten emport -PY_CHECK_EMSCRIPTEN_PORT([BZIP2], [-sUSE_BZIP2]) +AS_CASE([$with_bzip2], [auto|bzip2], [PY_CHECK_EMSCRIPTEN_PORT([BZIP2], [-sUSE_BZIP2])]) -PKG_CHECK_MODULES([BZIP2], [bzip2], [have_bzip2=yes], [ +AS_VAR_IF([with_bzip2], [bzip2-rs], [ + AS_VAR_SET([bzip2_name], ["libbz2_rs"]) + AS_VAR_SET([bzip2_libname], ["bz2_rs"]) +], [ + AS_VAR_SET([bzip2_name], ["bzip2"]) + AS_VAR_SET([bzip2_libname], ["bz2"]) +]) + +AS_VAR_IF([with_bzip2], [no], [have_bzip2=no], [ +PKG_CHECK_MODULES([BZIP2], [$bzip2_name], [have_bzip2=yes], [ WITH_SAVE_ENV([ CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" LIBS="$LIBS $BZIP2_LIBS" AC_CHECK_HEADERS([bzlib.h], [ - AC_CHECK_LIB([bz2], [BZ2_bzCompress], [have_bzip2=yes], [have_bzip2=no]) + AC_CHECK_LIB([$bzip2_libname], [BZ2_bzCompress], [have_bzip2=yes], [have_bzip2=no]) ], [have_bzip2=no]) AS_VAR_IF([have_bzip2], [yes], [ BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + BZIP2_LIBS=${BZIP2_LIBS-"-l$bzip2_libname"} ]) ]) ]) +]) + +AS_CASE([$with_bzip2], + [auto|no], [], + [AS_VAR_IF([have_bzip2], [no], + [AC_MSG_ERROR([--with-bzip2=$with_bzip2 requested but $bzip2_name was not found])])]) PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ WITH_SAVE_ENV([