]> code.delx.au - gnu-emacs/commitdiff
Merge branch 'project-next'
authorDmitry Gutov <dgutov@yandex.ru>
Tue, 10 Nov 2015 00:47:46 +0000 (02:47 +0200)
committerDmitry Gutov <dgutov@yandex.ru>
Tue, 10 Nov 2015 00:47:46 +0000 (02:47 +0200)
60 files changed:
CONTRIBUTE
ChangeLog.2
admin/notes/repo
doc/lispref/windows.texi
etc/NEWS
lib/intprops.h
lib/timespec-add.c
lib/timespec-sub.c
lisp/abbrev.el
lisp/bookmark.el
lisp/emacs-lisp/cl-macs.el
lisp/erc/ChangeLog.2
lisp/erc/erc-pcomplete.el
lisp/filenotify.el
lisp/frame.el
lisp/gnus/gnus-sum.el
lisp/hexl.el
lisp/json.el
lisp/progmodes/elisp-mode.el
lisp/vc/vc-bzr.el
lisp/vc/vc-git.el
lisp/vc/vc-hg.el
lisp/vc/vc-svn.el
lisp/vc/vc.el
src/alloc.c
src/buffer.c
src/casefiddle.c
src/ccl.c
src/character.c
src/coding.c
src/data.c
src/dispnew.c
src/editfns.c
src/fns.c
src/ftfont.c
src/gnutls.c
src/gtkutil.c
src/image.c
src/keymap.c
src/lisp.h
src/lread.c
src/macros.c
src/minibuf.c
src/nsterm.m
src/term.c
src/tparam.c
src/unexelf.c
src/window.h
src/xdisp.c
src/xrdb.c
src/xselect.c
src/xsmfns.c
src/xterm.c
test/automated/abbrev-tests.el [new file with mode: 0644]
test/automated/auto-revert-tests.el
test/automated/buffer-tests.el [new file with mode: 0644]
test/automated/cl-lib-tests.el
test/automated/file-notify-tests.el
test/automated/json-tests.el
test/automated/subr-tests.el

index 4d5d08a0fd53cbfbdbb9af45e0889ad86c673c1d..0ca5d0d56dbd905b5fae9f745d6afd3b743425bf 100644 (file)
@@ -201,48 +201,6 @@ then exclude that commit from the merge to trunk.
 
 ** Other process information
 
-*** Non-ASCII characters in Emacs files
-
-If you introduce non-ASCII characters into Emacs source files, it is a
-good idea to add a 'coding' cookie to the file to state its encoding.
-Please use the UTF-8 encoding unless it cannot do the job for some
-good reason.  As of Emacs 24.4, it is no longer necessary to have
-explicit 'coding' cookies in *.el files if they are encoded in UTF-8,
-but other files need them even if encoded in UTF-8.  However, if
-an *.el file is intended for use with older Emacs versions (e.g. if
-it's also distributed via ELPA), having an explicit encoding
-specification is still a good idea.
-
-*** Useful files in the admin/ directory
-
-See all the files in admin/notes/* .  In particular, see
-admin/notes/newfile, see admin/notes/repo.
-
-The file admin/MAINTAINERS records the areas of interest of frequent
-Emacs contributors.  If you are making changes in one of the files
-mentioned there, it is a good idea to consult the person who expressed
-an interest in that file, and/or get his/her feedback for the changes.
-If you are a frequent contributor and have interest in maintaining
-specific files, please record those interests in that file, so that
-others could be aware of that.
-
-*** git vs rename
-
-Git does not explicitly represent a file renaming; it uses a percent
-changed heuristic to deduce that a file was renamed.  So if you are
-planning to make extensive changes to a file after renaming it (or
-moving it to another directory), you should:
-
-- create a feature branch
-
-- commit the rename without any changes
-
-- make other changes
-
-- merge the feature branch to trunk, _not_ squashing the commits into
-  one.  The commit message on this merge should summarize the renames
-  and all the changes.
-
 ** Emacs Mailing lists.
 
 Discussion about Emacs development takes place on emacs-devel@gnu.org.
@@ -260,6 +218,17 @@ packages the patch's commit message and changes.  To send just one
 such patch without additional remarks, you can use a command like
 'git send-email --to=bug-gnu-emacs@gnu.org 0001-DESCRIPTION.patch'.
 
+** Issue tracker (a.k.a. "bug tracker")
+
+The Emacs issue tracker is at http://debbugs.gnu.org/.  The form
+presented by that page allows to view bug reports and search the
+database for bugs matching several criteria.  Messages posted to the
+bug-gnu-emacs@gnu.org mailing list, mentioned above, are recorded by
+the tracker with the corresponding bugs/issues.
+
+GNU ELPA has a 'debbugs' package that allows accessing the tracker
+database from Emacs.
+
 ** Document your changes.
 
 Any change that matters to end-users should have an entry in etc/NEWS.
@@ -301,6 +270,48 @@ implementation in more detail.
 
 The file etc/DEBUG describes how to debug Emacs bugs.
 
+*** Non-ASCII characters in Emacs files
+
+If you introduce non-ASCII characters into Emacs source files, it is a
+good idea to add a 'coding' cookie to the file to state its encoding.
+Please use the UTF-8 encoding unless it cannot do the job for some
+good reason.  As of Emacs 24.4, it is no longer necessary to have
+explicit 'coding' cookies in *.el files if they are encoded in UTF-8,
+but other files need them even if encoded in UTF-8.  However, if
+an *.el file is intended for use with older Emacs versions (e.g. if
+it's also distributed via ELPA), having an explicit encoding
+specification is still a good idea.
+
+*** Useful files in the admin/ directory
+
+See all the files in admin/notes/* .  In particular, see
+admin/notes/newfile, see admin/notes/repo.
+
+The file admin/MAINTAINERS records the areas of interest of frequent
+Emacs contributors.  If you are making changes in one of the files
+mentioned there, it is a good idea to consult the person who expressed
+an interest in that file, and/or get his/her feedback for the changes.
+If you are a frequent contributor and have interest in maintaining
+specific files, please record those interests in that file, so that
+others could be aware of that.
+
+*** git vs rename
+
+Git does not explicitly represent a file renaming; it uses a percent
+changed heuristic to deduce that a file was renamed.  So if you are
+planning to make extensive changes to a file after renaming it (or
+moving it to another directory), you should:
+
+- create a feature branch
+
+- commit the rename without any changes
+
+- make other changes
+
+- merge the feature branch to trunk, _not_ squashing the commits into
+  one.  The commit message on this merge should summarize the renames
+  and all the changes.
+
 
 \f
 This file is part of GNU Emacs.
index 599a4c85b9ca56921366762523ce8d32ce59a027..a915adbd80c6e9d89c34442fcd88903b9bcb3ee1 100644 (file)
@@ -1,6 +1,356 @@
+2015-11-08  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Prefer xpalloc to doubling buffers by hand
+
+       * src/lread.c (grow_read_buffer): New function, which uses xpalloc.
+       (read1): Use it for simplicity.
+       * src/macros.c (store_kbd_macro_char):
+       * src/minibuf.c (read_minibuf_noninteractive):
+       * src/term.c (encode_terminal_code):
+       * src/xrdb.c (magic_db):
+       Prefer xpalloc to growing buffers by hand.
+       This doesn’t fix any bugs, but simplifies the code a bit.
+
+2015-11-08  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Merge from gnulib
+
+       This incorporates:
+       2015-11-05 timespec-sub: fix overflow bug; add tests
+       2015-11-04 intprops: revise _WRAPV macros, revert _OVERFLOW
+       2015-11-03 intprops: add parentheses
+       * lib/intprops.h, lib/timespec-add.c, lib/timespec-sub.c:
+       Copy from gnulib.
+
+2015-11-07  David Reitter  <david.reitter@gmail.com>
+
+       Provide NS notification objects where required to eliminate warnings
+
+       * nsterm.m (windowDidResize:, toggleFullScreen:):
+       Call notification functions with notification objects
+       as per delegate APIs.
+
+2015-11-07  Noam Postavsky  <npostavs@users.sourceforge.net>
+
+       Add test for bug #21824
+
+       * test/automated/buffer-tests.el: New file.
+       (overlay-modification-hooks-message-other-buf): New test.
+
+2015-11-07  Kelvin White  <kwhite@gnu.org>
+
+       * lisp/erc/erc-pcomplete.el (pcomplete-erc-nicks): Fix bug#18771.
+
+2015-11-07  David Reitter  <david.reitter@gmail.com>
+
+       Ignore fullscreen exit notifications on NS when frame is dead
+
+       * nsterm.m (windowDidResize:, windowWillExitFullScreen:)
+       (windowDidExitFullScreen:): Return if frame is dead.
+       These functions may be called when a fullscreen frame
+       is closed; they are called before, not after.
+
+       May address Bug#21428.
+
+2015-11-07  Eli Zaretskii  <eliz@gnu.org>
+
+       Speed up lookup in redisplay--variables
+
+       * lisp/frame.el (redisplay--variables): Make it a hash-table.
+
+       * src/xdisp.c (maybe_set_redisplay): Access redisplay--variables
+       as a hash-table.  This speeds up this function by an order of
+       magnitude: where previously a setq was slowed down by 100% by
+       introducing the maybe_set_redisplay test, it is now only 5%
+       slower.
+       (syms_of_xdisp) <redisplay--variables>: Doc fix.
+
+2015-11-07  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/emacs-lisp/cl-macs.el (cl-defstruct): Fix a bug.
+
+       The defsubst was being created as:
+           (cl-defsubst name (args) ("DOC") ...)
+
+       * test/automated/cl-lib-tests.el (cl-lib-struct-constructors):
+       Add test.
+
+2015-11-07  Mihai Olteanu  <mihai_olteanu@fastmail.fm>  (tiny change)
+
+       Update doc string of hexl-mode
+
+       * lisp/hexl.el (hexl-mode): Doc fix.  (Bug#21800)
+
+2015-11-07  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix error in copy-abbrev-table
+
+       * lisp/abbrev.el (define-abbrev): Don't erase the :abbrev-table-modiff
+       property of the abbrev-table.  (Bug#21828)
+
+       * test/automated/abbrev-tests.el: New file.
+
+2015-11-07  Michael Albinus  <michael.albinus@gmx.de>
+
+       Add test to auto-revert-tests.el for Bug#21841
+
+       * test/automated/auto-revert-tests.el
+       (auto-revert-test01-auto-revert-several-files): New test.
+       (auto-revert-test02-auto-revert-tail-mode)
+       (auto-revert-test03-auto-revert-mode-dired): Rename them.
+
+2015-11-07  Martin Rudalics  <rudalics@gmx.at>
+
+       * doc/lispref/windows.texi (Coordinates and Windows): Fix typo.
+
+2015-11-07  Martin Rudalics  <rudalics@gmx.at>
+
+       In x_consider_frame_title don't set title of tooltip frames
+
+       * src/xdisp.c (x_consider_frame_title): Return immediately for
+       tooltip frames to avoid displaying empty tooltips.
+
+2015-11-06  Anders Lindgren  <andlind@gmail.com>
+
+       Fixed NextStep fullscreen problem (bug#21770).
+
+       * src/nsterm.m (ns_constrain_all_frames): Don't constrain
+       fullscreen frames.
+
+2015-11-06  Eli Zaretskii  <eliz@gnu.org>
+
+       Ensure redisplay after evaluation
+
+       * lisp/progmodes/elisp-mode.el (elisp--eval-last-sexp):
+       Revert last change.
+       * lisp/frame.el (redisplay--variables): Populate the
+       redisplay--variables list.
+       * src/xdisp.c (maybe_set_redisplay): New function.
+       (syms_of_xdisp) <redisplay--variables>: New variable.
+       * src/window.h (maybe_set_redisplay): Declare prototype.
+       * src/data.c (set_internal): Call maybe_set_redisplay.  (Bug#21835)
+
+2015-11-06  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * test/automated/subr-tests.el (subr-test-when): Fix again.
+
+2015-11-06  Eli Zaretskii  <eliz@gnu.org>
+
+       Don't invoke overlay modification hooks in wrong buffer
+
+       * src/buffer.c (report_overlay_modification): When called with
+       AFTER non-zero, don't invoke overlay modification hooks if the
+       buffer recorded in last_overlay_modification_hooks is different
+       from the current buffer.  (Bug#21824)
+
+2015-11-06  Juanma Barranquero  <lekktu@gmail.com>
+
+       * admin/notes/repo: Fix a few obsolete references to Bazaar.
+
+2015-11-06  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * test/automated/subr-tests.el (subr-test-when): Fix test.
+
+2015-11-06  Martin Rudalics  <rudalics@gmx.at>
+
+       Avoid division by zero crash observed by Yuan MEI
+
+       See http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg00194.html.
+
+       * src/dispnew.c (required_matrix_height, required_matrix_width):
+       Avoid division by zero.
+       * src/xterm.c (x_term_init): Init dpyinfo->smallest_font_height and
+       dpyinfo->smallest_char_width to 1.
+
+2015-11-06  Eli Zaretskii  <eliz@gnu.org>
+
+       Ensure redisplay after "C-x C-e"
+
+       * lisp/progmodes/elisp-mode.el (elisp--eval-last-sexp): Make sure
+       redisplay happens to account for any side effects of the evaluated
+       sexp.  (Bug#21835)
+
+2015-11-06  Michael Albinus  <michael.albinus@gmx.de>
+
+       Skip some file notification tests for cygwin
+
+       * test/automated/file-notify-tests.el (file-notify--test-with-events):
+       Remove argument TIMEOUT.  Adapt all callees.
+       (file-notify-test02-events, file-notify-test04-file-validity):
+       Skip for cygwin.  (Bug#21804)
+
+2015-11-05  Stephen Leake  <stephen_leake@stephe-leake.org>
+
+       * lisp/progmodes/xref.el: Require semantic/symref during compilation.
+
+2015-11-05  Daiki Ueno  <ueno@gnu.org>
+
+       Suppress redundant Pinentry startup messages
+
+       * lisp/net/pinentry.el (pinentry-start): Add optional QUIET argument.
+       * lisp/epg.el: Declare `pinentry-start'.
+       (epg--start): Call `pinentry-start' with QUIET argument set.
+
+2015-11-05  Xue Fuqiao  <xfq.free@gmail.com>
+
+       * doc/emacs/ack.texi (Acknowledgments): Updates.
+
+2015-11-05  Juanma Barranquero  <lekktu@gmail.com>
+
+       * test/automated/elisp-mode-test.el: Silence some run-time warnings.
+       (xref-elisp-deftest): Bind `find-file-suppress-same-file-warnings' to t.
+
+2015-11-05  Tassilo Horn  <tsdh@gnu.org>
+
+       * lisp/textmodes/tex-mode.el (tex--prettify-symbols-alist):
+       Add prettification support for \times.
+
+2015-11-05  Juanma Barranquero  <lekktu@gmail.com>
+
+       * test/automated/process-tests.el: Skip tests when bash is unavailable.
+       (process-test-sentinel-accept-process-output)
+       (process-test-sentinel-sit-for): skip-unless bash executable found.
+
+2015-11-05  Eli Zaretskii  <eliz@gnu.org>
+
+       Add test for bug #21831
+
+       * test/automated/process-tests.el
+       (start-process-should-not-modify-arguments): New test.  (Bug#21831)
+       Suggested by Nicolas Richard <youngfrog@members.fsf.org>
+
+2015-11-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * lisp/emacs-lisp/eieio-compat.el: Typo caught by tests.
+
+       (eieio--generic-static-object-generalizer): Fix typo.
+       * test/automated/eieio-tests.el: Byte-compile it again.  It looks
+       like the underlying cause of bug#17852 was fixed in the mean time.
+
+2015-11-04  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       Revert "* lisp/subr.el (when): Use `macroexp-progn'"
+
+       This reverts commit 8e843831eaf271801836b7a3e4dd3b4fb0bb72b8.
+       It breaks bootstrapping (duh).
+
+2015-11-04  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/files.el (report-errors): Obsolete.
+
+       (normal-mode, hack-local-variables, dir-locals-find-file):
+       Use `with-demoted-errors' instead.
+
+2015-11-04  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/subr.el (when): Use `macroexp-progn'.
+
+       * test/automated/subr-tests.el (subr-test-when): New test.
+
+2015-11-04  Juanma Barranquero  <lekktu@gmail.com>
+
+       * lisp/progmodes/xref.el: Doc fixes.
+       (xref-make-file-location, xref-make-buffer-location, xref-make)
+       (xref-make-bogus-location, xref-make-match): Add cross-references.
+       (xref--insert-xrefs): Fix typo in docstring.
+
+2015-11-04  Anders Lindgren  <andlind@gmail.com>
+
+       Render fringe bitmaps correctly on NextStep (bug#21301)
+
+       The fringe bitmaps were inverted, the background was not transparent,
+       the image data was horizontally mirrored, and periodic fringe bitmaps
+       were not supported.
+
+       * src/nsimage.m ([EmacsImage initFromXBM:width:height:fg:bg:]):
+       When both background and foreground colors are 0, set the background
+       alpha channel to 0 (making the background transparent).  When
+       copying the image data, do this from the most significant bit
+       (leftmost) to the least (rightmost), to avoid mirroring.
+       * src/nsterm.m (ns_draw_fringe_bitmap): Don't invert the image bits.
+       Add support for periodic images (e.g. the empty line indicator).
+
+2015-11-03  Michael Heerdegen  <michael_heerdegen@web.de>
+
+       * lisp/emacs-lisp/pcase.el (pcase): Tweak docstring.
+
+2015-11-03  Nicolas Petton  <nicolas@petton.fr>
+
+       * admin/MAINTAINERS: Add seq-tests.el, map-tests.el, and thunk-tests.el.
+
+       * admin/MAINTAINERS: Add thunk.el.
+
+2015-11-03  Jay Belanger  <jay.p.belanger@gmail.com>
+
+       * lisp/calc/calc (calc-bug-address): Change maintainer address.
+
+2015-11-03  Michael Albinus  <michael.albinus@gmx.de>
+
+       Fix a stupid error in gfilenotify.c
+
+       * src/gfilenotify.c (dir_monitor_callback): Cancel monitor only,
+       if we've got a `deleted' signal AND the file name is the watched one.
+
+2015-11-03  Stephen Leake  <stephen_leake@stephe-leake.org>
+
+       Fix Bug#21816; case insensitive file system in elisp-mode-tests.el
+
+       * test/automated/elisp-mode-tests.el (xref-elisp-test-run):
+       Use case-insensitive string compare for file names.
+       (emacs-test-dir): Add 'downcase' to cause case differences (at
+       least on my system).
+
+2015-11-02  Juanma Barranquero  <lekktu@gmail.com>
+
+       flymake-tests.el (warning-predicate-rx-gcc): Fix check
+
+       * test/automated/flymake-tests.el (warning-predicate-rx-gcc):
+       Also check that "make" is available, not just "gcc".
+
+2015-11-02  Ken Brown  <kbrown@cornell.edu>
+
+       Document behavior of collation on Cygwin
+
+       * test/automated/fns-tests.el (fns-tests-collate-sort): Mark as
+       expected failure on Cygwin.
+       * doc/lispref/strings.texi (Text Comparison): Document that
+       punctuation and whitespace are not ignored for sorting on Cygwin.
+
+2015-11-02  Dani Moncayo  <dmoncayo@gmail.com>
+
+       * build-aux/msys-to-w32: Prevent double slashes in w32 path list.
+
+2015-11-01  Glenn Morris  <rgm@gnu.org>
+
+       * lisp/progmodes/f90.el (f90-no-block-limit): Add associate.
+       (Bug#21794)
+       * test/automated/f90.el (f90-test-bug21794): New test.
+
+2015-11-01  Juanma Barranquero  <lekktu@gmail.com>
+
+       Fix incompatibility with TCC in test for bug#18745
+
+       * test/automated/process-tests.el (process-test-quoted-batfile):
+       Remove spaces unrelated to the bug being tested.
+
+2015-11-01  Michael Albinus  <michael.albinus@gmx.de>
+
+       Improve completion in tramp-gvfs.el
+
+       * lisp/net/tramp-gvfs.el (tramp-zeroconf-parse-device-names):
+       Rename from `tramp-zeroconf-parse-service-device-names'.
+       (tramp-zeroconf-parse-webdav-device-names): Remove.  Code merged
+       with `tramp-zeroconf-parse-device-names'.
+       (tramp-gvfs-parse-device-names): New defun.
+       (top): Use it when `tramp-zeroconf-parse-device-names' is not
+       applicable.
+
+       * lisp/net/tramp.el (tramp-set-completion-function): The argument
+       could also be a zeroconf service type.
+
 2015-10-31  Thomas Fitzsimmons  <fitzsim@fitzsim.org>
 
-       ntlm.el: Change version to 2.0.0
+       * lisp/net/ntlm.el: Change version to 2.0.0.
 
 2015-10-31  Juanma Barranquero  <lekktu@gmail.com>
 
 
        * lisp/net/soap-client.el, lisp/net/soap-inspect.el: Update home page.
 
+2015-10-25  Eli Zaretskii  <eliz@gnu.org>
+
+       * lisp/progmodes/grep.el (grep): Doc fix.  (Bug#21754)
+
+2015-10-25  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * src/keyboard.c (post-command-hook): Extend the docstring.
+       Mainly, explain how to use it without hanging Emacs, or giving the
+       impression that it is hanging.  Also mention `pre-command-hook'.
+       (pre-command-hook): Mention `post-command-hook'.
+
+2015-10-25  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/custom.el (custom-declare-variable): Shorten code again.
+       Without using pcase this time.  We can't use pcase because it is
+       loaded after custom in loadup.el.  Also add a comment explaining
+       this to future dummies like me.
+
+2015-10-25  Michael Albinus  <michael.albinus@gmx.de>
+
+       * doc/lispref/os.texi (File Notifications): Document `stopped event'.
+
+2015-10-25  Michael Albinus  <michael.albinus@gmx.de>
+
+       Introduce `stopped' event in file notification
+
+       * lisp/filenotify.el (file-notify--rm-descriptor): New defun.
+       (file-notify-rm-watch): Use it.
+       (file-notify-callback): Implement `stopped' event.
+       (file-notify-add-watch): Mention `stopped' in the docstring.
+       Check, that upper directory exists.
+
+       * test/automated/file-notify-tests.el (file-notify-test01-add-watch):
+       Add two test cases.
+       (file-notify-test02-events): Handle also `stopped' event.
+       (file-notify-test04-file-validity): Add another test case.
+
+2015-10-25  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Revert commit that broke 'make bootstrap'
+
+       * lisp/custom.el (custom-declare-variable): Revert commit
+       79fac080d277fed07b3c192890ad59d36d9f83b6.  custom.el needs to work
+       even when pcase has not been defined yet, when doing bootstrapping.
+
+2015-10-25  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Port recent inline functions fix to Standard C
+
+       * src/lisp.h (LISP_MACRO_DEFUN, LISP_MACRO_DEFUN_VOID): Remove.
+       All uses rewritten to define the function directly rather than to
+       use a macro to define the function.  This conforms to Standard C,
+       which does not allow stray semicolons at the top level.  I hope it
+       also avoids the problems with TAGS.  Those macros, though clever,
+       were pretty confusing anyway, and it wasn’t clear they were worth
+       the aggravation even without the TAGS problem.
+
+2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/isearch.el: Make character-fold search the default again.
+
+2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/character-fold.el: Many improvements.
+       (character-fold-search-forward, character-fold-search-backward):
+       New command.
+       (character-fold-to-regexp): Remove lax-whitespace hack.
+       (character-fold-search): Remove variable.  Only isearch and
+       query-replace use char-folding, and they both have their own
+       variables to configure that.
+
+2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/isearch.el: Generalize definition of regexp-function toggles.
+       (isearch-specify-regexp-function): New macro for specifying
+       possible values of `isearch-regexp-function'.
+       (isearch-toggle-character-fold, isearch-toggle-symbol)
+       (isearch-toggle-word): Define with `isearch-specify-regexp-function'.
+
+2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/isearch.el (search-default-regexp-mode): New variable.
+       (isearch-mode): Use it.
+
+2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/isearch.el (search-exit-option, search-slow-window-lines)
+       (search-slow-speed, search-upper-case)
+       (search-nonincremental-instead, search-whitespace-regexp)
+       (search-invisible, isearch-hide-immediately)
+       (isearch-resume-in-command-history, search-ring-max)
+       (regexp-search-ring-max, search-ring-update, search-highlight)
+       (isearch-fail): Delete :group entries.
+
+2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
+
+       * lisp/custom.el (custom-declare-variable): Shorten code a bit.
+
+2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
+
+       addpm.c: Silence some warnings.
+
+       * nt/addpm.c (DdeCommand): Cast pData argument of DdeClientTransaction
+       to LPBYTE.
+       (add_registry): Pass NULL to optional lpClass argument of
+       RegCreateKeyEx, not an empty string.
+
+2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
+
+       addpm.c: Do not add obsolete GTK libraries to the path.
+
+       * nt/addpm.c (REG_GTK, REG_RUNEMACS_PATH): Delete.
+       (add_registry): Remove variables `size' and `gtk_key'.
+       Do not add the GTK DLL directory to the library search path; it is
+       confusing behavior (in particular, the same Emacs version with and
+       without invoking addpm will use a different path), and the GTK image
+       libraries are obsolete anyway.
+
+2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
+
+       addpm.c: Replace existing registry entries, but do not create new ones
+
+       * nt/addpm.c (add_registry): If the Emacs registry key exists, replace
+       existing values from previous versions, but do not add new ones; the
+       key could exist for other reasons unrelated to old Emacsen, like X-style
+       resources, or to set some environment variables like HOME or LANG, and
+       in that case we don't want to populate it with obsolete values.
+
+2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
+
+       * nt/addpm.c (add_registry): Do not compute unused return value.
+
+2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
+
+       addpm.c: Don't pass REG_OPTION_NON_VOLATILE to RegOpenKeyEx
+
+       * nt/addpm.c (add_registry): Pass 0 to ulOptions argument of
+       RegOpenKeyEx, not REG_OPTION_NON_VOLATILE.  This doesn't change
+       current behavior because REG_OPTION_NON_VOLATILE is defined to
+       be 0L anyway, but that option is actually documented only for
+       RegCreateKeyEx.
+
+2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
+
+       * src/w32notify.c (Fw32notify_add_watch): Fix version check.
+
+2015-10-24  Eli Zaretskii  <eliz@gnu.org>
+
+       Update frame title when redisplay scrolls selected window
+
+       * src/xdisp.c (redisplay_window): Reconsider the frame's title
+       when the mode-line of the frame's selected window needs to be
+       updated.
+
+2015-10-24  Eli Zaretskii  <eliz@gnu.org>
+
+       Update frame title when scrolling the selected window
+
+       * src/window.c (wset_update_mode_line): New function, sets either
+       the window's update_mode_line flag or the global update_mode_lines
+       variable.
+       (Fset_window_start, set_window_buffer, window_scroll_pixel_based)
+       (window_scroll_line_based): Call it instead of only setting the
+       window's update_mode_line flag.
+
+2015-10-24  Eli Zaretskii  <eliz@gnu.org>
+
+       An even better fix for bug#21739
+
+       * src/window.c (set_window_buffer): If the window is the frame's
+       selected window, set update_mode_lines, not the window's
+       update_mode_line flag.
+       * src/buffer.c (Fkill_buffer): Undo last change.
+       (set_update_modelines_for_buf): Function deleted.
+
+2015-10-24  Thomas Fitzsimmons  <fitzsim@fitzsim.org>
+           Alexandru Harsanyi  <AlexHarsanyi@gmail.com>
+
+       Sync with soap-client repository, version 3.0.0
+
        * lisp/net/soap-client.el, lisp/net/soap-inspect.el:
        Bump version to 3.0.0.
 
        * lisp/net/soap-client.el (soap-invoke): Encode the string for
        `url-request-data' as UTF-8.  Fixes issue 16.
 
-2015-10-25  Eli Zaretskii  <eliz@gnu.org>
-
-       * lisp/progmodes/grep.el (grep): Doc fix.  (Bug#21754)
-
-2015-10-25  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * src/keyboard.c (post-command-hook): Extend the docstring.
-       Mainly, explain how to use it without hanging Emacs, or giving the
-       impression that it is hanging.  Also mention `pre-command-hook'.
-       (pre-command-hook): Mention `post-command-hook'.
-
-2015-10-25  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/custom.el (custom-declare-variable): Shorten code again.
-       Without using pcase this time.  We can't use pcase because it is
-       loaded after custom in loadup.el.  Also add a comment explaining
-       this to future dummies like me.
-
-2015-10-25  Michael Albinus  <michael.albinus@gmx.de>
-
-       * doc/lispref/os.texi (File Notifications): Document `stopped event'.
-
-2015-10-25  Michael Albinus  <michael.albinus@gmx.de>
-
-       Introduce `stopped' event in file notification
-
-       * lisp/filenotify.el (file-notify--rm-descriptor): New defun.
-       (file-notify-rm-watch): Use it.
-       (file-notify-callback): Implement `stopped' event.
-       (file-notify-add-watch): Mention `stopped' in the docstring.
-       Check, that upper directory exists.
-
-       * test/automated/file-notify-tests.el (file-notify-test01-add-watch):
-       Add two test cases.
-       (file-notify-test02-events): Handle also `stopped' event.
-       (file-notify-test04-file-validity): Add another test case.
-
-2015-10-25  Paul Eggert  <eggert@cs.ucla.edu>
-
-       Revert commit that broke 'make bootstrap'
-
-       * lisp/custom.el (custom-declare-variable): Revert commit
-       79fac080d277fed07b3c192890ad59d36d9f83b6.  custom.el needs to work
-       even when pcase has not been defined yet, when doing bootstrapping.
-
-2015-10-25  Paul Eggert  <eggert@cs.ucla.edu>
-
-       Port recent inline functions fix to Standard C
-
-       * src/lisp.h (LISP_MACRO_DEFUN, LISP_MACRO_DEFUN_VOID): Remove.
-       All uses rewritten to define the function directly rather than to
-       use a macro to define the function.  This conforms to Standard C,
-       which does not allow stray semicolons at the top level.  I hope it
-       also avoids the problems with TAGS.  Those macros, though clever,
-       were pretty confusing anyway, and it wasn’t clear they were worth
-       the aggravation even without the TAGS problem.
-
-2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/isearch.el: Make character-fold search the default again.
-
-2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/character-fold.el: Many improvements.
-       (character-fold-search-forward, character-fold-search-backward):
-       New command.
-       (character-fold-to-regexp): Remove lax-whitespace hack.
-       (character-fold-search): Remove variable.  Only isearch and
-       query-replace use char-folding, and they both have their own
-       variables to configure that.
-
-2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/isearch.el: Generalize definition of regexp-function toggles.
-       (isearch-specify-regexp-function): New macro for specifying
-       possible values of `isearch-regexp-function'.
-       (isearch-toggle-character-fold, isearch-toggle-symbol)
-       (isearch-toggle-word): Define with `isearch-specify-regexp-function'.
-
-2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/isearch.el (search-default-regexp-mode): New variable.
-       (isearch-mode): Use it.
-
-2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/isearch.el (search-exit-option, search-slow-window-lines)
-       (search-slow-speed, search-upper-case)
-       (search-nonincremental-instead, search-whitespace-regexp)
-       (search-invisible, isearch-hide-immediately)
-       (isearch-resume-in-command-history, search-ring-max)
-       (regexp-search-ring-max, search-ring-update, search-highlight)
-       (isearch-fail): Delete :group entries.
-
-2015-10-24  Artur Malabarba  <bruce.connor.am@gmail.com>
-
-       * lisp/custom.el (custom-declare-variable): Shorten code a bit.
-
-2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
-
-       addpm.c: Silence some warnings.
-
-       * nt/addpm.c (DdeCommand): Cast pData argument of DdeClientTransaction
-       to LPBYTE.
-       (add_registry): Pass NULL to optional lpClass argument of
-       RegCreateKeyEx, not an empty string.
-
-2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
-
-       addpm.c: Do not add obsolete GTK libraries to the path.
-
-       * nt/addpm.c (REG_GTK, REG_RUNEMACS_PATH): Delete.
-       (add_registry): Remove variables `size' and `gtk_key'.
-       Do not add the GTK DLL directory to the library search path; it is
-       confusing behavior (in particular, the same Emacs version with and
-       without invoking addpm will use a different path), and the GTK image
-       libraries are obsolete anyway.
-
-2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
-
-       addpm.c: Replace existing registry entries, but do not create new ones
-
-       * nt/addpm.c (add_registry): If the Emacs registry key exists, replace
-       existing values from previous versions, but do not add new ones; the
-       key could exist for other reasons unrelated to old Emacsen, like X-style
-       resources, or to set some environment variables like HOME or LANG, and
-       in that case we don't want to populate it with obsolete values.
-
-2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
-
-       * nt/addpm.c (add_registry): Do not compute unused return value.
-
-2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
-
-       addpm.c: Don't pass REG_OPTION_NON_VOLATILE to RegOpenKeyEx
-
-       * nt/addpm.c (add_registry): Pass 0 to ulOptions argument of
-       RegOpenKeyEx, not REG_OPTION_NON_VOLATILE.  This doesn't change
-       current behavior because REG_OPTION_NON_VOLATILE is defined to
-       be 0L anyway, but that option is actually documented only for
-       RegCreateKeyEx.
-
-2015-10-24  Juanma Barranquero  <lekktu@gmail.com>
-
-       * src/w32notify.c (Fw32notify_add_watch): Fix version check.
-
-2015-10-24  Eli Zaretskii  <eliz@gnu.org>
-
-       Update frame title when redisplay scrolls selected window
-
-       * src/xdisp.c (redisplay_window): Reconsider the frame's title
-       when the mode-line of the frame's selected window needs to be
-       updated.
-
-2015-10-24  Eli Zaretskii  <eliz@gnu.org>
-
-       Update frame title when scrolling the selected window
-
-       * src/window.c (wset_update_mode_line): New function, sets either
-       the window's update_mode_line flag or the global update_mode_lines
-       variable.
-       (Fset_window_start, set_window_buffer, window_scroll_pixel_based)
-       (window_scroll_line_based): Call it instead of only setting the
-       window's update_mode_line flag.
-
-2015-10-24  Eli Zaretskii  <eliz@gnu.org>
-
-       An even better fix for bug#21739
-
-       * src/window.c (set_window_buffer): If the window is the frame's
-       selected window, set update_mode_lines, not the window's
-       update_mode_line flag.
-       * src/buffer.c (Fkill_buffer): Undo last change.
-       (set_update_modelines_for_buf): Function deleted.
-
-2015-10-24  Thomas Fitzsimmons  <fitzsim@fitzsim.org>
-
-       Sync with soap-client repository, version 3.0.0
-
 2015-10-24  Nicolas Petton  <nicolas@petton.fr>
 
        Update the new icon
 
 This file records repository revisions from
 commit 9d56a21e6a696ad19ac65c4b405aeca44785884a (exclusive) to
-commit cb56d4cec80a4da41710e2fa68dcd3d95e2a8e4c (inclusive).
+commit 8a8613bcf4227dfe46a694b761e9575bdf6ca2ce (inclusive).
 See ChangeLog.1 for earlier changes.
 
 ;; Local Variables:
index b27a3f42891d10dce2f1bf6dee8c3a3d2abca220..3ab3da78071752842cf77aca1210a4686e074336 100644 (file)
@@ -41,8 +41,8 @@ preferable not to merge from master until you are done with the
 feature.  Unless you really need some change that was done on the
 master while you were developing on the branch, you don't really need
 those merges; just merge once, when you are done with the feature, and
-Bazaar will take care of the rest.  Bazaar is much better in this than
-CVS, so interim merges are unnecessary.
+Git will take care of the rest.  Git is much better in this than CVS,
+so interim merges are unnecessary.
 
 Or use shelves; or rebase; or do something else.  See the thread for
 yet another fun excursion into the exciting world of version control.
index 1da2d1cfe7ba8636898eca93e40f0e2fd3f65331..357247ef433af18c93223e5c71507cd87df0d346 100644 (file)
@@ -3899,7 +3899,7 @@ visible in some window:
 @group
 (let ((edges (window-absolute-body-pixel-edges))
       (position (pos-visible-in-window-p nil nil t)))
-  (x-set-mouse-absolute-pixel-position
+  (set-mouse-absolute-pixel-position
    (+ (nth 0 edges) (nth 0 position))
    (+ (nth 1 edges) (nth 1 position))))
 @end group
index 57cc4084084fee6b1b70c8550d318d634651444e..4c5639ffd3d10247c969770250348107c5100fcf 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -321,6 +321,10 @@ standards.
 \f
 * Changes in Specialized Modes and Packages in Emacs 25.1
 
+** New function `bookmark-set-no-overwrite' bound to C-x r M.
+It raises an error if a bookmark of that name already exists,
+unlike `bookmark-set' which silently updates an existing bookmark.
+
 ** JSON
 ---
 *** `json-pretty-print' and `json-pretty-print-buffer' now maintain
index 4441f1c294e7215db3aabdcf76825016b9406781..c55c4db1034982c2077a6d050cc270615fe56b52 100644 (file)
 
    The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators
    might not yield numerically correct answers due to arithmetic overflow.
-   The INT_<op>_WRAPV macros return the low-order bits of the answer.
-   For example, INT_ADD_WRAPV (INT_MAX, 1) returns INT_MIN on a two's
-   complement host, even if INT_MAX + 1 would trap.
-
+   The INT_<op>_WRAPV macros also store the low-order bits of the answer.
    These macros work correctly on all known practical hosts, and do not rely
    on undefined behavior due to signed arithmetic overflow.
 
-   Example usage:
+   Example usage, assuming A and B are long int:
 
-     long int a = ...;
-     long int b = ...;
      long int result = INT_MULTIPLY_WRAPV (a, b);
      printf ("result is %ld (%s)\n", result,
              INT_MULTIPLY_OVERFLOW (a, b) ? "after overflow" : "no overflow");
 
-     enum {
-       INT_PRODUCTS_FIT_IN_LONG
-         = ! INT_CONST_MULTIPLY_OVERFLOW ((long int) INT_MIN, INT_MIN)
-     };
+   Example usage with WRAPV flavor:
+
+     long int result;
+     bool overflow = INT_MULTIPLY_WRAPV (a, b, &result);
+     printf ("result is %ld (%s)\n", result,
+             overflow ? "after overflow" : "no overflow");
 
    Restrictions on these macros:
 
    These macros may evaluate their arguments zero or multiple times, so the
    arguments should not have side effects.
 
-   On non-GCC-compatible compilers that do not support C11, the type
-   of INT_<op>_WRAPV (A, B) might differ from the native type of (A op
-   B), so it is wise to convert the result to the native type.  Such a
-   conversion is safe and cannot trap.
-
-   For runtime efficiency GCC 5 and later has builtin functions for +,
-   -, * when doing integer overflow checking or wraparound arithmetic.
-   Unfortunately, these builtins require nonnull pointer arguments and
-   so cannot be used in constant expressions; see GCC bug 68120
-   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68120>.  In constant
-   expressions, use the macros INT_CONST_ADD_OVERFLOW and
-   INT_CONST_ADD_WRAPV instead, and similarly for SUBTRACT and
-   MULTIPLY; these macros avoid the builtins and are slower in
-   non-constant expressions.  Perhaps someday GCC's API for overflow
-   checking will be improved and we can remove the need for the
-   INT_CONST_ variants.
+   The WRAPV macros are not constant expressions.  They support only
+   +, binary -, and *.  The result type must be signed.
 
    These macros are tuned for their last argument being a constant.
 
    Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,
    A % B, and A << B would overflow, respectively.  */
 
-#define INT_CONST_ADD_OVERFLOW(a, b) \
+#define INT_ADD_OVERFLOW(a, b) \
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
-#define INT_CONST_SUBTRACT_OVERFLOW(a, b) \
+#define INT_SUBTRACT_OVERFLOW(a, b) \
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)
 #define INT_NEGATE_OVERFLOW(a) \
   INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
-#define INT_CONST_MULTIPLY_OVERFLOW(a, b) \
+#define INT_MULTIPLY_OVERFLOW(a, b) \
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
 #define INT_DIVIDE_OVERFLOW(a, b) \
   _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW)
                       _GL_INT_MINIMUM (0 * (b) + (a)),          \
                       _GL_INT_MAXIMUM (0 * (b) + (a)))
 
-/* Return the low order bits of the integer expressions
-   A * B, A - B, -A, A * B, A / B, A % B, and A << B, respectively.
-   See above for restrictions.  */
-#define INT_CONST_ADD_WRAPV(a, b) _GL_INT_OP_WRAPV (a, b, +)
-#define INT_CONST_SUBTRACT_WRAPV(a, b) _GL_INT_OP_WRAPV (a, b, -)
-#define INT_NEGATE_WRAPV(a) INT_CONST_SUBTRACT_WRAPV (0, a)
-#define INT_CONST_MULTIPLY_WRAPV(a, b) _GL_INT_OP_WRAPV (a, b, *)
-#define INT_DIVIDE_WRAPV(a, b) \
-  (INT_DIVIDE_OVERFLOW(a, b) ? INT_NEGATE_WRAPV (a) : (a) / (b))
-#define INT_REMAINDER_WRAPV(a, b) \
-  (INT_REMAINDER_OVERFLOW(a, b) ? 0 : (a) % (b))
-#define INT_LEFT_SHIFT_WRAPV(a, b) _GL_INT_OP_WRAPV (a, b, <<)
-
-/* Return the low order bits of A <op> B, where OP specifies the operation.
-   See above for restrictions.  */
-#if !_GL_HAVE___TYPEOF__ && 201112 <= __STDC_VERSION__
-# define _GL_INT_OP_WRAPV(a, b, op) \
-   _Generic ((a) op (b), \
-             int: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, int), \
-             long int: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long int), \
-             long long int: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, \
-                                                           long long int), \
-             default: (a) op (b))
+/* Compute A + B, A - B, A * B, respectively, storing the result into *R.
+   Return 1 if the result overflows.  See above for restrictions.  */
+#define INT_ADD_WRAPV(a, b, r) \
+  _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW)
+#define INT_SUBTRACT_WRAPV(a, b, r) \
+  _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW)
+#define INT_MULTIPLY_WRAPV(a, b, r) \
+  _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW)
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390.  See:
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
+   https://llvm.org/bugs/show_bug.cgi?id=25390
+   For now, assume all versions of GCC-like compilers generate bogus
+   warnings for _Generic.  This matters only for older compilers that
+   lack __builtin_add_overflow.  */
+#if __GNUC__
+# define _GL__GENERIC_BOGUS 1
 #else
-# define _GL_INT_OP_WRAPV(a, b, op) \
-   (! _GL_INT_SIGNED ((0 * (a)) op (0 * (b))) \
-    ? ((a) op (b)) \
-    : _GL_EXPR_CAST ((a) op (b), \
-                     (sizeof ((a) op (b)) <= sizeof (int) \
-                      ? _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, int) \
-                      : _GL_INT_OP_WRAPV_LONGISH (a, b, op))))
-
-/* Cast to E's type the value of V if possible.  Yield V as-is otherwise.  */
-# if _GL_HAVE___TYPEOF__
-#  define _GL_EXPR_CAST(e, v) ((__typeof__ (e)) (v))
-# else
-#  define _GL_EXPR_CAST(e, v) (v)
-# endif
+# define _GL__GENERIC_BOGUS 0
+#endif
 
+/* Store A <op> B into *R, where OP specifies the operation.
+   BUILTIN is the builtin operation, and OVERFLOW the overflow predicate.
+   See above for restrictions.  */
+#if 5 <= __GNUC__ || __has_builtin (__builtin_add_oveflow)
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r)
+#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
+   (_Generic \
+    (*(r), \
+     signed char: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \
+                        signed char, SCHAR_MIN, SCHAR_MAX), \
+     short int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \
+                        short int, SHRT_MIN, SHRT_MAX), \
+     int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        int, INT_MIN, INT_MAX), \
+     long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        long int, LONG_MIN, LONG_MAX), \
+     long long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                        long long int, LLONG_MIN, LLONG_MAX)))
+#else
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
+   (sizeof *(r) == sizeof (signed char) \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \
+                       signed char, SCHAR_MIN, SCHAR_MAX) \
+    : sizeof *(r) == sizeof (short int) \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \
+                       short int, SHRT_MIN, SHRT_MAX) \
+    : sizeof *(r) == sizeof (int) \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                       int, INT_MIN, INT_MAX) \
+    : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
 # ifdef LLONG_MAX
-#  define _GL_INT_OP_WRAPV_LONGISH(a, b, op) \
-    (sizeof ((a) op (b)) <= sizeof (long int) \
-     ? _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long int) \
-     : _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long long int))
+#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+    (sizeof *(r) == sizeof (long int) \
+     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        long int, LONG_MIN, LONG_MAX) \
+     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                        long long int, LLONG_MIN, LLONG_MAX))
 # else
-#  define _GL_INT_OP_WRAPV_LONGISH(a, b, op) \
-    _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long int)
+#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+    _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                     long int, LONG_MIN, LONG_MAX))
 # endif
 #endif
 
-/* Return A <op> B, where the operation is given by OP and the result
-   type is T.  T is a signed integer type that is at least as wide as int.
-   Do arithmetic using 'unsigned T' to avoid signed integer overflow.
-   Subtract TYPE_MINIMUM (T) before converting back to T, and add it
-   back afterwards, to avoid signed overflow during conversion.  */
-#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, t) \
-  ((unsigned t) (a) op (unsigned t) (b) <= TYPE_MAXIMUM (t) \
-   ? (t) ((unsigned t) (a) op (unsigned t) (b)) \
-   : ((t) ((unsigned t) (a) op (unsigned t) (b) - TYPE_MINIMUM (t)) \
-      + TYPE_MINIMUM (t)))
-
-/* Calls to the INT_<op>_<result> macros are like their INT_CONST_<op>_<result>
-   counterparts, except they are faster with GCC 5 or later, and they
-   are not constant expressions due to limitations in the GNU C API.  */
-
-#define INT_ADD_OVERFLOW(a, b) \
-  _GL_OP_OVERFLOW (a, b, INT_CONST_ADD_OVERFLOW, __builtin_add_overflow)
-#define INT_SUBTRACT_OVERFLOW(a, b) \
-  _GL_OP_OVERFLOW (a, b, INT_CONST_SUBTRACT_OVERFLOW, __builtin_sub_overflow)
-#define INT_MULTIPLY_OVERFLOW(a, b) \
-  _GL_OP_OVERFLOW (a, b, INT_CONST_MULTIPLY_OVERFLOW, __builtin_mul_overflow)
-
-#define INT_ADD_WRAPV(a, b) \
-  _GL_OP_WRAPV (a, b, INT_CONST_ADD_WRAPV, __builtin_add_overflow)
-#define INT_SUBTRACT_WRAPV(a, b) \
-  _GL_OP_WRAPV (a, b, INT_CONST_SUBTRACT_WRAPV, __builtin_sub_overflow)
-#define INT_MULTIPLY_WRAPV(a, b) \
-  _GL_OP_WRAPV (a, b, INT_CONST_MULTIPLY_WRAPV, __builtin_mul_overflow)
-
-#if __GNUC__ < 5
-# define _GL_OP_OVERFLOW(a, b, portable, builtin) portable (a, b)
-# define _GL_OP_WRAPV(a, b, portable, builtin) portable (a, b)
-#else
-# define _GL_OP_OVERFLOW(a, b, portable, builtin) \
-   builtin (a, b, &(__typeof__ ((a) + (b))) {0})
-# define _GL_OP_WRAPV(a, b, portable, builtin) \
-   _GL_OP_WRAPV_GENSYM(a, b, builtin, __gl_wrapv##__COUNTER__)
-# define _GL_OP_WRAPV_GENSYM(a, b, builtin, r) \
-   ({__typeof__ ((a) + (b)) r; builtin (a, b, &r); r; })
-#endif
+/* Store the low-order bits of A <op> B into *R, where the operation
+   is given by OP.  Use the unsigned type UT for calculation to avoid
+   overflow problems.  *R's type is T, with extremal values TMIN and
+   TMAX.  T must be a signed integer type.  */
+#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
+  (sizeof ((a) op (b)) < sizeof (t) \
+   ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \
+   : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax))
+#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \
+  ((overflow (a, b) \
+    || (_GL_INT_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \
+    || (tmax) < ((a) op (b))) \
+   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t, tmin, tmax), 1) \
+   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t, tmin, tmax), 0))
+
+/* Return A <op> B, where the operation is given by OP.  Use the
+   unsigned type UT for calculation to avoid overflow problems.
+   Convert the result to type T without overflow by subtracting TMIN
+   from large values before converting, and adding it afterwards.
+   Compilers can optimize all the operations except OP.  */
+#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t, tmin, tmax) \
+  (((ut) (a) op (ut) (b)) <= (tmax) \
+   ? (t) ((ut) (a) op (ut) (b)) \
+   : ((t) (((ut) (a) op (ut) (b)) - (tmin)) + (tmin)))
 
 #endif /* _GL_INTPROPS_H */
index 255489eeb13713a815fc9fa7344c7c2f1c34eb67..e8f6aac29d0ffb7e67061ce0d3dae8f45fc22908 100644 (file)
@@ -33,36 +33,39 @@ timespec_add (struct timespec a, struct timespec b)
   int ns = a.tv_nsec + b.tv_nsec;
   int nsd = ns - TIMESPEC_RESOLUTION;
   int rns = ns;
+  time_t tmin = TYPE_MINIMUM (time_t);
+  time_t tmax = TYPE_MAXIMUM (time_t);
 
   if (0 <= nsd)
     {
       rns = nsd;
-      if (rs == TYPE_MAXIMUM (time_t))
-        {
-          if (0 <= bs)
-            goto high_overflow;
-          bs++;
-        }
-      else
+      if (bs < tmax)
+        bs++;
+      else if (rs < 0)
         rs++;
+      else
+        goto high_overflow;
     }
 
-  if (INT_ADD_OVERFLOW (rs, bs))
+  /* INT_ADD_WRAPV is not appropriate since time_t might be unsigned.
+     In theory time_t might be narrower than int, so plain
+     INT_ADD_OVERFLOW does not suffice.  */
+  if (! INT_ADD_OVERFLOW (rs, bs) && tmin <= rs + bs && rs + bs <= tmax)
+    rs += bs;
+  else
     {
       if (rs < 0)
         {
-          rs = TYPE_MINIMUM (time_t);
+          rs = tmin;
           rns = 0;
         }
       else
         {
         high_overflow:
-          rs = TYPE_MAXIMUM (time_t);
+          rs = tmax;
           rns = TIMESPEC_RESOLUTION - 1;
         }
     }
-  else
-    rs += bs;
 
   return make_timespec (rs, rns);
 }
index c57437556d1b2fbae5b24491d02950c635d210b8..392ec1592a1c87e1a8cffa2ff7b42fc9cd171569 100644 (file)
@@ -33,36 +33,39 @@ timespec_sub (struct timespec a, struct timespec b)
   time_t bs = b.tv_sec;
   int ns = a.tv_nsec - b.tv_nsec;
   int rns = ns;
+  time_t tmin = TYPE_MINIMUM (time_t);
+  time_t tmax = TYPE_MAXIMUM (time_t);
 
   if (ns < 0)
     {
       rns = ns + TIMESPEC_RESOLUTION;
-      if (rs == TYPE_MINIMUM (time_t))
-        {
-          if (bs <= 0)
-            goto low_overflow;
-          bs--;
-        }
-      else
+      if (bs < tmax)
+        bs++;
+      else if (- TYPE_SIGNED (time_t) < rs)
         rs--;
+      else
+        goto low_overflow;
     }
 
-  if (INT_SUBTRACT_OVERFLOW (rs, bs))
+  /* INT_SUBTRACT_WRAPV is not appropriate since time_t might be unsigned.
+     In theory time_t might be narrower than int, so plain
+     INT_SUBTRACT_OVERFLOW does not suffice.  */
+  if (! INT_SUBTRACT_OVERFLOW (rs, bs) && tmin <= rs - bs && rs - bs <= tmax)
+    rs -= bs;
+  else
     {
       if (rs < 0)
         {
         low_overflow:
-          rs = TYPE_MINIMUM (time_t);
+          rs = tmin;
           rns = 0;
         }
       else
         {
-          rs = TYPE_MAXIMUM (time_t);
+          rs = tmax;
           rns = TIMESPEC_RESOLUTION - 1;
         }
     }
-  else
-    rs -= bs;
 
   return make_timespec (rs, rns);
 }
index f372a280ffe0313566da2a25ebba20b3813abeca..43a905b906e976811ea79db161671a337de27104 100644 (file)
@@ -580,6 +580,8 @@ An obsolete but still supported calling form is:
                   ,@(if (cadr props) (list :system (cadr props))))))
   (unless (plist-get props :count)
     (setq props (plist-put props :count 0)))
+  (setq props (plist-put props :abbrev-table-modiff
+                         (abbrev-table-get table :abbrev-table-modiff)))
   (let ((system-flag (plist-get props :system))
         (sym (intern name table)))
     ;; Don't override a prior user-defined abbrev with a system abbrev,
index e9310259e7e02fac5f411398de0e6917e2329a19..e3b1dc4ebd3062aa8df1ea9395d56e93376df2b5 100644 (file)
@@ -196,6 +196,7 @@ A non-nil value may result in truncated bookmark names."
 
 ;;;###autoload (define-key ctl-x-r-map "b" 'bookmark-jump)
 ;;;###autoload (define-key ctl-x-r-map "m" 'bookmark-set)
+;;;###autoload (define-key ctl-x-r-map "M" 'bookmark-set-no-overwrite)
 ;;;###autoload (define-key ctl-x-r-map "l" 'bookmark-bmenu-list)
 
 ;;;###autoload
@@ -204,6 +205,7 @@ A non-nil value may result in truncated bookmark names."
     ;; Read the help on all of these functions for details...
     (define-key map "x" 'bookmark-set)
     (define-key map "m" 'bookmark-set) ;"m"ark
+    (define-key map "M" 'bookmark-set-no-overwrite) ;"M"aybe mark
     (define-key map "j" 'bookmark-jump)
     (define-key map "g" 'bookmark-jump) ;"g"o
     (define-key map "o" 'bookmark-jump-other-window)
@@ -755,30 +757,19 @@ This expects to be called from `point-min' in a bookmark file."
     map))
 
 ;;;###autoload
-(defun bookmark-set (&optional name no-overwrite)
-  "Set a bookmark named NAME at the current location.
-If name is nil, then prompt the user.
-
-With a prefix arg (non-nil NO-OVERWRITE), do not overwrite any
-existing bookmark that has the same name as NAME, but instead push the
-new bookmark onto the bookmark alist.  The most recently set bookmark
-with name NAME is thus the one in effect at any given time, but the
-others are still there, should the user decide to delete the most
-recent one.
-
-To yank words from the text of the buffer and use them as part of the
-bookmark name, type C-w while setting a bookmark.  Successive C-w's
-yank successive words.
-
-Typing C-u inserts (at the bookmark name prompt) the name of the last
-bookmark used in the document where the new bookmark is being set;
-this helps you use a single bookmark name to track progress through a
-large document.  If there is no prior bookmark for this document, then
-C-u inserts an appropriate name based on the buffer or file.
-
-Use \\[bookmark-delete] to remove bookmarks (you give it a name and
-it removes only the first instance of a bookmark with that name from
-the list of bookmarks.)"
+(defun bookmark-set-internal (prompt name overwrite-or-push)
+  "Interactively set a bookmark named NAME at the current location.
+
+Begin the interactive prompt with PROMPT, followed by a space, a
+generated default name in parentheses, a colon and a space.
+
+If OVERWRITE-OR-PUSH is nil, then error if there is already a
+bookmark named NAME; if `overwrite', then replace any existing
+bookmark if there is one; if `push' then push the new bookmark
+onto the bookmark alist.  The `push' behavior means that among
+bookmarks named NAME, this most recently set one becomes the one in
+effect, but the others are still there, in order, if the topmost one
+is ever deleted."
   (interactive (list nil current-prefix-arg))
   (unwind-protect
        (let* ((record (bookmark-make-record))
@@ -807,12 +798,24 @@ the list of bookmarks.)"
          (let ((str
                 (or name
                     (read-from-minibuffer
-                     (format "Set bookmark (%s): " default)
+                     (format "%s (default: \"%s\"): " prompt default)
                      nil
                      bookmark-minibuffer-read-name-map
                      nil nil defaults))))
            (and (string-equal str "") (setq str default))
-           (bookmark-store str (cdr record) no-overwrite)
+
+           (cond
+            ((eq overwrite-or-push nil)
+             (if (bookmark-get-bookmark str t)
+                 (error "A bookmark named \"%s\" already exists." str)
+               (bookmark-store str (cdr record) nil)))
+            ((eq overwrite-or-push 'overwrite)
+             (bookmark-store str (cdr record) nil))
+            ((eq overwrite-or-push 'push)
+             (bookmark-store str (cdr record) t))
+            (t
+             (error "Unrecognized value for `overwrite-or-push': %S"
+                    overwrite-or-push)))
 
            ;; Ask for an annotation buffer for this bookmark
            (when bookmark-use-annotations
@@ -821,6 +824,66 @@ the list of bookmarks.)"
     (setq bookmark-current-buffer nil)))
 
 
+(defun bookmark-set (&optional name no-overwrite)
+  "Set a bookmark named NAME at the current location.
+If NAME is nil, then prompt the user.
+
+With a prefix arg (non-nil NO-OVERWRITE), do not overwrite any
+existing bookmark that has the same name as NAME, but instead push the
+new bookmark onto the bookmark alist.  The most recently set bookmark
+with name NAME is thus the one in effect at any given time, but the
+others are still there, should the user decide to delete the most
+recent one.
+
+To yank words from the text of the buffer and use them as part of the
+bookmark name, type C-w while setting a bookmark.  Successive C-w's
+yank successive words.
+
+Typing C-u inserts (at the bookmark name prompt) the name of the last
+bookmark used in the document where the new bookmark is being set;
+this helps you use a single bookmark name to track progress through a
+large document.  If there is no prior bookmark for this document, then
+C-u inserts an appropriate name based on the buffer or file.
+
+Use \\[bookmark-delete] to remove bookmarks (you give it a name and
+it removes only the first instance of a bookmark with that name from
+the list of bookmarks.)"
+  (interactive (list nil current-prefix-arg))
+  (let ((prompt
+         (if no-overwrite "Set bookmark" "Set bookmark unconditionally")))
+    (bookmark-set-internal prompt name (if no-overwrite 'push 'overwrite))))
+
+(defun bookmark-set-no-overwrite (&optional name push-bookmark)
+  "Set a bookmark named NAME at the current location.
+If NAME is nil, then prompt the user.
+
+If a bookmark named NAME already exists and prefix argument
+PUSH-BOOKMARK is non-nil, then push the new bookmark onto the
+bookmark alist.  Pushing it means that among bookmarks named
+NAME, this one becomes the one in effect, but the others are
+still there, in order, and become effective again if the user
+ever deletes the most recent one.
+
+Otherwise, if a bookmark named NAME already exists but PUSH-BOOKMARK
+is nil, raise an error.
+
+To yank words from the text of the buffer and use them as part of the
+bookmark name, type C-w while setting a bookmark.  Successive C-w's
+yank successive words.
+
+Typing C-u inserts (at the bookmark name prompt) the name of the last
+bookmark used in the document where the new bookmark is being set;
+this helps you use a single bookmark name to track progress through a
+large document.  If there is no prior bookmark for this document, then
+C-u inserts an appropriate name based on the buffer or file.
+
+Use \\[bookmark-delete] to remove bookmarks (you give it a name and
+it removes only the first instance of a bookmark with that name from
+the list of bookmarks.)"
+  (interactive (list nil current-prefix-arg))
+  (bookmark-set-internal "Set bookmark" name (if push-bookmark 'push nil)))
+
+
 (defun bookmark-kill-line (&optional newline-too)
   "Kill from point to end of line.
 If optional arg NEWLINE-TOO is non-nil, delete the newline too.
index c42094f0f0c5e52a90301205636863ad5563d014..80f0cd73ceed61769f205d40505727988df85c9d 100644 (file)
@@ -2730,7 +2730,7 @@ non-nil value, that slot cannot be set via `setf'.
                            slots defaults)))
        (push `(cl-defsubst ,cname
                    (&cl-defs (nil ,@descs) ,@args)
-                 ,(if (stringp doc) (list doc)
+                 ,(if (stringp doc) doc
                     (format "Constructor for objects of type `%s'." name))
                  ,@(if (cl--safe-expr-p `(progn ,@(mapcar #'cl-second descs)))
                        '((declare (side-effect-free t))))
index 8dce5084ec9057011362cc9915609026c540d884..80ee3bbbd093ab9a2c66cd780cb35362be9dd016 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-07  Kelvin White  <kwhite@gnu.org>
+
+       * erc-pcomplete.el (pcomplete-erc-nicks): Fix bug for tab complete
+       (bug#18771)
+
 2015-03-25  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * erc.el (erc-switch-to-buffer): Fix last change (bug#20187).
index e46ac68b2594f76c08f54b97ca794d2196a4c89d..686a3a8e1d0f2d465c24497992da1f3d22536265 100644 (file)
@@ -225,9 +225,10 @@ If optional argument IGNORE-SELF is non-nil, don't return the current nick."
                  (erc-get-channel-user-list)))
         (nicks nil))
     (dolist (user users)
-      (unless (and ignore-self
-                   (string= (erc-server-user-nickname (car user))
-                            (erc-current-nick)))
+      (unless (or (not user) 
+                  (and ignore-self
+                       (string= (erc-server-user-nickname (car user))
+                                (erc-current-nick))))
         (setq nicks (cons (concat (erc-server-user-nickname (car user))
                                   postfix)
                           nicks))))
index 132f1644f8fc1c832603cf47607b3839d880ca51..4c5d43fb44eaca7156e553c862460197e141e22c 100644 (file)
@@ -62,7 +62,7 @@ WHAT is a file or directory name to be removed, needed just for `inotify'."
       ;; Send `stopped' event.
       (dolist (entry (cdr registered))
        (funcall (cdr entry)
-                `(,(file-notify--descriptor desc) stopped
+                `(,descriptor stopped
                   ,(or (and (stringp (car entry))
                             (expand-file-name (car entry) dir))
                        dir))))
@@ -123,14 +123,17 @@ This is available in case a file has been moved."
 ;; `inotify' returns the same descriptor when the file (directory)
 ;; uses the same inode.  We want to distinguish, and apply a virtual
 ;; descriptor which make the difference.
-(defun file-notify--descriptor (descriptor)
+(defun file-notify--descriptor (desc file)
   "Return the descriptor to be used in `file-notify-*-watch'.
 For `gfilenotify' and `w32notify' it is the same descriptor as
 used in the low-level file notification package."
-  (if (and (natnump descriptor) (eq file-notify--library 'inotify))
-      (cons descriptor
-            (car (cadr (gethash descriptor file-notify-descriptors))))
-    descriptor))
+  (if (and (natnump desc) (eq file-notify--library 'inotify))
+      (cons desc
+            (and (stringp file)
+                 (car (assoc
+                       (file-name-nondirectory file)
+                       (gethash desc file-notify-descriptors)))))
+    desc))
 
 ;; The callback function used to map between specific flags of the
 ;; respective file notifications, and the ones we return.
@@ -210,9 +213,11 @@ EVENT is the cadr of the event in `file-notify-handle-event'
                               (car file-notify--pending-event)))
                   ;; If the source is handled by another watch, we
                   ;; must fire the rename event there as well.
-                  (when (not (equal (file-notify--descriptor desc)
+                  (when (not (equal (file-notify--descriptor desc file1)
                                     (file-notify--descriptor
-                                     (caar file-notify--pending-event))))
+                                     (caar file-notify--pending-event)
+                                     (file-notify--event-file-name
+                                      file-notify--pending-event))))
                     (setq pending-event
                           `((,(caar file-notify--pending-event)
                              renamed ,file ,file1)
@@ -223,7 +228,10 @@ EVENT is the cadr of the event in `file-notify-handle-event'
         ;; Apply pending callback.
         (when pending-event
           (setcar
-           (car pending-event) (file-notify--descriptor (caar pending-event)))
+           (car pending-event)
+           (file-notify--descriptor
+            (caar pending-event)
+            (file-notify--event-file-name file-notify--pending-event)))
           (funcall (cadr pending-event) (car pending-event))
           (setq pending-event nil))
 
@@ -257,14 +265,15 @@ EVENT is the cadr of the event in `file-notify-handle-event'
          (if file1
              (funcall
               callback
-              `(,(file-notify--descriptor desc) ,action ,file ,file1))
+              `(,(file-notify--descriptor desc file) ,action ,file ,file1))
            (funcall
             callback
-            `(,(file-notify--descriptor desc) ,action ,file)))))
+            `(,(file-notify--descriptor desc file) ,action ,file)))))
 
       ;; Modify `file-notify-descriptors'.
       (when stopped
-        (file-notify--rm-descriptor (file-notify--descriptor desc) file)))))
+        (file-notify--rm-descriptor
+         (file-notify--descriptor desc file) file)))))
 
 ;; `gfilenotify' and `w32notify' return a unique descriptor for every
 ;; `file-notify-add-watch', while `inotify' returns a unique
@@ -375,7 +384,8 @@ FILE is the name of the file whose event is being reported."
      file-notify-descriptors)
 
     ;; Return descriptor.
-    (file-notify--descriptor desc)))
+    (file-notify--descriptor
+     desc (unless (file-directory-p file) (file-name-nondirectory file)))))
 
 (defun file-notify-rm-watch (descriptor)
   "Remove an existing watch specified by its DESCRIPTOR.
@@ -396,7 +406,7 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
             (if handler
                 ;; A file name handler could exist even if there is no local
                 ;; file notification support.
-                (funcall handler 'file-notify-rm-watch desc)
+                (funcall handler 'file-notify-rm-watch descriptor)
 
               (funcall
                (cond
index f5508517dc6ee9e1b3254af3d55e5c625baeb1ff..3f31a2973c6073fd67c6b01b0c8b85235b37c87e 100644 (file)
@@ -2231,6 +2231,15 @@ See also `toggle-frame-maximized'."
 (make-obsolete-variable
  'window-system-version "it does not give useful information." "24.3")
 
+;; Variables which should trigger redisplay of the current buffer.
+(setq redisplay--variables (make-hash-table :test 'eq :size 10))
+(mapc (lambda (var)
+        (puthash var 1 redisplay--variables))
+      '(line-spacing
+        overline-margin
+        line-prefix
+        wrap-prefix))
+
 (provide 'frame)
 
 ;;; frame.el ends here
index d4ca6555b666d8fd6ca5ded5d98e8914ddc4dcf7..be0554fdb86b27137aa40fae6e226015704321bc 100644 (file)
@@ -2220,6 +2220,7 @@ increase the score of each group you read."
   "\M-\C-e" gnus-summary-expire-articles-now
   "\177" gnus-summary-delete-article
   [delete] gnus-summary-delete-article
+  [backspace] gnus-summary-delete-article
   "m" gnus-summary-move-article
   "r" gnus-summary-respool-article
   "w" gnus-summary-edit-article
index 499253e931f750e55778ad256092368a03a6978c..20a48bc3110e7e392d1c8abb1f8a65e9f6bfe404 100644 (file)
@@ -294,7 +294,7 @@ in hexl format.
 
 A sample format:
 
-  HEX ADDR: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f     ASCII-TEXT
+  HEX ADDR: 0011 2233 4455 6677 8899 aabb ccdd eeff     ASCII-TEXT
   --------  ---- ---- ---- ---- ---- ---- ---- ----  ----------------
   00000000: 5468 6973 2069 7320 6865 786c 2d6d 6f64  This is hexl-mod
   00000010: 652e 2020 4561 6368 206c 696e 6520 7265  e.  Each line re
index b23d12ad0ed0446c9806eec0bd3dea3eda6a9304..97cf9934c34bb2fcc89d8978f4cedbd43fc7e147 100644 (file)
@@ -111,6 +111,17 @@ Used only when `json-encoding-pretty-print' is non-nil.")
   "If non-nil, ] and } closings will be formatted lisp-style,
 without indentation.")
 
+(defvar json-pre-element-read-function nil
+  "Function called (if non-nil) by `json-read-array' and
+`json-read-object' right before reading a JSON array or object,
+respectively.  The function is called with one argument, which is
+the current JSON key.")
+
+(defvar json-post-element-read-function nil
+  "Function called (if non-nil) by `json-read-array' and
+`json-read-object' right after reading a JSON array or object,
+respectively.")
+
 \f
 
 ;;; Utilities
@@ -196,6 +207,61 @@ Unlike `reverse', this keeps the property-value pairs intact."
 
 \f
 
+;;; Paths
+
+(defvar json--path '()
+  "Used internally by `json-path-to-position' to keep track of
+the path during recursive calls to `json-read'.")
+
+(defun json--record-path (key)
+  "Record the KEY to the current JSON path.
+Used internally by `json-path-to-position'."
+  (push (cons (point) key) json--path))
+
+(defun json--check-position (position)
+  "Check if the last parsed JSON structure passed POSITION.
+Used internally by `json-path-to-position'."
+  (let ((start (caar json--path)))
+    (when (< start position (+ (point) 1))
+      (throw :json-path (list :path (nreverse (mapcar #'cdr json--path))
+                              :match-start start
+                              :match-end (point)))))
+  (pop json--path))
+
+(defun json-path-to-position (position &optional string)
+  "Return the path to the JSON element at POSITION.
+
+When STRING is provided, return the path to the position in the
+string, else to the position in the current buffer.
+
+The return value is a property list with the following
+properties:
+
+:path        -- A list of strings and numbers forming the path to
+                the JSON element at the given position.  Strings
+                denote object names, while numbers denote array
+                indexes.
+
+:match-start -- Position where the matched JSON element begins.
+
+:match-end   -- Position where the matched JSON element ends.
+
+This can for instance be useful to determine the path to a JSON
+element in a deeply nested structure."
+  (save-excursion
+    (unless string
+      (goto-char (point-min)))
+    (let* ((json--path '())
+           (json-pre-element-read-function #'json--record-path)
+           (json-post-element-read-function
+            (apply-partially #'json--check-position position))
+           (path (catch :json-path
+                   (if string
+                       (json-read-from-string string)
+                     (json-read)))))
+      (when (plist-get path :path)
+        path))))
+
 ;;; Keywords
 
 (defvar json-keywords '("true" "false" "null")
@@ -403,7 +469,12 @@ Please see the documentation of `json-object-type' and `json-key-type'."
       (if (char-equal (json-peek) ?:)
           (json-advance)
         (signal 'json-object-format (list ":" (json-peek))))
+      (json-skip-whitespace)
+      (when json-pre-element-read-function
+        (funcall json-pre-element-read-function key))
       (setq value (json-read))
+      (when json-post-element-read-function
+        (funcall json-post-element-read-function))
       (setq elements (json-add-to-object elements key value))
       (json-skip-whitespace)
       (unless (char-equal (json-peek) ?})
@@ -509,7 +580,12 @@ become JSON objects."
   ;; read values until "]"
   (let (elements)
     (while (not (char-equal (json-peek) ?\]))
+      (json-skip-whitespace)
+      (when json-pre-element-read-function
+        (funcall json-pre-element-read-function (length elements)))
       (push (json-read) elements)
+      (when json-post-element-read-function
+        (funcall json-post-element-read-function))
       (json-skip-whitespace)
       (unless (char-equal (json-peek) ?\])
         (if (char-equal (json-peek) ?,)
index 29257cdd4ab708ca66d8e0700055527ef831a902..a19542fb2040d597a40339598064080e4ae884ec 100644 (file)
@@ -1123,7 +1123,6 @@ character)."
      (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
      eval-last-sexp-arg-internal)))
 
-
 (defun elisp--eval-last-sexp-print-value (value &optional eval-last-sexp-arg-internal)
   (let ((unabbreviated (let ((print-length nil) (print-level nil))
                         (prin1-to-string value)))
index 9b2711d81469d9d314617f66d8ad2cddefe55a70..caedbd9f6c302c89f7b63aea81f0d9f73ceb8fe3 100644 (file)
@@ -517,7 +517,7 @@ in the branch repository (or whose status not be determined)."
     ;; elisp function to remerge from the .BASE/OTHER/THIS files.
     (smerge-start-session)
     (add-hook 'after-save-hook 'vc-bzr-resolve-when-done nil t)
-    (message "There are unresolved conflicts in this file")))
+    (vc-message-unresolved-conflicts buffer-file-name)))
 
 (defun vc-bzr-version-dirstate (dir)
   "Try to return as a string the bzr revision ID of directory DIR.
index 27898a991a010bb929f225850e29dd7630c595dc..8bf37f09dc2ffa527832694a6ea56eaa2e070523 100644 (file)
@@ -841,7 +841,7 @@ This prompts for a branch to merge from."
     (smerge-start-session)
     (when vc-git-resolve-conflicts
       (add-hook 'after-save-hook 'vc-git-resolve-when-done nil 'local))
-    (message "There are unresolved conflicts in this file")))
+    (vc-message-unresolved-conflicts buffer-file-name)))
 
 ;;; HISTORY FUNCTIONS
 
index f9957c1afff32bdc4329457284347650f2fd5d60..92b0c3169c1cca097687fa53c5ec626413c4cd1d 100644 (file)
@@ -535,7 +535,7 @@ REV is the revision to check out into WORKFILE."
     (vc-file-setprop buffer-file-name 'vc-state 'conflict)
     (smerge-start-session)
     (add-hook 'after-save-hook 'vc-hg-resolve-when-done nil t)
-    (message "There are unresolved conflicts in this file")))
+    (vc-message-unresolved-conflicts buffer-file-name)))
 
 
 ;; Modeled after the similar function in vc-bzr.el
index 4ef63a23db55eacb319e61f5c10a4c8830aaabda..de58fb91c62c44780751590f5213d260314afc02 100644 (file)
@@ -686,7 +686,7 @@ and that it passes `vc-svn-global-switches' to it before FLAGS."
       ;; use conflict markers in which case we don't really know what to do.
       ;; So let's just punt for now.
       nil)
-    (message "There are unresolved conflicts in this file")))
+    (vc-message-unresolved-conflicts buffer-file-name)))
 
 (defun vc-svn-parse-status (&optional filename)
   "Parse output of \"svn status\" command in the current buffer.
index 0a2169534e569565427b44af289e1ec92a18e424..efd816b4f0ebe9f53d2991ba7e88a783b5031351 100644 (file)
@@ -2068,6 +2068,13 @@ changes from the current branch."
     (smerge-mode 1)
     (message "File contains conflicts.")))
 
+;;;###autoload
+(defun vc-message-unresolved-conflicts (filename)
+  "Display a message indicating unresolved conflicts in FILENAME."
+  ;; This enables all VC backends to give a standard, recognizeable
+  ;; conflict message that indicates which file is conflicted.
+  (message "There are unresolved conflicts in %s" filename))
+
 ;;;###autoload
 (defalias 'vc-resolve-conflicts 'smerge-ediff)
 
index 8f94d2b60974eac37831e51160ab4498991cb1ef..81d644a16ad28c8ebcd8052d826e4e3993260dea 100644 (file)
@@ -802,9 +802,10 @@ void *
 xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
 {
   eassert (0 <= nitems && 0 < item_size);
-  if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
+  ptrdiff_t nbytes;
+  if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes)
     memory_full (SIZE_MAX);
-  return xmalloc (nitems * item_size);
+  return xmalloc (nbytes);
 }
 
 
@@ -815,9 +816,10 @@ void *
 xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
 {
   eassert (0 <= nitems && 0 < item_size);
-  if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
+  ptrdiff_t nbytes;
+  if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes)
     memory_full (SIZE_MAX);
-  return xrealloc (pa, nitems * item_size);
+  return xrealloc (pa, nbytes);
 }
 
 
@@ -848,33 +850,43 @@ void *
 xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
         ptrdiff_t nitems_max, ptrdiff_t item_size)
 {
+  ptrdiff_t n0 = *nitems;
+  eassume (0 < item_size && 0 < nitems_incr_min && 0 <= n0 && -1 <= nitems_max);
+
   /* The approximate size to use for initial small allocation
      requests.  This is the largest "small" request for the GNU C
      library malloc.  */
   enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
 
   /* If the array is tiny, grow it to about (but no greater than)
-     DEFAULT_MXFAST bytes.  Otherwise, grow it by about 50%.  */
-  ptrdiff_t n = *nitems;
-  ptrdiff_t tiny_max = DEFAULT_MXFAST / item_size - n;
-  ptrdiff_t half_again = n >> 1;
-  ptrdiff_t incr_estimate = max (tiny_max, half_again);
-
-  /* Adjust the increment according to three constraints: NITEMS_INCR_MIN,
+     DEFAULT_MXFAST bytes.  Otherwise, grow it by about 50%.
+     Adjust the growth according to three constraints: NITEMS_INCR_MIN,
      NITEMS_MAX, and what the C language can represent safely.  */
-  ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / item_size;
-  ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
-                    ? nitems_max : C_language_max);
-  ptrdiff_t nitems_incr_max = n_max - n;
-  ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max));
 
-  eassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max);
+  ptrdiff_t n, nbytes;
+  if (INT_ADD_WRAPV (n0, n0 >> 1, &n))
+    n = PTRDIFF_MAX;
+  if (0 <= nitems_max && nitems_max < n)
+    n = nitems_max;
+
+  ptrdiff_t adjusted_nbytes
+    = ((INT_MULTIPLY_WRAPV (n, item_size, &nbytes) || SIZE_MAX < nbytes)
+       ? min (PTRDIFF_MAX, SIZE_MAX)
+       : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0);
+  if (adjusted_nbytes)
+    {
+      n = adjusted_nbytes / item_size;
+      nbytes = adjusted_nbytes - adjusted_nbytes % item_size;
+    }
+
   if (! pa)
     *nitems = 0;
-  if (nitems_incr_max < incr)
+  if (n - n0 < nitems_incr_min
+      && (INT_ADD_WRAPV (n0, nitems_incr_min, &n)
+         || (0 <= nitems_max && nitems_max < n)
+         || INT_MULTIPLY_WRAPV (n, item_size, &nbytes)))
     memory_full (SIZE_MAX);
-  n += incr;
-  pa = xrealloc (pa, n * item_size);
+  pa = xrealloc (pa, nbytes);
   *nitems = n;
   return pa;
 }
@@ -2104,9 +2116,8 @@ INIT must be an integer that represents a character.  */)
       EMACS_INT string_len = XINT (length);
       unsigned char *p, *beg, *end;
 
-      if (string_len > STRING_BYTES_MAX / len)
+      if (INT_MULTIPLY_WRAPV (len, string_len, &nbytes))
        string_overflow ();
-      nbytes = len * string_len;
       val = make_uninit_multibyte_string (string_len, nbytes);
       for (beg = SDATA (val), p = beg, end = beg + nbytes; p < end; p += len)
        {
@@ -5317,11 +5328,35 @@ compact_font_cache_entry (Lisp_Object entry)
             are not marked too.  But we must be sure that nothing is
             marked within OBJ before we really drop it.  */
          for (i = 0; i < size; i++)
-           if (VECTOR_MARKED_P (XFONT_ENTITY (AREF (XCDR (obj), i))))
-             break;
+            {
+              Lisp_Object objlist;
+
+              if (VECTOR_MARKED_P (XFONT_ENTITY (AREF (XCDR (obj), i))))
+                break;
+
+              objlist = AREF (AREF (XCDR (obj), i), FONT_OBJLIST_INDEX);
+              for (; CONSP (objlist); objlist = XCDR (objlist))
+                {
+                  Lisp_Object val = XCAR (objlist);
+                  struct font *font = XFONT_OBJECT (val);
+
+                  if (!NILP (AREF (val, FONT_TYPE_INDEX))
+                      && VECTOR_MARKED_P(font))
+                    break;
+                }
+              if (CONSP (objlist))
+               {
+                 /* Foiund a marked font, bail out.  */
+                 break;
+               }
+            }
 
          if (i == size)
-           drop = 1;
+           {
+             /* No marked fonts were found, so this entire font
+                entity can be dropped.  */
+             drop = 1;
+           }
        }
       if (drop)
        *prev = XCDR (tail);
index 91e42dca2bf34166e42f3b6104211078d60a9155..ab91aaa4e8102cded7565ed68711ddda6f4d5703 100644 (file)
@@ -3245,9 +3245,9 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
   else
     nbytes = SBYTES (str);
 
-  if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+  if (INT_ADD_WRAPV (ssl->bytes, nbytes, &nbytes))
     memory_full (SIZE_MAX);
-  ssl->bytes += nbytes;
+  ssl->bytes = nbytes;
 
   if (STRINGP (str2))
     {
@@ -3259,9 +3259,9 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
       else
        nbytes = SBYTES (str2);
 
-      if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+      if (INT_ADD_WRAPV (ssl->bytes, nbytes, &nbytes))
        memory_full (SIZE_MAX);
-      ssl->bytes += nbytes;
+      ssl->bytes = nbytes;
     }
 }
 
@@ -3357,9 +3357,8 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
       unsigned char *p;
       ptrdiff_t total;
 
-      if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes))
+      if (INT_ADD_WRAPV (overlay_heads.bytes, overlay_tails.bytes, &total))
        memory_full (SIZE_MAX);
-      total = overlay_heads.bytes + overlay_tails.bytes;
       if (total > overlay_str_len)
        overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
                                   total - overlay_str_len, -1, 1);
@@ -4481,6 +4480,23 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
     Lisp_Object *copy;
     ptrdiff_t i;
 
+    if (size)
+      {
+       Lisp_Object ovl
+         = XVECTOR (last_overlay_modification_hooks)->contents[1];
+
+       /* If the buffer of the first overlay in the array doesn't
+          match the current buffer, then these modification hooks
+          should not be run in this buffer.  This could happen when
+          some code calls some insdel functions, such as del_range_1,
+          with the PREPARE argument false -- in that case this
+          function is never called to record the overlay modification
+          hook functions in the last_overlay_modification_hooks
+          array, so anything we find there is not ours.  */
+       if (XMARKER (OVERLAY_START (ovl))->buffer != current_buffer)
+         return;
+      }
+
     USE_SAFE_ALLOCA;
     SAFE_ALLOCA_LISP (copy, size);
     memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
index 8755353240aa8a7889b0fce3e6ec6e5b97de0ca7..b94ea8e212efa5c83660b4c0a14f94f9a2f95a42 100644 (file)
@@ -114,15 +114,15 @@ casify_object (enum case_action flag, Lisp_Object obj)
       ptrdiff_t i, i_byte, size = SCHARS (obj);
       int len;
       USE_SAFE_ALLOCA;
-      ptrdiff_t o_size = (size < STRING_BYTES_BOUND / MAX_MULTIBYTE_LENGTH
-                         ? size * MAX_MULTIBYTE_LENGTH
-                         : STRING_BYTES_BOUND);
+      ptrdiff_t o_size;
+      if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &o_size))
+       o_size = PTRDIFF_MAX;
       unsigned char *dst = SAFE_ALLOCA (o_size);
       unsigned char *o = dst;
 
       for (i = i_byte = 0; i < size; i++, i_byte += len)
        {
-         if (o_size - (o - dst) < MAX_MULTIBYTE_LENGTH)
+         if (o_size - MAX_MULTIBYTE_LENGTH < o - dst)
            string_overflow ();
          c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len);
          if (inword && flag != CASE_CAPITALIZE_UP)
index bf2aa1254d40098031d4cb1b4a0549d6717b3c1f..9792717378de8bc5776226262b3ca4c657e562fe 100644 (file)
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -2071,12 +2071,10 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
     }
 
   buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1;
-
-  if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes)
+  outbufsize = str_bytes;
+  if (INT_MULTIPLY_WRAPV (buf_magnification, outbufsize, &outbufsize)
+      || INT_ADD_WRAPV (256, outbufsize, &outbufsize))
     memory_full (SIZE_MAX);
-  outbufsize = (ccl.buf_magnification
-               ? str_bytes * ccl.buf_magnification + 256
-               : str_bytes + 256);
   outp = outbuf = xmalloc (outbufsize);
 
   consumed_chars = consumed_bytes = 0;
index 3e2bf1e70c23014f45a77ef4e8ef8453fe6555f4..bc2fa4a12da227ac5e5b37930b2a9c48ab9cd392 100644 (file)
@@ -25,14 +25,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* At first, see the document in `character.h' to understand the code
    in this file.  */
 
-#ifdef emacs
 #include <config.h>
-#endif
 
 #include <stdio.h>
 
-#ifdef emacs
-
 #include <sys/types.h>
 #include <intprops.h>
 #include "lisp.h"
@@ -41,12 +37,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "composite.h"
 #include "disptab.h"
 
-#else  /* not emacs */
-
-#include "mulelib.h"
-
-#endif /* emacs */
-
 /* Char-table of information about which character to unify to which
    Unicode character.  Mainly used by the macro MAYBE_UNIFY_CHAR.  */
 Lisp_Object Vchar_unify_table;
@@ -302,9 +292,8 @@ char_width (int c, struct Lisp_Char_Table *dp)
            if (CHARACTERP (ch))
              {
                int w = CHAR_WIDTH (XFASTINT (ch));
-               if (INT_ADD_OVERFLOW (width, w))
+               if (INT_ADD_WRAPV (width, w, &width))
                  string_overflow ();
-               width += w;
              }
          }
     }
@@ -349,20 +338,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision,
       int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes);
       ptrdiff_t thiswidth = char_width (c, dp);
 
-      if (precision <= 0)
-       {
-         if (INT_ADD_OVERFLOW (width, thiswidth))
-           string_overflow ();
-       }
-      else if (precision - width < thiswidth)
+      if (0 < precision && precision - width < thiswidth)
        {
          *nchars = i;
          *nbytes = i_byte;
          return width;
        }
+      if (INT_ADD_WRAPV (thiswidth, width, &width))
+       string_overflow ();
       i++;
       i_byte += bytes;
-      width += thiswidth;
   }
 
   if (precision > 0)
@@ -436,22 +421,16 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision,
          thiswidth = char_width (c, dp);
        }
 
-      if (precision <= 0)
-       {
-#ifdef emacs
-         if (INT_ADD_OVERFLOW (width, thiswidth))
-           string_overflow ();
-#endif
-       }
-      else if (precision - width < thiswidth)
+      if (0 < precision && precision - width < thiswidth)
        {
          *nchars = i;
          *nbytes = i_byte;
          return width;
        }
+      if (INT_ADD_WRAPV (thiswidth, width, &width))
+       string_overflow ();
       i += chars;
       i_byte += bytes;
-      width += thiswidth;
     }
 
   if (precision > 0)
@@ -657,9 +636,8 @@ count_size_as_multibyte (const unsigned char *str, ptrdiff_t len)
   for (bytes = 0; str < endp; str++)
     {
       int n = *str < 0x80 ? 1 : 2;
-      if (INT_ADD_OVERFLOW (bytes, n))
+      if (INT_ADD_WRAPV (bytes, n, &bytes))
         string_overflow ();
-      bytes += n;
     }
   return bytes;
 }
@@ -795,6 +773,7 @@ string_escape_byte8 (Lisp_Object string)
   ptrdiff_t nbytes = SBYTES (string);
   bool multibyte = STRING_MULTIBYTE (string);
   ptrdiff_t byte8_count;
+  ptrdiff_t thrice_byte8_count, uninit_nchars, uninit_nbytes;
   const unsigned char *src, *src_end;
   unsigned char *dst;
   Lisp_Object val;
@@ -808,23 +787,23 @@ string_escape_byte8 (Lisp_Object string)
   if (byte8_count == 0)
     return string;
 
+  if (INT_MULTIPLY_WRAPV (byte8_count, 3, &thrice_byte8_count))
+    string_overflow ();
+
   if (multibyte)
     {
-      if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
-         || (STRING_BYTES_BOUND - nbytes) / 2 < byte8_count)
-       string_overflow ();
-
       /* Convert 2-byte sequence of byte8 chars to 4-byte octal.  */
-      val = make_uninit_multibyte_string (nchars + byte8_count * 3,
-                                         nbytes + byte8_count * 2);
+      if (INT_ADD_WRAPV (nchars, thrice_byte8_count, &uninit_nchars)
+         || INT_ADD_WRAPV (nbytes, 2 * byte8_count, &uninit_nbytes))
+       string_overflow ();
+      val = make_uninit_multibyte_string (uninit_nchars, uninit_nbytes);
     }
   else
     {
-      if ((STRING_BYTES_BOUND - nbytes) / 3 < byte8_count)
-       string_overflow ();
-
       /* Convert 1-byte sequence of byte8 chars to 4-byte octal.  */
-      val = make_uninit_string (nbytes + byte8_count * 3);
+      if (INT_ADD_WRAPV (thrice_byte8_count, nbytes, &uninit_nbytes))
+       string_overflow ();
+      val = make_uninit_string (uninit_nbytes);
     }
 
   src = SDATA (string);
@@ -981,8 +960,6 @@ character is not ASCII nor 8-bit character, an error is signaled.  */)
   return make_number (c);
 }
 
-#ifdef emacs
-
 /* Return true if C is an alphabetic character.  */
 bool
 alphabeticp (int c)
@@ -1131,5 +1108,3 @@ See The Unicode Standard for the meaning of those values.  */);
   /* The correct char-table is setup in characters.el.  */
   Vunicode_category_table = Qnil;
 }
-
-#endif /* emacs */
index 0b42a36543c8f338d2d78ba3e99923c8aace6c1a..85b97ce61745e1f8a49ba762d33733662f3f1762 100644 (file)
@@ -1008,11 +1008,12 @@ coding_change_destination (struct coding_system *coding)
 static void
 coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes)
 {
-  if (STRING_BYTES_BOUND - coding->dst_bytes < bytes)
+  ptrdiff_t newbytes;
+  if (INT_ADD_WRAPV (coding->dst_bytes, bytes, &newbytes)
+      || SIZE_MAX < newbytes)
     string_overflow ();
-  coding->destination = xrealloc (coding->destination,
-                                 coding->dst_bytes + bytes);
-  coding->dst_bytes += bytes;
+  coding->destination = xrealloc (coding->destination, newbytes);
+  coding->dst_bytes = newbytes;
 }
 
 static void
@@ -7048,14 +7049,12 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
              if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
                {
                  eassert (growable_destination (coding));
-                 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
-                      / MAX_MULTIBYTE_LENGTH)
-                     < to_nchars)
+                 ptrdiff_t dst_size;
+                 if (INT_MULTIPLY_WRAPV (to_nchars, MAX_MULTIBYTE_LENGTH,
+                                         &dst_size)
+                     || INT_ADD_WRAPV (buf_end - buf, dst_size, &dst_size))
                    memory_full (SIZE_MAX);
-                 dst = alloc_destination (coding,
-                                          buf_end - buf
-                                          + MAX_MULTIBYTE_LENGTH * to_nchars,
-                                          dst);
+                 dst = alloc_destination (coding, dst_size, dst);
                  if (EQ (coding->src_object, coding->dst_object))
                    {
                      coding_set_source (coding);
index 5382b01066eef2ec4a153342dfce273cdf387ecd..ccec15f430a5008e843454efc9a7b7263b80da26 100644 (file)
@@ -1240,6 +1240,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
        return;
     }
 
+  maybe_set_redisplay (symbol);
   sym = XSYMBOL (symbol);
 
  start:
@@ -2630,30 +2631,16 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
       switch (code)
        {
        case Aadd:
-         if (INT_ADD_OVERFLOW (accum, next))
-           {
-             overflow = 1;
-             accum &= INTMASK;
-           }
-         accum += next;
+         overflow |= INT_ADD_WRAPV (accum, next, &accum);
          break;
        case Asub:
-         if (INT_SUBTRACT_OVERFLOW (accum, next))
-           {
-             overflow = 1;
-             accum &= INTMASK;
-           }
-         accum = argnum ? accum - next : nargs == 1 ? - next : next;
+         if (! argnum)
+           accum = nargs == 1 ? - next : next;
+         else
+           overflow |= INT_SUBTRACT_WRAPV (accum, next, &accum);
          break;
        case Amult:
-         if (INT_MULTIPLY_OVERFLOW (accum, next))
-           {
-             EMACS_UINT a = accum, b = next, ab = a * b;
-             overflow = 1;
-             accum = ab & INTMASK;
-           }
-         else
-           accum *= next;
+         overflow |= INT_MULTIPLY_WRAPV (accum, next, &accum);
          break;
        case Adiv:
          if (! (argnum || nargs == 1))
@@ -2662,7 +2649,10 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
            {
              if (next == 0)
                xsignal0 (Qarith_error);
-             accum /= next;
+             if (INT_DIVIDE_OVERFLOW (accum, next))
+               overflow = true;
+             else
+               accum /= next;
            }
          break;
        case Alogand:
index 91640769838f09a5e2636d29a82365aa1c434bcb..64c84aec6f9319217a71bd790d24f90e28295aa4 100644 (file)
@@ -1331,10 +1331,8 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
               || matrix_dim.width != pool->ncolumns);
 
   /* Enlarge the glyph pool.  */
-  needed = matrix_dim.width;
-  if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
+  if (INT_MULTIPLY_WRAPV (matrix_dim.height, matrix_dim.width, &needed))
     memory_full (SIZE_MAX);
-  needed *= matrix_dim.height;
   if (needed > pool->nglyphs)
     {
       ptrdiff_t old_nglyphs = pool->nglyphs;
@@ -1694,7 +1692,8 @@ required_matrix_height (struct window *w)
 
   if (FRAME_WINDOW_P (f))
     {
-      int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
+      /* http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg00194.html  */
+      int ch_height = max (FRAME_SMALLEST_FONT_HEIGHT (f), 1);
       int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
 
       return (((window_pixel_height + ch_height - 1)
@@ -1720,7 +1719,8 @@ required_matrix_width (struct window *w)
   struct frame *f = XFRAME (w->frame);
   if (FRAME_WINDOW_P (f))
     {
-      int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
+      /* http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg00194.html  */
+      int ch_width = max (FRAME_SMALLEST_CHAR_WIDTH (f), 1);
 
       /* Compute number of glyphs needed in a glyph row.  */
       return (((WINDOW_PIXEL_WIDTH (w) + ch_width - 1)
@@ -6092,15 +6092,15 @@ init_display (void)
     struct frame *sf = SELECTED_FRAME ();
     int width = FRAME_TOTAL_COLS (sf);
     int height = FRAME_TOTAL_LINES (sf);
+    int area;
 
     /* If these sizes are so big they cause overflow, just ignore the
        change.  It's not clear what better we could do.  The rest of
        the code assumes that (width + 2) * height * sizeof (struct glyph)
        does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX.  */
-    if (INT_ADD_OVERFLOW (width, 2)
-       || INT_MULTIPLY_OVERFLOW (width + 2, height)
-       || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
-           < (width + 2) * height))
+    if (INT_ADD_WRAPV (width, 2, &area)
+       || INT_MULTIPLY_WRAPV (height, area, &area)
+       || min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < area)
       fatal ("screen size %dx%d too big", width, height);
   }
 
index 050eb2ac6ec3d4cfc5d708df7e3a57bf0611693e..316d9408065c125db2eb708c242023cbc593d677 100644 (file)
@@ -3887,9 +3887,12 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
   ptrdiff_t formatlen = SBYTES (args[0]);
 
   /* Allocate the info and discarded tables.  */
-  if ((SIZE_MAX - formatlen) / sizeof (struct info) <= nargs)
+  ptrdiff_t alloca_size;
+  if (INT_MULTIPLY_WRAPV (nargs, sizeof *info, &alloca_size)
+      || INT_ADD_WRAPV (sizeof *info, alloca_size, &alloca_size)
+      || INT_ADD_WRAPV (formatlen, alloca_size, &alloca_size)
+      || SIZE_MAX < alloca_size)
     memory_full (SIZE_MAX);
-  size_t alloca_size = (nargs + 1) * sizeof *info + formatlen;
   /* info[0] is unused.  Unused elements have -1 for start.  */
   info = SAFE_ALLOCA (alloca_size);
   memset (info, 0, alloca_size);
index f545066fb079f6f7593870d94c43ba7f7f2e6801..46956668777949be1edb1475c642032de5559fd2 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -2389,9 +2389,9 @@ ARRAY is a vector, string, char-table, or bool-vector.  */)
          unsigned char str[MAX_MULTIBYTE_LENGTH];
          int len = CHAR_STRING (charval, str);
          ptrdiff_t size_byte = SBYTES (array);
+         ptrdiff_t product;
 
-         if (INT_MULTIPLY_OVERFLOW (SCHARS (array), len)
-             || SCHARS (array) * len != size_byte)
+         if (INT_MULTIPLY_WRAPV (size, len, &product) || product != size_byte)
            error ("Attempt to change byte length of a string");
          for (idx = 0; idx < size_byte; idx++)
            *p++ = str[idx % len];
index fb1addb7a0ceedfad58ca608e0efa3318f8548a4..57ded171de4647037d202c5e11646d48f7e2527b 100644 (file)
@@ -2561,20 +2561,21 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
        }
     }
 
-  if (INT_MAX / 2 < len)
+  int len2;
+  if (INT_MULTIPLY_WRAPV (len, 2, &len2))
     memory_full (SIZE_MAX);
 
   if (gstring.allocated == 0)
     {
       gstring.glyph_size = sizeof (MFLTGlyphFT);
-      gstring.glyphs = xnmalloc (len * 2, sizeof (MFLTGlyphFT));
-      gstring.allocated = len * 2;
+      gstring.glyphs = xnmalloc (len2, sizeof (MFLTGlyphFT));
+      gstring.allocated = len2;
     }
-  else if (gstring.allocated < len * 2)
+  else if (gstring.allocated < len2)
     {
-      gstring.glyphs = xnrealloc (gstring.glyphs, len * 2,
+      gstring.glyphs = xnrealloc (gstring.glyphs, len2,
                                  sizeof (MFLTGlyphFT));
-      gstring.allocated = len * 2;
+      gstring.allocated = len2;
     }
   glyphs = (MFLTGlyphFT *) (gstring.glyphs);
   memset (glyphs, 0, len * sizeof (MFLTGlyphFT));
@@ -2624,11 +2625,12 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
       int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt);
       if (result != -2)
        break;
-      if (INT_MAX / 2 < gstring.allocated)
+      int len2;
+      if (INT_MULTIPLY_WRAPV (gstring.allocated, 2, &len2))
        memory_full (SIZE_MAX);
       gstring.glyphs = xnrealloc (gstring.glyphs,
                                  gstring.allocated, 2 * sizeof (MFLTGlyphFT));
-      gstring.allocated *= 2;
+      gstring.allocated = len2;
     }
   if (gstring.used > LGSTRING_GLYPH_LEN (lgstring))
     return Qnil;
index 864cac5f511d56214973a721a9a69045a0e71bfb..0c69b0001eecefd5c97d300698e6816a90d59154 100644 (file)
@@ -781,10 +781,11 @@ static Lisp_Object
 gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix)
 {
   ptrdiff_t prefix_length = strlen (prefix);
-  if ((STRING_BYTES_BOUND - prefix_length) / 3 < buf_size)
+  ptrdiff_t retlen;
+  if (INT_MULTIPLY_WRAPV (buf_size, 3, &retlen)
+      || INT_ADD_WRAPV (prefix_length - (buf_size != 0), retlen, &retlen))
     string_overflow ();
-  Lisp_Object ret = make_uninit_string (prefix_length + 3 * buf_size
-                                       - (buf_size != 0));
+  Lisp_Object ret = make_uninit_string (retlen);
   char *string = SSDATA (ret);
   strcpy (string, prefix);
 
index 701bcab70609ff66b507c74db4a3893276446c3d..90683eba7b888d0caf0ddcb0b566e72aae3c75b6 100644 (file)
@@ -517,9 +517,12 @@ get_utf8_string (const char *str)
       if (cp) g_free (cp);
 
       len = strlen (str);
-      if ((min (PTRDIFF_MAX, SIZE_MAX) - len - 1) / 4 < nr_bad)
+      ptrdiff_t alloc;
+      if (INT_MULTIPLY_WRAPV (nr_bad, 4, &alloc)
+         || INT_ADD_WRAPV (len + 1, alloc, &alloc)
+         || SIZE_MAX < alloc)
        memory_full (SIZE_MAX);
-      up = utf8_str = xmalloc (len + nr_bad * 4 + 1);
+      up = utf8_str = xmalloc (alloc);
       p = (unsigned char *)str;
 
       while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read,
index 928eb5cfa3717d03ae4ab35ceafee7c73691ccd0..41687eb885c008f3e7b3e92a187593d0a05d082a 100644 (file)
@@ -4662,13 +4662,16 @@ x_to_xcolors (struct frame *f, struct image *img, bool rgb_p)
   int x, y;
   XColor *colors, *p;
   XImagePtr_or_DC ximg;
+  ptrdiff_t nbytes;
 #ifdef HAVE_NTGUI
   HGDIOBJ prev;
 #endif /* HAVE_NTGUI */
 
-  if (img->height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width)
+  if (INT_MULTIPLY_WRAPV (sizeof *colors, img->width, &nbytes)
+      || INT_MULTIPLY_WRAPV (img->height, nbytes, &nbytes)
+      || SIZE_MAX < nbytes)
     memory_full (SIZE_MAX);
-  colors = xmalloc (sizeof *colors * img->width * img->height);
+  colors = xmalloc (nbytes);
 
   /* Get the X image or create a memory device context for IMG. */
   ximg = image_get_x_image_or_dc (f, img, 0, &prev);
@@ -4801,15 +4804,17 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus
   XColor *colors = x_to_xcolors (f, img, 1);
   XColor *new, *p;
   int x, y, i, sum;
+  ptrdiff_t nbytes;
 
   for (i = sum = 0; i < 9; ++i)
     sum += eabs (matrix[i]);
 
 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
 
-  if (img->height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width)
+  if (INT_MULTIPLY_WRAPV (sizeof *new, img->width, &nbytes)
+      || INT_MULTIPLY_WRAPV (img->height, nbytes, &nbytes))
     memory_full (SIZE_MAX);
-  new = xmalloc (sizeof *new * img->width * img->height);
+  new = xmalloc (nbytes);
 
   for (y = 0; y < img->height; ++y)
     {
@@ -5898,6 +5903,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
   png_uint_32 row_bytes;
   bool transparent_p;
   struct png_memory_storage tbr;  /* Data to be read */
+  ptrdiff_t nbytes;
 
 #ifdef USE_CAIRO
   unsigned char *data = 0;
@@ -6102,10 +6108,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
   row_bytes = png_get_rowbytes (png_ptr, info_ptr);
 
   /* Allocate memory for the image.  */
-  if (height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows
-      || row_bytes > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height)
+  if (INT_MULTIPLY_WRAPV (row_bytes, sizeof *pixels, &nbytes)
+      || INT_MULTIPLY_WRAPV (nbytes, height, &nbytes))
     memory_full (SIZE_MAX);
-  c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
+  c->pixels = pixels = xmalloc (nbytes);
   c->rows = rows = xmalloc (height * sizeof *rows);
   for (i = 0; i < height; ++i)
     rows[i] = pixels + i * row_bytes;
index c988d12fe804fe710208bb514682be5cf2e92674..67a4a1075d99106e6f71ff5add94411cbb9898cc 100644 (file)
@@ -853,7 +853,9 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
                XSETCDR (elt, def);
                return def;
              }
-           else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
+           else if (CONSP (idx)
+                    && CHARACTERP (XCAR (idx))
+                    && CHARACTERP (XCAR (elt)))
              {
                int from = XFASTINT (XCAR (idx));
                int to = XFASTINT (XCDR (idx));
@@ -1984,9 +1986,10 @@ For an approximate inverse of this, see `kbd'.  */)
     size += XINT (Flength (prefix));
 
   /* This has one extra element at the end that we don't pass to Fconcat.  */
-  if (min (PTRDIFF_MAX, SIZE_MAX) / word_size / 4 < size)
+  EMACS_INT size4;
+  if (INT_MULTIPLY_WRAPV (size, 4, &size4))
     memory_full (SIZE_MAX);
-  SAFE_ALLOCA_LISP (args, size * 4);
+  SAFE_ALLOCA_LISP (args, size4);
 
   /* In effect, this computes
      (mapconcat 'single-key-description keys " ")
index a1409d1af8cfd8f97135fa2eefffa313b3203fc0..784ab18c0eea66b283bad178556b033bcb99462b 100644 (file)
@@ -4447,40 +4447,24 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
     }                                  \
   } while (false)
 
-
-/* Return floor (NBYTES / WORD_SIZE).  */
-
-INLINE ptrdiff_t
-lisp_word_count (ptrdiff_t nbytes)
-{
-  if (-1 >> 1 == -1)
-    switch (word_size + 0)
-      {
-      case 2: return nbytes >> 1;
-      case 4: return nbytes >> 2;
-      case 8: return nbytes >> 3;
-      case 16: return nbytes >> 4;
-      default: break;
-      }
-  return nbytes / word_size - (nbytes % word_size < 0);
-}
-
 /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects.  */
 
 #define SAFE_ALLOCA_LISP(buf, nelt)                           \
   do {                                                        \
-    if ((nelt) <= lisp_word_count (sa_avail))                 \
-      (buf) = AVAIL_ALLOCA ((nelt) * word_size);              \
-    else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
+    ptrdiff_t alloca_nbytes;                                  \
+    if (INT_MULTIPLY_WRAPV (nelt, word_size, &alloca_nbytes)   \
+       || SIZE_MAX < alloca_nbytes)                           \
+      memory_full (SIZE_MAX);                                 \
+    else if (alloca_nbytes <= sa_avail)                               \
+      (buf) = AVAIL_ALLOCA (alloca_nbytes);                   \
+    else                                                      \
       {                                                               \
        Lisp_Object arg_;                                      \
-       (buf) = xmalloc ((nelt) * word_size);                  \
+       (buf) = xmalloc (alloca_nbytes);                       \
        arg_ = make_save_memory (buf, nelt);                   \
        sa_must_free = true;                                   \
        record_unwind_protect (free_save_value, arg_);         \
       }                                                               \
-    else                                                      \
-      memory_full (SIZE_MAX);                                 \
   } while (false)
 
 
index 7c891f9954f6794035fcf4fac82a7671c8f3f172..c4456f37f6dd1c18ef3a6c96951e74daaf0f7e5a 100644 (file)
@@ -2120,6 +2120,15 @@ read0 (Lisp_Object readcharfun)
 static ptrdiff_t read_buffer_size;
 static char *read_buffer;
 
+/* Grow the read buffer by at least MAX_MULTIBYTE_LENGTH bytes.  */
+
+static void
+grow_read_buffer (void)
+{
+  read_buffer = xpalloc (read_buffer, &read_buffer_size,
+                        MAX_MULTIBYTE_LENGTH, -1, 1);
+}
+
 /* Read a \-escape sequence, assuming we already read the `\'.
    If the escape sequence forces unibyte, return eight-bit char.  */
 
@@ -2985,10 +2994,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
            if (end - p < MAX_MULTIBYTE_LENGTH)
              {
                ptrdiff_t offset = p - read_buffer;
-               if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
-                 memory_full (SIZE_MAX);
-               read_buffer = xrealloc (read_buffer, read_buffer_size * 2);
-               read_buffer_size *= 2;
+               grow_read_buffer ();
                p = read_buffer + offset;
                end = read_buffer + read_buffer_size;
              }
@@ -3119,10 +3125,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
              if (end - p < MAX_MULTIBYTE_LENGTH)
                {
                  ptrdiff_t offset = p - read_buffer;
-                 if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
-                   memory_full (SIZE_MAX);
-                 read_buffer = xrealloc (read_buffer, read_buffer_size * 2);
-                 read_buffer_size *= 2;
+                 grow_read_buffer ();
                  p = read_buffer + offset;
                  end = read_buffer + read_buffer_size;
                }
@@ -3149,10 +3152,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
          if (p == end)
            {
              ptrdiff_t offset = p - read_buffer;
-             if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
-               memory_full (SIZE_MAX);
-             read_buffer = xrealloc (read_buffer, read_buffer_size * 2);
-             read_buffer_size *= 2;
+             grow_read_buffer ();
              p = read_buffer + offset;
              end = read_buffer + read_buffer_size;
            }
index d963838069bf0929f2a482e8d5a2ceb9876db212..7c6ab2efc306542311198c1dfbdb28d620429948 100644 (file)
@@ -184,16 +184,11 @@ store_kbd_macro_char (Lisp_Object c)
     {
       if (kb->kbd_macro_ptr - kb->kbd_macro_buffer == kb->kbd_macro_bufsize)
        {
-         ptrdiff_t ptr_offset, end_offset, nbytes;
-
-         ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
-         end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
-         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2
-             < kb->kbd_macro_bufsize)
-           memory_full (SIZE_MAX);
-         nbytes = kb->kbd_macro_bufsize * (2 * sizeof *kb->kbd_macro_buffer);
-         kb->kbd_macro_buffer = xrealloc (kb->kbd_macro_buffer, nbytes);
-         kb->kbd_macro_bufsize *= 2;
+         ptrdiff_t ptr_offset = kb->kbd_macro_ptr - kb->kbd_macro_buffer;
+         ptrdiff_t end_offset = kb->kbd_macro_end - kb->kbd_macro_buffer;
+         kb->kbd_macro_buffer = xpalloc (kb->kbd_macro_buffer,
+                                         &kb->kbd_macro_bufsize,
+                                         1, -1, sizeof *kb->kbd_macro_buffer);
          kb->kbd_macro_ptr = kb->kbd_macro_buffer + ptr_offset;
          kb->kbd_macro_end = kb->kbd_macro_buffer + end_offset;
        }
index 31b69461bde6f80a561813f0d94ccb8057a79ff1..727a70b166fe83b7f99a21d54c0cd480d0d3eea5 100644 (file)
@@ -229,12 +229,7 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial,
          if (hide_char)
            fprintf (stdout, "%c", hide_char);
          if (len == size)
-           {
-             if (STRING_BYTES_BOUND / 2 < size)
-               memory_full (SIZE_MAX);
-             size *= 2;
-             line = xrealloc (line, size);
-           }
+           line = xpalloc (line, &size, 1, -1, sizeof *line);
          line[len++] = c;
        }
     }
index 4f97276d7945e037d4551320ddfb4f0cb0694f2a..fabfa2914a0b868fd417173bd0201c09a02c287f 100644 (file)
@@ -839,6 +839,9 @@ static NSRect constrain_frame_rect(NSRect frameRect)
 
 static void
 ns_constrain_all_frames (void)
+/* --------------------------------------------------------------------------
+     Ensure that the menu bar doesn't cover any frames.
+   -------------------------------------------------------------------------- */
 {
   Lisp_Object tail, frame;
 
@@ -851,10 +854,14 @@ ns_constrain_all_frames (void)
       struct frame *f = XFRAME (frame);
       if (FRAME_NS_P (f))
         {
-          NSView *view = FRAME_NS_VIEW (f);
+          EmacsView *view = FRAME_NS_VIEW (f);
 
-          [[view window] setFrame:constrain_frame_rect([[view window] frame])
-                          display:NO];
+          if (![view isFullscreen])
+            {
+              [[view window]
+                setFrame:constrain_frame_rect([[view window] frame])
+                 display:NO];
+            }
         }
     }
 
@@ -862,10 +869,11 @@ ns_constrain_all_frames (void)
 }
 
 
-/* Show or hide the menu bar, based on user setting.  */
-
 static void
 ns_update_auto_hide_menu_bar (void)
+/* --------------------------------------------------------------------------
+     Show or hide the menu bar, based on user setting.
+   -------------------------------------------------------------------------- */
 {
 #ifdef NS_IMPL_COCOA
   NSTRACE ("ns_update_auto_hide_menu_bar");
@@ -6259,7 +6267,10 @@ not_in_argv (NSString *arg)
       wr = NSMakeRect (0, 0, neww, newh);
       NSTRACE_RECT ("setFrame", wr);
       [view setFrame: wr];
-      [self windowDidMove:nil];   // Update top/left.
+      // to do: consider using [NSNotificationCenter postNotificationName:].
+      [self windowDidMove: // Update top/left.
+             [NSNotification notificationWithName:NSWindowDidMoveNotification
+                                           object:[view window]]];
     }
   else
     {
@@ -6372,7 +6383,11 @@ not_in_argv (NSString *arg)
 - (void)windowDidResize: (NSNotification *)notification
 {
   NSTRACE ("windowDidResize");
-
+  if (!FRAME_LIVE_P (emacsframe))
+    {
+      NSTRACE_MSG ("Ignored (frame dead)");
+      return;
+    }
   if (emacsframe->output_data.ns->in_animation)
     {
       NSTRACE_MSG ("Ignored (in animation)");
@@ -6894,7 +6909,11 @@ not_in_argv (NSString *arg)
 - (void)windowWillExitFullScreen:(NSNotification *)notification
 {
   NSTRACE ("windowWillExitFullScreen");
-
+  if (!FRAME_LIVE_P (emacsframe))
+    {
+      NSTRACE_MSG ("Ignored (frame dead)");
+      return;
+    }
   if (next_maximized != -1)
     fs_before_fs = next_maximized;
 }
@@ -6902,7 +6921,11 @@ not_in_argv (NSString *arg)
 - (void)windowDidExitFullScreen:(NSNotification *)notification
 {
   NSTRACE ("windowDidExitFullScreen");
-
+  if (!FRAME_LIVE_P (emacsframe))
+    {
+      NSTRACE_MSG ("Ignored (frame dead)");
+      return;
+    }
   [self setFSValue: fs_before_fs];
   fs_before_fs = -1;
 #ifdef HAVE_NATIVE_FS
@@ -7031,13 +7054,17 @@ not_in_argv (NSString *arg)
 
       nonfs_window = w;
 
-      [self windowWillEnterFullScreen:nil];
+      [self windowWillEnterFullScreen:
+             [NSNotification notificationWithName:NSWindowWillEnterFullScreenNotification
+                                           object:[self window]]];
       [fw makeKeyAndOrderFront:NSApp];
       [fw makeFirstResponder:self];
       [w orderOut:self];
       r = [fw frameRectForContentRect:[screen frame]];
       [fw setFrame: r display:YES animate:ns_use_fullscreen_animation];
-      [self windowDidEnterFullScreen:nil];
+      [self windowDidEnterFullScreen:
+             [NSNotification notificationWithName:NSWindowDidEnterFullScreenNotification
+                                           object:[self window]]];
       [fw display];
     }
   else
@@ -7065,11 +7092,17 @@ not_in_argv (NSString *arg)
       if (FRAME_EXTERNAL_TOOL_BAR (f))
         FRAME_TOOLBAR_HEIGHT (f) = tobar_height;
 
-      [self windowWillExitFullScreen:nil];
+      // to do: consider using [NSNotificationCenter postNotificationName:] to send notifications.
+
+      [self windowWillExitFullScreen:
+             [NSNotification notificationWithName:NSWindowWillExitFullScreenNotification
+                                           object:[self window]]];
       [fw setFrame: [w frame] display:YES animate:ns_use_fullscreen_animation];
       [fw close];
       [w makeKeyAndOrderFront:NSApp];
-      [self windowDidExitFullScreen:nil];
+      [self windowDidExitFullScreen:
+             [NSNotification notificationWithName:NSWindowDidExitFullScreenNotification
+                                           object:[self window]]];
       [self updateFrameSize:YES];
     }
 }
index 9b1e7cad4b2ddec192d5363a161b59bb9bc5c9c1..6ab611d51e20e6fc326180e1b8572259be07bf4d 100644 (file)
@@ -532,15 +532,13 @@ encode_terminal_code (struct glyph *src, int src_len,
      multibyte-form.  But, it may be enlarged on demand if
      Vglyph_table contains a string or a composite glyph is
      encountered.  */
-  if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len)
+  if (INT_MULTIPLY_WRAPV (src_len, MAX_MULTIBYTE_LENGTH, &required))
     memory_full (SIZE_MAX);
-  required = src_len;
-  required *= MAX_MULTIBYTE_LENGTH;
   if (encode_terminal_src_size < required)
-    {
-      encode_terminal_src = xrealloc (encode_terminal_src, required);
-      encode_terminal_src_size = required;
-    }
+    encode_terminal_src = xpalloc (encode_terminal_src,
+                                  &encode_terminal_src_size,
+                                  required - encode_terminal_src_size,
+                                  -1, sizeof *encode_terminal_src);
 
   charset_list = coding_charset_list (coding);
 
index 02047db209504d73218fa3e65c42cd302c62d579..3a64059e0ebf874bda1eea95eb570ee47b8b4277 100644 (file)
@@ -167,9 +167,9 @@ tparam1 (const char *string, char *outstring, int len,
                        doup++, append_len_incr = strlen (up);
                      else
                        doleft++, append_len_incr = strlen (left);
-                     if (INT_ADD_OVERFLOW (append_len, append_len_incr))
+                     if (INT_ADD_WRAPV (append_len_incr,
+                                        append_len, &append_len))
                        memory_full (SIZE_MAX);
-                     append_len += append_len_incr;
                    }
                }
              *op++ = tem ? tem : 0200;
index 483da6eef0c57214f59ccb88fdda44736ca7d623..c10c7f21bf2ab774b9a277eacacc070234362b79 100644 (file)
@@ -40,347 +40,6 @@ what you give them.   Help stamp out software-hoarding!  */
  * On some machines, an existing old_name file is required.
  *
  */
-
-/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
- * ELF support added.
- *
- * Basic theory: the data space of the running process needs to be
- * dumped to the output file.  Normally we would just enlarge the size
- * of .data, scooting everything down.  But we can't do that in ELF,
- * because there is often something between the .data space and the
- * .bss space.
- *
- * In the temacs dump below, notice that the Global Offset Table
- * (.got) and the Dynamic link data (.dynamic) come between .data1 and
- * .bss.  It does not work to overlap .data with these fields.
- *
- * The solution is to create a new .data segment.  This segment is
- * filled with data from the current process.  Since the contents of
- * various sections refer to sections by index, the new .data segment
- * is made the last in the table to avoid changing any existing index.
-
- * This is an example of how the section headers are changed.  "Addr"
- * is a process virtual address.  "Offset" is a file offset.
-
-raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
-
-temacs:
-
-           **** SECTION HEADER TABLE ****
- [No]    Type    Flags   Addr         Offset       Size          Name
-         Link    Info    Adralgn      Entsize
-
- [1]     1       2       0x80480d4    0xd4         0x13          .interp
-         0       0       0x1          0
-
- [2]     5       2       0x80480e8    0xe8         0x388         .hash
-         3       0       0x4          0x4
-
- [3]     11      2       0x8048470    0x470        0x7f0         .dynsym
-         4       1       0x4          0x10
-
- [4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
-         0       0       0x1          0
-
- [5]     9       2       0x8049010    0x1010       0x338         .rel.plt
-         3       7       0x4          0x8
-
- [6]     1       6       0x8049348    0x1348       0x3           .init
-         0       0       0x4          0
-
- [7]     1       6       0x804934c    0x134c       0x680         .plt
-         0       0       0x4          0x4
-
- [8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
-         0       0       0x4          0
-
- [9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
-         0       0       0x4          0
-
- [10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
-         0       0       0x4          0
-
- [11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
-         0       0       0x4          0
-
- [12]    1       3       0x8088330    0x3f330      0x20afc       .data
-         0       0       0x4          0
-
- [13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
-         0       0       0x4          0
-
- [14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
-         0       0       0x4          0x4
-
- [15]    6       3       0x80a9874    0x60874      0x80          .dynamic
-         4       0       0x4          0x8
-
- [16]    8       3       0x80a98f4    0x608f4      0x449c        .bss
-         0       0       0x4          0
-
- [17]    2       0       0            0x608f4      0x9b90        .symtab
-         18      371     0x4          0x10
-
- [18]    3       0       0            0x6a484      0x8526        .strtab
-         0       0       0x1          0
-
- [19]    3       0       0            0x729aa      0x93          .shstrtab
-         0       0       0x1          0
-
- [20]    1       0       0            0x72a3d      0x68b7        .comment
-         0       0       0x1          0
-
- raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
-
- xemacs:
-
-            **** SECTION HEADER TABLE ****
- [No]    Type    Flags   Addr         Offset       Size          Name
-         Link    Info    Adralgn      Entsize
-
- [1]     1       2       0x80480d4    0xd4         0x13          .interp
-         0       0       0x1          0
-
- [2]     5       2       0x80480e8    0xe8         0x388         .hash
-         3       0       0x4          0x4
-
- [3]     11      2       0x8048470    0x470        0x7f0         .dynsym
-         4       1       0x4          0x10
-
- [4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
-         0       0       0x1          0
-
- [5]     9       2       0x8049010    0x1010       0x338         .rel.plt
-         3       7       0x4          0x8
-
- [6]     1       6       0x8049348    0x1348       0x3           .init
-         0       0       0x4          0
-
- [7]     1       6       0x804934c    0x134c       0x680         .plt
-         0       0       0x4          0x4
-
- [8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
-         0       0       0x4          0
-
- [9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
-         0       0       0x4          0
-
- [10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
-         0       0       0x4          0
-
- [11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
-         0       0       0x4          0
-
- [12]    1       3       0x8088330    0x3f330      0x20afc       .data
-         0       0       0x4          0
-
- [13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
-         0       0       0x4          0
-
- [14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
-         0       0       0x4          0x4
-
- [15]    6       3       0x80a9874    0x60874      0x80          .dynamic
-         4       0       0x4          0x8
-
- [16]    8       3       0x80c6800    0x7d800      0             .bss
-         0       0       0x4          0
-
- [17]    2       0       0            0x7d800      0x9b90        .symtab
-         18      371     0x4          0x10
-
- [18]    3       0       0            0x87390      0x8526        .strtab
-         0       0       0x1          0
-
- [19]    3       0       0            0x8f8b6      0x93          .shstrtab
-         0       0       0x1          0
-
- [20]    1       0       0            0x8f949      0x68b7        .comment
-         0       0       0x1          0
-
- [21]    1       3       0x80a98f4    0x608f4      0x1cf0c       .data
-         0       0       0x4          0
-
-  * This is an example of how the file header is changed.  "Shoff" is
-  * the section header offset within the file.  Since that table is
-  * after the new .data section, it is moved.  "Shnum" is the number of
-  * sections, which we increment.
-  *
-  * "Phoff" is the file offset to the program header.  "Phentsize" and
-  * "Shentsz" are the program and section header entries sizes respectively.
-  * These can be larger than the apparent struct sizes.
-
- raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
-
- temacs:
-
-                     **** ELF HEADER ****
- Class        Data       Type         Machine     Version
- Entry        Phoff      Shoff        Flags       Ehsize
- Phentsize    Phnum      Shentsz      Shnum       Shstrndx
-
- 1            1          2            3           1
- 0x80499cc    0x34       0x792f4      0           0x34
- 0x20         5          0x28         21          19
-
- raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
-
- xemacs:
-
-                     **** ELF HEADER ****
- Class        Data       Type         Machine     Version
- Entry        Phoff      Shoff        Flags       Ehsize
- Phentsize    Phnum      Shentsz      Shnum       Shstrndx
-
- 1            1          2            3           1
- 0x80499cc    0x34       0x96200      0           0x34
- 0x20         5          0x28         22          19
-
-  * These are the program headers.  "Offset" is the file offset to the
-  * segment.  "Vaddr" is the memory load address.  "Filesz" is the
-  * segment size as it appears in the file, and "Memsz" is the size in
-  * memory.  Below, the third segment is the code and the fourth is the
-  * data: the difference between Filesz and Memsz is .bss
-
- raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
-
- temacs:
-  ***** PROGRAM EXECUTION HEADER *****
- Type        Offset      Vaddr       Paddr
- Filesz      Memsz       Flags       Align
-
- 6           0x34        0x8048034   0
- 0xa0        0xa0        5           0
-
- 3           0xd4        0           0
- 0x13        0           4           0
-
- 1           0x34        0x8048034   0
- 0x3f2f9     0x3f2f9     5           0x1000
-
- 1           0x3f330     0x8088330   0
- 0x215c4     0x25a60     7           0x1000
-
- 2           0x60874     0x80a9874   0
- 0x80        0           7           0
-
- raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
-
- xemacs:
-  ***** PROGRAM EXECUTION HEADER *****
- Type        Offset      Vaddr       Paddr
- Filesz      Memsz       Flags       Align
-
- 6           0x34        0x8048034   0
- 0xa0        0xa0        5           0
-
- 3           0xd4        0           0
- 0x13        0           4           0
-
- 1           0x34        0x8048034   0
- 0x3f2f9     0x3f2f9     5           0x1000
-
- 1           0x3f330     0x8088330   0
- 0x3e4d0     0x3e4d0     7           0x1000
-
- 2           0x60874     0x80a9874   0
- 0x80        0           7           0
-
-
- */
-\f
-/* Modified by wtien@urbana.mcd.mot.com of Motorola Inc.
- *
- * The above mechanism does not work if the unexeced ELF file is being
- * re-layout by other applications (such as `strip'). All the applications
- * that re-layout the internal of ELF will layout all sections in ascending
- * order of their file offsets. After the re-layout, the data2 section will
- * still be the LAST section in the section header vector, but its file offset
- * is now being pushed far away down, and causes part of it not to be mapped
- * in (ie. not covered by the load segment entry in PHDR vector), therefore
- * causes the new binary to fail.
- *
- * The solution is to modify the unexec algorithm to insert the new data2
- * section header right before the new bss section header, so their file
- * offsets will be in the ascending order. Since some of the section's (all
- * sections AFTER the bss section) indexes are now changed, we also need to
- * modify some fields to make them point to the right sections. This is done
- * by macro PATCH_INDEX. All the fields that need to be patched are:
- *
- * 1. ELF header e_shstrndx field.
- * 2. section header sh_link and sh_info field.
- * 3. symbol table entry st_shndx field.
- *
- * The above example now should look like:
-
-           **** SECTION HEADER TABLE ****
- [No]    Type    Flags   Addr         Offset       Size          Name
-         Link    Info    Adralgn      Entsize
-
- [1]     1       2       0x80480d4    0xd4         0x13          .interp
-         0       0       0x1          0
-
- [2]     5       2       0x80480e8    0xe8         0x388         .hash
-         3       0       0x4          0x4
-
- [3]     11      2       0x8048470    0x470        0x7f0         .dynsym
-         4       1       0x4          0x10
-
- [4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
-         0       0       0x1          0
-
- [5]     9       2       0x8049010    0x1010       0x338         .rel.plt
-         3       7       0x4          0x8
-
- [6]     1       6       0x8049348    0x1348       0x3           .init
-         0       0       0x4          0
-
- [7]     1       6       0x804934c    0x134c       0x680         .plt
-         0       0       0x4          0x4
-
- [8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
-         0       0       0x4          0
-
- [9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
-         0       0       0x4          0
-
- [10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
-         0       0       0x4          0
-
- [11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
-         0       0       0x4          0
-
- [12]    1       3       0x8088330    0x3f330      0x20afc       .data
-         0       0       0x4          0
-
- [13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
-         0       0       0x4          0
-
- [14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
-         0       0       0x4          0x4
-
- [15]    6       3       0x80a9874    0x60874      0x80          .dynamic
-         4       0       0x4          0x8
-
- [16]    1       3       0x80a98f4    0x608f4      0x1cf0c       .data
-         0       0       0x4          0
-
- [17]    8       3       0x80c6800    0x7d800      0             .bss
-         0       0       0x4          0
-
- [18]    2       0       0            0x7d800      0x9b90        .symtab
-         19      371     0x4          0x10
-
- [19]    3       0       0            0x87390      0x8526        .strtab
-         0       0       0x1          0
-
- [20]    3       0       0            0x8f8b6      0x93          .shstrtab
-         0       0       0x1          0
-
- [21]    1       0       0            0x8f949      0x68b7        .comment
-         0       0       0x1          0
-
- */
 \f
 /* We do not use mmap because that fails with NFS.
    Instead we read the whole file, modify it, and write it out.  */
@@ -535,29 +194,6 @@ verify ((! TYPE_SIGNED (ElfW (Half))
 /* Get the address of a particular section or program header entry,
  * accounting for the size of the entries.
  */
-/*
-   On PPC Reference Platform running Solaris 2.5.1
-   the plt section is also of type NOBI like the bss section.
-   (not really stored) and therefore sections after the bss
-   section start at the plt offset. The plt section is always
-   the one just before the bss section.
-   Thus, we modify the test from
-      if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
-   to
-      if (NEW_SECTION_H (nn).sh_offset >=
-               OLD_SECTION_H (old_bss_index-1).sh_offset)
-   This is just a hack. We should put the new data section
-   before the .plt section.
-   And we should not have this routine at all but use
-   the libelf library to read the old file and create the new
-   file.
-   The changed code is minimal and depends on prep set in m/prep.h
-   Erik Deumens
-   Quantum Theory Project
-   University of Florida
-   deumens@qtp.ufl.edu
-   Apr 23, 1996
-   */
 
 static void *
 entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize)
@@ -570,59 +206,18 @@ entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize)
   (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shentsize))
 #define NEW_SECTION_H(n) \
   (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize))
-#define NEW_PROGRAM_H(n) \
-  (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phentsize))
+#define OLD_PROGRAM_H(n) \
+  (*(ElfW (Phdr) *) entry_address (old_program_h, n, old_file_h->e_phentsize))
 
-#define PATCH_INDEX(n) ((n) += old_bss_index <= (n))
 typedef unsigned char byte;
 
-/* Round X up to a multiple of Y.  */
-
-static ElfW (Addr)
-round_up (ElfW (Addr) x, ElfW (Addr) y)
-{
-  ElfW (Addr) rem = x % y;
-  if (rem == 0)
-    return x;
-  return x - rem + y;
-}
-
-/* Return the index of the section named NAME.
-   SECTION_NAMES, FILE_NAME and FILE_H give information
-   about the file we are looking in.
-
-   If we don't find the section NAME, that is a fatal error
-   if NOERROR is false; return -1 if NOERROR is true.  */
-
-static ptrdiff_t
-find_section (const char *name, const char *section_names, const char *file_name,
-             ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h,
-             bool noerror)
-{
-  ptrdiff_t idx;
-
-  for (idx = 1; idx < old_file_h->e_shnum; idx++)
-    {
-      char const *found_name = section_names + OLD_SECTION_H (idx).sh_name;
-#ifdef UNEXELF_DEBUG
-      fprintf (stderr, "Looking for %s - found %s\n", name, found_name);
-#endif
-      if (strcmp (name, found_name) == 0)
-       return idx;
-    }
-
-  if (! noerror)
-    fatal ("Can't find %s in %s", name, file_name);
-  return -1;
-}
-
 /* ****************************************************************
  * unexec
  *
  * driving logic.
  *
- * In ELF, this works by replacing the old .bss section with a new
- * .data section, and inserting an empty .bss immediately afterwards.
+ * In ELF, this works by replacing the old bss SHT_NOBITS section with
+ * a new, larger, SHT_PROGBITS section.
  *
  */
 void
@@ -647,22 +242,16 @@ unexec (const char *new_name, const char *old_name)
   ElfW (Phdr) *old_program_h, *new_program_h;
   ElfW (Shdr) *old_section_h, *new_section_h;
 
-  /* Point to the section name table in the old file.  */
-  char *old_section_names;
+  /* Point to the section name table.  */
+  char *old_section_names, *new_section_names;
 
+  ElfW (Phdr) *old_bss_seg, *new_bss_seg;
   ElfW (Addr) old_bss_addr, new_bss_addr;
   ElfW (Word) old_bss_size, new_data2_size;
-  ElfW (Off)  new_data2_offset;
-  ElfW (Addr) new_data2_addr;
-  ElfW (Off)  old_bss_offset;
-  ElfW (Word) new_data2_incr;
-
-  ptrdiff_t n, nn;
-  ptrdiff_t old_bss_index, old_sbss_index, old_plt_index;
-  ptrdiff_t old_data_index, new_data2_index;
-#if defined _SYSTYPE_SYSV || defined __sgi
-  ptrdiff_t old_mdebug_index;
-#endif
+  ElfW (Off) old_bss_offset, new_data2_offset;
+
+  ptrdiff_t n;
+  ptrdiff_t old_bss_index;
   struct stat stat_buf;
   off_t old_file_size;
 
@@ -706,78 +295,44 @@ unexec (const char *new_name, const char *old_name)
   old_section_names = (char *) old_base
     + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
 
-  /* Find the mdebug section, if any.  */
-
-#if defined _SYSTYPE_SYSV || defined __sgi
-  old_mdebug_index = find_section (".mdebug", old_section_names,
-                                  old_name, old_file_h, old_section_h, 1);
-#endif
-
-  /* Find the old .bss section.  Figure out parameters of the new
-     data2 and bss sections.  */
-
-  old_bss_index = find_section (".bss", old_section_names,
-                               old_name, old_file_h, old_section_h, 0);
-
-  old_sbss_index = find_section (".sbss", old_section_names,
-                                old_name, old_file_h, old_section_h, 1);
-  if (old_sbss_index != -1)
-    if (OLD_SECTION_H (old_sbss_index).sh_type != SHT_NOBITS)
-      old_sbss_index = -1;
-
-  /* PowerPC64 has .plt in the BSS section.  */
-  old_plt_index = find_section (".plt", old_section_names,
-                               old_name, old_file_h, old_section_h, 1);
-  if (old_plt_index != -1)
-    if (OLD_SECTION_H (old_plt_index).sh_type != SHT_NOBITS)
-      old_plt_index = -1;
-
-  if (old_sbss_index == -1 && old_plt_index == -1)
-    {
-      old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
-      old_bss_offset = OLD_SECTION_H (old_bss_index).sh_offset;
-      new_data2_index = old_bss_index;
-    }
-  else if (old_plt_index != -1
-          && (old_sbss_index == -1
-              || (OLD_SECTION_H (old_sbss_index).sh_addr
-                  > OLD_SECTION_H (old_plt_index).sh_addr)))
+  /* Find the PT_LOAD header covering the highest address.  This
+     segment will be where bss sections are located, past p_filesz.  */
+  old_bss_seg = 0;
+  for (n = old_file_h->e_phnum; --n >= 0; )
     {
-      old_bss_addr = OLD_SECTION_H (old_plt_index).sh_addr;
-      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
-       + OLD_SECTION_H (old_plt_index).sh_size;
-      if (old_sbss_index != -1)
-       old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size;
-      old_bss_offset = OLD_SECTION_H (old_plt_index).sh_offset;
-      new_data2_index = old_plt_index;
+      ElfW (Phdr) *seg = &OLD_PROGRAM_H (n);
+      if (seg->p_type == PT_LOAD
+         && (old_bss_seg == 0
+             || seg->p_vaddr > old_bss_seg->p_vaddr))
+       old_bss_seg = seg;
     }
-  else
+
+  /* Note that old_bss_addr may be lower than the first bss section
+     address, since the section may need aligning.  */
+  old_bss_addr = old_bss_seg->p_vaddr + old_bss_seg->p_filesz;
+  old_bss_offset = old_bss_seg->p_offset + old_bss_seg->p_filesz;
+  old_bss_size = old_bss_seg->p_memsz - old_bss_seg->p_filesz;
+
+  /* Find the last bss style section in the bss segment range.  */
+  old_bss_index = -1;
+  for (n = old_file_h->e_shnum; --n > 0; )
     {
-      old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
-       + OLD_SECTION_H (old_sbss_index).sh_size;
-      old_bss_offset = OLD_SECTION_H (old_sbss_index).sh_offset;
-      new_data2_index = old_sbss_index;
+      ElfW (Shdr) *shdr = &OLD_SECTION_H (n);
+      if (shdr->sh_type == SHT_NOBITS
+         && shdr->sh_addr >= old_bss_addr
+         && shdr->sh_addr + shdr->sh_size <= old_bss_addr + old_bss_size
+         && (old_bss_index == -1
+             || OLD_SECTION_H (old_bss_index).sh_addr < shdr->sh_addr))
+       old_bss_index = n;
     }
 
-  /* Find the old .data section.  Figure out parameters of
-     the new data2 and bss sections.  */
-
-  old_data_index = find_section (".data", old_section_names,
-                                old_name, old_file_h, old_section_h, 0);
+  if (old_bss_index == -1)
+    fatal ("no bss section found");
 
   new_break = sbrk (0);
   new_bss_addr = (ElfW (Addr)) new_break;
-  new_data2_addr = old_bss_addr;
   new_data2_size = new_bss_addr - old_bss_addr;
-  new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset
-    + (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
-  /* This is the amount by which the sections following the bss sections
-     must be shifted in the image.  It can differ from new_data2_size if
-     the end of the old .data section (and thus the offset of the .bss
-     section) was unaligned.  */
-  new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset);
+  new_data2_offset = old_bss_offset;
 
 #ifdef UNEXELF_DEBUG
   fprintf (stderr, "old_bss_index %td\n", old_bss_index);
@@ -785,10 +340,8 @@ unexec (const char *new_name, const char *old_name)
   DEBUG_LOG (old_bss_size);
   DEBUG_LOG (old_bss_offset);
   DEBUG_LOG (new_bss_addr);
-  DEBUG_LOG (new_data2_addr);
   DEBUG_LOG (new_data2_size);
   DEBUG_LOG (new_data2_offset);
-  DEBUG_LOG (new_data2_incr);
 #endif
 
   if (new_bss_addr < old_bss_addr + old_bss_size)
@@ -802,7 +355,7 @@ unexec (const char *new_name, const char *old_name)
   if (new_file < 0)
     fatal ("Can't creat (%s): %s", new_name, strerror (errno));
 
-  new_file_size = old_file_size + old_file_h->e_shentsize + new_data2_incr;
+  new_file_size = old_file_size + new_data2_size;
 
   if (ftruncate (new_file, new_file_size))
     fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno));
@@ -812,26 +365,24 @@ unexec (const char *new_name, const char *old_name)
   if (new_base == MAP_FAILED)
     fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
 
-  new_file_h = (ElfW (Ehdr) *) new_base;
-  new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
-  new_section_h = (ElfW (Shdr) *)
-    ((byte *) new_base + old_file_h->e_shoff + new_data2_incr);
-
   /* Make our new file, program and section headers as copies of the
      originals.  */
 
+  new_file_h = (ElfW (Ehdr) *) new_base;
   memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
-  memcpy (new_program_h, old_program_h,
-         old_file_h->e_phnum * old_file_h->e_phentsize);
 
-  /* Modify the e_shstrndx if necessary. */
-  PATCH_INDEX (new_file_h->e_shstrndx);
+  /* Fix up file header.  Section header is further away now.  */
+
+  if (new_file_h->e_shoff >= old_bss_offset)
+    new_file_h->e_shoff += new_data2_size;
 
-  /* Fix up file header.  We'll add one section.  Section header is
-     further away now.  */
+  new_program_h = (ElfW (Phdr) *) ((byte *) new_base + new_file_h->e_phoff);
+  new_section_h = (ElfW (Shdr) *) ((byte *) new_base + new_file_h->e_shoff);
 
-  new_file_h->e_shoff += new_data2_incr;
-  new_file_h->e_shnum += 1;
+  memcpy (new_program_h, old_program_h,
+         old_file_h->e_phnum * old_file_h->e_phentsize);
+  memcpy (new_section_h, old_section_h,
+         old_file_h->e_shnum * old_file_h->e_shentsize);
 
 #ifdef UNEXELF_DEBUG
   DEBUG_LOG (old_file_h->e_shoff);
@@ -840,188 +391,71 @@ unexec (const char *new_name, const char *old_name)
   fprintf (stderr, "New section count %td\n", (ptrdiff_t) new_file_h->e_shnum);
 #endif
 
-  /* Fix up a new program header.  Extend the writable data segment so
-     that the bss area is covered too. Find that segment by looking
-     for a segment that ends just before the .bss area.  Make sure
-     that no segments are above the new .data2.  Put a loop at the end
-     to adjust the offset and address of any segment that is above
-     data2, just in case we decide to allow this later.  */
-
-  for (n = new_file_h->e_phnum; --n >= 0; )
-    {
-      /* Compute maximum of all requirements for alignment of section.  */
-      ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align;
-      if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
-       alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
-
-#ifdef __sgi
-         /* According to r02kar@x4u2.desy.de (Karsten Kuenne)
-            and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we
-            always get "Program segment above .bss" when dumping
-            when the executable doesn't have an sbss section.  */
-      if (old_sbss_index != -1)
-#endif /* __sgi */
-      if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
-         > (old_sbss_index == -1
-            ? old_bss_addr
-            : round_up (old_bss_addr, alignment)))
-         fatal ("Program segment above .bss in %s", old_name);
-
-      if (NEW_PROGRAM_H (n).p_type == PT_LOAD
-         && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
-                       + (NEW_PROGRAM_H (n)).p_filesz,
-                       alignment)
-             == round_up (old_bss_addr, alignment)))
-       break;
-    }
-  if (n < 0)
-    fatal ("Couldn't find segment next to .bss in %s", old_name);
-
-  /* Make sure that the size includes any padding before the old .bss
-     section.  */
-  NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr;
-  NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
+  /* Fix up program header.  Extend the writable data segment so
+     that the bss area is covered too.  */
 
-#if 0 /* Maybe allow section after data2 - does this ever happen? */
-  for (n = new_file_h->e_phnum; --n >= 0; )
-    {
-      if (NEW_PROGRAM_H (n).p_vaddr
-         && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
-       NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size;
-
-      if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
-       NEW_PROGRAM_H (n).p_offset += new_data2_incr;
-    }
-#endif
+  new_bss_seg = new_program_h + (old_bss_seg - old_program_h);
+  new_bss_seg->p_filesz = new_bss_addr - new_bss_seg->p_vaddr;
+  new_bss_seg->p_memsz = new_bss_seg->p_filesz;
 
-  /* Fix up section headers based on new .data2 section.  Any section
-     whose offset or virtual address is after the new .data2 section
-     gets its value adjusted.  .bss size becomes zero and new address
-     is set.  data2 section header gets added by copying the existing
-     .data header and modifying the offset, address and size.  */
+  /* Copy over what we have in memory now for the bss area. */
+  memcpy (new_base + new_data2_offset, (caddr_t) old_bss_addr, new_data2_size);
 
-  /* Walk through all section headers, insert the new data2 section right
-     before the new bss section. */
-  for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++)
+  /* Walk through all section headers, copying data and updating.  */
+  for (n = 1; n < old_file_h->e_shnum; n++)
     {
       caddr_t src;
-      /* If it is (s)bss section, insert the new data2 section before it.  */
-      /* new_data2_index is the index of either old_sbss or old_bss, that was
-        chosen as a section for new_data2.   */
-      if (n == new_data2_index)
-       {
-         /* Steal the data section header for this data2 section. */
-         memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
-                 new_file_h->e_shentsize);
-
-         NEW_SECTION_H (nn).sh_addr = new_data2_addr;
-         NEW_SECTION_H (nn).sh_offset = new_data2_offset;
-         NEW_SECTION_H (nn).sh_size = new_data2_size;
-         /* Use the bss section's alignment. This will assure that the
-            new data2 section always be placed in the same spot as the old
-            bss section by any other application. */
-         NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
-
-         /* Now copy over what we have in the memory now. */
-         memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
-                 (caddr_t) OLD_SECTION_H (n).sh_addr,
-                 new_data2_size);
-         nn++;
-       }
+      ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n);
+      ElfW (Shdr) *new_shdr = &NEW_SECTION_H (n);
 
-      memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
-             old_file_h->e_shentsize);
-
-      if (n == old_bss_index
-         /* The new bss and sbss section's size is zero, and its file offset
-            and virtual address should be off by NEW_DATA2_SIZE.  */
-         || n == old_sbss_index || n == old_plt_index
-         )
-       {
-         /* NN should be `old_s?bss_index + 1' at this point. */
-         NEW_SECTION_H (nn).sh_offset = new_data2_offset + new_data2_size;
-         NEW_SECTION_H (nn).sh_addr = new_data2_addr + new_data2_size;
-         /* Let the new bss section address alignment be the same as the
-            section address alignment followed the old bss section, so
-            this section will be placed in exactly the same place. */
-         NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
-         NEW_SECTION_H (nn).sh_size = 0;
-       }
-      else
+      if (new_shdr->sh_type == SHT_NOBITS
+         && new_shdr->sh_addr >= old_bss_addr
+         && (new_shdr->sh_addr + new_shdr->sh_size
+             <= old_bss_addr + old_bss_size))
        {
-         /* Any section that was originally placed after the .bss
-            section should now be off by NEW_DATA2_INCR.  If a
-            section overlaps the .bss section, consider it to be
-            placed after the .bss section.  Overlap can occur if the
-            section just before .bss has less-strict alignment; this
-            was observed between .symtab and .bss on Solaris 2.5.1
-            (sparc) with GCC snapshot 960602.
-
-> dump -h temacs
-
-temacs:
-
-          **** SECTION HEADER TABLE ****
-[No]   Type    Flags   Addr         Offset       Size          Name
-       Link    Info    Adralgn      Entsize
-
-[22]   1       3       0x335150     0x315150     0x4           .data.rel.local
-       0       0       0x4          0
-
-[23]   8       3       0x335158     0x315158     0x42720       .bss
-       0       0       0x8          0
-
-[24]   2       0       0            0x315154     0x1c9d0       .symtab
-       25      1709    0x4          0x10
-         */
-
-         if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset
-             || (NEW_SECTION_H (nn).sh_offset + NEW_SECTION_H (nn).sh_size
-                 > new_data2_offset))
-           NEW_SECTION_H (nn).sh_offset += new_data2_incr;
-
-         /* Any section that was originally placed after the section
-            header table should now be off by the size of one section
-            header table entry.  */
-         if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff)
-           NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize;
+         /* This section now has file backing.  */
+         new_shdr->sh_type = SHT_PROGBITS;
+
+         /* SHT_NOBITS sections do not need a valid sh_offset, so it
+            might be incorrect.  Write the correct value.  */
+         new_shdr->sh_offset = (new_shdr->sh_addr - new_bss_seg->p_vaddr
+                                + new_bss_seg->p_offset);
+
+         /* If this is was a SHT_NOBITS .plt section, then it is
+            probably a PowerPC PLT.  If it is PowerPC64 ELFv1 then
+            glibc ld.so doesn't initialize the toc pointer word.  A
+            non-zero toc pointer word can defeat Power7 thread safety
+            during lazy update of a PLT entry.  This only matters if
+            emacs becomes multi-threaded.  */
+         if (strcmp (old_section_names + new_shdr->sh_name, ".plt") == 0)
+           memset (new_shdr->sh_offset + new_base, 0, new_shdr->sh_size);
+
+         /* Extend the size of the last bss section to cover dumped
+            data.  */
+         if (n == old_bss_index)
+           new_shdr->sh_size = new_bss_addr - new_shdr->sh_addr;
+
+         /* We have already copied this section from the current
+            process.  */
+         continue;
        }
 
-      /* If any section hdr refers to the section after the new .data
-        section, make it refer to next one because we have inserted
-        a new section in between.  */
-
-      PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
-      /* For symbol tables, info is a symbol table index,
-        so don't change it.  */
-      if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
-         && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
-       PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
-
-      if (old_sbss_index != -1)
-       if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss"))
-         {
-           NEW_SECTION_H (nn).sh_offset =
-             round_up (NEW_SECTION_H (nn).sh_offset,
-                       NEW_SECTION_H (nn).sh_addralign);
-           NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
-         }
+      /* Any section that was originally placed after the .bss
+        section should now be offset by NEW_DATA2_SIZE.  */
+      if (new_shdr->sh_offset >= old_bss_offset)
+       new_shdr->sh_offset += new_data2_size;
 
       /* Now, start to copy the content of sections.  */
-      if (NEW_SECTION_H (nn).sh_type == SHT_NULL
-         || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
+      if (new_shdr->sh_type == SHT_NULL
+         || new_shdr->sh_type == SHT_NOBITS)
        continue;
 
-      /* Write out the sections. .data and .data1 (and data2, called
-        ".data" in the strings table) get copied from the current process
-        instead of the old file.  */
-      if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".sdata")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".lit4")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".lit8")
+      /* Some sections are copied from the current process instead of
+        the old file.  */
+      if (!strcmp (old_section_names + new_shdr->sh_name, ".data")
+         || !strcmp (old_section_names + new_shdr->sh_name, ".sdata")
+         || !strcmp (old_section_names + new_shdr->sh_name, ".lit4")
+         || !strcmp (old_section_names + new_shdr->sh_name, ".lit8")
          /* The conditional bit below was in Oliva's original code
             (1999-08-25) and seems to have been dropped by mistake
             subsequently.  It prevents a crash at startup under X in
@@ -1043,68 +477,41 @@ temacs:
             loader, but I never got anywhere with an SGI support call
             seeking clues.  -- fx 2002-11-29.  */
 #ifdef IRIX6_5
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".got")
+         || !strcmp (old_section_names + new_shdr->sh_name, ".got")
 #endif
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".sdata1")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".data1")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".sbss"))
-       src = (caddr_t) OLD_SECTION_H (n).sh_addr;
+         || !strcmp (old_section_names + new_shdr->sh_name, ".sdata1")
+         || !strcmp (old_section_names + new_shdr->sh_name, ".data1"))
+       src = (caddr_t) old_shdr->sh_addr;
       else
-       src = old_base + OLD_SECTION_H (n).sh_offset;
-
-      memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
-             NEW_SECTION_H (nn).sh_size);
+       src = old_base + old_shdr->sh_offset;
 
-#if defined __alpha__ && !defined __OpenBSD__
-      /* Update Alpha COFF symbol table: */
-      if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
-         == 0)
-       {
-         pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
-
-         symhdr->cbLineOffset += new_data2_size;
-         symhdr->cbDnOffset += new_data2_size;
-         symhdr->cbPdOffset += new_data2_size;
-         symhdr->cbSymOffset += new_data2_size;
-         symhdr->cbOptOffset += new_data2_size;
-         symhdr->cbAuxOffset += new_data2_size;
-         symhdr->cbSsOffset += new_data2_size;
-         symhdr->cbSsExtOffset += new_data2_size;
-         symhdr->cbFdOffset += new_data2_size;
-         symhdr->cbRfdOffset += new_data2_size;
-         symhdr->cbExtOffset += new_data2_size;
-       }
-#endif /* __alpha__ && !__OpenBSD__ */
+      memcpy (new_shdr->sh_offset + new_base, src, new_shdr->sh_size);
 
-#if defined (_SYSTYPE_SYSV)
-      if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
-         && old_mdebug_index != -1)
+#if (defined __alpha__ && !defined __OpenBSD__) || defined _SYSTYPE_SYSV
+      /* Update Alpha and MIPS COFF debug symbol table.  */
+      if (strcmp (old_section_names + new_shdr->sh_name, ".mdebug") == 0
+         && new_shdr->sh_offset - old_shdr->sh_offset != 0
+#if defined _SYSTYPE_SYSV
+         && new_shdr->sh_type == SHT_MIPS_DEBUG
+#endif
+         )
        {
-         ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset;
-         ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset;
-         ptrdiff_t diff = new_offset - old_offset;
-         HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
-
-         if (diff)
-           {
-             phdr->cbLineOffset += diff;
-             phdr->cbDnOffset   += diff;
-             phdr->cbPdOffset   += diff;
-             phdr->cbSymOffset  += diff;
-             phdr->cbOptOffset  += diff;
-             phdr->cbAuxOffset  += diff;
-             phdr->cbSsOffset   += diff;
-             phdr->cbSsExtOffset += diff;
-             phdr->cbFdOffset   += diff;
-             phdr->cbRfdOffset  += diff;
-             phdr->cbExtOffset  += diff;
-           }
+         ptrdiff_t diff = new_shdr->sh_offset - old_shdr->sh_offset;
+         HDRR *phdr = (HDRR *) (new_shdr->sh_offset + new_base);
+
+         phdr->cbLineOffset += diff;
+         phdr->cbDnOffset += diff;
+         phdr->cbPdOffset += diff;
+         phdr->cbSymOffset += diff;
+         phdr->cbOptOffset += diff;
+         phdr->cbAuxOffset += diff;
+         phdr->cbSsOffset += diff;
+         phdr->cbSsExtOffset += diff;
+         phdr->cbFdOffset += diff;
+         phdr->cbRfdOffset += diff;
+         phdr->cbExtOffset += diff;
        }
-#endif /* _SYSTYPE_SYSV */
+#endif /* __alpha__ || _SYSTYPE_SYSV */
 
 #if __sgi
       /* Adjust  the HDRR offsets in .mdebug and copy the
@@ -1115,7 +522,8 @@ temacs:
         the ld bug that gets the line table in a hole in the
         elf file rather than in the .mdebug section proper.
         David Anderson. davea@sgi.com  Jan 16,1994.  */
-      if (n == old_mdebug_index)
+      if (strcmp (old_section_names + new_shdr->sh_name, ".mdebug") == 0
+         && new_shdr->sh_offset - old_shdr->sh_offset != 0)
        {
 #define MDEBUGADJUST(__ct,__fileaddr)          \
   if (n_phdrr->__ct > 0)                       \
@@ -1123,9 +531,9 @@ temacs:
       n_phdrr->__fileaddr += movement;         \
     }
 
-         HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
-         HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
-         unsigned movement = new_data2_size;
+         HDRR *o_phdrr = (HDRR *) ((byte *) old_base + old_shdr->sh_offset);
+         HDRR *n_phdrr = (HDRR *) ((byte *) new_base + new_shdr->sh_offset);
+         ptrdiff_t movement = new_shdr->sh_offset - old_shdr->sh_offset;
 
          MDEBUGADJUST (idnMax, cbDnOffset);
          MDEBUGADJUST (ipdMax, cbPdOffset);
@@ -1141,44 +549,16 @@ temacs:
             requires special handling.  */
          if (n_phdrr->cbLine > 0)
            {
-             if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
-                                          + OLD_SECTION_H (n).sh_size))
-               {
-                 /* line data is in a hole in elf. do special copy and adjust
-                    for this ld mistake.
-                    */
-                 n_phdrr->cbLineOffset += movement;
+             n_phdrr->cbLineOffset += movement;
 
-                 memcpy (n_phdrr->cbLineOffset + new_base,
-                         o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
-               }
-             else
-               {
-                 /* somehow line data is in .mdebug as it is supposed to be.  */
-                 MDEBUGADJUST (cbLine, cbLineOffset);
-               }
+             if (o_phdrr->cbLineOffset > (old_shdr->sh_offset
+                                          + old_shdr->sh_size))
+               /* If not covered by section, it hasn't yet been copied.  */
+               memcpy (n_phdrr->cbLineOffset + new_base,
+                       o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
            }
        }
 #endif /* __sgi */
-
-      /* If it is the symbol table, its st_shndx field needs to be patched.  */
-      if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
-         || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
-       {
-         ElfW (Shdr) *spt = &NEW_SECTION_H (nn);
-         ptrdiff_t num = spt->sh_size / spt->sh_entsize;
-         ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset +
-                                          new_base);
-         for (; num--; sym++)
-           {
-             if ((sym->st_shndx == SHN_UNDEF)
-                 || (sym->st_shndx == SHN_ABS)
-                 || (sym->st_shndx == SHN_COMMON))
-               continue;
-
-             PATCH_INDEX (sym->st_shndx);
-           }
-       }
     }
 
   /* Update the symbol values of _edata and _end.  */
@@ -1186,15 +566,16 @@ temacs:
     {
       byte *symnames;
       ElfW (Sym) *symp, *symendp;
+      ElfW (Shdr) *sym_shdr = &NEW_SECTION_H (n);
 
-      if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
-         && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
+      if (sym_shdr->sh_type != SHT_DYNSYM
+         && sym_shdr->sh_type != SHT_SYMTAB)
        continue;
 
       symnames = ((byte *) new_base
-                 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
-      symp = (ElfW (Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
-      symendp = (ElfW (Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
+                 + NEW_SECTION_H (sym_shdr->sh_link).sh_offset);
+      symp = (ElfW (Sym) *) (sym_shdr->sh_offset + new_base);
+      symendp = (ElfW (Sym) *) ((byte *) symp + sym_shdr->sh_size);
 
       for (; symp < symendp; symp ++)
        {
@@ -1218,39 +599,54 @@ temacs:
          if (strncmp ((char *) (symnames + symp->st_name),
                       "_OBJC_", sizeof ("_OBJC_") - 1) == 0)
            {
-             caddr_t old, new;
-
-             new = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr)
-                    + NEW_SECTION_H (symp->st_shndx).sh_offset + new_base);
-             /* "Unpatch" index.  */
-             nn = symp->st_shndx;
-             if (nn > old_bss_index)
-               nn--;
-             if (nn == old_bss_index)
-               memset (new, 0, symp->st_size);
-             else
+             ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx);
+             if (new_shdr->sh_type != SHT_NOBITS)
                {
-                 old = ((symp->st_value
-                         - NEW_SECTION_H (symp->st_shndx).sh_addr)
-                        + OLD_SECTION_H (nn).sh_offset + old_base);
-                 memcpy (new, old, symp->st_size);
+                 ElfW (Shdr) *old_shdr = &OLD_SECTION_H (symp->st_shndx);
+                 ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr;
+                 ptrdiff_t newoff = reladdr + new_shdr->sh_offset;
+
+                 if (old_shdr->sh_type == SHT_NOBITS)
+                   memset (new_base + newoff, 0, symp->st_size);
+                 else
+                   {
+                     ptrdiff_t oldoff = reladdr + old_shdr->sh_offset;
+                     memcpy (new_base + newoff, old_base + oldoff,
+                             symp->st_size);
+                   }
                }
            }
 #endif
        }
     }
 
-  /* This loop seeks out relocation sections for the data section, so
-     that it can undo relocations performed by the runtime linker.  */
+  /* Modify the names of sections we changed from SHT_NOBITS to
+     SHT_PROGBITS.  This is really just cosmetic, but some tools that
+     (wrongly) operate on section names rather than types might be
+     confused by a SHT_PROGBITS .bss section.  */
+  new_section_names = ((char *) new_base
+                      + NEW_SECTION_H (new_file_h->e_shstrndx).sh_offset);
   for (n = new_file_h->e_shnum; 0 < --n; )
     {
-      ElfW (Shdr) section = NEW_SECTION_H (n);
+      ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n);
+      ElfW (Shdr) *new_shdr = &NEW_SECTION_H (n);
+
+      /* Replace the leading '.' with ','.  When .shstrtab is string
+        merged this will rename both .bss and .rela.bss to ,bss and
+        .rela,bss.  */
+      if (old_shdr->sh_type == SHT_NOBITS
+         && new_shdr->sh_type == SHT_PROGBITS)
+       *(new_section_names + new_shdr->sh_name) = ',';
+    }
 
-      /* Cause a compilation error if anyone uses n instead of nn below.  */
-      #define n ((void) 0);
-      n /* Prevent 'macro "n" is not used' warnings.  */
+  /* This loop seeks out relocation sections for the data section, so
+     that it can undo relocations performed by the runtime loader.  */
+  for (n = new_file_h->e_shnum; 0 < --n; )
+    {
+      ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n);
+      ElfW (Shdr) *shdr;
 
-      switch (section.sh_type)
+      switch (rel_shdr->sh_type)
        {
        default:
          break;
@@ -1259,44 +655,36 @@ temacs:
          /* This code handles two different size structs, but there should
             be no harm in that provided that r_offset is always the first
             member.  */
-         nn = section.sh_info;
-         if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
-             || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                         ".sdata")
-             || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                         ".lit4")
-             || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                         ".lit8")
+         shdr = &NEW_SECTION_H (rel_shdr->sh_info);
+         if (!strcmp (old_section_names + shdr->sh_name, ".data")
+             || !strcmp (old_section_names + shdr->sh_name, ".sdata")
+             || !strcmp (old_section_names + shdr->sh_name, ".lit4")
+             || !strcmp (old_section_names + shdr->sh_name, ".lit8")
 #ifdef IRIX6_5                 /* see above */
-             || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                         ".got")
+             || !strcmp (old_section_names + shdr->sh_name, ".got")
 #endif
-             || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                         ".sdata1")
-             || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                         ".data1"))
+             || !strcmp (old_section_names + shdr->sh_name, ".sdata1")
+             || !strcmp (old_section_names + shdr->sh_name, ".data1"))
            {
-             ElfW (Addr) offset = (NEW_SECTION_H (nn).sh_addr
-                                  - NEW_SECTION_H (nn).sh_offset);
-             caddr_t reloc = old_base + section.sh_offset, end;
-             for (end = reloc + section.sh_size; reloc < end;
-                  reloc += section.sh_entsize)
+             ElfW (Addr) offset = shdr->sh_addr - shdr->sh_offset;
+             caddr_t reloc = old_base + rel_shdr->sh_offset, end;
+             for (end = reloc + rel_shdr->sh_size;
+                  reloc < end;
+                  reloc += rel_shdr->sh_entsize)
                {
                  ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset;
-#ifdef __alpha__
-                 /* The Alpha ELF binutils currently have a bug that
-                    sometimes results in relocs that contain all
-                    zeroes.  Work around this for now...  */
+                 /* Ignore R_*_NONE relocs.  */
                  if (((ElfW (Rel) *) reloc)->r_offset == 0)
                    continue;
-#endif
-                 memcpy (new_base + addr, old_base + addr, sizeof (ElfW (Addr)));
+                 /* Assume reloc applies to a word.
+                    ??? This is not always true, eg. TLS module/index
+                    pair in .got which occupies two words.  */
+                 memcpy (new_base + addr, old_base + addr,
+                         sizeof (ElfW (Addr)));
                }
            }
          break;
        }
-
-      #undef n
     }
 
   /* Write out new_file, and free the buffers.  */
index eaff57eaedfb35f9330f7bcc226e00cb5a001e03..135f5de7d8aaa953233b4cda3e9c73b3a5679800 100644 (file)
@@ -1056,6 +1056,7 @@ extern void wset_redisplay (struct window *w);
 extern void fset_redisplay (struct frame *f);
 extern void bset_redisplay (struct buffer *b);
 extern void bset_update_mode_line (struct buffer *b);
+extern void maybe_set_redisplay (Lisp_Object);
 /* Call this to tell redisplay to look for other windows than selected-window
    that need to be redisplayed.  Calling one of the *set_redisplay functions
    above already does it, so it's only needed in unusual cases.  */
index bdf2d09179e05f4b3dd3046d1a53fc73c5c5bbf6..30dfac556014a1419bee08a292db8f5879a9ea00 100644 (file)
@@ -620,6 +620,17 @@ bset_update_mode_line (struct buffer *b)
   b->text->redisplay = true;
 }
 
+void
+maybe_set_redisplay (Lisp_Object symbol)
+{
+  if (HASH_TABLE_P (Vredisplay__variables)
+      && hash_lookup (XHASH_TABLE (Vredisplay__variables), symbol, NULL) >= 0)
+    {
+      bset_update_mode_line (current_buffer);
+      current_buffer->prevent_redisplay_optimizations_p = true;
+    }
+}
+
 #ifdef GLYPH_DEBUG
 
 /* True means print traces of redisplay if compiled with
@@ -11541,9 +11552,10 @@ x_consider_frame_title (Lisp_Object frame)
 {
   struct frame *f = XFRAME (frame);
 
-  if (FRAME_WINDOW_P (f)
-      || FRAME_MINIBUF_ONLY_P (f)
-      || f->explicit_name)
+  if ((FRAME_WINDOW_P (f)
+       || FRAME_MINIBUF_ONLY_P (f)
+       || f->explicit_name)
+      && NILP (Fframe_parameter (frame, Qtooltip)))
     {
       /* Do we have more than one visible frame on this X display?  */
       Lisp_Object tail, other_frame, fmt;
@@ -31465,6 +31477,10 @@ display table takes effect; in this case, Emacs does not consult
   DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
               doc: /*  */);
   Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
+
+  DEFVAR_LISP ("redisplay--variables", Vredisplay__variables,
+     doc: /* A hash-table of variables changing which triggers a thorough redisplay.  */);
+  Vredisplay__variables = Qnil;
 }
 
 
index ce6e7d21edb15c9858a9f0f557382574d375473c..10bc76986e6b96379891d410367fbbbb3148321f 100644 (file)
@@ -177,12 +177,8 @@ magic_db (const char *string, ptrdiff_t string_len, const char *class,
 
       /* Do we have room for this component followed by a '\0'?  */
       if (path_size - path_len <= next_len)
-       {
-         if (min (PTRDIFF_MAX, SIZE_MAX) / 2 - 1 - path_len < next_len)
-           memory_full (SIZE_MAX);
-         path_size = (path_len + next_len + 1) * 2;
-         path = xrealloc (path, path_size);
-       }
+       path = xpalloc (path, &path_size, path_len - path_size + next_len + 1,
+                       -1, sizeof *path);
 
       memcpy (path + path_len, next, next_len);
       path_len += next_len;
index 9d178a50d7a8f8f5b7a4ef4a677d085f0a90ef82..41bd2bc40de25ad986c7df9190928488616a7dc8 100644 (file)
@@ -2330,10 +2330,11 @@ x_property_data_to_lisp (struct frame *f, const unsigned char *data,
                         Atom type, int format, unsigned long size)
 {
   ptrdiff_t format_bytes = format >> 3;
-  if (PTRDIFF_MAX / format_bytes < size)
+  ptrdiff_t data_bytes;
+  if (INT_MULTIPLY_WRAPV (size, format_bytes, &data_bytes))
     memory_full (SIZE_MAX);
   return selection_data_to_lisp_data (FRAME_DISPLAY_INFO (f), data,
-                                     size * format_bytes, type, format);
+                                     data_bytes, type, format);
 }
 
 DEFUN ("x-get-atom-name", Fx_get_atom_name,
index b84f2ac58d925811c67750d26248a922a09dac67..8c4a6d3462c2832f4a050ff62f38aeff73ce8e3b 100644 (file)
@@ -223,9 +223,8 @@ smc_save_yourself_CB (SmcConn smcConn,
   props[props_idx]->name = xstrdup (SmRestartCommand);
   props[props_idx]->type = xstrdup (SmLISTofARRAY8);
   /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */
-  if (INT_MAX - 3 < initial_argc)
+  if (INT_ADD_WRAPV (initial_argc, 3, &i))
     memory_full (SIZE_MAX);
-  i = 3 + initial_argc;
   props[props_idx]->num_vals = i;
   vp = xnmalloc (i, sizeof *vp);
   props[props_idx]->vals = vp;
index 691ad05efe182f8a3a717b4be3bde4f2eb3b7b6f..5756378bd3af91c874523f17717575d1e173bafa 100644 (file)
@@ -11773,7 +11773,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   struct terminal *terminal;
   struct x_display_info *dpyinfo;
   XrmDatabase xrdb;
-  ptrdiff_t lim;
 
   block_input ();
 
@@ -11963,6 +11962,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   dpyinfo->display = dpy;
   dpyinfo->connection = ConnectionNumber (dpyinfo->display);
 
+  /* http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg00194.html  */
+  dpyinfo->smallest_font_height = 1;
+  dpyinfo->smallest_char_width = 1;
+
   /* Set the name of the terminal. */
   terminal->name = xlispstrdup (display_name);
 
@@ -11970,13 +11973,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   XSetAfterFunction (x_current_display, x_trace_wire);
 #endif
 
-  lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@";
   Lisp_Object system_name = Fsystem_name ();
-  if (lim - SBYTES (Vinvocation_name) < SBYTES (system_name))
+  ptrdiff_t nbytes;
+  if (INT_ADD_WRAPV (SBYTES (Vinvocation_name), SBYTES (system_name) + 2,
+                    &nbytes))
     memory_full (SIZE_MAX);
   dpyinfo->x_id = ++x_display_id;
-  dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name)
-                               + SBYTES (system_name) + 2);
+  dpyinfo->x_id_name = xmalloc (nbytes);
   char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name);
   *nametail++ = '@';
   lispstpcpy (nametail, system_name);
diff --git a/test/automated/abbrev-tests.el b/test/automated/abbrev-tests.el
new file mode 100644 (file)
index 0000000..d08e026
--- /dev/null
@@ -0,0 +1,43 @@
+;;; abbrev-tests.el --- Test suite for abbrevs.
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Eli Zaretskii <eliz@gnu.org>
+;; Keywords: abbrevs
+
+;; 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/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'abbrev)
+
+(ert-deftest copy-abbrev-table-test ()
+  (defvar foo-abbrev-table nil)         ; Avoid compiler warning
+  (define-abbrev-table 'foo-abbrev-table
+    '())
+  (should (abbrev-table-p foo-abbrev-table))
+  ;; Bug 21828
+  (let ((new-foo-abbrev-table
+         (condition-case nil
+             (copy-abbrev-table foo-abbrev-table)
+           (error nil))))
+    (should (abbrev-table-p new-foo-abbrev-table)))
+  (should-not (string-equal (buffer-name) "*Backtrace*")))
+
+(provide 'abbrev-tests)
+
+;;; abbrev-tests.el ends here
index 7cabc5c3e66e5d9b527999746660666a7b3673b2..2745f106087fd938e059427a7c88782ccb29690f 100644 (file)
         (kill-buffer buf))
       (ignore-errors (delete-file tmpfile)))))
 
-(ert-deftest auto-revert-test01-auto-revert-tail-mode ()
+;; This is inspired by Bug#21841.
+(ert-deftest auto-revert-test01-auto-revert-several-files ()
+  "Check autorevert for several files at once."
+  (skip-unless (executable-find "cp"))
+
+  (let* ((cp (executable-find "cp"))
+         (tmpdir1 (make-temp-file "auto-revert-test" 'dir))
+         (tmpdir2 (make-temp-file "auto-revert-test" 'dir))
+         (tmpfile1
+          (make-temp-file (expand-file-name "auto-revert-test" tmpdir1)))
+         (tmpfile2
+          (make-temp-file (expand-file-name "auto-revert-test" tmpdir1)))
+         buf1 buf2)
+    (unwind-protect
+       (progn
+          (with-current-buffer (get-buffer-create "*Messages*")
+            (narrow-to-region (point-max) (point-max)))
+         (write-region "any text" nil tmpfile1 nil 'no-message)
+         (setq buf1 (find-file-noselect tmpfile1))
+         (write-region "any text" nil tmpfile2 nil 'no-message)
+         (setq buf2 (find-file-noselect tmpfile2))
+
+          (dolist (buf (list buf1 buf2))
+            (with-current-buffer buf
+              (should (string-equal (buffer-string) "any text"))
+              ;; `buffer-stale--default-function' checks for
+              ;; `verify-visited-file-modtime'.  We must ensure that
+              ;; it returns nil.
+              (sleep-for 1)
+              (auto-revert-mode 1)
+              (should auto-revert-mode)))
+
+          ;; Modify files.  We wait for a second, in order to have
+          ;; another timestamp.
+          (sleep-for 1)
+          (write-region
+           "another text" nil
+           (expand-file-name (file-name-nondirectory tmpfile1) tmpdir2)
+           nil 'no-message)
+          (write-region
+           "another text" nil
+           (expand-file-name (file-name-nondirectory tmpfile2) tmpdir2)
+           nil 'no-message)
+          ;;(copy-directory tmpdir2 tmpdir1 nil 'copy-contents)
+          ;; Strange, that `copy-directory' does not work as expected.
+          ;; The following shell command is not portable on all
+          ;; platforms, unfortunately.
+          (shell-command (format "%s -f %s/* %s" cp tmpdir2 tmpdir1))
+
+          ;; Check, that the buffers have been reverted.
+          (dolist (buf (list buf1 buf2))
+            (with-current-buffer buf
+              (auto-revert--wait-for-revert buf)
+              (should (string-match "another text" (buffer-string))))))
+
+      ;; Exit.
+      (with-current-buffer "*Messages*" (widen))
+      (ignore-errors
+        (dolist (buf (list buf1 buf2))
+          (with-current-buffer buf (set-buffer-modified-p nil))
+          (kill-buffer buf)))
+      (ignore-errors (delete-directory tmpdir1 'recursive))
+      (ignore-errors (delete-directory tmpdir2 'recursive)))))
+
+(ert-deftest auto-revert-test02-auto-revert-tail-mode ()
   "Check autorevert tail mode."
   ;; `auto-revert-buffers' runs every 5".  And we must wait, until the
   ;; file has been reverted.
       (ignore-errors (kill-buffer buf))
       (ignore-errors (delete-file tmpfile)))))
 
-(ert-deftest auto-revert-test02-auto-revert-mode-dired ()
+(ert-deftest auto-revert-test03-auto-revert-mode-dired ()
   "Check autorevert for dired."
   ;; `auto-revert-buffers' runs every 5".  And we must wait, until the
   ;; file has been reverted.
diff --git a/test/automated/buffer-tests.el b/test/automated/buffer-tests.el
new file mode 100644 (file)
index 0000000..bb3c92d
--- /dev/null
@@ -0,0 +1,48 @@
+;;; buffer-tests.el --- tests for buffer.c functions -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015 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/>.
+
+;;; Code:
+
+(require 'ert)
+
+(ert-deftest overlay-modification-hooks-message-other-buf ()
+  "Test for bug#21824.
+After a modification-hook has been run and there is an overlay in
+the *Messages* buffer, the message coalescing [2 times] wrongly
+runs the modification-hook of the overlay in the 1st buffer, but
+with parameters from the *Messages* buffer modification."
+  (let ((buf nil)
+        (msg-ov nil))
+    (with-temp-buffer
+      (insert "123")
+      (overlay-put (make-overlay 1 3)
+                   'modification-hooks
+                   (list (lambda (&rest _)
+                           (setq buf (current-buffer)))))
+      (goto-char 2)
+      (insert "x")
+      (unwind-protect
+          (progn
+            (setq msg-ov (make-overlay 1 1 (get-buffer-create "*Messages*")))
+            (message "a message")
+            (message "a message")
+            (should (eq buf (current-buffer))))
+        (when msg-ov (delete-overlay msg-ov))))))
+
+;;; buffer-tests.el ends here
index d6e6bef2db6652fa2145d4e9f78506b327fa0018..9b230db99e40867cf1429cf6eef41c55d23fec1c 100644 (file)
 
 (cl-defstruct (mystruct
                (:constructor cl-lib--con-1 (&aux (abc 1)))
-               (:constructor cl-lib--con-2 (&optional def)))
+               (:constructor cl-lib--con-2 (&optional def) "Constructor docstring."))
+  "General docstring."
   (abc 5 :readonly t) (def nil))
 (ert-deftest cl-lib-struct-accessors ()
   (let ((x (make-mystruct :abc 1 :def 2)))
               (`((cl-tag-slot) (abc 5 :readonly t)
                  (def . ,(or `nil `(nil))))
                t)))))
+(ert-deftest cl-lib-struct-constructors ()
+  (should (equal (documentation 'cl-lib--con-2 t)
+                 "Constructor docstring."))
+  (should (mystruct-p (cl-lib--con-1)))
+  (should (mystruct-p (cl-lib--con-2))))
 
 (ert-deftest cl-lib-arglist-performance ()
   ;; An `&aux' should not cause lambda's arglist to be turned into an &rest
index 964dc4a07b1d0376305a8a3eddada840fb95581c..67e929a647728d2f3fbb73633131662d31846182 100644 (file)
@@ -275,10 +275,10 @@ TIMEOUT is the maximum time to wait for, in seconds."
      (while (null ,until)
        (read-event nil nil 0.1))))
 
-(defmacro file-notify--test-with-events (timeout events &rest body)
+(defmacro file-notify--test-with-events (events &rest body)
   "Run BODY collecting events and then compare with EVENTS.
-Don't wait longer than TIMEOUT seconds for the events to be delivered."
-  (declare (indent 2))
+Don't wait longer than timeout seconds for the events to be delivered."
+  (declare (indent 1))
   (let ((outer (make-symbol "outer")))
     `(let ((,outer file-notify--test-events))
        (setq file-notify--test-expected-events
@@ -286,7 +286,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
        (let (file-notify--test-events)
          ,@body
          (file-notify--wait-for-events
-          ,timeout (= (length ,events) (length file-notify--test-events)))
+          (file-notify--test-timeout)
+          (= (length ,events) (length file-notify--test-events)))
          (should (equal ,events (mapcar #'cadr file-notify--test-events)))
          (setq ,outer (append ,outer file-notify--test-events)))
        (setq file-notify--test-events ,outer))))
@@ -294,6 +295,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
 (ert-deftest file-notify-test02-events ()
   "Check file creation/change/removal notifications."
   (skip-unless (file-notify--test-local-enabled))
+  ;; Under cygwin there are so bad timings that it doesn't make sense to test.
+  (skip-unless (not (eq system-type 'cygwin)))
 
   (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
        file-notify--test-tmpfile1 (file-notify--test-make-temp-name))
@@ -305,8 +308,7 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
               (file-notify-add-watch
                file-notify--test-tmpfile
                '(change) 'file-notify--test-event-handler))
-        (file-notify--test-with-events
-            (file-notify--test-timeout) '(created changed deleted)
+        (file-notify--test-with-events '(created changed deleted)
           (write-region
            "any text" nil file-notify--test-tmpfile nil 'no-message)
           (delete-file file-notify--test-tmpfile))
@@ -324,7 +326,6 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
                 file-notify--test-tmpfile
                 '(change) 'file-notify--test-event-handler))
          (file-notify--test-with-events
-             (file-notify--test-timeout)
              ;; There are two `deleted' events, for the file and for
              ;; the directory.
              '(created changed deleted deleted stopped)
@@ -343,7 +344,6 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
                '(change) 'file-notify--test-event-handler))
         (should file-notify--test-desc)
         (file-notify--test-with-events
-            (file-notify--test-timeout)
             ;; w32notify does not distinguish between `changed' and
             ;; `attribute-changed'.
             (if (eq file-notify--library 'w32notify)
@@ -368,8 +368,7 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
                file-notify--test-tmpfile
                '(change) 'file-notify--test-event-handler))
         (should file-notify--test-desc)
-        (file-notify--test-with-events
-            (file-notify--test-timeout) '(created changed renamed)
+        (file-notify--test-with-events '(created changed renamed)
           (write-region
            "any text" nil file-notify--test-tmpfile nil 'no-message)
           (rename-file file-notify--test-tmpfile file-notify--test-tmpfile1)
@@ -386,7 +385,6 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
                  file-notify--test-tmpfile
                  '(attribute-change) 'file-notify--test-event-handler))
           (file-notify--test-with-events
-              (file-notify--test-timeout)
               (if (file-remote-p temporary-file-directory)
                   ;; In the remote case, `write-region' raises also an
                   ;; `attribute-changed' event.
@@ -511,6 +509,8 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
 (ert-deftest file-notify-test04-file-validity ()
   "Check `file-notify-valid-p' for files."
   (skip-unless (file-notify--test-local-enabled))
+  ;; Under cygwin there are so bad timings that it doesn't make sense to test.
+  (skip-unless (not (eq system-type 'cygwin)))
 
   (unwind-protect
       (progn
@@ -519,8 +519,7 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
               (file-notify-add-watch
                file-notify--test-tmpfile
                '(change) #'file-notify--test-event-handler))
-        (file-notify--test-with-events
-            (file-notify--test-timeout) '(created changed deleted)
+        (file-notify--test-with-events '(created changed deleted)
           (should (file-notify-valid-p file-notify--test-desc))
           (write-region
            "any text" nil file-notify--test-tmpfile nil 'no-message)
@@ -547,8 +546,7 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
                 (file-notify-add-watch
                  file-notify--test-tmpfile
                  '(change) #'file-notify--test-event-handler))
-          (file-notify--test-with-events
-              (file-notify--test-timeout) '(created changed deleted stopped)
+          (file-notify--test-with-events '(created changed deleted stopped)
             (should (file-notify-valid-p file-notify--test-desc))
             (write-region
              "any text" nil file-notify--test-tmpfile nil 'no-message)
@@ -624,6 +622,7 @@ Don't wait longer than TIMEOUT seconds for the events to be delivered."
 ;; TODO:
 
 ;; * For w32notify, no stopped events arrive when a directory is removed.
+;; * Try to handle arriving events under cygwin reliably.
 
 (provide 'file-notify-tests)
 ;;; file-notify-tests.el ends here
index d1b7a2fa022c1f56470f16a9e90919ff904054cc..fa1f5484eec7b9ee20c07dae5bc62d4a8546754e 100644 (file)
   (should (equal (json-read-from-string "\"\\nasd\\u0444\\u044b\\u0432fgh\\t\"")
                  "\nasdфывfgh\t")))
 
+(ert-deftest test-json-path-to-position-with-objects ()
+  (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}")
+         (matched-path (json-path-to-position 32 json-string)))
+    (should (equal (plist-get matched-path :path) '("foo" "bar" "baz")))
+    (should (equal (plist-get matched-path :match-start) 25))
+    (should (equal (plist-get matched-path :match-end) 32))))
+
+(ert-deftest test-json-path-to-position-with-arrays ()
+  (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}")
+         (matched-path (json-path-to-position 20 json-string)))
+    (should (equal (plist-get matched-path :path) '("foo" 1 0)))
+    (should (equal (plist-get matched-path :match-start) 18))
+    (should (equal (plist-get matched-path :match-end) 23))))
+
+(ert-deftest test-json-path-to-position-no-match ()
+  (let* ((json-string "{\"foo\": {\"bar\": \"baz\"}}")
+         (matched-path (json-path-to-position 5 json-string)))
+    (should (null matched-path))))
+
 (provide 'json-tests)
 ;;; json-tests.el ends here
index 85d5d112d9e80dc6bac80794cf65f946cfea2aac..ee8db593b498e9964e5c08f557b7d47ccc3b8e69 100644 (file)
   (should (equal (when t 'x 2) 2))
   (should (equal (when nil 'x 1) nil))
   (should (equal (when nil 'x 2) nil))
-  (should (equal (macroexpand-all '(when a b))
-                 '(if a b)))
+  (let ((x 1))
+    (should-not (when nil
+                  (setq x (1+ x))
+                  x))
+    (should (= x 1))
+    (should (= 2 (when t
+                   (setq x (1+ x))
+                   x)))
+    (should (= x 2)))
   (should (equal (macroexpand-all '(when a b c d))
                  '(if a (progn b c d)))))