summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen <larsi@gnus.org>2013-08-11 21:43:36 +0200
committerLars Magne Ingebrigtsen <larsi@gnus.org>2013-08-11 21:43:36 +0200
commit313546eb796f4588c1c9af60f08f2bd122ef0bdb (patch)
tree011785b2e4c70e7f0ec25e28ff752e4279f2a97d
parentf90e3ebd13de8169ada56274f3abaa1ea8dc6d05 (diff)
downloademacs-313546eb796f4588c1c9af60f08f2bd122ef0bdb.tar.gz
Add zlib support via the `decompress-gzipped-region' function
This adds a new file, src/decompress.c, as well as tests for the presence of -lz.
-rw-r--r--ChangeLog4
-rw-r--r--configure.ac18
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/NEWS4
-rw-r--r--src/ChangeLog8
-rw-r--r--src/Makefile.in6
-rw-r--r--src/decompress.c139
-rw-r--r--src/emacs.c4
-rw-r--r--src/lisp.h5
9 files changed, 190 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index c88303bb525..2384178e82c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-08-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * configure.ac: Test for zlib.
+
2013-08-10 Eli Zaretskii <eliz@gnu.org>
* configure.ac: Define and substitute UPDATE_MANIFEST.
diff --git a/configure.ac b/configure.ac
index e4a846402f2..ca30b38dab4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2942,6 +2942,24 @@ elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes"; then
fi
AC_SUBST(LIBPNG)
+HAVE_ZLIB=no
+LIBZ=
+if test "${HAVE_PNG}" = "yes"; then
+ ### PNG depends on zlib, so if we have PNG, we have zlib.
+ HAVE_ZLIB=yes
+ AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if you have the zlib library (-lz).])
+else
+ ### No PNG, so check zlib ourselves.
+ LIBS="-lz $LIBS"
+ AC_CHECK_LIB(z, inflateEnd, HAVE_ZLIB=yes, HAVE_ZLIB=no)
+ if test "${HAVE_ZLIB}" = "yes"; then
+ AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if you have the zlib library (-lz).])
+ LIBZ=-lz
+ fi
+fi
+AC_SUBST(LIBZ)
+
+
### Use -ltiff if available, unless `--with-tiff=no'.
### mingw32 doesn't use -ltiff, since it loads the library dynamically.
HAVE_TIFF=no
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 1de3abd549c..cbaa780a4a4 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
+2013-08-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * NEWS: Mention -lz and `decompress-gzipped-region'.
+
2013-08-08 Juanma Barranquero <lekktu@gmail.com>
* NEWS: Document new keybinding of `C-x r f' to frameset-to-register.
diff --git a/etc/NEWS b/etc/NEWS
index 370a9c82712..f5f6e48639e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -41,6 +41,10 @@ specially.
** Directories passed to configure option `--enable-locallisppath' are
no longer created during installation.
+** Emacs can be compiled with zlib support. If this library is present
+(which it normally is on most systems), the function
+`decompress-gzipped-region' becomes available.
+
---
** Emacs for NS (OSX, GNUStep) can be built with ImageMagick support.
pkg-config is required to find ImageMagick libraries.
diff --git a/src/ChangeLog b/src/ChangeLog
index fce45d37447..340e8407b33 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2013-08-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * lisp.h: Include decompress.c support.
+
+ * emacs.c (main): Include decompress.c support.
+
+ * Makefile.in: Include -lz if present.
+
2013-08-11 Jan Djärv <jan.h.d@swipnet.se>
* nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:frame:
diff --git a/src/Makefile.in b/src/Makefile.in
index 65927ba236c..f0ed770ac8f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -243,6 +243,8 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
+LIBZ = @LIBZ@
+
XRANDR_LIBS = @XRANDR_LIBS@
XRANDR_CFLAGS = @XRANDR_CFLAGS@
@@ -374,7 +376,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
process.o gnutls.o callproc.o \
region-cache.o sound.o atimer.o \
doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \
- profiler.o \
+ profiler.o decompress.o \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ)
obj = $(base_obj) $(NS_OBJC_OBJ)
@@ -429,7 +431,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
- $(GFILENOTIFY_LIBS) $(LIB_MATH)
+ $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ)
all: emacs$(EXEEXT) $(OTHER_FILES)
.PHONY: all
diff --git a/src/decompress.c b/src/decompress.c
new file mode 100644
index 00000000000..18f7884a4c2
--- /dev/null
+++ b/src/decompress.c
@@ -0,0 +1,139 @@
+/* Interface to zlib.
+ Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#ifdef HAVE_ZLIB
+
+#include <zlib.h>
+
+#include "lisp.h"
+#include "character.h"
+#include "buffer.h"
+
+
+#define BUFFER_SIZE 16384
+
+struct decompress_unwind_data {
+ ptrdiff_t old_point, start;
+ z_stream *stream;
+};
+
+static void
+unwind_decompress (void *ddata) {
+ struct decompress_unwind_data *data = ddata;
+ inflateEnd (data->stream);
+ /* Delete any uncompressed data already inserted and restore
+ point. */
+ if (data->start) {
+ del_range (data->start, PT);
+ SET_PT (data->old_point);
+ }
+}
+
+DEFUN ("decompress-gzipped-region", Fdecompress_gzipped_region,
+ Sdecompress_gzipped_region,
+ 2, 2, 0,
+ doc: /* Decompress a gzip-compressed region.
+The text in the region will be replaced by the decompressed data.
+On failure, nil is returned and the data is left in place.
+This function can only be called in unibyte buffers.*/)
+ (Lisp_Object start, Lisp_Object end)
+{
+ ptrdiff_t istart, iend, point = PT;
+ z_stream stream;
+ int decompressed;
+ char out[16384];
+ struct decompress_unwind_data unwind_data;
+ ptrdiff_t count = SPECPDL_INDEX ();
+
+ validate_region (&start, &end);
+ move_gap_both (iend, iend);
+
+ if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
+ error ("This function can only be called in unibyte buffers");
+
+ /* This is a unibyte buffer, so character positions and bytes are
+ the same. */
+ istart = XINT (start);
+ iend = XINT (end);
+
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+ stream.avail_in = 0;
+ stream.next_in = Z_NULL;
+
+ /* This magic number apparently means "this is gzip". */
+ if (inflateInit2 (&stream, 16 + MAX_WBITS) != Z_OK)
+ return Qnil;
+
+ /* We're inserting the decompressed data at the end of the
+ compressed data. */
+ SET_PT (iend);
+
+ stream.avail_in = iend - istart;
+ stream.next_in = (char *) BYTE_POS_ADDR (istart);
+
+ unwind_data.start = iend;
+ unwind_data.stream = &stream;
+ unwind_data.old_point = point;
+ record_unwind_protect_ptr (unwind_decompress, &unwind_data);
+
+ immediate_quit = 1;
+
+ /* Run inflate() on input until the output buffer isn't full. */
+ do {
+ stream.avail_out = BUFFER_SIZE;
+ stream.next_out = out;
+ switch (inflate (&stream, Z_NO_FLUSH)) {
+ case Z_STREAM_ERROR:
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ unbind_to (count, Qnil);
+ return Qnil;
+ }
+
+ decompressed = BUFFER_SIZE - stream.avail_out;
+ insert_1_both (out, decompressed, decompressed, 0, 0, 0);
+ QUIT;
+ } while (stream.avail_out == 0);
+
+ immediate_quit = 0;
+
+ unwind_data.start = 0;
+ unbind_to (count, Qnil);
+
+ /* Delete the compressed data. */
+ del_range (istart, iend);
+
+ return Qt;
+}
+
+
+/***********************************************************************
+ Initialization
+ ***********************************************************************/
+void
+syms_of_decompress (void)
+{
+ defsubr (&Sdecompress_gzipped_region);
+}
+
+#endif /* HAVE_ZLIB */
diff --git a/src/emacs.c b/src/emacs.c
index 23aef6a2b65..3c80d3ed753 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1406,6 +1406,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
syms_of_xml ();
#endif
+#ifdef HAVE_ZLIB
+ syms_of_decompress ();
+#endif
+
syms_of_menu ();
#ifdef HAVE_NTGUI
diff --git a/src/lisp.h b/src/lisp.h
index 8ca6d05a821..107150461eb 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4213,6 +4213,11 @@ extern void syms_of_xml (void);
extern void xml_cleanup_parser (void);
#endif
+#ifdef HAVE_ZLIB
+/* Defined in decompress.c. */
+extern void syms_of_decompress (void);
+#endif
+
#ifdef HAVE_DBUS
/* Defined in dbusbind.c. */
void syms_of_dbusbind (void);