From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Juan =?utf-8?Q?Jos=C3=A9_Garc=C3=ADa-Ripoll?= Newsgroups: gmane.emacs.devel Subject: decompress.c now also compresses Date: Sun, 29 Mar 2020 17:52:03 +0200 Message-ID: <86zhbz17mk.fsf@csic.es> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="100123"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (windows-nt) To: emacs-devel@gnu.org Cancel-Lock: sha1:Y442TlWpobfe4teZ5hBNR/4irl4= Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Mar 29 17:52:54 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jIaF4-000Pwq-0a for ged-emacs-devel@m.gmane-mx.org; Sun, 29 Mar 2020 17:52:54 +0200 Original-Received: from localhost ([::1]:38892 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jIaF3-0007xW-3B for ged-emacs-devel@m.gmane-mx.org; Sun, 29 Mar 2020 11:52:53 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42359) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jIaEQ-0007Py-RW for emacs-devel@gnu.org; Sun, 29 Mar 2020 11:52:17 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jIaEN-0000eM-U5 for emacs-devel@gnu.org; Sun, 29 Mar 2020 11:52:14 -0400 Original-Received: from ciao.gmane.io ([159.69.161.202]:48104) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jIaEN-0000dZ-GN for emacs-devel@gnu.org; Sun, 29 Mar 2020 11:52:11 -0400 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1jIaEL-000PF2-SX for emacs-devel@gnu.org; Sun, 29 Mar 2020 17:52:09 +0200 X-Injected-Via-Gmane: http://gmane.org/ X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 159.69.161.202 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:245941 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Hi, I attach a patch that adds support for compressing buffers using zlib. It is a minor extension to the file src/decompress.c but it may be useful because of two reasons (i) in Windows, Emasc is shipped without g[un]zip.exe, (ii) the whole process of compression takes about 20 times less time than calling gzip. (benchmark 1 '(mapc 'simple-zlib-compress (directory-files "~/emacs-build/git/emacs-27/lisp/" t ".*\\.el"))) ;; => Elapsed time: 2.602588s (0.014894s in 1 GCs) (benchmark 1 '(mapc 'simple-gzip-compress (directory-files "~/emacs-build/git/emacs-27/lisp/" t ".*\\.el"))) ;; => Elapsed time: 61.986128s (0.039815s in 3 GCs) I attach a patch that was produced against emacs-27 but also seems to work against emacs-28 (at least the decompress.c part, I am unsure about how NEWS should be edited). I also attach a lisp file that test and benchmark the compression/decompression using Emacs' lisp sources. Best Juanjo -- Juan José García Ripoll http://juanjose.garciaripoll.com http://quinfog.hbar.es --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=decompress.diff Content-Transfer-Encoding: 8bit diff --git a/etc/NEWS b/etc/NEWS index d3f27e3..96ddf5c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3656,6 +3656,10 @@ easier to undo immediately afterwards. ** When called interactively, 'next-buffer' and 'previous-buffer' now signal 'user-error' if there is no buffer to switch to. +--- +** New function 'zlib-compress-region' compresses a unibyte buffer region using +gzip's format, via the zlib library. + * Changes in Emacs 27.1 on Non-Free Operating Systems diff --git a/src/decompress.c b/src/decompress.c index 5d24638..68178db 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -1,247 +1,394 @@ -/* Interface to zlib. - Copyright (C) 2013-2020 Free Software Foundation, Inc. - -This file is part of GNU Emacs. - -GNU Emacs is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or (at -your option) any later version. - -GNU Emacs is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Emacs. If not, see . */ - -#include - -#ifdef HAVE_ZLIB - -#include - -#include "lisp.h" -#include "buffer.h" -#include "composite.h" - -#include - -#ifdef WINDOWSNT -# include -# include "w32common.h" -# include "w32.h" - -DEF_DLL_FN (int, inflateInit2_, - (z_streamp strm, int windowBits, const char *version, - int stream_size)); -DEF_DLL_FN (int, inflate, (z_streamp strm, int flush)); -DEF_DLL_FN (int, inflateEnd, (z_streamp strm)); - -static bool zlib_initialized; - -static bool -init_zlib_functions (void) -{ - HMODULE library = w32_delayed_load (Qzlib); - - if (!library) - return false; - - LOAD_DLL_FN (library, inflateInit2_); - LOAD_DLL_FN (library, inflate); - LOAD_DLL_FN (library, inflateEnd); - return true; -} - -# undef inflate -# undef inflateEnd -# undef inflateInit2_ - -# define inflate fn_inflate -# define inflateEnd fn_inflateEnd -# define inflateInit2_ fn_inflateInit2_ - -#endif /* WINDOWSNT */ - - -struct decompress_unwind_data -{ - ptrdiff_t old_point, orig, start, nbytes; - z_stream *stream; -}; - -static void -unwind_decompress (void *ddata) -{ - struct decompress_unwind_data *data = ddata; - inflateEnd (data->stream); - - /* Delete any uncompressed data already inserted on error, but - without calling the change hooks. */ - if (data->start) - { - del_range_2 (data->start, data->start, /* byte, char offsets the same */ - data->start + data->nbytes, data->start + data->nbytes, - 0); - update_compositions (data->start, data->start, CHECK_HEAD); - /* "Balance" the before-change-functions call, which would - otherwise be left "hanging". */ - signal_after_change (data->orig, data->start - data->orig, - data->start - data->orig); - } - /* Put point where it was, or if the buffer has shrunk because the - compressed data is bigger than the uncompressed, at - point-max. */ - SET_PT (min (data->old_point, ZV)); -} - -DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, - doc: /* Return t if zlib decompression is available in this instance of Emacs. */) - (void) -{ -#ifdef WINDOWSNT - Lisp_Object found = Fassq (Qzlib, Vlibrary_cache); - if (CONSP (found)) - return XCDR (found); - else - { - Lisp_Object status; - zlib_initialized = init_zlib_functions (); - status = zlib_initialized ? Qt : Qnil; - Vlibrary_cache = Fcons (Fcons (Qzlib, status), Vlibrary_cache); - return status; - } -#else - return Qt; -#endif -} - -DEFUN ("zlib-decompress-region", Fzlib_decompress_region, - Szlib_decompress_region, - 2, 3, 0, - doc: /* Decompress a gzip- or zlib-compressed region. -Replace the text in the region by the decompressed data. - -If optional parameter ALLOW-PARTIAL is nil or omitted, then on -failure, return nil and leave the data in place. Otherwise, return -the number of bytes that were not decompressed and replace the region -text by whatever data was successfully decompressed (similar to gzip). -If decompression is completely successful return t. - -This function can be called only in unibyte buffers. */) - (Lisp_Object start, Lisp_Object end, Lisp_Object allow_partial) -{ - ptrdiff_t istart, iend, pos_byte; - z_stream stream; - int inflate_status; - struct decompress_unwind_data unwind_data; - ptrdiff_t count = SPECPDL_INDEX (); - - validate_region (&start, &end); - - if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) - error ("This function can be called only in unibyte buffers"); - -#ifdef WINDOWSNT - if (!zlib_initialized) - zlib_initialized = init_zlib_functions (); - if (!zlib_initialized) - { - message1 ("zlib library not found"); - return Qnil; - } -#endif - - /* This is a unibyte buffer, so character positions and bytes are - the same. */ - istart = XFIXNUM (start); - iend = XFIXNUM (end); - - /* Do the following before manipulating the gap. */ - modify_text (istart, iend); - - move_gap_both (iend, iend); - - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = 0; - stream.next_in = Z_NULL; - - /* The magic number 32 apparently means "autodetect both the gzip and - zlib formats" according to zlib.h. */ - if (inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) - return Qnil; - - unwind_data.orig = istart; - unwind_data.start = iend; - unwind_data.stream = &stream; - unwind_data.old_point = PT; - unwind_data.nbytes = 0; - record_unwind_protect_ptr (unwind_decompress, &unwind_data); - - /* Insert the decompressed data at the end of the compressed data. */ - SET_PT (iend); - - pos_byte = istart; - - /* Keep calling 'inflate' until it reports an error or end-of-input. */ - do - { - /* Maximum number of bytes that one 'inflate' call should read and write. - Do not make avail_out too large, as that might unduly delay C-g. - zlib requires that avail_in and avail_out not exceed UINT_MAX. */ - ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); - int avail_out = 16 * 1024; - int decompressed; - - if (GAP_SIZE < avail_out) - make_gap (avail_out - GAP_SIZE); - stream.next_in = BYTE_POS_ADDR (pos_byte); - stream.avail_in = avail_in; - stream.next_out = GPT_ADDR; - stream.avail_out = avail_out; - inflate_status = inflate (&stream, Z_NO_FLUSH); - pos_byte += avail_in - stream.avail_in; - decompressed = avail_out - stream.avail_out; - insert_from_gap (decompressed, decompressed, 0); - unwind_data.nbytes += decompressed; - maybe_quit (); - } - while (inflate_status == Z_OK); - - Lisp_Object ret = Qt; - if (inflate_status != Z_STREAM_END) - { - if (!NILP (allow_partial)) - ret = make_int (iend - pos_byte); - else - return unbind_to (count, Qnil); - } - - unwind_data.start = 0; - - /* Delete the compressed data. */ - del_range_2 (istart, istart, /* byte and char offsets are the same. */ - iend, iend, 0); - - signal_after_change (istart, iend - istart, unwind_data.nbytes); - update_compositions (istart, istart, CHECK_HEAD); - - return unbind_to (count, ret); -} - - -/*********************************************************************** - Initialization - ***********************************************************************/ -void -syms_of_decompress (void) -{ - defsubr (&Szlib_decompress_region); - defsubr (&Szlib_available_p); -} - -#endif /* HAVE_ZLIB */ +/* Interface to zlib. + Copyright (C) 2013-2020 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see . */ + +#include + +#ifdef HAVE_ZLIB + +#include + +#include "lisp.h" +#include "buffer.h" +#include "composite.h" + +#include + +#ifdef WINDOWSNT +# include +# include "w32common.h" +# include "w32.h" + +/* We import inflateInit2_ and deflateInit2_ because inflateInit and + deflateInit are macros defined on top of these symbols by zlib.h */ +DEF_DLL_FN (int, inflateInit2_, + (z_streamp strm, int windowBits, const char *version, + int stream_size)); +DEF_DLL_FN (int, inflate, (z_streamp strm, int flush)); +DEF_DLL_FN (int, inflateEnd, (z_streamp strm)); +DEF_DLL_FN (int, deflateInit2_, + (z_streamp strm, int level, int method, int windowBits, + int memLevel, int strategy, const char *version, + int stream_size)); +DEF_DLL_FN (int, deflateInit2_, + (z_streamp strm, int level, int method, int windowBits, + int memLevel, int strategy, const char *version, + int stream_size)); +DEF_DLL_FN (int, deflate, (z_streamp strm, int flush)); +DEF_DLL_FN (int, deflateEnd, (z_streamp strm)); + +static bool zlib_initialized; + +static bool +init_zlib_functions (void) +{ + HMODULE library = w32_delayed_load (Qzlib); + + if (!library) + return false; + + LOAD_DLL_FN (library, inflateInit2_); + LOAD_DLL_FN (library, inflate); + LOAD_DLL_FN (library, inflateEnd); + LOAD_DLL_FN (library, deflateInit2_); + LOAD_DLL_FN (library, deflate); + LOAD_DLL_FN (library, deflateEnd); + return true; +} + +# undef inflate +# undef inflateEnd +# undef inflateInit2_ +# undef deflate +# undef deflateEnd +# undef deflateInit2_ + +# define inflate fn_inflate +# define inflateEnd fn_inflateEnd +# define inflateInit2_ fn_inflateInit2_ +# define deflate fn_deflate +# define deflateEnd fn_deflateEnd +# define deflateInit2_ fn_deflateInit2_ + +#endif /* WINDOWSNT */ + + +struct decompress_unwind_data +{ + ptrdiff_t old_point, orig, start, nbytes; + z_stream *stream; + int deflating; +}; + +static void +unwind_zlib (void *ddata) +{ + struct decompress_unwind_data *data = ddata; + (data->deflating? deflateEnd : inflateEnd) (data->stream); + + /* Delete any uncompressed data already inserted on error, but + without calling the change hooks. */ + if (data->start) + { + del_range_2 (data->start, data->start, /* byte, char offsets the same */ + data->start + data->nbytes, data->start + data->nbytes, + 0); + update_compositions (data->start, data->start, CHECK_HEAD); + /* "Balance" the before-change-functions call, which would + otherwise be left "hanging". */ + signal_after_change (data->orig, data->start - data->orig, + data->start - data->orig); + } + /* Put point where it was, or if the buffer has shrunk because the + compressed data is bigger than the uncompressed, at + point-max. */ + SET_PT (min (data->old_point, ZV)); +} + +DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, + doc: /* Return t if zlib decompression is available in this instance of Emacs. */) + (void) +{ +#ifdef WINDOWSNT + Lisp_Object found = Fassq (Qzlib, Vlibrary_cache); + if (CONSP (found)) + return XCDR (found); + else + { + Lisp_Object status; + zlib_initialized = init_zlib_functions (); + status = zlib_initialized ? Qt : Qnil; + Vlibrary_cache = Fcons (Fcons (Qzlib, status), Vlibrary_cache); + return status; + } +#else + return Qt; +#endif +} + +DEFUN ("zlib-decompress-region", Fzlib_decompress_region, + Szlib_decompress_region, + 2, 3, 0, + doc: /* Decompress a gzip- or zlib-compressed region. +Replace the text in the region by the decompressed data. + +If optional parameter ALLOW-PARTIAL is nil or omitted, then on +failure, return nil and leave the data in place. Otherwise, return +the number of bytes that were not decompressed and replace the region +text by whatever data was successfully decompressed (similar to gzip). +If decompression is completely successful return t. + +This function can be called only in unibyte buffers. */) + (Lisp_Object start, Lisp_Object end, Lisp_Object allow_partial) +{ + ptrdiff_t istart, iend, pos_byte; + z_stream stream; + int inflate_status; + struct decompress_unwind_data unwind_data; + ptrdiff_t count = SPECPDL_INDEX (); + + validate_region (&start, &end); + + if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) + error ("This function can be called only in unibyte buffers"); + +#ifdef WINDOWSNT + if (!zlib_initialized) + zlib_initialized = init_zlib_functions (); + if (!zlib_initialized) + { + message1 ("zlib library not found"); + return Qnil; + } +#endif + + /* This is a unibyte buffer, so character positions and bytes are + the same. */ + istart = XFIXNUM (start); + iend = XFIXNUM (end); + + /* Do the following before manipulating the gap. */ + modify_text (istart, iend); + + move_gap_both (iend, iend); + + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = 0; + stream.next_in = Z_NULL; + + /* The magic number 32 apparently means "autodetect both the gzip and + zlib formats" according to zlib.h. */ + if (inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) + return Qnil; + + unwind_data.orig = istart; + unwind_data.start = iend; + unwind_data.stream = &stream; + unwind_data.old_point = PT; + unwind_data.nbytes = 0; + unwind_data.deflating = 0; + record_unwind_protect_ptr (unwind_zlib, &unwind_data); + + /* Insert the decompressed data at the end of the compressed data. */ + SET_PT (iend); + + pos_byte = istart; + + /* Keep calling 'inflate' until it reports an error or end-of-input. */ + do + { + /* Maximum number of bytes that one 'inflate' call should read and write. + Do not make avail_out too large, as that might unduly delay C-g. + zlib requires that avail_in and avail_out not exceed UINT_MAX. */ + ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); + int avail_out = 16 * 1024; + int decompressed; + + if (GAP_SIZE < avail_out) + make_gap (avail_out - GAP_SIZE); + stream.next_in = BYTE_POS_ADDR (pos_byte); + stream.avail_in = avail_in; + stream.next_out = GPT_ADDR; + stream.avail_out = avail_out; + inflate_status = inflate (&stream, Z_NO_FLUSH); + pos_byte += avail_in - stream.avail_in; + decompressed = avail_out - stream.avail_out; + insert_from_gap (decompressed, decompressed, 0); + unwind_data.nbytes += decompressed; + maybe_quit (); + } + while (inflate_status == Z_OK); + + Lisp_Object ret = Qt; + if (inflate_status != Z_STREAM_END) + { + if (!NILP (allow_partial)) + ret = make_int (iend - pos_byte); + else + return unbind_to (count, Qnil); + } + + unwind_data.start = 0; + + /* Delete the compressed data. */ + del_range_2 (istart, istart, /* byte and char offsets are the same. */ + iend, iend, 0); + + signal_after_change (istart, iend - istart, unwind_data.nbytes); + update_compositions (istart, istart, CHECK_HEAD); + + return unbind_to (count, ret); +} + + +DEFUN ("zlib-compress-region", Fzlib_compress_region, + Szlib_compress_region, + 2, 3, 0, + doc: /* Compress a region to a gzip or zlib stream. +Replace the text in the region by the compressed data. + +If optional parameter NO-WRAPPER is nil or omitted, use the GZIP +wrapper format; otherwise, output just a deflated stream of +bytes. If decompression is completely successful return t. + +This function can be called only in unibyte buffers.*/) + (Lisp_Object start, Lisp_Object end, Lisp_Object zlib) +{ + ptrdiff_t istart, iend, pos_byte; + z_stream stream; + int deflate_status, flush; + struct decompress_unwind_data unwind_data; + ptrdiff_t count = SPECPDL_INDEX (); + bool gzipp = NILP (zlib); + + validate_region (&start, &end); + + if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) + error ("This function can be called only in unibyte buffers"); + +#ifdef WINDOWSNT + if (!zlib_initialized) + zlib_initialized = init_zlib_functions (); + if (!zlib_initialized) + { + message1 ("zlib library not found"); + return Qnil; + } +#endif + + /* This is a unibyte buffer, so character positions and bytes are + the same. */ + istart = XFIXNUM (start); + iend = XFIXNUM (end); + + /* Do the following before manipulating the gap. */ + modify_text (istart, iend); + + move_gap_both (iend, iend); + + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = 0; + stream.next_in = Z_NULL; + + /* Initiate the deflate() process, choosing the format, compression + strategy and level (9), and amount of memory used. */ + if (deflateInit2 (&stream, 9, Z_DEFLATED, MAX_WBITS + (gzipp? 16: 0), + 8, Z_DEFAULT_STRATEGY) != Z_OK) + return Qnil; + + unwind_data.orig = istart; + unwind_data.start = iend; + unwind_data.stream = &stream; + unwind_data.old_point = PT; + unwind_data.nbytes = 0; + unwind_data.deflating = 1; + record_unwind_protect_ptr (unwind_zlib, &unwind_data); + + /* Insert the decompressed data at the end of the compressed data. */ + SET_PT (iend); + + pos_byte = istart; + + /* Keep calling 'deflate' until it reports an error or end-of-input. */ + flush = Z_NO_FLUSH; + do + { + /* Maximum number of bytes that one 'deflate' call should read and write. + Do not make avail_out too large, as that might unduly delay C-g. + zlib requires that avail_in and avail_out not exceed UINT_MAX. */ + ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); + int avail_out = 16 * 1024; + int compressed; + + if (GAP_SIZE < avail_out) + make_gap (avail_out - GAP_SIZE); + stream.next_in = BYTE_POS_ADDR (pos_byte); + stream.avail_in = avail_in; + stream.next_out = GPT_ADDR; + stream.avail_out = avail_out; + deflate_status = deflate (&stream, flush); + + pos_byte += avail_in - stream.avail_in; + compressed = avail_out - stream.avail_out; + insert_from_gap (compressed, compressed, 0); + unwind_data.nbytes += compressed; + if (deflate_status == Z_BUF_ERROR && flush == Z_NO_FLUSH) { + /* When we run out of input, zlib returns Z_BUF_ERROR. + We then have to flush all output. */ + flush = Z_FINISH; + deflate_status = Z_OK; + } + maybe_quit (); + } + while (deflate_status == Z_OK); + + Lisp_Object ret = Qt; + if (deflate_status != Z_STREAM_END) + { + /* When compression did not succeed, delete output. */ + ret = make_int (iend - pos_byte); + } + + unwind_data.start = 0; + + /* Delete the uncompressed data. */ + del_range_2 (istart, istart, /* byte and char offsets are the same. */ + iend, iend, 0); + + signal_after_change (istart, iend - istart, unwind_data.nbytes); + update_compositions (istart, istart, CHECK_HEAD); + + return unbind_to (count, ret); +} + + +/*********************************************************************** + Initialization + ***********************************************************************/ +void +syms_of_decompress (void) +{ + defsubr (&Szlib_decompress_region); + defsubr (&Szlib_compress_region); + defsubr (&Szlib_available_p); +} + +#endif /* HAVE_ZLIB */ --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=test.lisp Content-Transfer-Encoding: base64 KHN3aXRjaC10by1idWZmZXIgIipNZXNzYWdlcyoiKQ0KDQooc2V0cSBkZWJ1Zy1vbi1lcnJvciB0 KQ0KDQooZGVmdW4gdGVzdC16bGliLWNvbXByZXNzIChmaWxlbmFtZSAmb3B0aW9uYWwgc2hvdy1k aWZmKQ0KICAiVGVzdCBjb21wcmVzc2lvbiBwYXNzaW5nIHRoZSBvdXRwdXQgb2YgemxpYi1jb21w cmVzcy1yZWdpb24gdG8NCmd6aXAgLWQgYW5kIGNvbXBhcmluZyB0aGUgb3V0cHV0LiBJZiBTSE9X LURJRkYgaXMgbm90IG5pbCwgc2F2ZSB0aGUNCmZhaWxpbmcgZmlsZXMgYW5kIG91dHB1dCBhIGRp ZmYuDQoNClJldHVybnMgVCBvbiBzdWNjZXNzLCBOSUwgb24gZmFpbHVyZSBvZiB0aGUgY29tcGFy aXNvbi4iDQogICh3aXRoLXRlbXAtYnVmZmVyDQogICAgKHNldC1idWZmZXItbXVsdGlieXRlIG5p bCkNCiAgICAoaW5zZXJ0LWZpbGUtY29udGVudHMtbGl0ZXJhbGx5IGZpbGVuYW1lIG5pbCBuaWwg bmlsIHQpDQogICAgKGxldCAoKGItemxpYiAoY3VycmVudC1idWZmZXIpKQ0KICAgICAgICAgIChz LW9yaWcgKGJ1ZmZlci1zdHJpbmcpKQ0KICAgICAgICAgIChjb2RpbmcgYnVmZmVyLWZpbGUtY29k aW5nLXN5c3RlbSkpDQogICAgICAodW5sZXNzICh6bGliLWNvbXByZXNzLXJlZ2lvbiAocG9pbnQt bWluKSAocG9pbnQtbWF4KSkNCiAgICAgICAgKGVycm9yICJGYWlsZWQgdG8gY29tcHJlc3MgJXMi IGZpbGVuYW1lKSkNCiAgICAgICh3aXRoLXRlbXAtYnVmZmVyDQogICAgICAgIChsZXQgKChiLWd1 bnppcHBlZCAoY3VycmVudC1idWZmZXIpKSkNCiAgICAgICAgICAoc2V0LWJ1ZmZlci1tdWx0aWJ5 dGUgbmlsKQ0KICAgICAgICAgICh3aXRoLWN1cnJlbnQtYnVmZmVyIGItemxpYg0KICAgICAgICAg ICAgKGxldCAoKGNvZGluZy1zeXN0ZW0tZm9yLXdyaXRlICdyYXctdGV4dC11bml4KQ0KICAgICAg ICAgICAgICAgICAgKGNvZGluZy1zeXN0ZW0tZm9yLXJlYWQgJ3Jhdy10ZXh0LXVuaXgpKQ0KICAg ICAgICAgICAgICAoY2FsbC1wcm9jZXNzLXJlZ2lvbiAocG9pbnQtbWluKSAocG9pbnQtbWF4KQ0K ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ3ppcC5leGUiIG5pbCBiLWd1bnpp cHBlZCBuaWwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1kIiAiLWMiICIt cSIgIi0iKSkNCiAgICAgICAgICAgIChkZWxldGUtcmVnaW9uIChwb2ludC1taW4pIChwb2ludC1t YXgpKQ0KICAgICAgICAgICAgKGluc2VydC1maWxlIGZpbGVuYW1lKQ0KICAgICAgICAgICAgKGxl dCogKChzLXVuY29tcCAod2l0aC1jdXJyZW50LWJ1ZmZlciBiLWd1bnppcHBlZCAoYnVmZmVyLXN0 cmluZykpKQ0KICAgICAgICAgICAgICAgICAgIChzdWNjZXNzIChzdHJpbmctZXF1YWwgcy1vcmln IHMtdW5jb21wKSkpDQogICAgICAgICAgICAgICh3aGVuIHNob3ctZGlmZg0KICAgICAgICAgICAg ICAgIChtZXNzYWdlICJDb21wcmVzc2lvbi9kZWNvbXByZXNzaW9uIHdpdGggJVMgJXMgIg0KICAg ICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lDQogICAgICAgICAgICAgICAgICAgICAgICAg KGlmIHN1Y2Nlc3MgInN1Y2NlZWRlZCEiICJmYWlsZWQhIikpDQogICAgICAgICAgICAgICAgKHVu bGVzcyBzdWNjZXNzDQogICAgICAgICAgICAgICAgICAod2l0aC1jdXJyZW50LWJ1ZmZlciBiLXps aWINCiAgICAgICAgICAgICAgICAgICAgKHdyaXRlLXJlZ2lvbiAocG9pbnQtbWluKSAocG9pbnQt bWF4KSAidGVzdC1maWxlLWEiKSkNCiAgICAgICAgICAgICAgICAgICh3aXRoLWN1cnJlbnQtYnVm ZmVyIGItZ3VuemlwcGVkDQogICAgICAgICAgICAgICAgICAgICh3cml0ZS1yZWdpb24gKHBvaW50 LW1pbikgKHBvaW50LW1heCkgInRlc3QtZmlsZS1iIikpDQogICAgICAgICAgICAgICAgICAoZGlm ZiAidGVzdC1maWxlLWEiICJ0ZXN0LWZpbGUtYiIpKSkNCiAgICAgICAgICAgICAgc3VjY2Vzcw0K ICAgICAgICAgICAgICApKSkpKSkpDQoNCihkZWZ1biB0ZXN0LWRpcmVjdG9yeSAoZGlyIHBhdHRl cm4pDQogICJSdW5zIFRFU1QtWkxJQi1DT01QUkVTUyBvbiBhbGwgZmlsZXMgaW4gRElSIHRoYXQg bWF0Y2ggUEFUVEVSTi4NClJldHVybnMgYSBsaXN0IG9mIGZpbGVzIHRoYXQgZmFpbCB0aGUgdGVz dC4iDQogIChsZXQgKChmYWlsdXJlcyBuaWwpKQ0KICAgIChkb2xpc3QgKGYgKGRpcmVjdG9yeS1m aWxlcyBkaXIgdCBwYXR0ZXJuKSkNCiAgICAgICh1bmxlc3MgKHRlc3QtemxpYi1jb21wcmVzcyBm KQ0KICAgICAgICAocHVzaCBmIGZhaWx1cmVzKSkpDQogICAgKG1lc3NhZ2UgIkZpbGVzIHRoYXQg ZmFpbGVkIHRlc3Q6ICVTIiBmYWlsdXJlcykpKQ0KDQoodGVzdC1kaXJlY3RvcnkgIn4vZW1hY3Mt YnVpbGQvZ2l0L2VtYWNzLTI3L2xpc3AvIiAiLipcXC5lbCIpDQoNCjs7IFJ1biB0aGlzIGlmIHNv bWUgZmlsZSBmYWlscyB0byBwYXNzDQo7OyAodGVzdC16bGliLWNvbXByZXNzICJjOi9Vc2Vycy9q dWFuai9lbWFjcy1idWlsZC9naXQvZW1hY3MtMjcvbGlzcC9maW5kZXItaW5mLmVsIiB0KQ0KDQoN CihkZWZ1biBzaW1wbGUtemxpYi1jb21wcmVzcyAoZmlsZW5hbWUpDQogICJDb21wcmVzcyB0aGUg YnVmZmVyIGRpcmVjdGx5IHdpdGggWkxJQi1DT01QUkVTUy1SRUdJT04iDQogICh3aXRoLXRlbXAt YnVmZmVyDQogICAgKHNldC1idWZmZXItbXVsdGlieXRlIG5pbCkNCiAgICAoaW5zZXJ0LWZpbGUt Y29udGVudHMtbGl0ZXJhbGx5IGZpbGVuYW1lIG5pbCBuaWwgbmlsIHQpDQogICAgKHVubGVzcyAo emxpYi1jb21wcmVzcy1yZWdpb24gKHBvaW50LW1pbikgKHBvaW50LW1heCkpDQogICAgICAoZXJy b3IgIkZhaWxlZCB0byBjb21wcmVzcyAlcyIgZmlsZW5hbWUpKSkpDQoNCihkZWZ1biBzaW1wbGUt Z3ppcC1jb21wcmVzcyAoZmlsZW5hbWUpDQogICJDb21wcmVzcyB0aGUgYnVmZmVyIGluZGlyZWN0 bHksIHBhc3NpbmcgaXRzIGNvbnRlbnQgdGhyb3VnaCBnemlwLiINCiAgKHdpdGgtdGVtcC1idWZm ZXINCiAgICAoc2V0LWJ1ZmZlci1tdWx0aWJ5dGUgbmlsKQ0KICAgIChpbnNlcnQtZmlsZS1jb250 ZW50cy1saXRlcmFsbHkgZmlsZW5hbWUgbmlsIG5pbCBuaWwgdCkNCiAgICAobGV0ICgoY29kaW5n LXN5c3RlbS1mb3Itd3JpdGUgJ3Jhdy10ZXh0LXVuaXgpDQogICAgICAgICAgKGNvZGluZy1zeXN0 ZW0tZm9yLXJlYWQgJ3Jhdy10ZXh0LXVuaXgpKQ0KICAgICAgKGNhbGwtcHJvY2Vzcy1yZWdpb24g KHBvaW50LW1pbikgKHBvaW50LW1heCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJnemlw LmV4ZSIgdCB0KSkpKQ0KDQooYmVuY2htYXJrIDEgJyhtYXBjICdzaW1wbGUtemxpYi1jb21wcmVz cw0KICAgICAgICAgICAgICAgICAgICAoZGlyZWN0b3J5LWZpbGVzICAifi9lbWFjcy1idWlsZC9n aXQvZW1hY3MtMjcvbGlzcC8iIHQgIi4qXFwuZWwiKSkpDQo7OyA9PiBFbGFwc2VkIHRpbWU6IDIu NjAyNTg4cyAoMC4wMTQ4OTRzIGluIDEgR0NzKQ0KDQooYmVuY2htYXJrIDEgJyhtYXBjICdzaW1w bGUtZ3ppcC1jb21wcmVzcw0KICAgICAgICAgICAgICAgICAgICAoZGlyZWN0b3J5LWZpbGVzICAi fi9lbWFjcy1idWlsZC9naXQvZW1hY3MtMjcvbGlzcC8iIHQgIi4qXFwuZWwiKSkpDQo7OyA9PiBF bGFwc2VkIHRpbWU6IDYxLjk4NjEyOHMgKDAuMDM5ODE1cyBpbiAzIEdDcykNCg== --=-=-=--