diff options
author | Eli Zaretskii <eliz@gnu.org> | 2013-08-12 16:15:01 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2013-08-12 16:15:01 +0300 |
commit | 594a430782d12499543637915fd974483523f500 (patch) | |
tree | ed3011bd979d4ed2aedee2fe19effb0ef00450bd /src/decompress.c | |
parent | 7a67e06b99a85ae700a7ccc75468397d53af59ed (diff) | |
download | emacs-594a430782d12499543637915fd974483523f500.tar.gz |
Fix build with zlib on MS-Windows.
configure.ac (LIBZ): Comment on w32 peculiarities regarding LIBZ.
src/decompress.c [WINDOWSNT]: Include windows.h and w32.h.
(DEF_ZLIB_FN, LOAD_ZLIB_FN) [WINDOWSNT]: New macros. Use them to
define static variables that are pointers to zlib functions to be
dynamically loaded.
(init_zlib_functions) [WINDOWSNT]: New function.
(fn_inflateInit2_, fn_inflate, fn_inflateEnd, fn_inflateInit2):
New macros.
(Fdecompress_gzipped_region, unwind_decompress): Use the fn_*
macros instead of invoking the zlib functions directly.
(syms_of_decompress): DEFSYM Qzlib_dll. Staticpro
Szlib_available_p.
lisp/term/w32-win.el (dynamic-library-alist): Add DLLs for zlib.
Diffstat (limited to 'src/decompress.c')
-rw-r--r-- | src/decompress.c | 80 |
1 files changed, 77 insertions, 3 deletions
diff --git a/src/decompress.c b/src/decompress.c index 866f4f51516..af8435b2fd0 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -26,6 +26,58 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "character.h" #include "buffer.h" +static Lisp_Object Qzlib_dll; + +#ifdef WINDOWSNT +#include <windows.h> +#include "w32.h" + +/* Macro for defining functions that will be loaded from the zlib DLL. */ +#define DEF_ZLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args + +/* Macro for loading zlib functions from the library. */ +#define LOAD_ZLIB_FN(lib,func) { \ + fn_##func = (void *) GetProcAddress (lib, #func); \ + if (!fn_##func) return 0; \ + } + +DEF_ZLIB_FN (int, inflateInit2_, + (z_streamp strm, int windowBits, const char *version, int stream_size)); + +DEF_ZLIB_FN (int, inflate, + (z_streamp strm, int flush)); + +DEF_ZLIB_FN (int, inflateEnd, + (z_streamp strm)); + +static bool +init_zlib_functions (void) +{ + HMODULE library = w32_delayed_load (Qzlib_dll); + + if (!library) + { + message1 ("zlib library not found"); + return 0; + } + + LOAD_ZLIB_FN (library, inflateInit2_); + LOAD_ZLIB_FN (library, inflate); + LOAD_ZLIB_FN (library, inflateEnd); + return 1; +} + +#else /* !WINDOWSNT */ + +#define fn_inflateInit2_ inflateInit2_ +#define fn_inflate inflate +#define fn_inflateEnd inflateEnd + +#endif /* WINDOWSNT */ + +#define fn_inflateInit2(strm, windowBits) \ + fn_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + struct decompress_unwind_data { @@ -37,7 +89,7 @@ static void unwind_decompress (void *ddata) { struct decompress_unwind_data *data = ddata; - inflateEnd (data->stream); + fn_inflateEnd (data->stream); /* Delete any uncompressed data already inserted and restore point. */ if (data->start) @@ -47,6 +99,26 @@ unwind_decompress (void *ddata) } } +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_dll, Vlibrary_cache); + if (CONSP (found)) + return XCDR (found); + else + { + Lisp_Object status; + status = init_zlib_functions () ? Qt : Qnil; + Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache); + return status; + } +#else + return Qt; +#endif +} + DEFUN ("decompress-gzipped-region", Fdecompress_gzipped_region, Sdecompress_gzipped_region, 2, 2, 0, @@ -80,7 +152,7 @@ This function can be called only in unibyte buffers. */) stream.next_in = Z_NULL; /* This magic number apparently means "this is gzip". */ - if (inflateInit2 (&stream, 16 + MAX_WBITS) != Z_OK) + if (fn_inflateInit2 (&stream, 16 + MAX_WBITS) != Z_OK) return Qnil; unwind_data.start = iend; @@ -111,7 +183,7 @@ This function can be called only in unibyte buffers. */) stream.avail_in = avail_in; stream.next_out = GPT_ADDR; stream.avail_out = avail_out; - inflate_status = inflate (&stream, Z_NO_FLUSH); + inflate_status = fn_inflate (&stream, Z_NO_FLUSH); pos_byte += avail_in - stream.avail_in; decompressed = avail_out - stream.avail_out; insert_from_gap (decompressed, decompressed, 0); @@ -137,7 +209,9 @@ This function can be called only in unibyte buffers. */) void syms_of_decompress (void) { + DEFSYM (Qzlib_dll, "zlib"); defsubr (&Sdecompress_gzipped_region); + defsubr (&Szlib_available_p); } #endif /* HAVE_ZLIB */ |