commit 4ec02445931e25ea0f9d612b0e6cc5c7a01df1db (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Mon Apr 22 11:12:45 2019 +0300 ; * etc/NEWS: Improve wording of a recent addition. diff --git a/etc/NEWS b/etc/NEWS index b444fc5967..b13ab47768 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -93,8 +93,9 @@ change to one of the data structures that it relies on. ** The configure options '--enable-checking=conslist' and '--enable-checking=xmallocoverrun' have been withdrawn. The former made Emacs irredeemably slow, and the latter made it crash. Neither -option was useful with modern debugging tools such as AddressSanitizer -(see etc/DEBUG). +option was useful with modern debugging tools such as AddressSanitizer. +(See etc/DEBUG for the details of using the modern replacements of the +removed configure options.) --- ** Emacs now requires GTK 2.24 and GTK 3.10 for the GTK 2 and GTK 3 commit 02894982115f6f32ffca2cb1fc4ece122d202853 Author: Michael Albinus Date: Mon Apr 22 09:58:37 2019 +0200 Some changes in tramp-tests * test/lisp/net/tramp-tests.el (tramp-test32-shell-command): Check for backward compatibility. (tramp-test33-environment-variables): Apply a better check for unset variable. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index e2f806e827..4495a1fce4 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4189,7 +4189,9 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (ignore-errors (delete-file tmp-name))) ;; Test `shell-command-width' of `async-shell-command'. - (when (and (zerop (call-process "tput" nil nil nil "cols")) + ;; Since Emacs 27.1. + (when (and (boundp 'shell-command-width) + (zerop (call-process "tput" nil nil nil "cols")) (zerop (process-file "tput" nil nil nil "cols"))) (let (shell-command-width) (should @@ -4280,7 +4282,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (should-not (string-match (regexp-quote envvar) - (funcall this-shell-command-to-string "set"))))))))) + (funcall this-shell-command-to-string "env"))))))))) ;; This test is inspired by Bug#27009. (ert-deftest tramp-test33-environment-variables-and-port-numbers () commit b20d8a932240d5332b4f44b95b2bc1d6fc74c7b0 Author: Paul Eggert Date: Sun Apr 21 23:15:42 2019 -0700 Mention AddressSanitizer etc. in etc/DEBUG * etc/DEBUG: Modernize for AddressSanitizer etc. * etc/NEWS: Defer to etc/DEBUG for this. diff --git a/etc/DEBUG b/etc/DEBUG index d401d0be90..717553871a 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -12,24 +12,21 @@ debugging techniques. *** Configuring Emacs for debugging It is best to configure and build Emacs with special options that will -make the debugging easier. Here's the configure-time options we +make the debugging easier. Here are the configure-time options we recommend (they are in addition to any other options you might need, such as --prefix): ./configure --enable-checking='yes,glyphs' --enable-check-lisp-object-type \ CFLAGS='-O0 -g3' -The CFLAGS value is important: debugging optimized code can be very -hard. (If the problem only happens with optimized code, you may need -to enable optimizations. If that happens, try using -Og first, -instead of -O2, as the former will disable some optimizations that -make debugging some code exceptionally hard.) +The -O0 flag is important, as debugging optimized code can be hard. +If the problem happens only with optimized code, you may need to +enable optimizations. If that happens, try using -Og first instead of +-O2, as -Og disables some optimizations that make debugging some code +exceptionally hard. -Modern versions of GCC support more elaborate debug info that is -available by just using the -g3 compiler switch. Try using -gdwarf-4 -in addition to -g3, and if that fails, try -gdwarf-3. This is -especially important if you have to debug optimized code. More info -about this is available below; search for "analyze failed assertions". +Older versions of GCC may need more than just the -g3 flag. For more, +search for "analyze failed assertions" below. The 2 --enable-* switches are optional. They don't have any effect on debugging with GDB, but will compile additional code that might catch @@ -184,20 +181,15 @@ Good luck! ** When you are trying to analyze failed assertions or backtraces, it is essential to compile Emacs with flags suitable for debugging. -With GCC 4.8 or later, you can invoke 'make' with CFLAGS="-Og -g3". -With older GCC or non-GCC compilers, you can use CFLAGS="-O0 -g3". +With GCC 4.8 or later, you can invoke 'make' with CFLAGS="-O0 -g3". +With older GCC, you can use CFLAGS="-O0 -g3 -gdwarf-4", replacing "4" +by the highest version of DWARF that your compiler supports; +with non-GCC compilers, "-O0 -g3" may be the best you can do. With GCC and higher optimization levels such as -O2, the -fno-omit-frame-pointer and -fno-crossjumping options are often essential. The latter prevents GCC from using the same abort call for all assertions in a given function, rendering the stack backtrace useless for identifying the specific failed assertion. -Some versions of GCC support recent versions of the DWARF standard for -debugging info, but default to older versions; for example, they could -support -gdwarf-4 compiler option (for DWARF v4), but default to -version 2 of the DWARF standard. For best results in debugging -abilities, find out the highest version of DWARF your GCC can support, -and use the corresponding -gdwarf-N switch instead of just -g (you -will still need -g3, as in "-gdwarf-4 -g3"). ** It is a good idea to run Emacs under GDB (or some other suitable debugger) *all the time*. Then, when Emacs crashes, you will be able @@ -923,41 +915,83 @@ setting the new-console option before running Emacs under GDB: (gdb) set new-console 1 (gdb) run -** Running Emacs built with malloc debugging packages +** Running Emacs with undefined-behavior sanitization -If Emacs exhibits bugs that seem to be related to use of memory -allocated off the heap, it might be useful to link Emacs with a -special debugging library, such as Electric Fence (a.k.a. efence) or -GNU Checker, which helps find such problems. +Building Emacs with undefined-behavior sanitization can help debug +integer overflow and other undefined behavior in C code. To use +UndefinedBehaviorSanitizer with GCC and similar compilers, append +'-fsanitize=undefined' to CFLAGS, either when running 'configure' or +running 'make'. For example: -Emacs compiled with such packages might not run without some hacking, -because Emacs replaces the system's memory allocation functions with -its own versions, and because the dumping process might be -incompatible with the way these packages use to track allocated -memory. Here are some of the changes you might find necessary: + ./configure CFLAGS='-O0 -g3 -fsanitize=undefined' - - Make sure unexec is disabled, e.g., './configure --without-unexec'. +You may need to append '-static-libubsan' to CFLAGS if your version of +GCC is installed in an unusual location. - - Configure with a different --prefix= option. If you use GCC, - version 2.7.2 is preferred, as some malloc debugging packages - work a lot better with it than with 2.95 or later versions. +When using GDB to debug an executable with undefined-behavior +sanitization, the GDB command: - - Type "make" then "make -k install". + (gdb) rbreak ^__ubsan_handle_ - - If required, invoke the package-specific command to prepare - src/temacs for execution. +will let you gain control when an error is detected and before +UndefinedBehaviorSanitizer outputs to stderr or terminates the +program. - - cd ..; src/temacs +** Running Emacs with address sanitization -(Note that this runs 'temacs' instead of the usual 'emacs' executable. -This avoids problems with dumping Emacs mentioned above.) +Building Emacs with address sanitization can help debug memory-use +problems. To use AddressSanitizer with GCC and similar compilers, +append '-fsanitize=address' to CFLAGS, either when running 'configure' +or running 'make'. Configure, build and run Emacs with +ASAN_OPTIONS='detect_leaks=0' in the environment to suppress +diagnostics of minor memory leaks in Emacs. For example: -Some malloc debugging libraries might print lots of false alarms for -bitfields used by Emacs in some data structures. If you want to get -rid of the false alarms, you will have to hack the definitions of -these data structures on the respective headers to remove the ':N' -bitfield definitions (which will cause each such field to use a full -int). + export ASAN_OPTIONS='detect_leaks=0' + ./configure CFLAGS='-O0 -g3 -fsanitize=address' + make + src/emacs + +You may need to append '-static-libasan' to CFLAGS if your version of +GCC is installed in an unusual location. + +When using GDB to debug an executable with address sanitization, the +GDB command: + + (gdb) rbreak ^__asan_report_ + +will let you gain control when an error is detected and before +AddressSanitizer outputs to stderr or terminates the program. + +Address sanitization is incompatible with undefined-behavior +sanitization, unfortunately. Address sanitization is also +incompatible with the --with-dumping=unexec option of 'configure'. + +** Running Emacs under Valgrind + +Valgrind is free software that can be useful +when debugging low-level Emacs problems. Unlike GCC sanitizers, +Valgrind does not need you to compile Emacs with special debugging +flags, so it can be helpful in investigating problems that vanish when +Emacs is recompiled with debugging enabled. However, by default +Valgrind generates many false alarms with Emacs, and you will need to +maintain a suppressions file to suppress these false alarms and use +Valgrind effectively. For example, you might invoke Valgrind this +way: + + valgrind --suppressions=valgrind.supp ./emacs + +where valgrind.supp contains groups of lines like the following, which +suppresses some Valgrind false alarms during Emacs garbage collection: + + { + Fgarbage_collect Cond - conservative garbage collection + Memcheck:Cond + ... + fun:Fgarbage_collect + } + +Unfortunately Valgrind suppression files tend to be system-dependent, +so you will need to keep one around that matches your system. ** How to recover buffer contents from an Emacs core dump file diff --git a/etc/NEWS b/etc/NEWS index 051063171e..b444fc5967 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -93,7 +93,8 @@ change to one of the data structures that it relies on. ** The configure options '--enable-checking=conslist' and '--enable-checking=xmallocoverrun' have been withdrawn. The former made Emacs irredeemably slow, and the latter made it crash. Neither -option was useful with modern debugging tools. +option was useful with modern debugging tools such as AddressSanitizer +(see etc/DEBUG). --- ** Emacs now requires GTK 2.24 and GTK 3.10 for the GTK 2 and GTK 3 commit 1ea048f6e02e56891278a040a5b21678c661764a Author: Paul Eggert Date: Sun Apr 21 21:47:10 2019 -0700 Remove --enable-checking=xmallocoverrun It doesn’t work anymore, and these days ‘gcc -fsanitize=address’ does a better job anyway. * configure.ac: Remove the option. * configure.ac (ac_xmalloc_overrun, XMALLOC_OVERRUN_CHECK): * src/alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD) (XMALLOC_OVERRUN_CHECK_SIZE, XMALLOC_OVERRUN_SIZE_SIZE) (xmalloc_overrun_check_header, xmalloc_overrun_check_trailer) (xmalloc_put_size, xmalloc_get_size, overrun_check_malloc) (overrun_check_realloc, overrun_check_free): Remove. All uses removed. * etc/NEWS: Mention this. diff --git a/configure.ac b/configure.ac index dd88380d78..0ecb8c40e6 100644 --- a/configure.ac +++ b/configure.ac @@ -545,7 +545,7 @@ AC_ARG_ENABLE(checking, enable only specific categories of checks. Categories are: all,yes,no. Flags are: stringbytes, stringoverrun, stringfreelist, - structs, xmallocoverrun, glyphs])], + structs, glyphs])], [ac_checking_flags="${enableval}"],[]) IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS," CHECK_STRUCTS=false @@ -559,21 +559,18 @@ do ac_gc_check_stringbytes= ; ac_gc_check_string_overrun= ; ac_gc_check_string_free_list= ; - ac_xmalloc_overrun= ; ac_glyphs_debug= ;; all) ac_enable_checking=1 ; CHECK_STRUCTS=true ac_gc_check_stringbytes=1 ; ac_gc_check_string_overrun=1 ; ac_gc_check_string_free_list=1 ; - ac_xmalloc_overrun=1 ; ac_glyphs_debug=1 ;; # these enable particular checks stringbytes) ac_gc_check_stringbytes=1 ;; stringoverrun) ac_gc_check_string_overrun=1 ;; stringfreelist) ac_gc_check_string_free_list=1 ;; structs) CHECK_STRUCTS=true ;; - xmallocoverrun) ac_xmalloc_overrun=1 ;; glyphs) ac_glyphs_debug=1 ;; *) AC_MSG_ERROR(unknown check category $check) ;; esac @@ -607,10 +604,6 @@ if test x$ac_gc_check_string_free_list != x ; then AC_DEFINE(GC_CHECK_STRING_FREE_LIST, 1, [Define this to check the string free list.]) fi -if test x$ac_xmalloc_overrun != x ; then - AC_DEFINE(XMALLOC_OVERRUN_CHECK, 1, -[Define this to check for malloc buffer overrun.]) -fi if test x$ac_glyphs_debug != x ; then AC_DEFINE(GLYPH_DEBUG, 1, [Define this to enable glyphs debugging code.]) diff --git a/etc/NEWS b/etc/NEWS index f991dbaf97..051063171e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -90,9 +90,10 @@ check that the portable dumper code has been updated to match the last change to one of the data structures that it relies on. +++ -** The configure option '--enable-checking=conslist' has been withdrawn. -It made Emacs irredeemably slow, and is no longer useful with modern -debugging tools. +** The configure options '--enable-checking=conslist' and +'--enable-checking=xmallocoverrun' have been withdrawn. The former +made Emacs irredeemably slow, and the latter made it crash. Neither +option was useful with modern debugging tools. --- ** Emacs now requires GTK 2.24 and GTK 3.10 for the GTK 2 and GTK 3 diff --git a/src/alloc.c b/src/alloc.c index d279b6f872..402fada1ad 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -151,9 +151,7 @@ malloc_initialize_hook (void) if (malloc_set_state (malloc_state_ptr) != 0) emacs_abort (); -# ifndef XMALLOC_OVERRUN_CHECK alloc_unexec_post (); -# endif } } @@ -651,171 +649,6 @@ verify (LISP_ALIGNMENT % GCALIGNMENT == 0); it never does anything that requires an alignment of 16. */ enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; -#ifndef XMALLOC_OVERRUN_CHECK -#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 -#else - -/* Check for overrun in malloc'ed buffers by wrapping a header and trailer - around each block. - - The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes - followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original - block size in little-endian order. The trailer consists of - XMALLOC_OVERRUN_CHECK_SIZE fixed bytes. - - The header is used to detect whether this block has been allocated - through these functions, as some low-level libc functions may - bypass the malloc hooks. */ - -#define XMALLOC_OVERRUN_CHECK_SIZE 16 -#define XMALLOC_OVERRUN_CHECK_OVERHEAD \ - (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE) - -/* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to - hold a size_t value and (2) the header size is a multiple of the - alignment that Emacs needs for C types and for USE_LSB_TAG. */ -#define XMALLOC_OVERRUN_SIZE_SIZE \ - (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \ - + LISP_ALIGNMENT - 1) \ - / LISP_ALIGNMENT * LISP_ALIGNMENT) \ - - XMALLOC_OVERRUN_CHECK_SIZE) - -static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = - { '\x9a', '\x9b', '\xae', '\xaf', - '\xbf', '\xbe', '\xce', '\xcf', - '\xea', '\xeb', '\xec', '\xed', - '\xdf', '\xde', '\x9c', '\x9d' }; - -static char const xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] = - { '\xaa', '\xab', '\xac', '\xad', - '\xba', '\xbb', '\xbc', '\xbd', - '\xca', '\xcb', '\xcc', '\xcd', - '\xda', '\xdb', '\xdc', '\xdd' }; - -/* Insert and extract the block size in the header. */ - -static void -xmalloc_put_size (unsigned char *ptr, size_t size) -{ - int i; - for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++) - { - *--ptr = size & ((1 << CHAR_BIT) - 1); - size >>= CHAR_BIT; - } -} - -static size_t -xmalloc_get_size (unsigned char *ptr) -{ - size_t size = 0; - int i; - ptr -= XMALLOC_OVERRUN_SIZE_SIZE; - for (i = 0; i < XMALLOC_OVERRUN_SIZE_SIZE; i++) - { - size <<= CHAR_BIT; - size += *ptr++; - } - return size; -} - - -/* Like malloc, but wraps allocated block with header and trailer. */ - -static void * -overrun_check_malloc (size_t size) -{ - register unsigned char *val; - if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size) - emacs_abort (); - - val = malloc (size + XMALLOC_OVERRUN_CHECK_OVERHEAD); - if (val) - { - memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); - val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; - xmalloc_put_size (val, size); - memcpy (val + size, xmalloc_overrun_check_trailer, - XMALLOC_OVERRUN_CHECK_SIZE); - } - return val; -} - - -/* Like realloc, but checks old block for overrun, and wraps new block - with header and trailer. */ - -static void * -overrun_check_realloc (void *block, size_t size) -{ - register unsigned char *val = (unsigned char *) block; - if (SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD < size) - emacs_abort (); - - if (val - && memcmp (xmalloc_overrun_check_header, - val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, - XMALLOC_OVERRUN_CHECK_SIZE) == 0) - { - size_t osize = xmalloc_get_size (val); - if (memcmp (xmalloc_overrun_check_trailer, val + osize, - XMALLOC_OVERRUN_CHECK_SIZE)) - emacs_abort (); - memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); - val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; - memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); - } - - val = realloc (val, size + XMALLOC_OVERRUN_CHECK_OVERHEAD); - - if (val) - { - memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE); - val += XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; - xmalloc_put_size (val, size); - memcpy (val + size, xmalloc_overrun_check_trailer, - XMALLOC_OVERRUN_CHECK_SIZE); - } - return val; -} - -/* Like free, but checks block for overrun. */ - -static void -overrun_check_free (void *block) -{ - unsigned char *val = (unsigned char *) block; - - if (val - && memcmp (xmalloc_overrun_check_header, - val - XMALLOC_OVERRUN_CHECK_SIZE - XMALLOC_OVERRUN_SIZE_SIZE, - XMALLOC_OVERRUN_CHECK_SIZE) == 0) - { - size_t osize = xmalloc_get_size (val); - if (memcmp (xmalloc_overrun_check_trailer, val + osize, - XMALLOC_OVERRUN_CHECK_SIZE)) - emacs_abort (); -#ifdef XMALLOC_CLEAR_FREE_MEMORY - val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; - memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD); -#else - memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE); - val -= XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE; - memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE); -#endif - } - - free (val); -} - -#undef malloc -#undef realloc -#undef free -#define malloc overrun_check_malloc -#define realloc overrun_check_realloc -#define free overrun_check_free -#endif - /* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. If that variable is set, block input while in one of Emacs's memory @@ -1790,7 +1623,7 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] = calculating a value to be passed to malloc. */ static ptrdiff_t const STRING_BYTES_MAX = min (STRING_BYTES_BOUND, - ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD + ((SIZE_MAX - GC_STRING_EXTRA - offsetof (struct sblock, data) - SDATA_DATA_OFFSET) commit 72067661fef9cb9e1a746a7a825053c8204c7a38 Author: Paul Eggert Date: Sun Apr 21 21:47:10 2019 -0700 Remove --enablechecking=conslist configure option * configure.ac: Remove the option. * configure.ac (ac_gc_check_cons_list, GC_CHECK_CONS_LIST): * src/alloc.c (check_cons_list) [GC_CHECK_CONS_LIST]: * src/lisp.h (lisp_h_check_cons_list, check_cons_list): Remove. All uses removed. * etc/NEWS: Mention this. diff --git a/configure.ac b/configure.ac index b4a9b30691..dd88380d78 100644 --- a/configure.ac +++ b/configure.ac @@ -545,7 +545,7 @@ AC_ARG_ENABLE(checking, enable only specific categories of checks. Categories are: all,yes,no. Flags are: stringbytes, stringoverrun, stringfreelist, - structs, xmallocoverrun, conslist, glyphs])], + structs, xmallocoverrun, glyphs])], [ac_checking_flags="${enableval}"],[]) IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS," CHECK_STRUCTS=false @@ -560,7 +560,6 @@ do ac_gc_check_string_overrun= ; ac_gc_check_string_free_list= ; ac_xmalloc_overrun= ; - ac_gc_check_cons_list= ; ac_glyphs_debug= ;; all) ac_enable_checking=1 ; CHECK_STRUCTS=true @@ -568,7 +567,6 @@ do ac_gc_check_string_overrun=1 ; ac_gc_check_string_free_list=1 ; ac_xmalloc_overrun=1 ; - ac_gc_check_cons_list=1 ; ac_glyphs_debug=1 ;; # these enable particular checks stringbytes) ac_gc_check_stringbytes=1 ;; @@ -576,7 +574,6 @@ do stringfreelist) ac_gc_check_string_free_list=1 ;; structs) CHECK_STRUCTS=true ;; xmallocoverrun) ac_xmalloc_overrun=1 ;; - conslist) ac_gc_check_cons_list=1 ;; glyphs) ac_glyphs_debug=1 ;; *) AC_MSG_ERROR(unknown check category $check) ;; esac @@ -614,10 +611,6 @@ if test x$ac_xmalloc_overrun != x ; then AC_DEFINE(XMALLOC_OVERRUN_CHECK, 1, [Define this to check for malloc buffer overrun.]) fi -if test x$ac_gc_check_cons_list != x ; then - AC_DEFINE(GC_CHECK_CONS_LIST, 1, -[Define this to check for errors in cons list.]) -fi if test x$ac_glyphs_debug != x ; then AC_DEFINE(GLYPH_DEBUG, 1, [Define this to enable glyphs debugging code.]) diff --git a/etc/NEWS b/etc/NEWS index 4d76143b13..f991dbaf97 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -89,6 +89,11 @@ Options" in the Emacs manual for more information. check that the portable dumper code has been updated to match the last change to one of the data structures that it relies on. ++++ +** The configure option '--enable-checking=conslist' has been withdrawn. +It made Emacs irredeemably slow, and is no longer useful with modern +debugging tools. + --- ** Emacs now requires GTK 2.24 and GTK 3.10 for the GTK 2 and GTK 3 builds respectively. diff --git a/src/alloc.c b/src/alloc.c index 186a4c6a09..d279b6f872 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2801,18 +2801,6 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, return val; } -#ifdef GC_CHECK_CONS_LIST -/* Get an error now if there's any junk in the cons free list. */ -void -check_cons_list (void) -{ - struct Lisp_Cons *tail = cons_free_list; - - while (tail) - tail = tail->u.s.u.chain; -} -#endif - /* Make a list of 1, 2, 3, 4 or 5 specified objects. */ Lisp_Object @@ -6003,8 +5991,6 @@ garbage_collect_1 (struct gcstat *gcst) /* Record this function, so it appears on the profiler's backtraces. */ record_in_backtrace (QAutomatic_GC, 0, 0); - check_cons_list (); - /* Don't keep undo information around forever. Do this early on, so it is no problem if the user quits. */ FOR_EACH_BUFFER (nextb) @@ -6124,8 +6110,6 @@ garbage_collect_1 (struct gcstat *gcst) unmark_main_thread (); - check_cons_list (); - gc_in_progress = 0; unblock_input (); diff --git a/src/eval.c b/src/eval.c index a636f6c50a..4693767ce7 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2210,8 +2210,6 @@ eval_sub (Lisp_Object form) Lisp_Object args_left = original_args; ptrdiff_t numargs = list_length (args_left); - check_cons_list (); - if (numargs < XSUBR (fun)->min_args || (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs)) @@ -2240,7 +2238,6 @@ eval_sub (Lisp_Object form) val = XSUBR (fun)->function.aMANY (argnum, vals); - check_cons_list (); lisp_eval_depth--; /* Do the debug-on-exit now, while VALS still exists. */ if (backtrace_debug_on_exit (specpdl + count)) @@ -2346,7 +2343,6 @@ eval_sub (Lisp_Object form) else xsignal1 (Qinvalid_function, original_fun); } - check_cons_list (); lisp_eval_depth--; if (backtrace_debug_on_exit (specpdl + count)) @@ -2786,8 +2782,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) if (debug_on_next_call) do_debug_on_call (Qlambda, count); - check_cons_list (); - original_fun = args[0]; retry: @@ -2817,13 +2811,11 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) else if (EQ (funcar, Qautoload)) { Fautoload_do_load (fun, original_fun, Qnil); - check_cons_list (); goto retry; } else xsignal1 (Qinvalid_function, original_fun); } - check_cons_list (); lisp_eval_depth--; if (backtrace_debug_on_exit (specpdl + count)) val = call_debugger (list2 (Qexit, val)); @@ -2935,7 +2927,6 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) set_backtrace_args (specpdl + count, arg_vector, numargs); tem = funcall_lambda (fun, numargs, arg_vector); - check_cons_list (); lisp_eval_depth--; /* Do the debug-on-exit now, while arg_vector still exists. */ if (backtrace_debug_on_exit (specpdl + count)) diff --git a/src/lisp.h b/src/lisp.h index 2d250fc52c..d803f16000 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -413,9 +413,6 @@ typedef EMACS_INT Lisp_Word; #define lisp_h_XCONS(a) \ (eassert (CONSP (a)), XUNTAG (a, Lisp_Cons, struct Lisp_Cons)) #define lisp_h_XHASH(a) XUFIXNUM (a) -#ifndef GC_CHECK_CONS_LIST -# define lisp_h_check_cons_list() ((void) 0) -#endif #if USE_LSB_TAG # define lisp_h_make_fixnum(n) \ XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0)) @@ -459,9 +456,6 @@ typedef EMACS_INT Lisp_Word; # define XCDR(c) lisp_h_XCDR (c) # define XCONS(a) lisp_h_XCONS (a) # define XHASH(a) lisp_h_XHASH (a) -# ifndef GC_CHECK_CONS_LIST -# define check_cons_list() lisp_h_check_cons_list () -# endif # if USE_LSB_TAG # define make_fixnum(n) lisp_h_make_fixnum (n) # define XFIXNAT(a) lisp_h_XFIXNAT (a) @@ -3965,11 +3959,6 @@ extern void init_alloc (void); extern void syms_of_alloc (void); extern struct buffer * allocate_buffer (void); extern int valid_lisp_object_p (Lisp_Object); -#ifdef GC_CHECK_CONS_LIST -extern void check_cons_list (void); -#else -INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); } -#endif /* Defined in gmalloc.c. */ #if !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC && !defined SYSTEM_MALLOC commit 418400ab7b36d873905f5ab5e1e07f2bdbd05f9c Author: Paul Eggert Date: Sun Apr 21 21:45:04 2019 -0700 Simplify XPNTR Because XPNTR now uses ATTRIBUTE_NO_SANITIZE_UNDEFINED, it can be simplified. * src/alloc.c (macro_PNTR_ADD, PNTR_ADD, macro_XPNTR): Remove. (XPNTR): Open-code rather than using the removed macros and functions. Also, simplify by using LISP_WORD_TAG. diff --git a/src/alloc.c b/src/alloc.c index a9cdd77ef2..186a4c6a09 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -528,40 +528,14 @@ pointer_align (void *ptr, int alignment) return (void *) ROUNDUP ((uintptr_t) ptr, alignment); } -/* Define PNTR_ADD and XPNTR as functions, which are cleaner and can - be used in debuggers. Also, define them as macros if - DEFINE_KEY_OPS_AS_MACROS, for performance in that case. - The macro_* macros are private to this section of code. */ - -/* Add a pointer P to an integer I without gcc -fsanitize complaining - about the result being out of range of the underlying array. */ - -#define macro_PNTR_ADD(p, i) ((p) + (i)) - -static ATTRIBUTE_NO_SANITIZE_UNDEFINED ATTRIBUTE_UNUSED char * -PNTR_ADD (char *p, EMACS_UINT i) -{ - return macro_PNTR_ADD (p, i); -} - -#if DEFINE_KEY_OPS_AS_MACROS -# define PNTR_ADD(p, i) macro_PNTR_ADD (p, i) -#endif - /* Extract the pointer hidden within O. */ -#define macro_XPNTR(o) \ - ((void *) \ - (SYMBOLP (o) \ - ? PNTR_ADD ((char *) lispsym, \ - (XLI (o) \ - - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS)))) \ - : (char *) XLP (o) - (XLI (o) & ~VALMASK))) - static ATTRIBUTE_NO_SANITIZE_UNDEFINED void * XPNTR (Lisp_Object a) { - return macro_XPNTR (a); + return (SYMBOLP (a) + ? (char *) lispsym + (XLI (a) - LISP_WORD_TAG (Lisp_Symbol)) + : (char *) XLP (a) - (XLI (a) & ~VALMASK)); } static void commit e85bff0bbb60e1d819f8f5e00f8496026f27f7ea Author: Paul Eggert Date: Sun Apr 21 21:16:03 2019 -0700 Fix drain_reloc_list alignment bug * src/pdumper.c (dump_charset): Use alignof (struct charset), not alignof (int), since struct charset might be more strictly aligned than int. I think this is just a minor performance issue, but we might as well use the correct alignment. (drain_reloc_list): Use an alignment instead of a size for the output alignment. This prevents undefined behavior when alignof (struct emacs_reloc) == 8 and sizeof (dump_off) == 4 when building on x86-64 with gcc -fsanitize=undefined. diff --git a/src/pdumper.c b/src/pdumper.c index 6ab82769ec..39931c6807 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -3167,7 +3167,7 @@ dump_charset (struct dump_context *ctx, int cs_i) #if CHECK_STRUCTS && !defined (HASH_charset_317C49E291) # error "charset changed. See CHECK_STRUCTS comment." #endif - dump_align_output (ctx, alignof (int)); + dump_align_output (ctx, alignof (struct charset)); const struct charset *cs = charset_table + cs_i; struct charset out; dump_object_start (ctx, &out, sizeof (out)); @@ -3816,7 +3816,8 @@ drain_reloc_list (struct dump_context *ctx, Lisp_Object relocs = Fsort (Fnreverse (*reloc_list), Qdump_emacs_portable__sort_predicate); *reloc_list = Qnil; - dump_align_output (ctx, sizeof (dump_off)); + dump_align_output (ctx, max (alignof (struct dump_reloc), + alignof (struct emacs_reloc))); struct dump_table_locator locator; memset (&locator, 0, sizeof (locator)); locator.offset = ctx->offset; commit 4a5ed6b05a71593cda33af4da44f30eb84b51f30 Author: Paul Eggert Date: Sun Apr 21 20:36:56 2019 -0700 Port dump_bitset_clear to -fsanitize=undefined * src/pdumper.c (dump_bitset_clear): Pacify -fsanitize=undefined by avoiding memset (NULL, x, 0), which strictly speaking has undefined behavior although it works on all production platforms I know. diff --git a/src/pdumper.c b/src/pdumper.c index 3facd523e4..6ab82769ec 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -4923,7 +4923,8 @@ static void dump_bitset_clear (struct dump_bitset *bitset) { int xword_size = sizeof (bitset->bits[0]); - memset (bitset->bits, 0, bitset->number_words * xword_size); + if (bitset->number_words) + memset (bitset->bits, 0, bitset->number_words * xword_size); } struct pdumper_loaded_dump_private commit f67bc3f12b8ebe4ff0d133063e3c41ab772dbd45 Author: Paul Eggert Date: Sun Apr 21 20:34:03 2019 -0700 Port to recent gcc -fsanitize=undefined * src/alloc.c (XPNTR): Add ATTRIBUTE_NO_SANITIZE_UNDEFINED and remove ATTRIBUTE_UNUSED. Do not define as a macro, so that ATTRIBUTE_NO_SANITIZE_UNDEFINED works. * src/lisp.h (lisp_h_XSYMBOL): Remove. All uses removed. With recent GCC the macro does not work with -fsanitize=undefined, and the macro can be omitted as its only function is to optimize -O0. diff --git a/src/alloc.c b/src/alloc.c index b5b6dc2f05..a9cdd77ef2 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -558,16 +558,12 @@ PNTR_ADD (char *p, EMACS_UINT i) - ((EMACS_UINT) Lisp_Symbol << (USE_LSB_TAG ? 0 : VALBITS)))) \ : (char *) XLP (o) - (XLI (o) & ~VALMASK))) -static ATTRIBUTE_UNUSED void * +static ATTRIBUTE_NO_SANITIZE_UNDEFINED void * XPNTR (Lisp_Object a) { return macro_XPNTR (a); } -#if DEFINE_KEY_OPS_AS_MACROS -# define XPNTR(a) macro_XPNTR (a) -#endif - static void XFLOAT_INIT (Lisp_Object f, double n) { diff --git a/src/lisp.h b/src/lisp.h index c2cb89de9d..2d250fc52c 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -421,19 +421,6 @@ typedef EMACS_INT Lisp_Word; XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0)) # define lisp_h_XFIXNAT(a) XFIXNUM (a) # define lisp_h_XFIXNUM(a) (XLI (a) >> INTTYPEBITS) -# ifdef __CHKP__ -# define lisp_h_XSYMBOL(a) \ - (eassert (SYMBOLP (a)), \ - (struct Lisp_Symbol *) ((char *) XUNTAG (a, Lisp_Symbol, \ - struct Lisp_Symbol) \ - + (intptr_t) lispsym)) -# else - /* If !__CHKP__ this is equivalent, and is a bit faster as of GCC 7. */ -# define lisp_h_XSYMBOL(a) \ - (eassert (SYMBOLP (a)), \ - (struct Lisp_Symbol *) ((intptr_t) XLI (a) - Lisp_Symbol \ - + (char *) lispsym)) -# endif # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) #endif @@ -479,7 +466,6 @@ typedef EMACS_INT Lisp_Word; # define make_fixnum(n) lisp_h_make_fixnum (n) # define XFIXNAT(a) lisp_h_XFIXNAT (a) # define XFIXNUM(a) lisp_h_XFIXNUM (a) -# define XSYMBOL(a) lisp_h_XSYMBOL (a) # define XTYPE(a) lisp_h_XTYPE (a) # endif #endif @@ -1023,21 +1009,17 @@ INLINE bool } INLINE struct Lisp_Symbol * ATTRIBUTE_NO_SANITIZE_UNDEFINED -(XSYMBOL) (Lisp_Object a) +XSYMBOL (Lisp_Object a) { -#if USE_LSB_TAG - return lisp_h_XSYMBOL (a); -#else eassert (SYMBOLP (a)); intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol, struct Lisp_Symbol); void *p = (char *) lispsym + i; -# ifdef __CHKP__ +#ifdef __CHKP__ /* Bypass pointer checking. Although this could be improved it is probably not worth the trouble. */ p = __builtin___bnd_set_ptr_bounds (p, sizeof (struct Lisp_Symbol)); -# endif - return p; #endif + return p; } INLINE Lisp_Object commit 3a618e5f89c86bc96925b06647fb33568c8fa2c9 Author: Basil L. Contovounesios Date: Wed Apr 17 17:35:12 2019 +0100 Move side-effect-free from unsafep.el to subr.el * lisp/emacs-lisp/unsafep.el: Move side-effect-free property setting from here... * lisp/subr.el: ...to here, as function declarations for modularity. diff --git a/lisp/emacs-lisp/unsafep.el b/lisp/emacs-lisp/unsafep.el index d20b751d88..1a2f1f31b1 100644 --- a/lisp/emacs-lisp/unsafep.el +++ b/lisp/emacs-lisp/unsafep.el @@ -92,11 +92,6 @@ in the parse.") (put 'unsafep-vars 'risky-local-variable t) -;;Side-effect-free functions from subr.el -(dolist (x '(assoc-default butlast last match-string - match-string-no-properties member-ignore-case remove remq)) - (put x 'side-effect-free t)) - ;;Other safe functions (dolist (x '(;;Special forms and catch if or prog1 prog2 progn while unwind-protect diff --git a/lisp/subr.el b/lisp/subr.el index bf3716bbd3..f68f9dd419 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -580,6 +580,7 @@ i.e., subtract 2 * most-negative-fixnum from VALUE before shifting it." If LIST is nil, return nil. If N is non-nil, return the Nth-to-last link of LIST. If N is bigger than the length of LIST, return LIST." + (declare (side-effect-free t)) (if n (and (>= n 0) (let ((m (safe-length list))) @@ -591,6 +592,7 @@ If N is bigger than the length of LIST, return LIST." "Return a copy of LIST with the last N elements removed. If N is omitted or nil, the last element is removed from the copy." + (declare (side-effect-free t)) (if (and n (<= n 0)) list (nbutlast (copy-sequence list) n))) @@ -726,6 +728,7 @@ If that is non-nil, the element matches; then `assoc-default' If no element matches, the value is nil. If TEST is omitted or nil, `equal' is used." + (declare (side-effect-free t)) (let (found (tail alist) value) (while (and tail (not found)) (let ((elt (car tail))) @@ -739,6 +742,7 @@ If TEST is omitted or nil, `equal' is used." ELT must be a string. Upper-case and lower-case letters are treated as equal. Unibyte strings are converted to multibyte for comparison. Non-strings in LIST are ignored." + (declare (side-effect-free t)) (while (and list (not (and (stringp (car list)) (eq t (compare-strings elt 0 nil (car list) 0 nil t))))) @@ -822,6 +826,7 @@ Example: (defun remove (elt seq) "Return a copy of SEQ with all occurrences of ELT removed. SEQ must be a list, vector, or string. The comparison is done with `equal'." + (declare (side-effect-free t)) (if (nlistp seq) ;; If SEQ isn't a list, there's no need to copy SEQ because ;; `delete' will return a new object. @@ -832,6 +837,7 @@ SEQ must be a list, vector, or string. The comparison is done with `equal'." "Return LIST with all occurrences of ELT removed. The comparison is done with `eq'. Contrary to `delq', this does not use side-effects, and the argument LIST is not modified." + (declare (side-effect-free t)) (while (and (eq elt (car list)) (setq list (cdr list)))) (if (memq elt list) (delq elt (copy-sequence list)) @@ -3898,6 +3904,7 @@ Zero means the entire text matched by the whole regexp or whole string. STRING should be given if the last search was by `string-match' on STRING. If STRING is nil, the current buffer should be the same buffer the search/match was performed in." + (declare (side-effect-free t)) (if (match-beginning num) (if string (substring string (match-beginning num) (match-end num)) @@ -3911,6 +3918,7 @@ Zero means the entire text matched by the whole regexp or whole string. STRING should be given if the last search was by `string-match' on STRING. If STRING is nil, the current buffer should be the same buffer the search/match was performed in." + (declare (side-effect-free t)) (if (match-beginning num) (if string (substring-no-properties string (match-beginning num) commit 2ea55c2774e726c7e393ee81b152aa9734c410cb Author: Paul Eggert Date: Sun Apr 21 09:59:13 2019 -0700 Fix double-free in pdumper Revert the double-free bug that I introduced in 2019-03-11T15:20:54Z!eggert@cs.ucla.edu. * src/pdumper.c (dump_mmap_reset): Do not free the private member; that’s the release function’s job. (dump_mm_heap_cb_release): Free cb if its refcount goes to zero. (dump_mmap_contiguous_heap): Mention memory leak in comment. diff --git a/src/pdumper.c b/src/pdumper.c index 5bc5bb47f4..3facd523e4 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -4623,9 +4623,7 @@ dump_mmap_reset (struct dump_memory_map *map) { map->mapping = NULL; map->release = NULL; - void *private = map->private; map->private = NULL; - free (private); } static void @@ -4648,7 +4646,10 @@ dump_mm_heap_cb_release (struct dump_memory_map_heap_control_block *cb) { eassert (cb->refcount > 0); if (--cb->refcount == 0) - free (cb->mem); + { + free (cb->mem); + free (cb); + } } static void @@ -4663,7 +4664,12 @@ dump_mmap_contiguous_heap (struct dump_memory_map *maps, int nr_maps, size_t total_size) { bool ret = false; + + /* FIXME: This storage sometimes is never freed. + Beware: the simple patch 2019-03-11T15:20:54Z!eggert@cs.ucla.edu + is worse, as it sometimes frees this storage twice. */ struct dump_memory_map_heap_control_block *cb = calloc (1, sizeof (*cb)); + char *mem; if (!cb) goto out; commit d9664f0d9e03ecfbcd7115a27200c5259bc19162 Merge: d2b78ea1d4 9d7e08dd8f Author: Glenn Morris Date: Sun Apr 21 07:51:38 2019 -0700 Merge from origin/emacs-26 9d7e08d (origin/emacs-26) Avoid false positives and false negatives o... 75b589c Fix markup related to quoting in Info fd6ff29 Merge branch 'emacs-26' of git.savannah.gnu.org:/srv/git/emac... cd2204f Add a package: line to c-submit-bug-report. a992dca ; Remove empty NEWS sections ea67270 ; Add NEWS sections for 26.3 45b0946 ; Bump Emacs version to 26.2.50 aae8cc3 * admin/admin.el (set-version): Add NEWS headers for a .50 ve... commit d2b78ea1d4f5deb62efac0d1cad7c8df015a2d76 Merge: 828a6eb64f bacdaa5b25 Author: Glenn Morris Date: Sun Apr 21 07:51:38 2019 -0700 ; Merge from origin/emacs-26 The following commit was skipped: bacdaa5 Use pkg-config to find lcms2 CFLAGS and LIBS (Bug#30346) commit 828a6eb64f66b2452d0eb0f5b54f274320f28bba Merge: 86a8b49b22 cd2204f0ee Author: Glenn Morris Date: Sun Apr 21 07:51:38 2019 -0700 Merge from origin/emacs-26 cd2204f Add a package: line to c-submit-bug-report. a992dca ; Remove empty NEWS sections ea67270 ; Add NEWS sections for 26.3 Conflicts: etc/NEWS commit 86a8b49b229f85ad8ce22d9180b07f3bf235d9f3 Merge: e8d483971f 45b09460f9 Author: Glenn Morris Date: Sun Apr 21 07:51:37 2019 -0700 ; Merge from origin/emacs-26 The following commit was skipped: 45b0946 ; Bump Emacs version to 26.2.50 commit e8d483971fe6e67f72349a084dcacb365f42d7a8 Merge: 5185b39106 aae8cc3304 Author: Glenn Morris Date: Sun Apr 21 07:51:37 2019 -0700 Merge from origin/emacs-26 aae8cc3 * admin/admin.el (set-version): Add NEWS headers for a .50 ve... commit 5185b391064ef54c6f3aae10371f682e7001f4d2 Merge: 50d00e7153 f90a3360d8 Author: Glenn Morris Date: Sun Apr 21 07:51:37 2019 -0700 ; Merge from origin/emacs-26 The following commit was skipped: f90a336 Backport doc improvement in ELisp manual commit 50d00e71530d584d20a339d3000a042c51c9d15b Merge: 3f90aa7eec 037970f1af Author: Glenn Morris Date: Sun Apr 21 07:51:36 2019 -0700 Merge from origin/emacs-26 037970f Document insert-image-file's return value (Bug#32978) 598b45a Autoload cua-toggle-rectangle-mark (Bug#34947) 95bd56d Tell xclip not to expect job-control under eshell (Bug#35257) 9997bbb ; * src/emacs.c: Fix typo in comment (Bug#35320). a4ad7be Fix off-by-one-link error in image--set-property commit 9d7e08dd8f28b1c62dfdff592ba92e8d2fa14726 (refs/remotes/origin/emacs-26) Author: Mauro Aranda Date: Mon Apr 8 20:24:32 2019 -0300 Avoid false positives and false negatives of Info-quoted face * lisp/info.el (Info-mode-font-lock-keywords): Modify the regexp, for matching single quotes of opening single quote and closing single quote, and avoid matching text followed by a curly quote when it is not quoting. (Bug#35202) diff --git a/lisp/info.el b/lisp/info.el index 301f6ece14..94b0ef6ce7 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -4262,8 +4262,9 @@ With a zero prefix arg, put the name inside a function call to `info'." ;; We deliberately fontify only ‘..’ quoting, and not `..', because ;; the former can be done much more reliably, i.e. without risking ;; false positives. +;; FIXME: It doesn't handle nested quotes. (defvar Info-mode-font-lock-keywords - '(("‘\\([^’]*\\)’" (1 'Info-quoted)))) + '(("‘\\([‘’]\\|[^‘’]*\\)’" (1 'Info-quoted)))) ;; Autoload cookie needed by desktop.el ;;;###autoload commit 75b589c7d2ebbe9e7048341cf666c185c07ec680 Author: Eli Zaretskii Date: Sun Apr 21 14:56:04 2019 +0300 Fix markup related to quoting in Info * doc/misc/sc.texi (Citations): Fix markup of '>'. * doc/misc/mh-e.texi (Speedbar): Fix markup in a @table. * doc/misc/calc.texi (Yacas Language Mode): Fix a typo. * doc/emacs/mark.texi (Setting Mark): Remove duplicate quoting. (Bug#35202) diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi index aa753888e5..5ffe7264a3 100644 --- a/doc/emacs/mark.texi +++ b/doc/emacs/mark.texi @@ -76,7 +76,7 @@ Set point and the mark around the text you drag across. @item mouse-3 Set the mark at point, then move point to where you click (@code{mouse-save-then-kill}). -@item @samp{Shifted cursor motion keys} +@item @r{Shifted cursor motion keys} Set the mark at point if the mark is inactive, then move point. @xref{Shift Selection}. @end table diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi index 7cfb7e1f0b..8ef08a36d8 100644 --- a/doc/misc/calc.texi +++ b/doc/misc/calc.texi @@ -14661,7 +14661,7 @@ conventions of Yacas, a free computer algebra system. While the operators and functions in Yacas are similar to those of Calc, the names of built-in functions in Yacas are capitalized. The Calc formula @samp{sin(2 x)}, for example, is entered and displayed @samp{Sin(2 x)} -in Yacas mode, and `@samp{arcsin(x^2)} is @samp{ArcSin(x^2)} in Yacas +in Yacas mode, and @samp{arcsin(x^2)} is @samp{ArcSin(x^2)} in Yacas mode. Complex numbers are written are written @samp{3 + 4 I}. The standard special constants are written @code{Pi}, @code{E}, @code{I}, @code{GoldenRatio} and @code{Gamma}. @code{Infinity} diff --git a/doc/misc/mh-e.texi b/doc/misc/mh-e.texi index 898b3418f8..52e22178b2 100644 --- a/doc/misc/mh-e.texi +++ b/doc/misc/mh-e.texi @@ -6294,24 +6294,24 @@ Emacs navigational keys (like the arrow keys, or @kbd{C-n}) to move the cursor over the desired folder and then use the shortcuts for the menu items listed in the table below. -@table @samp +@table @asis @findex mh-speed-view -@item Visit Folder (@key{RET}) +@item @samp{Visit Folder} (@key{RET}) Visits the selected folder just as if you had used @kbd{F v} (@code{mh-speed-view}). @c ------------------------- @findex mh-speed-expand-folder -@item Expand Nested Folders (@kbd{+}) +@item @samp{Expand Nested Folders} (@kbd{+}) Expands the selected folder in the speedbar, exposing the children folders inside it (@code{mh-speed-expand-folder}). @c ------------------------- @findex mh-speed-contract-folder -@item Contract Nested Folders (@kbd{-}) +@item @samp{Contract Nested Folders} (@kbd{-}) Contracts or collapses the selected folder in the speedbar, hiding the children folders inside it (@code{mh-speed-contract-folder}). @c ------------------------- @findex mh-speed-refresh -@item Refresh Speedbar (@kbd{r}) +@item @samp{Refresh Speedbar} (@kbd{r}) Regenerates the list of folders in the speedbar. Run this command if you've added or deleted a folder, or want to update the unseen message count before the next automatic update (@code{mh-speed-refresh}). diff --git a/doc/misc/sc.texi b/doc/misc/sc.texi index 7d53c6dbe5..d10bdc6426 100644 --- a/doc/misc/sc.texi +++ b/doc/misc/sc.texi @@ -249,10 +249,10 @@ And that's what I think too. @end menu Note that multiple inclusions of the original messages result in a -nesting of the @samp{@code{>}} characters. This can sometimes be quite +nesting of the @samp{>} characters. This can sometimes be quite confusing when many levels of citations are included since it may be difficult or impossible to figure out who actually participated in the -thread, and multiple nesting of @samp{@code{>}} characters can sometimes +thread, and multiple nesting of @samp{>} characters can sometimes make the message very difficult for the eye to scan. @cindex non-nested citations commit fd6ff29506cd55ace8fdfa1c3f370cbc7e074ec2 Merge: bacdaa5b25 cd2204f0ee Author: Eli Zaretskii Date: Sun Apr 21 14:21:52 2019 +0300 Merge branch 'emacs-26' of git.savannah.gnu.org:/srv/git/emacs into emacs-26 commit bacdaa5b25f9946290d81325e8f7b94c1705c0a2 Author: Noam Postavsky Date: Sun Feb 4 20:43:26 2018 -0500 Use pkg-config to find lcms2 CFLAGS and LIBS (Bug#30346) * configure.ac: Use EMACS_CHECK_MODULES fors LCMS2 rather than AC_SEARCH_LIBS. * src/Makefile.in: Get LCMS2_LIBS and LCMS2_CFLAGS from configure, instead of just LIBLCMS2. (cherry picked from commit cb3863370cbe574810f796726faa39ba0de0a429) diff --git a/configure.ac b/configure.ac index b712a43eea..5ad3cda6e9 100644 --- a/configure.ac +++ b/configure.ac @@ -3471,23 +3471,20 @@ fi AC_SUBST(LIBJPEG) HAVE_LCMS2=no -LIBLCMS2= +LCMS2_CFLAGS= +LCMS2_LIBS= if test "${with_lcms2}" != "no"; then - OLIBS=$LIBS - AC_SEARCH_LIBS([cmsCreateTransform], [lcms2], [HAVE_LCMS2=yes]) - LIBS=$OLIBS - case $ac_cv_search_cmsCreateTransform in - -*) LIBLCMS2=$ac_cv_search_cmsCreateTransform ;; - esac + EMACS_CHECK_MODULES([LCMS2], [lcms2]) fi if test "${HAVE_LCMS2}" = "yes"; then AC_DEFINE([HAVE_LCMS2], 1, [Define to 1 if you have the lcms2 library (-llcms2).]) ### mingw32 doesn't use -llcms2, since it loads the library dynamically. if test "${opsys}" = "mingw32"; then - LIBLCMS2= + LCMS2_LIBS= fi fi -AC_SUBST(LIBLCMS2) +AC_SUBST(LCMS2_CFLAGS) +AC_SUBST(LCMS2_LIBS) HAVE_ZLIB=no LIBZ= diff --git a/src/Makefile.in b/src/Makefile.in index 5989ab4cef..eb34b97219 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -234,7 +234,8 @@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ GETADDRINFO_A_LIBS = @GETADDRINFO_A_LIBS@ -LIBLCMS2 = @LIBLCMS2@ +LCMS2_LIBS = @LCMS2_LIBS@ +LCMS2_CFLAGS = @LCMS2_CFLAGS@ LIBZ = @LIBZ@ @@ -360,7 +361,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \ $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \ - $(WEBKIT_CFLAGS) \ + $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \ $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ $(LIBSYSTEMD_CFLAGS) \ @@ -492,7 +493,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(LIBXML2_LIBS) $(LIBGPM) $(LIBS_SYSTEM) $(CAIRO_LIBS) \ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ - $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LIBLCMS2) \ + $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) ## FORCE it so that admin/unidata can decide whether these files commit cd2204f0ee018ef29c2d8536b7e6d41dc9b10052 Author: Glenn Morris Date: Sat Apr 20 11:38:47 2019 -0700 Add a package: line to c-submit-bug-report. * lisp/progmodes/cc-mode.el (c-submit-bug-report): Add a Package: line for mail clients that do not support X- headers. diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 5283cfea6e..aa2a286dbe 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -2220,6 +2220,7 @@ Key bindings: ;; reporter-submit-bug-report requires sendmail. (declare-function mail-position-on-field "sendmail" (field &optional soft)) +(declare-function mail-text "sendmail" ()) (defun c-submit-bug-report () "Submit via mail a bug report on CC Mode." @@ -2284,9 +2285,26 @@ Key bindings: vars) (lambda () (run-hooks 'c-prepare-bug-report-hook) + (let ((hook (get mail-user-agent 'hookvar))) + (if hook + (add-hook hook + (lambda () + (save-excursion + (mail-text) + (unless (looking-at "Package: ") + (insert "Package: " c-mode-bug-package "\n\n")))) + nil t))) (save-excursion (or (mail-position-on-field "X-Debbugs-Package") - (insert c-mode-bug-package))) + (insert c-mode-bug-package)) + ;; For mail clients that do not support X- headers. + ;; Sadly reporter-submit-bug-report unconditionally adds + ;; a blank line before SALUTATION, so we can't use that. + ;; It is also sad that reporter offers no way to leave point + ;; after this line we are now inserting. + (mail-text) + (or (looking-at "Package:") + (insert "Package: " c-mode-bug-package))) (insert (format "Buffer Style: %s\nc-emacs-features: %s\n" style c-features))))))) commit a992dcabc718dc87de6b80669cff18b09e71c5e7 Author: Glenn Morris Date: Sat Apr 20 10:06:26 2019 -0700 ; Remove empty NEWS sections diff --git a/etc/NEWS b/etc/NEWS index fe7c1697a6..573c8236b2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -57,9 +57,6 @@ directory as part of the Emacs installation. This allows to build Emacs modules outside of the Emacs source tree. -* Startup Changes in Emacs 26.2 - - * Changes in Emacs 26.2 ** Emacs is now compliant with the latest version 11.0 of the Unicode Standard. @@ -69,9 +66,6 @@ Default t means don't try to load color fonts when using Xft, as they often cause crashes. Set it to nil if you really need those fonts. -* Editing Changes in Emacs 26.2 - - * Changes in Specialized Modes and Packages in Emacs 26.2 ** Dired @@ -143,9 +137,6 @@ hash value. To get back the previous behavior, customize the new option 'vc-hg-symbolic-revision-styles' to the value '("{rev}")'. -* New Modes and Packages in Emacs 26.2 - - * Incompatible Lisp Changes in Emacs 26.2 ** shadowfile config files have changed their syntax. commit ea67270752908056bc30ccc8c12196e5ce2350c3 Author: Glenn Morris Date: Sat Apr 20 10:04:18 2019 -0700 ; Add NEWS sections for 26.3 diff --git a/etc/NEWS b/etc/NEWS index c927872f4d..fe7c1697a6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -16,6 +16,33 @@ You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing 'C-u C-h C-n'. +* Installation Changes in Emacs 26.3 + + +* Startup Changes in Emacs 26.3 + + +* Changes in Emacs 26.3 + + +* Editing Changes in Emacs 26.3 + + +* Changes in Specialized Modes and Packages in Emacs 26.3 + + +* New Modes and Packages in Emacs 26.3 + + +* Incompatible Lisp Changes in Emacs 26.3 + + +* Lisp Changes in Emacs 26.3 + + +* Changes in Emacs 26.3 on Non-Free Operating Systems + + * Installation Changes in Emacs 26.2 ** Building Emacs with the '--with-xwidgets' option now requires WebKit2. commit 45b09460f9946c51d0cd92da76feed5e05e150de Author: Glenn Morris Date: Sat Apr 20 10:03:40 2019 -0700 ; Bump Emacs version to 26.2.50 diff --git a/README b/README index 38dcc637a3..2f03170418 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Copyright (C) 2001-2019 Free Software Foundation, Inc. See the end of the file for license conditions. -This directory tree holds version 26.2 of GNU Emacs, the extensible, +This directory tree holds version 26.2.50 of GNU Emacs, the extensible, customizable, self-documenting real-time display editor. The file INSTALL in this directory says how to build and install GNU diff --git a/configure.ac b/configure.ac index b712a43eea..beb3bac3a9 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see . AC_PREREQ(2.65) dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el. -AC_INIT(GNU Emacs, 26.2, bug-gnu-emacs@gnu.org) +AC_INIT(GNU Emacs, 26.2.50, bug-gnu-emacs@gnu.org) dnl Set emacs_config_options to the options of 'configure', quoted for the shell, dnl and then quoted again for a C string. Separate options with spaces. diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index 5141047a09..26d0a77b05 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -66,7 +66,7 @@ /^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/ /^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/ /^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/ -/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "26.2"/ +/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "26.2.50"/ /^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/ /^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/ /^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/ diff --git a/nt/README.W32 b/nt/README.W32 index da5151fb02..58d1adf6e1 100644 --- a/nt/README.W32 +++ b/nt/README.W32 @@ -1,7 +1,7 @@ Copyright (C) 2001-2019 Free Software Foundation, Inc. See the end of the file for license conditions. - Emacs version 26.2 for MS-Windows + Emacs version 26.2.50 for MS-Windows This README file describes how to set up and run a precompiled distribution of the latest version of GNU Emacs for MS-Windows. You commit aae8cc3304f1d769f06794fa10d9b66f74a6198c Author: Glenn Morris Date: Sat Apr 20 10:02:58 2019 -0700 * admin/admin.el (set-version): Add NEWS headers for a .50 version. diff --git a/admin/admin.el b/admin/admin.el index c1f6174874..fda6708d4c 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -138,7 +138,10 @@ Root must be the root of an Emacs source tree." (if (eq 2 (length newversion)) 0 1)))) (majorbump (and oldversion (not (equal oldmajor newmajor)))) (minorbump (and oldversion (not majorbump) - (not (equal (cadr oldversion) (cadr newversion))))) + (or (not (equal (cadr oldversion) + (cadr newversion))) + (and (equal (cadr oldversion) (cadr newversion)) + (equal (nth 2 newversion) 50))))) (newsfile (expand-file-name "etc/NEWS" root)) (oldnewsfile (expand-file-name (format "etc/NEWS.%s" oldmajor) root))) (unless (> (length newversion) 2) ; pretest or release candidate? commit f90a3360d8c724d61ff89a2e788542a4ff6cb352 Author: Eli Zaretskii Date: Sat Apr 20 10:21:02 2019 +0300 Backport doc improvement in ELisp manual * doc/lispref/processes.texi (Accepting Output): Backport: document how do avoid race conditions while waiting for all of the process's output to arrive. diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index d2ab518e5e..7331eb6376 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -1834,6 +1834,26 @@ corresponding connection contains buffered data. The function returns arrived. @end defun +If a connection from a process contains buffered data, +@code{accept-process-output} can return non-@code{nil} even after the +process has exited. Therefore, although the following loop: + +@example +;; This loop contains a bug. +(while (process-live-p process) + (accept-process-output process)) +@end example + +@noindent +will often read all output from @var{process}, it has a race condition +and can miss some output if @code{process-live-p} returns @code{nil} +while the connection still contains data. Better is to write the loop +like this: + +@example +(while (accept-process-output process)) +@end example + @node Processes and Threads @subsection Processes and Threads @cindex processes, threads commit 037970f1af6c87767501ac6d46c50abe9d3f44e0 Author: Noam Postavsky Date: Wed Apr 17 20:22:09 2019 -0400 Document insert-image-file's return value (Bug#32978) * lisp/image-file.el (insert-image-file): Document return value. diff --git a/lisp/image-file.el b/lisp/image-file.el index 46358b6eae..123a50e184 100644 --- a/lisp/image-file.el +++ b/lisp/image-file.el @@ -97,8 +97,9 @@ the variable is set using \\[customize]." ;;;###autoload (defun insert-image-file (file &optional visit beg end replace) "Insert the image file FILE into the current buffer. -Optional arguments VISIT, BEG, END, and REPLACE are interpreted as for -the command `insert-file-contents'." +Optional arguments VISIT, BEG, END, and REPLACE are interpreted +as for the command `insert-file-contents'. Return list of +absolute file name and number of characters inserted." (let ((rval (image-file-call-underlying #'insert-file-contents-literally 'insert-file-contents commit 598b45adbd8cfc39cf797465ce57a5a50fe730d5 Author: Braun Gábor Date: Fri Mar 22 16:11:44 2019 +0100 Autoload cua-toggle-rectangle-mark (Bug#34947) * lisp/emulation/cua-base.el (cua-toggle-rectangle-mark): Autoload it. Library cua-base.el binds cua-toggle-rectangle-mark to a key in the :set function in (defcustom cua-rectangle-mark-key ...), so it should ensure that the command is defined. Copyright-paperwork-exempt: yes diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index e0efd46ea2..4dd292fbdb 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -592,6 +592,7 @@ a cons (TYPE . COLOR), then both properties are affected." (autoload 'cua-set-rectangle-mark "cua-rect" "Start rectangle at mouse click position." t nil) +(autoload 'cua-toggle-rectangle-mark "cua-rect" nil t) ;; Stub definitions until it is loaded (defvar cua--rectangle) commit 95bd56df883478bc16e25d7fc5e5d25a56278b7c Author: Noam Postavsky Date: Mon Apr 15 20:38:15 2019 -0400 Tell xclip not to expect job-control under eshell (Bug#35257) * lisp/eshell/esh-proc.el (eshell-needs-pipe): Add "xclip" and other programs that xclip.el (in GNU ELPA) calls with `process-connection-type' bound to nil. diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 33ec19ae36..e5ccdf7f21 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -242,7 +242,11 @@ The prompt will be set to PROMPT." "A marker that tracks the beginning of output of the last subprocess. Used only on systems which do not support async subprocesses.") -(defvar eshell-needs-pipe '("bc") +(defvar eshell-needs-pipe + '("bc" + ;; xclip.el (in GNU ELPA) calls all of these with + ;; `process-connection-type' set to nil. + "pbpaste" "putclip" "xclip" "xsel" "wl-copy") "List of commands which need `process-connection-type' to be nil. Currently only affects commands in pipelines, and not those at the front. If an element contains a directory part it must match commit 9997bbb3ee39fd57a51c263f4f17d2b15cead334 Author: Noam Postavsky Date: Fri Apr 19 14:06:08 2019 -0400 ; * src/emacs.c: Fix typo in comment (Bug#35320). diff --git a/src/emacs.c b/src/emacs.c index 41a9327941..f2bebac8f1 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -335,7 +335,7 @@ section of the Emacs manual or the file BUGS.\n" bool fatal_error_in_progress; #ifdef HAVE_NS -/* NS autrelease pool, for memory management. */ +/* NS autorelease pool, for memory management. */ static void *ns_pool; #endif commit a4ad7bed187493c1c230f223b52c71f5c34f7c89 Author: Basil L. Contovounesios Date: Wed Apr 17 14:24:31 2019 +0100 Fix off-by-one-link error in image--set-property * lisp/image.el (image--set-property): Ensure new value is set even in the unlikely case that the plist is empty. Fix off-by-one-link error when deleting a property. (bug#35285) * test/lisp/image-tests.el: New file. (image--set-property): New test. diff --git a/lisp/image.el b/lisp/image.el index 9d2045de61..585e6e10be 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -452,10 +452,10 @@ Internal use only." ;; plist. Decouple plist entries where the key matches ;; the property. (if (eq (cadr image) property) - (setcdr image (cddr image)) + (setcdr image (cdddr image)) (setq image (cddr image)))) ;; Just enter the new value. - (plist-put (cdr image) property value)) + (setcdr image (plist-put (cdr image) property value))) value) (defun image-property (image property) diff --git a/test/lisp/image-tests.el b/test/lisp/image-tests.el new file mode 100644 index 0000000000..89b926e629 --- /dev/null +++ b/test/lisp/image-tests.el @@ -0,0 +1,45 @@ +;;; image-tests.el --- tests for image.el -*- lexical-binding: t -*- + +;; Copyright (C) 2019 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 . + +;;; Code: + +(require 'ert) +(require 'image) + +(ert-deftest image--set-property () + "Test `image--set-property' behavior." + (let ((image (list 'image))) + ;; Add properties. + (setf (image-property image :scale) 1) + (should (equal image '(image :scale 1))) + (setf (image-property image :width) 8) + (should (equal image '(image :scale 1 :width 8))) + (setf (image-property image :height) 16) + (should (equal image '(image :scale 1 :width 8 :height 16))) + ;; Delete properties. + (setf (image-property image :type) nil) + (should (equal image '(image :scale 1 :width 8 :height 16))) + (setf (image-property image :scale) nil) + (should (equal image '(image :width 8 :height 16))) + (setf (image-property image :height) nil) + (should (equal image '(image :width 8))) + (setf (image-property image :width) nil) + (should (equal image '(image))))) + +;;; image-tests.el ends here