aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Verona2013-07-20 01:44:36 +0200
committerJoakim Verona2013-07-20 01:44:36 +0200
commit759dbb1aebe68fb392f7ed53eba4b460ae6b83be (patch)
tree1becc0cc6d676589eb274cb2c457e4256e908010
parent6c1769c85ecb61b40a1f9a3b56b61cdd6c1f8992 (diff)
parent3f5bef16fab0ba83cb2298f8137fec831af1aec4 (diff)
downloademacs-759dbb1aebe68fb392f7ed53eba4b460ae6b83be.tar.gz
emacs-759dbb1aebe68fb392f7ed53eba4b460ae6b83be.zip
Merge branch 'trunk' into xwidget
-rw-r--r--doc/lispref/ChangeLog9
-rw-r--r--doc/lispref/windows.texi11
-rw-r--r--doc/misc/ChangeLog4
-rw-r--r--doc/misc/gnus.texi5
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/NEWS21
-rw-r--r--lisp/ChangeLog119
-rw-r--r--lisp/autorevert.el22
-rw-r--r--lisp/cedet/semantic/bovine/el.el2
-rw-r--r--lisp/desktop.el507
-rw-r--r--lisp/edmacro.el3
-rw-r--r--lisp/epa.el3
-rw-r--r--lisp/filenotify.el40
-rw-r--r--lisp/frame.el44
-rw-r--r--lisp/gnus/ChangeLog15
-rw-r--r--lisp/gnus/gnus-art.el13
-rw-r--r--lisp/gnus/gnus-start.el20
-rw-r--r--lisp/gnus/registry.el2
-rw-r--r--lisp/mail/mailalias.el4
-rw-r--r--lisp/net/eww.el2
-rw-r--r--lisp/net/shr.el14
-rw-r--r--lisp/net/tramp-adb.el3
-rw-r--r--lisp/net/tramp-compat.el4
-rw-r--r--lisp/net/tramp-gvfs.el3
-rw-r--r--lisp/net/tramp-sh.el13
-rw-r--r--lisp/net/tramp-smb.el3
-rw-r--r--lisp/net/tramp.el4
-rw-r--r--lisp/org/org-freemind.el2
-rw-r--r--lisp/progmodes/ruby-mode.el43
-rw-r--r--lisp/shell.el18
-rw-r--r--lisp/simple.el21
-rw-r--r--lisp/subr.el63
-rw-r--r--src/ChangeLog409
-rw-r--r--src/alloc.c117
-rw-r--r--src/atimer.c12
-rw-r--r--src/atimer.h2
-rw-r--r--src/buffer.c13
-rw-r--r--src/buffer.h2
-rw-r--r--src/bytecode.c19
-rw-r--r--src/callint.c4
-rw-r--r--src/callproc.c175
-rw-r--r--src/charset.c43
-rw-r--r--src/coding.c80
-rw-r--r--src/composite.c13
-rw-r--r--src/conf_post.h6
-rw-r--r--src/cygw32.c11
-rw-r--r--src/dired.c22
-rw-r--r--src/dispnew.c17
-rw-r--r--src/doc.c41
-rw-r--r--src/editfns.c28
-rw-r--r--src/emacs.c9
-rw-r--r--src/eval.c133
-rw-r--r--src/fileio.c225
-rw-r--r--src/filelock.c24
-rw-r--r--src/fns.c13
-rw-r--r--src/font.c15
-rw-r--r--src/fontset.c18
-rw-r--r--src/frame.c57
-rw-r--r--src/ftfont.c11
-rw-r--r--src/gfilenotify.c2
-rw-r--r--src/gtkutil.c10
-rw-r--r--src/image.c38
-rw-r--r--src/insdel.c36
-rw-r--r--src/keyboard.c297
-rw-r--r--src/keyboard.h2
-rw-r--r--src/keymap.c35
-rw-r--r--src/lisp.h114
-rw-r--r--src/lread.c171
-rw-r--r--src/macros.c3
-rw-r--r--src/menu.c24
-rw-r--r--src/minibuf.c40
-rw-r--r--src/nsfns.m11
-rw-r--r--src/nsfont.m2
-rw-r--r--src/nsmenu.m12
-rw-r--r--src/nsselect.m16
-rw-r--r--src/nsterm.m13
-rw-r--r--src/print.c8
-rw-r--r--src/process.c112
-rw-r--r--src/search.c4
-rw-r--r--src/sound.c12
-rw-r--r--src/sysdep.c324
-rw-r--r--src/systty.h2
-rw-r--r--src/term.c43
-rw-r--r--src/termhooks.h2
-rw-r--r--src/textprop.c42
-rw-r--r--src/unexaix.c2
-rw-r--r--src/unexcoff.c2
-rw-r--r--src/unexsol.c2
-rw-r--r--src/w32.c3
-rw-r--r--src/w32fns.c16
-rw-r--r--src/w32term.c15
-rw-r--r--src/window.c20
-rw-r--r--src/window.h1
-rw-r--r--src/xdisp.c65
-rw-r--r--src/xfaces.c49
-rw-r--r--src/xfns.c47
-rw-r--r--src/xfont.c4
-rw-r--r--src/xmenu.c55
-rw-r--r--src/xml.c2
-rw-r--r--src/xselect.c53
-rw-r--r--src/xterm.c19
101 files changed, 2678 insertions, 1612 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index f8b7406c427..8b0dd6afa4e 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,12 @@
12013-07-19 Xue Fuqiao <xfq.free@gmail.com>
2
3 * windows.texi (Display Action Functions): Mention next-window.
4
52013-07-16 Xue Fuqiao <xfq.free@gmail.com>
6
7 * windows.texi (Selecting Windows): Fix the introduction of
8 `set-frame-selected-window''s arguments.
9
12013-07-10 Paul Eggert <eggert@cs.ucla.edu> 102013-07-10 Paul Eggert <eggert@cs.ucla.edu>
2 11
3 Timestamp fixes for undo (Bug#14824). 12 Timestamp fixes for undo (Bug#14824).
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index f2a4b3849dd..1f65f687014 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -1355,10 +1355,9 @@ within that frame. @var{frame} should be a live frame; if omitted or
1355 1355
1356@defun set-frame-selected-window frame window &optional norecord 1356@defun set-frame-selected-window frame window &optional norecord
1357This function makes @var{window} the window selected within the frame 1357This function makes @var{window} the window selected within the frame
1358@var{frame}. @var{frame} should be a live frame; if omitted or 1358@var{frame}. @var{frame} should be a live frame; if @code{nil}, it
1359@code{nil}, it defaults to the selected frame. @var{window} should be 1359defaults to the selected frame. @var{window} should be a live window;
1360a live window; if omitted or @code{nil}, it defaults to the selected 1360if @code{nil}, it defaults to the selected window.
1361window.
1362 1361
1363If @var{frame} is the selected frame, this makes @var{window} the 1362If @var{frame} is the selected frame, this makes @var{window} the
1364selected window. 1363selected window.
@@ -1925,6 +1924,10 @@ frames to search for a reusable window:
1925A frame means consider windows on that frame only. 1924A frame means consider windows on that frame only.
1926@end itemize 1925@end itemize
1927 1926
1927Note that these meanings differ slightly from those of the
1928@var{all-frames} argument to @code{next-window} (@pxref{Cyclic Window
1929Ordering}).
1930
1928If @var{alist} contains no @code{reusable-frames} entry, this function 1931If @var{alist} contains no @code{reusable-frames} entry, this function
1929normally searches just the selected frame; however, if the variable 1932normally searches just the selected frame; however, if the variable
1930@code{pop-up-frames} is non-@code{nil}, it searches all frames on the 1933@code{pop-up-frames} is non-@code{nil}, it searches all frames on the
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 2fe1914f926..0400a7518dd 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,7 @@
12013-07-19 Geoff Kuenning <geoff@cs.hmc.edu> (tiny change)
2
3 * gnus.texi (Customizing Articles): Document function predicates.
4
12013-07-08 Tassilo Horn <tsdh@gnu.org> 52013-07-08 Tassilo Horn <tsdh@gnu.org>
2 6
3 * gnus.texi (lines): Correct description of 7 * gnus.texi (lines): Correct description of
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index e5ba2c19eec..be0425a679b 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -11858,6 +11858,11 @@ predicate. The following predicates are recognized: @code{or},
11858 (typep "text/x-vcard")) 11858 (typep "text/x-vcard"))
11859@end lisp 11859@end lisp
11860 11860
11861@item
11862A function: the function is called with no arguments and should return
11863@code{nil} or non-@code{nil}. The current article is available in the
11864buffer named by @code{gnus-article-buffer}.
11865
11861@end enumerate 11866@end enumerate
11862 11867
11863You may have noticed that the word @dfn{part} is used here. This refers 11868You may have noticed that the word @dfn{part} is used here. This refers
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 02b13e12945..d477f8e3d36 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
12013-07-16 Jan Djärv <jan.h.d@swipnet.se>
2
3 * NEWS: Document blink-cursor-blinks and blink timers stopped.
4
12013-07-13 Eli Zaretskii <eliz@gnu.org> 52013-07-13 Eli Zaretskii <eliz@gnu.org>
2 6
3 * NEWS: Document prefer-utf-8 and the new attributes 7 * NEWS: Document prefer-utf-8 and the new attributes
diff --git a/etc/NEWS b/etc/NEWS
index 03174a0137f..f98ebec8003 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -122,6 +122,11 @@ monitor, use the new functions above. Similar notes also apply to
122Generic commands are interactive functions whose implementation can be 122Generic commands are interactive functions whose implementation can be
123selected among several alternatives, as a matter of user preference. 123selected among several alternatives, as a matter of user preference.
124 124
125** The blink cursor stops blinking after 10 blinks (default) on X and NS.
126You can change the default by customizing the variable blink-cursor-blinks.
127Also timers for blinking are stopped when no blinking is done, so Emacs does
128not consume CPU cycles.
129
125 130
126* Editing Changes in Emacs 24.4 131* Editing Changes in Emacs 24.4
127 132
@@ -255,8 +260,10 @@ on the given date.
255*** `desktop-auto-save-timeout' defines the number of seconds between 260*** `desktop-auto-save-timeout' defines the number of seconds between
256auto-saves of the desktop. 261auto-saves of the desktop.
257 262
258*** `desktop-restore-frames' enables saving and restoring the window/frame 263*** `desktop-restore-frames', enabled by default, allows saving and
259configuration. 264restoring the window/frame configuration. Additional options
265`desktop-restore-in-current-display' and
266`desktop-restoring-reuses-frames' allow further customization.
260 267
261** Dired 268** Dired
262 269
@@ -454,6 +461,13 @@ module.
454*** The Info-edit command is obsolete. Editing Info nodes by hand 461*** The Info-edit command is obsolete. Editing Info nodes by hand
455has not been relevant for some time. 462has not been relevant for some time.
456 463
464** Shell
465
466*** `explicit-bash-args' now always defaults to use --noediting.
467During initialization, Emacs no longer expends a process to decide
468whether it is safe to use Bash's --noediting option. These days
469--noediting is ubiquitous; it was introduced in 1996 in Bash version 2.
470
457 471
458* New Modes and Packages in Emacs 24.4 472* New Modes and Packages in Emacs 24.4
459 473
@@ -547,6 +561,9 @@ The few hooks that used with-wrapper-hook are replaced as follows:
547*** `completion-in-region-function' obsoletes `completion-in-region-functions'. 561*** `completion-in-region-function' obsoletes `completion-in-region-functions'.
548*** `filter-buffer-substring-function' obsoletes `filter-buffer-substring-functions'. 562*** `filter-buffer-substring-function' obsoletes `filter-buffer-substring-functions'.
549 563
564** `split-string' now takes an optional argument TRIM.
565The value, if non-nil, is a regexp that specifies what to trim from
566the start and end of each substring.
550 567
551** `get-upcase-table' is obsoleted by the new `case-table-get-table'. 568** `get-upcase-table' is obsoleted by the new `case-table-get-table'.
552 569
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 5451abc2119..6b99c5719bb 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,118 @@
12013-07-19 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * net/shr.el (shr-mouse-browse-url): New command and keystroke
4 (bug#14815).
5
6 * net/eww.el (eww-process-text-input): Allow inputting when the
7 point is at the start of the line, as the properties aren't
8 front-sticky.
9
10 * net/shr.el (shr-make-table-1): Ensure that we don't infloop on
11 degenerate widths.
12
132013-07-19 Richard Stallman <rms@gnu.org>
14
15 * epa.el (epa-popup-info-window): Doc fix.
16
17 * subr.el (split-string): New arg TRIM.
18
192013-07-18 Juanma Barranquero <lekktu@gmail.com>
20
21 * frame.el (blink-cursor-timer-function, blink-cursor-suspend):
22 Add check for W32 (followup to 2013-07-16T11:41:06Z!jan.h.d@swipnet.se).
23
242013-07-18 Michael Albinus <michael.albinus@gmx.de>
25
26 * filenotify.el (file-notify--library): Rename from
27 `file-notify-support'. Do not autoload. Adapt all uses.
28 (file-notify-supported-p): New defun.
29
30 * autorevert.el (auto-revert-use-notify):
31 Use `file-notify-supported-p' instead of `file-notify-support'.
32 Adapt docstring.
33 (auto-revert-notify-add-watch): Use `file-notify-supported-p'.
34
35 * net/tramp.el (tramp-file-name-for-operation):
36 Add `file-notify-supported-p'.
37
38 * net/tramp-sh.el (tramp-sh-handle-file-notify-supported-p):
39 New defun.
40 (tramp-sh-file-name-handler-alist): Add it as handler for
41 `file-notify-supported-p '.
42
43 * net/tramp-adb.el (tramp-adb-file-name-handler-alist):
44 * net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
45 * net/tramp-smb.el (tramp-smb-file-name-handler-alist):
46 Add `ignore' as handler for `file-notify-*' functions.
47
482013-07-17 Eli Zaretskii <eliz@gnu.org>
49
50 * simple.el (line-move-partial, line-move): Don't start vscroll or
51 scroll-up if the current line is not taller than the window.
52 (Bug#14881)
53
542013-07-16 Dmitry Gutov <dgutov@yandex.ru>
55
56 * progmodes/ruby-mode.el (ruby-font-lock-keywords): Do not
57 highlight question marks in the method names as strings.
58 (ruby-block-beg-keywords): Inline.
59 (ruby-font-lock-keyword-beg-re): Extract from
60 `ruby-font-lock-keywords'.
61
622013-07-16 Jan Djärv <jan.h.d@swipnet.se>
63
64 * frame.el (blink-cursor-blinks): New defcustom.
65 (blink-cursor-blinks-done): New defvar.
66 (blink-cursor-start): Set blink-cursor-blinks-done to 1.
67 (blink-cursor-timer-function): Check if number of blinks has been
68 done on X and NS.
69 (blink-cursor-suspend, blink-cursor-check): New defuns.
70
712013-07-15 Glenn Morris <rgm@gnu.org>
72
73 * edmacro.el (edmacro-format-keys): Fix previous change.
74
752013-07-15 Paul Eggert <eggert@cs.ucla.edu>
76
77 * shell.el (explicit-bash-args): Remove obsolete hack for Bash 1.x.
78 The hack didn't work outside English locales anyway.
79
802013-07-15 Juanma Barranquero <lekktu@gmail.com>
81
82 * simple.el (define-alternatives): Rename from alternatives-define,
83 per RMS' suggestion.
84
852013-07-14 Juanma Barranquero <lekktu@gmail.com>
86
87 * desktop.el (desktop-restore-frames): Change default to t.
88 (desktop-restore-in-current-display): Now offer more options.
89 (desktop-restoring-reuses-frames): New customization option.
90 (desktop--saved-states): Doc fix.
91 (desktop-filter-parameters-alist): New variable, renamed and expanded
92 from desktop--excluded-frame-parameters.
93 (desktop--target-display): New variable.
94 (desktop-switch-to-gui-p, desktop-switch-to-tty-p)
95 (desktop--filter-tty*, desktop--filter-*-color)
96 (desktop--filter-minibuffer, desktop--filter-restore-desktop-parm)
97 (desktop--filter-save-desktop-parm)
98 (desktop-restore-in-original-display-p): New functions.
99 (desktop--filter-frame-parms): Use new desktop-filter-parameters-alist.
100 (desktop--save-minibuffer-frames): New function, inspired by a similar
101 function from Martin Rudalics.
102 (desktop--save-frames): Call it; play nice with desktop-globals-to-save.
103 (desktop--restore-in-this-display-p): Remove.
104 (desktop--find-frame): Rename from desktop--find-frame-in-display
105 and add predicate argument.
106 (desktop--make-full-frame): Remove, integrated into desktop--make-frame.
107 (desktop--reuse-list): New variable.
108 (desktop--select-frame, desktop--make-frame, desktop--sort-states):
109 New functions.
110 (desktop--restore-frames): Add support for "minibuffer-special" frames.
111
1122013-07-14 Michael Albinus <michael.albinus@gmx.de>
113
114 * net/tramp-sh.el (tramp-sh-handle-vc-registered): Use `ignore-error'.
115
12013-07-13 Dmitry Gutov <dgutov@yandex.ru> 1162013-07-13 Dmitry Gutov <dgutov@yandex.ru>
2 117
3 * progmodes/ruby-mode.el (ruby-font-lock-keywords): Highlight 118 * progmodes/ruby-mode.el (ruby-font-lock-keywords): Highlight
@@ -3475,8 +3590,8 @@
3475 (prolog-char-quote-workaround): 3590 (prolog-char-quote-workaround):
3476 * progmodes/cperl-mode.el (cperl-under-as-char): 3591 * progmodes/cperl-mode.el (cperl-under-as-char):
3477 * progmodes/vhdl-mode.el (vhdl-underscore-is-part-of-word): 3592 * progmodes/vhdl-mode.el (vhdl-underscore-is-part-of-word):
3478 Mark as obsolete. 3593 Mark as obsolete.
3479 (vhdl-mode-syntax-table, vhdl-mode-ext-syntax-table): Initialize in 3594 (vhdl-mode-syntax-table, vhdl-mode-ext-syntax-table): Initialize in
3480 their declaration. 3595 their declaration.
3481 (vhdl-mode-syntax-table-init): Remove. 3596 (vhdl-mode-syntax-table-init): Remove.
3482 3597
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 00e88fc4a3d..5c593e2ef71 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -271,21 +271,20 @@ This variable becomes buffer local when set in any fashion.")
271 :type 'boolean 271 :type 'boolean
272 :version "24.4") 272 :version "24.4")
273 273
274(defcustom auto-revert-use-notify (and file-notify-support t) 274(defcustom auto-revert-use-notify
275 ;; We use the support of the local filesystem as default.
276 (file-notify-supported-p temporary-file-directory)
275 "If non-nil Auto Revert Mode uses file notification functions. 277 "If non-nil Auto Revert Mode uses file notification functions.
276This requires Emacs being compiled with file notification 278You should set this variable through Custom."
277support (see `file-notify-support'). You should set this variable
278through Custom."
279 :group 'auto-revert 279 :group 'auto-revert
280 :type 'boolean 280 :type 'boolean
281 :set (lambda (variable value) 281 :set (lambda (variable value)
282 (set-default variable (and file-notify-support value)) 282 (set-default variable value)
283 (unless (symbol-value variable) 283 (unless (symbol-value variable)
284 (when file-notify-support 284 (dolist (buf (buffer-list))
285 (dolist (buf (buffer-list)) 285 (with-current-buffer buf
286 (with-current-buffer buf 286 (when (symbol-value 'auto-revert-notify-watch-descriptor)
287 (when (symbol-value 'auto-revert-notify-watch-descriptor) 287 (auto-revert-notify-rm-watch))))))
288 (auto-revert-notify-rm-watch)))))))
289 :initialize 'custom-initialize-default 288 :initialize 'custom-initialize-default
290 :version "24.4") 289 :version "24.4")
291 290
@@ -513,7 +512,8 @@ will use an up-to-date value of `auto-revert-interval'"
513 (set (make-local-variable 'auto-revert-use-notify) nil)) 512 (set (make-local-variable 'auto-revert-use-notify) nil))
514 513
515 (when (and buffer-file-name auto-revert-use-notify 514 (when (and buffer-file-name auto-revert-use-notify
516 (not auto-revert-notify-watch-descriptor)) 515 (not auto-revert-notify-watch-descriptor)
516 (file-notify-supported-p buffer-file-name))
517 (setq auto-revert-notify-watch-descriptor 517 (setq auto-revert-notify-watch-descriptor
518 (ignore-errors 518 (ignore-errors
519 (file-notify-add-watch 519 (file-notify-add-watch
diff --git a/lisp/cedet/semantic/bovine/el.el b/lisp/cedet/semantic/bovine/el.el
index 07e0e08bbaf..0bbe3c61d76 100644
--- a/lisp/cedet/semantic/bovine/el.el
+++ b/lisp/cedet/semantic/bovine/el.el
@@ -474,7 +474,7 @@ Return a bovination list to use."
474 ((and name (file-exists-p (concat name ".el.gz"))) 474 ((and name (file-exists-p (concat name ".el.gz")))
475 ;; This is the linux distro case. 475 ;; This is the linux distro case.
476 (concat name ".el.gz")) 476 (concat name ".el.gz"))
477 ;; source file does not exists 477 ;; Source file does not exist.
478 (name 478 (name
479 (message "semantic: cannot find source file %s" (concat name ".el"))) 479 (message "semantic: cannot find source file %s" (concat name ".el")))
480 (t 480 (t
diff --git a/lisp/desktop.el b/lisp/desktop.el
index fcd032a64d0..e62307d5959 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -33,6 +33,7 @@
33;; - the mark & mark-active 33;; - the mark & mark-active
34;; - buffer-read-only 34;; - buffer-read-only
35;; - some local variables 35;; - some local variables
36;; - frame and window configuration
36 37
37;; To use this, use customize to turn on desktop-save-mode or add the 38;; To use this, use customize to turn on desktop-save-mode or add the
38;; following line somewhere in your init file: 39;; following line somewhere in your init file:
@@ -127,7 +128,6 @@
127;; --------------------------------------------------------------------------- 128;; ---------------------------------------------------------------------------
128;; TODO: 129;; TODO:
129;; 130;;
130;; Save window configuration.
131;; Recognize more minor modes. 131;; Recognize more minor modes.
132;; Save mark rings. 132;; Save mark rings.
133 133
@@ -369,16 +369,29 @@ modes are restored automatically; they should not be listed here."
369 :type '(repeat symbol) 369 :type '(repeat symbol)
370 :group 'desktop) 370 :group 'desktop)
371 371
372(defcustom desktop-restore-frames nil 372(defcustom desktop-restore-frames t
373 "When non-nil, save window/frame configuration to desktop file." 373 "When non-nil, save window/frame configuration to desktop file."
374 :type 'boolean 374 :type 'boolean
375 :group 'desktop 375 :group 'desktop
376 :version "24.4") 376 :version "24.4")
377 377
378(defcustom desktop-restore-in-current-display nil 378(defcustom desktop-restore-in-current-display nil
379 "When non-nil, frames are restored in the current display. 379 "If t, frames are restored in the current display.
380Otherwise they are restored, if possible, in their original displays." 380If nil, frames are restored, if possible, in their original displays.
381 :type 'boolean 381If `delete', frames on other displays are deleted instead of restored."
382 :type '(choice (const :tag "Restore in current display" t)
383 (const :tag "Restore in original display" nil)
384 (const :tag "Delete frames in other displays" 'delete))
385 :group 'desktop
386 :version "24.4")
387
388(defcustom desktop-restoring-reuses-frames t
389 "If t, restoring frames reuses existing frames.
390If nil, existing frames are deleted.
391If `keep', existing frames are kept and not reused."
392 :type '(choice (const :tag "Reuse existing frames" t)
393 (const :tag "Delete existing frames" nil)
394 (const :tag "Keep existing frames" 'keep))
382 :group 'desktop 395 :group 'desktop
383 :version "24.4") 396 :version "24.4")
384 397
@@ -566,7 +579,7 @@ DIRNAME omitted or nil means use `desktop-dirname'."
566Used to avoid writing contents unchanged between auto-saves.") 579Used to avoid writing contents unchanged between auto-saves.")
567 580
568(defvar desktop--saved-states nil 581(defvar desktop--saved-states nil
569 "Internal use only.") 582 "Saved window/frame state. Internal use only.")
570 583
571;; ---------------------------------------------------------------------------- 584;; ----------------------------------------------------------------------------
572;; Desktop file conflict detection 585;; Desktop file conflict detection
@@ -869,30 +882,193 @@ DIRNAME must be the directory in which the desktop file will be saved."
869 882
870 883
871;; ---------------------------------------------------------------------------- 884;; ----------------------------------------------------------------------------
872(defconst desktop--excluded-frame-parameters 885(defvar desktop-filter-parameters-alist
873 '(buffer-list 886 '((background-color . desktop--filter-*-color)
874 buffer-predicate 887 (buffer-list . t)
875 buried-buffer-list 888 (buffer-predicate . t)
876 explicit-name 889 (buried-buffer-list . t)
877 font 890 (desktop-font . desktop--filter-restore-desktop-parm)
878 font-backend 891 (desktop-fullscreen . desktop--filter-restore-desktop-parm)
879 minibuffer 892 (desktop-height . desktop--filter-restore-desktop-parm)
880 name 893 (desktop-width . desktop--filter-restore-desktop-parm)
881 outer-window-id 894 (font . desktop--filter-save-desktop-parm)
882 parent-id 895 (font-backend . t)
883 window-id 896 (foreground-color . desktop--filter-*-color)
884 window-system) 897 (fullscreen . desktop--filter-save-desktop-parm)
885 "Frame parameters not saved or restored.") 898 (height . desktop--filter-save-desktop-parm)
886 899 (minibuffer . desktop--filter-minibuffer)
887(defun desktop--filter-frame-parms (frame) 900 (name . t)
888 "Return frame parameters of FRAME. 901 (outer-window-id . t)
889Parameters in `desktop--excluded-frame-parameters' are excluded. 902 (parent-id . t)
903 (tty . desktop--filter-tty*)
904 (tty-type . desktop--filter-tty*)
905 (width . desktop--filter-save-desktop-parm)
906 (window-id . t)
907 (window-system . t))
908 "Alist of frame parameters and filtering functions.
909
910Each element is a cons (PARAM . FILTER), where PARAM is a parameter
911name (a symbol identifying a frame parameter), and FILTER can be t
912\(meaning the parameter is removed from the parameter list on saving
913and restoring), or a function that will be called with three args:
914
915 CURRENT a cons (PARAM . VALUE), where PARAM is the one being
916 filtered and VALUE is its current value
917 PARAMETERS the complete alist of parameters being filtered
918 SAVING non-nil if filtering before saving state, nil otherwise
919
920The FILTER function must return:
921 nil CURRENT is removed from the list
922 t CURRENT is left as is
923 (PARAM' . VALUE') replace CURRENT with this
924
925Frame parameters not on this list are passed intact.")
926
927(defvar desktop--target-display nil
928 "Either (minibuffer . VALUE) or nil.
929This refers to the current frame config being processed inside
930`frame--restore-frames' and its auxiliary functions (like filtering).
931If nil, there is no need to change the display.
932If non-nil, display parameter to use when creating the frame.
933Internal use only.")
934
935(defun desktop-switch-to-gui-p (parameters)
936 "True when switching to a graphic display.
937Return t if PARAMETERS describes a text-only terminal and
938the target is a graphic display; otherwise return nil.
939Only meaningful when called from a filtering function in
940`desktop-filter-parameters-alist'."
941 (and desktop--target-display ; we're switching
942 (null (cdr (assq 'display parameters))) ; from a tty
943 (cdr desktop--target-display))) ; to a GUI display
944
945(defun desktop-switch-to-tty-p (parameters)
946 "True when switching to a text-only terminal.
947Return t if PARAMETERS describes a graphic display and
948the target is a text-only terminal; otherwise return nil.
949Only meaningful when called from a filtering function in
950`desktop-filter-parameters-alist'."
951 (and desktop--target-display ; we're switching
952 (cdr (assq 'display parameters)) ; from a GUI display
953 (null (cdr desktop--target-display)))) ; to a tty
954
955(defun desktop--filter-tty* (_current parameters saving)
956 ;; Remove tty and tty-type parameters when switching
957 ;; to a GUI frame.
958 (or saving
959 (not (desktop-switch-to-gui-p parameters))))
960
961(defun desktop--filter-*-color (current parameters saving)
962 ;; Remove (foreground|background)-color parameters
963 ;; when switching to a GUI frame if they denote an
964 ;; "unspecified" color.
965 (or saving
966 (not (desktop-switch-to-gui-p parameters))
967 (not (stringp (cdr current)))
968 (not (string-match-p "^unspecified-[fb]g$" (cdr current)))))
969
970(defun desktop--filter-minibuffer (current _parameters saving)
971 ;; When minibuffer is a window, save it as minibuffer . t
972 (or (not saving)
973 (if (windowp (cdr current))
974 '(minibuffer . t)
975 t)))
976
977(defun desktop--filter-restore-desktop-parm (current parameters saving)
978 ;; When switching to a GUI frame, convert desktop-XXX parameter to XXX
979 (or saving
980 (not (desktop-switch-to-gui-p parameters))
981 (let ((val (cdr current)))
982 (if (eq val :desktop-processed)
983 nil
984 (cons (intern (substring (symbol-name (car current))
985 8)) ;; (length "desktop-")
986 val)))))
987
988(defun desktop--filter-save-desktop-parm (current parameters saving)
989 ;; When switching to a tty frame, save parameter XXX as desktop-XXX so it
990 ;; can be restored in a subsequent GUI session, unless it already exists.
991 (cond (saving t)
992 ((desktop-switch-to-tty-p parameters)
993 (let ((sym (intern (format "desktop-%s" (car current)))))
994 (if (assq sym parameters)
995 nil
996 (cons sym (cdr current)))))
997 ((desktop-switch-to-gui-p parameters)
998 (let* ((dtp (assq (intern (format "desktop-%s" (car current)))
999 parameters))
1000 (val (cdr dtp)))
1001 (if (eq val :desktop-processed)
1002 nil
1003 (setcdr dtp :desktop-processed)
1004 (cons (car current) val))))
1005 (t t)))
1006
1007(defun desktop-restore-in-original-display-p ()
1008 "True if saved frames' displays should be honored."
1009 (cond ((daemonp) t)
1010 ((eq system-type 'windows-nt) nil)
1011 (t (null desktop-restore-in-current-display))))
1012
1013(defun desktop--filter-frame-parms (parameters saving)
1014 "Filter frame parameters and return filtered list.
1015PARAMETERS is a parameter alist as returned by `frame-parameters'.
1016If SAVING is non-nil, filtering is happening before saving frame state;
1017otherwise, filtering is being done before restoring frame state.
1018Parameters are filtered according to the setting of
1019`desktop-filter-parameters-alist' (which see).
890Internal use only." 1020Internal use only."
891 (let (params) 1021 (let ((filtered nil))
892 (dolist (param (frame-parameters frame)) 1022 (dolist (param parameters)
893 (unless (memq (car param) desktop--excluded-frame-parameters) 1023 (let ((filter (cdr (assq (car param) desktop-filter-parameters-alist)))
894 (push param params))) 1024 this)
895 params)) 1025 (cond (;; no filter: pass param
1026 (null filter)
1027 (push param filtered))
1028 (;; filter = t; skip param
1029 (eq filter t))
1030 (;; filter func returns nil: skip param
1031 (null (setq this (funcall filter param parameters saving))))
1032 (;; filter func returns t: pass param
1033 (eq this t)
1034 (push param filtered))
1035 (;; filter func returns a new param: use it
1036 t
1037 (push this filtered)))))
1038 ;; Set the display parameter after filtering, so that filter functions
1039 ;; have access to its original value.
1040 (when desktop--target-display
1041 (let ((display (assq 'display filtered)))
1042 (if display
1043 (setcdr display (cdr desktop--target-display))
1044 (push desktop--target-display filtered))))
1045 filtered))
1046
1047(defun desktop--save-minibuffer-frames ()
1048 ;; Adds a desktop-mini parameter to frames
1049 ;; desktop-mini is a list (MINIBUFFER NUMBER DEFAULT?) where
1050 ;; MINIBUFFER t if the frame (including minibuffer-only) owns a minibuffer
1051 ;; NUMBER if MINIBUFFER = t, an ID for the frame; if nil, the ID of
1052 ;; the frame containing the minibuffer used by this frame
1053 ;; DEFAULT? if t, this frame is the value of default-minibuffer-frame
1054 ;; FIXME: What happens with multi-terminal sessions?
1055 (let ((frames (frame-list))
1056 (count 0))
1057 ;; Reset desktop-mini for all frames
1058 (dolist (frame frames)
1059 (set-frame-parameter frame 'desktop-mini nil))
1060 ;; Number all frames with its own minibuffer
1061 (dolist (frame (minibuffer-frame-list))
1062 (set-frame-parameter frame 'desktop-mini
1063 (list t
1064 (setq count (1+ count))
1065 (eq frame default-minibuffer-frame))))
1066 ;; Now link minibufferless frames with their minibuffer frames
1067 (dolist (frame frames)
1068 (unless (frame-parameter frame 'desktop-mini)
1069 (let* ((mb-frame (window-frame (minibuffer-window frame)))
1070 (this (cadr (frame-parameter mb-frame 'desktop-mini))))
1071 (set-frame-parameter frame 'desktop-mini (list nil this nil)))))))
896 1072
897(defun desktop--save-frames () 1073(defun desktop--save-frames ()
898 "Save window/frame state, as a global variable. 1074 "Save window/frame state, as a global variable.
@@ -900,12 +1076,14 @@ Intended to be called from `desktop-save'.
900Internal use only." 1076Internal use only."
901 (setq desktop--saved-states 1077 (setq desktop--saved-states
902 (and desktop-restore-frames 1078 (and desktop-restore-frames
903 (mapcar (lambda (frame) 1079 (progn
904 (cons (desktop--filter-frame-parms frame) 1080 (desktop--save-minibuffer-frames)
905 (window-state-get (frame-root-window frame) t))) 1081 (mapcar (lambda (frame)
906 (cons (selected-frame) 1082 (cons (desktop--filter-frame-parms (frame-parameters frame) t)
907 (delq (selected-frame) (frame-list)))))) 1083 (window-state-get (frame-root-window frame) t)))
908 (desktop-outvar 'desktop--saved-states)) 1084 (frame-list)))))
1085 (unless (memq 'desktop--saved-states desktop-globals-to-save)
1086 (desktop-outvar 'desktop--saved-states)))
909 1087
910;;;###autoload 1088;;;###autoload
911(defun desktop-save (dirname &optional release auto-save) 1089(defun desktop-save (dirname &optional release auto-save)
@@ -1006,71 +1184,220 @@ This function also sets `desktop-dirname' to nil."
1006(defvar desktop-lazy-timer nil) 1184(defvar desktop-lazy-timer nil)
1007 1185
1008;; ---------------------------------------------------------------------------- 1186;; ----------------------------------------------------------------------------
1009(defun desktop--restore-in-this-display-p () 1187(defvar desktop--reuse-list nil
1010 (or desktop-restore-in-current-display 1188 "Internal use only.")
1011 (and (eq system-type 'windows-nt) (not (display-graphic-p))))) 1189
1012 1190(defun desktop--find-frame (predicate display &rest args)
1013(defun desktop--find-frame-in-display (frames display) 1191 "Find a suitable frame in `desktop--reuse-list'.
1014 (let (result) 1192Look through frames whose display property matches DISPLAY and
1015 (while (and frames (not result)) 1193return the first one for which (PREDICATE frame ARGS) returns t.
1016 (if (equal display (frame-parameter (car frames) 'display)) 1194If PREDICATE is nil, it is always satisfied. Internal use only.
1017 (setq result (car frames)) 1195This is an auxiliary function for `desktop--select-frame'."
1018 (setq frames (cdr frames)))) 1196 (catch :found
1019 result)) 1197 (dolist (frame desktop--reuse-list)
1020 1198 (when (and (equal (frame-parameter frame 'display) display)
1021(defun desktop--make-full-frame (full display config) 1199 (or (null predicate)
1022 (let ((width (and (eq full 'fullheight) (cdr (assq 'width config)))) 1200 (apply predicate frame args)))
1023 (height (and (eq full 'fullwidth) (cdr (assq 'height config)))) 1201 (throw :found frame)))
1024 (params '((visibility))) 1202 nil))
1203
1204(defun desktop--select-frame (display frame-cfg)
1205 "Look for an existing frame to reuse.
1206DISPLAY is the display where the frame will be shown, and FRAME-CFG
1207is the parameter list of the frame being restored. Internal use only."
1208 (if (eq desktop-restoring-reuses-frames t)
1209 (let ((frame nil)
1210 mini)
1211 ;; There are no fancy heuristics there. We could implement some
1212 ;; based on frame size and/or position, etc., but it is not clear
1213 ;; that any "gain" (in the sense of reduced flickering, etc.) is
1214 ;; worth the added complexity. In fact, the code below mainly
1215 ;; tries to work nicely when M-x desktop-read is used after a desktop
1216 ;; session has already been loaded. The other main use case, which
1217 ;; is the initial desktop-read upon starting Emacs, should usually
1218 ;; only have one, or very few, frame(s) to reuse.
1219 (cond (;; When the target is tty, every existing frame is reusable.
1220 (null display)
1221 (setq frame (desktop--find-frame nil display)))
1222 (;; If the frame has its own minibuffer, let's see whether
1223 ;; that frame has already been loaded (which can happen after
1224 ;; M-x desktop-read).
1225 (car (setq mini (cdr (assq 'desktop-mini frame-cfg))))
1226 (setq frame (or (desktop--find-frame
1227 (lambda (f m)
1228 (equal (frame-parameter f 'desktop-mini) m))
1229 display mini))))
1230 (;; For minibufferless frames, check whether they already exist,
1231 ;; and that they are linked to the right minibuffer frame.
1232 mini
1233 (setq frame (desktop--find-frame
1234 (lambda (f n)
1235 (let ((m (frame-parameter f 'desktop-mini)))
1236 (and m
1237 (null (car m))
1238 (= (cadr m) n)
1239 (equal (cadr (frame-parameter
1240 (window-frame (minibuffer-window f))
1241 'desktop-mini))
1242 n))))
1243 display (cadr mini))))
1244 (;; Default to just finding a frame in the same display.
1245 t
1246 (setq frame (desktop--find-frame nil display))))
1247 ;; If found, remove from the list.
1248 (when frame
1249 (setq desktop--reuse-list (delq frame desktop--reuse-list)))
1025 frame) 1250 frame)
1026 (when width 1251 nil))
1027 (setq params (append `((user-size . t) (width . ,width)) params) 1252
1028 config (assq-delete-all 'height config))) 1253(defun desktop--make-frame (frame-cfg window-cfg)
1029 (when height 1254 "Set up a frame according to its saved state.
1030 (setq params (append `((user-size . t) (height . ,height)) params) 1255That means either creating a new frame or reusing an existing one.
1031 config (assq-delete-all 'width config))) 1256FRAME-CFG is the parameter list of the new frame; WINDOW-CFG is
1032 (setq frame (make-frame-on-display display params)) 1257its window state. Internal use only."
1033 (modify-frame-parameters frame config) 1258 (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg)))
1259 (lines (assq 'tool-bar-lines frame-cfg))
1260 (filtered-cfg (desktop--filter-frame-parms frame-cfg nil))
1261 (display (cdr (assq 'display filtered-cfg))) ;; post-filtering
1262 alt-cfg frame)
1263
1264 ;; This works around bug#14795 (or feature#14795, if not a bug :-)
1265 (setq filtered-cfg (assq-delete-all 'tool-bar-lines filtered-cfg))
1266 (push '(tool-bar-lines . 0) filtered-cfg)
1267
1268 (when fullscreen
1269 ;; Currently Emacs has the limitation that it does not record the size
1270 ;; and position of a frame before maximizing it, so we cannot save &
1271 ;; restore that info. Instead, when restoring, we resort to creating
1272 ;; invisible "fullscreen" frames of default size and then maximizing them
1273 ;; (and making them visible) which at least is somewhat user-friendly
1274 ;; when these frames are later de-maximized.
1275 (let ((width (and (eq fullscreen 'fullheight) (cdr (assq 'width filtered-cfg))))
1276 (height (and (eq fullscreen 'fullwidth) (cdr (assq 'height filtered-cfg))))
1277 (visible (assq 'visibility filtered-cfg)))
1278 (dolist (parameter '(visibility fullscreen width height))
1279 (setq filtered-cfg (assq-delete-all parameter filtered-cfg)))
1280 (when width
1281 (setq filtered-cfg (append `((user-size . t) (width . ,width))
1282 filtered-cfg)))
1283 (when height
1284 (setq filtered-cfg (append `((user-size . t) (height . ,height))
1285 filtered-cfg)))
1286 ;; These are parameters to apply after creating/setting the frame.
1287 (push visible alt-cfg)
1288 (push (cons 'fullscreen fullscreen) alt-cfg)))
1289
1290 ;; Time to select or create a frame an apply the big bunch of parameters
1291 (if (setq frame (desktop--select-frame display filtered-cfg))
1292 (modify-frame-parameters frame filtered-cfg)
1293 (setq frame (make-frame-on-display display filtered-cfg)))
1294
1295 ;; Let's give the finishing touches (visibility, tool-bar, maximization).
1296 (when lines (push lines alt-cfg))
1297 (when alt-cfg (modify-frame-parameters frame alt-cfg))
1298 ;; Now restore window state.
1299 (window-state-put window-cfg (frame-root-window frame) 'safe)
1034 frame)) 1300 frame))
1035 1301
1302(defun desktop--sort-states (state1 state2)
1303 ;; Order: default minibuffer frame
1304 ;; other frames with minibuffer, ascending ID
1305 ;; minibufferless frames, ascending ID
1306 (let ((dm1 (cdr (assq 'desktop-mini (car state1))))
1307 (dm2 (cdr (assq 'desktop-mini (car state2)))))
1308 (cond ((nth 2 dm1) t)
1309 ((nth 2 dm2) nil)
1310 ((null (car dm2)) t)
1311 ((null (car dm1)) nil)
1312 (t (< (cadr dm1) (cadr dm2))))))
1313
1036(defun desktop--restore-frames () 1314(defun desktop--restore-frames ()
1037 "Restore window/frame configuration. 1315 "Restore window/frame configuration.
1038Internal use only." 1316Internal use only."
1039 (when (and desktop-restore-frames desktop--saved-states) 1317 (when (and desktop-restore-frames desktop--saved-states)
1040 (let ((frames (frame-list)) 1318 (let* ((frame-mb-map nil) ;; Alist of frames with their own minibuffer
1041 (current (frame-parameter nil 'display)) 1319 (visible nil)
1042 (selected nil)) 1320 (delete-saved (eq desktop-restore-in-current-display 'delete))
1321 (forcing (not (desktop-restore-in-original-display-p)))
1322 (target (and forcing (cons 'display (frame-parameter nil 'display)))))
1323
1324 ;; Sorting saved states allows us to easily restore minibuffer-owning frames
1325 ;; before minibufferless ones.
1326 (setq desktop--saved-states (sort desktop--saved-states #'desktop--sort-states))
1327 ;; Potentially all existing frames are reusable. Later we will decide which ones
1328 ;; to reuse, and how to deal with any leftover.
1329 (setq desktop--reuse-list (frame-list))
1330
1043 (dolist (state desktop--saved-states) 1331 (dolist (state desktop--saved-states)
1044 (condition-case err 1332 (condition-case err
1045 (let* ((config (car state)) 1333 (let* ((frame-cfg (car state))
1046 (display (if (desktop--restore-in-this-display-p) 1334 (window-cfg (cdr state))
1047 (setcdr (assq 'display config) current) 1335 (d-mini (cdr (assq 'desktop-mini frame-cfg)))
1048 (cdr (assq 'display config)))) 1336 num frame to-tty)
1049 (full (cdr (assq 'fullscreen config))) 1337 ;; Only set target if forcing displays and the target display is different.
1050 (frame (and (not full) 1338 (if (or (not forcing)
1051 (desktop--find-frame-in-display frames display)))) 1339 (equal target (or (assq 'display frame-cfg) '(display . nil))))
1052 (cond (full 1340 (setq desktop--target-display nil)
1053 ;; treat fullscreen/maximized frames specially 1341 (setq desktop--target-display target
1054 (setq frame (desktop--make-full-frame full display config))) 1342 to-tty (null (cdr target))))
1055 (frame 1343 ;; Time to restore frames and set up their minibuffers as they were.
1056 ;; found a frame in the right display -- reuse 1344 ;; We only skip a frame (thus deleting it) if either:
1057 (setq frames (delq frame frames)) 1345 ;; - we're switching displays, and the user chose the option to delete, or
1058 (modify-frame-parameters frame config)) 1346 ;; - we're switching to tty, and the frame to restore is minibuffer-only.
1059 (t 1347 (unless (and desktop--target-display
1060 ;; no frames in the display -- make a new one 1348 (or delete-saved
1061 (setq frame (make-frame-on-display display config)))) 1349 (and to-tty
1062 ;; restore windows 1350 (eq (cdr (assq 'minibuffer frame-cfg)) 'only))))
1063 (window-state-put (cdr state) (frame-root-window frame) 'safe) 1351
1064 (unless selected (setq selected frame))) 1352 ;; Restore minibuffers. Some of this stuff could be done in a filter
1353 ;; function, but it would be messy because restoring minibuffers affects
1354 ;; global state; it's best to do it here than add a bunch of global
1355 ;; variables to pass info back-and-forth to/from the filter function.
1356 (cond
1357 ((null d-mini)) ;; No desktop-mini. Process as normal frame.
1358 (to-tty) ;; Ignore minibuffer stuff and process as normal frame.
1359 ((car d-mini) ;; Frame has its own minibuffer (or it is minibuffer-only).
1360 (setq num (cadr d-mini))
1361 (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only)
1362 (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0))
1363 frame-cfg))))
1364 (t ;; Frame depends on other frame's minibufer window.
1365 (let ((mb-frame (cdr (assq (cadr d-mini) frame-mb-map))))
1366 (unless (frame-live-p mb-frame)
1367 (error "Minibuffer frame %s not found" (cadr d-mini)))
1368 (let ((mb-param (assq 'minibuffer frame-cfg))
1369 (mb-window (minibuffer-window mb-frame)))
1370 (unless (and (window-live-p mb-window)
1371 (window-minibuffer-p mb-window))
1372 (error "Not a minibuffer window %s" mb-window))
1373 (if mb-param
1374 (setcdr mb-param mb-window)
1375 (push (cons 'minibuffer mb-window) frame-cfg))))))
1376 ;; OK, we're ready at last to create (or reuse) a frame and
1377 ;; restore the window config.
1378 (setq frame (desktop--make-frame frame-cfg window-cfg))
1379 ;; Set default-minibuffer if required.
1380 (when (nth 2 d-mini) (setq default-minibuffer-frame frame))
1381 ;; Store frame/NUM to assign to minibufferless frames.
1382 (when num (push (cons num frame) frame-mb-map))
1383 ;; Try to locate at least one visible frame.
1384 (when (and (not visible) (frame-visible-p frame))
1385 (setq visible frame))))
1065 (error 1386 (error
1066 (message "Error restoring frame: %S" (error-message-string err))))) 1387 (delay-warning 'desktop (error-message-string err) :error))))
1067 (when selected 1388
1068 ;; make sure the original selected frame is visible and selected 1389 ;; Delete remaining frames, but do not fail if some resist being deleted.
1069 (unless (or (frame-parameter selected 'visibility) (daemonp)) 1390 (unless (eq desktop-restoring-reuses-frames 'keep)
1070 (modify-frame-parameters selected '((visibility . t)))) 1391 (dolist (frame desktop--reuse-list)
1071 (select-frame-set-input-focus selected) 1392 (ignore-errors (delete-frame frame))))
1072 ;; delete any remaining frames 1393 (setq desktop--reuse-list nil)
1073 (mapc #'delete-frame frames))))) 1394 ;; Make sure there's at least one visible frame, and select it.
1395 (unless (or visible (daemonp))
1396 (setq visible (if (frame-live-p default-minibuffer-frame)
1397 default-minibuffer-frame
1398 (car (frame-list))))
1399 (make-frame-visible visible)
1400 (select-frame-set-input-focus visible)))))
1074 1401
1075;;;###autoload 1402;;;###autoload
1076(defun desktop-read (&optional dirname) 1403(defun desktop-read (&optional dirname)
diff --git a/lisp/edmacro.el b/lisp/edmacro.el
index 67992d16527..73662951188 100644
--- a/lisp/edmacro.el
+++ b/lisp/edmacro.el
@@ -562,7 +562,8 @@ doubt, use whitespace."
562 (unless (string-match " " desc) 562 (unless (string-match " " desc)
563 (let ((times 1) (pos bind-len)) 563 (let ((times 1) (pos bind-len))
564 (while (not (cl-mismatch rest-mac rest-mac 564 (while (not (cl-mismatch rest-mac rest-mac
565 0 bind-len pos (+ bind-len pos))) 565 :start1 0 :end1 bind-len
566 :start2 pos :end2 (+ bind-len pos)))
566 (cl-incf times) 567 (cl-incf times)
567 (cl-incf pos bind-len)) 568 (cl-incf pos bind-len))
568 (when (> times 1) 569 (when (> times 1)
diff --git a/lisp/epa.el b/lisp/epa.el
index 14f8879c1c6..68e7a18fe17 100644
--- a/lisp/epa.el
+++ b/lisp/epa.el
@@ -34,8 +34,7 @@
34 :group 'epg) 34 :group 'epg)
35 35
36(defcustom epa-popup-info-window t 36(defcustom epa-popup-info-window t
37 "If non-nil, status information from epa commands is displayed on 37 "If non-nil, display status information from epa commands in another window."
38the separate window."
39 :type 'boolean 38 :type 'boolean
40 :group 'epa) 39 :group 'epa)
41 40
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index e170db2dd5f..c9a7e106faa 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -27,8 +27,7 @@
27 27
28;;; Code: 28;;; Code:
29 29
30;;;###autoload 30(defconst file-notify--library
31(defconst file-notify-support
32 (cond 31 (cond
33 ((featurep 'gfilenotify) 'gfilenotify) 32 ((featurep 'gfilenotify) 'gfilenotify)
34 ((featurep 'inotify) 'inotify) 33 ((featurep 'inotify) 'inotify)
@@ -191,6 +190,17 @@ car of that event, which is the symbol `file-notify'."
191 (funcall callback (list desc action file file1)) 190 (funcall callback (list desc action file file1))
192 (funcall callback (list desc action file))))))) 191 (funcall callback (list desc action file)))))))
193 192
193(defun file-notify-supported-p (file)
194 "Returns non-nil if filesystem pertaining to FILE could be watched."
195 (unless (stringp file)
196 (signal 'wrong-type-argument (list file)))
197 (setq file (expand-file-name file))
198
199 (let ((handler (find-file-name-handler file 'file-notify-supported-p)))
200 (if handler
201 (funcall handler 'file-notify-supported-p file)
202 (and file-notify--library t))))
203
194(defun file-notify-add-watch (file flags callback) 204(defun file-notify-add-watch (file flags callback)
195 "Add a watch for filesystem events pertaining to FILE. 205 "Add a watch for filesystem events pertaining to FILE.
196This arranges for filesystem events pertaining to FILE to be reported 206This arranges for filesystem events pertaining to FILE to be reported
@@ -238,7 +248,7 @@ FILE is the name of the file whose event is being reported."
238 248
239 (let* ((handler (find-file-name-handler file 'file-notify-add-watch)) 249 (let* ((handler (find-file-name-handler file 'file-notify-add-watch))
240 (dir (directory-file-name 250 (dir (directory-file-name
241 (if (or (and (not handler) (eq file-notify-support 'w32notify)) 251 (if (or (and (not handler) (eq file-notify--library 'w32notify))
242 (file-directory-p file)) 252 (file-directory-p file))
243 file 253 file
244 (file-name-directory file)))) 254 (file-name-directory file))))
@@ -259,32 +269,32 @@ FILE is the name of the file whose event is being reported."
259 269
260 ;; Check, whether Emacs has been compiled with file 270 ;; Check, whether Emacs has been compiled with file
261 ;; notification support. 271 ;; notification support.
262 (unless file-notify-support 272 (unless file-notify--library
263 (signal 'file-notify-error 273 (signal 'file-notify-error
264 '("No file notification package available"))) 274 '("No file notification package available")))
265 275
266 ;; Determine low-level function to be called. 276 ;; Determine low-level function to be called.
267 (setq func (cond 277 (setq func (cond
268 ((eq file-notify-support 'gfilenotify) 'gfile-add-watch) 278 ((eq file-notify--library 'gfilenotify) 'gfile-add-watch)
269 ((eq file-notify-support 'inotify) 'inotify-add-watch) 279 ((eq file-notify--library 'inotify) 'inotify-add-watch)
270 ((eq file-notify-support 'w32notify) 'w32notify-add-watch))) 280 ((eq file-notify--library 'w32notify) 'w32notify-add-watch)))
271 281
272 ;; Determine respective flags. 282 ;; Determine respective flags.
273 (if (eq file-notify-support 'gfilenotify) 283 (if (eq file-notify--library 'gfilenotify)
274 (setq l-flags '(watch-mounts send-moved)) 284 (setq l-flags '(watch-mounts send-moved))
275 (when (memq 'change flags) 285 (when (memq 'change flags)
276 (setq 286 (setq
277 l-flags 287 l-flags
278 (cond 288 (cond
279 ((eq file-notify-support 'inotify) '(create modify move delete)) 289 ((eq file-notify--library 'inotify) '(create modify move delete))
280 ((eq file-notify-support 'w32notify) 290 ((eq file-notify--library 'w32notify)
281 '(file-name directory-name size last-write-time))))) 291 '(file-name directory-name size last-write-time)))))
282 (when (memq 'attribute-change flags) 292 (when (memq 'attribute-change flags)
283 (add-to-list 293 (add-to-list
284 'l-flags 294 'l-flags
285 (cond 295 (cond
286 ((eq file-notify-support 'inotify) 'attrib) 296 ((eq file-notify--library 'inotify) 'attrib)
287 ((eq file-notify-support 'w32notify) 'attributes))))) 297 ((eq file-notify--library 'w32notify) 'attributes)))))
288 298
289 ;; Call low-level function. 299 ;; Call low-level function.
290 (setq desc (funcall func dir l-flags 'file-notify-callback)))) 300 (setq desc (funcall func dir l-flags 'file-notify-callback))))
@@ -311,9 +321,9 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
311 (funcall handler 'file-notify-rm-watch descriptor) 321 (funcall handler 'file-notify-rm-watch descriptor)
312 (funcall 322 (funcall
313 (cond 323 (cond
314 ((eq file-notify-support 'gfilenotify) 'gfile-rm-watch) 324 ((eq file-notify--library 'gfilenotify) 'gfile-rm-watch)
315 ((eq file-notify-support 'inotify) 'inotify-rm-watch) 325 ((eq file-notify--library 'inotify) 'inotify-rm-watch)
316 ((eq file-notify-support 'w32notify) 'w32notify-rm-watch)) 326 ((eq file-notify--library 'w32notify) 'w32notify-rm-watch))
317 descriptor))) 327 descriptor)))
318 328
319 (remhash descriptor file-notify-descriptors))) 329 (remhash descriptor file-notify-descriptors)))
diff --git a/lisp/frame.el b/lisp/frame.el
index 3ac24a509a0..ed47afa4b94 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -1671,6 +1671,16 @@ left untouched. FRAME nil or omitted means use the selected frame."
1671 :type 'number 1671 :type 'number
1672 :group 'cursor) 1672 :group 'cursor)
1673 1673
1674(defcustom blink-cursor-blinks 10
1675 "How many times to blink before using a solid cursor on NS and X.
1676Use 0 or negative value to blink forever."
1677 :version "24.4"
1678 :type 'integer
1679 :group 'cursor)
1680
1681(defvar blink-cursor-blinks-done 1
1682 "Number of blinks done since we started blinking on NS and X")
1683
1674(defvar blink-cursor-idle-timer nil 1684(defvar blink-cursor-idle-timer nil
1675 "Timer started after `blink-cursor-delay' seconds of Emacs idle time. 1685 "Timer started after `blink-cursor-delay' seconds of Emacs idle time.
1676The function `blink-cursor-start' is called when the timer fires.") 1686The function `blink-cursor-start' is called when the timer fires.")
@@ -1688,6 +1698,7 @@ command starts, by installing a pre-command hook."
1688 (when (null blink-cursor-timer) 1698 (when (null blink-cursor-timer)
1689 ;; Set up the timer first, so that if this signals an error, 1699 ;; Set up the timer first, so that if this signals an error,
1690 ;; blink-cursor-end is not added to pre-command-hook. 1700 ;; blink-cursor-end is not added to pre-command-hook.
1701 (setq blink-cursor-blinks-done 1)
1691 (setq blink-cursor-timer 1702 (setq blink-cursor-timer
1692 (run-with-timer blink-cursor-interval blink-cursor-interval 1703 (run-with-timer blink-cursor-interval blink-cursor-interval
1693 'blink-cursor-timer-function)) 1704 'blink-cursor-timer-function))
@@ -1696,7 +1707,15 @@ command starts, by installing a pre-command hook."
1696 1707
1697(defun blink-cursor-timer-function () 1708(defun blink-cursor-timer-function ()
1698 "Timer function of timer `blink-cursor-timer'." 1709 "Timer function of timer `blink-cursor-timer'."
1699 (internal-show-cursor nil (not (internal-show-cursor-p)))) 1710 (internal-show-cursor nil (not (internal-show-cursor-p)))
1711 ;; Each blink is two calls to this function.
1712 (when (memq window-system '(x ns w32))
1713 (setq blink-cursor-blinks-done (1+ blink-cursor-blinks-done))
1714 (when (and (> blink-cursor-blinks 0)
1715 (<= (* 2 blink-cursor-blinks) blink-cursor-blinks-done))
1716 (blink-cursor-suspend)
1717 (add-hook 'post-command-hook 'blink-cursor-check))))
1718
1700 1719
1701(defun blink-cursor-end () 1720(defun blink-cursor-end ()
1702 "Stop cursor blinking. 1721 "Stop cursor blinking.
@@ -1709,6 +1728,29 @@ itself as a pre-command hook."
1709 (cancel-timer blink-cursor-timer) 1728 (cancel-timer blink-cursor-timer)
1710 (setq blink-cursor-timer nil))) 1729 (setq blink-cursor-timer nil)))
1711 1730
1731(defun blink-cursor-suspend ()
1732 "Suspend cursor blinking on NS, X and W32.
1733This is called when no frame has focus and timers can be suspended.
1734Timers are restarted by `blink-cursor-check', which is called when a
1735frame receives focus."
1736 (when (memq window-system '(x ns w32))
1737 (blink-cursor-end)
1738 (when blink-cursor-idle-timer
1739 (cancel-timer blink-cursor-idle-timer)
1740 (setq blink-cursor-idle-timer nil))))
1741
1742(defun blink-cursor-check ()
1743 "Check if cursot blinking shall be restarted.
1744This is done when a frame gets focus. Blink timers may be stopped by
1745`blink-cursor-suspend'."
1746 (when (and blink-cursor-mode
1747 (not blink-cursor-idle-timer))
1748 (remove-hook 'post-command-hook 'blink-cursor-check)
1749 (setq blink-cursor-idle-timer
1750 (run-with-idle-timer blink-cursor-delay
1751 blink-cursor-delay
1752 'blink-cursor-start))))
1753
1712(define-obsolete-variable-alias 'blink-cursor 'blink-cursor-mode "22.1") 1754(define-obsolete-variable-alias 'blink-cursor 'blink-cursor-mode "22.1")
1713 1755
1714(define-minor-mode blink-cursor-mode 1756(define-minor-mode blink-cursor-mode
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index eade6273e95..4b2892ae4b0 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,18 @@
12013-07-19 Geoff Kuenning <geoff@cs.hmc.edu> (tiny change)
2
3 * gnus-art.el (gnus-treat-predicate): Allow functions as predicates
4 (bug#13384).
5
62013-07-18 Lars Magne Ingebrigtsen <larsi@gnus.org>
7
8 * gnus-start.el (gnus-clean-old-newsrc): Remove the newsrc cleanups
9 that were only relevant in a development version a long time ago.
10
112013-07-18 Katsumi Yamaoka <yamaoka@jpl.org>
12
13 * gnus-art.el (gnus-shr-put-image): Make it work as well for shr.el's
14 that the old Emacs 24s bundle.
15
12013-07-10 David Engster <deng@randomsample.de> 162013-07-10 David Engster <deng@randomsample.de>
2 17
3 * gnus-start.el (gnus-clean-old-newsrc): Always remove 'unexist' marks 18 * gnus-start.el (gnus-clean-old-newsrc): Always remove 'unexist' marks
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index b41ff9c0550..31a108a3c98 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -6197,9 +6197,14 @@ Provided for backwards compatibility."
6197 6197
6198(defun gnus-shr-put-image (data alt &optional flags) 6198(defun gnus-shr-put-image (data alt &optional flags)
6199 "Put image DATA with a string ALT. Enable image to be deleted." 6199 "Put image DATA with a string ALT. Enable image to be deleted."
6200 (let ((image (shr-put-image data (propertize (or alt "*") 6200 (let ((image (if flags
6201 'gnus-image-category 'shr) 6201 (shr-put-image data (propertize (or alt "*")
6202 flags))) 6202 'gnus-image-category 'shr)
6203 flags)
6204 ;; Old `shr-put-image' doesn't take the optional `flags'
6205 ;; argument.
6206 (shr-put-image data (propertize (or alt "*")
6207 'gnus-image-category 'shr)))))
6203 (when image 6208 (when image
6204 (gnus-add-image 'shr image)))) 6209 (gnus-add-image 'shr image))))
6205 6210
@@ -8414,6 +8419,8 @@ For example:
8414 (not (gnus-treat-predicate (car val)))) 8419 (not (gnus-treat-predicate (car val))))
8415 ((eq pred 'typep) 8420 ((eq pred 'typep)
8416 (equal (car val) gnus-treat-type)) 8421 (equal (car val) gnus-treat-type))
8422 ((functionp pred)
8423 (funcall pred))
8417 (t 8424 (t
8418 (error "%S is not a valid predicate" pred))))) 8425 (error "%S is not a valid predicate" pred)))))
8419 ((eq val t) 8426 ((eq val t)
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 94803800e0b..05cf290cac9 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -2305,24 +2305,8 @@ If FORCE is non-nil, the .newsrc file is read."
2305 (gnus-clean-old-newsrc)))) 2305 (gnus-clean-old-newsrc))))
2306 2306
2307(defun gnus-clean-old-newsrc (&optional force) 2307(defun gnus-clean-old-newsrc (&optional force)
2308 (when gnus-newsrc-file-version 2308 ;; Currently no cleanups.
2309 ;; Remove totally bogus `unexists' entries. The name is 2309 )
2310 ;; `unexist'.
2311 (dolist (info (cdr gnus-newsrc-alist))
2312 (let ((exist (assoc 'unexists (gnus-info-marks info))))
2313 (when exist
2314 (gnus-info-set-marks
2315 info (delete exist (gnus-info-marks info))))))
2316 (when (or force
2317 (not (string= gnus-newsrc-file-version gnus-version)))
2318 (message (concat "Removing unexist marks because newsrc "
2319 "version does not match Gnus version."))
2320 ;; Remove old `exist' marks from old nnimap groups.
2321 (dolist (info (cdr gnus-newsrc-alist))
2322 (let ((exist (assoc 'unexist (gnus-info-marks info))))
2323 (when exist
2324 (gnus-info-set-marks
2325 info (delete exist (gnus-info-marks info)))))))))
2326 2310
2327(defun gnus-convert-old-newsrc () 2311(defun gnus-convert-old-newsrc ()
2328 "Convert old newsrc formats into the current format, if needed." 2312 "Convert old newsrc formats into the current format, if needed."
diff --git a/lisp/gnus/registry.el b/lisp/gnus/registry.el
index 37fe6440743..b056ac5e7f3 100644
--- a/lisp/gnus/registry.el
+++ b/lisp/gnus/registry.el
@@ -228,7 +228,7 @@ With assert non-nil, errors out if the key does not exist already."
228 (let ((entry (gethash key data))) 228 (let ((entry (gethash key data)))
229 (when assert 229 (when assert
230 (assert entry nil 230 (assert entry nil
231 "Key %s does not exists in database" key)) 231 "Key %s does not exist in database" key))
232 ;; clean entry from the secondary indices 232 ;; clean entry from the secondary indices
233 (dolist (tr tracked) 233 (dolist (tr tracked)
234 ;; is this tracked symbol indexed? 234 ;; is this tracked symbol indexed?
diff --git a/lisp/mail/mailalias.el b/lisp/mail/mailalias.el
index c5f1e3921fa..4d9b24e0043 100644
--- a/lisp/mail/mailalias.el
+++ b/lisp/mail/mailalias.el
@@ -209,7 +209,9 @@ removed from alias expansions."
209 (if (re-search-forward "[ \t]*[\n,][ \t]*" end1 t) 209 (if (re-search-forward "[ \t]*[\n,][ \t]*" end1 t)
210 (setq epos (match-beginning 0) 210 (setq epos (match-beginning 0)
211 seplen (- (point) epos)) 211 seplen (- (point) epos))
212 (setq epos (marker-position end1) seplen 0)) 212 ;; Handle the last name in this header field.
213 ;; We already moved END1 back across whitespace after it.
214 (setq epos (marker-position end1) seplen 0))
213 (let ((string (buffer-substring-no-properties pos epos)) 215 (let ((string (buffer-substring-no-properties pos epos))
214 translation) 216 translation)
215 (if (and (not (assoc string disabled-aliases)) 217 (if (and (not (assoc string disabled-aliases))
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index d832aa7ef3e..d65932ae7c9 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -603,7 +603,7 @@ appears in a <link> or <a> tag."
603 (insert " "))) 603 (insert " ")))
604 604
605(defun eww-process-text-input (beg end length) 605(defun eww-process-text-input (beg end length)
606 (let* ((form (get-text-property end 'eww-form)) 606 (let* ((form (get-text-property (min (1+ end) (point-max)) 'eww-form))
607 (properties (text-properties-at end)) 607 (properties (text-properties-at end))
608 (type (plist-get form :type))) 608 (type (plist-get form :type)))
609 (when (and form 609 (when (and form
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 4506ede8722..6ddf8d2af90 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -143,6 +143,7 @@ cid: URL as the argument.")
143 (define-key map [tab] 'shr-next-link) 143 (define-key map [tab] 'shr-next-link)
144 (define-key map [backtab] 'shr-previous-link) 144 (define-key map [backtab] 'shr-previous-link)
145 (define-key map [follow-link] 'mouse-face) 145 (define-key map [follow-link] 'mouse-face)
146 (define-key map [mouse-2] 'shr-mouse-browse-url)
146 (define-key map "I" 'shr-insert-image) 147 (define-key map "I" 'shr-insert-image)
147 (define-key map "w" 'shr-copy-url) 148 (define-key map "w" 'shr-copy-url)
148 (define-key map "u" 'shr-copy-url) 149 (define-key map "u" 'shr-copy-url)
@@ -657,6 +658,12 @@ size, and full-buffer size."
657 (forward-line 1) 658 (forward-line 1)
658 (goto-char end)))))) 659 (goto-char end))))))
659 660
661(defun shr-mouse-browse-url (ev)
662 "Browse the URL under the mouse cursor."
663 (interactive "e")
664 (mouse-set-point ev)
665 (shr-browse-url))
666
660(defun shr-browse-url (&optional external) 667(defun shr-browse-url (&optional external)
661 "Browse the URL under point. 668 "Browse the URL under point.
662If EXTERNAL, browse the URL using `shr-external-browser'." 669If EXTERNAL, browse the URL using `shr-external-browser'."
@@ -1476,9 +1483,6 @@ ones, in case fg and bg are nil."
1476 (if column 1483 (if column
1477 (aref widths width-column) 1484 (aref widths width-column)
1478 10)) 1485 10))
1479 ;; Sanity check for degenerate tables.
1480 (when (zerop width)
1481 (setq width 10))
1482 (when (and fill 1486 (when (and fill
1483 (setq colspan (cdr (assq :colspan (cdr column))))) 1487 (setq colspan (cdr (assq :colspan (cdr column)))))
1484 (setq colspan (string-to-number colspan)) 1488 (setq colspan (string-to-number colspan))
@@ -1491,6 +1495,9 @@ ones, in case fg and bg are nil."
1491 (setq width-column (+ width-column (1- colspan)))) 1495 (setq width-column (+ width-column (1- colspan))))
1492 (when (or column 1496 (when (or column
1493 (not fill)) 1497 (not fill))
1498 ;; Sanity check for degenerate tables.
1499 (when (zerop width)
1500 (setq width 10))
1494 (push (shr-render-td (cdr column) width fill) 1501 (push (shr-render-td (cdr column) width fill)
1495 tds)) 1502 tds))
1496 (setq i (1+ i) 1503 (setq i (1+ i)
@@ -1499,6 +1506,7 @@ ones, in case fg and bg are nil."
1499 (nreverse trs))) 1506 (nreverse trs)))
1500 1507
1501(defun shr-render-td (cont width fill) 1508(defun shr-render-td (cont width fill)
1509 (when (= width 0) (debug))
1502 (with-temp-buffer 1510 (with-temp-buffer
1503 (let ((bgcolor (cdr (assq :bgcolor cont))) 1511 (let ((bgcolor (cdr (assq :bgcolor cont)))
1504 (fgcolor (cdr (assq :fgcolor cont))) 1512 (fgcolor (cdr (assq :fgcolor cont)))
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 14fb8575fff..56c0ee2dc2d 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -108,6 +108,9 @@
108 (file-writable-p . tramp-adb-handle-file-writable-p) 108 (file-writable-p . tramp-adb-handle-file-writable-p)
109 (file-local-copy . tramp-adb-handle-file-local-copy) 109 (file-local-copy . tramp-adb-handle-file-local-copy)
110 (file-modes . tramp-handle-file-modes) 110 (file-modes . tramp-handle-file-modes)
111 (file-notify-add-watch . ignore)
112 (file-notify-rm-watch . ignore)
113 (file-notify-supported-p . ignore)
111 (expand-file-name . tramp-adb-handle-expand-file-name) 114 (expand-file-name . tramp-adb-handle-expand-file-name)
112 (find-backup-file-name . tramp-handle-find-backup-file-name) 115 (find-backup-file-name . tramp-handle-find-backup-file-name)
113 (directory-files . tramp-handle-directory-files) 116 (directory-files . tramp-handle-directory-files)
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index d4115352b34..2b0ea74c492 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -184,7 +184,7 @@
184 'file-expand-wildcards 'around 'tramp-advice-file-expand-wildcards) 184 'file-expand-wildcards 'around 'tramp-advice-file-expand-wildcards)
185 (ad-activate 'file-expand-wildcards))))) 185 (ad-activate 'file-expand-wildcards)))))
186 186
187;; `with-temp-message' does not exists in XEmacs. 187;; `with-temp-message' does not exist in XEmacs.
188(if (fboundp 'with-temp-message) 188(if (fboundp 'with-temp-message)
189 (defalias 'tramp-compat-with-temp-message 'with-temp-message) 189 (defalias 'tramp-compat-with-temp-message 'with-temp-message)
190 (defmacro tramp-compat-with-temp-message (message &rest body) 190 (defmacro tramp-compat-with-temp-message (message &rest body)
@@ -292,7 +292,7 @@ Not actually used. Use `(format \"%o\" i)' instead?"
292 (error "Non-octal junk in string `%s'" x)) 292 (error "Non-octal junk in string `%s'" x))
293 (string-to-number ostr 8))) 293 (string-to-number ostr 8)))
294 294
295;; ID-FORMAT does not exists in XEmacs. 295;; ID-FORMAT does not exist in XEmacs.
296(defun tramp-compat-file-attributes (filename &optional id-format) 296(defun tramp-compat-file-attributes (filename &optional id-format)
297 "Like `file-attributes' for Tramp files (compat function)." 297 "Like `file-attributes' for Tramp files (compat function)."
298 (cond 298 (cond
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index c2fdc0491b6..526408140c2 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -435,6 +435,9 @@ Every entry is a list (NAME ADDRESS).")
435 (file-name-nondirectory . tramp-handle-file-name-nondirectory) 435 (file-name-nondirectory . tramp-handle-file-name-nondirectory)
436 ;; `file-name-sans-versions' performed by default handler. 436 ;; `file-name-sans-versions' performed by default handler.
437 (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) 437 (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
438 (file-notify-add-watch . ignore)
439 (file-notify-rm-watch . ignore)
440 (file-notify-supported-p . ignore)
438 (file-ownership-preserved-p . ignore) 441 (file-ownership-preserved-p . ignore)
439 (file-readable-p . tramp-gvfs-handle-file-readable-p) 442 (file-readable-p . tramp-gvfs-handle-file-readable-p)
440 (file-regular-p . tramp-handle-file-regular-p) 443 (file-regular-p . tramp-handle-file-regular-p)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 281f497692d..d2fc1b9979e 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -867,7 +867,8 @@ of command line.")
867 (set-file-acl . tramp-sh-handle-set-file-acl) 867 (set-file-acl . tramp-sh-handle-set-file-acl)
868 (vc-registered . tramp-sh-handle-vc-registered) 868 (vc-registered . tramp-sh-handle-vc-registered)
869 (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch) 869 (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
870 (file-notify-rm-watch . tramp-sh-handle-file-notify-rm-watch)) 870 (file-notify-rm-watch . tramp-sh-handle-file-notify-rm-watch)
871 (file-notify-supported-p . tramp-sh-handle-file-notify-supported-p))
871 "Alist of handler functions. 872 "Alist of handler functions.
872Operations not mentioned here will be handled by the normal Emacs functions.") 873Operations not mentioned here will be handled by the normal Emacs functions.")
873 874
@@ -3334,7 +3335,8 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
3334 ;; `process-file-side-effects' in order to keep the cache when 3335 ;; `process-file-side-effects' in order to keep the cache when
3335 ;; `process-file' calls appear. 3336 ;; `process-file' calls appear.
3336 (let (process-file-side-effects) 3337 (let (process-file-side-effects)
3337 (tramp-run-real-handler 'vc-registered (list file))))))) 3338 (ignore-errors
3339 (tramp-run-real-handler 'vc-registered (list file))))))))
3338 3340
3339;;;###tramp-autoload 3341;;;###tramp-autoload
3340(defun tramp-sh-file-name-handler (operation &rest args) 3342(defun tramp-sh-file-name-handler (operation &rest args)
@@ -3497,6 +3499,13 @@ Fall back to normal file name handler if no Tramp handler exists."
3497 (tramp-message proc 6 (format "Kill %S" proc)) 3499 (tramp-message proc 6 (format "Kill %S" proc))
3498 (kill-process proc)) 3500 (kill-process proc))
3499 3501
3502(defun tramp-sh-handle-file-notify-supported-p (file-name)
3503 "Like `file-notify-supported-p' for Tramp files."
3504 (with-parsed-tramp-file-name (expand-file-name file-name) nil
3505 (and (or (tramp-get-remote-gvfs-monitor-dir v)
3506 (tramp-get-remote-inotifywait v))
3507 t)))
3508
3500;;; Internal Functions: 3509;;; Internal Functions:
3501 3510
3502(defun tramp-maybe-send-script (vec script name) 3511(defun tramp-maybe-send-script (vec script name)
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 65c52ae4f3c..d9bb5057e7a 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -209,6 +209,9 @@ See `tramp-actions-before-shell' for more info.")
209 (file-name-nondirectory . tramp-handle-file-name-nondirectory) 209 (file-name-nondirectory . tramp-handle-file-name-nondirectory)
210 ;; `file-name-sans-versions' performed by default handler. 210 ;; `file-name-sans-versions' performed by default handler.
211 (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) 211 (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
212 (file-notify-add-watch . ignore)
213 (file-notify-rm-watch . ignore)
214 (file-notify-supported-p . ignore)
212 (file-ownership-preserved-p . ignore) 215 (file-ownership-preserved-p . ignore)
213 (file-readable-p . tramp-handle-file-exists-p) 216 (file-readable-p . tramp-handle-file-exists-p)
214 (file-regular-p . tramp-handle-file-regular-p) 217 (file-regular-p . tramp-handle-file-regular-p)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 3513701d20e..fd5435bd3d4 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1980,8 +1980,8 @@ ARGS are the arguments OPERATION has been called with."
1980 ;; Emacs 22+ only. 1980 ;; Emacs 22+ only.
1981 'set-file-times 1981 'set-file-times
1982 ;; Emacs 24+ only. 1982 ;; Emacs 24+ only.
1983 'file-acl 'file-notify-add-watch 'file-selinux-context 1983 'file-acl 'file-notify-add-watch 'file-notify-supported-p
1984 'set-file-acl 'set-file-selinux-context 1984 'file-selinux-context 'set-file-acl 'set-file-selinux-context
1985 ;; XEmacs only. 1985 ;; XEmacs only.
1986 'abbreviate-file-name 'create-file-buffer 1986 'abbreviate-file-name 'create-file-buffer
1987 'dired-file-modtime 'dired-make-compressed-filename 1987 'dired-file-modtime 'dired-make-compressed-filename
diff --git a/lisp/org/org-freemind.el b/lisp/org/org-freemind.el
index 3b1c6863f54..2ee58501ca1 100644
--- a/lisp/org/org-freemind.el
+++ b/lisp/org/org-freemind.el
@@ -598,7 +598,7 @@ DRAWERS-REGEXP are converted to freemind notes."
598 598
599(defun org-freemind-check-overwrite (file interactively) 599(defun org-freemind-check-overwrite (file interactively)
600 "Check if file FILE already exists. 600 "Check if file FILE already exists.
601If FILE does not exists return t. 601If FILE does not exist return t.
602 602
603If INTERACTIVELY is non-nil ask if the file should be replaced 603If INTERACTIVELY is non-nil ask if the file should be replaced
604and return t/nil if it should/should not be replaced. 604and return t/nil if it should/should not be replaced.
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 0b83921504b..c8fae7ba1e6 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -46,11 +46,6 @@
46 :prefix "ruby-" 46 :prefix "ruby-"
47 :group 'languages) 47 :group 'languages)
48 48
49(defconst ruby-keyword-end-re
50 (if (string-match "\\_>" "ruby")
51 "\\_>"
52 "\\>"))
53
54(defconst ruby-block-beg-keywords 49(defconst ruby-block-beg-keywords
55 '("class" "module" "def" "if" "unless" "case" "while" "until" "for" "begin" "do") 50 '("class" "module" "def" "if" "unless" "case" "while" "until" "for" "begin" "do")
56 "Keywords at the beginning of blocks.") 51 "Keywords at the beginning of blocks.")
@@ -60,7 +55,7 @@
60 "Regexp to match the beginning of blocks.") 55 "Regexp to match the beginning of blocks.")
61 56
62(defconst ruby-non-block-do-re 57(defconst ruby-non-block-do-re
63 (concat (regexp-opt '("while" "until" "for" "rescue") t) ruby-keyword-end-re) 58 (regexp-opt '("while" "until" "for" "rescue") 'symbols)
64 "Regexp to match keywords that nest without blocks.") 59 "Regexp to match keywords that nest without blocks.")
65 60
66(defconst ruby-indent-beg-re 61(defconst ruby-indent-beg-re
@@ -696,7 +691,7 @@ Can be one of `heredoc', `modifier', `expr-qstr', `expr-re'."
696 ((looking-at (concat "\\_<\\(" ruby-block-beg-re "\\)\\_>")) 691 ((looking-at (concat "\\_<\\(" ruby-block-beg-re "\\)\\_>"))
697 (and 692 (and
698 (save-match-data 693 (save-match-data
699 (or (not (looking-at (concat "do" ruby-keyword-end-re))) 694 (or (not (looking-at "do\\_>"))
700 (save-excursion 695 (save-excursion
701 (back-to-indentation) 696 (back-to-indentation)
702 (not (looking-at ruby-non-block-do-re))))) 697 (not (looking-at ruby-non-block-do-re)))))
@@ -1718,14 +1713,16 @@ See the definition of `ruby-font-lock-syntactic-keywords'."
1718 "The syntax table to use for fontifying Ruby mode buffers. 1713 "The syntax table to use for fontifying Ruby mode buffers.
1719See `font-lock-syntax-table'.") 1714See `font-lock-syntax-table'.")
1720 1715
1716(defconst ruby-font-lock-keyword-beg-re "\\(?:^\\|[^.@$]\\|\\.\\.\\)")
1717
1721(defconst ruby-font-lock-keywords 1718(defconst ruby-font-lock-keywords
1722 (list 1719 (list
1723 ;; functions 1720 ;; functions
1724 '("^\\s *def\\s +\\(?:[^( \t\n.]*\\.\\)?\\([^( \t\n]+\\)" 1721 '("^\\s *def\\s +\\(?:[^( \t\n.]*\\.\\)?\\([^( \t\n]+\\)"
1725 1 font-lock-function-name-face) 1722 1 font-lock-function-name-face)
1723 ;; keywords
1726 (list (concat 1724 (list (concat
1727 "\\(^\\|[^.@$]\\|\\.\\.\\)\\(" 1725 ruby-font-lock-keyword-beg-re
1728 ;; keywords
1729 (regexp-opt 1726 (regexp-opt
1730 '("alias" 1727 '("alias"
1731 "and" 1728 "and"
@@ -1760,11 +1757,14 @@ See `font-lock-syntax-table'.")
1760 "when" 1757 "when"
1761 "while" 1758 "while"
1762 "yield") 1759 "yield")
1763 'symbols) 1760 'symbols))
1764 "\\|" 1761 1 'font-lock-keyword-face)
1762 ;; some core methods
1763 (list (concat
1764 ruby-font-lock-keyword-beg-re
1765 (regexp-opt 1765 (regexp-opt
1766 ;; built-in methods on Kernel 1766 '(;; built-in methods on Kernel
1767 '("__callee__" 1767 "__callee__"
1768 "__dir__" 1768 "__dir__"
1769 "__method__" 1769 "__method__"
1770 "abort" 1770 "abort"
@@ -1823,20 +1823,17 @@ See `font-lock-syntax-table'.")
1823 "public" 1823 "public"
1824 "refine" 1824 "refine"
1825 "using") 1825 "using")
1826 'symbols) 1826 'symbols))
1827 "\\)") 1827 1 'font-lock-builtin-face)
1828 2
1829 '(if (match-beginning 4)
1830 font-lock-builtin-face
1831 font-lock-keyword-face))
1832 ;; Perl-ish keywords 1828 ;; Perl-ish keywords
1833 "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$" 1829 "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$"
1834 ;; here-doc beginnings 1830 ;; here-doc beginnings
1835 `(,ruby-here-doc-beg-re 0 (unless (ruby-singleton-class-p (match-beginning 0)) 1831 `(,ruby-here-doc-beg-re 0 (unless (ruby-singleton-class-p (match-beginning 0))
1836 'font-lock-string-face)) 1832 'font-lock-string-face))
1837 ;; variables 1833 ;; variables
1838 '("\\(^\\|[^.@$]\\|\\.\\.\\)\\_<\\(nil\\|self\\|true\\|false\\)\\>" 1834 `(,(concat ruby-font-lock-keyword-beg-re
1839 2 font-lock-variable-name-face) 1835 "\\_<\\(nil\\|self\\|true\\|false\\)\\>")
1836 1 font-lock-variable-name-face)
1840 ;; keywords that evaluate to certain values 1837 ;; keywords that evaluate to certain values
1841 '("\\_<__\\(?:LINE\\|ENCODING\\|FILE\\)__\\_>" 0 font-lock-variable-name-face) 1838 '("\\_<__\\(?:LINE\\|ENCODING\\|FILE\\)__\\_>" 0 font-lock-variable-name-face)
1842 ;; symbols 1839 ;; symbols
@@ -1852,7 +1849,7 @@ See `font-lock-syntax-table'.")
1852 1 (unless (eq ?\( (char-after)) font-lock-type-face)) 1849 1 (unless (eq ?\( (char-after)) font-lock-type-face))
1853 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face) 1850 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face)
1854 ;; conversion methods on Kernel 1851 ;; conversion methods on Kernel
1855 (list (concat "\\(?:^\\|[^.@$]\\|\\.\\.\\)" 1852 (list (concat ruby-font-lock-keyword-beg-re
1856 (regexp-opt '("Array" "Complex" "Float" "Hash" 1853 (regexp-opt '("Array" "Complex" "Float" "Hash"
1857 "Integer" "Rational" "String") 'symbols)) 1854 "Integer" "Rational" "String") 'symbols))
1858 1 font-lock-builtin-face) 1855 1 font-lock-builtin-face)
@@ -1864,7 +1861,7 @@ See `font-lock-syntax-table'.")
1864 1 font-lock-negation-char-face) 1861 1 font-lock-negation-char-face)
1865 ;; character literals 1862 ;; character literals
1866 ;; FIXME: Support longer escape sequences. 1863 ;; FIXME: Support longer escape sequences.
1867 '("\\?\\\\?\\S " 0 font-lock-string-face) 1864 '("\\_<\\?\\\\?\\S " 0 font-lock-string-face)
1868 ) 1865 )
1869 "Additional expressions to highlight in Ruby mode.") 1866 "Additional expressions to highlight in Ruby mode.")
1870 1867
diff --git a/lisp/shell.el b/lisp/shell.el
index 51a0ffc4fe8..a78ab7f81ab 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -284,21 +284,9 @@ Value is a list of strings, which may be nil."
284;; Note: There are no explicit references to the variable `explicit-bash-args'. 284;; Note: There are no explicit references to the variable `explicit-bash-args'.
285;; It is used implicitly by M-x shell when the interactive shell is `bash'. 285;; It is used implicitly by M-x shell when the interactive shell is `bash'.
286(defcustom explicit-bash-args 286(defcustom explicit-bash-args
287 (let* ((prog (or (and (boundp 'explicit-shell-file-name) explicit-shell-file-name) 287 ;; Tell bash not to use readline. It's safe to assume --noediting now,
288 (getenv "ESHELL") shell-file-name)) 288 ;; as it was introduced in 1996 in Bash version 2.
289 (name (file-name-nondirectory prog))) 289 '("--noediting" "-i")
290 ;; Tell bash not to use readline, except for bash 1.x which
291 ;; doesn't grok --noediting. Bash 1.x has -nolineediting, but
292 ;; process-send-eof cannot terminate bash if we use it.
293 (if (and (not purify-flag)
294 (equal name "bash")
295 (file-executable-p prog)
296 (string-match "bad option"
297 (shell-command-to-string
298 (concat (shell-quote-argument prog)
299 " --noediting"))))
300 '("-i")
301 '("--noediting" "-i")))
302 "Args passed to inferior shell by \\[shell], if the shell is bash. 290 "Args passed to inferior shell by \\[shell], if the shell is bash.
303Value is a list of strings, which may be nil." 291Value is a list of strings, which may be nil."
304 :type '(repeat (string :tag "Argument")) 292 :type '(repeat (string :tag "Argument"))
diff --git a/lisp/simple.el b/lisp/simple.el
index 3e3ff485c5e..4b158d31f36 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -4800,6 +4800,8 @@ The value is a floating-point number."
4800 (this-ypos (nth 2 this-lh)) 4800 (this-ypos (nth 2 this-lh))
4801 (dlh (default-line-height)) 4801 (dlh (default-line-height))
4802 (wslines (window-screen-lines)) 4802 (wslines (window-screen-lines))
4803 (edges (window-inside-pixel-edges))
4804 (winh (- (nth 3 edges) (nth 1 edges) 1))
4803 py vs last-line) 4805 py vs last-line)
4804 (if (> (mod wslines 1.0) 0.0) 4806 (if (> (mod wslines 1.0) 0.0)
4805 (setq wslines (round (+ wslines 0.5)))) 4807 (setq wslines (round (+ wslines 0.5))))
@@ -4848,7 +4850,7 @@ The value is a floating-point number."
4848 nil) 4850 nil)
4849 ;; If cursor is not in the bottom scroll margin, and the 4851 ;; If cursor is not in the bottom scroll margin, and the
4850 ;; current line is is not too tall, move forward. 4852 ;; current line is is not too tall, move forward.
4851 ((and (or (null this-height) (<= this-height dlh)) 4853 ((and (or (null this-height) (<= this-height winh))
4852 vpos 4854 vpos
4853 (> vpos 0) 4855 (> vpos 0)
4854 (< py last-line)) 4856 (< py last-line))
@@ -4865,7 +4867,7 @@ The value is a floating-point number."
4865 (> vpos 0) 4867 (> vpos 0)
4866 (= py last-line)) 4868 (= py last-line))
4867 ;; Don't vscroll if the partially-visible line at window 4869 ;; Don't vscroll if the partially-visible line at window
4868 ;; bottom has the default height (a.k.a. "just one more text 4870 ;; bottom is not too tall (a.k.a. "just one more text
4869 ;; line"): in that case, we do want redisplay to behave 4871 ;; line"): in that case, we do want redisplay to behave
4870 ;; normally, i.e. recenter or whatever. 4872 ;; normally, i.e. recenter or whatever.
4871 ;; 4873 ;;
@@ -4874,7 +4876,7 @@ The value is a floating-point number."
4874 ;; partially-visible glyph row at the end of the window. As 4876 ;; partially-visible glyph row at the end of the window. As
4875 ;; we are dealing with floats, we disregard sub-pixel 4877 ;; we are dealing with floats, we disregard sub-pixel
4876 ;; discrepancies between that and DLH. 4878 ;; discrepancies between that and DLH.
4877 (if (and rowh rbot (>= (- (+ rowh rbot) dlh) 1)) 4879 (if (and rowh rbot (>= (- (+ rowh rbot) winh) 1))
4878 (set-window-vscroll nil dlh t)) 4880 (set-window-vscroll nil dlh t))
4879 (line-move-1 arg noerror to-end) 4881 (line-move-1 arg noerror to-end)
4880 t) 4882 t)
@@ -4918,10 +4920,13 @@ The value is a floating-point number."
4918 ;; If we moved into a tall line, set vscroll to make 4920 ;; If we moved into a tall line, set vscroll to make
4919 ;; scrolling through tall images more smooth. 4921 ;; scrolling through tall images more smooth.
4920 (let ((lh (line-pixel-height)) 4922 (let ((lh (line-pixel-height))
4921 (dlh (default-line-height))) 4923 (edges (window-inside-pixel-edges))
4924 (dlh (default-line-height))
4925 winh)
4926 (setq winh (- (nth 3 edges) (nth 1 edges) 1))
4922 (if (and (< arg 0) 4927 (if (and (< arg 0)
4923 (< (point) (window-start)) 4928 (< (point) (window-start))
4924 (> lh dlh)) 4929 (> lh winh))
4925 (set-window-vscroll 4930 (set-window-vscroll
4926 nil 4931 nil
4927 (- lh dlh) t)))) 4932 (- lh dlh) t))))
@@ -7437,19 +7442,19 @@ warning using STRING as the message.")
7437 7442
7438;;; Generic dispatcher commands 7443;;; Generic dispatcher commands
7439 7444
7440;; Macro `alternatives-define' is used to create generic commands. 7445;; Macro `define-alternatives' is used to create generic commands.
7441;; Generic commands are these (like web, mail, news, encrypt, irc, etc.) 7446;; Generic commands are these (like web, mail, news, encrypt, irc, etc.)
7442;; that can have different alternative implementations where choosing 7447;; that can have different alternative implementations where choosing
7443;; among them is exclusively a matter of user preference. 7448;; among them is exclusively a matter of user preference.
7444 7449
7445;; (alternatives-define COMMAND) creates a new interactive command 7450;; (define-alternatives COMMAND) creates a new interactive command
7446;; M-x COMMAND and a customizable variable COMMAND-alternatives. 7451;; M-x COMMAND and a customizable variable COMMAND-alternatives.
7447;; Typically, the user will not need to customize this variable; packages 7452;; Typically, the user will not need to customize this variable; packages
7448;; wanting to add alternative implementations should use 7453;; wanting to add alternative implementations should use
7449;; 7454;;
7450;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives 7455;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives
7451 7456
7452(defmacro alternatives-define (command &rest customizations) 7457(defmacro define-alternatives (command &rest customizations)
7453 "Define new command `COMMAND'. 7458 "Define new command `COMMAND'.
7454The variable `COMMAND-alternatives' will contain alternative 7459The variable `COMMAND-alternatives' will contain alternative
7455implementations of COMMAND, so that running `C-u M-x COMMAND' 7460implementations of COMMAND, so that running `C-u M-x COMMAND'
diff --git a/lisp/subr.el b/lisp/subr.el
index b6ee96f879e..75c6b3a0620 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3529,7 +3529,7 @@ likely to have undesired semantics.")
3529;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical 3529;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical
3530;; expression leads to the equivalent implementation that if SEPARATORS 3530;; expression leads to the equivalent implementation that if SEPARATORS
3531;; is defaulted, OMIT-NULLS is treated as t. 3531;; is defaulted, OMIT-NULLS is treated as t.
3532(defun split-string (string &optional separators omit-nulls) 3532(defun split-string (string &optional separators omit-nulls trim)
3533 "Split STRING into substrings bounded by matches for SEPARATORS. 3533 "Split STRING into substrings bounded by matches for SEPARATORS.
3534 3534
3535The beginning and end of STRING, and each match for SEPARATORS, are 3535The beginning and end of STRING, and each match for SEPARATORS, are
@@ -3547,17 +3547,50 @@ that for the default value of SEPARATORS leading and trailing whitespace
3547are effectively trimmed). If nil, all zero-length substrings are retained, 3547are effectively trimmed). If nil, all zero-length substrings are retained,
3548which correctly parses CSV format, for example. 3548which correctly parses CSV format, for example.
3549 3549
3550If TRIM is non-nil, it should be a regular expression to match
3551text to trim from the beginning and end of each substring. If trimming
3552makes the substring empty, it is treated as null.
3553
3554If you want to trim whitespace from the substrings, the reliably correct
3555way is using TRIM. Making SEPARATORS match that whitespace gives incorrect
3556results when there is whitespace at the start or end of STRING. If you
3557see such calls to `split-string', please fix them.
3558
3550Note that the effect of `(split-string STRING)' is the same as 3559Note that the effect of `(split-string STRING)' is the same as
3551`(split-string STRING split-string-default-separators t)'. In the rare 3560`(split-string STRING split-string-default-separators t)'. In the rare
3552case that you wish to retain zero-length substrings when splitting on 3561case that you wish to retain zero-length substrings when splitting on
3553whitespace, use `(split-string STRING split-string-default-separators)'. 3562whitespace, use `(split-string STRING split-string-default-separators)'.
3554 3563
3555Modifies the match data; use `save-match-data' if necessary." 3564Modifies the match data; use `save-match-data' if necessary."
3556 (let ((keep-nulls (not (if separators omit-nulls t))) 3565 (let* ((keep-nulls (not (if separators omit-nulls t)))
3557 (rexp (or separators split-string-default-separators)) 3566 (rexp (or separators split-string-default-separators))
3558 (start 0) 3567 (start 0)
3559 notfirst 3568 this-start this-end
3560 (list nil)) 3569 notfirst
3570 (list nil)
3571 (push-one
3572 ;; Push the substring in range THIS-START to THIS-END
3573 ;; onto LIST, trimming it and perhaps discarding it.
3574 (lambda ()
3575 (when trim
3576 ;; Discard the trim from start of this substring.
3577 (let ((tem (string-match trim string this-start)))
3578 (and (eq tem this-start)
3579 (setq this-start (match-end 0)))))
3580
3581 (when (or keep-nulls (< this-start this-end))
3582 (let ((this (substring string this-start this-end)))
3583
3584 ;; Discard the trim from end of this substring.
3585 (when trim
3586 (let ((tem (string-match (concat trim "\\'") this 0)))
3587 (and tem (< tem (length this))
3588 (setq this (substring this 0 tem)))))
3589
3590 ;; Trimming could make it empty; check again.
3591 (when (or keep-nulls (> (length this) 0))
3592 (push this list)))))))
3593
3561 (while (and (string-match rexp string 3594 (while (and (string-match rexp string
3562 (if (and notfirst 3595 (if (and notfirst
3563 (= start (match-beginning 0)) 3596 (= start (match-beginning 0))
@@ -3565,15 +3598,15 @@ Modifies the match data; use `save-match-data' if necessary."
3565 (1+ start) start)) 3598 (1+ start) start))
3566 (< start (length string))) 3599 (< start (length string)))
3567 (setq notfirst t) 3600 (setq notfirst t)
3568 (if (or keep-nulls (< start (match-beginning 0))) 3601 (setq this-start start this-end (match-beginning 0)
3569 (setq list 3602 start (match-end 0))
3570 (cons (substring string start (match-beginning 0)) 3603
3571 list))) 3604 (funcall push-one))
3572 (setq start (match-end 0))) 3605
3573 (if (or keep-nulls (< start (length string))) 3606 ;; Handle the substring at the end of STRING.
3574 (setq list 3607 (setq this-start start this-end (length string))
3575 (cons (substring string start) 3608 (funcall push-one)
3576 list))) 3609
3577 (nreverse list))) 3610 (nreverse list)))
3578 3611
3579(defun combine-and-quote-strings (strings &optional separator) 3612(defun combine-and-quote-strings (strings &optional separator)
diff --git a/src/ChangeLog b/src/ChangeLog
index 6ee0cacb520..a63e441dcb2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,414 @@
12013-07-19 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix some minor file descriptor leaks and related glitches.
4 * filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC.
5 (create_lock_file): Use write, not emacs_write.
6 * image.c (slurp_file, png_load_body):
7 * process.c (Fnetwork_interface_list, Fnetwork_interface_info)
8 (server_accept_connection):
9 Don't leak an fd on memory allocation failure.
10 * image.c (slurp_file): Add a cheap heuristic for growing files.
11 * xfaces.c (Fx_load_color_file): Block input around the fopen too,
12 as that's what the other routines do. Maybe input need not be
13 blocked at all, but it's better to be consistent.
14 Avoid undefined behavior when strlen is zero.
15
16 * alloc.c (staticpro): Avoid buffer overrun on repeated calls.
17 (NSTATICS): Now a constant; doesn't need to be a macro.
18
192013-07-19 Richard Stallman <rms@gnu.org>
20
21 * coding.c (decode_coding_utf_8): Add simple loop for fast
22 processing of ASCII characters.
23
242013-07-19 Paul Eggert <eggert@cs.ucla.edu>
25
26 * conf_post.h (RE_TRANSLATE_P) [emacs]: Remove obsolete optimization.
27
282013-07-19 Eli Zaretskii <eliz@gnu.org>
29
30 * keyboard.c (kbd_buffer_get_event): Use Display_Info instead of
31 unportable 'struct x_display_info'.
32 (DISPLAY_LIST_INFO): Delete macro: not needed, since Display_Info
33 is a portable type.
34
352013-07-19 Paul Eggert <eggert@cs.ucla.edu>
36
37 * sysdep.c [GNU_LINUX]: Fix fd and memory leaks and similar issues.
38 (procfs_ttyname): Don't use uninitialized storage if emacs_fopen
39 or fscanf fails.
40 (system_process_attributes): Prefer plain char to unsigned char
41 when either will do. Clean up properly if interrupted or if
42 memory allocations fail. Don't assume sscanf succeeds. Remove
43 no-longer-needed workaround to stop GCC from whining. Read
44 command-line once, instead of multiple times. Check read status a
45 bit more carefully.
46
47 Fix obscure porting bug with varargs functions.
48 The code assumed that int is treated like ptrdiff_t in a vararg
49 function, which is not a portable assumption. There was a similar
50 -- though these days less likely -- porting problem with various
51 assumptions that pointers of different types all smell the same as
52 far as vararg functions is conserved. To make this problem less
53 likely in the future, redo the API to use varargs functions.
54 * alloc.c (make_save_value): Remove this vararg function.
55 All uses changed to ...
56 (make_save_int_int_int, make_save_obj_obj_obj_obj)
57 (make_save_ptr_int, make_save_funcptr_ptr_obj, make_save_memory):
58 New functions.
59 (make_save_ptr): Rename from make_save_pointer, for consistency with
60 the above. Define only on platforms that need it. All uses changed.
61
622013-07-18 Paul Eggert <eggert@cs.ucla.edu>
63
64 * keyboard.c: Try to fix typos in previous change.
65 (DISPLAY_LIST_INFO): New macro.
66 (kbd_buffer_get_event): Do not access members that are not present
67 in X11. Revert inadvertent change of "!=" to "=".
68
692013-07-18 Juanma Barranquero <lekktu@gmail.com>
70
71 * keyboard.c (kbd_buffer_get_event):
72 * w32term.c (x_focus_changed): Port FOCUS_(IN|OUT)_EVENT changes to W32.
73 Followup to 2013-07-16T11:41:06Z!jan.h.d@swipnet.se.
74
752013-07-18 Paul Eggert <eggert@cs.ucla.edu>
76
77 * filelock.c: Fix unlikely file descriptor leaks.
78 (get_boot_time_1): Rework to avoid using emacs_open.
79 This doesn't actually fix a leak, but is better anyway.
80 (read_lock_data): Use read, not emacs_read.
81
82 * doc.c: Fix minor memory and file descriptor leaks.
83 * doc.c (get_doc_string): Fix memory leak when doc file absent.
84 (get_doc_string, Fsnarf_documentation):
85 Fix file descriptor leak on error.
86
87 * term.c: Fix minor fdopen-related file descriptor leaks.
88 * term.c (Fresume_tty) [!MSDOS]: Close fd if fdopen (fd) fails.
89 (init_tty) [!DOS_NT]: Likewise. Also close fd if isatty (fd) fails.
90
91 * charset.c: Fix file descriptor leaks and errno issues.
92 Include <errno.h>.
93 (load_charset_map_from_file): Don't leak file descriptor on error.
94 Use plain record_xmalloc since the allocation is larger than
95 MAX_ALLOCA; that's simpler here. Simplify test for exhaustion
96 of entries.
97 * eval.c (record_unwind_protect_nothing):
98 * fileio.c (fclose_unwind):
99 New functions.
100 * lread.c (load_unwind): Remove. All uses replaced by fclose_unwind.
101 The replacement doesn't block input, but that no longer seems
102 necessary.
103
1042013-07-17 Paul Eggert <eggert@cs.ucla.edu>
105
106 * lread.c: Fix file descriptor leaks and errno issues.
107 (Fload): Close some races that leaked fds or streams when 'load'
108 was interrupted.
109 (Fload, openp): Report error number of last nontrivial failure to open.
110 ENOENT counts as trivial.
111 * eval.c (do_nothing, clear_unwind_protect, set_unwind_protect_ptr):
112 New functions.
113 * fileio.c (close_file_unwind): No need to test whether FD is nonnegative,
114 now that the function is always called with a nonnegative arg.
115 * lisp.h (set_unwind_protect_ptr, set_unwind_protect_int): Remove.
116 All uses replaced with ...
117 (clear_unwind_protect, set_unwind_protect_ptr): New decls.
118
119 A few more minor file errno-reporting bugs.
120 * callproc.c (Fcall_process):
121 * doc.c (Fsnarf_documentation):
122 * fileio.c (Frename_file, Fadd_name_to_file, Fmake_symbolic_link):
123 * process.c (set_socket_option):
124 Don't let a constructor trash errno.
125 * doc.c: Include <errno.h>.
126
1272013-07-16 Juanma Barranquero <lekktu@gmail.com>
128
129 * w32fns.c (unwind_create_tip_frame): Fix declaration.
130
1312013-07-16 Paul Eggert <eggert@cs.ucla.edu>
132
133 Fix w32 bug with call-process-region (Bug#14885).
134 * callproc.c (Fcall_process_region): Pass nil, not "/dev/null",
135 to Fcall_process when the input is empty. This simplifies the
136 code a bit. It makes no difference on POSIXish platforms but
137 apparently it fixes a bug on w32.
138
139 Fix bug where insert-file-contents closes a file twice. (Bug#14839).
140 * fileio.c (close_file_unwind): Don't close if FD is negative;
141 this can happen when unwinding a zapped file descriptor.
142 (Finsert_file_contents): Unwind-protect the fd before the point marker,
143 in case Emacs runs out of memory between the two unwind-protects.
144 Don't trash errno when closing FD.
145 Zap the FD in the specpdl when closing it, instead of deferring
146 the removal of the unwind-protect; this fixes a bug where a child
147 function unwinds the stack past us.
148
149 New unwind-protect flavors to better type-check C callbacks.
150 This also lessens the need to write wrappers for callbacks,
151 and the need for make_save_pointer.
152 * alloca.c (free_save_value):
153 * atimer.c (run_all_atimers):
154 Now extern.
155 * alloc.c (safe_alloca_unwind):
156 * atimer.c (unwind_stop_other_atimers):
157 * keyboard.c (cancel_hourglass_unwind) [HAVE_WINDOW_SYSTEM]:
158 * menu.c (cleanup_popup_menu) [HAVE_NS]:
159 * minibuf.c (choose_minibuf_frame_1):
160 * process.c (make_serial_process_unwind):
161 * xdisp.h (pop_message_unwind):
162 * xselect.c (queue_selection_requests_unwind):
163 Remove no-longer-needed wrapper. All uses replaced by the wrappee.
164 * alloca.c (record_xmalloc):
165 Prefer record_unwind_protect_ptr to record_unwind_protect with
166 make_save_pointer.
167 * alloca.c (Fgarbage_collect):
168 Prefer record_unwind_protect_void to passing a dummy.
169 * buffer.c (restore_buffer):
170 * window.c (restore_window_configuration):
171 * xfns.c, w32fns.c (do_unwind_create_frame)
172 New wrapper. All record-unwind uses of wrappee changed.
173 * buffer.c (set_buffer_if_live):
174 * callproc.c (call_process_cleanup, delete_temp_file):
175 * coding.c (code_conversion_restore):
176 * dired.c (directory_files_internal_w32_unwind) [WINDOWSNT]:
177 * editfns.c (save_excursion_restore)
178 (subst_char_in_region_unwind, subst_char_in_region_unwind_1)
179 (save_restriction_restore):
180 * eval.c (restore_stack_limits, un_autoload):
181 * fns.c (require_unwind):
182 * keyboard.c (recursive_edit_unwind, tracking_off):
183 * lread.c (record_load_unwind, load_warn_old_style_backquotes):
184 * macros.c (pop_kbd_macro, restore_menu_items):
185 * nsfns.m (unwind_create_frame):
186 * print.c (print_unwind):
187 * process.c (start_process_unwind):
188 * search.c (unwind_set_match_data):
189 * window.c (select_window_norecord, select_frame_norecord):
190 * xdisp.c (unwind_with_echo_area_buffer, unwind_format_mode_line)
191 (fast_set_selected_frame):
192 * xfns.c, w32fns.c (unwind_create_tip_frame):
193 Return void, not a dummy Lisp_Object. All uses changed.
194 * buffer.h (set_buffer_if_live): Move decl here from lisp.h.
195 * callproc.c (call_process_kill):
196 * fileio.c (restore_point_unwind, decide_coding_unwind)
197 (build_annotations_unwind):
198 * insdel.c (Fcombine_after_change_execute_1):
199 * keyboard.c (read_char_help_form_unwind):
200 * menu.c (unuse_menu_items):
201 * minibuf.c (run_exit_minibuf_hook, read_minibuf_unwind):
202 * sound.c (sound_cleanup):
203 * xdisp.c (unwind_redisplay):
204 * xfns.c (clean_up_dialog):
205 * xselect.c (x_selection_request_lisp_error, x_catch_errors_unwind):
206 Accept no args and return void, instead of accepting and returning
207 a dummy Lisp_Object. All uses changed.
208 * cygw32.c (fchdir_unwind):
209 * fileio.c (close_file_unwind):
210 * keyboard.c (restore_kboard_configuration):
211 * lread.c (readevalllop_1):
212 * process.c (wait_reading_process_output_unwind):
213 Accept int and return void, rather than accepting an Emacs integer
214 and returning a dummy object. In some cases this fixes an
215 unlikely bug when the corresponding int is outside Emacs integer
216 range. All uses changed.
217 * dired.c (directory_files_internal_unwind):
218 * fileio.c (do_auto_save_unwind):
219 * gtkutil.c (pop_down_dialog):
220 * insdel.c (reset_var_on_error):
221 * lread.c (load_unwind):
222 * xfns.c (clean_up_file_dialog):
223 * xmenu.c, nsmenu.m (pop_down_menu):
224 * xmenu.c (cleanup_widget_value_tree):
225 * xselect.c (wait_for_property_change_unwind):
226 Accept pointer and return void, rather than accepting an Emacs
227 save value encapsulating the pointer and returning a dummy object.
228 All uses changed.
229 * editfns.c (Fformat): Update the saved pointer directly via
230 set_unwind_protect_ptr rather than indirectly via make_save_pointer.
231 * eval.c (specpdl_func): Remove. All uses replaced by definiens.
232 (unwind_body): New function.
233 (record_unwind_protect): First arg is now a function returning void,
234 not a dummy Lisp_Object.
235 (record_unwind_protect_ptr, record_unwind_protect_int)
236 (record_unwind_protect_void): New functions.
237 (unbind_to): Support SPECPDL_UNWIND_PTR etc.
238 * fileio.c (struct auto_save_unwind): New type.
239 (do_auto_save_unwind): Use it.
240 (do_auto_save_unwind_1): Remove; subsumed by new do_auto_save_unwind.
241 * insdel.c (struct rvoe_arg): New type.
242 (reset_var_on_error): Use it.
243 * lisp.h (SPECPDL_UNWIND_PTR, SPECPDL_UNWIND_INT, SPECPDL_UNWIND_VOID):
244 New constants.
245 (specbinding_func): Remove; there are now several such functions.
246 (union specbinding): New members unwind_ptr, unwind_int, unwind_void.
247 (set_unwind_protect_ptr): New function.
248 * xselect.c: Remove unnecessary forward decls, to simplify maintenance.
249
250 Be simpler and more consistent about reporting I/O errors.
251 * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
252 Say "Read error" and "Write error", rather than "I/O error", or
253 "IO error reading", or "IO error writing", when a read or write
254 error occurs.
255 * process.c (Fmake_network_process, wait_reading_process_output)
256 (send_process, Fprocess_send_eof, wait_reading_process_output):
257 Capitalize diagnostics consistently. Put "failed foo" at the
258 start of the diagnostic, so that we don't capitalize the
259 function name "foo". Consistently say "failed" for such
260 diagnostics.
261 * sysdep.c, w32.c (serial_open): Now accepts Lisp string, not C string.
262 All callers changed. This is so it can use report_file_error.
263 * sysdep.c (serial_open, serial_configure): Capitalize I/O
264 diagnostics consistently as above.
265
266 * fileio.c (report_file_errno): Fix errno reporting bug.
267 If the file name is neither null nor a pair, package it up as a
268 singleton list. All callers changed, both to this function and to
269 report_file_error. This fixes a bug where the memory allocator
270 invoked by list1 set errno so that the immediately following
271 report_file_error reported the wrong errno value.
272
273 Fix minor problems found by --enable-gcc-warnings.
274 * frame.c (Fhandle_focus_in, Fhandle_focus_out): Return a value.
275 * keyboard.c (kbd_buffer_get_event): Remove unused local.
276
2772013-07-16 Jan Djärv <jan.h.d@swipnet.se>
278
279 * xterm.c (x_focus_changed): Always generate FOCUS_IN_EVENT.
280 Set event->arg to Qt if switch-event shall be generated.
281 Generate FOCUS_OUT_EVENT for FocusOut if this is the focused frame.
282
283 * termhooks.h (enum event_kind): Add FOCUS_OUT_EVENT.
284
285 * nsterm.m (windowDidResignKey): If this is the focused frame, generate
286 FOCUS_OUT_EVENT.
287
288 * keyboard.c (Qfocus_in, Qfocus_out): New static objects.
289 (make_lispy_focus_in, make_lispy_focus_out): Declare and define.
290 (kbd_buffer_get_event): For FOCUS_IN, make a focus_in event if no
291 switch frame event is made. Check ! NILP (event->arg) if X11 (moved
292 from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11
293 and there is a focused frame.
294 (head_table): Add focus-in and focus-out.
295 (keys_of_keyboard): Add focus-in and focus-out to Vspecial_event_map,
296 bind to handle-focus-in/out.
297
298 * frame.c (Fhandle_focus_in, Fhandle_focus_out): New functions.
299 (Fhandle_switch_frame): Call Fhandle_focus_in.
300 (syms_of_frame): defsubr handle-focus-in/out.
301
3022013-07-16 Paul Eggert <eggert@cs.ucla.edu>
303
304 Fix porting bug to older POSIXish platforms (Bug#14862).
305 * sysdep.c (emacs_pipe): New function, that implements
306 pipe2 (fd, O_CLOEXEC) even on hosts that lack O_CLOEXEC.
307 This should port better to CentOS 5 and to Mac OS X 10.6.
308 All calls to pipe2 changed.
309
310 Prefer list1 (X) to Fcons (X, Qnil) when building lists.
311 This makes the code easier to read and the executable a bit smaller.
312 Do not replace all calls to Fcons that happen to create lists,
313 just calls that are intended to create lists. For example, when
314 creating an alist that maps FOO to nil, use list1 (Fcons (FOO, Qnil))
315 rather than list1 (list1 (FOO)) or Fcons (Fcons (FOO, Qnil), Qnil).
316 Similarly for list2 through list5.
317 * buffer.c (Fget_buffer_create, Fmake_indirect_buffer):
318 * bytecode.c (exec_byte_code):
319 * callint.c (quotify_arg, Fcall_interactively):
320 * callproc.c (Fcall_process, create_temp_file):
321 * charset.c (load_charset_map_from_file)
322 (Fdefine_charset_internal, init_charset):
323 * coding.c (get_translation_table, detect_coding_system)
324 (Fcheck_coding_systems_region)
325 (Fset_terminal_coding_system_internal)
326 (Fdefine_coding_system_internal, Fdefine_coding_system_alias):
327 * composite.c (update_compositions, Ffind_composition_internal):
328 * dired.c (directory_files_internal, file_name_completion)
329 (Fsystem_users):
330 * dispnew.c (Fopen_termscript, bitch_at_user, init_display):
331 * doc.c (Fsnarf_documentation):
332 * editfns.c (Fmessage_box):
333 * emacs.c (main):
334 * eval.c (do_debug_on_call, signal_error, maybe_call_debugger)
335 (Feval, eval_sub, Ffuncall, apply_lambda):
336 * fileio.c (make_temp_name, Fcopy_file, Faccess_file)
337 (Fset_file_selinux_context, Fset_file_acl, Fset_file_modes)
338 (Fset_file_times, Finsert_file_contents)
339 (Fchoose_write_coding_system, Fwrite_region):
340 * fns.c (Flax_plist_put, Fyes_or_no_p, syms_of_fns):
341 * font.c (font_registry_charsets, font_parse_fcname)
342 (font_prepare_cache, font_update_drivers, Flist_fonts):
343 * fontset.c (Fset_fontset_font, Ffontset_info, syms_of_fontset):
344 * frame.c (make_frame, Fmake_terminal_frame)
345 (x_set_frame_parameters, x_report_frame_params)
346 (x_default_parameter, Fx_parse_geometry):
347 * ftfont.c (syms_of_ftfont):
348 * image.c (gif_load):
349 * keyboard.c (command_loop_1):
350 * keymap.c (Fmake_keymap, Fmake_sparse_keymap, access_keymap_1)
351 (Fcopy_keymap, append_key, Fcurrent_active_maps)
352 (Fminor_mode_key_binding, accessible_keymaps_1)
353 (Faccessible_keymaps, Fwhere_is_internal):
354 * lread.c (read_emacs_mule_char):
355 * menu.c (find_and_return_menu_selection):
356 * minibuf.c (get_minibuffer):
357 * nsfns.m (Fns_perform_service):
358 * nsfont.m (ns_script_to_charset):
359 * nsmenu.m (ns_popup_dialog):
360 * nsselect.m (ns_get_local_selection, ns_string_from_pasteboard)
361 (Fx_own_selection_internal):
362 * nsterm.m (append2):
363 * print.c (Fredirect_debugging_output)
364 (print_prune_string_charset):
365 * process.c (Fdelete_process, Fprocess_contact)
366 (Fformat_network_address, set_socket_option)
367 (read_and_dispose_of_process_output, write_queue_push)
368 (send_process, exec_sentinel):
369 * sound.c (Fplay_sound_internal):
370 * textprop.c (validate_plist, add_properties)
371 (Fput_text_property, Fadd_face_text_property)
372 (copy_text_properties, text_property_list, syms_of_textprop):
373 * unexaix.c (report_error):
374 * unexcoff.c (report_error):
375 * unexsol.c (unexec):
376 * xdisp.c (redisplay_tool_bar, store_mode_line_string)
377 (Fformat_mode_line, syms_of_xdisp):
378 * xfaces.c (set_font_frame_param)
379 (Finternal_lisp_face_attribute_values)
380 (Finternal_merge_in_global_face, syms_of_xfaces):
381 * xfns.c (x_default_scroll_bar_color_parameter)
382 (x_default_font_parameter, x_create_tip_frame):
383 * xfont.c (xfont_supported_scripts):
384 * xmenu.c (Fx_popup_dialog, xmenu_show, xdialog_show)
385 (menu_help_callback, xmenu_show):
386 * xml.c (make_dom):
387 * xterm.c (set_wm_state):
388 Prefer list1 (FOO) to Fcons (FOO, Qnil) when creating a list,
389 and similarly for list2 through list5.
390
3912013-07-15 Paul Eggert <eggert@cs.ucla.edu>
392
393 * callproc.c (Fcall_process_region): Fix minor race and tune.
394 (create_temp_file): New function, with the temp-file-creation part
395 of the old Fcall_process_region. Use Fcopy_sequence to create the
396 temp file name, rather than alloca + build_string, for simplicity.
397 Don't bother to block input around the temp file creation;
398 shouldn't be needed. Simplify use of mktemp. Use
399 record_unwind_protect immediately after creating the temp file;
400 this closes an unlikely race where the temp file was not removed.
401 Use memcpy rather than an open-coded loop.
402 (Fcall_process_region): Use the new function. If the input is
403 empty, redirect from /dev/null rather than from a newly created
404 empty temp file; this avoids unnecessary file system traffic.
405
12013-07-14 Paul Eggert <eggert@cs.ucla.edu> 4062013-07-14 Paul Eggert <eggert@cs.ucla.edu>
2 407
408 * filelock.c (create_lock_file) [!HAVE_MKOSTEMP && !HAVE_MKSTEMP]:
409 Simplify by making this case like the other two. This is a bit
410 slower on obsolete hosts, but the extra complexity isn't worth it.
411
3 * callproc.c (child_setup, relocate_fd) [!DOS_NT]: 412 * callproc.c (child_setup, relocate_fd) [!DOS_NT]:
4 * process.c (create_process) [!DOS_NT]: 413 * process.c (create_process) [!DOS_NT]:
5 Remove now-unnecessary calls to emacs_close. 414 Remove now-unnecessary calls to emacs_close.
diff --git a/src/alloc.c b/src/alloc.c
index b71cdb98d78..4c924f72384 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -209,7 +209,6 @@ Lisp_Object Qchar_table_extra_slots;
209 209
210static Lisp_Object Qpost_gc_hook; 210static Lisp_Object Qpost_gc_hook;
211 211
212static void free_save_value (Lisp_Object);
213static void mark_terminals (void); 212static void mark_terminals (void);
214static void gc_sweep (void); 213static void gc_sweep (void);
215static Lisp_Object make_pure_vector (ptrdiff_t); 214static Lisp_Object make_pure_vector (ptrdiff_t);
@@ -342,7 +341,7 @@ struct gcpro *gcprolist;
342/* Addresses of staticpro'd variables. Initialize it to a nonzero 341/* Addresses of staticpro'd variables. Initialize it to a nonzero
343 value; otherwise some compilers put it into BSS. */ 342 value; otherwise some compilers put it into BSS. */
344 343
345#define NSTATICS 0x800 344enum { NSTATICS = 2048 };
346static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; 345static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
347 346
348/* Index of next unused slot in staticvec. */ 347/* Index of next unused slot in staticvec. */
@@ -813,22 +812,13 @@ xputenv (char const *string)
813 memory_full (0); 812 memory_full (0);
814} 813}
815 814
816/* Unwind for SAFE_ALLOCA */
817
818Lisp_Object
819safe_alloca_unwind (Lisp_Object arg)
820{
821 free_save_value (arg);
822 return Qnil;
823}
824
825/* Return a newly allocated memory block of SIZE bytes, remembering 815/* Return a newly allocated memory block of SIZE bytes, remembering
826 to free it when unwinding. */ 816 to free it when unwinding. */
827void * 817void *
828record_xmalloc (size_t size) 818record_xmalloc (size_t size)
829{ 819{
830 void *p = xmalloc (size); 820 void *p = xmalloc (size);
831 record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); 821 record_unwind_protect_ptr (xfree, p);
832 return p; 822 return p;
833} 823}
834 824
@@ -3352,67 +3342,88 @@ verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT)
3352 >> SAVE_SLOT_BITS) 3342 >> SAVE_SLOT_BITS)
3353 == 0); 3343 == 0);
3354 3344
3355/* Return a Lisp_Save_Value object with the data saved according to 3345/* Return Lisp_Save_Value objects for the various combinations
3356 DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ 3346 that callers need. */
3357 3347
3358Lisp_Object 3348Lisp_Object
3359make_save_value (enum Lisp_Save_Type save_type, ...) 3349make_save_int_int_int (ptrdiff_t a, ptrdiff_t b, ptrdiff_t c)
3360{ 3350{
3361 va_list ap;
3362 int i;
3363 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3351 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3364 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3352 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3353 p->save_type = SAVE_TYPE_INT_INT_INT;
3354 p->data[0].integer = a;
3355 p->data[1].integer = b;
3356 p->data[2].integer = c;
3357 return val;
3358}
3365 3359
3366 eassert (0 < save_type 3360Lisp_Object
3367 && (save_type < 1 << (SAVE_TYPE_BITS - 1) 3361make_save_obj_obj_obj_obj (Lisp_Object a, Lisp_Object b, Lisp_Object c,
3368 || save_type == SAVE_TYPE_MEMORY)); 3362 Lisp_Object d)
3369 p->save_type = save_type; 3363{
3370 va_start (ap, save_type); 3364 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3371 save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); 3365 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3372 3366 p->save_type = SAVE_TYPE_OBJ_OBJ_OBJ_OBJ;
3373 for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) 3367 p->data[0].object = a;
3374 switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) 3368 p->data[1].object = b;
3375 { 3369 p->data[2].object = c;
3376 case SAVE_POINTER: 3370 p->data[3].object = d;
3377 p->data[i].pointer = va_arg (ap, void *); 3371 return val;
3378 break; 3372}
3379
3380 case SAVE_FUNCPOINTER:
3381 p->data[i].funcpointer = va_arg (ap, voidfuncptr);
3382 break;
3383
3384 case SAVE_INTEGER:
3385 p->data[i].integer = va_arg (ap, ptrdiff_t);
3386 break;
3387 3373
3388 case SAVE_OBJECT: 3374#if defined HAVE_NS || defined DOS_NT
3389 p->data[i].object = va_arg (ap, Lisp_Object); 3375Lisp_Object
3390 break; 3376make_save_ptr (void *a)
3377{
3378 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3379 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3380 p->save_type = SAVE_POINTER;
3381 p->data[0].pointer = a;
3382 return val;
3383}
3384#endif
3391 3385
3392 default: 3386Lisp_Object
3393 emacs_abort (); 3387make_save_ptr_int (void *a, ptrdiff_t b)
3394 } 3388{
3389 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3390 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3391 p->save_type = SAVE_TYPE_PTR_INT;
3392 p->data[0].pointer = a;
3393 p->data[1].integer = b;
3394 return val;
3395}
3395 3396
3396 va_end (ap); 3397Lisp_Object
3398make_save_funcptr_ptr_obj (void (*a) (void), void *b, Lisp_Object c)
3399{
3400 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3401 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3402 p->save_type = SAVE_TYPE_FUNCPTR_PTR_OBJ;
3403 p->data[0].funcpointer = a;
3404 p->data[1].pointer = b;
3405 p->data[2].object = c;
3397 return val; 3406 return val;
3398} 3407}
3399 3408
3400/* The most common task it to save just one C pointer. */ 3409/* Return a Lisp_Save_Value object that represents an array A
3410 of N Lisp objects. */
3401 3411
3402Lisp_Object 3412Lisp_Object
3403make_save_pointer (void *pointer) 3413make_save_memory (Lisp_Object *a, ptrdiff_t n)
3404{ 3414{
3405 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3415 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3406 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3416 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3407 p->save_type = SAVE_POINTER; 3417 p->save_type = SAVE_TYPE_MEMORY;
3408 p->data[0].pointer = pointer; 3418 p->data[0].pointer = a;
3419 p->data[1].integer = n;
3409 return val; 3420 return val;
3410} 3421}
3411 3422
3412/* Free a Lisp_Save_Value object. Do not use this function 3423/* Free a Lisp_Save_Value object. Do not use this function
3413 if SAVE contains pointer other than returned by xmalloc. */ 3424 if SAVE contains pointer other than returned by xmalloc. */
3414 3425
3415static void 3426void
3416free_save_value (Lisp_Object save) 3427free_save_value (Lisp_Object save)
3417{ 3428{
3418 xfree (XSAVE_POINTER (save, 0)); 3429 xfree (XSAVE_POINTER (save, 0));
@@ -4741,7 +4752,7 @@ valid_pointer_p (void *p)
4741 Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may 4752 Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may
4742 not validate p in that case. */ 4753 not validate p in that case. */
4743 4754
4744 if (pipe2 (fd, O_CLOEXEC) == 0) 4755 if (emacs_pipe (fd) == 0)
4745 { 4756 {
4746 bool valid = emacs_write (fd[1], (char *) p, 16) == 16; 4757 bool valid = emacs_write (fd[1], (char *) p, 16) == 16;
4747 emacs_close (fd[1]); 4758 emacs_close (fd[1]);
@@ -5125,9 +5136,9 @@ Does not copy symbols. Copies strings without text properties. */)
5125void 5136void
5126staticpro (Lisp_Object *varaddress) 5137staticpro (Lisp_Object *varaddress)
5127{ 5138{
5128 staticvec[staticidx++] = varaddress;
5129 if (staticidx >= NSTATICS) 5139 if (staticidx >= NSTATICS)
5130 fatal ("NSTATICS too small; try increasing and recompiling Emacs."); 5140 fatal ("NSTATICS too small; try increasing and recompiling Emacs.");
5141 staticvec[staticidx++] = varaddress;
5131} 5142}
5132 5143
5133 5144
@@ -5227,7 +5238,7 @@ See Info node `(elisp)Garbage Collection'. */)
5227 5238
5228 /* Save what's currently displayed in the echo area. */ 5239 /* Save what's currently displayed in the echo area. */
5229 message_p = push_message (); 5240 message_p = push_message ();
5230 record_unwind_protect (pop_message_unwind, Qnil); 5241 record_unwind_protect_void (pop_message_unwind);
5231 5242
5232 /* Save a copy of the contents of the stack, for debugging. */ 5243 /* Save a copy of the contents of the stack, for debugging. */
5233#if MAX_SAVE_STACK > 0 5244#if MAX_SAVE_STACK > 0
diff --git a/src/atimer.c b/src/atimer.c
index bb5294670d3..219b3502acc 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -250,7 +250,7 @@ stop_other_atimers (struct atimer *t)
250/* Run all timers again, if some have been stopped with a call to 250/* Run all timers again, if some have been stopped with a call to
251 stop_other_atimers. */ 251 stop_other_atimers. */
252 252
253static void 253void
254run_all_atimers (void) 254run_all_atimers (void)
255{ 255{
256 if (stopped_atimers) 256 if (stopped_atimers)
@@ -274,16 +274,6 @@ run_all_atimers (void)
274} 274}
275 275
276 276
277/* A version of run_all_atimers suitable for a record_unwind_protect. */
278
279Lisp_Object
280unwind_stop_other_atimers (Lisp_Object dummy)
281{
282 run_all_atimers ();
283 return Qnil;
284}
285
286
287/* Arrange for a SIGALRM to arrive when the next timer is ripe. */ 277/* Arrange for a SIGALRM to arrive when the next timer is ripe. */
288 278
289static void 279static void
diff --git a/src/atimer.h b/src/atimer.h
index 2a92f1bebea..a1825fc0933 100644
--- a/src/atimer.h
+++ b/src/atimer.h
@@ -77,6 +77,6 @@ void do_pending_atimers (void);
77void init_atimer (void); 77void init_atimer (void);
78void turn_on_atimers (bool); 78void turn_on_atimers (bool);
79void stop_other_atimers (struct atimer *); 79void stop_other_atimers (struct atimer *);
80Lisp_Object unwind_stop_other_atimers (Lisp_Object); 80void run_all_atimers (void);
81 81
82#endif /* EMACS_ATIMER_H */ 82#endif /* EMACS_ATIMER_H */
diff --git a/src/buffer.c b/src/buffer.c
index 44371144687..063e02e8f6c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -617,7 +617,7 @@ even if it is dead. The return value is never nil. */)
617 617
618 /* Put this in the alist of all live buffers. */ 618 /* Put this in the alist of all live buffers. */
619 XSETBUFFER (buffer, b); 619 XSETBUFFER (buffer, b);
620 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil)); 620 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
621 /* And run buffer-list-update-hook. */ 621 /* And run buffer-list-update-hook. */
622 if (!NILP (Vrun_hooks)) 622 if (!NILP (Vrun_hooks))
623 call1 (Vrun_hooks, Qbuffer_list_update_hook); 623 call1 (Vrun_hooks, Qbuffer_list_update_hook);
@@ -828,7 +828,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
828 828
829 /* Put this in the alist of all live buffers. */ 829 /* Put this in the alist of all live buffers. */
830 XSETBUFFER (buf, b); 830 XSETBUFFER (buf, b);
831 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); 831 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buf)));
832 832
833 bset_mark (b, Fmake_marker ()); 833 bset_mark (b, Fmake_marker ());
834 834
@@ -2215,14 +2215,19 @@ ends when the current command terminates. Use `switch-to-buffer' or
2215 return buffer; 2215 return buffer;
2216} 2216}
2217 2217
2218void
2219restore_buffer (Lisp_Object buffer_or_name)
2220{
2221 Fset_buffer (buffer_or_name);
2222}
2223
2218/* Set the current buffer to BUFFER provided if it is alive. */ 2224/* Set the current buffer to BUFFER provided if it is alive. */
2219 2225
2220Lisp_Object 2226void
2221set_buffer_if_live (Lisp_Object buffer) 2227set_buffer_if_live (Lisp_Object buffer)
2222{ 2228{
2223 if (BUFFER_LIVE_P (XBUFFER (buffer))) 2229 if (BUFFER_LIVE_P (XBUFFER (buffer)))
2224 set_buffer_internal (XBUFFER (buffer)); 2230 set_buffer_internal (XBUFFER (buffer));
2225 return Qnil;
2226} 2231}
2227 2232
2228DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only, 2233DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
diff --git a/src/buffer.h b/src/buffer.h
index 276cca32e48..641a561cafc 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1073,6 +1073,8 @@ extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object);
1073extern void record_buffer (Lisp_Object); 1073extern void record_buffer (Lisp_Object);
1074extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t); 1074extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
1075extern void mmap_set_vars (bool); 1075extern void mmap_set_vars (bool);
1076extern void restore_buffer (Lisp_Object);
1077extern void set_buffer_if_live (Lisp_Object);
1076 1078
1077/* Set the current buffer to B. 1079/* Set the current buffer to B.
1078 1080
diff --git a/src/bytecode.c b/src/bytecode.c
index c79027597f8..e0e7b22ea13 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -572,9 +572,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
572 if (nargs < mandatory) 572 if (nargs < mandatory)
573 /* Too few arguments. */ 573 /* Too few arguments. */
574 Fsignal (Qwrong_number_of_arguments, 574 Fsignal (Qwrong_number_of_arguments,
575 Fcons (Fcons (make_number (mandatory), 575 list2 (Fcons (make_number (mandatory),
576 rest ? Qand_rest : make_number (nonrest)), 576 rest ? Qand_rest : make_number (nonrest)),
577 Fcons (make_number (nargs), Qnil))); 577 make_number (nargs)));
578 else 578 else
579 { 579 {
580 for (; i < nonrest; i++) 580 for (; i < nonrest; i++)
@@ -593,9 +593,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
593 else 593 else
594 /* Too many arguments. */ 594 /* Too many arguments. */
595 Fsignal (Qwrong_number_of_arguments, 595 Fsignal (Qwrong_number_of_arguments,
596 Fcons (Fcons (make_number (mandatory), 596 list2 (Fcons (make_number (mandatory), make_number (nonrest)),
597 make_number (nonrest)), 597 make_number (nargs)));
598 Fcons (make_number (nargs), Qnil)));
599 } 598 }
600 else if (! NILP (args_template)) 599 else if (! NILP (args_template))
601 /* We should push some arguments on the stack. */ 600 /* We should push some arguments on the stack. */
@@ -1064,8 +1063,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1064 1063
1065 CASE (Bsave_window_excursion): /* Obsolete since 24.1. */ 1064 CASE (Bsave_window_excursion): /* Obsolete since 24.1. */
1066 { 1065 {
1067 register ptrdiff_t count1 = SPECPDL_INDEX (); 1066 ptrdiff_t count1 = SPECPDL_INDEX ();
1068 record_unwind_protect (Fset_window_configuration, 1067 record_unwind_protect (restore_window_configuration,
1069 Fcurrent_window_configuration (Qnil)); 1068 Fcurrent_window_configuration (Qnil));
1070 BEFORE_POTENTIAL_GC (); 1069 BEFORE_POTENTIAL_GC ();
1071 TOP = Fprogn (TOP); 1070 TOP = Fprogn (TOP);
@@ -1090,7 +1089,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1090 } 1089 }
1091 1090
1092 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */ 1091 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
1093 record_unwind_protect (Fprogn, POP); 1092 record_unwind_protect (unwind_body, POP);
1094 NEXT; 1093 NEXT;
1095 1094
1096 CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */ 1095 CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */
@@ -1172,14 +1171,14 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1172 } 1171 }
1173 1172
1174 CASE (Blist1): 1173 CASE (Blist1):
1175 TOP = Fcons (TOP, Qnil); 1174 TOP = list1 (TOP);
1176 NEXT; 1175 NEXT;
1177 1176
1178 CASE (Blist2): 1177 CASE (Blist2):
1179 { 1178 {
1180 Lisp_Object v1; 1179 Lisp_Object v1;
1181 v1 = POP; 1180 v1 = POP;
1182 TOP = Fcons (TOP, Fcons (v1, Qnil)); 1181 TOP = list2 (TOP, v1);
1183 NEXT; 1182 NEXT;
1184 } 1183 }
1185 1184
diff --git a/src/callint.c b/src/callint.c
index 0651b68dc05..38431226508 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -127,7 +127,7 @@ quotify_arg (register Lisp_Object exp)
127 if (CONSP (exp) 127 if (CONSP (exp)
128 || (SYMBOLP (exp) 128 || (SYMBOLP (exp)
129 && !NILP (exp) && !EQ (exp, Qt))) 129 && !NILP (exp) && !EQ (exp, Qt)))
130 return Fcons (Qquote, Fcons (exp, Qnil)); 130 return list2 (Qquote, exp);
131 131
132 return exp; 132 return exp;
133} 133}
@@ -802,7 +802,7 @@ invoke it. If KEYS is omitted or nil, the return value of
802 for (i = 1; i < nargs; i++) 802 for (i = 1; i < nargs; i++)
803 { 803 {
804 if (varies[i] > 0) 804 if (varies[i] > 0)
805 visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil); 805 visargs[i] = list1 (intern (callint_argfuns[varies[i]]));
806 else 806 else
807 visargs[i] = quotify_arg (args[i]); 807 visargs[i] = quotify_arg (args[i]);
808 } 808 }
diff --git a/src/callproc.c b/src/callproc.c
index cdf92422b4d..e0040ada609 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -123,8 +123,8 @@ record_kill_process (struct Lisp_Process *p)
123 123
124/* Clean up when exiting call_process_cleanup. */ 124/* Clean up when exiting call_process_cleanup. */
125 125
126static Lisp_Object 126static void
127call_process_kill (Lisp_Object ignored) 127call_process_kill (void)
128{ 128{
129 if (synch_process_fd >= 0) 129 if (synch_process_fd >= 0)
130 emacs_close (synch_process_fd); 130 emacs_close (synch_process_fd);
@@ -136,15 +136,13 @@ call_process_kill (Lisp_Object ignored)
136 proc.pid = synch_process_pid; 136 proc.pid = synch_process_pid;
137 record_kill_process (&proc); 137 record_kill_process (&proc);
138 } 138 }
139
140 return Qnil;
141} 139}
142 140
143/* Clean up when exiting Fcall_process. 141/* Clean up when exiting Fcall_process.
144 On MSDOS, delete the temporary file on any kind of termination. 142 On MSDOS, delete the temporary file on any kind of termination.
145 On Unix, kill the process and any children on termination by signal. */ 143 On Unix, kill the process and any children on termination by signal. */
146 144
147static Lisp_Object 145static void
148call_process_cleanup (Lisp_Object arg) 146call_process_cleanup (Lisp_Object arg)
149{ 147{
150#ifdef MSDOS 148#ifdef MSDOS
@@ -162,7 +160,7 @@ call_process_cleanup (Lisp_Object arg)
162 { 160 {
163 ptrdiff_t count = SPECPDL_INDEX (); 161 ptrdiff_t count = SPECPDL_INDEX ();
164 kill (-synch_process_pid, SIGINT); 162 kill (-synch_process_pid, SIGINT);
165 record_unwind_protect (call_process_kill, make_number (0)); 163 record_unwind_protect_void (call_process_kill);
166 message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); 164 message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
167 immediate_quit = 1; 165 immediate_quit = 1;
168 QUIT; 166 QUIT;
@@ -183,8 +181,6 @@ call_process_cleanup (Lisp_Object arg)
183 if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) 181 if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
184 unlink (SDATA (file)); 182 unlink (SDATA (file));
185#endif 183#endif
186
187 return Qnil;
188} 184}
189 185
190#ifdef DOS_NT 186#ifdef DOS_NT
@@ -392,7 +388,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
392 388
393 if (NILP (Ffile_accessible_directory_p (current_dir))) 389 if (NILP (Ffile_accessible_directory_p (current_dir)))
394 report_file_error ("Setting current directory", 390 report_file_error ("Setting current directory",
395 Fcons (BVAR (current_buffer, directory), Qnil)); 391 BVAR (current_buffer, directory));
396 392
397 if (STRING_MULTIBYTE (infile)) 393 if (STRING_MULTIBYTE (infile))
398 infile = ENCODE_FILE (infile); 394 infile = ENCODE_FILE (infile);
@@ -409,8 +405,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
409 405
410 filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); 406 filefd = emacs_open (SSDATA (infile), O_RDONLY, 0);
411 if (filefd < 0) 407 if (filefd < 0)
412 report_file_error ("Opening process input file", 408 {
413 Fcons (DECODE_FILE (infile), Qnil)); 409 int open_errno = errno;
410 report_file_errno ("Opening process input file", DECODE_FILE (infile),
411 open_errno);
412 }
414 413
415 if (STRINGP (output_file)) 414 if (STRINGP (output_file))
416 { 415 {
@@ -422,7 +421,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
422 int open_errno = errno; 421 int open_errno = errno;
423 output_file = DECODE_FILE (output_file); 422 output_file = DECODE_FILE (output_file);
424 report_file_errno ("Opening process output file", 423 report_file_errno ("Opening process output file",
425 Fcons (output_file, Qnil), open_errno); 424 output_file, open_errno);
426 } 425 }
427 if (STRINGP (error_file) || NILP (error_file)) 426 if (STRINGP (error_file) || NILP (error_file))
428 output_to_buffer = 0; 427 output_to_buffer = 0;
@@ -440,8 +439,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
440 { 439 {
441 int openp_errno = errno; 440 int openp_errno = errno;
442 emacs_close (filefd); 441 emacs_close (filefd);
443 report_file_errno ("Searching for program", 442 report_file_errno ("Searching for program", args[0], openp_errno);
444 Fcons (args[0], Qnil), openp_errno);
445 } 443 }
446 } 444 }
447 445
@@ -506,7 +504,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
506 int open_errno = errno; 504 int open_errno = errno;
507 emacs_close (filefd); 505 emacs_close (filefd);
508 report_file_errno ("Opening process output file", 506 report_file_errno ("Opening process output file",
509 Fcons (build_string (tempfile), Qnil), open_errno); 507 build_string (tempfile), open_errno);
510 } 508 }
511 } 509 }
512 else 510 else
@@ -524,7 +522,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
524 { 522 {
525#ifndef MSDOS 523#ifndef MSDOS
526 int fd[2]; 524 int fd[2];
527 if (pipe2 (fd, O_CLOEXEC) != 0) 525 if (emacs_pipe (fd) != 0)
528 { 526 {
529 int pipe_errno = errno; 527 int pipe_errno = errno;
530 emacs_close (filefd); 528 emacs_close (filefd);
@@ -563,8 +561,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
563 error_file = build_string (NULL_DEVICE); 561 error_file = build_string (NULL_DEVICE);
564 else if (STRINGP (error_file)) 562 else if (STRINGP (error_file))
565 error_file = DECODE_FILE (error_file); 563 error_file = DECODE_FILE (error_file);
566 report_file_errno ("Cannot redirect stderr", 564 report_file_errno ("Cannot redirect stderr", error_file, open_errno);
567 Fcons (error_file, Qnil), open_errno);
568 } 565 }
569 566
570#ifdef MSDOS /* MW, July 1993 */ 567#ifdef MSDOS /* MW, July 1993 */
@@ -596,8 +593,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
596 unlink (tempfile); 593 unlink (tempfile);
597 emacs_close (filefd); 594 emacs_close (filefd);
598 report_file_errno ("Cannot re-open temporary file", 595 report_file_errno ("Cannot re-open temporary file",
599 Fcons (build_string (tempfile), Qnil), 596 build_string (tempfile), open_errno);
600 open_errno);
601 } 597 }
602 } 598 }
603 else 599 else
@@ -935,7 +931,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
935 return make_number (WEXITSTATUS (status)); 931 return make_number (WEXITSTATUS (status));
936} 932}
937 933
938static Lisp_Object 934static void
939delete_temp_file (Lisp_Object name) 935delete_temp_file (Lisp_Object name)
940{ 936{
941 /* Suppress jka-compr handling, etc. */ 937 /* Suppress jka-compr handling, etc. */
@@ -957,44 +953,18 @@ delete_temp_file (Lisp_Object name)
957 internal_delete_file (name); 953 internal_delete_file (name);
958#endif 954#endif
959 unbind_to (count, Qnil); 955 unbind_to (count, Qnil);
960 return Qnil;
961} 956}
962 957
963DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, 958/* Create a temporary file suitable for storing the input data of
964 3, MANY, 0, 959 call-process-region. NARGS and ARGS are the same as for
965 doc: /* Send text from START to END to a synchronous process running PROGRAM. 960 call-process-region. */
966The remaining arguments are optional.
967Delete the text if fourth arg DELETE is non-nil.
968 961
969Insert output in BUFFER before point; t means current buffer; nil for 962static Lisp_Object
970 BUFFER means discard it; 0 means discard and don't wait; and `(:file 963create_temp_file (ptrdiff_t nargs, Lisp_Object *args)
971 FILE)', where FILE is a file name string, means that it should be
972 written to that file (if the file already exists it is overwritten).
973BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
974REAL-BUFFER says what to do with standard output, as above,
975while STDERR-FILE says what to do with standard error in the child.
976STDERR-FILE may be nil (discard standard error output),
977t (mix it with ordinary output), or a file name string.
978
979Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.
980Remaining args are passed to PROGRAM at startup as command args.
981
982If BUFFER is 0, `call-process-region' returns immediately with value nil.
983Otherwise it waits for PROGRAM to terminate
984and returns a numeric exit status or a signal description string.
985If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
986
987usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */)
988 (ptrdiff_t nargs, Lisp_Object *args)
989{ 964{
990 struct gcpro gcpro1; 965 struct gcpro gcpro1;
991 Lisp_Object filename_string; 966 Lisp_Object filename_string;
992 register Lisp_Object start, end; 967 Lisp_Object val, start, end;
993 ptrdiff_t count = SPECPDL_INDEX ();
994 /* Qt denotes we have not yet called Ffind_operation_coding_system. */
995 Lisp_Object coding_systems;
996 Lisp_Object val, *args2;
997 ptrdiff_t i;
998 Lisp_Object tmpdir; 968 Lisp_Object tmpdir;
999 969
1000 if (STRINGP (Vtemporary_file_directory)) 970 if (STRINGP (Vtemporary_file_directory))
@@ -1016,9 +986,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1016 } 986 }
1017 987
1018 { 988 {
1019 USE_SAFE_ALLOCA;
1020 Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); 989 Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
1021 Lisp_Object encoded_tem;
1022 char *tempfile; 990 char *tempfile;
1023 991
1024#ifdef WINDOWSNT 992#ifdef WINDOWSNT
@@ -1036,39 +1004,30 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1036 } 1004 }
1037#endif 1005#endif
1038 1006
1039 encoded_tem = ENCODE_FILE (pattern); 1007 filename_string = Fcopy_sequence (ENCODE_FILE (pattern));
1040 tempfile = SAFE_ALLOCA (SBYTES (encoded_tem) + 1); 1008 GCPRO1 (filename_string);
1041 memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); 1009 tempfile = SSDATA (filename_string);
1042 coding_systems = Qt;
1043 1010
1044#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
1045 { 1011 {
1046 int fd, open_errno; 1012 int fd;
1047 1013
1048 block_input (); 1014#ifdef HAVE_MKOSTEMP
1049# ifdef HAVE_MKOSTEMP
1050 fd = mkostemp (tempfile, O_CLOEXEC); 1015 fd = mkostemp (tempfile, O_CLOEXEC);
1051# else 1016#elif defined HAVE_MKSTEMP
1052 fd = mkstemp (tempfile); 1017 fd = mkstemp (tempfile);
1053# endif 1018#else
1054 open_errno = errno; 1019 errno = EEXIST;
1055 unblock_input (); 1020 mktemp (tempfile);
1021 /* INT_MAX denotes success, because close (INT_MAX) does nothing. */
1022 fd = *tempfile ? INT_MAX : -1;
1023#endif
1056 if (fd < 0) 1024 if (fd < 0)
1057 report_file_errno ("Failed to open temporary file", 1025 report_file_error ("Failed to open temporary file using pattern",
1058 Fcons (build_string (tempfile), Qnil), open_errno); 1026 pattern);
1059 emacs_close (fd); 1027 emacs_close (fd);
1060 } 1028 }
1061#else
1062 errno = EEXIST;
1063 mktemp (tempfile);
1064 if (!*tempfile)
1065 report_file_error ("Failed to open temporary file using pattern",
1066 Fcons (pattern, Qnil));
1067#endif
1068 1029
1069 filename_string = build_string (tempfile); 1030 record_unwind_protect (delete_temp_file, filename_string);
1070 GCPRO1 (filename_string);
1071 SAFE_FREE ();
1072 } 1031 }
1073 1032
1074 start = args[0]; 1033 start = args[0];
@@ -1080,10 +1039,12 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1080 val = Qraw_text; 1039 val = Qraw_text;
1081 else 1040 else
1082 { 1041 {
1042 Lisp_Object coding_systems;
1043 Lisp_Object *args2;
1083 USE_SAFE_ALLOCA; 1044 USE_SAFE_ALLOCA;
1084 SAFE_NALLOCA (args2, 1, nargs + 1); 1045 SAFE_NALLOCA (args2, 1, nargs + 1);
1085 args2[0] = Qcall_process_region; 1046 args2[0] = Qcall_process_region;
1086 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1047 memcpy (args2 + 1, args, nargs * sizeof *args);
1087 coding_systems = Ffind_operation_coding_system (nargs + 1, args2); 1048 coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
1088 val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil; 1049 val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil;
1089 SAFE_FREE (); 1050 SAFE_FREE ();
@@ -1105,7 +1066,57 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1105 /* Note that Fcall_process takes care of binding 1066 /* Note that Fcall_process takes care of binding
1106 coding-system-for-read. */ 1067 coding-system-for-read. */
1107 1068
1108 record_unwind_protect (delete_temp_file, filename_string); 1069 RETURN_UNGCPRO (filename_string);
1070}
1071
1072DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
1073 3, MANY, 0,
1074 doc: /* Send text from START to END to a synchronous process running PROGRAM.
1075The remaining arguments are optional.
1076Delete the text if fourth arg DELETE is non-nil.
1077
1078Insert output in BUFFER before point; t means current buffer; nil for
1079 BUFFER means discard it; 0 means discard and don't wait; and `(:file
1080 FILE)', where FILE is a file name string, means that it should be
1081 written to that file (if the file already exists it is overwritten).
1082BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
1083REAL-BUFFER says what to do with standard output, as above,
1084while STDERR-FILE says what to do with standard error in the child.
1085STDERR-FILE may be nil (discard standard error output),
1086t (mix it with ordinary output), or a file name string.
1087
1088Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.
1089Remaining args are passed to PROGRAM at startup as command args.
1090
1091If BUFFER is 0, `call-process-region' returns immediately with value nil.
1092Otherwise it waits for PROGRAM to terminate
1093and returns a numeric exit status or a signal description string.
1094If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
1095
1096usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */)
1097 (ptrdiff_t nargs, Lisp_Object *args)
1098{
1099 struct gcpro gcpro1;
1100 Lisp_Object infile;
1101 ptrdiff_t count = SPECPDL_INDEX ();
1102 Lisp_Object start = args[0];
1103 Lisp_Object end = args[1];
1104 bool empty_input;
1105
1106 if (STRINGP (start))
1107 empty_input = SCHARS (start) == 0;
1108 else if (NILP (start))
1109 empty_input = BEG == Z;
1110 else
1111 {
1112 validate_region (&args[0], &args[1]);
1113 start = args[0];
1114 end = args[1];
1115 empty_input = XINT (start) == XINT (end);
1116 }
1117
1118 infile = empty_input ? Qnil : create_temp_file (nargs, args);
1119 GCPRO1 (infile);
1109 1120
1110 if (nargs > 3 && !NILP (args[3])) 1121 if (nargs > 3 && !NILP (args[3]))
1111 Fdelete_region (start, end); 1122 Fdelete_region (start, end);
@@ -1120,7 +1131,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1120 args[0] = args[2]; 1131 args[0] = args[2];
1121 nargs = 2; 1132 nargs = 2;
1122 } 1133 }
1123 args[1] = filename_string; 1134 args[1] = infile;
1124 1135
1125 RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); 1136 RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args)));
1126} 1137}
diff --git a/src/charset.c b/src/charset.c
index fdb8eebde8b..eedf65faa6c 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -28,6 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28 28
29#define CHARSET_INLINE EXTERN_INLINE 29#define CHARSET_INLINE EXTERN_INLINE
30 30
31#include <errno.h>
31#include <stdio.h> 32#include <stdio.h>
32#include <unistd.h> 33#include <unistd.h>
33#include <limits.h> 34#include <limits.h>
@@ -477,7 +478,8 @@ read_hex (FILE *fp, bool *eof, bool *overflow)
477 `file-name-handler-alist' to avoid running any Lisp code. */ 478 `file-name-handler-alist' to avoid running any Lisp code. */
478 479
479static void 480static void
480load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int control_flag) 481load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
482 int control_flag)
481{ 483{
482 unsigned min_code = CHARSET_MIN_CODE (charset); 484 unsigned min_code = CHARSET_MIN_CODE (charset);
483 unsigned max_code = CHARSET_MAX_CODE (charset); 485 unsigned max_code = CHARSET_MAX_CODE (charset);
@@ -487,22 +489,26 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
487 struct charset_map_entries *head, *entries; 489 struct charset_map_entries *head, *entries;
488 int n_entries; 490 int n_entries;
489 ptrdiff_t count; 491 ptrdiff_t count;
490 USE_SAFE_ALLOCA;
491 492
492 suffixes = Fcons (build_string (".map"), 493 suffixes = list2 (build_string (".map"), build_string (".TXT"));
493 Fcons (build_string (".TXT"), Qnil));
494 494
495 count = SPECPDL_INDEX (); 495 count = SPECPDL_INDEX ();
496 record_unwind_protect_nothing ();
496 specbind (Qfile_name_handler_alist, Qnil); 497 specbind (Qfile_name_handler_alist, Qnil);
497 fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil); 498 fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil);
498 unbind_to (count, Qnil); 499 fp = fd < 0 ? 0 : fdopen (fd, "r");
499 if (fd < 0 500 if (!fp)
500 || ! (fp = fdopen (fd, "r"))) 501 {
501 error ("Failure in loading charset map: %s", SDATA (mapfile)); 502 int open_errno = errno;
503 emacs_close (fd);
504 report_file_errno ("Loading charset map", mapfile, open_errno);
505 }
506 set_unwind_protect_ptr (count, fclose_unwind, fp);
507 unbind_to (count + 1, Qnil);
502 508
503 /* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is 509 /* Use record_xmalloc, as `charset_map_entries' is
504 large (larger than MAX_ALLOCA). */ 510 large (larger than MAX_ALLOCA). */
505 head = SAFE_ALLOCA (sizeof *head); 511 head = record_xmalloc (sizeof *head);
506 entries = head; 512 entries = head;
507 memset (entries, 0, sizeof (struct charset_map_entries)); 513 memset (entries, 0, sizeof (struct charset_map_entries));
508 514
@@ -531,9 +537,9 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
531 if (from < min_code || to > max_code || from > to || c > MAX_CHAR) 537 if (from < min_code || to > max_code || from > to || c > MAX_CHAR)
532 continue; 538 continue;
533 539
534 if (n_entries > 0 && (n_entries % 0x10000) == 0) 540 if (n_entries == 0x10000)
535 { 541 {
536 entries->next = SAFE_ALLOCA (sizeof *entries->next); 542 entries->next = record_xmalloc (sizeof *entries->next);
537 entries = entries->next; 543 entries = entries->next;
538 memset (entries, 0, sizeof (struct charset_map_entries)); 544 memset (entries, 0, sizeof (struct charset_map_entries));
539 n_entries = 0; 545 n_entries = 0;
@@ -545,9 +551,10 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
545 n_entries++; 551 n_entries++;
546 } 552 }
547 fclose (fp); 553 fclose (fp);
554 clear_unwind_protect (count);
548 555
549 load_charset_map (charset, head, n_entries, control_flag); 556 load_charset_map (charset, head, n_entries, control_flag);
550 SAFE_FREE (); 557 unbind_to (count, Qnil);
551} 558}
552 559
553static void 560static void
@@ -1178,7 +1185,7 @@ usage: (define-charset-internal ...) */)
1178 charset.iso_final) = id; 1185 charset.iso_final) = id;
1179 if (new_definition_p) 1186 if (new_definition_p)
1180 Viso_2022_charset_list = nconc2 (Viso_2022_charset_list, 1187 Viso_2022_charset_list = nconc2 (Viso_2022_charset_list,
1181 Fcons (make_number (id), Qnil)); 1188 list1 (make_number (id)));
1182 if (ISO_CHARSET_TABLE (1, 0, 'J') == id) 1189 if (ISO_CHARSET_TABLE (1, 0, 'J') == id)
1183 charset_jisx0201_roman = id; 1190 charset_jisx0201_roman = id;
1184 else if (ISO_CHARSET_TABLE (2, 0, '@') == id) 1191 else if (ISO_CHARSET_TABLE (2, 0, '@') == id)
@@ -1198,7 +1205,7 @@ usage: (define-charset-internal ...) */)
1198 emacs_mule_bytes[charset.emacs_mule_id] = charset.dimension + 2; 1205 emacs_mule_bytes[charset.emacs_mule_id] = charset.dimension + 2;
1199 if (new_definition_p) 1206 if (new_definition_p)
1200 Vemacs_mule_charset_list = nconc2 (Vemacs_mule_charset_list, 1207 Vemacs_mule_charset_list = nconc2 (Vemacs_mule_charset_list,
1201 Fcons (make_number (id), Qnil)); 1208 list1 (make_number (id)));
1202 } 1209 }
1203 1210
1204 if (new_definition_p) 1211 if (new_definition_p)
@@ -1206,7 +1213,7 @@ usage: (define-charset-internal ...) */)
1206 Vcharset_list = Fcons (args[charset_arg_name], Vcharset_list); 1213 Vcharset_list = Fcons (args[charset_arg_name], Vcharset_list);
1207 if (charset.supplementary_p) 1214 if (charset.supplementary_p)
1208 Vcharset_ordered_list = nconc2 (Vcharset_ordered_list, 1215 Vcharset_ordered_list = nconc2 (Vcharset_ordered_list,
1209 Fcons (make_number (id), Qnil)); 1216 list1 (make_number (id)));
1210 else 1217 else
1211 { 1218 {
1212 Lisp_Object tail; 1219 Lisp_Object tail;
@@ -1223,7 +1230,7 @@ usage: (define-charset-internal ...) */)
1223 Vcharset_ordered_list); 1230 Vcharset_ordered_list);
1224 else if (NILP (tail)) 1231 else if (NILP (tail))
1225 Vcharset_ordered_list = nconc2 (Vcharset_ordered_list, 1232 Vcharset_ordered_list = nconc2 (Vcharset_ordered_list,
1226 Fcons (make_number (id), Qnil)); 1233 list1 (make_number (id)));
1227 else 1234 else
1228 { 1235 {
1229 val = Fcons (XCAR (tail), XCDR (tail)); 1236 val = Fcons (XCAR (tail), XCDR (tail));
@@ -2308,7 +2315,7 @@ Please check your installation!\n",
2308 exit (1); 2315 exit (1);
2309 } 2316 }
2310 2317
2311 Vcharset_map_path = Fcons (tempdir, Qnil); 2318 Vcharset_map_path = list1 (tempdir);
2312} 2319}
2313 2320
2314 2321
diff --git a/src/coding.c b/src/coding.c
index a1494ad38aa..385a22a188d 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -1363,6 +1363,45 @@ decode_coding_utf_8 (struct coding_system *coding)
1363 break; 1363 break;
1364 } 1364 }
1365 1365
1366 /* In the simple case, rapidly handle ordinary characters */
1367 if (multibytep && ! eol_dos
1368 && charbuf < charbuf_end - 6 && src < src_end - 6)
1369 {
1370 while (charbuf < charbuf_end - 6 && src < src_end - 6)
1371 {
1372 c1 = *src;
1373 if (c1 & 0x80)
1374 break;
1375 src++;
1376 consumed_chars++;
1377 *charbuf++ = c1;
1378
1379 c1 = *src;
1380 if (c1 & 0x80)
1381 break;
1382 src++;
1383 consumed_chars++;
1384 *charbuf++ = c1;
1385
1386 c1 = *src;
1387 if (c1 & 0x80)
1388 break;
1389 src++;
1390 consumed_chars++;
1391 *charbuf++ = c1;
1392
1393 c1 = *src;
1394 if (c1 & 0x80)
1395 break;
1396 src++;
1397 consumed_chars++;
1398 *charbuf++ = c1;
1399 }
1400 /* If we handled at least one character, restart the main loop. */
1401 if (src != src_base)
1402 continue;
1403 }
1404
1366 if (byte_after_cr >= 0) 1405 if (byte_after_cr >= 0)
1367 c1 = byte_after_cr, byte_after_cr = -1; 1406 c1 = byte_after_cr, byte_after_cr = -1;
1368 else 1407 else
@@ -6864,11 +6903,9 @@ get_translation_table (Lisp_Object attrs, bool encodep, int *max_lookup)
6864 if (CHAR_TABLE_P (standard)) 6903 if (CHAR_TABLE_P (standard))
6865 { 6904 {
6866 if (CONSP (translation_table)) 6905 if (CONSP (translation_table))
6867 translation_table = nconc2 (translation_table, 6906 translation_table = nconc2 (translation_table, list1 (standard));
6868 Fcons (standard, Qnil));
6869 else 6907 else
6870 translation_table = Fcons (translation_table, 6908 translation_table = list2 (translation_table, standard);
6871 Fcons (standard, Qnil));
6872 } 6909 }
6873 } 6910 }
6874 6911
@@ -7793,7 +7830,7 @@ make_conversion_work_buffer (bool multibyte)
7793} 7830}
7794 7831
7795 7832
7796static Lisp_Object 7833static void
7797code_conversion_restore (Lisp_Object arg) 7834code_conversion_restore (Lisp_Object arg)
7798{ 7835{
7799 Lisp_Object current, workbuf; 7836 Lisp_Object current, workbuf;
@@ -7811,7 +7848,6 @@ code_conversion_restore (Lisp_Object arg)
7811 } 7848 }
7812 set_buffer_internal (XBUFFER (current)); 7849 set_buffer_internal (XBUFFER (current));
7813 UNGCPRO; 7850 UNGCPRO;
7814 return Qnil;
7815} 7851}
7816 7852
7817Lisp_Object 7853Lisp_Object
@@ -8667,20 +8703,20 @@ detect_coding_system (const unsigned char *src,
8667 { 8703 {
8668 detect_info.found = CATEGORY_MASK_RAW_TEXT; 8704 detect_info.found = CATEGORY_MASK_RAW_TEXT;
8669 id = CODING_SYSTEM_ID (Qno_conversion); 8705 id = CODING_SYSTEM_ID (Qno_conversion);
8670 val = Fcons (make_number (id), Qnil); 8706 val = list1 (make_number (id));
8671 } 8707 }
8672 else if (! detect_info.rejected && ! detect_info.found) 8708 else if (! detect_info.rejected && ! detect_info.found)
8673 { 8709 {
8674 detect_info.found = CATEGORY_MASK_ANY; 8710 detect_info.found = CATEGORY_MASK_ANY;
8675 id = coding_categories[coding_category_undecided].id; 8711 id = coding_categories[coding_category_undecided].id;
8676 val = Fcons (make_number (id), Qnil); 8712 val = list1 (make_number (id));
8677 } 8713 }
8678 else if (highest) 8714 else if (highest)
8679 { 8715 {
8680 if (detect_info.found) 8716 if (detect_info.found)
8681 { 8717 {
8682 detect_info.found = 1 << category; 8718 detect_info.found = 1 << category;
8683 val = Fcons (make_number (this->id), Qnil); 8719 val = list1 (make_number (this->id));
8684 } 8720 }
8685 else 8721 else
8686 for (i = 0; i < coding_category_raw_text; i++) 8722 for (i = 0; i < coding_category_raw_text; i++)
@@ -8688,7 +8724,7 @@ detect_coding_system (const unsigned char *src,
8688 { 8724 {
8689 detect_info.found = 1 << coding_priorities[i]; 8725 detect_info.found = 1 << coding_priorities[i];
8690 id = coding_categories[coding_priorities[i]].id; 8726 id = coding_categories[coding_priorities[i]].id;
8691 val = Fcons (make_number (id), Qnil); 8727 val = list1 (make_number (id));
8692 break; 8728 break;
8693 } 8729 }
8694 } 8730 }
@@ -8705,7 +8741,7 @@ detect_coding_system (const unsigned char *src,
8705 found |= 1 << category; 8741 found |= 1 << category;
8706 id = coding_categories[category].id; 8742 id = coding_categories[category].id;
8707 if (id >= 0) 8743 if (id >= 0)
8708 val = Fcons (make_number (id), val); 8744 val = list1 (make_number (id));
8709 } 8745 }
8710 } 8746 }
8711 for (i = coding_category_raw_text - 1; i >= 0; i--) 8747 for (i = coding_category_raw_text - 1; i >= 0; i--)
@@ -8730,7 +8766,7 @@ detect_coding_system (const unsigned char *src,
8730 this = coding_categories + coding_category_utf_8_sig; 8766 this = coding_categories + coding_category_utf_8_sig;
8731 else 8767 else
8732 this = coding_categories + coding_category_utf_8_nosig; 8768 this = coding_categories + coding_category_utf_8_nosig;
8733 val = Fcons (make_number (this->id), Qnil); 8769 val = list1 (make_number (this->id));
8734 } 8770 }
8735 } 8771 }
8736 else if (base_category == coding_category_utf_16_auto) 8772 else if (base_category == coding_category_utf_16_auto)
@@ -8747,13 +8783,13 @@ detect_coding_system (const unsigned char *src,
8747 this = coding_categories + coding_category_utf_16_be_nosig; 8783 this = coding_categories + coding_category_utf_16_be_nosig;
8748 else 8784 else
8749 this = coding_categories + coding_category_utf_16_le_nosig; 8785 this = coding_categories + coding_category_utf_16_le_nosig;
8750 val = Fcons (make_number (this->id), Qnil); 8786 val = list1 (make_number (this->id));
8751 } 8787 }
8752 } 8788 }
8753 else 8789 else
8754 { 8790 {
8755 detect_info.found = 1 << XINT (CODING_ATTR_CATEGORY (attrs)); 8791 detect_info.found = 1 << XINT (CODING_ATTR_CATEGORY (attrs));
8756 val = Fcons (make_number (coding.id), Qnil); 8792 val = list1 (make_number (coding.id));
8757 } 8793 }
8758 8794
8759 /* Then, detect eol-format if necessary. */ 8795 /* Then, detect eol-format if necessary. */
@@ -9224,7 +9260,7 @@ is nil. */)
9224 attrs = AREF (CODING_SYSTEM_SPEC (elt), 0); 9260 attrs = AREF (CODING_SYSTEM_SPEC (elt), 0);
9225 ASET (attrs, coding_attr_trans_tbl, 9261 ASET (attrs, coding_attr_trans_tbl,
9226 get_translation_table (attrs, 1, NULL)); 9262 get_translation_table (attrs, 1, NULL));
9227 list = Fcons (Fcons (elt, Fcons (attrs, Qnil)), list); 9263 list = Fcons (list2 (elt, attrs), list);
9228 } 9264 }
9229 9265
9230 if (STRINGP (start)) 9266 if (STRINGP (start))
@@ -9635,7 +9671,7 @@ DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_intern
9635 tset_charset_list 9671 tset_charset_list
9636 (term, (terminal_coding->common_flags & CODING_REQUIRE_ENCODING_MASK 9672 (term, (terminal_coding->common_flags & CODING_REQUIRE_ENCODING_MASK
9637 ? coding_charset_list (terminal_coding) 9673 ? coding_charset_list (terminal_coding)
9638 : Fcons (make_number (charset_ascii), Qnil))); 9674 : list1 (make_number (charset_ascii))));
9639 return Qnil; 9675 return Qnil;
9640} 9676}
9641 9677
@@ -10080,9 +10116,9 @@ usage: (define-coding-system-internal ...) */)
10080 { 10116 {
10081 dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp))); 10117 dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp)));
10082 if (dim < dim2) 10118 if (dim < dim2)
10083 tmp = Fcons (XCAR (tail), Fcons (tmp, Qnil)); 10119 tmp = list2 (XCAR (tail), tmp);
10084 else 10120 else
10085 tmp = Fcons (tmp, Fcons (XCAR (tail), Qnil)); 10121 tmp = list2 (tmp, XCAR (tail));
10086 } 10122 }
10087 else 10123 else
10088 { 10124 {
@@ -10093,7 +10129,7 @@ usage: (define-coding-system-internal ...) */)
10093 break; 10129 break;
10094 } 10130 }
10095 if (NILP (tmp2)) 10131 if (NILP (tmp2))
10096 tmp = nconc2 (tmp, Fcons (XCAR (tail), Qnil)); 10132 tmp = nconc2 (tmp, list1 (XCAR (tail)));
10097 else 10133 else
10098 { 10134 {
10099 XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2))); 10135 XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2)));
@@ -10411,7 +10447,7 @@ usage: (define-coding-system-internal ...) */)
10411 && ! EQ (eol_type, Qmac)) 10447 && ! EQ (eol_type, Qmac))
10412 error ("Invalid eol-type"); 10448 error ("Invalid eol-type");
10413 10449
10414 aliases = Fcons (name, Qnil); 10450 aliases = list1 (name);
10415 10451
10416 if (NILP (eol_type)) 10452 if (NILP (eol_type))
10417 { 10453 {
@@ -10421,7 +10457,7 @@ usage: (define-coding-system-internal ...) */)
10421 Lisp_Object this_spec, this_name, this_aliases, this_eol_type; 10457 Lisp_Object this_spec, this_name, this_aliases, this_eol_type;
10422 10458
10423 this_name = AREF (eol_type, i); 10459 this_name = AREF (eol_type, i);
10424 this_aliases = Fcons (this_name, Qnil); 10460 this_aliases = list1 (this_name);
10425 this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac); 10461 this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac);
10426 this_spec = make_uninit_vector (3); 10462 this_spec = make_uninit_vector (3);
10427 ASET (this_spec, 0, attrs); 10463 ASET (this_spec, 0, attrs);
@@ -10536,7 +10572,7 @@ DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias,
10536 list. */ 10572 list. */
10537 while (!NILP (XCDR (aliases))) 10573 while (!NILP (XCDR (aliases)))
10538 aliases = XCDR (aliases); 10574 aliases = XCDR (aliases);
10539 XSETCDR (aliases, Fcons (alias, Qnil)); 10575 XSETCDR (aliases, list1 (alias));
10540 10576
10541 eol_type = AREF (spec, 2); 10577 eol_type = AREF (spec, 2);
10542 if (VECTORP (eol_type)) 10578 if (VECTORP (eol_type))
diff --git a/src/composite.c b/src/composite.c
index 8b1f0171a60..99b5da22af5 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -595,7 +595,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask)
595 specbind (Qinhibit_point_motion_hooks, Qt); 595 specbind (Qinhibit_point_motion_hooks, Qt);
596 Fremove_list_of_text_properties (make_number (min_pos), 596 Fremove_list_of_text_properties (make_number (min_pos),
597 make_number (max_pos), 597 make_number (max_pos),
598 Fcons (Qauto_composed, Qnil), Qnil); 598 list1 (Qauto_composed), Qnil);
599 unbind_to (count, Qnil); 599 unbind_to (count, Qnil);
600 } 600 }
601} 601}
@@ -1873,11 +1873,9 @@ See `find-composition' for more details. */)
1873 return list3 (make_number (s), make_number (e), gstring); 1873 return list3 (make_number (s), make_number (e), gstring);
1874 } 1874 }
1875 if (!COMPOSITION_VALID_P (start, end, prop)) 1875 if (!COMPOSITION_VALID_P (start, end, prop))
1876 return Fcons (make_number (start), Fcons (make_number (end), 1876 return list3 (make_number (start), make_number (end), Qnil);
1877 Fcons (Qnil, Qnil)));
1878 if (NILP (detail_p)) 1877 if (NILP (detail_p))
1879 return Fcons (make_number (start), Fcons (make_number (end), 1878 return list3 (make_number (start), make_number (end), Qt);
1880 Fcons (Qt, Qnil)));
1881 1879
1882 if (COMPOSITION_REGISTERD_P (prop)) 1880 if (COMPOSITION_REGISTERD_P (prop))
1883 id = COMPOSITION_ID (prop); 1881 id = COMPOSITION_ID (prop);
@@ -1899,10 +1897,7 @@ See `find-composition' for more details. */)
1899 relative_p = (method == COMPOSITION_WITH_RULE_ALTCHARS 1897 relative_p = (method == COMPOSITION_WITH_RULE_ALTCHARS
1900 ? Qnil : Qt); 1898 ? Qnil : Qt);
1901 mod_func = COMPOSITION_MODIFICATION_FUNC (prop); 1899 mod_func = COMPOSITION_MODIFICATION_FUNC (prop);
1902 tail = Fcons (components, 1900 tail = list4 (components, relative_p, mod_func, make_number (width));
1903 Fcons (relative_p,
1904 Fcons (mod_func,
1905 Fcons (make_number (width), Qnil))));
1906 } 1901 }
1907 else 1902 else
1908 tail = Qnil; 1903 tail = Qnil;
diff --git a/src/conf_post.h b/src/conf_post.h
index b19456749a2..16714076f6f 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -160,13 +160,7 @@ extern void _DebPrint (const char *fmt, ...);
160/* Tell regex.c to use a type compatible with Emacs. */ 160/* Tell regex.c to use a type compatible with Emacs. */
161#define RE_TRANSLATE_TYPE Lisp_Object 161#define RE_TRANSLATE_TYPE Lisp_Object
162#define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C) 162#define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C)
163#ifdef make_number
164/* If make_number is a macro, use it. */
165#define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0))) 163#define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0)))
166#else
167/* If make_number is a function, avoid it. */
168#define RE_TRANSLATE_P(TBL) (!(INTEGERP (TBL) && XINT (TBL) == 0))
169#endif
170#endif 164#endif
171 165
172#include <string.h> 166#include <string.h>
diff --git a/src/cygw32.c b/src/cygw32.c
index bbc3a49fd88..3e0f4ae1803 100644
--- a/src/cygw32.c
+++ b/src/cygw32.c
@@ -23,12 +23,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23#include <unistd.h> 23#include <unistd.h>
24#include <fcntl.h> 24#include <fcntl.h>
25 25
26static Lisp_Object 26static void
27fchdir_unwind (Lisp_Object dir_fd) 27fchdir_unwind (int dir_fd)
28{ 28{
29 (void) fchdir (XFASTINT (dir_fd)); 29 (void) fchdir (dir_fd);
30 (void) close (XFASTINT (dir_fd)); 30 (void) close (dir_fd);
31 return Qnil;
32} 31}
33 32
34static void 33static void
@@ -40,7 +39,7 @@ chdir_to_default_directory ()
40 if (old_cwd_fd == -1) 39 if (old_cwd_fd == -1)
41 error ("could not open current directory: %s", strerror (errno)); 40 error ("could not open current directory: %s", strerror (errno));
42 41
43 record_unwind_protect (fchdir_unwind, make_number (old_cwd_fd)); 42 record_unwind_protect_int (fchdir_unwind, old_cwd_fd);
44 43
45 new_cwd = Funhandled_file_name_directory ( 44 new_cwd = Funhandled_file_name_directory (
46 Fexpand_file_name (build_string ("."), Qnil)); 45 Fexpand_file_name (build_string ("."), Qnil));
diff --git a/src/dired.c b/src/dired.c
index b3348b0aff0..2b79b54f2a4 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -107,22 +107,20 @@ open_directory (char const *name, int *fdp)
107} 107}
108 108
109#ifdef WINDOWSNT 109#ifdef WINDOWSNT
110Lisp_Object 110void
111directory_files_internal_w32_unwind (Lisp_Object arg) 111directory_files_internal_w32_unwind (Lisp_Object arg)
112{ 112{
113 Vw32_get_true_file_attributes = arg; 113 Vw32_get_true_file_attributes = arg;
114 return Qnil;
115} 114}
116#endif 115#endif
117 116
118static Lisp_Object 117static void
119directory_files_internal_unwind (Lisp_Object dh) 118directory_files_internal_unwind (void *dh)
120{ 119{
121 DIR *d = XSAVE_POINTER (dh, 0); 120 DIR *d = dh;
122 block_input (); 121 block_input ();
123 closedir (d); 122 closedir (d);
124 unblock_input (); 123 unblock_input ();
125 return Qnil;
126} 124}
127 125
128/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. 126/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
@@ -185,13 +183,12 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
185 183
186 d = open_directory (SSDATA (dirfilename), &fd); 184 d = open_directory (SSDATA (dirfilename), &fd);
187 if (d == NULL) 185 if (d == NULL)
188 report_file_error ("Opening directory", Fcons (directory, Qnil)); 186 report_file_error ("Opening directory", directory);
189 187
190 /* Unfortunately, we can now invoke expand-file-name and 188 /* Unfortunately, we can now invoke expand-file-name and
191 file-attributes on filenames, both of which can throw, so we must 189 file-attributes on filenames, both of which can throw, so we must
192 do a proper unwind-protect. */ 190 do a proper unwind-protect. */
193 record_unwind_protect (directory_files_internal_unwind, 191 record_unwind_protect_ptr (directory_files_internal_unwind, d);
194 make_save_pointer (d));
195 192
196#ifdef WINDOWSNT 193#ifdef WINDOWSNT
197 if (attrs) 194 if (attrs)
@@ -488,10 +485,9 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
488 485
489 d = open_directory (SSDATA (encoded_dir), &fd); 486 d = open_directory (SSDATA (encoded_dir), &fd);
490 if (!d) 487 if (!d)
491 report_file_error ("Opening directory", Fcons (dirname, Qnil)); 488 report_file_error ("Opening directory", dirname);
492 489
493 record_unwind_protect (directory_files_internal_unwind, 490 record_unwind_protect_ptr (directory_files_internal_unwind, d);
494 make_save_pointer (d));
495 491
496 /* Loop reading blocks */ 492 /* Loop reading blocks */
497 /* (att3b compiler bug requires do a null comparison this way) */ 493 /* (att3b compiler bug requires do a null comparison this way) */
@@ -1017,7 +1013,7 @@ return a list with one element, taken from `user-real-login-name'. */)
1017#endif 1013#endif
1018 if (EQ (users, Qnil)) 1014 if (EQ (users, Qnil))
1019 /* At least current user is always known. */ 1015 /* At least current user is always known. */
1020 users = Fcons (Vuser_real_login_name, Qnil); 1016 users = list1 (Vuser_real_login_name);
1021 return users; 1017 return users;
1022} 1018}
1023 1019
diff --git a/src/dispnew.c b/src/dispnew.c
index 7db0a46d6da..29cd90ca21a 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5630,7 +5630,7 @@ FILE = nil means just close any termscript file currently open. */)
5630 file = Fexpand_file_name (file, Qnil); 5630 file = Fexpand_file_name (file, Qnil);
5631 tty->termscript = emacs_fopen (SSDATA (file), "w"); 5631 tty->termscript = emacs_fopen (SSDATA (file), "w");
5632 if (tty->termscript == 0) 5632 if (tty->termscript == 0)
5633 report_file_error ("Opening termscript", Fcons (file, Qnil)); 5633 report_file_error ("Opening termscript", file);
5634 } 5634 }
5635 return Qnil; 5635 return Qnil;
5636} 5636}
@@ -5710,7 +5710,7 @@ bitch_at_user (void)
5710 { 5710 {
5711 const char *msg 5711 const char *msg
5712 = "Keyboard macro terminated by a command ringing the bell"; 5712 = "Keyboard macro terminated by a command ringing the bell";
5713 Fsignal (Quser_error, Fcons (build_string (msg), Qnil)); 5713 Fsignal (Quser_error, list1 (build_string (msg)));
5714 } 5714 }
5715 else 5715 else
5716 ring_bell (XFRAME (selected_frame)); 5716 ring_bell (XFRAME (selected_frame));
@@ -6138,15 +6138,14 @@ init_display (void)
6138 6138
6139 /* Update frame parameters to reflect the new type. */ 6139 /* Update frame parameters to reflect the new type. */
6140 Fmodify_frame_parameters 6140 Fmodify_frame_parameters
6141 (selected_frame, Fcons (Fcons (Qtty_type, 6141 (selected_frame, list1 (Fcons (Qtty_type,
6142 Ftty_type (selected_frame)), Qnil)); 6142 Ftty_type (selected_frame))));
6143 if (t->display_info.tty->name) 6143 if (t->display_info.tty->name)
6144 Fmodify_frame_parameters (selected_frame, 6144 Fmodify_frame_parameters
6145 Fcons (Fcons (Qtty, build_string (t->display_info.tty->name)), 6145 (selected_frame,
6146 Qnil)); 6146 list1 (Fcons (Qtty, build_string (t->display_info.tty->name))));
6147 else 6147 else
6148 Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil), 6148 Fmodify_frame_parameters (selected_frame, list1 (Fcons (Qtty, Qnil)));
6149 Qnil));
6150 } 6149 }
6151 6150
6152 { 6151 {
diff --git a/src/doc.c b/src/doc.c
index 3c5a682c001..009616f4f87 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#include <config.h> 22#include <config.h>
23 23
24#include <errno.h>
24#include <sys/types.h> 25#include <sys/types.h>
25#include <sys/file.h> /* Must be after sys/types.h for USG. */ 26#include <sys/file.h> /* Must be after sys/types.h for USG. */
26#include <fcntl.h> 27#include <fcntl.h>
@@ -84,6 +85,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
84 int offset; 85 int offset;
85 EMACS_INT position; 86 EMACS_INT position;
86 Lisp_Object file, tem, pos; 87 Lisp_Object file, tem, pos;
88 ptrdiff_t count;
87 USE_SAFE_ALLOCA; 89 USE_SAFE_ALLOCA;
88 90
89 if (INTEGERP (filepos)) 91 if (INTEGERP (filepos))
@@ -143,9 +145,14 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
143 } 145 }
144#endif 146#endif
145 if (fd < 0) 147 if (fd < 0)
146 return concat3 (build_string ("Cannot open doc string file \""), 148 {
147 file, build_string ("\"\n")); 149 SAFE_FREE ();
150 return concat3 (build_string ("Cannot open doc string file \""),
151 file, build_string ("\"\n"));
152 }
148 } 153 }
154 count = SPECPDL_INDEX ();
155 record_unwind_protect_int (close_file_unwind, fd);
149 156
150 /* Seek only to beginning of disk block. */ 157 /* Seek only to beginning of disk block. */
151 /* Make sure we read at least 1024 bytes before `position' 158 /* Make sure we read at least 1024 bytes before `position'
@@ -153,13 +160,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
153 offset = min (position, max (1024, position % (8 * 1024))); 160 offset = min (position, max (1024, position % (8 * 1024)));
154 if (TYPE_MAXIMUM (off_t) < position 161 if (TYPE_MAXIMUM (off_t) < position
155 || lseek (fd, position - offset, 0) < 0) 162 || lseek (fd, position - offset, 0) < 0)
156 { 163 error ("Position %"pI"d out of range in doc string file \"%s\"",
157 emacs_close (fd); 164 position, name);
158 error ("Position %"pI"d out of range in doc string file \"%s\"",
159 position, name);
160 }
161
162 SAFE_FREE ();
163 165
164 /* Read the doc string into get_doc_string_buffer. 166 /* Read the doc string into get_doc_string_buffer.
165 P points beyond the data just read. */ 167 P points beyond the data just read. */
@@ -189,10 +191,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
189 space_left = 1024 * 8; 191 space_left = 1024 * 8;
190 nread = emacs_read (fd, p, space_left); 192 nread = emacs_read (fd, p, space_left);
191 if (nread < 0) 193 if (nread < 0)
192 { 194 report_file_error ("Read error on documentation file", file);
193 emacs_close (fd);
194 error ("Read error on documentation file");
195 }
196 p[nread] = 0; 195 p[nread] = 0;
197 if (!nread) 196 if (!nread)
198 break; 197 break;
@@ -208,7 +207,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
208 } 207 }
209 p += nread; 208 p += nread;
210 } 209 }
211 emacs_close (fd); 210 unbind_to (count, Qnil);
211 SAFE_FREE ();
212 212
213 /* Sanity checking. */ 213 /* Sanity checking. */
214 if (CONSP (filepos)) 214 if (CONSP (filepos))
@@ -573,6 +573,7 @@ the same file name is found in the `doc-directory'. */)
573 Lisp_Object sym; 573 Lisp_Object sym;
574 char *p, *name; 574 char *p, *name;
575 bool skip_file = 0; 575 bool skip_file = 0;
576 ptrdiff_t count;
576 577
577 CHECK_STRING (filename); 578 CHECK_STRING (filename);
578 579
@@ -609,8 +610,13 @@ the same file name is found in the `doc-directory'. */)
609 610
610 fd = emacs_open (name, O_RDONLY, 0); 611 fd = emacs_open (name, O_RDONLY, 0);
611 if (fd < 0) 612 if (fd < 0)
612 report_file_error ("Opening doc string file", 613 {
613 Fcons (build_string (name), Qnil)); 614 int open_errno = errno;
615 report_file_errno ("Opening doc string file", build_string (name),
616 open_errno);
617 }
618 count = SPECPDL_INDEX ();
619 record_unwind_protect_int (close_file_unwind, fd);
614 Vdoc_file_name = filename; 620 Vdoc_file_name = filename;
615 filled = 0; 621 filled = 0;
616 pos = 0; 622 pos = 0;
@@ -688,8 +694,7 @@ the same file name is found in the `doc-directory'. */)
688 filled -= end - buf; 694 filled -= end - buf;
689 memmove (buf, end, filled); 695 memmove (buf, end, filled);
690 } 696 }
691 emacs_close (fd); 697 return unbind_to (count, Qnil);
692 return Qnil;
693} 698}
694 699
695DEFUN ("substitute-command-keys", Fsubstitute_command_keys, 700DEFUN ("substitute-command-keys", Fsubstitute_command_keys,
diff --git a/src/editfns.c b/src/editfns.c
index cc6b4cff895..50bde90788d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -838,9 +838,8 @@ This function does not move point. */)
838Lisp_Object 838Lisp_Object
839save_excursion_save (void) 839save_excursion_save (void)
840{ 840{
841 return make_save_value 841 return make_save_obj_obj_obj_obj
842 (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, 842 (Fpoint_marker (),
843 Fpoint_marker (),
844 /* Do not copy the mark if it points to nowhere. */ 843 /* Do not copy the mark if it points to nowhere. */
845 (XMARKER (BVAR (current_buffer, mark))->buffer 844 (XMARKER (BVAR (current_buffer, mark))->buffer
846 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) 845 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
@@ -853,7 +852,7 @@ save_excursion_save (void)
853 852
854/* Restore saved buffer before leaving `save-excursion' special form. */ 853/* Restore saved buffer before leaving `save-excursion' special form. */
855 854
856Lisp_Object 855void
857save_excursion_restore (Lisp_Object info) 856save_excursion_restore (Lisp_Object info)
858{ 857{
859 Lisp_Object tem, tem1, omark, nmark; 858 Lisp_Object tem, tem1, omark, nmark;
@@ -927,7 +926,6 @@ save_excursion_restore (Lisp_Object info)
927 out: 926 out:
928 927
929 free_misc (info); 928 free_misc (info);
930 return Qnil;
931} 929}
932 930
933DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0, 931DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
@@ -2809,18 +2807,16 @@ determines whether case is significant or ignored. */)
2809 return make_number (0); 2807 return make_number (0);
2810} 2808}
2811 2809
2812static Lisp_Object 2810static void
2813subst_char_in_region_unwind (Lisp_Object arg) 2811subst_char_in_region_unwind (Lisp_Object arg)
2814{ 2812{
2815 bset_undo_list (current_buffer, arg); 2813 bset_undo_list (current_buffer, arg);
2816 return arg;
2817} 2814}
2818 2815
2819static Lisp_Object 2816static void
2820subst_char_in_region_unwind_1 (Lisp_Object arg) 2817subst_char_in_region_unwind_1 (Lisp_Object arg)
2821{ 2818{
2822 bset_filename (current_buffer, arg); 2819 bset_filename (current_buffer, arg);
2823 return arg;
2824} 2820}
2825 2821
2826DEFUN ("subst-char-in-region", Fsubst_char_in_region, 2822DEFUN ("subst-char-in-region", Fsubst_char_in_region,
@@ -3331,7 +3327,7 @@ save_restriction_save (void)
3331 } 3327 }
3332} 3328}
3333 3329
3334Lisp_Object 3330void
3335save_restriction_restore (Lisp_Object data) 3331save_restriction_restore (Lisp_Object data)
3336{ 3332{
3337 struct buffer *cur = NULL; 3333 struct buffer *cur = NULL;
@@ -3398,8 +3394,6 @@ save_restriction_restore (Lisp_Object data)
3398 3394
3399 if (cur) 3395 if (cur)
3400 set_buffer_internal (cur); 3396 set_buffer_internal (cur);
3401
3402 return Qnil;
3403} 3397}
3404 3398
3405DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0, 3399DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
@@ -3492,7 +3486,7 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
3492 { 3486 {
3493 Lisp_Object pane, menu; 3487 Lisp_Object pane, menu;
3494 struct gcpro gcpro1; 3488 struct gcpro gcpro1;
3495 pane = Fcons (Fcons (build_string ("OK"), Qt), Qnil); 3489 pane = list1 (Fcons (build_string ("OK"), Qt));
3496 GCPRO1 (pane); 3490 GCPRO1 (pane);
3497 menu = Fcons (val, pane); 3491 menu = Fcons (val, pane);
3498 Fx_popup_dialog (Qt, menu, Qt); 3492 Fx_popup_dialog (Qt, menu, Qt);
@@ -3627,7 +3621,7 @@ usage: (format STRING &rest OBJECTS) */)
3627 ptrdiff_t bufsize = sizeof initial_buffer; 3621 ptrdiff_t bufsize = sizeof initial_buffer;
3628 ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1; 3622 ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1;
3629 char *p; 3623 char *p;
3630 Lisp_Object buf_save_value IF_LINT (= {0}); 3624 ptrdiff_t buf_save_value_index IF_LINT (= 0);
3631 char *format, *end, *format_start; 3625 char *format, *end, *format_start;
3632 ptrdiff_t formatlen, nchars; 3626 ptrdiff_t formatlen, nchars;
3633 /* True if the format is multibyte. */ 3627 /* True if the format is multibyte. */
@@ -4236,14 +4230,14 @@ usage: (format STRING &rest OBJECTS) */)
4236 { 4230 {
4237 buf = xmalloc (bufsize); 4231 buf = xmalloc (bufsize);
4238 sa_must_free = 1; 4232 sa_must_free = 1;
4239 buf_save_value = make_save_pointer (buf); 4233 buf_save_value_index = SPECPDL_INDEX ();
4240 record_unwind_protect (safe_alloca_unwind, buf_save_value); 4234 record_unwind_protect_ptr (xfree, buf);
4241 memcpy (buf, initial_buffer, used); 4235 memcpy (buf, initial_buffer, used);
4242 } 4236 }
4243 else 4237 else
4244 { 4238 {
4245 buf = xrealloc (buf, bufsize); 4239 buf = xrealloc (buf, bufsize);
4246 set_save_pointer (buf_save_value, 0, buf); 4240 set_unwind_protect_ptr (buf_save_value_index, xfree, buf);
4247 } 4241 }
4248 4242
4249 p = buf + used; 4243 p = buf + used;
diff --git a/src/emacs.c b/src/emacs.c
index 08609ee6a08..01bff0c5283 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -988,7 +988,7 @@ main (int argc, char **argv)
988 use a pipe for synchronization. The parent waits for the child 988 use a pipe for synchronization. The parent waits for the child
989 to close its end of the pipe (using `daemon-initialized') 989 to close its end of the pipe (using `daemon-initialized')
990 before exiting. */ 990 before exiting. */
991 if (pipe2 (daemon_pipe, O_CLOEXEC) != 0) 991 if (emacs_pipe (daemon_pipe) != 0)
992 { 992 {
993 fprintf (stderr, "Cannot pipe!\n"); 993 fprintf (stderr, "Cannot pipe!\n");
994 exit (1); 994 exit (1);
@@ -1508,12 +1508,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1508 char *file; 1508 char *file;
1509 /* Handle -l loadup, args passed by Makefile. */ 1509 /* Handle -l loadup, args passed by Makefile. */
1510 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args)) 1510 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
1511 Vtop_level = Fcons (intern_c_string ("load"), 1511 Vtop_level = list2 (intern_c_string ("load"), build_string (file));
1512 Fcons (build_string (file), Qnil));
1513 /* Unless next switch is -nl, load "loadup.el" first thing. */ 1512 /* Unless next switch is -nl, load "loadup.el" first thing. */
1514 if (! no_loadup) 1513 if (! no_loadup)
1515 Vtop_level = Fcons (intern_c_string ("load"), 1514 Vtop_level = list2 (intern_c_string ("load"),
1516 Fcons (build_string ("loadup.el"), Qnil)); 1515 build_string ("loadup.el"));
1517 } 1516 }
1518 1517
1519 if (initialized) 1518 if (initialized)
diff --git a/src/eval.c b/src/eval.c
index 0e231bdb285..23834cb54f6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -152,13 +152,6 @@ specpdl_arg (union specbinding *pdl)
152 return pdl->unwind.arg; 152 return pdl->unwind.arg;
153} 153}
154 154
155static specbinding_func
156specpdl_func (union specbinding *pdl)
157{
158 eassert (pdl->kind == SPECPDL_UNWIND);
159 return pdl->unwind.func;
160}
161
162Lisp_Object 155Lisp_Object
163backtrace_function (union specbinding *pdl) 156backtrace_function (union specbinding *pdl)
164{ 157{
@@ -267,12 +260,11 @@ init_eval (void)
267 260
268/* Unwind-protect function used by call_debugger. */ 261/* Unwind-protect function used by call_debugger. */
269 262
270static Lisp_Object 263static void
271restore_stack_limits (Lisp_Object data) 264restore_stack_limits (Lisp_Object data)
272{ 265{
273 max_specpdl_size = XINT (XCAR (data)); 266 max_specpdl_size = XINT (XCAR (data));
274 max_lisp_eval_depth = XINT (XCDR (data)); 267 max_lisp_eval_depth = XINT (XCDR (data));
275 return Qnil;
276} 268}
277 269
278/* Call the Lisp debugger, giving it argument ARG. */ 270/* Call the Lisp debugger, giving it argument ARG. */
@@ -338,7 +330,7 @@ do_debug_on_call (Lisp_Object code)
338{ 330{
339 debug_on_next_call = 0; 331 debug_on_next_call = 0;
340 set_backtrace_debug_on_exit (specpdl_ptr - 1, true); 332 set_backtrace_debug_on_exit (specpdl_ptr - 1, true);
341 call_debugger (Fcons (code, Qnil)); 333 call_debugger (list1 (code));
342} 334}
343 335
344/* NOTE!!! Every function that can call EVAL must protect its args 336/* NOTE!!! Every function that can call EVAL must protect its args
@@ -450,23 +442,32 @@ usage: (cond CLAUSES...) */)
450DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, 442DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0,
451 doc: /* Eval BODY forms sequentially and return value of last one. 443 doc: /* Eval BODY forms sequentially and return value of last one.
452usage: (progn BODY...) */) 444usage: (progn BODY...) */)
453 (Lisp_Object args) 445 (Lisp_Object body)
454{ 446{
455 register Lisp_Object val = Qnil; 447 Lisp_Object val = Qnil;
456 struct gcpro gcpro1; 448 struct gcpro gcpro1;
457 449
458 GCPRO1 (args); 450 GCPRO1 (body);
459 451
460 while (CONSP (args)) 452 while (CONSP (body))
461 { 453 {
462 val = eval_sub (XCAR (args)); 454 val = eval_sub (XCAR (body));
463 args = XCDR (args); 455 body = XCDR (body);
464 } 456 }
465 457
466 UNGCPRO; 458 UNGCPRO;
467 return val; 459 return val;
468} 460}
469 461
462/* Evaluate BODY sequentually, discarding its value. Suitable for
463 record_unwind_protect. */
464
465void
466unwind_body (Lisp_Object body)
467{
468 Fprogn (body);
469}
470
470DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, 471DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0,
471 doc: /* Eval FIRST and BODY sequentially; return value from FIRST. 472 doc: /* Eval FIRST and BODY sequentially; return value from FIRST.
472The value of FIRST is saved during the evaluation of the remaining args, 473The value of FIRST is saved during the evaluation of the remaining args,
@@ -1149,7 +1150,7 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...) */)
1149 Lisp_Object val; 1150 Lisp_Object val;
1150 ptrdiff_t count = SPECPDL_INDEX (); 1151 ptrdiff_t count = SPECPDL_INDEX ();
1151 1152
1152 record_unwind_protect (Fprogn, Fcdr (args)); 1153 record_unwind_protect (unwind_body, Fcdr (args));
1153 val = eval_sub (Fcar (args)); 1154 val = eval_sub (Fcar (args));
1154 return unbind_to (count, val); 1155 return unbind_to (count, val);
1155} 1156}
@@ -1611,7 +1612,7 @@ signal_error (const char *s, Lisp_Object arg)
1611 } 1612 }
1612 1613
1613 if (!NILP (hare)) 1614 if (!NILP (hare))
1614 arg = Fcons (arg, Qnil); /* Make it a list. */ 1615 arg = list1 (arg);
1615 1616
1616 xsignal (Qerror, Fcons (build_string (s), arg)); 1617 xsignal (Qerror, Fcons (build_string (s), arg));
1617} 1618}
@@ -1703,7 +1704,7 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data)
1703 /* RMS: What's this for? */ 1704 /* RMS: What's this for? */
1704 && when_entered_debugger < num_nonmacro_input_events) 1705 && when_entered_debugger < num_nonmacro_input_events)
1705 { 1706 {
1706 call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); 1707 call_debugger (list2 (Qerror, combined_data));
1707 return 1; 1708 return 1;
1708 } 1709 }
1709 1710
@@ -1890,10 +1891,10 @@ this does nothing and returns nil. */)
1890 Qnil); 1891 Qnil);
1891} 1892}
1892 1893
1893Lisp_Object 1894void
1894un_autoload (Lisp_Object oldqueue) 1895un_autoload (Lisp_Object oldqueue)
1895{ 1896{
1896 register Lisp_Object queue, first, second; 1897 Lisp_Object queue, first, second;
1897 1898
1898 /* Queue to unwind is current value of Vautoload_queue. 1899 /* Queue to unwind is current value of Vautoload_queue.
1899 oldqueue is the shadowed value to leave in Vautoload_queue. */ 1900 oldqueue is the shadowed value to leave in Vautoload_queue. */
@@ -1910,7 +1911,6 @@ un_autoload (Lisp_Object oldqueue)
1910 Ffset (first, second); 1911 Ffset (first, second);
1911 queue = XCDR (queue); 1912 queue = XCDR (queue);
1912 } 1913 }
1913 return Qnil;
1914} 1914}
1915 1915
1916/* Load an autoloaded function. 1916/* Load an autoloaded function.
@@ -1992,7 +1992,7 @@ If LEXICAL is t, evaluate using lexical scoping. */)
1992{ 1992{
1993 ptrdiff_t count = SPECPDL_INDEX (); 1993 ptrdiff_t count = SPECPDL_INDEX ();
1994 specbind (Qinternal_interpreter_environment, 1994 specbind (Qinternal_interpreter_environment,
1995 CONSP (lexical) || NILP (lexical) ? lexical : Fcons (Qt, Qnil)); 1995 CONSP (lexical) || NILP (lexical) ? lexical : list1 (Qt));
1996 return unbind_to (count, eval_sub (form)); 1996 return unbind_to (count, eval_sub (form));
1997} 1997}
1998 1998
@@ -2257,7 +2257,7 @@ eval_sub (Lisp_Object form)
2257 2257
2258 lisp_eval_depth--; 2258 lisp_eval_depth--;
2259 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2259 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2260 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); 2260 val = call_debugger (list2 (Qexit, val));
2261 specpdl_ptr--; 2261 specpdl_ptr--;
2262 2262
2263 return val; 2263 return val;
@@ -2878,7 +2878,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2878 check_cons_list (); 2878 check_cons_list ();
2879 lisp_eval_depth--; 2879 lisp_eval_depth--;
2880 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2880 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2881 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); 2881 val = call_debugger (list2 (Qexit, val));
2882 specpdl_ptr--; 2882 specpdl_ptr--;
2883 return val; 2883 return val;
2884} 2884}
@@ -2920,7 +2920,7 @@ apply_lambda (Lisp_Object fun, Lisp_Object args)
2920 { 2920 {
2921 /* Don't do it again when we return to eval. */ 2921 /* Don't do it again when we return to eval. */
2922 set_backtrace_debug_on_exit (specpdl_ptr - 1, false); 2922 set_backtrace_debug_on_exit (specpdl_ptr - 1, false);
2923 tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); 2923 tem = call_debugger (list2 (Qexit, tem));
2924 } 2924 }
2925 SAFE_FREE (); 2925 SAFE_FREE ();
2926 return tem; 2926 return tem;
@@ -3190,8 +3190,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3190 } 3190 }
3191} 3191}
3192 3192
3193/* Push unwind-protect entries of various types. */
3194
3193void 3195void
3194record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) 3196record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg)
3195{ 3197{
3196 specpdl_ptr->unwind.kind = SPECPDL_UNWIND; 3198 specpdl_ptr->unwind.kind = SPECPDL_UNWIND;
3197 specpdl_ptr->unwind.func = function; 3199 specpdl_ptr->unwind.func = function;
@@ -3199,6 +3201,72 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
3199 grow_specpdl (); 3201 grow_specpdl ();
3200} 3202}
3201 3203
3204void
3205record_unwind_protect_ptr (void (*function) (void *), void *arg)
3206{
3207 specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
3208 specpdl_ptr->unwind_ptr.func = function;
3209 specpdl_ptr->unwind_ptr.arg = arg;
3210 grow_specpdl ();
3211}
3212
3213void
3214record_unwind_protect_int (void (*function) (int), int arg)
3215{
3216 specpdl_ptr->unwind_int.kind = SPECPDL_UNWIND_INT;
3217 specpdl_ptr->unwind_int.func = function;
3218 specpdl_ptr->unwind_int.arg = arg;
3219 grow_specpdl ();
3220}
3221
3222void
3223record_unwind_protect_void (void (*function) (void))
3224{
3225 specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID;
3226 specpdl_ptr->unwind_void.func = function;
3227 grow_specpdl ();
3228}
3229
3230static void
3231do_nothing (void)
3232{}
3233
3234/* Push an unwind-protect entry that does nothing, so that
3235 set_unwind_protect_ptr can overwrite it later. */
3236
3237void
3238record_unwind_protect_nothing (void)
3239{
3240 record_unwind_protect_void (do_nothing);
3241}
3242
3243/* Clear the unwind-protect entry COUNT, so that it does nothing.
3244 It need not be at the top of the stack. */
3245
3246void
3247clear_unwind_protect (ptrdiff_t count)
3248{
3249 union specbinding *p = specpdl + count;
3250 p->unwind_void.kind = SPECPDL_UNWIND_VOID;
3251 p->unwind_void.func = do_nothing;
3252}
3253
3254/* Set the unwind-protect entry COUNT so that it invokes FUNC (ARG).
3255 It need not be at the top of the stack. Discard the entry's
3256 previous value without invoking it. */
3257
3258void
3259set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg)
3260{
3261 union specbinding *p = specpdl + count;
3262 p->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
3263 p->unwind_ptr.func = func;
3264 p->unwind_ptr.arg = arg;
3265}
3266
3267/* Pop and execute entries from the unwind-protect stack until the
3268 depth COUNT is reached. Return VALUE. */
3269
3202Lisp_Object 3270Lisp_Object
3203unbind_to (ptrdiff_t count, Lisp_Object value) 3271unbind_to (ptrdiff_t count, Lisp_Object value)
3204{ 3272{
@@ -3220,7 +3288,16 @@ unbind_to (ptrdiff_t count, Lisp_Object value)
3220 switch (specpdl_ptr->kind) 3288 switch (specpdl_ptr->kind)
3221 { 3289 {
3222 case SPECPDL_UNWIND: 3290 case SPECPDL_UNWIND:
3223 specpdl_func (specpdl_ptr) (specpdl_arg (specpdl_ptr)); 3291 specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg);
3292 break;
3293 case SPECPDL_UNWIND_PTR:
3294 specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg);
3295 break;
3296 case SPECPDL_UNWIND_INT:
3297 specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg);
3298 break;
3299 case SPECPDL_UNWIND_VOID:
3300 specpdl_ptr->unwind_void.func ();
3224 break; 3301 break;
3225 case SPECPDL_LET: 3302 case SPECPDL_LET:
3226 /* If variable has a trivial value (no forwarding), we can 3303 /* If variable has a trivial value (no forwarding), we can
diff --git a/src/fileio.c b/src/fileio.c
index c3566390130..a19fcd9f663 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -160,11 +160,16 @@ static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
160 160
161 161
162/* Signal a file-access failure. STRING describes the failure, 162/* Signal a file-access failure. STRING describes the failure,
163 DATA the file that was involved, and ERRORNO the errno value. */ 163 NAME the file involved, and ERRORNO the errno value.
164
165 If NAME is neither null nor a pair, package it up as a singleton
166 list before reporting it; this saves report_file_errno's caller the
167 trouble of preserving errno before calling list1. */
164 168
165void 169void
166report_file_errno (char const *string, Lisp_Object data, int errorno) 170report_file_errno (char const *string, Lisp_Object name, int errorno)
167{ 171{
172 Lisp_Object data = CONSP (name) || NILP (name) ? name : list1 (name);
168 Lisp_Object errstring; 173 Lisp_Object errstring;
169 char *str; 174 char *str;
170 175
@@ -198,27 +203,37 @@ report_file_errno (char const *string, Lisp_Object data, int errorno)
198 } 203 }
199} 204}
200 205
206/* Signal a file-access failure that set errno. STRING describes the
207 failure, NAME the file involved. When invoking this function, take
208 care to not use arguments such as build_string ("foo") that involve
209 side effects that may set errno. */
210
201void 211void
202report_file_error (char const *string, Lisp_Object data) 212report_file_error (char const *string, Lisp_Object name)
203{ 213{
204 report_file_errno (string, data, errno); 214 report_file_errno (string, name, errno);
205} 215}
206 216
207Lisp_Object 217void
208close_file_unwind (Lisp_Object fd) 218close_file_unwind (int fd)
209{ 219{
210 emacs_close (XFASTINT (fd)); 220 emacs_close (fd);
211 return Qnil; 221}
222
223void
224fclose_unwind (void *arg)
225{
226 FILE *stream = arg;
227 fclose (stream);
212} 228}
213 229
214/* Restore point, having saved it as a marker. */ 230/* Restore point, having saved it as a marker. */
215 231
216Lisp_Object 232void
217restore_point_unwind (Lisp_Object location) 233restore_point_unwind (Lisp_Object location)
218{ 234{
219 Fgoto_char (location); 235 Fgoto_char (location);
220 Fset_marker (location, Qnil, Qnil); 236 Fset_marker (location, Qnil, Qnil);
221 return Qnil;
222} 237}
223 238
224 239
@@ -749,7 +764,7 @@ make_temp_name (Lisp_Object prefix, bool base64_p)
749 dog-slow, but also useless since eventually nil would 764 dog-slow, but also useless since eventually nil would
750 have to be returned anyway. */ 765 have to be returned anyway. */
751 report_file_error ("Cannot create temporary name for prefix", 766 report_file_error ("Cannot create temporary name for prefix",
752 Fcons (prefix, Qnil)); 767 prefix);
753 /* not reached */ 768 /* not reached */
754 } 769 }
755 } 770 }
@@ -2019,7 +2034,7 @@ entries (depending on how Emacs was built). */)
2019 { 2034 {
2020 acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS); 2035 acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS);
2021 if (acl == NULL && acl_errno_valid (errno)) 2036 if (acl == NULL && acl_errno_valid (errno))
2022 report_file_error ("Getting ACL", Fcons (file, Qnil)); 2037 report_file_error ("Getting ACL", file);
2023 } 2038 }
2024 if (!CopyFile (SDATA (encoded_file), 2039 if (!CopyFile (SDATA (encoded_file),
2025 SDATA (encoded_newname), 2040 SDATA (encoded_newname),
@@ -2027,7 +2042,7 @@ entries (depending on how Emacs was built). */)
2027 { 2042 {
2028 /* CopyFile doesn't set errno when it fails. By far the most 2043 /* CopyFile doesn't set errno when it fails. By far the most
2029 "popular" reason is that the target is read-only. */ 2044 "popular" reason is that the target is read-only. */
2030 report_file_errno ("Copying file", Fcons (file, Fcons (newname, Qnil)), 2045 report_file_errno ("Copying file", list2 (file, newname),
2031 GetLastError () == 5 ? EACCES : EPERM); 2046 GetLastError () == 5 ? EACCES : EPERM);
2032 } 2047 }
2033 /* CopyFile retains the timestamp by default. */ 2048 /* CopyFile retains the timestamp by default. */
@@ -2058,7 +2073,7 @@ entries (depending on how Emacs was built). */)
2058 bool fail = 2073 bool fail =
2059 acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0; 2074 acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0;
2060 if (fail && acl_errno_valid (errno)) 2075 if (fail && acl_errno_valid (errno))
2061 report_file_error ("Setting ACL", Fcons (newname, Qnil)); 2076 report_file_error ("Setting ACL", newname);
2062 2077
2063 acl_free (acl); 2078 acl_free (acl);
2064 } 2079 }
@@ -2068,12 +2083,12 @@ entries (depending on how Emacs was built). */)
2068 immediate_quit = 0; 2083 immediate_quit = 0;
2069 2084
2070 if (ifd < 0) 2085 if (ifd < 0)
2071 report_file_error ("Opening input file", Fcons (file, Qnil)); 2086 report_file_error ("Opening input file", file);
2072 2087
2073 record_unwind_protect (close_file_unwind, make_number (ifd)); 2088 record_unwind_protect_int (close_file_unwind, ifd);
2074 2089
2075 if (fstat (ifd, &st) != 0) 2090 if (fstat (ifd, &st) != 0)
2076 report_file_error ("Input file status", Fcons (file, Qnil)); 2091 report_file_error ("Input file status", file);
2077 2092
2078 if (!NILP (preserve_extended_attributes)) 2093 if (!NILP (preserve_extended_attributes))
2079 { 2094 {
@@ -2082,7 +2097,7 @@ entries (depending on how Emacs was built). */)
2082 { 2097 {
2083 conlength = fgetfilecon (ifd, &con); 2098 conlength = fgetfilecon (ifd, &con);
2084 if (conlength == -1) 2099 if (conlength == -1)
2085 report_file_error ("Doing fgetfilecon", Fcons (file, Qnil)); 2100 report_file_error ("Doing fgetfilecon", file);
2086 } 2101 }
2087#endif 2102#endif
2088 } 2103 }
@@ -2090,11 +2105,11 @@ entries (depending on how Emacs was built). */)
2090 if (out_st.st_mode != 0 2105 if (out_st.st_mode != 0
2091 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) 2106 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2092 report_file_errno ("Input and output files are the same", 2107 report_file_errno ("Input and output files are the same",
2093 Fcons (file, Fcons (newname, Qnil)), 0); 2108 list2 (file, newname), 0);
2094 2109
2095 /* We can copy only regular files. */ 2110 /* We can copy only regular files. */
2096 if (!S_ISREG (st.st_mode)) 2111 if (!S_ISREG (st.st_mode))
2097 report_file_errno ("Non-regular file", Fcons (file, Qnil), 2112 report_file_errno ("Non-regular file", file,
2098 S_ISDIR (st.st_mode) ? EISDIR : EINVAL); 2113 S_ISDIR (st.st_mode) ? EISDIR : EINVAL);
2099 2114
2100 { 2115 {
@@ -2109,15 +2124,15 @@ entries (depending on how Emacs was built). */)
2109 new_mask); 2124 new_mask);
2110 } 2125 }
2111 if (ofd < 0) 2126 if (ofd < 0)
2112 report_file_error ("Opening output file", Fcons (newname, Qnil)); 2127 report_file_error ("Opening output file", newname);
2113 2128
2114 record_unwind_protect (close_file_unwind, make_number (ofd)); 2129 record_unwind_protect_int (close_file_unwind, ofd);
2115 2130
2116 immediate_quit = 1; 2131 immediate_quit = 1;
2117 QUIT; 2132 QUIT;
2118 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0) 2133 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
2119 if (emacs_write_sig (ofd, buf, n) != n) 2134 if (emacs_write_sig (ofd, buf, n) != n)
2120 report_file_error ("I/O error", Fcons (newname, Qnil)); 2135 report_file_error ("Write error", newname);
2121 immediate_quit = 0; 2136 immediate_quit = 0;
2122 2137
2123#ifndef MSDOS 2138#ifndef MSDOS
@@ -2145,8 +2160,8 @@ entries (depending on how Emacs was built). */)
2145 st.st_mode & mode_mask) 2160 st.st_mode & mode_mask)
2146 : fchmod (ofd, st.st_mode & mode_mask)) 2161 : fchmod (ofd, st.st_mode & mode_mask))
2147 { 2162 {
2148 case -2: report_file_error ("Copying permissions from", list1 (file)); 2163 case -2: report_file_error ("Copying permissions from", file);
2149 case -1: report_file_error ("Copying permissions to", list1 (newname)); 2164 case -1: report_file_error ("Copying permissions to", newname);
2150 } 2165 }
2151 } 2166 }
2152#endif /* not MSDOS */ 2167#endif /* not MSDOS */
@@ -2158,7 +2173,7 @@ entries (depending on how Emacs was built). */)
2158 bool fail = fsetfilecon (ofd, con) != 0; 2173 bool fail = fsetfilecon (ofd, con) != 0;
2159 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ 2174 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */
2160 if (fail && errno != ENOTSUP) 2175 if (fail && errno != ENOTSUP)
2161 report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil)); 2176 report_file_error ("Doing fsetfilecon", newname);
2162 2177
2163 freecon (con); 2178 freecon (con);
2164 } 2179 }
@@ -2174,7 +2189,7 @@ entries (depending on how Emacs was built). */)
2174 } 2189 }
2175 2190
2176 if (emacs_close (ofd) < 0) 2191 if (emacs_close (ofd) < 0)
2177 report_file_error ("I/O error", Fcons (newname, Qnil)); 2192 report_file_error ("Write error", newname);
2178 2193
2179 emacs_close (ifd); 2194 emacs_close (ifd);
2180 2195
@@ -2220,7 +2235,7 @@ DEFUN ("make-directory-internal", Fmake_directory_internal,
2220#else 2235#else
2221 if (mkdir (dir, 0777 & ~auto_saving_dir_umask) != 0) 2236 if (mkdir (dir, 0777 & ~auto_saving_dir_umask) != 0)
2222#endif 2237#endif
2223 report_file_error ("Creating directory", list1 (directory)); 2238 report_file_error ("Creating directory", directory);
2224 2239
2225 return Qnil; 2240 return Qnil;
2226} 2241}
@@ -2239,7 +2254,7 @@ DEFUN ("delete-directory-internal", Fdelete_directory_internal,
2239 dir = SSDATA (encoded_dir); 2254 dir = SSDATA (encoded_dir);
2240 2255
2241 if (rmdir (dir) != 0) 2256 if (rmdir (dir) != 0)
2242 report_file_error ("Removing directory", list1 (directory)); 2257 report_file_error ("Removing directory", directory);
2243 2258
2244 return Qnil; 2259 return Qnil;
2245} 2260}
@@ -2282,7 +2297,7 @@ With a prefix argument, TRASH is nil. */)
2282 encoded_file = ENCODE_FILE (filename); 2297 encoded_file = ENCODE_FILE (filename);
2283 2298
2284 if (unlink (SSDATA (encoded_file)) < 0) 2299 if (unlink (SSDATA (encoded_file)) < 0)
2285 report_file_error ("Removing old name", list1 (filename)); 2300 report_file_error ("Removing old name", filename);
2286 return Qnil; 2301 return Qnil;
2287} 2302}
2288 2303
@@ -2364,7 +2379,8 @@ This is what happens in interactive use with M-x. */)
2364 INTEGERP (ok_if_already_exists), 0, 0); 2379 INTEGERP (ok_if_already_exists), 0, 0);
2365 if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0) 2380 if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0)
2366 { 2381 {
2367 if (errno == EXDEV) 2382 int rename_errno = errno;
2383 if (rename_errno == EXDEV)
2368 { 2384 {
2369 ptrdiff_t count; 2385 ptrdiff_t count;
2370 symlink_target = Ffile_symlink_p (file); 2386 symlink_target = Ffile_symlink_p (file);
@@ -2390,7 +2406,7 @@ This is what happens in interactive use with M-x. */)
2390 unbind_to (count, Qnil); 2406 unbind_to (count, Qnil);
2391 } 2407 }
2392 else 2408 else
2393 report_file_error ("Renaming", list2 (file, newname)); 2409 report_file_errno ("Renaming", list2 (file, newname), rename_errno);
2394 } 2410 }
2395 UNGCPRO; 2411 UNGCPRO;
2396 return Qnil; 2412 return Qnil;
@@ -2444,7 +2460,10 @@ This is what happens in interactive use with M-x. */)
2444 2460
2445 unlink (SSDATA (newname)); 2461 unlink (SSDATA (newname));
2446 if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0) 2462 if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0)
2447 report_file_error ("Adding new name", list2 (file, newname)); 2463 {
2464 int link_errno = errno;
2465 report_file_errno ("Adding new name", list2 (file, newname), link_errno);
2466 }
2448 2467
2449 UNGCPRO; 2468 UNGCPRO;
2450 return Qnil; 2469 return Qnil;
@@ -2503,6 +2522,7 @@ This happens for interactive use with M-x. */)
2503 if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) < 0) 2522 if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) < 0)
2504 { 2523 {
2505 /* If we didn't complain already, silently delete existing file. */ 2524 /* If we didn't complain already, silently delete existing file. */
2525 int symlink_errno;
2506 if (errno == EEXIST) 2526 if (errno == EEXIST)
2507 { 2527 {
2508 unlink (SSDATA (encoded_linkname)); 2528 unlink (SSDATA (encoded_linkname));
@@ -2520,7 +2540,9 @@ This happens for interactive use with M-x. */)
2520 build_string ("Symbolic links are not supported")); 2540 build_string ("Symbolic links are not supported"));
2521 } 2541 }
2522 2542
2523 report_file_error ("Making symbolic link", list2 (filename, linkname)); 2543 symlink_errno = errno;
2544 report_file_errno ("Making symbolic link", list2 (filename, linkname),
2545 symlink_errno);
2524 } 2546 }
2525 UNGCPRO; 2547 UNGCPRO;
2526 return Qnil; 2548 return Qnil;
@@ -2719,7 +2741,7 @@ If there is no error, returns nil. */)
2719 encoded_filename = ENCODE_FILE (absname); 2741 encoded_filename = ENCODE_FILE (absname);
2720 2742
2721 if (faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, AT_EACCESS) != 0) 2743 if (faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, AT_EACCESS) != 0)
2722 report_file_error (SSDATA (string), Fcons (filename, Qnil)); 2744 report_file_error (SSDATA (string), filename);
2723 2745
2724 return Qnil; 2746 return Qnil;
2725} 2747}
@@ -3054,14 +3076,14 @@ or if Emacs was not compiled with SELinux support. */)
3054 != 0); 3076 != 0);
3055 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ 3077 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */
3056 if (fail && errno != ENOTSUP) 3078 if (fail && errno != ENOTSUP)
3057 report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil)); 3079 report_file_error ("Doing lsetfilecon", absname);
3058 3080
3059 context_free (parsed_con); 3081 context_free (parsed_con);
3060 freecon (con); 3082 freecon (con);
3061 return fail ? Qnil : Qt; 3083 return fail ? Qnil : Qt;
3062 } 3084 }
3063 else 3085 else
3064 report_file_error ("Doing lgetfilecon", Fcons (absname, Qnil)); 3086 report_file_error ("Doing lgetfilecon", absname);
3065 } 3087 }
3066#endif 3088#endif
3067 3089
@@ -3151,7 +3173,7 @@ support. */)
3151 acl = acl_from_text (SSDATA (acl_string)); 3173 acl = acl_from_text (SSDATA (acl_string));
3152 if (acl == NULL) 3174 if (acl == NULL)
3153 { 3175 {
3154 report_file_error ("Converting ACL", Fcons (absname, Qnil)); 3176 report_file_error ("Converting ACL", absname);
3155 return Qnil; 3177 return Qnil;
3156 } 3178 }
3157 3179
@@ -3161,7 +3183,7 @@ support. */)
3161 acl) 3183 acl)
3162 != 0); 3184 != 0);
3163 if (fail && acl_errno_valid (errno)) 3185 if (fail && acl_errno_valid (errno))
3164 report_file_error ("Setting ACL", Fcons (absname, Qnil)); 3186 report_file_error ("Setting ACL", absname);
3165 3187
3166 acl_free (acl); 3188 acl_free (acl);
3167 return fail ? Qnil : Qt; 3189 return fail ? Qnil : Qt;
@@ -3221,7 +3243,7 @@ symbolic notation, like the `chmod' command from GNU Coreutils. */)
3221 encoded_absname = ENCODE_FILE (absname); 3243 encoded_absname = ENCODE_FILE (absname);
3222 3244
3223 if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0) 3245 if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0)
3224 report_file_error ("Doing chmod", Fcons (absname, Qnil)); 3246 report_file_error ("Doing chmod", absname);
3225 3247
3226 return Qnil; 3248 return Qnil;
3227} 3249}
@@ -3287,7 +3309,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3287 if (file_directory_p (SSDATA (encoded_absname))) 3309 if (file_directory_p (SSDATA (encoded_absname)))
3288 return Qnil; 3310 return Qnil;
3289#endif 3311#endif
3290 report_file_error ("Setting file times", Fcons (absname, Qnil)); 3312 report_file_error ("Setting file times", absname);
3291 } 3313 }
3292 } 3314 }
3293 3315
@@ -3369,7 +3391,7 @@ verify (READ_BUF_SIZE <= INT_MAX);
3369 o remove all text properties. 3391 o remove all text properties.
3370 o set back the buffer multibyteness. */ 3392 o set back the buffer multibyteness. */
3371 3393
3372static Lisp_Object 3394static void
3373decide_coding_unwind (Lisp_Object unwind_data) 3395decide_coding_unwind (Lisp_Object unwind_data)
3374{ 3396{
3375 Lisp_Object multibyte, undo_list, buffer; 3397 Lisp_Object multibyte, undo_list, buffer;
@@ -3388,8 +3410,6 @@ decide_coding_unwind (Lisp_Object unwind_data)
3388 /* Now we are safe to change the buffer's multibyteness directly. */ 3410 /* Now we are safe to change the buffer's multibyteness directly. */
3389 bset_enable_multibyte_characters (current_buffer, multibyte); 3411 bset_enable_multibyte_characters (current_buffer, multibyte);
3390 bset_undo_list (current_buffer, undo_list); 3412 bset_undo_list (current_buffer, undo_list);
3391
3392 return Qnil;
3393} 3413}
3394 3414
3395/* Read from a non-regular file. STATE is a Lisp_Save_Value 3415/* Read from a non-regular file. STATE is a Lisp_Save_Value
@@ -3510,7 +3530,7 @@ by calling `format-decode', which see. */)
3510 && BEG == Z); 3530 && BEG == Z);
3511 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark; 3531 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
3512 bool we_locked_file = 0; 3532 bool we_locked_file = 0;
3513 bool deferred_remove_unwind_protect = 0; 3533 ptrdiff_t fd_index;
3514 3534
3515 if (current_buffer->base_buffer && ! NILP (visit)) 3535 if (current_buffer->base_buffer && ! NILP (visit))
3516 error ("Cannot do file visiting in an indirect buffer"); 3536 error ("Cannot do file visiting in an indirect buffer");
@@ -3553,7 +3573,7 @@ by calling `format-decode', which see. */)
3553 { 3573 {
3554 save_errno = errno; 3574 save_errno = errno;
3555 if (NILP (visit)) 3575 if (NILP (visit))
3556 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); 3576 report_file_error ("Opening input file", orig_filename);
3557 mtime = time_error_value (save_errno); 3577 mtime = time_error_value (save_errno);
3558 st.st_size = -1; 3578 st.st_size = -1;
3559 if (!NILP (Vcoding_system_for_read)) 3579 if (!NILP (Vcoding_system_for_read))
@@ -3561,14 +3581,15 @@ by calling `format-decode', which see. */)
3561 goto notfound; 3581 goto notfound;
3562 } 3582 }
3563 3583
3584 fd_index = SPECPDL_INDEX ();
3585 record_unwind_protect_int (close_file_unwind, fd);
3586
3564 /* Replacement should preserve point as it preserves markers. */ 3587 /* Replacement should preserve point as it preserves markers. */
3565 if (!NILP (replace)) 3588 if (!NILP (replace))
3566 record_unwind_protect (restore_point_unwind, Fpoint_marker ()); 3589 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3567 3590
3568 record_unwind_protect (close_file_unwind, make_number (fd));
3569
3570 if (fstat (fd, &st) != 0) 3591 if (fstat (fd, &st) != 0)
3571 report_file_error ("Input file status", Fcons (orig_filename, Qnil)); 3592 report_file_error ("Input file status", orig_filename);
3572 mtime = get_stat_mtime (&st); 3593 mtime = get_stat_mtime (&st);
3573 3594
3574 /* This code will need to be changed in order to work on named 3595 /* This code will need to be changed in order to work on named
@@ -3682,15 +3703,14 @@ by calling `format-decode', which see. */)
3682 int ntail; 3703 int ntail;
3683 if (lseek (fd, - (1024 * 3), SEEK_END) < 0) 3704 if (lseek (fd, - (1024 * 3), SEEK_END) < 0)
3684 report_file_error ("Setting file position", 3705 report_file_error ("Setting file position",
3685 Fcons (orig_filename, Qnil)); 3706 orig_filename);
3686 ntail = emacs_read (fd, read_buf + nread, 1024 * 3); 3707 ntail = emacs_read (fd, read_buf + nread, 1024 * 3);
3687 nread = ntail < 0 ? ntail : nread + ntail; 3708 nread = ntail < 0 ? ntail : nread + ntail;
3688 } 3709 }
3689 } 3710 }
3690 3711
3691 if (nread < 0) 3712 if (nread < 0)
3692 error ("IO error reading %s: %s", 3713 report_file_error ("Read error", orig_filename);
3693 SDATA (orig_filename), emacs_strerror (errno));
3694 else if (nread > 0) 3714 else if (nread > 0)
3695 { 3715 {
3696 struct buffer *prev = current_buffer; 3716 struct buffer *prev = current_buffer;
@@ -3726,8 +3746,7 @@ by calling `format-decode', which see. */)
3726 3746
3727 /* Rewind the file for the actual read done later. */ 3747 /* Rewind the file for the actual read done later. */
3728 if (lseek (fd, 0, SEEK_SET) < 0) 3748 if (lseek (fd, 0, SEEK_SET) < 0)
3729 report_file_error ("Setting file position", 3749 report_file_error ("Setting file position", orig_filename);
3730 Fcons (orig_filename, Qnil));
3731 } 3750 }
3732 } 3751 }
3733 3752
@@ -3793,8 +3812,7 @@ by calling `format-decode', which see. */)
3793 if (beg_offset != 0) 3812 if (beg_offset != 0)
3794 { 3813 {
3795 if (lseek (fd, beg_offset, SEEK_SET) < 0) 3814 if (lseek (fd, beg_offset, SEEK_SET) < 0)
3796 report_file_error ("Setting file position", 3815 report_file_error ("Setting file position", orig_filename);
3797 Fcons (orig_filename, Qnil));
3798 } 3816 }
3799 3817
3800 immediate_quit = 1; 3818 immediate_quit = 1;
@@ -3807,8 +3825,7 @@ by calling `format-decode', which see. */)
3807 3825
3808 nread = emacs_read (fd, read_buf, sizeof read_buf); 3826 nread = emacs_read (fd, read_buf, sizeof read_buf);
3809 if (nread < 0) 3827 if (nread < 0)
3810 error ("IO error reading %s: %s", 3828 report_file_error ("Read error", orig_filename);
3811 SSDATA (orig_filename), emacs_strerror (errno));
3812 else if (nread == 0) 3829 else if (nread == 0)
3813 break; 3830 break;
3814 3831
@@ -3866,16 +3883,14 @@ by calling `format-decode', which see. */)
3866 /* How much can we scan in the next step? */ 3883 /* How much can we scan in the next step? */
3867 trial = min (curpos, sizeof read_buf); 3884 trial = min (curpos, sizeof read_buf);
3868 if (lseek (fd, curpos - trial, SEEK_SET) < 0) 3885 if (lseek (fd, curpos - trial, SEEK_SET) < 0)
3869 report_file_error ("Setting file position", 3886 report_file_error ("Setting file position", orig_filename);
3870 Fcons (orig_filename, Qnil));
3871 3887
3872 total_read = nread = 0; 3888 total_read = nread = 0;
3873 while (total_read < trial) 3889 while (total_read < trial)
3874 { 3890 {
3875 nread = emacs_read (fd, read_buf + total_read, trial - total_read); 3891 nread = emacs_read (fd, read_buf + total_read, trial - total_read);
3876 if (nread < 0) 3892 if (nread < 0)
3877 error ("IO error reading %s: %s", 3893 report_file_error ("Read error", orig_filename);
3878 SDATA (orig_filename), emacs_strerror (errno));
3879 else if (nread == 0) 3894 else if (nread == 0)
3880 break; 3895 break;
3881 total_read += nread; 3896 total_read += nread;
@@ -3987,8 +4002,7 @@ by calling `format-decode', which see. */)
3987 CONVERSION_BUFFER. */ 4002 CONVERSION_BUFFER. */
3988 4003
3989 if (lseek (fd, beg_offset, SEEK_SET) < 0) 4004 if (lseek (fd, beg_offset, SEEK_SET) < 0)
3990 report_file_error ("Setting file position", 4005 report_file_error ("Setting file position", orig_filename);
3991 Fcons (orig_filename, Qnil));
3992 4006
3993 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ 4007 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3994 unprocessed = 0; /* Bytes not processed in previous loop. */ 4008 unprocessed = 0; /* Bytes not processed in previous loop. */
@@ -4018,16 +4032,10 @@ by calling `format-decode', which see. */)
4018 memcpy (read_buf, coding.carryover, unprocessed); 4032 memcpy (read_buf, coding.carryover, unprocessed);
4019 } 4033 }
4020 UNGCPRO; 4034 UNGCPRO;
4021 emacs_close (fd);
4022
4023 /* We should remove the unwind_protect calling
4024 close_file_unwind, but other stuff has been added the stack,
4025 so defer the removal till we reach the `handled' label. */
4026 deferred_remove_unwind_protect = 1;
4027
4028 if (this < 0) 4035 if (this < 0)
4029 error ("IO error reading %s: %s", 4036 report_file_error ("Read error", orig_filename);
4030 SDATA (orig_filename), emacs_strerror (errno)); 4037 emacs_close (fd);
4038 clear_unwind_protect (fd_index);
4031 4039
4032 if (unprocessed > 0) 4040 if (unprocessed > 0)
4033 { 4041 {
@@ -4168,8 +4176,7 @@ by calling `format-decode', which see. */)
4168 if (beg_offset != 0 || !NILP (replace)) 4176 if (beg_offset != 0 || !NILP (replace))
4169 { 4177 {
4170 if (lseek (fd, beg_offset, SEEK_SET) < 0) 4178 if (lseek (fd, beg_offset, SEEK_SET) < 0)
4171 report_file_error ("Setting file position", 4179 report_file_error ("Setting file position", orig_filename);
4172 Fcons (orig_filename, Qnil));
4173 } 4180 }
4174 4181
4175 /* In the following loop, HOW_MUCH contains the total bytes read so 4182 /* In the following loop, HOW_MUCH contains the total bytes read so
@@ -4208,8 +4215,7 @@ by calling `format-decode', which see. */)
4208 to be signaled after decoding the text we read. */ 4215 to be signaled after decoding the text we read. */
4209 nbytes = internal_condition_case_1 4216 nbytes = internal_condition_case_1
4210 (read_non_regular, 4217 (read_non_regular,
4211 make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd, 4218 make_save_int_int_int (fd, inserted, trytry),
4212 inserted, trytry),
4213 Qerror, read_non_regular_quit); 4219 Qerror, read_non_regular_quit);
4214 4220
4215 if (NILP (nbytes)) 4221 if (NILP (nbytes))
@@ -4269,13 +4275,10 @@ by calling `format-decode', which see. */)
4269 Vdeactivate_mark = Qt; 4275 Vdeactivate_mark = Qt;
4270 4276
4271 emacs_close (fd); 4277 emacs_close (fd);
4272 4278 clear_unwind_protect (fd_index);
4273 /* Discard the unwind protect for closing the file. */
4274 specpdl_ptr--;
4275 4279
4276 if (how_much < 0) 4280 if (how_much < 0)
4277 error ("IO error reading %s: %s", 4281 report_file_error ("Read error", orig_filename);
4278 SDATA (orig_filename), emacs_strerror (errno));
4279 4282
4280 /* Make the text read part of the buffer. */ 4283 /* Make the text read part of the buffer. */
4281 GAP_SIZE -= inserted; 4284 GAP_SIZE -= inserted;
@@ -4399,11 +4402,6 @@ by calling `format-decode', which see. */)
4399 4402
4400 handled: 4403 handled:
4401 4404
4402 if (deferred_remove_unwind_protect)
4403 /* If requested above, discard the unwind protect for closing the
4404 file. */
4405 specpdl_ptr--;
4406
4407 if (!NILP (visit)) 4405 if (!NILP (visit))
4408 { 4406 {
4409 if (empty_undo_list_p) 4407 if (empty_undo_list_p)
@@ -4574,8 +4572,7 @@ by calling `format-decode', which see. */)
4574 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 4572 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
4575 { 4573 {
4576 /* If visiting nonexistent file, return nil. */ 4574 /* If visiting nonexistent file, return nil. */
4577 report_file_errno ("Opening input file", Fcons (orig_filename, Qnil), 4575 report_file_errno ("Opening input file", orig_filename, save_errno);
4578 save_errno);
4579 } 4576 }
4580 4577
4581 if (read_quit) 4578 if (read_quit)
@@ -4590,11 +4587,10 @@ by calling `format-decode', which see. */)
4590 4587
4591static Lisp_Object build_annotations (Lisp_Object, Lisp_Object); 4588static Lisp_Object build_annotations (Lisp_Object, Lisp_Object);
4592 4589
4593static Lisp_Object 4590static void
4594build_annotations_unwind (Lisp_Object arg) 4591build_annotations_unwind (Lisp_Object arg)
4595{ 4592{
4596 Vwrite_region_annotation_buffers = arg; 4593 Vwrite_region_annotation_buffers = arg;
4597 return Qnil;
4598} 4594}
4599 4595
4600/* Decide the coding-system to encode the data with. */ 4596/* Decide the coding-system to encode the data with. */
@@ -4631,7 +4627,7 @@ This function is for internal use only. It may prompt the user. */ )
4631 && !NILP (Ffboundp (Vselect_safe_coding_system_function))) 4627 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4632 /* Confirm that VAL can surely encode the current region. */ 4628 /* Confirm that VAL can surely encode the current region. */
4633 val = call5 (Vselect_safe_coding_system_function, 4629 val = call5 (Vselect_safe_coding_system_function,
4634 start, end, Fcons (Qt, Fcons (val, Qnil)), 4630 start, end, list2 (Qt, val),
4635 Qnil, filename); 4631 Qnil, filename);
4636 } 4632 }
4637 else 4633 else
@@ -4834,7 +4830,7 @@ This calls `write-region-annotate-functions' at the start, and
4834 4830
4835 record_unwind_protect (build_annotations_unwind, 4831 record_unwind_protect (build_annotations_unwind,
4836 Vwrite_region_annotation_buffers); 4832 Vwrite_region_annotation_buffers);
4837 Vwrite_region_annotation_buffers = Fcons (Fcurrent_buffer (), Qnil); 4833 Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ());
4838 count1 = SPECPDL_INDEX (); 4834 count1 = SPECPDL_INDEX ();
4839 4835
4840 given_buffer = current_buffer; 4836 given_buffer = current_buffer;
@@ -4901,11 +4897,10 @@ This calls `write-region-annotate-functions' at the start, and
4901 if (!auto_saving) unlock_file (lockname); 4897 if (!auto_saving) unlock_file (lockname);
4902#endif /* CLASH_DETECTION */ 4898#endif /* CLASH_DETECTION */
4903 UNGCPRO; 4899 UNGCPRO;
4904 report_file_errno ("Opening output file", Fcons (filename, Qnil), 4900 report_file_errno ("Opening output file", filename, open_errno);
4905 open_errno);
4906 } 4901 }
4907 4902
4908 record_unwind_protect (close_file_unwind, make_number (desc)); 4903 record_unwind_protect_int (close_file_unwind, desc);
4909 4904
4910 if (NUMBERP (append)) 4905 if (NUMBERP (append))
4911 { 4906 {
@@ -4917,8 +4912,7 @@ This calls `write-region-annotate-functions' at the start, and
4917 if (!auto_saving) unlock_file (lockname); 4912 if (!auto_saving) unlock_file (lockname);
4918#endif /* CLASH_DETECTION */ 4913#endif /* CLASH_DETECTION */
4919 UNGCPRO; 4914 UNGCPRO;
4920 report_file_errno ("Lseek error", Fcons (filename, Qnil), 4915 report_file_errno ("Lseek error", filename, lseek_errno);
4921 lseek_errno);
4922 } 4916 }
4923 } 4917 }
4924 4918
@@ -5071,8 +5065,7 @@ This calls `write-region-annotate-functions' at the start, and
5071 } 5065 }
5072 5066
5073 if (! ok) 5067 if (! ok)
5074 error ("IO error writing %s: %s", SDATA (filename), 5068 report_file_errno ("Write error", filename, save_errno);
5075 emacs_strerror (save_errno));
5076 5069
5077 if (visiting) 5070 if (visiting)
5078 { 5071 {
@@ -5498,11 +5491,18 @@ auto_save_1 (void)
5498 Qnil, Qnil); 5491 Qnil, Qnil);
5499} 5492}
5500 5493
5501static Lisp_Object 5494struct auto_save_unwind
5502do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ 5495{
5496 FILE *stream;
5497 bool auto_raise;
5498};
5503 5499
5500static void
5501do_auto_save_unwind (void *arg)
5504{ 5502{
5505 FILE *stream = XSAVE_POINTER (arg, 0); 5503 struct auto_save_unwind *p = arg;
5504 FILE *stream = p->stream;
5505 minibuffer_auto_raise = p->auto_raise;
5506 auto_saving = 0; 5506 auto_saving = 0;
5507 if (stream != NULL) 5507 if (stream != NULL)
5508 { 5508 {
@@ -5510,15 +5510,6 @@ do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */
5510 fclose (stream); 5510 fclose (stream);
5511 unblock_input (); 5511 unblock_input ();
5512 } 5512 }
5513 return Qnil;
5514}
5515
5516static Lisp_Object
5517do_auto_save_unwind_1 (Lisp_Object value) /* used as unwind-protect function */
5518
5519{
5520 minibuffer_auto_raise = XINT (value);
5521 return Qnil;
5522} 5513}
5523 5514
5524static Lisp_Object 5515static Lisp_Object
@@ -5561,6 +5552,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5561 ptrdiff_t count = SPECPDL_INDEX (); 5552 ptrdiff_t count = SPECPDL_INDEX ();
5562 bool orig_minibuffer_auto_raise = minibuffer_auto_raise; 5553 bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
5563 bool old_message_p = 0; 5554 bool old_message_p = 0;
5555 struct auto_save_unwind auto_save_unwind;
5564 struct gcpro gcpro1, gcpro2; 5556 struct gcpro gcpro1, gcpro2;
5565 5557
5566 if (max_specpdl_size < specpdl_size + 40) 5558 if (max_specpdl_size < specpdl_size + 40)
@@ -5572,7 +5564,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5572 if (NILP (no_message)) 5564 if (NILP (no_message))
5573 { 5565 {
5574 old_message_p = push_message (); 5566 old_message_p = push_message ();
5575 record_unwind_protect (pop_message_unwind, Qnil); 5567 record_unwind_protect_void (pop_message_unwind);
5576 } 5568 }
5577 5569
5578 /* Ordinarily don't quit within this function, 5570 /* Ordinarily don't quit within this function,
@@ -5611,10 +5603,9 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5611 stream = emacs_fopen (SSDATA (listfile), "w"); 5603 stream = emacs_fopen (SSDATA (listfile), "w");
5612 } 5604 }
5613 5605
5614 record_unwind_protect (do_auto_save_unwind, 5606 auto_save_unwind.stream = stream;
5615 make_save_pointer (stream)); 5607 auto_save_unwind.auto_raise = minibuffer_auto_raise;
5616 record_unwind_protect (do_auto_save_unwind_1, 5608 record_unwind_protect_ptr (do_auto_save_unwind, &auto_save_unwind);
5617 make_number (minibuffer_auto_raise));
5618 minibuffer_auto_raise = 0; 5609 minibuffer_auto_raise = 0;
5619 auto_saving = 1; 5610 auto_saving = 1;
5620 auto_save_error_occurred = 0; 5611 auto_save_error_occurred = 0;
diff --git a/src/filelock.c b/src/filelock.c
index 244663ad20a..b9c991e4baf 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -257,18 +257,14 @@ void
257get_boot_time_1 (const char *filename, bool newest) 257get_boot_time_1 (const char *filename, bool newest)
258{ 258{
259 struct utmp ut, *utp; 259 struct utmp ut, *utp;
260 int desc;
261 260
262 if (filename) 261 if (filename)
263 { 262 {
264 /* On some versions of IRIX, opening a nonexistent file name 263 /* On some versions of IRIX, opening a nonexistent file name
265 is likely to crash in the utmp routines. */ 264 is likely to crash in the utmp routines. */
266 desc = emacs_open (filename, O_RDONLY, 0); 265 if (faccessat (AT_FDCWD, filename, R_OK, AT_EACCESS) != 0)
267 if (desc < 0)
268 return; 266 return;
269 267
270 emacs_close (desc);
271
272 utmpname (filename); 268 utmpname (filename);
273 } 269 }
274 270
@@ -412,8 +408,6 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
412 USE_SAFE_ALLOCA; 408 USE_SAFE_ALLOCA;
413 char *nonce = SAFE_ALLOCA (lfdirlen + sizeof nonce_base); 409 char *nonce = SAFE_ALLOCA (lfdirlen + sizeof nonce_base);
414 int fd; 410 int fd;
415 bool need_fchmod;
416 mode_t world_readable = S_IRUSR | S_IRGRP | S_IROTH;
417 memcpy (nonce, lfname, lfdirlen); 411 memcpy (nonce, lfname, lfdirlen);
418 strcpy (nonce + lfdirlen, nonce_base); 412 strcpy (nonce + lfdirlen, nonce_base);
419 413
@@ -421,17 +415,14 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
421 /* Prefer mkostemp to mkstemp, as it avoids a window where FD is 415 /* Prefer mkostemp to mkstemp, as it avoids a window where FD is
422 temporarily open without close-on-exec. */ 416 temporarily open without close-on-exec. */
423 fd = mkostemp (nonce, O_BINARY | O_CLOEXEC); 417 fd = mkostemp (nonce, O_BINARY | O_CLOEXEC);
424 need_fchmod = 1;
425#elif HAVE_MKSTEMP 418#elif HAVE_MKSTEMP
426 /* Prefer mkstemp to mktemp, as it avoids a race between 419 /* Prefer mkstemp to mktemp, as it avoids a race between
427 mktemp and emacs_open. */ 420 mktemp and emacs_open. */
428 fd = mkstemp (nonce); 421 fd = mkstemp (nonce);
429 need_fchmod = 1;
430#else 422#else
431 mktemp (nonce); 423 mktemp (nonce);
432 fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 424 fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
433 world_readable); 425 S_IRUSR | S_IWUSR);
434 need_fchmod = 0;
435#endif 426#endif
436 427
437 if (fd < 0) 428 if (fd < 0)
@@ -439,13 +430,15 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
439 else 430 else
440 { 431 {
441 ptrdiff_t lock_info_len; 432 ptrdiff_t lock_info_len;
442#if ! HAVE_MKOSTEMP 433#if ! (HAVE_MKOSTEMP && O_CLOEXEC)
443 fcntl (fd, F_SETFD, FD_CLOEXEC); 434 fcntl (fd, F_SETFD, FD_CLOEXEC);
444#endif 435#endif
445 lock_info_len = strlen (lock_info_str); 436 lock_info_len = strlen (lock_info_str);
446 err = 0; 437 err = 0;
447 if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len 438 /* Use 'write', not 'emacs_write', as garbage collection
448 || (need_fchmod && fchmod (fd, world_readable) != 0)) 439 might signal an error, which would leak FD. */
440 if (write (fd, lock_info_str, lock_info_len) != lock_info_len
441 || fchmod (fd, S_IRUSR | S_IRGRP | S_IROTH) != 0)
449 err = errno; 442 err = errno;
450 /* There is no need to call fsync here, as the contents of 443 /* There is no need to call fsync here, as the contents of
451 the lock file need not survive system crashes. */ 444 the lock file need not survive system crashes. */
@@ -517,7 +510,8 @@ read_lock_data (char *lfname, char lfinfo[MAX_LFINFO + 1])
517 int fd = emacs_open (lfname, O_RDONLY | O_BINARY | O_NOFOLLOW, 0); 510 int fd = emacs_open (lfname, O_RDONLY | O_BINARY | O_NOFOLLOW, 0);
518 if (0 <= fd) 511 if (0 <= fd)
519 { 512 {
520 ptrdiff_t read_bytes = emacs_read (fd, lfinfo, MAX_LFINFO + 1); 513 /* Use read, not emacs_read, since FD isn't unwind-protected. */
514 ptrdiff_t read_bytes = read (fd, lfinfo, MAX_LFINFO + 1);
521 int read_errno = errno; 515 int read_errno = errno;
522 if (emacs_close (fd) != 0) 516 if (emacs_close (fd) != 0)
523 return -1; 517 return -1;
diff --git a/src/fns.c b/src/fns.c
index 49bd8470f7f..9fd0ad2a9d1 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1962,7 +1962,7 @@ The PLIST is modified by side effects. */)
1962 prev = tail; 1962 prev = tail;
1963 QUIT; 1963 QUIT;
1964 } 1964 }
1965 newcell = Fcons (prop, Fcons (val, Qnil)); 1965 newcell = list2 (prop, val);
1966 if (NILP (prev)) 1966 if (NILP (prev))
1967 return newcell; 1967 return newcell;
1968 else 1968 else
@@ -2455,9 +2455,8 @@ is nil, and `use-dialog-box' is non-nil. */)
2455 { 2455 {
2456 Lisp_Object pane, menu, obj; 2456 Lisp_Object pane, menu, obj;
2457 redisplay_preserve_echo_area (4); 2457 redisplay_preserve_echo_area (4);
2458 pane = Fcons (Fcons (build_string ("Yes"), Qt), 2458 pane = list2 (Fcons (build_string ("Yes"), Qt),
2459 Fcons (Fcons (build_string ("No"), Qnil), 2459 Fcons (build_string ("No"), Qnil));
2460 Qnil));
2461 GCPRO1 (pane); 2460 GCPRO1 (pane);
2462 menu = Fcons (prompt, pane); 2461 menu = Fcons (prompt, pane);
2463 obj = Fx_popup_dialog (Qt, menu, Qnil); 2462 obj = Fx_popup_dialog (Qt, menu, Qnil);
@@ -2586,10 +2585,10 @@ particular subfeatures supported in this version of FEATURE. */)
2586 2585
2587static Lisp_Object require_nesting_list; 2586static Lisp_Object require_nesting_list;
2588 2587
2589static Lisp_Object 2588static void
2590require_unwind (Lisp_Object old_value) 2589require_unwind (Lisp_Object old_value)
2591{ 2590{
2592 return require_nesting_list = old_value; 2591 require_nesting_list = old_value;
2593} 2592}
2594 2593
2595DEFUN ("require", Frequire, Srequire, 1, 3, 0, 2594DEFUN ("require", Frequire, Srequire, 1, 3, 0,
@@ -4915,7 +4914,7 @@ syms_of_fns (void)
4915 DEFVAR_LISP ("features", Vfeatures, 4914 DEFVAR_LISP ("features", Vfeatures,
4916 doc: /* A list of symbols which are the features of the executing Emacs. 4915 doc: /* A list of symbols which are the features of the executing Emacs.
4917Used by `featurep' and `require', and altered by `provide'. */); 4916Used by `featurep' and `require', and altered by `provide'. */);
4918 Vfeatures = Fcons (intern_c_string ("emacs"), Qnil); 4917 Vfeatures = list1 (intern_c_string ("emacs"));
4919 DEFSYM (Qsubfeatures, "subfeatures"); 4918 DEFSYM (Qsubfeatures, "subfeatures");
4920 DEFSYM (Qfuncall, "funcall"); 4919 DEFSYM (Qfuncall, "funcall");
4921 4920
diff --git a/src/font.c b/src/font.c
index 231df2ef71a..124d5f9bd9e 100644
--- a/src/font.c
+++ b/src/font.c
@@ -472,7 +472,7 @@ font_registry_charsets (Lisp_Object registry, struct charset **encoding, struct
472 goto invalid_entry; 472 goto invalid_entry;
473 val = Fcons (make_number (encoding_id), make_number (repertory_id)); 473 val = Fcons (make_number (encoding_id), make_number (repertory_id));
474 font_charset_alist 474 font_charset_alist
475 = nconc2 (font_charset_alist, Fcons (Fcons (registry, val), Qnil)); 475 = nconc2 (font_charset_alist, list1 (Fcons (registry, val)));
476 } 476 }
477 477
478 if (encoding) 478 if (encoding)
@@ -483,7 +483,7 @@ font_registry_charsets (Lisp_Object registry, struct charset **encoding, struct
483 483
484 invalid_entry: 484 invalid_entry:
485 font_charset_alist 485 font_charset_alist
486 = nconc2 (font_charset_alist, Fcons (Fcons (registry, Qnil), Qnil)); 486 = nconc2 (font_charset_alist, list1 (Fcons (registry, Qnil)));
487 return -1; 487 return -1;
488} 488}
489 489
@@ -1453,7 +1453,7 @@ font_parse_fcname (char *name, ptrdiff_t len, Lisp_Object font)
1453 else 1453 else
1454 { 1454 {
1455 extra_props = nconc2 (extra_props, 1455 extra_props = nconc2 (extra_props,
1456 Fcons (Fcons (key, val), Qnil)); 1456 list1 (Fcons (key, val)));
1457 } 1457 }
1458 } 1458 }
1459 p = q; 1459 p = q;
@@ -1861,7 +1861,7 @@ otf_open (Lisp_Object file)
1861 else 1861 else
1862 { 1862 {
1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; 1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
1864 val = make_save_pointer (otf); 1864 val = make_save_ptr (otf);
1865 otf_list = Fcons (Fcons (file, val), otf_list); 1865 otf_list = Fcons (Fcons (file, val), otf_list);
1866 } 1866 }
1867 return otf; 1867 return otf;
@@ -2519,7 +2519,7 @@ font_prepare_cache (FRAME_PTR f, struct font_driver *driver)
2519 val = XCDR (val); 2519 val = XCDR (val);
2520 if (NILP (val)) 2520 if (NILP (val))
2521 { 2521 {
2522 val = Fcons (driver->type, Fcons (make_number (1), Qnil)); 2522 val = list2 (driver->type, make_number (1));
2523 XSETCDR (cache, Fcons (val, XCDR (cache))); 2523 XSETCDR (cache, Fcons (val, XCDR (cache)));
2524 } 2524 }
2525 else 2525 else
@@ -3517,8 +3517,7 @@ font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers)
3517 3517
3518 for (list = f->font_driver_list; list; list = list->next) 3518 for (list = f->font_driver_list; list; list = list->next)
3519 if (list->on) 3519 if (list->on)
3520 active_drivers = nconc2 (active_drivers, 3520 active_drivers = nconc2 (active_drivers, list1 (list->driver->type));
3521 Fcons (list->driver->type, Qnil));
3522 return active_drivers; 3521 return active_drivers;
3523} 3522}
3524 3523
@@ -4133,7 +4132,7 @@ how close they are to PREFER. */)
4133 return Qnil; 4132 return Qnil;
4134 if (NILP (XCDR (list)) 4133 if (NILP (XCDR (list))
4135 && ASIZE (XCAR (list)) == 1) 4134 && ASIZE (XCAR (list)) == 1)
4136 return Fcons (AREF (XCAR (list), 0), Qnil); 4135 return list1 (AREF (XCAR (list), 0));
4137 4136
4138 if (! NILP (prefer)) 4137 if (! NILP (prefer))
4139 vec = font_sort_entities (list, prefer, frame, 0); 4138 vec = font_sort_entities (list, prefer, frame, 0);
diff --git a/src/fontset.c b/src/fontset.c
index 2f6313c4214..6a6a434add0 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -1523,7 +1523,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1523 { 1523 {
1524 if (XFASTINT (target) < 0x80) 1524 if (XFASTINT (target) < 0x80)
1525 error ("Can't set a font for partial ASCII range"); 1525 error ("Can't set a font for partial ASCII range");
1526 range_list = Fcons (Fcons (target, target), Qnil); 1526 range_list = list1 (Fcons (target, target));
1527 } 1527 }
1528 else if (CONSP (target)) 1528 else if (CONSP (target))
1529 { 1529 {
@@ -1539,7 +1539,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1539 error ("Can't set a font for partial ASCII range"); 1539 error ("Can't set a font for partial ASCII range");
1540 ascii_changed = 1; 1540 ascii_changed = 1;
1541 } 1541 }
1542 range_list = Fcons (target, Qnil); 1542 range_list = list1 (target);
1543 } 1543 }
1544 else if (SYMBOLP (target) && !NILP (target)) 1544 else if (SYMBOLP (target) && !NILP (target))
1545 { 1545 {
@@ -1552,7 +1552,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1552 { 1552 {
1553 if (EQ (target, Qlatin)) 1553 if (EQ (target, Qlatin))
1554 ascii_changed = 1; 1554 ascii_changed = 1;
1555 val = Fcons (target, Qnil); 1555 val = list1 (target);
1556 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table, 1556 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
1557 val); 1557 val);
1558 range_list = Fnreverse (XCDR (val)); 1558 range_list = Fnreverse (XCDR (val));
@@ -1568,7 +1568,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1568 SDATA (SYMBOL_NAME (target))); 1568 SDATA (SYMBOL_NAME (target)));
1569 } 1569 }
1570 else if (NILP (target)) 1570 else if (NILP (target))
1571 range_list = Fcons (Qnil, Qnil); 1571 range_list = list1 (Qnil);
1572 else 1572 else
1573 error ("Invalid target for setting a font"); 1573 error ("Invalid target for setting a font");
1574 1574
@@ -1628,7 +1628,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1628 if (! NILP (font_object)) 1628 if (! NILP (font_object))
1629 { 1629 {
1630 update_auto_fontset_alist (font_object, fontset); 1630 update_auto_fontset_alist (font_object, fontset);
1631 alist = Fcons (Fcons (Qfont, Fcons (name, font_object)), Qnil); 1631 alist = list1 (Fcons (Qfont, Fcons (name, font_object)));
1632 Fmodify_frame_parameters (fr, alist); 1632 Fmodify_frame_parameters (fr, alist);
1633 } 1633 }
1634 } 1634 }
@@ -1999,7 +1999,7 @@ format is the same as above. */)
1999 slot = Fassq (RFONT_DEF_SPEC (elt), alist); 1999 slot = Fassq (RFONT_DEF_SPEC (elt), alist);
2000 name = AREF (font_object, FONT_NAME_INDEX); 2000 name = AREF (font_object, FONT_NAME_INDEX);
2001 if (NILP (Fmember (name, XCDR (slot)))) 2001 if (NILP (Fmember (name, XCDR (slot))))
2002 nconc2 (slot, Fcons (name, Qnil)); 2002 nconc2 (slot, list1 (name));
2003 } 2003 }
2004 } 2004 }
2005 } 2005 }
@@ -2238,9 +2238,9 @@ alternate fontnames (if any) are tried instead. */);
2238 2238
2239 DEFVAR_LISP ("fontset-alias-alist", Vfontset_alias_alist, 2239 DEFVAR_LISP ("fontset-alias-alist", Vfontset_alias_alist,
2240 doc: /* Alist of fontset names vs the aliases. */); 2240 doc: /* Alist of fontset names vs the aliases. */);
2241 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset), 2241 Vfontset_alias_alist
2242 build_pure_c_string ("fontset-default")), 2242 = list1 (Fcons (FONTSET_NAME (Vdefault_fontset),
2243 Qnil); 2243 build_pure_c_string ("fontset-default")));
2244 2244
2245 DEFVAR_LISP ("vertical-centering-font-regexp", 2245 DEFVAR_LISP ("vertical-centering-font-regexp",
2246 Vvertical_centering_font_regexp, 2246 Vvertical_centering_font_regexp,
diff --git a/src/frame.c b/src/frame.c
index 648687a7cb4..5fa54052cd2 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -389,7 +389,7 @@ make_frame (int mini_p)
389 etc. Running Lisp functions at this point surely ends in a 389 etc. Running Lisp functions at this point surely ends in a
390 SEGV. */ 390 SEGV. */
391 set_window_buffer (root_window, buf, 0, 0); 391 set_window_buffer (root_window, buf, 0, 0);
392 fset_buffer_list (f, Fcons (buf, Qnil)); 392 fset_buffer_list (f, list1 (buf));
393 } 393 }
394 394
395 if (mini_p) 395 if (mini_p)
@@ -726,15 +726,15 @@ affects all frames on the same terminal device. */)
726 calculate_costs (f); 726 calculate_costs (f);
727 XSETFRAME (frame, f); 727 XSETFRAME (frame, f);
728 Fmodify_frame_parameters (frame, parms); 728 Fmodify_frame_parameters (frame, parms);
729 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type, 729 Fmodify_frame_parameters
730 build_string (t->display_info.tty->type)), 730 (frame, list1 (Fcons (Qtty_type,
731 Qnil)); 731 build_string (t->display_info.tty->type))));
732 if (t->display_info.tty->name != NULL) 732 if (t->display_info.tty->name != NULL)
733 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, 733 Fmodify_frame_parameters
734 build_string (t->display_info.tty->name)), 734 (frame, list1 (Fcons (Qtty,
735 Qnil)); 735 build_string (t->display_info.tty->name))));
736 else 736 else
737 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil)); 737 Fmodify_frame_parameters (frame, list1 (Fcons (Qtty, Qnil)));
738 738
739 /* Make the frame face alist be frame-specific, so that each 739 /* Make the frame face alist be frame-specific, so that each
740 frame could change its face definitions independently. */ 740 frame could change its face definitions independently. */
@@ -887,6 +887,26 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
887 return do_switch_frame (frame, 1, 0, norecord); 887 return do_switch_frame (frame, 1, 0, norecord);
888} 888}
889 889
890DEFUN ("handle-focus-in", Fhandle_focus_in, Shandle_focus_in, 1, 1, "e",
891 doc: /* Handle a focus-in event.
892Focus in events are usually bound to this function.
893Focus in events occur when a frame has focus, but a switch-frame event
894is not generated.
895This function checks if blink-cursor timers should be turned on again. */)
896 (Lisp_Object event)
897{
898 return call0 (intern ("blink-cursor-check"));
899}
900
901DEFUN ("handle-focus-out", Fhandle_focus_out, Shandle_focus_out, 1, 1, "e",
902 doc: /* Handle a focus-out event.
903Focus out events are usually bound to this function.
904Focus out events occur when no frame has focus.
905This function checks if blink-cursor timers should be turned off. */)
906 (Lisp_Object event)
907{
908 return call0 (intern ("blink-cursor-suspend"));
909}
890 910
891DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e", 911DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
892 doc: /* Handle a switch-frame event EVENT. 912 doc: /* Handle a switch-frame event EVENT.
@@ -902,6 +922,7 @@ to that frame. */)
902 /* Preserve prefix arg that the command loop just cleared. */ 922 /* Preserve prefix arg that the command loop just cleared. */
903 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); 923 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
904 Frun_hooks (1, &Qmouse_leave_buffer_hook); 924 Frun_hooks (1, &Qmouse_leave_buffer_hook);
925 Fhandle_focus_in (event); // switch-frame implies a focus in.
905 return do_switch_frame (event, 0, 0, Qnil); 926 return do_switch_frame (event, 0, 0, Qnil);
906} 927}
907 928
@@ -2731,7 +2752,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
2731 { 2752 {
2732 left_no_change = 1; 2753 left_no_change = 1;
2733 if (f->left_pos < 0) 2754 if (f->left_pos < 0)
2734 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil)); 2755 left = list2 (Qplus, make_number (f->left_pos));
2735 else 2756 else
2736 XSETINT (left, f->left_pos); 2757 XSETINT (left, f->left_pos);
2737 } 2758 }
@@ -2739,7 +2760,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
2739 { 2760 {
2740 top_no_change = 1; 2761 top_no_change = 1;
2741 if (f->top_pos < 0) 2762 if (f->top_pos < 0)
2742 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil)); 2763 top = list2 (Qplus, make_number (f->top_pos));
2743 else 2764 else
2744 XSETINT (top, f->top_pos); 2765 XSETINT (top, f->top_pos);
2745 } 2766 }
@@ -2874,13 +2895,13 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
2874 if (f->left_pos >= 0) 2895 if (f->left_pos >= 0)
2875 store_in_alist (alistptr, Qleft, tem); 2896 store_in_alist (alistptr, Qleft, tem);
2876 else 2897 else
2877 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil))); 2898 store_in_alist (alistptr, Qleft, list2 (Qplus, tem));
2878 2899
2879 XSETINT (tem, f->top_pos); 2900 XSETINT (tem, f->top_pos);
2880 if (f->top_pos >= 0) 2901 if (f->top_pos >= 0)
2881 store_in_alist (alistptr, Qtop, tem); 2902 store_in_alist (alistptr, Qtop, tem);
2882 else 2903 else
2883 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil))); 2904 store_in_alist (alistptr, Qtop, list2 (Qplus, tem));
2884 2905
2885 store_in_alist (alistptr, Qborder_width, 2906 store_in_alist (alistptr, Qborder_width,
2886 make_number (f->border_width)); 2907 make_number (f->border_width));
@@ -3739,7 +3760,7 @@ x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
3739 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type); 3760 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3740 if (EQ (tem, Qunbound)) 3761 if (EQ (tem, Qunbound))
3741 tem = deflt; 3762 tem = deflt;
3742 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); 3763 x_set_frame_parameters (f, list1 (Fcons (prop, tem)));
3743 return tem; 3764 return tem;
3744} 3765}
3745 3766
@@ -3871,9 +3892,9 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
3871 Lisp_Object element; 3892 Lisp_Object element;
3872 3893
3873 if (x >= 0 && (geometry & XNegative)) 3894 if (x >= 0 && (geometry & XNegative))
3874 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil))); 3895 element = list3 (Qleft, Qminus, make_number (-x));
3875 else if (x < 0 && ! (geometry & XNegative)) 3896 else if (x < 0 && ! (geometry & XNegative))
3876 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil))); 3897 element = list3 (Qleft, Qplus, make_number (x));
3877 else 3898 else
3878 element = Fcons (Qleft, make_number (x)); 3899 element = Fcons (Qleft, make_number (x));
3879 result = Fcons (element, result); 3900 result = Fcons (element, result);
@@ -3884,9 +3905,9 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
3884 Lisp_Object element; 3905 Lisp_Object element;
3885 3906
3886 if (y >= 0 && (geometry & YNegative)) 3907 if (y >= 0 && (geometry & YNegative))
3887 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil))); 3908 element = list3 (Qtop, Qminus, make_number (-y));
3888 else if (y < 0 && ! (geometry & YNegative)) 3909 else if (y < 0 && ! (geometry & YNegative))
3889 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil))); 3910 element = list3 (Qtop, Qplus, make_number (y));
3890 else 3911 else
3891 element = Fcons (Qtop, make_number (y)); 3912 element = Fcons (Qtop, make_number (y));
3892 result = Fcons (element, result); 3913 result = Fcons (element, result);
@@ -4449,6 +4470,8 @@ automatically. See also `mouse-autoselect-window'. */);
4449 defsubr (&Swindow_system); 4470 defsubr (&Swindow_system);
4450 defsubr (&Smake_terminal_frame); 4471 defsubr (&Smake_terminal_frame);
4451 defsubr (&Shandle_switch_frame); 4472 defsubr (&Shandle_switch_frame);
4473 defsubr (&Shandle_focus_in);
4474 defsubr (&Shandle_focus_out);
4452 defsubr (&Sselect_frame); 4475 defsubr (&Sselect_frame);
4453 defsubr (&Sselected_frame); 4476 defsubr (&Sselected_frame);
4454 defsubr (&Sframe_list); 4477 defsubr (&Sframe_list);
diff --git a/src/ftfont.c b/src/ftfont.c
index 0ad173af98a..10090cb3bda 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -393,7 +393,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
393 cache_data = xmalloc (sizeof *cache_data); 393 cache_data = xmalloc (sizeof *cache_data);
394 cache_data->ft_face = NULL; 394 cache_data->ft_face = NULL;
395 cache_data->fc_charset = NULL; 395 cache_data->fc_charset = NULL;
396 val = make_save_value (SAVE_TYPE_PTR_INT, cache_data, 0); 396 val = make_save_ptr_int (cache_data, 0);
397 cache = Fcons (Qnil, val); 397 cache = Fcons (Qnil, val);
398 Fputhash (key, cache, ft_face_cache); 398 Fputhash (key, cache, ft_face_cache);
399 } 399 }
@@ -2703,13 +2703,12 @@ syms_of_ftfont (void)
2703 DEFSYM (Qsans__serif, "sans serif"); 2703 DEFSYM (Qsans__serif, "sans serif");
2704 2704
2705 staticpro (&freetype_font_cache); 2705 staticpro (&freetype_font_cache);
2706 freetype_font_cache = Fcons (Qt, Qnil); 2706 freetype_font_cache = list1 (Qt);
2707 2707
2708 staticpro (&ftfont_generic_family_list); 2708 staticpro (&ftfont_generic_family_list);
2709 ftfont_generic_family_list 2709 ftfont_generic_family_list = list3 (Fcons (Qmonospace, Qt),
2710 = Fcons (Fcons (Qmonospace, Qt), 2710 Fcons (Qsans_serif, Qt),
2711 Fcons (Fcons (Qsans_serif, Qt), 2711 Fcons (Qsans, Qt));
2712 Fcons (Fcons (Qsans, Qt), Qnil)));
2713 2712
2714 staticpro (&ft_face_cache); 2713 staticpro (&ft_face_cache);
2715 ft_face_cache = Qnil; 2714 ft_face_cache = Qnil;
diff --git a/src/gfilenotify.c b/src/gfilenotify.c
index 4e684d1fb54..8f13c72df81 100644
--- a/src/gfilenotify.c
+++ b/src/gfilenotify.c
@@ -173,7 +173,7 @@ will be reported only in case of the 'moved' event. */)
173 CHECK_STRING (file); 173 CHECK_STRING (file);
174 file = Fdirectory_file_name (Fexpand_file_name (file, Qnil)); 174 file = Fdirectory_file_name (Fexpand_file_name (file, Qnil));
175 if (NILP (Ffile_exists_p (file))) 175 if (NILP (Ffile_exists_p (file)))
176 report_file_error ("File does not exists", Fcons (file, Qnil)); 176 report_file_error ("File does not exist", file);
177 177
178 CHECK_LIST (flags); 178 CHECK_LIST (flags);
179 179
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 8ac58f18158..f8ddf6a90f6 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1650,10 +1650,10 @@ xg_dialog_response_cb (GtkDialog *w,
1650 1650
1651/* Destroy the dialog. This makes it pop down. */ 1651/* Destroy the dialog. This makes it pop down. */
1652 1652
1653static Lisp_Object 1653static void
1654pop_down_dialog (Lisp_Object arg) 1654pop_down_dialog (void *arg)
1655{ 1655{
1656 struct xg_dialog_data *dd = XSAVE_POINTER (arg, 0); 1656 struct xg_dialog_data *dd = arg;
1657 1657
1658 block_input (); 1658 block_input ();
1659 if (dd->w) gtk_widget_destroy (dd->w); 1659 if (dd->w) gtk_widget_destroy (dd->w);
@@ -1663,8 +1663,6 @@ pop_down_dialog (Lisp_Object arg)
1663 g_main_loop_unref (dd->loop); 1663 g_main_loop_unref (dd->loop);
1664 1664
1665 unblock_input (); 1665 unblock_input ();
1666
1667 return Qnil;
1668} 1666}
1669 1667
1670/* If there are any emacs timers pending, add a timeout to main loop in DATA. 1668/* If there are any emacs timers pending, add a timeout to main loop in DATA.
@@ -1719,7 +1717,7 @@ xg_dialog_run (FRAME_PTR f, GtkWidget *w)
1719 g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL); 1717 g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL);
1720 gtk_widget_show (w); 1718 gtk_widget_show (w);
1721 1719
1722 record_unwind_protect (pop_down_dialog, make_save_pointer (&dd)); 1720 record_unwind_protect_ptr (pop_down_dialog, &dd);
1723 1721
1724 (void) xg_maybe_add_timer (&dd); 1722 (void) xg_maybe_add_timer (&dd);
1725 g_main_loop_run (dd.loop); 1723 g_main_loop_run (dd.loop);
diff --git a/src/image.c b/src/image.c
index c085e6e63eb..1e3944ac1a1 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2276,23 +2276,28 @@ slurp_file (char *file, ptrdiff_t *size)
2276 unsigned char *buf = NULL; 2276 unsigned char *buf = NULL;
2277 struct stat st; 2277 struct stat st;
2278 2278
2279 if (fp && fstat (fileno (fp), &st) == 0 2279 if (fp)
2280 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
2281 && (buf = xmalloc (st.st_size),
2282 fread (buf, 1, st.st_size, fp) == st.st_size))
2283 {
2284 *size = st.st_size;
2285 fclose (fp);
2286 }
2287 else
2288 { 2280 {
2289 if (fp) 2281 ptrdiff_t count = SPECPDL_INDEX ();
2290 fclose (fp); 2282 record_unwind_protect_ptr (fclose_unwind, fp);
2291 if (buf) 2283
2284 if (fstat (fileno (fp), &st) == 0
2285 && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
2292 { 2286 {
2293 xfree (buf); 2287 /* Report an error if we read past the purported EOF.
2294 buf = NULL; 2288 This can happen if the file grows as we read it. */
2289 ptrdiff_t buflen = st.st_size;
2290 buf = xmalloc (buflen + 1);
2291 if (fread (buf, 1, buflen + 1, fp) == buflen)
2292 *size = buflen;
2293 else
2294 {
2295 xfree (buf);
2296 buf = NULL;
2297 }
2295 } 2298 }
2299
2300 unbind_to (count, Qnil);
2296 } 2301 }
2297 2302
2298 return buf; 2303 return buf;
@@ -5732,8 +5737,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5732 if (fread (sig, 1, sizeof sig, fp) != sizeof sig 5737 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
5733 || fn_png_sig_cmp (sig, 0, sizeof sig)) 5738 || fn_png_sig_cmp (sig, 0, sizeof sig))
5734 { 5739 {
5735 image_error ("Not a PNG file: `%s'", file, Qnil);
5736 fclose (fp); 5740 fclose (fp);
5741 image_error ("Not a PNG file: `%s'", file, Qnil);
5737 return 0; 5742 return 0;
5738 } 5743 }
5739 } 5744 }
@@ -7581,8 +7586,7 @@ gif_load (struct frame *f, struct image *img)
7581 delay |= ext->Bytes[1]; 7586 delay |= ext->Bytes[1];
7582 } 7587 }
7583 } 7588 }
7584 img->lisp_data = Fcons (Qextension_data, 7589 img->lisp_data = list2 (Qextension_data, img->lisp_data);
7585 Fcons (img->lisp_data, Qnil));
7586 if (delay) 7590 if (delay)
7587 img->lisp_data 7591 img->lisp_data
7588 = Fcons (Qdelay, 7592 = Fcons (Qdelay,
diff --git a/src/insdel.c b/src/insdel.c
index ed684264249..15d585568a0 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1913,12 +1913,18 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1913 VARIABLE is the variable to maybe set to nil. 1913 VARIABLE is the variable to maybe set to nil.
1914 NO-ERROR-FLAG is nil if there was an error, 1914 NO-ERROR-FLAG is nil if there was an error,
1915 anything else meaning no error (so this function does nothing). */ 1915 anything else meaning no error (so this function does nothing). */
1916static Lisp_Object 1916struct rvoe_arg
1917reset_var_on_error (Lisp_Object val)
1918{ 1917{
1919 if (NILP (XCDR (val))) 1918 Lisp_Object *location;
1920 Fset (XCAR (val), Qnil); 1919 bool errorp;
1921 return Qnil; 1920};
1921
1922static void
1923reset_var_on_error (void *ptr)
1924{
1925 struct rvoe_arg *p = ptr;
1926 if (p->errorp)
1927 *p->location = Qnil;
1922} 1928}
1923 1929
1924/* Signal a change to the buffer immediately before it happens. 1930/* Signal a change to the buffer immediately before it happens.
@@ -1936,6 +1942,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
1936 Lisp_Object preserve_marker; 1942 Lisp_Object preserve_marker;
1937 struct gcpro gcpro1, gcpro2, gcpro3; 1943 struct gcpro gcpro1, gcpro2, gcpro3;
1938 ptrdiff_t count = SPECPDL_INDEX (); 1944 ptrdiff_t count = SPECPDL_INDEX ();
1945 struct rvoe_arg rvoe_arg;
1939 1946
1940 if (inhibit_modification_hooks) 1947 if (inhibit_modification_hooks)
1941 return; 1948 return;
@@ -1963,13 +1970,14 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
1963 if (!NILP (Vbefore_change_functions)) 1970 if (!NILP (Vbefore_change_functions))
1964 { 1971 {
1965 Lisp_Object args[3]; 1972 Lisp_Object args[3];
1966 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil); 1973 rvoe_arg.location = &Vbefore_change_functions;
1974 rvoe_arg.errorp = 1;
1967 1975
1968 PRESERVE_VALUE; 1976 PRESERVE_VALUE;
1969 PRESERVE_START_END; 1977 PRESERVE_START_END;
1970 1978
1971 /* Mark before-change-functions to be reset to nil in case of error. */ 1979 /* Mark before-change-functions to be reset to nil in case of error. */
1972 record_unwind_protect (reset_var_on_error, rvoe_arg); 1980 record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg);
1973 1981
1974 /* Actually run the hook functions. */ 1982 /* Actually run the hook functions. */
1975 args[0] = Qbefore_change_functions; 1983 args[0] = Qbefore_change_functions;
@@ -1978,7 +1986,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
1978 Frun_hook_with_args (3, args); 1986 Frun_hook_with_args (3, args);
1979 1987
1980 /* There was no error: unarm the reset_on_error. */ 1988 /* There was no error: unarm the reset_on_error. */
1981 XSETCDR (rvoe_arg, Qt); 1989 rvoe_arg.errorp = 0;
1982 } 1990 }
1983 1991
1984 if (buffer_has_overlays ()) 1992 if (buffer_has_overlays ())
@@ -2009,6 +2017,8 @@ void
2009signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) 2017signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
2010{ 2018{
2011 ptrdiff_t count = SPECPDL_INDEX (); 2019 ptrdiff_t count = SPECPDL_INDEX ();
2020 struct rvoe_arg rvoe_arg;
2021
2012 if (inhibit_modification_hooks) 2022 if (inhibit_modification_hooks)
2013 return; 2023 return;
2014 2024
@@ -2042,10 +2052,11 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
2042 if (!NILP (Vafter_change_functions)) 2052 if (!NILP (Vafter_change_functions))
2043 { 2053 {
2044 Lisp_Object args[4]; 2054 Lisp_Object args[4];
2045 Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil); 2055 rvoe_arg.location = &Vafter_change_functions;
2056 rvoe_arg.errorp = 1;
2046 2057
2047 /* Mark after-change-functions to be reset to nil in case of error. */ 2058 /* Mark after-change-functions to be reset to nil in case of error. */
2048 record_unwind_protect (reset_var_on_error, rvoe_arg); 2059 record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg);
2049 2060
2050 /* Actually run the hook functions. */ 2061 /* Actually run the hook functions. */
2051 args[0] = Qafter_change_functions; 2062 args[0] = Qafter_change_functions;
@@ -2055,7 +2066,7 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
2055 Frun_hook_with_args (4, args); 2066 Frun_hook_with_args (4, args);
2056 2067
2057 /* There was no error: unarm the reset_on_error. */ 2068 /* There was no error: unarm the reset_on_error. */
2058 XSETCDR (rvoe_arg, Qt); 2069 rvoe_arg.errorp = 0;
2059 } 2070 }
2060 2071
2061 if (buffer_has_overlays ()) 2072 if (buffer_has_overlays ())
@@ -2075,11 +2086,10 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
2075 unbind_to (count, Qnil); 2086 unbind_to (count, Qnil);
2076} 2087}
2077 2088
2078static Lisp_Object 2089static void
2079Fcombine_after_change_execute_1 (Lisp_Object val) 2090Fcombine_after_change_execute_1 (Lisp_Object val)
2080{ 2091{
2081 Vcombine_after_change_calls = val; 2092 Vcombine_after_change_calls = val;
2082 return val;
2083} 2093}
2084 2094
2085DEFUN ("combine-after-change-execute", Fcombine_after_change_execute, 2095DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
diff --git a/src/keyboard.c b/src/keyboard.c
index a6f43d216ff..33c39949c1d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -295,6 +295,7 @@ static struct input_event * volatile kbd_store_ptr;
295static Lisp_Object Qmouse_movement; 295static Lisp_Object Qmouse_movement;
296static Lisp_Object Qscroll_bar_movement; 296static Lisp_Object Qscroll_bar_movement;
297Lisp_Object Qswitch_frame; 297Lisp_Object Qswitch_frame;
298static Lisp_Object Qfocus_in, Qfocus_out;
298static Lisp_Object Qdelete_frame; 299static Lisp_Object Qdelete_frame;
299static Lisp_Object Qiconify_frame; 300static Lisp_Object Qiconify_frame;
300static Lisp_Object Qmake_frame_visible; 301static Lisp_Object Qmake_frame_visible;
@@ -359,7 +360,7 @@ Lisp_Object Qvertical_line;
359static Lisp_Object Qvertical_scroll_bar; 360static Lisp_Object Qvertical_scroll_bar;
360Lisp_Object Qmenu_bar; 361Lisp_Object Qmenu_bar;
361 362
362static Lisp_Object recursive_edit_unwind (Lisp_Object buffer); 363static void recursive_edit_unwind (Lisp_Object buffer);
363static Lisp_Object command_loop (void); 364static Lisp_Object command_loop (void);
364static Lisp_Object Qcommand_execute; 365static Lisp_Object Qcommand_execute;
365EMACS_TIME timer_check (void); 366EMACS_TIME timer_check (void);
@@ -423,12 +424,14 @@ static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object,
423 Lisp_Object, const char *const *, 424 Lisp_Object, const char *const *,
424 Lisp_Object *, ptrdiff_t); 425 Lisp_Object *, ptrdiff_t);
425static Lisp_Object make_lispy_switch_frame (Lisp_Object); 426static Lisp_Object make_lispy_switch_frame (Lisp_Object);
427static Lisp_Object make_lispy_focus_in (Lisp_Object);
428static Lisp_Object make_lispy_focus_out (Lisp_Object);
426static bool help_char_p (Lisp_Object); 429static bool help_char_p (Lisp_Object);
427static void save_getcjmp (sys_jmp_buf); 430static void save_getcjmp (sys_jmp_buf);
428static void restore_getcjmp (sys_jmp_buf); 431static void restore_getcjmp (sys_jmp_buf);
429static Lisp_Object apply_modifiers (int, Lisp_Object); 432static Lisp_Object apply_modifiers (int, Lisp_Object);
430static void clear_event (struct input_event *); 433static void clear_event (struct input_event *);
431static Lisp_Object restore_kboard_configuration (Lisp_Object); 434static void restore_kboard_configuration (int);
432#ifdef USABLE_SIGIO 435#ifdef USABLE_SIGIO
433static void deliver_input_available_signal (int signo); 436static void deliver_input_available_signal (int signo);
434#endif 437#endif
@@ -844,7 +847,7 @@ This function is called by the editor initialization to begin editing. */)
844 return unbind_to (count, Qnil); 847 return unbind_to (count, Qnil);
845} 848}
846 849
847Lisp_Object 850void
848recursive_edit_unwind (Lisp_Object buffer) 851recursive_edit_unwind (Lisp_Object buffer)
849{ 852{
850 if (BUFFERP (buffer)) 853 if (BUFFERP (buffer))
@@ -852,7 +855,6 @@ recursive_edit_unwind (Lisp_Object buffer)
852 855
853 command_loop_level--; 856 command_loop_level--;
854 update_mode_lines = 1; 857 update_mode_lines = 1;
855 return Qnil;
856} 858}
857 859
858 860
@@ -949,7 +951,7 @@ pop_kboard (void)
949 from which further input is accepted. If F is non-nil, set its 951 from which further input is accepted. If F is non-nil, set its
950 KBOARD as the current keyboard. 952 KBOARD as the current keyboard.
951 953
952 This function uses record_unwind_protect to return to the previous 954 This function uses record_unwind_protect_int to return to the previous
953 state later. 955 state later.
954 956
955 If Emacs is already in single_kboard mode, and F's keyboard is 957 If Emacs is already in single_kboard mode, and F's keyboard is
@@ -980,8 +982,7 @@ temporarily_switch_to_single_kboard (struct frame *f)
980 else if (f != NULL) 982 else if (f != NULL)
981 current_kboard = FRAME_KBOARD (f); 983 current_kboard = FRAME_KBOARD (f);
982 single_kboard = 1; 984 single_kboard = 1;
983 record_unwind_protect (restore_kboard_configuration, 985 record_unwind_protect_int (restore_kboard_configuration, was_locked);
984 (was_locked ? Qt : Qnil));
985} 986}
986 987
987#if 0 /* This function is not needed anymore. */ 988#if 0 /* This function is not needed anymore. */
@@ -990,26 +991,22 @@ record_single_kboard_state ()
990{ 991{
991 if (single_kboard) 992 if (single_kboard)
992 push_kboard (current_kboard); 993 push_kboard (current_kboard);
993 record_unwind_protect (restore_kboard_configuration, 994 record_unwind_protect_int (restore_kboard_configuration, single_kboard);
994 (single_kboard ? Qt : Qnil));
995} 995}
996#endif 996#endif
997 997
998static Lisp_Object 998static void
999restore_kboard_configuration (Lisp_Object was_locked) 999restore_kboard_configuration (int was_locked)
1000{ 1000{
1001 if (NILP (was_locked)) 1001 single_kboard = was_locked;
1002 single_kboard = 0; 1002 if (was_locked)
1003 else
1004 { 1003 {
1005 struct kboard *prev = current_kboard; 1004 struct kboard *prev = current_kboard;
1006 single_kboard = 1;
1007 pop_kboard (); 1005 pop_kboard ();
1008 /* The pop should not change the kboard. */ 1006 /* The pop should not change the kboard. */
1009 if (single_kboard && current_kboard != prev) 1007 if (single_kboard && current_kboard != prev)
1010 emacs_abort (); 1008 emacs_abort ();
1011 } 1009 }
1012 return Qnil;
1013} 1010}
1014 1011
1015 1012
@@ -1237,7 +1234,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
1237/* Restore mouse tracking enablement. See Ftrack_mouse for the only use 1234/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
1238 of this function. */ 1235 of this function. */
1239 1236
1240static Lisp_Object 1237static void
1241tracking_off (Lisp_Object old_value) 1238tracking_off (Lisp_Object old_value)
1242{ 1239{
1243 do_mouse_tracking = old_value; 1240 do_mouse_tracking = old_value;
@@ -1254,7 +1251,6 @@ tracking_off (Lisp_Object old_value)
1254 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW); 1251 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
1255 } 1252 }
1256 } 1253 }
1257 return Qnil;
1258} 1254}
1259 1255
1260DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, 1256DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0,
@@ -1317,17 +1313,6 @@ static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
1317void safe_run_hooks (Lisp_Object); 1313void safe_run_hooks (Lisp_Object);
1318static void adjust_point_for_property (ptrdiff_t, bool); 1314static void adjust_point_for_property (ptrdiff_t, bool);
1319 1315
1320/* Cancel hourglass from protect_unwind.
1321 ARG is not used. */
1322#ifdef HAVE_WINDOW_SYSTEM
1323static Lisp_Object
1324cancel_hourglass_unwind (Lisp_Object arg)
1325{
1326 cancel_hourglass ();
1327 return Qnil;
1328}
1329#endif
1330
1331/* The last boundary auto-added to buffer-undo-list. */ 1316/* The last boundary auto-added to buffer-undo-list. */
1332Lisp_Object last_undo_boundary; 1317Lisp_Object last_undo_boundary;
1333 1318
@@ -1430,7 +1415,7 @@ command_loop_1 (void)
1430 if (!NILP (Vquit_flag)) 1415 if (!NILP (Vquit_flag))
1431 { 1416 {
1432 Vquit_flag = Qnil; 1417 Vquit_flag = Qnil;
1433 Vunread_command_events = Fcons (make_number (quit_char), Qnil); 1418 Vunread_command_events = list1 (make_number (quit_char));
1434 } 1419 }
1435 } 1420 }
1436 1421
@@ -1562,7 +1547,7 @@ command_loop_1 (void)
1562 if (display_hourglass_p 1547 if (display_hourglass_p
1563 && NILP (Vexecuting_kbd_macro)) 1548 && NILP (Vexecuting_kbd_macro))
1564 { 1549 {
1565 record_unwind_protect (cancel_hourglass_unwind, Qnil); 1550 record_unwind_protect_void (cancel_hourglass);
1566 start_hourglass (); 1551 start_hourglass ();
1567 } 1552 }
1568#endif 1553#endif
@@ -2204,14 +2189,13 @@ static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
2204static void record_char (Lisp_Object c); 2189static void record_char (Lisp_Object c);
2205 2190
2206static Lisp_Object help_form_saved_window_configs; 2191static Lisp_Object help_form_saved_window_configs;
2207static Lisp_Object 2192static void
2208read_char_help_form_unwind (Lisp_Object arg) 2193read_char_help_form_unwind (void)
2209{ 2194{
2210 Lisp_Object window_config = XCAR (help_form_saved_window_configs); 2195 Lisp_Object window_config = XCAR (help_form_saved_window_configs);
2211 help_form_saved_window_configs = XCDR (help_form_saved_window_configs); 2196 help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
2212 if (!NILP (window_config)) 2197 if (!NILP (window_config))
2213 Fset_window_configuration (window_config); 2198 Fset_window_configuration (window_config);
2214 return Qnil;
2215} 2199}
2216 2200
2217#define STOP_POLLING \ 2201#define STOP_POLLING \
@@ -2258,9 +2242,9 @@ read_event_from_main_queue (EMACS_TIME *end_time,
2258 emacs_abort (); 2242 emacs_abort ();
2259 } 2243 }
2260 if (!CONSP (last)) 2244 if (!CONSP (last))
2261 kset_kbd_queue (kb, Fcons (c, Qnil)); 2245 kset_kbd_queue (kb, list1 (c));
2262 else 2246 else
2263 XSETCDR (last, Fcons (c, Qnil)); 2247 XSETCDR (last, list1 (c));
2264 kb->kbd_queue_has_data = 1; 2248 kb->kbd_queue_has_data = 1;
2265 c = Qnil; 2249 c = Qnil;
2266 if (single_kboard) 2250 if (single_kboard)
@@ -2682,9 +2666,9 @@ read_char (int commandflag, Lisp_Object map,
2682 emacs_abort (); 2666 emacs_abort ();
2683 } 2667 }
2684 if (!CONSP (last)) 2668 if (!CONSP (last))
2685 kset_kbd_queue (kb, Fcons (c, Qnil)); 2669 kset_kbd_queue (kb, list1 (c));
2686 else 2670 else
2687 XSETCDR (last, Fcons (c, Qnil)); 2671 XSETCDR (last, list1 (c));
2688 kb->kbd_queue_has_data = 1; 2672 kb->kbd_queue_has_data = 1;
2689 current_kboard = kb; 2673 current_kboard = kb;
2690 /* This is going to exit from read_char 2674 /* This is going to exit from read_char
@@ -3002,7 +2986,7 @@ read_char (int commandflag, Lisp_Object map,
3002 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) 2986 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
3003 { 2987 {
3004 /* Change menu-bar to (menu-bar) as the event "position". */ 2988 /* Change menu-bar to (menu-bar) as the event "position". */
3005 POSN_SET_POSN (EVENT_START (c), Fcons (posn, Qnil)); 2989 POSN_SET_POSN (EVENT_START (c), list1 (posn));
3006 2990
3007 also_record = c; 2991 also_record = c;
3008 Vunread_command_events = Fcons (c, Vunread_command_events); 2992 Vunread_command_events = Fcons (c, Vunread_command_events);
@@ -3199,7 +3183,7 @@ read_char (int commandflag, Lisp_Object map,
3199 help_form_saved_window_configs 3183 help_form_saved_window_configs
3200 = Fcons (Fcurrent_window_configuration (Qnil), 3184 = Fcons (Fcurrent_window_configuration (Qnil),
3201 help_form_saved_window_configs); 3185 help_form_saved_window_configs);
3202 record_unwind_protect (read_char_help_form_unwind, Qnil); 3186 record_unwind_protect_void (read_char_help_form_unwind);
3203 call0 (Qhelp_form_show); 3187 call0 (Qhelp_form_show);
3204 3188
3205 cancel_echoing (); 3189 cancel_echoing ();
@@ -3585,8 +3569,8 @@ kbd_buffer_store_event_hold (register struct input_event *event,
3585 if (single_kboard && kb != current_kboard) 3569 if (single_kboard && kb != current_kboard)
3586 { 3570 {
3587 kset_kbd_queue 3571 kset_kbd_queue
3588 (kb, Fcons (make_lispy_switch_frame (event->frame_or_window), 3572 (kb, list2 (make_lispy_switch_frame (event->frame_or_window),
3589 Fcons (make_number (c), Qnil))); 3573 make_number (c)));
3590 kb->kbd_queue_has_data = 1; 3574 kb->kbd_queue_has_data = 1;
3591 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) 3575 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
3592 { 3576 {
@@ -3949,9 +3933,9 @@ kbd_buffer_get_event (KBOARD **kbp,
3949 else if (event->kind == NS_TEXT_EVENT) 3933 else if (event->kind == NS_TEXT_EVENT)
3950 { 3934 {
3951 if (event->code == KEY_NS_PUT_WORKING_TEXT) 3935 if (event->code == KEY_NS_PUT_WORKING_TEXT)
3952 obj = Fcons (intern ("ns-put-working-text"), Qnil); 3936 obj = list1 (intern ("ns-put-working-text"));
3953 else 3937 else
3954 obj = Fcons (intern ("ns-unput-working-text"), Qnil); 3938 obj = list1 (intern ("ns-unput-working-text"));
3955 kbd_fetch_ptr = event + 1; 3939 kbd_fetch_ptr = event + 1;
3956 if (used_mouse_menu) 3940 if (used_mouse_menu)
3957 *used_mouse_menu = 1; 3941 *used_mouse_menu = 1;
@@ -3963,8 +3947,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3963 else if (event->kind == DELETE_WINDOW_EVENT) 3947 else if (event->kind == DELETE_WINDOW_EVENT)
3964 { 3948 {
3965 /* Make an event (delete-frame (FRAME)). */ 3949 /* Make an event (delete-frame (FRAME)). */
3966 obj = Fcons (event->frame_or_window, Qnil); 3950 obj = list2 (Qdelete_frame, list1 (event->frame_or_window));
3967 obj = Fcons (Qdelete_frame, Fcons (obj, Qnil));
3968 kbd_fetch_ptr = event + 1; 3951 kbd_fetch_ptr = event + 1;
3969 } 3952 }
3970#endif 3953#endif
@@ -3973,15 +3956,13 @@ kbd_buffer_get_event (KBOARD **kbp,
3973 else if (event->kind == ICONIFY_EVENT) 3956 else if (event->kind == ICONIFY_EVENT)
3974 { 3957 {
3975 /* Make an event (iconify-frame (FRAME)). */ 3958 /* Make an event (iconify-frame (FRAME)). */
3976 obj = Fcons (event->frame_or_window, Qnil); 3959 obj = list2 (Qiconify_frame, list1 (event->frame_or_window));
3977 obj = Fcons (Qiconify_frame, Fcons (obj, Qnil));
3978 kbd_fetch_ptr = event + 1; 3960 kbd_fetch_ptr = event + 1;
3979 } 3961 }
3980 else if (event->kind == DEICONIFY_EVENT) 3962 else if (event->kind == DEICONIFY_EVENT)
3981 { 3963 {
3982 /* Make an event (make-frame-visible (FRAME)). */ 3964 /* Make an event (make-frame-visible (FRAME)). */
3983 obj = Fcons (event->frame_or_window, Qnil); 3965 obj = list2 (Qmake_frame_visible, list1 (event->frame_or_window));
3984 obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil));
3985 kbd_fetch_ptr = event + 1; 3966 kbd_fetch_ptr = event + 1;
3986 } 3967 }
3987#endif 3968#endif
@@ -4004,11 +3985,11 @@ kbd_buffer_get_event (KBOARD **kbp,
4004#ifdef HAVE_NTGUI 3985#ifdef HAVE_NTGUI
4005 else if (event->kind == LANGUAGE_CHANGE_EVENT) 3986 else if (event->kind == LANGUAGE_CHANGE_EVENT)
4006 { 3987 {
4007 /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */ 3988 /* Make an event (language-change FRAME CODEPAGE LANGUAGE-ID). */
4008 obj = Fcons (Qlanguage_change, 3989 obj = list4 (Qlanguage_change,
4009 list3 (event->frame_or_window, 3990 event->frame_or_window,
4010 make_number (event->code), 3991 make_number (event->code),
4011 make_number (event->modifiers))); 3992 make_number (event->modifiers));
4012 kbd_fetch_ptr = event + 1; 3993 kbd_fetch_ptr = event + 1;
4013 } 3994 }
4014#endif 3995#endif
@@ -4017,11 +3998,11 @@ kbd_buffer_get_event (KBOARD **kbp,
4017 { 3998 {
4018#ifdef HAVE_W32NOTIFY 3999#ifdef HAVE_W32NOTIFY
4019 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */ 4000 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
4020 obj = Fcons (Qfile_notify, 4001 obj = list3 (Qfile_notify,
4021 list2 (list3 (make_number (event->code), 4002 list3 (make_number (event->code),
4022 XCAR (event->arg), 4003 XCAR (event->arg),
4023 XCDR (event->arg)), 4004 XCDR (event->arg)),
4024 event->frame_or_window)); 4005 event->frame_or_window);
4025#else 4006#else
4026 obj = make_lispy_event (event); 4007 obj = make_lispy_event (event);
4027#endif 4008#endif
@@ -4030,7 +4011,7 @@ kbd_buffer_get_event (KBOARD **kbp,
4030#endif /* USE_FILE_NOTIFY */ 4011#endif /* USE_FILE_NOTIFY */
4031 else if (event->kind == SAVE_SESSION_EVENT) 4012 else if (event->kind == SAVE_SESSION_EVENT)
4032 { 4013 {
4033 obj = Fcons (Qsave_session, Fcons (event->arg, Qnil)); 4014 obj = list2 (Qsave_session, event->arg);
4034 kbd_fetch_ptr = event + 1; 4015 kbd_fetch_ptr = event + 1;
4035 } 4016 }
4036 /* Just discard these, by returning nil. 4017 /* Just discard these, by returning nil.
@@ -4067,17 +4048,43 @@ kbd_buffer_get_event (KBOARD **kbp,
4067 switch-frame event if necessary. */ 4048 switch-frame event if necessary. */
4068 Lisp_Object frame, focus; 4049 Lisp_Object frame, focus;
4069 4050
4070 frame = event->frame_or_window; 4051 frame = event->frame_or_window;
4071 focus = FRAME_FOCUS_FRAME (XFRAME (frame)); 4052 focus = FRAME_FOCUS_FRAME (XFRAME (frame));
4072 if (FRAMEP (focus)) 4053 if (FRAMEP (focus))
4073 frame = focus; 4054 frame = focus;
4074 4055
4075 if (!EQ (frame, internal_last_event_frame) 4056 if (
4076 && !EQ (frame, selected_frame)) 4057#ifdef HAVE_X11
4077 obj = make_lispy_switch_frame (frame); 4058 ! NILP (event->arg)
4078 internal_last_event_frame = frame; 4059 &&
4079 kbd_fetch_ptr = event + 1; 4060#endif
4080 } 4061 !EQ (frame, internal_last_event_frame)
4062 && !EQ (frame, selected_frame))
4063 obj = make_lispy_switch_frame (frame);
4064 else
4065 obj = make_lispy_focus_in (frame);
4066
4067 internal_last_event_frame = frame;
4068 kbd_fetch_ptr = event + 1;
4069 }
4070 else if (event->kind == FOCUS_OUT_EVENT)
4071 {
4072#ifdef HAVE_WINDOW_SYSTEM
4073
4074 Display_Info *di;
4075 Lisp_Object frame = event->frame_or_window;
4076 bool focused = false;
4077
4078 for (di = x_display_list; di && ! focused; di = di->next)
4079 focused = di->x_highlight_frame != 0;
4080
4081 if (!focused)
4082 obj = make_lispy_focus_out (frame);
4083
4084#endif /* HAVE_WINDOW_SYSTEM */
4085
4086 kbd_fetch_ptr = event + 1;
4087 }
4081#ifdef HAVE_DBUS 4088#ifdef HAVE_DBUS
4082 else if (event->kind == DBUS_EVENT) 4089 else if (event->kind == DBUS_EVENT)
4083 { 4090 {
@@ -5572,14 +5579,12 @@ make_lispy_event (struct input_event *event)
5572 5579
5573 /* ELisp manual 2.4b says (x y) are window relative but 5580 /* ELisp manual 2.4b says (x y) are window relative but
5574 code says they are frame-relative. */ 5581 code says they are frame-relative. */
5575 position 5582 position = list4 (event->frame_or_window,
5576 = Fcons (event->frame_or_window, 5583 Qmenu_bar,
5577 Fcons (Qmenu_bar, 5584 Fcons (event->x, event->y),
5578 Fcons (Fcons (event->x, event->y), 5585 make_number (event->timestamp));
5579 Fcons (make_number (event->timestamp), 5586
5580 Qnil)))); 5587 return list2 (item, position);
5581
5582 return Fcons (item, Fcons (position, Qnil));
5583 } 5588 }
5584#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */ 5589#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */
5585 5590
@@ -5598,12 +5603,9 @@ make_lispy_event (struct input_event *event)
5598 portion_whole = Fcons (event->x, event->y); 5603 portion_whole = Fcons (event->x, event->y);
5599 part = *scroll_bar_parts[(int) event->part]; 5604 part = *scroll_bar_parts[(int) event->part];
5600 5605
5601 position 5606 position = list5 (window, Qvertical_scroll_bar,
5602 = Fcons (window, 5607 portion_whole, make_number (event->timestamp),
5603 Fcons (Qvertical_scroll_bar, 5608 part);
5604 Fcons (portion_whole,
5605 Fcons (make_number (event->timestamp),
5606 Fcons (part, Qnil)))));
5607 } 5609 }
5608#endif /* not USE_TOOLKIT_SCROLL_BARS */ 5610#endif /* not USE_TOOLKIT_SCROLL_BARS */
5609 5611
@@ -5751,19 +5753,11 @@ make_lispy_event (struct input_event *event)
5751 &mouse_syms, 5753 &mouse_syms,
5752 ASIZE (mouse_syms)); 5754 ASIZE (mouse_syms));
5753 if (event->modifiers & drag_modifier) 5755 if (event->modifiers & drag_modifier)
5754 return Fcons (head, 5756 return list3 (head, start_pos, position);
5755 Fcons (start_pos,
5756 Fcons (position,
5757 Qnil)));
5758 else if (event->modifiers & (double_modifier | triple_modifier)) 5757 else if (event->modifiers & (double_modifier | triple_modifier))
5759 return Fcons (head, 5758 return list3 (head, position, make_number (double_click_count));
5760 Fcons (position,
5761 Fcons (make_number (double_click_count),
5762 Qnil)));
5763 else 5759 else
5764 return Fcons (head, 5760 return list2 (head, position);
5765 Fcons (position,
5766 Qnil));
5767 } 5761 }
5768 } 5762 }
5769 5763
@@ -5862,14 +5856,9 @@ make_lispy_event (struct input_event *event)
5862 } 5856 }
5863 5857
5864 if (event->modifiers & (double_modifier | triple_modifier)) 5858 if (event->modifiers & (double_modifier | triple_modifier))
5865 return Fcons (head, 5859 return list3 (head, position, make_number (double_click_count));
5866 Fcons (position,
5867 Fcons (make_number (double_click_count),
5868 Qnil)));
5869 else 5860 else
5870 return Fcons (head, 5861 return list2 (head, position);
5871 Fcons (position,
5872 Qnil));
5873 } 5862 }
5874 5863
5875 5864
@@ -5900,12 +5889,8 @@ make_lispy_event (struct input_event *event)
5900 portion_whole = Fcons (event->x, event->y); 5889 portion_whole = Fcons (event->x, event->y);
5901 part = *scroll_bar_parts[(int) event->part]; 5890 part = *scroll_bar_parts[(int) event->part];
5902 5891
5903 position 5892 position = list5 (window, Qvertical_scroll_bar, portion_whole,
5904 = Fcons (window, 5893 make_number (event->timestamp), part);
5905 Fcons (Qvertical_scroll_bar,
5906 Fcons (portion_whole,
5907 Fcons (make_number (event->timestamp),
5908 Fcons (part, Qnil)))));
5909 5894
5910 /* Always treat scroll bar events as clicks. */ 5895 /* Always treat scroll bar events as clicks. */
5911 event->modifiers |= click_modifier; 5896 event->modifiers |= click_modifier;
@@ -5923,7 +5908,7 @@ make_lispy_event (struct input_event *event)
5923 Vlispy_mouse_stem, 5908 Vlispy_mouse_stem,
5924 NULL, &mouse_syms, 5909 NULL, &mouse_syms,
5925 ASIZE (mouse_syms)); 5910 ASIZE (mouse_syms));
5926 return Fcons (head, Fcons (position, Qnil)); 5911 return list2 (head, position);
5927 } 5912 }
5928 5913
5929#endif /* USE_TOOLKIT_SCROLL_BARS */ 5914#endif /* USE_TOOLKIT_SCROLL_BARS */
@@ -5949,10 +5934,7 @@ make_lispy_event (struct input_event *event)
5949 Qdrag_n_drop, Qnil, 5934 Qdrag_n_drop, Qnil,
5950 lispy_drag_n_drop_names, 5935 lispy_drag_n_drop_names,
5951 &drag_n_drop_syms, 1); 5936 &drag_n_drop_syms, 1);
5952 return Fcons (head, 5937 return list3 (head, position, files);
5953 Fcons (position,
5954 Fcons (files,
5955 Qnil)));
5956 } 5938 }
5957 5939
5958#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ 5940#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
@@ -5962,22 +5944,20 @@ make_lispy_event (struct input_event *event)
5962 /* This is the prefix key. We translate this to 5944 /* This is the prefix key. We translate this to
5963 `(menu_bar)' because the code in keyboard.c for menu 5945 `(menu_bar)' because the code in keyboard.c for menu
5964 events, which we use, relies on this. */ 5946 events, which we use, relies on this. */
5965 return Fcons (Qmenu_bar, Qnil); 5947 return list1 (Qmenu_bar);
5966 return event->arg; 5948 return event->arg;
5967#endif 5949#endif
5968 5950
5969 case SELECT_WINDOW_EVENT: 5951 case SELECT_WINDOW_EVENT:
5970 /* Make an event (select-window (WINDOW)). */ 5952 /* Make an event (select-window (WINDOW)). */
5971 return Fcons (Qselect_window, 5953 return list2 (Qselect_window, list1 (event->frame_or_window));
5972 Fcons (Fcons (event->frame_or_window, Qnil),
5973 Qnil));
5974 5954
5975 case TOOL_BAR_EVENT: 5955 case TOOL_BAR_EVENT:
5976 if (EQ (event->arg, event->frame_or_window)) 5956 if (EQ (event->arg, event->frame_or_window))
5977 /* This is the prefix key. We translate this to 5957 /* This is the prefix key. We translate this to
5978 `(tool_bar)' because the code in keyboard.c for tool bar 5958 `(tool_bar)' because the code in keyboard.c for tool bar
5979 events, which we use, relies on this. */ 5959 events, which we use, relies on this. */
5980 return Fcons (Qtool_bar, Qnil); 5960 return list1 (Qtool_bar);
5981 else if (SYMBOLP (event->arg)) 5961 else if (SYMBOLP (event->arg))
5982 return apply_modifiers (event->modifiers, event->arg); 5962 return apply_modifiers (event->modifiers, event->arg);
5983 return event->arg; 5963 return event->arg;
@@ -6018,9 +5998,8 @@ make_lispy_event (struct input_event *event)
6018#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */ 5998#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
6019 5999
6020 case CONFIG_CHANGED_EVENT: 6000 case CONFIG_CHANGED_EVENT:
6021 return Fcons (Qconfig_changed_event, 6001 return list3 (Qconfig_changed_event,
6022 Fcons (event->arg, 6002 event->arg, event->frame_or_window);
6023 Fcons (event->frame_or_window, Qnil)));
6024#ifdef HAVE_GPM 6003#ifdef HAVE_GPM
6025 case GPM_CLICK_EVENT: 6004 case GPM_CLICK_EVENT:
6026 { 6005 {
@@ -6061,24 +6040,13 @@ make_lispy_event (struct input_event *event)
6061 ASIZE (mouse_syms)); 6040 ASIZE (mouse_syms));
6062 6041
6063 if (event->modifiers & drag_modifier) 6042 if (event->modifiers & drag_modifier)
6064 return Fcons (head, 6043 return list3 (head, start_pos, position);
6065 Fcons (start_pos,
6066 Fcons (position,
6067 Qnil)));
6068 else if (event->modifiers & double_modifier) 6044 else if (event->modifiers & double_modifier)
6069 return Fcons (head, 6045 return list3 (head, position, make_number (2));
6070 Fcons (position,
6071 Fcons (make_number (2),
6072 Qnil)));
6073 else if (event->modifiers & triple_modifier) 6046 else if (event->modifiers & triple_modifier)
6074 return Fcons (head, 6047 return list3 (head, position, make_number (3));
6075 Fcons (position,
6076 Fcons (make_number (3),
6077 Qnil)));
6078 else 6048 else
6079 return Fcons (head, 6049 return list2 (head, position);
6080 Fcons (position,
6081 Qnil));
6082 } 6050 }
6083#endif /* HAVE_GPM */ 6051#endif /* HAVE_GPM */
6084 6052
@@ -6098,13 +6066,12 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
6098 Lisp_Object part_sym; 6066 Lisp_Object part_sym;
6099 6067
6100 part_sym = *scroll_bar_parts[(int) part]; 6068 part_sym = *scroll_bar_parts[(int) part];
6101 return Fcons (Qscroll_bar_movement, 6069 return list2 (Qscroll_bar_movement,
6102 Fcons (list5 (bar_window, 6070 list5 (bar_window,
6103 Qvertical_scroll_bar, 6071 Qvertical_scroll_bar,
6104 Fcons (x, y), 6072 Fcons (x, y),
6105 make_number (t), 6073 make_number (t),
6106 part_sym), 6074 part_sym));
6107 Qnil));
6108 } 6075 }
6109 /* Or is it an ordinary mouse movement? */ 6076 /* Or is it an ordinary mouse movement? */
6110 else 6077 else
@@ -6119,7 +6086,18 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
6119static Lisp_Object 6086static Lisp_Object
6120make_lispy_switch_frame (Lisp_Object frame) 6087make_lispy_switch_frame (Lisp_Object frame)
6121{ 6088{
6122 return Fcons (Qswitch_frame, Fcons (frame, Qnil)); 6089 return list2 (Qswitch_frame, frame);
6090}
6091
6092static Lisp_Object
6093make_lispy_focus_in (Lisp_Object frame)
6094{
6095 return list2 (Qfocus_in, frame);
6096}
6097static Lisp_Object
6098make_lispy_focus_out (Lisp_Object frame)
6099{
6100 return list2 (Qfocus_out, frame);
6123} 6101}
6124 6102
6125/* Manipulating modifiers. */ 6103/* Manipulating modifiers. */
@@ -6352,7 +6330,7 @@ parse_modifiers (Lisp_Object symbol)
6352 if (modifiers & ~INTMASK) 6330 if (modifiers & ~INTMASK)
6353 emacs_abort (); 6331 emacs_abort ();
6354 XSETFASTINT (mask, modifiers); 6332 XSETFASTINT (mask, modifiers);
6355 elements = Fcons (unmodified, Fcons (mask, Qnil)); 6333 elements = list2 (unmodified, mask);
6356 6334
6357 /* Cache the parsing results on SYMBOL. */ 6335 /* Cache the parsing results on SYMBOL. */
6358 Fput (symbol, Qevent_symbol_element_mask, 6336 Fput (symbol, Qevent_symbol_element_mask,
@@ -6425,7 +6403,7 @@ apply_modifiers (int modifiers, Lisp_Object base)
6425 the caches: 6403 the caches:
6426 XSETFASTINT (idx, modifiers); 6404 XSETFASTINT (idx, modifiers);
6427 Fput (new_symbol, Qevent_symbol_element_mask, 6405 Fput (new_symbol, Qevent_symbol_element_mask,
6428 Fcons (base, Fcons (idx, Qnil))); 6406 list2 (base, idx));
6429 Fput (new_symbol, Qevent_symbol_elements, 6407 Fput (new_symbol, Qevent_symbol_elements,
6430 Fcons (base, lispy_modifier_list (modifiers))); 6408 Fcons (base, lispy_modifier_list (modifiers)));
6431 Sadly, this is only correct if `base' is indeed a base event, 6409 Sadly, this is only correct if `base' is indeed a base event,
@@ -7577,7 +7555,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
7577 ASET (menu_bar_items_vector, i, key); i++; 7555 ASET (menu_bar_items_vector, i, key); i++;
7578 ASET (menu_bar_items_vector, i, 7556 ASET (menu_bar_items_vector, i,
7579 AREF (item_properties, ITEM_PROPERTY_NAME)); i++; 7557 AREF (item_properties, ITEM_PROPERTY_NAME)); i++;
7580 ASET (menu_bar_items_vector, i, Fcons (item, Qnil)); i++; 7558 ASET (menu_bar_items_vector, i, list1 (item)); i++;
7581 ASET (menu_bar_items_vector, i, make_number (0)); i++; 7559 ASET (menu_bar_items_vector, i, make_number (0)); i++;
7582 menu_bar_items_index = i; 7560 menu_bar_items_index = i;
7583 } 7561 }
@@ -8132,7 +8110,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
8132 8110
8133 /* As an exception, allow old-style menu separators. */ 8111 /* As an exception, allow old-style menu separators. */
8134 if (STRINGP (XCAR (item))) 8112 if (STRINGP (XCAR (item)))
8135 item = Fcons (XCAR (item), Qnil); 8113 item = list1 (XCAR (item));
8136 else if (!EQ (XCAR (item), Qmenu_item) 8114 else if (!EQ (XCAR (item), Qmenu_item)
8137 || (item = XCDR (item), !CONSP (item))) 8115 || (item = XCDR (item), !CONSP (item)))
8138 return 0; 8116 return 0;
@@ -9364,8 +9342,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9364 9342
9365 /* Zap the position in key, so we know that we've 9343 /* Zap the position in key, so we know that we've
9366 expanded it, and don't try to do so again. */ 9344 expanded it, and don't try to do so again. */
9367 POSN_SET_POSN (EVENT_START (key), 9345 POSN_SET_POSN (EVENT_START (key), list1 (posn));
9368 Fcons (posn, Qnil));
9369 9346
9370 mock_input = t + 2; 9347 mock_input = t + 2;
9371 goto replay_sequence; 9348 goto replay_sequence;
@@ -9520,8 +9497,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9520 9497
9521 new_head 9498 new_head
9522 = apply_modifiers (modifiers, XCAR (breakdown)); 9499 = apply_modifiers (modifiers, XCAR (breakdown));
9523 new_click 9500 new_click = list2 (new_head, EVENT_START (key));
9524 = Fcons (new_head, Fcons (EVENT_START (key), Qnil));
9525 9501
9526 /* Look for a binding for this new key. */ 9502 /* Look for a binding for this new key. */
9527 new_binding = follow_key (current_binding, new_click); 9503 new_binding = follow_key (current_binding, new_click);
@@ -10157,7 +10133,7 @@ The file will be closed when Emacs exits. */)
10157 file = Fexpand_file_name (file, Qnil); 10133 file = Fexpand_file_name (file, Qnil);
10158 dribble = emacs_fopen (SSDATA (file), "w"); 10134 dribble = emacs_fopen (SSDATA (file), "w");
10159 if (dribble == 0) 10135 if (dribble == 0)
10160 report_file_error ("Opening dribble", Fcons (file, Qnil)); 10136 report_file_error ("Opening dribble", file);
10161 } 10137 }
10162 return Qnil; 10138 return Qnil;
10163} 10139}
@@ -10222,8 +10198,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10222 reset_all_sys_modes (); 10198 reset_all_sys_modes ();
10223 /* sys_suspend can get an error if it tries to fork a subshell 10199 /* sys_suspend can get an error if it tries to fork a subshell
10224 and the system resources aren't available for that. */ 10200 and the system resources aren't available for that. */
10225 record_unwind_protect ((Lisp_Object (*) (Lisp_Object)) init_all_sys_modes, 10201 record_unwind_protect_void (init_all_sys_modes);
10226 Qnil);
10227 stuff_buffered_input (stuffstring); 10202 stuff_buffered_input (stuffstring);
10228 if (cannot_suspend) 10203 if (cannot_suspend)
10229 sys_subshell (); 10204 sys_subshell ();
@@ -10982,6 +10957,8 @@ static const struct event_head head_table[] = {
10982 {&Qmouse_movement, "mouse-movement", &Qmouse_movement}, 10957 {&Qmouse_movement, "mouse-movement", &Qmouse_movement},
10983 {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement}, 10958 {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement},
10984 {&Qswitch_frame, "switch-frame", &Qswitch_frame}, 10959 {&Qswitch_frame, "switch-frame", &Qswitch_frame},
10960 {&Qfocus_in, "focus-in", &Qfocus_in},
10961 {&Qfocus_out, "focus-out", &Qfocus_out},
10985 {&Qdelete_frame, "delete-frame", &Qdelete_frame}, 10962 {&Qdelete_frame, "delete-frame", &Qdelete_frame},
10986 {&Qiconify_frame, "iconify-frame", &Qiconify_frame}, 10963 {&Qiconify_frame, "iconify-frame", &Qiconify_frame},
10987 {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible}, 10964 {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible},
@@ -11109,7 +11086,7 @@ syms_of_keyboard (void)
11109 *p->var = intern_c_string (p->name); 11086 *p->var = intern_c_string (p->name);
11110 staticpro (p->var); 11087 staticpro (p->var);
11111 Fput (*p->var, Qevent_kind, *p->kind); 11088 Fput (*p->var, Qevent_kind, *p->kind);
11112 Fput (*p->var, Qevent_symbol_elements, Fcons (*p->var, Qnil)); 11089 Fput (*p->var, Qevent_symbol_elements, list1 (*p->var));
11113 } 11090 }
11114 } 11091 }
11115 11092
@@ -11504,7 +11481,7 @@ and the minor mode maps regardless of `overriding-local-map'. */);
11504 11481
11505 DEFVAR_LISP ("special-event-map", Vspecial_event_map, 11482 DEFVAR_LISP ("special-event-map", Vspecial_event_map,
11506 doc: /* Keymap defining bindings for special events to execute at low level. */); 11483 doc: /* Keymap defining bindings for special events to execute at low level. */);
11507 Vspecial_event_map = Fcons (intern_c_string ("keymap"), Qnil); 11484 Vspecial_event_map = list1 (intern_c_string ("keymap"));
11508 11485
11509 DEFVAR_LISP ("track-mouse", do_mouse_tracking, 11486 DEFVAR_LISP ("track-mouse", do_mouse_tracking,
11510 doc: /* Non-nil means generate motion events for mouse motion. */); 11487 doc: /* Non-nil means generate motion events for mouse motion. */);
@@ -11800,6 +11777,10 @@ keys_of_keyboard (void)
11800 initial_define_lispy_key (Vspecial_event_map, "language-change", 11777 initial_define_lispy_key (Vspecial_event_map, "language-change",
11801 "ignore"); 11778 "ignore");
11802#endif 11779#endif
11780 initial_define_lispy_key (Vspecial_event_map, "focus-in",
11781 "handle-focus-in");
11782 initial_define_lispy_key (Vspecial_event_map, "focus-out",
11783 "handle-focus-out");
11803} 11784}
11804 11785
11805/* Mark the pointers in the kboard objects. 11786/* Mark the pointers in the kboard objects.
diff --git a/src/keyboard.h b/src/keyboard.h
index 8bb1c409efc..daba94898d8 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -341,7 +341,7 @@ enum menu_item_idx
341 MENU_ITEMS_ITEM_LENGTH 341 MENU_ITEMS_ITEM_LENGTH
342}; 342};
343 343
344extern Lisp_Object unuse_menu_items (Lisp_Object dummy); 344extern void unuse_menu_items (void);
345 345
346/* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU 346/* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU
347 isn't defined. The use of HAVE_MULTILINGUAL_MENU could probably be 347 isn't defined. The use of HAVE_MULTILINGUAL_MENU could probably be
diff --git a/src/keymap.c b/src/keymap.c
index d29d5636e1c..d13a6274347 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -129,7 +129,7 @@ in case you use it as a menu with `x-popup-menu'. */)
129{ 129{
130 Lisp_Object tail; 130 Lisp_Object tail;
131 if (!NILP (string)) 131 if (!NILP (string))
132 tail = Fcons (string, Qnil); 132 tail = list1 (string);
133 else 133 else
134 tail = Qnil; 134 tail = Qnil;
135 return Fcons (Qkeymap, 135 return Fcons (Qkeymap,
@@ -151,9 +151,9 @@ in case you use it as a menu with `x-popup-menu'. */)
151 { 151 {
152 if (!NILP (Vpurify_flag)) 152 if (!NILP (Vpurify_flag))
153 string = Fpurecopy (string); 153 string = Fpurecopy (string);
154 return Fcons (Qkeymap, Fcons (string, Qnil)); 154 return list2 (Qkeymap, string);
155 } 155 }
156 return Fcons (Qkeymap, Qnil); 156 return list1 (Qkeymap);
157} 157}
158 158
159/* This function is used for installing the standard key bindings 159/* This function is used for installing the standard key bindings
@@ -534,12 +534,12 @@ access_keymap_1 (Lisp_Object map, Lisp_Object idx,
534 retval = val; 534 retval = val;
535 else if (CONSP (retval_tail)) 535 else if (CONSP (retval_tail))
536 { 536 {
537 XSETCDR (retval_tail, Fcons (val, Qnil)); 537 XSETCDR (retval_tail, list1 (val));
538 retval_tail = XCDR (retval_tail); 538 retval_tail = XCDR (retval_tail);
539 } 539 }
540 else 540 else
541 { 541 {
542 retval_tail = Fcons (val, Qnil); 542 retval_tail = list1 (val);
543 retval = Fcons (Qkeymap, Fcons (retval, retval_tail)); 543 retval = Fcons (Qkeymap, Fcons (retval, retval_tail));
544 } 544 }
545 } 545 }
@@ -617,8 +617,8 @@ map_keymap_internal (Lisp_Object map,
617 } 617 }
618 else if (CHAR_TABLE_P (binding)) 618 else if (CHAR_TABLE_P (binding))
619 map_char_table (map_keymap_char_table_item, Qnil, binding, 619 map_char_table (map_keymap_char_table_item, Qnil, binding,
620 make_save_value (SAVE_TYPE_FUNCPTR_PTR_OBJ, 620 make_save_funcptr_ptr_obj ((voidfuncptr) fun, data,
621 (voidfuncptr) fun, data, args)); 621 args));
622 } 622 }
623 UNGCPRO; 623 UNGCPRO;
624 return tail; 624 return tail;
@@ -1045,9 +1045,9 @@ However, a key definition which is a symbol whose definition is a keymap
1045is not copied. */) 1045is not copied. */)
1046 (Lisp_Object keymap) 1046 (Lisp_Object keymap)
1047{ 1047{
1048 register Lisp_Object copy, tail; 1048 Lisp_Object copy, tail;
1049 keymap = get_keymap (keymap, 1, 0); 1049 keymap = get_keymap (keymap, 1, 0);
1050 copy = tail = Fcons (Qkeymap, Qnil); 1050 copy = tail = list1 (Qkeymap);
1051 keymap = XCDR (keymap); /* Skip the `keymap' symbol. */ 1051 keymap = XCDR (keymap); /* Skip the `keymap' symbol. */
1052 1052
1053 while (CONSP (keymap) && !EQ (XCAR (keymap), Qkeymap)) 1053 while (CONSP (keymap) && !EQ (XCAR (keymap), Qkeymap))
@@ -1073,7 +1073,7 @@ is not copied. */)
1073 else 1073 else
1074 elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt))); 1074 elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt)));
1075 } 1075 }
1076 XSETCDR (tail, Fcons (elt, Qnil)); 1076 XSETCDR (tail, list1 (elt));
1077 tail = XCDR (tail); 1077 tail = XCDR (tail);
1078 keymap = XCDR (keymap); 1078 keymap = XCDR (keymap);
1079 } 1079 }
@@ -1341,8 +1341,7 @@ append_key (Lisp_Object key_sequence, Lisp_Object key)
1341 Lisp_Object args[2]; 1341 Lisp_Object args[2];
1342 1342
1343 args[0] = key_sequence; 1343 args[0] = key_sequence;
1344 1344 args[1] = list1 (key);
1345 args[1] = Fcons (key, Qnil);
1346 return Fvconcat (2, args); 1345 return Fvconcat (2, args);
1347} 1346}
1348 1347
@@ -1549,7 +1548,7 @@ like in the respective argument of `key-binding'. */)
1549{ 1548{
1550 ptrdiff_t count = SPECPDL_INDEX (); 1549 ptrdiff_t count = SPECPDL_INDEX ();
1551 1550
1552 Lisp_Object keymaps = Fcons (current_global_map, Qnil); 1551 Lisp_Object keymaps = list1 (current_global_map);
1553 1552
1554 /* If a mouse click position is given, our variables are based on 1553 /* If a mouse click position is given, our variables are based on
1555 the buffer clicked on, not the current buffer. So we may have to 1554 the buffer clicked on, not the current buffer. So we may have to
@@ -1809,7 +1808,7 @@ bindings; see the description of `lookup-key' for more details about this. */)
1809 if (KEYMAPP (binding)) 1808 if (KEYMAPP (binding))
1810 maps[j++] = Fcons (modes[i], binding); 1809 maps[j++] = Fcons (modes[i], binding);
1811 else if (j == 0) 1810 else if (j == 0)
1812 RETURN_UNGCPRO (Fcons (Fcons (modes[i], binding), Qnil)); 1811 RETURN_UNGCPRO (list1 (Fcons (modes[i], binding)));
1813 } 1812 }
1814 1813
1815 UNGCPRO; 1814 UNGCPRO;
@@ -1951,7 +1950,7 @@ accessible_keymaps_1 (Lisp_Object key, Lisp_Object cmd, Lisp_Object args, void *
1951 else 1950 else
1952 { 1951 {
1953 tem = append_key (thisseq, key); 1952 tem = append_key (thisseq, key);
1954 nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil)); 1953 nconc2 (tail, list1 (Fcons (tem, cmd)));
1955 } 1954 }
1956} 1955}
1957 1956
@@ -2005,13 +2004,13 @@ then the value includes only maps for prefixes that start with PREFIX. */)
2005 } 2004 }
2006 prefix = copy; 2005 prefix = copy;
2007 } 2006 }
2008 maps = Fcons (Fcons (prefix, tem), Qnil); 2007 maps = list1 (Fcons (prefix, tem));
2009 } 2008 }
2010 else 2009 else
2011 return Qnil; 2010 return Qnil;
2012 } 2011 }
2013 else 2012 else
2014 maps = Fcons (Fcons (zero_vector, get_keymap (keymap, 1, 0)), Qnil); 2013 maps = list1 (Fcons (zero_vector, get_keymap (keymap, 1, 0)));
2015 2014
2016 /* For each map in the list maps, 2015 /* For each map in the list maps,
2017 look at any other maps it points to, 2016 look at any other maps it points to,
@@ -2619,7 +2618,7 @@ The optional 5th arg NO-REMAP alters how command remapping is handled:
2619 if (CONSP (keymap) && KEYMAPP (XCAR (keymap))) 2618 if (CONSP (keymap) && KEYMAPP (XCAR (keymap)))
2620 keymaps = keymap; 2619 keymaps = keymap;
2621 else if (!NILP (keymap)) 2620 else if (!NILP (keymap))
2622 keymaps = Fcons (keymap, Fcons (current_global_map, Qnil)); 2621 keymaps = list2 (keymap, current_global_map);
2623 else 2622 else
2624 keymaps = Fcurrent_active_maps (Qnil, Qnil); 2623 keymaps = Fcurrent_active_maps (Qnil, Qnil);
2625 2624
diff --git a/src/lisp.h b/src/lisp.h
index e194a1ef765..26238113173 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -441,8 +441,7 @@ enum Lisp_Fwd_Type
441 displayed to users. These are Lisp_Save_Value, a Lisp_Misc 441 displayed to users. These are Lisp_Save_Value, a Lisp_Misc
442 subtype; and PVEC_OTHER, a kind of vectorlike object. The former 442 subtype; and PVEC_OTHER, a kind of vectorlike object. The former
443 is suitable for temporarily stashing away pointers and integers in 443 is suitable for temporarily stashing away pointers and integers in
444 a Lisp object (see the existing uses of make_save_value and 444 a Lisp object. The latter is useful for vector-like Lisp objects
445 XSAVE_VALUE). The latter is useful for vector-like Lisp objects
446 that need to be used as part of other objects, but which are never 445 that need to be used as part of other objects, but which are never
447 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for 446 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for
448 an example). 447 an example).
@@ -1819,46 +1818,27 @@ enum Lisp_Save_Type
1819/* Special object used to hold a different values for later use. 1818/* Special object used to hold a different values for later use.
1820 1819
1821 This is mostly used to package C integers and pointers to call 1820 This is mostly used to package C integers and pointers to call
1822 record_unwind_protect. A typical task is to pass just one C object 1821 record_unwind_protect when two or more values need to be saved.
1823 pointer to the unwind function. You should pack an object pointer with 1822 For example:
1824 make_save_pointer and then get it back with XSAVE_POINTER, e.g.:
1825 1823
1826 ... 1824 ...
1827 struct my_data *md = get_my_data (); 1825 struct my_data *md = get_my_data ();
1828 record_unwind_protect (my_unwind, make_save_pointer (md)); 1826 ptrdiff_t mi = get_my_integer ();
1827 record_unwind_protect (my_unwind, make_save_ptr_int (md, mi));
1829 ... 1828 ...
1830 1829
1831 Lisp_Object my_unwind (Lisp_Object arg) 1830 Lisp_Object my_unwind (Lisp_Object arg)
1832 { 1831 {
1833 struct my_data *md = XSAVE_POINTER (arg, 0); 1832 struct my_data *md = XSAVE_POINTER (arg, 0);
1834 ... 1833 ptrdiff_t mi = XSAVE_INTEGER (arg, 1);
1835 }
1836
1837 If you need to pass something else you can use make_save_value,
1838 which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers,
1839 function pointers or Lisp_Objects and conveniently get them back
1840 with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and
1841 XSAVE_OBJECT macros:
1842
1843 ...
1844 struct my_data *md = get_my_data ();
1845 Lisp_Object my_object = get_my_object ();
1846 record_unwind_protect
1847 (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object));
1848 ...
1849
1850 Lisp_Object my_unwind (Lisp_Object arg)
1851 {
1852 struct my_data *md = XSAVE_POINTER (arg, 0);
1853 Lisp_Object my_object = XSAVE_OBJECT (arg, 1);
1854 ... 1834 ...
1855 } 1835 }
1856 1836
1857 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the 1837 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the
1858 saved objects and raise eassert if type of the saved object doesn't match 1838 saved objects and raise eassert if type of the saved object doesn't match
1859 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) 1839 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2)
1860 or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and 1840 and XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and
1861 Lisp_Object was saved in slot 1 of ARG. */ 1841 slot 0 is a pointer. */
1862 1842
1863typedef void (*voidfuncptr) (void); 1843typedef void (*voidfuncptr) (void);
1864 1844
@@ -1868,12 +1848,13 @@ struct Lisp_Save_Value
1868 unsigned gcmarkbit : 1; 1848 unsigned gcmarkbit : 1;
1869 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS); 1849 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
1870 1850
1871 /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of 1851 /* V->data may hold up to SAVE_VALUE_SLOTS entries. The type of
1872 V's Ith entry is given by save_type (V, I). E.g., if save_type 1852 V's data entries are determined by V->save_type. E.g., if
1873 (V, 3) == SAVE_INTEGER, V->data[3].integer is in use. 1853 V->save_type == SAVE_TYPE_PTR_OBJ, V->data[0] is a pointer,
1854 V->data[1] is an integer, and V's other data entries are unused.
1874 1855
1875 If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of 1856 If V->save_type == SAVE_TYPE_MEMORY, V->data[0].pointer is the address of
1876 a memory area containing DATA[1].integer potential Lisp_Objects. */ 1857 a memory area containing V->data[1].integer potential Lisp_Objects. */
1877 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; 1858 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS;
1878 union { 1859 union {
1879 void *pointer; 1860 void *pointer;
@@ -2706,10 +2687,11 @@ typedef jmp_buf sys_jmp_buf;
2706 used all over the place, needs to be fast, and needs to know the size of 2687 used all over the place, needs to be fast, and needs to know the size of
2707 union specbinding. But only eval.c should access it. */ 2688 union specbinding. But only eval.c should access it. */
2708 2689
2709typedef Lisp_Object (*specbinding_func) (Lisp_Object);
2710
2711enum specbind_tag { 2690enum specbind_tag {
2712 SPECPDL_UNWIND, /* An unwind_protect function. */ 2691 SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */
2692 SPECPDL_UNWIND_PTR, /* Likewise, on void *. */
2693 SPECPDL_UNWIND_INT, /* Likewise, on int. */
2694 SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */
2713 SPECPDL_BACKTRACE, /* An element of the backtrace. */ 2695 SPECPDL_BACKTRACE, /* An element of the backtrace. */
2714 SPECPDL_LET, /* A plain and simple dynamic let-binding. */ 2696 SPECPDL_LET, /* A plain and simple dynamic let-binding. */
2715 /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */ 2697 /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */
@@ -2722,11 +2704,25 @@ union specbinding
2722 ENUM_BF (specbind_tag) kind : CHAR_BIT; 2704 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2723 struct { 2705 struct {
2724 ENUM_BF (specbind_tag) kind : CHAR_BIT; 2706 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2707 void (*func) (Lisp_Object);
2725 Lisp_Object arg; 2708 Lisp_Object arg;
2726 specbinding_func func;
2727 } unwind; 2709 } unwind;
2728 struct { 2710 struct {
2729 ENUM_BF (specbind_tag) kind : CHAR_BIT; 2711 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2712 void (*func) (void *);
2713 void *arg;
2714 } unwind_ptr;
2715 struct {
2716 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2717 void (*func) (int);
2718 int arg;
2719 } unwind_int;
2720 struct {
2721 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2722 void (*func) (void);
2723 } unwind_void;
2724 struct {
2725 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2730 /* `where' is not used in the case of SPECPDL_LET. */ 2726 /* `where' is not used in the case of SPECPDL_LET. */
2731 Lisp_Object symbol, old_value, where; 2727 Lisp_Object symbol, old_value, where;
2732 } let; 2728 } let;
@@ -3423,7 +3419,7 @@ extern void add_to_log (const char *, Lisp_Object, Lisp_Object);
3423extern void check_message_stack (void); 3419extern void check_message_stack (void);
3424extern void setup_echo_area_for_printing (int); 3420extern void setup_echo_area_for_printing (int);
3425extern bool push_message (void); 3421extern bool push_message (void);
3426extern Lisp_Object pop_message_unwind (Lisp_Object); 3422extern void pop_message_unwind (void);
3427extern Lisp_Object restore_message_unwind (Lisp_Object); 3423extern Lisp_Object restore_message_unwind (Lisp_Object);
3428extern void restore_message (void); 3424extern void restore_message (void);
3429extern Lisp_Object current_message (void); 3425extern Lisp_Object current_message (void);
@@ -3585,8 +3581,16 @@ extern bool abort_on_gc;
3585extern Lisp_Object make_float (double); 3581extern Lisp_Object make_float (double);
3586extern void display_malloc_warning (void); 3582extern void display_malloc_warning (void);
3587extern ptrdiff_t inhibit_garbage_collection (void); 3583extern ptrdiff_t inhibit_garbage_collection (void);
3588extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...); 3584extern Lisp_Object make_save_int_int_int (ptrdiff_t, ptrdiff_t, ptrdiff_t);
3589extern Lisp_Object make_save_pointer (void *); 3585extern Lisp_Object make_save_obj_obj_obj_obj (Lisp_Object, Lisp_Object,
3586 Lisp_Object, Lisp_Object);
3587extern Lisp_Object make_save_ptr (void *);
3588extern Lisp_Object make_save_ptr_int (void *, ptrdiff_t);
3589extern Lisp_Object make_save_ptr_ptr (void *, void *);
3590extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *,
3591 Lisp_Object);
3592extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t);
3593extern void free_save_value (Lisp_Object);
3590extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3594extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
3591extern void free_marker (Lisp_Object); 3595extern void free_marker (Lisp_Object);
3592extern void free_cons (struct Lisp_Cons *); 3596extern void free_cons (struct Lisp_Cons *);
@@ -3743,12 +3747,18 @@ extern Lisp_Object internal_condition_case_n
3743 (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, 3747 (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *,
3744 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); 3748 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
3745extern void specbind (Lisp_Object, Lisp_Object); 3749extern void specbind (Lisp_Object, Lisp_Object);
3746extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object); 3750extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
3751extern void record_unwind_protect_int (void (*) (int), int);
3752extern void record_unwind_protect_ptr (void (*) (void *), void *);
3753extern void record_unwind_protect_void (void (*) (void));
3754extern void record_unwind_protect_nothing (void);
3755extern void clear_unwind_protect (ptrdiff_t);
3756extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
3747extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); 3757extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
3748extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); 3758extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
3749extern _Noreturn void verror (const char *, va_list) 3759extern _Noreturn void verror (const char *, va_list)
3750 ATTRIBUTE_FORMAT_PRINTF (1, 0); 3760 ATTRIBUTE_FORMAT_PRINTF (1, 0);
3751extern Lisp_Object un_autoload (Lisp_Object); 3761extern void un_autoload (Lisp_Object);
3752extern Lisp_Object call_debugger (Lisp_Object arg); 3762extern Lisp_Object call_debugger (Lisp_Object arg);
3753extern void init_eval_once (void); 3763extern void init_eval_once (void);
3754extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...); 3764extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
@@ -3756,6 +3766,7 @@ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
3756extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object); 3766extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
3757extern void init_eval (void); 3767extern void init_eval (void);
3758extern void syms_of_eval (void); 3768extern void syms_of_eval (void);
3769extern void unwind_body (Lisp_Object);
3759extern void record_in_backtrace (Lisp_Object function, 3770extern void record_in_backtrace (Lisp_Object function,
3760 Lisp_Object *args, ptrdiff_t nargs); 3771 Lisp_Object *args, ptrdiff_t nargs);
3761extern void mark_specpdl (void); 3772extern void mark_specpdl (void);
@@ -3771,8 +3782,8 @@ extern void insert1 (Lisp_Object);
3771extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object); 3782extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
3772extern Lisp_Object save_excursion_save (void); 3783extern Lisp_Object save_excursion_save (void);
3773extern Lisp_Object save_restriction_save (void); 3784extern Lisp_Object save_restriction_save (void);
3774extern Lisp_Object save_excursion_restore (Lisp_Object); 3785extern void save_excursion_restore (Lisp_Object);
3775extern Lisp_Object save_restriction_restore (Lisp_Object); 3786extern void save_restriction_restore (Lisp_Object);
3776extern _Noreturn void time_overflow (void); 3787extern _Noreturn void time_overflow (void);
3777extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); 3788extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
3778extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, 3789extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
@@ -3791,7 +3802,6 @@ extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool,
3791 Lisp_Object, Lisp_Object, Lisp_Object); 3802 Lisp_Object, Lisp_Object, Lisp_Object);
3792extern bool overlay_touches_p (ptrdiff_t); 3803extern bool overlay_touches_p (ptrdiff_t);
3793extern Lisp_Object Vbuffer_alist; 3804extern Lisp_Object Vbuffer_alist;
3794extern Lisp_Object set_buffer_if_live (Lisp_Object);
3795extern Lisp_Object other_buffer_safely (Lisp_Object); 3805extern Lisp_Object other_buffer_safely (Lisp_Object);
3796extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; 3806extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string;
3797extern Lisp_Object get_truename_buffer (Lisp_Object); 3807extern Lisp_Object get_truename_buffer (Lisp_Object);
@@ -3825,8 +3835,9 @@ extern Lisp_Object Qinsert_file_contents;
3825extern Lisp_Object Qfile_name_history; 3835extern Lisp_Object Qfile_name_history;
3826extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); 3836extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
3827EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ 3837EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */
3828extern Lisp_Object close_file_unwind (Lisp_Object); 3838extern void close_file_unwind (int);
3829extern Lisp_Object restore_point_unwind (Lisp_Object); 3839extern void fclose_unwind (void *);
3840extern void restore_point_unwind (Lisp_Object);
3830extern _Noreturn void report_file_errno (const char *, Lisp_Object, int); 3841extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
3831extern _Noreturn void report_file_error (const char *, Lisp_Object); 3842extern _Noreturn void report_file_error (const char *, Lisp_Object);
3832extern bool internal_delete_file (Lisp_Object); 3843extern bool internal_delete_file (Lisp_Object);
@@ -4099,6 +4110,7 @@ extern void init_random (void);
4099extern void emacs_backtrace (int); 4110extern void emacs_backtrace (int);
4100extern _Noreturn void emacs_abort (void) NO_INLINE; 4111extern _Noreturn void emacs_abort (void) NO_INLINE;
4101extern int emacs_open (const char *, int, int); 4112extern int emacs_open (const char *, int, int);
4113extern int emacs_pipe (int[2]);
4102extern int emacs_close (int); 4114extern int emacs_close (int);
4103extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); 4115extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
4104extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); 4116extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t);
@@ -4262,7 +4274,6 @@ extern void init_system_name (void);
4262 4274
4263enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; 4275enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
4264 4276
4265extern Lisp_Object safe_alloca_unwind (Lisp_Object);
4266extern void *record_xmalloc (size_t); 4277extern void *record_xmalloc (size_t);
4267 4278
4268#define USE_SAFE_ALLOCA \ 4279#define USE_SAFE_ALLOCA \
@@ -4286,8 +4297,7 @@ extern void *record_xmalloc (size_t);
4286 { \ 4297 { \
4287 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ 4298 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
4288 sa_must_free = 1; \ 4299 sa_must_free = 1; \
4289 record_unwind_protect (safe_alloca_unwind, \ 4300 record_unwind_protect_ptr (xfree, buf); \
4290 make_save_pointer (buf)); \
4291 } \ 4301 } \
4292 } while (0) 4302 } while (0)
4293 4303
@@ -4312,9 +4322,9 @@ extern void *record_xmalloc (size_t);
4312 { \ 4322 { \
4313 Lisp_Object arg_; \ 4323 Lisp_Object arg_; \
4314 buf = xmalloc ((nelt) * word_size); \ 4324 buf = xmalloc ((nelt) * word_size); \
4315 arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \ 4325 arg_ = make_save_memory (buf, nelt); \
4316 sa_must_free = 1; \ 4326 sa_must_free = 1; \
4317 record_unwind_protect (safe_alloca_unwind, arg_); \ 4327 record_unwind_protect (free_save_value, arg_); \
4318 } \ 4328 } \
4319 else \ 4329 else \
4320 memory_full (SIZE_MAX); \ 4330 memory_full (SIZE_MAX); \
diff --git a/src/lread.c b/src/lread.c
index f0423f166dd..146543a99fd 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -145,7 +145,6 @@ static int read_emacs_mule_char (int, int (*) (int, Lisp_Object),
145static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool, 145static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool,
146 Lisp_Object, Lisp_Object, 146 Lisp_Object, Lisp_Object,
147 Lisp_Object, Lisp_Object); 147 Lisp_Object, Lisp_Object);
148static Lisp_Object load_unwind (Lisp_Object);
149 148
150/* Functions that read one byte from the current source READCHARFUN 149/* Functions that read one byte from the current source READCHARFUN
151 or unreads one byte. If the integer argument C is -1, it returns 150 or unreads one byte. If the integer argument C is -1, it returns
@@ -562,7 +561,7 @@ read_emacs_mule_char (int c, int (*readbyte) (int, Lisp_Object), Lisp_Object rea
562 c = DECODE_CHAR (charset, code); 561 c = DECODE_CHAR (charset, code);
563 if (c < 0) 562 if (c < 0)
564 Fsignal (Qinvalid_read_syntax, 563 Fsignal (Qinvalid_read_syntax,
565 Fcons (build_string ("invalid multibyte form"), Qnil)); 564 list1 (build_string ("invalid multibyte form")));
566 return c; 565 return c;
567} 566}
568 567
@@ -672,7 +671,7 @@ read_filtered_event (bool no_switch_frame, bool ascii_required,
672 { 671 {
673 if (error_nonascii) 672 if (error_nonascii)
674 { 673 {
675 Vunread_command_events = Fcons (val, Qnil); 674 Vunread_command_events = list1 (val);
676 error ("Non-character input-event"); 675 error ("Non-character input-event");
677 } 676 }
678 else 677 else
@@ -952,10 +951,10 @@ safe_to_load_version (int fd)
952/* Callback for record_unwind_protect. Restore the old load list OLD, 951/* Callback for record_unwind_protect. Restore the old load list OLD,
953 after loading a file successfully. */ 952 after loading a file successfully. */
954 953
955static Lisp_Object 954static void
956record_load_unwind (Lisp_Object old) 955record_load_unwind (Lisp_Object old)
957{ 956{
958 return Vloads_in_progress = old; 957 Vloads_in_progress = old;
959} 958}
960 959
961/* This handler function is used via internal_condition_case_1. */ 960/* This handler function is used via internal_condition_case_1. */
@@ -966,7 +965,7 @@ load_error_handler (Lisp_Object data)
966 return Qnil; 965 return Qnil;
967} 966}
968 967
969static Lisp_Object 968static void
970load_warn_old_style_backquotes (Lisp_Object file) 969load_warn_old_style_backquotes (Lisp_Object file)
971{ 970{
972 if (!NILP (Vold_style_backquotes)) 971 if (!NILP (Vold_style_backquotes))
@@ -976,7 +975,6 @@ load_warn_old_style_backquotes (Lisp_Object file)
976 args[1] = file; 975 args[1] = file;
977 Fmessage (2, args); 976 Fmessage (2, args);
978 } 977 }
979 return Qnil;
980} 978}
981 979
982DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0, 980DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0,
@@ -1041,10 +1039,12 @@ While the file is in the process of being loaded, the variable
1041is bound to the file's name. 1039is bound to the file's name.
1042 1040
1043Return t if the file exists and loads successfully. */) 1041Return t if the file exists and loads successfully. */)
1044 (Lisp_Object file, Lisp_Object noerror, Lisp_Object nomessage, Lisp_Object nosuffix, Lisp_Object must_suffix) 1042 (Lisp_Object file, Lisp_Object noerror, Lisp_Object nomessage,
1043 Lisp_Object nosuffix, Lisp_Object must_suffix)
1045{ 1044{
1046 register FILE *stream; 1045 FILE *stream;
1047 register int fd = -1; 1046 int fd;
1047 int fd_index;
1048 ptrdiff_t count = SPECPDL_INDEX (); 1048 ptrdiff_t count = SPECPDL_INDEX ();
1049 struct gcpro gcpro1, gcpro2, gcpro3; 1049 struct gcpro gcpro1, gcpro2, gcpro3;
1050 Lisp_Object found, efound, hist_file_name; 1050 Lisp_Object found, efound, hist_file_name;
@@ -1055,7 +1055,6 @@ Return t if the file exists and loads successfully. */)
1055 Lisp_Object handler; 1055 Lisp_Object handler;
1056 bool safe_p = 1; 1056 bool safe_p = 1;
1057 const char *fmode = "r"; 1057 const char *fmode = "r";
1058 Lisp_Object tmp[2];
1059 int version; 1058 int version;
1060 1059
1061#ifdef DOS_NT 1060#ifdef DOS_NT
@@ -1088,19 +1087,23 @@ Return t if the file exists and loads successfully. */)
1088 else 1087 else
1089 file = Fsubstitute_in_file_name (file); 1088 file = Fsubstitute_in_file_name (file);
1090 1089
1091
1092 /* Avoid weird lossage with null string as arg, 1090 /* Avoid weird lossage with null string as arg,
1093 since it would try to load a directory as a Lisp file. */ 1091 since it would try to load a directory as a Lisp file. */
1094 if (SBYTES (file) > 0) 1092 if (SCHARS (file) == 0)
1095 { 1093 {
1096 ptrdiff_t size = SBYTES (file); 1094 fd = -1;
1097 1095 errno = ENOENT;
1096 }
1097 else
1098 {
1099 Lisp_Object suffixes;
1098 found = Qnil; 1100 found = Qnil;
1099 GCPRO2 (file, found); 1101 GCPRO2 (file, found);
1100 1102
1101 if (! NILP (must_suffix)) 1103 if (! NILP (must_suffix))
1102 { 1104 {
1103 /* Don't insist on adding a suffix if FILE already ends with one. */ 1105 /* Don't insist on adding a suffix if FILE already ends with one. */
1106 ptrdiff_t size = SBYTES (file);
1104 if (size > 3 1107 if (size > 3
1105 && !strcmp (SSDATA (file) + size - 3, ".el")) 1108 && !strcmp (SSDATA (file) + size - 3, ".el"))
1106 must_suffix = Qnil; 1109 must_suffix = Qnil;
@@ -1113,20 +1116,28 @@ Return t if the file exists and loads successfully. */)
1113 must_suffix = Qnil; 1116 must_suffix = Qnil;
1114 } 1117 }
1115 1118
1116 fd = openp (Vload_path, file, 1119 if (!NILP (nosuffix))
1117 (!NILP (nosuffix) ? Qnil 1120 suffixes = Qnil;
1118 : !NILP (must_suffix) ? Fget_load_suffixes () 1121 else
1119 : Fappend (2, (tmp[0] = Fget_load_suffixes (), 1122 {
1120 tmp[1] = Vload_file_rep_suffixes, 1123 suffixes = Fget_load_suffixes ();
1121 tmp))), 1124 if (NILP (must_suffix))
1122 &found, Qnil); 1125 {
1126 Lisp_Object arg[2];
1127 arg[0] = suffixes;
1128 arg[1] = Vload_file_rep_suffixes;
1129 suffixes = Fappend (2, arg);
1130 }
1131 }
1132
1133 fd = openp (Vload_path, file, suffixes, &found, Qnil);
1123 UNGCPRO; 1134 UNGCPRO;
1124 } 1135 }
1125 1136
1126 if (fd == -1) 1137 if (fd == -1)
1127 { 1138 {
1128 if (NILP (noerror)) 1139 if (NILP (noerror))
1129 xsignal2 (Qfile_error, build_string ("Cannot open load file"), file); 1140 report_file_error ("Cannot open load file", file);
1130 return Qnil; 1141 return Qnil;
1131 } 1142 }
1132 1143
@@ -1164,6 +1175,12 @@ Return t if the file exists and loads successfully. */)
1164#endif 1175#endif
1165 } 1176 }
1166 1177
1178 if (0 <= fd)
1179 {
1180 fd_index = SPECPDL_INDEX ();
1181 record_unwind_protect_int (close_file_unwind, fd);
1182 }
1183
1167 /* Check if we're stuck in a recursive load cycle. 1184 /* Check if we're stuck in a recursive load cycle.
1168 1185
1169 2000-09-21: It's not possible to just check for the file loaded 1186 2000-09-21: It's not possible to just check for the file loaded
@@ -1179,11 +1196,7 @@ Return t if the file exists and loads successfully. */)
1179 Lisp_Object tem; 1196 Lisp_Object tem;
1180 for (tem = Vloads_in_progress; CONSP (tem); tem = XCDR (tem)) 1197 for (tem = Vloads_in_progress; CONSP (tem); tem = XCDR (tem))
1181 if (!NILP (Fequal (found, XCAR (tem))) && (++load_count > 3)) 1198 if (!NILP (Fequal (found, XCAR (tem))) && (++load_count > 3))
1182 { 1199 signal_error ("Recursive load", Fcons (found, Vloads_in_progress));
1183 if (fd >= 0)
1184 emacs_close (fd);
1185 signal_error ("Recursive load", Fcons (found, Vloads_in_progress));
1186 }
1187 record_unwind_protect (record_load_unwind, Vloads_in_progress); 1200 record_unwind_protect (record_load_unwind, Vloads_in_progress);
1188 Vloads_in_progress = Fcons (found, Vloads_in_progress); 1201 Vloads_in_progress = Fcons (found, Vloads_in_progress);
1189 } 1202 }
@@ -1196,9 +1209,8 @@ Return t if the file exists and loads successfully. */)
1196 1209
1197 /* Get the name for load-history. */ 1210 /* Get the name for load-history. */
1198 hist_file_name = (! NILP (Vpurify_flag) 1211 hist_file_name = (! NILP (Vpurify_flag)
1199 ? Fconcat (2, (tmp[0] = Ffile_name_directory (file), 1212 ? concat2 (Ffile_name_directory (file),
1200 tmp[1] = Ffile_name_nondirectory (found), 1213 Ffile_name_nondirectory (found))
1201 tmp))
1202 : found) ; 1214 : found) ;
1203 1215
1204 version = -1; 1216 version = -1;
@@ -1224,12 +1236,7 @@ Return t if the file exists and loads successfully. */)
1224 { 1236 {
1225 safe_p = 0; 1237 safe_p = 0;
1226 if (!load_dangerous_libraries) 1238 if (!load_dangerous_libraries)
1227 { 1239 error ("File `%s' was not compiled in Emacs", SDATA (found));
1228 if (fd >= 0)
1229 emacs_close (fd);
1230 error ("File `%s' was not compiled in Emacs",
1231 SDATA (found));
1232 }
1233 else if (!NILP (nomessage) && !force_load_messages) 1240 else if (!NILP (nomessage) && !force_load_messages)
1234 message_with_string ("File `%s' not compiled in Emacs", found, 1); 1241 message_with_string ("File `%s' not compiled in Emacs", found, 1);
1235 } 1242 }
@@ -1275,7 +1282,10 @@ Return t if the file exists and loads successfully. */)
1275 Lisp_Object val; 1282 Lisp_Object val;
1276 1283
1277 if (fd >= 0) 1284 if (fd >= 0)
1278 emacs_close (fd); 1285 {
1286 emacs_close (fd);
1287 clear_unwind_protect (fd_index);
1288 }
1279 val = call4 (Vload_source_file_function, found, hist_file_name, 1289 val = call4 (Vload_source_file_function, found, hist_file_name,
1280 NILP (noerror) ? Qnil : Qt, 1290 NILP (noerror) ? Qnil : Qt,
1281 (NILP (nomessage) || force_load_messages) ? Qnil : Qt); 1291 (NILP (nomessage) || force_load_messages) ? Qnil : Qt);
@@ -1285,26 +1295,28 @@ Return t if the file exists and loads successfully. */)
1285 1295
1286 GCPRO3 (file, found, hist_file_name); 1296 GCPRO3 (file, found, hist_file_name);
1287 1297
1288#ifdef WINDOWSNT 1298 if (fd < 0)
1289 efound = ENCODE_FILE (found);
1290 /* If we somehow got here with fd == -2, meaning the file is deemed
1291 to be remote, don't even try to reopen the file locally; just
1292 force a failure instead. */
1293 if (fd >= 0)
1294 { 1299 {
1295 emacs_close (fd); 1300 /* We somehow got here with fd == -2, meaning the file is deemed
1296 stream = emacs_fopen (SSDATA (efound), fmode); 1301 to be remote. Don't even try to reopen the file locally;
1302 just force a failure. */
1303 stream = NULL;
1304 errno = EINVAL;
1297 } 1305 }
1298 else 1306 else
1299 stream = NULL;
1300#else /* not WINDOWSNT */
1301 stream = fdopen (fd, fmode);
1302#endif /* not WINDOWSNT */
1303 if (stream == 0)
1304 { 1307 {
1308#ifdef WINDOWSNT
1305 emacs_close (fd); 1309 emacs_close (fd);
1306 error ("Failure to create stdio stream for %s", SDATA (file)); 1310 clear_unwind_protect (fd_index);
1311 efound = ENCODE_FILE (found);
1312 stream = emacs_fopen (SSDATA (efound), fmode);
1313#else
1314 stream = fdopen (fd, fmode);
1315#endif
1307 } 1316 }
1317 if (! stream)
1318 report_file_error ("Opening stdio stream", file);
1319 set_unwind_protect_ptr (fd_index, fclose_unwind, stream);
1308 1320
1309 if (! NILP (Vpurify_flag)) 1321 if (! NILP (Vpurify_flag))
1310 Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list); 1322 Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list);
@@ -1323,7 +1335,6 @@ Return t if the file exists and loads successfully. */)
1323 message_with_string ("Loading %s...", file, 1); 1335 message_with_string ("Loading %s...", file, 1);
1324 } 1336 }
1325 1337
1326 record_unwind_protect (load_unwind, make_save_pointer (stream));
1327 specbind (Qload_file_name, found); 1338 specbind (Qload_file_name, found);
1328 specbind (Qinhibit_file_name_operation, Qnil); 1339 specbind (Qinhibit_file_name_operation, Qnil);
1329 specbind (Qload_in_progress, Qt); 1340 specbind (Qload_in_progress, Qt);
@@ -1375,19 +1386,6 @@ Return t if the file exists and loads successfully. */)
1375 1386
1376 return Qt; 1387 return Qt;
1377} 1388}
1378
1379static Lisp_Object
1380load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */
1381{
1382 FILE *stream = XSAVE_POINTER (arg, 0);
1383 if (stream != NULL)
1384 {
1385 block_input ();
1386 fclose (stream);
1387 unblock_input ();
1388 }
1389 return Qnil;
1390}
1391 1389
1392static bool 1390static bool
1393complete_filename_p (Lisp_Object pathname) 1391complete_filename_p (Lisp_Object pathname)
@@ -1494,7 +1492,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1494 fn = alloca (fn_size = 100 + want_length); 1492 fn = alloca (fn_size = 100 + want_length);
1495 1493
1496 /* Loop over suffixes. */ 1494 /* Loop over suffixes. */
1497 for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes; 1495 for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
1498 CONSP (tail); tail = XCDR (tail)) 1496 CONSP (tail); tail = XCDR (tail))
1499 { 1497 {
1500 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); 1498 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
@@ -1523,7 +1521,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1523 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1521 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1524 { 1522 {
1525 bool exists; 1523 bool exists;
1526 last_errno = ENOENT;
1527 if (NILP (predicate)) 1524 if (NILP (predicate))
1528 exists = !NILP (Ffile_readable_p (string)); 1525 exists = !NILP (Ffile_readable_p (string));
1529 else 1526 else
@@ -1578,7 +1575,10 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1578 { 1575 {
1579 fd = emacs_open (pfn, O_RDONLY, 0); 1576 fd = emacs_open (pfn, O_RDONLY, 0);
1580 if (fd < 0) 1577 if (fd < 0)
1581 last_errno = errno; 1578 {
1579 if (errno != ENOENT)
1580 last_errno = errno;
1581 }
1582 else 1582 else
1583 { 1583 {
1584 struct stat st; 1584 struct stat st;
@@ -1682,11 +1682,10 @@ build_load_history (Lisp_Object filename, bool entire)
1682 Vload_history); 1682 Vload_history);
1683} 1683}
1684 1684
1685static Lisp_Object 1685static void
1686readevalloop_1 (Lisp_Object old) 1686readevalloop_1 (int old)
1687{ 1687{
1688 load_convert_to_unibyte = ! NILP (old); 1688 load_convert_to_unibyte = old;
1689 return Qnil;
1690} 1689}
1691 1690
1692/* Signal an `end-of-file' error, if possible with file name 1691/* Signal an `end-of-file' error, if possible with file name
@@ -1756,7 +1755,7 @@ readevalloop (Lisp_Object readcharfun,
1756 1755
1757 specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */ 1756 specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */
1758 specbind (Qcurrent_load_list, Qnil); 1757 specbind (Qcurrent_load_list, Qnil);
1759 record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); 1758 record_unwind_protect_int (readevalloop_1, load_convert_to_unibyte);
1760 load_convert_to_unibyte = !NILP (unibyte); 1759 load_convert_to_unibyte = !NILP (unibyte);
1761 1760
1762 /* If lexical binding is active (either because it was specified in 1761 /* If lexical binding is active (either because it was specified in
@@ -1764,8 +1763,8 @@ readevalloop (Lisp_Object readcharfun,
1764 lexical environment, otherwise, turn off lexical binding. */ 1763 lexical environment, otherwise, turn off lexical binding. */
1765 lex_bound = find_symbol_value (Qlexical_binding); 1764 lex_bound = find_symbol_value (Qlexical_binding);
1766 specbind (Qinternal_interpreter_environment, 1765 specbind (Qinternal_interpreter_environment,
1767 NILP (lex_bound) || EQ (lex_bound, Qunbound) 1766 (NILP (lex_bound) || EQ (lex_bound, Qunbound)
1768 ? Qnil : Fcons (Qt, Qnil)); 1767 ? Qnil : list1 (Qt)));
1769 1768
1770 GCPRO4 (sourcename, readfun, start, end); 1769 GCPRO4 (sourcename, readfun, start, end);
1771 1770
@@ -2724,7 +2723,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2724 if (c == '$') 2723 if (c == '$')
2725 return Vload_file_name; 2724 return Vload_file_name;
2726 if (c == '\'') 2725 if (c == '\'')
2727 return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil)); 2726 return list2 (Qfunction, read0 (readcharfun));
2728 /* #:foo is the uninterned symbol named foo. */ 2727 /* #:foo is the uninterned symbol named foo. */
2729 if (c == ':') 2728 if (c == ':')
2730 { 2729 {
@@ -2819,9 +2818,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2819 goto retry; 2818 goto retry;
2820 2819
2821 case '\'': 2820 case '\'':
2822 { 2821 return list2 (Qquote, read0 (readcharfun));
2823 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
2824 }
2825 2822
2826 case '`': 2823 case '`':
2827 { 2824 {
@@ -2851,7 +2848,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2851 value = read0 (readcharfun); 2848 value = read0 (readcharfun);
2852 new_backquote_flag = saved_new_backquote_flag; 2849 new_backquote_flag = saved_new_backquote_flag;
2853 2850
2854 return Fcons (Qbackquote, Fcons (value, Qnil)); 2851 return list2 (Qbackquote, value);
2855 } 2852 }
2856 } 2853 }
2857 case ',': 2854 case ',':
@@ -2889,7 +2886,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2889 } 2886 }
2890 2887
2891 value = read0 (readcharfun); 2888 value = read0 (readcharfun);
2892 return Fcons (comma_type, Fcons (value, Qnil)); 2889 return list2 (comma_type, value);
2893 } 2890 }
2894 else 2891 else
2895 { 2892 {
@@ -3665,7 +3662,7 @@ read_list (bool flag, Lisp_Object readcharfun)
3665 } 3662 }
3666 invalid_syntax ("] in a list"); 3663 invalid_syntax ("] in a list");
3667 } 3664 }
3668 tem = Fcons (elt, Qnil); 3665 tem = list1 (elt);
3669 if (!NILP (tail)) 3666 if (!NILP (tail))
3670 XSETCDR (tail, tem); 3667 XSETCDR (tail, tem);
3671 else 3668 else
@@ -4232,7 +4229,7 @@ init_lread (void)
4232 points to the eventual installed lisp, leim 4229 points to the eventual installed lisp, leim
4233 directories. We should not use those now, even 4230 directories. We should not use those now, even
4234 if they exist, so start over from a clean slate. */ 4231 if they exist, so start over from a clean slate. */
4235 Vload_path = Fcons (tem, Qnil); 4232 Vload_path = list1 (tem);
4236 } 4233 }
4237 } 4234 }
4238 else 4235 else
@@ -4459,8 +4456,8 @@ otherwise to default specified by file `epaths.h' when Emacs was built. */);
4459This list should not include the empty string. 4456This list should not include the empty string.
4460`load' and related functions try to append these suffixes, in order, 4457`load' and related functions try to append these suffixes, in order,
4461to the specified file name if a Lisp suffix is allowed or required. */); 4458to the specified file name if a Lisp suffix is allowed or required. */);
4462 Vload_suffixes = Fcons (build_pure_c_string (".elc"), 4459 Vload_suffixes = list2 (build_pure_c_string (".elc"),
4463 Fcons (build_pure_c_string (".el"), Qnil)); 4460 build_pure_c_string (".el"));
4464 DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes, 4461 DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes,
4465 doc: /* List of suffixes that indicate representations of \ 4462 doc: /* List of suffixes that indicate representations of \
4466the same file. 4463the same file.
@@ -4474,7 +4471,7 @@ and, if so, which suffixes they should try to append to the file name
4474in order to do so. However, if you want to customize which suffixes 4471in order to do so. However, if you want to customize which suffixes
4475the loading functions recognize as compression suffixes, you should 4472the loading functions recognize as compression suffixes, you should
4476customize `jka-compr-load-suffixes' rather than the present variable. */); 4473customize `jka-compr-load-suffixes' rather than the present variable. */);
4477 Vload_file_rep_suffixes = Fcons (empty_unibyte_string, Qnil); 4474 Vload_file_rep_suffixes = list1 (empty_unibyte_string);
4478 4475
4479 DEFVAR_BOOL ("load-in-progress", load_in_progress, 4476 DEFVAR_BOOL ("load-in-progress", load_in_progress,
4480 doc: /* Non-nil if inside of `load'. */); 4477 doc: /* Non-nil if inside of `load'. */);
diff --git a/src/macros.c b/src/macros.c
index 48d23a977b1..0c11efcdc9a 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -279,7 +279,7 @@ each iteration of the macro. Iteration stops if LOOPFUNC returns nil. */)
279/* Restore Vexecuting_kbd_macro and executing_kbd_macro_index. 279/* Restore Vexecuting_kbd_macro and executing_kbd_macro_index.
280 Called when the unwind-protect in Fexecute_kbd_macro gets invoked. */ 280 Called when the unwind-protect in Fexecute_kbd_macro gets invoked. */
281 281
282static Lisp_Object 282static void
283pop_kbd_macro (Lisp_Object info) 283pop_kbd_macro (Lisp_Object info)
284{ 284{
285 Lisp_Object tem; 285 Lisp_Object tem;
@@ -288,7 +288,6 @@ pop_kbd_macro (Lisp_Object info)
288 executing_kbd_macro_index = XINT (XCAR (tem)); 288 executing_kbd_macro_index = XINT (XCAR (tem));
289 Vreal_this_command = XCDR (tem); 289 Vreal_this_command = XCDR (tem);
290 Frun_hooks (1, &Qkbd_macro_termination_hook); 290 Frun_hooks (1, &Qkbd_macro_termination_hook);
291 return Qnil;
292} 291}
293 292
294DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0, 293DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0,
diff --git a/src/menu.c b/src/menu.c
index 58558d5aedd..6b4a22d3052 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -102,10 +102,10 @@ finish_menu_items (void)
102{ 102{
103} 103}
104 104
105Lisp_Object 105void
106unuse_menu_items (Lisp_Object dummy) 106unuse_menu_items (void)
107{ 107{
108 return menu_items_inuse = Qnil; 108 menu_items_inuse = Qnil;
109} 109}
110 110
111/* Call when finished using the data for the current menu 111/* Call when finished using the data for the current menu
@@ -124,19 +124,10 @@ discard_menu_items (void)
124 eassert (NILP (menu_items_inuse)); 124 eassert (NILP (menu_items_inuse));
125} 125}
126 126
127#ifdef HAVE_NS
128static Lisp_Object
129cleanup_popup_menu (Lisp_Object arg)
130{
131 discard_menu_items ();
132 return Qnil;
133}
134#endif
135
136/* This undoes save_menu_items, and it is called by the specpdl unwind 127/* This undoes save_menu_items, and it is called by the specpdl unwind
137 mechanism. */ 128 mechanism. */
138 129
139static Lisp_Object 130static void
140restore_menu_items (Lisp_Object saved) 131restore_menu_items (Lisp_Object saved)
141{ 132{
142 menu_items = XCAR (saved); 133 menu_items = XCAR (saved);
@@ -148,7 +139,6 @@ restore_menu_items (Lisp_Object saved)
148 menu_items_n_panes = XINT (XCAR (saved)); 139 menu_items_n_panes = XINT (XCAR (saved));
149 saved = XCDR (saved); 140 saved = XCDR (saved);
150 menu_items_submenu_depth = XINT (XCAR (saved)); 141 menu_items_submenu_depth = XINT (XCAR (saved));
151 return Qnil;
152} 142}
153 143
154/* Push the whole state of menu_items processing onto the specpdl. 144/* Push the whole state of menu_items processing onto the specpdl.
@@ -1004,7 +994,7 @@ find_and_return_menu_selection (FRAME_PTR f, bool keymaps, void *client_data)
1004 { 994 {
1005 int j; 995 int j;
1006 996
1007 entry = Fcons (entry, Qnil); 997 entry = list1 (entry);
1008 if (!NILP (prefix)) 998 if (!NILP (prefix))
1009 entry = Fcons (prefix, entry); 999 entry = Fcons (prefix, entry);
1010 for (j = submenu_depth - 1; j >= 0; j--) 1000 for (j = submenu_depth - 1; j >= 0; j--)
@@ -1213,7 +1203,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1213#endif /* HAVE_MENUS */ 1203#endif /* HAVE_MENUS */
1214 1204
1215 /* Now parse the lisp menus. */ 1205 /* Now parse the lisp menus. */
1216 record_unwind_protect (unuse_menu_items, Qnil); 1206 record_unwind_protect_void (unuse_menu_items);
1217 1207
1218 title = Qnil; 1208 title = Qnil;
1219 GCPRO1 (title); 1209 GCPRO1 (title);
@@ -1315,7 +1305,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
1315#endif 1305#endif
1316 1306
1317#ifdef HAVE_NS /* FIXME: ns-specific, why? --Stef */ 1307#ifdef HAVE_NS /* FIXME: ns-specific, why? --Stef */
1318 record_unwind_protect (cleanup_popup_menu, Qnil); 1308 record_unwind_protect_void (discard_menu_items);
1319#endif 1309#endif
1320 1310
1321 /* Display them in a menu. */ 1311 /* Display them in a menu. */
diff --git a/src/minibuf.c b/src/minibuf.c
index b69a16eff42..2c33b83c11b 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -137,13 +137,6 @@ choose_minibuf_frame (void)
137 } 137 }
138} 138}
139 139
140static Lisp_Object
141choose_minibuf_frame_1 (Lisp_Object ignore)
142{
143 choose_minibuf_frame ();
144 return Qnil;
145}
146
147DEFUN ("active-minibuffer-window", Factive_minibuffer_window, 140DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
148 Sactive_minibuffer_window, 0, 0, 0, 141 Sactive_minibuffer_window, 0, 0, 0,
149 doc: /* Return the currently active minibuffer window, or nil if none. */) 142 doc: /* Return the currently active minibuffer window, or nil if none. */)
@@ -171,8 +164,8 @@ without invoking the usual minibuffer commands. */)
171 164
172/* Actual minibuffer invocation. */ 165/* Actual minibuffer invocation. */
173 166
174static Lisp_Object read_minibuf_unwind (Lisp_Object); 167static void read_minibuf_unwind (void);
175static Lisp_Object run_exit_minibuf_hook (Lisp_Object); 168static void run_exit_minibuf_hook (void);
176 169
177 170
178/* Read a Lisp object from VAL and return it. If VAL is an empty 171/* Read a Lisp object from VAL and return it. If VAL is an empty
@@ -474,20 +467,20 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
474 467
475 /* Prepare for restoring the current buffer since choose_minibuf_frame 468 /* Prepare for restoring the current buffer since choose_minibuf_frame
476 calling Fset_frame_selected_window may change it (Bug#12766). */ 469 calling Fset_frame_selected_window may change it (Bug#12766). */
477 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); 470 record_unwind_protect (restore_buffer, Fcurrent_buffer ());
478 471
479 choose_minibuf_frame (); 472 choose_minibuf_frame ();
480 473
481 record_unwind_protect (choose_minibuf_frame_1, Qnil); 474 record_unwind_protect_void (choose_minibuf_frame);
482 475
483 record_unwind_protect (Fset_window_configuration, 476 record_unwind_protect (restore_window_configuration,
484 Fcurrent_window_configuration (Qnil)); 477 Fcurrent_window_configuration (Qnil));
485 478
486 /* If the minibuffer window is on a different frame, save that 479 /* If the minibuffer window is on a different frame, save that
487 frame's configuration too. */ 480 frame's configuration too. */
488 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window)); 481 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
489 if (!EQ (mini_frame, selected_frame)) 482 if (!EQ (mini_frame, selected_frame))
490 record_unwind_protect (Fset_window_configuration, 483 record_unwind_protect (restore_window_configuration,
491 Fcurrent_window_configuration (mini_frame)); 484 Fcurrent_window_configuration (mini_frame));
492 485
493 /* If the minibuffer is on an iconified or invisible frame, 486 /* If the minibuffer is on an iconified or invisible frame,
@@ -518,14 +511,14 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
518 Fcons (Vminibuffer_history_variable, 511 Fcons (Vminibuffer_history_variable,
519 minibuf_save_list)))))); 512 minibuf_save_list))))));
520 513
521 record_unwind_protect (read_minibuf_unwind, Qnil); 514 record_unwind_protect_void (read_minibuf_unwind);
522 minibuf_level++; 515 minibuf_level++;
523 /* We are exiting the minibuffer one way or the other, so run the hook. 516 /* We are exiting the minibuffer one way or the other, so run the hook.
524 It should be run before unwinding the minibuf settings. Do it 517 It should be run before unwinding the minibuf settings. Do it
525 separately from read_minibuf_unwind because we need to make sure that 518 separately from read_minibuf_unwind because we need to make sure that
526 read_minibuf_unwind is fully executed even if exit-minibuffer-hook 519 read_minibuf_unwind is fully executed even if exit-minibuffer-hook
527 signals an error. --Stef */ 520 signals an error. --Stef */
528 record_unwind_protect (run_exit_minibuf_hook, Qnil); 521 record_unwind_protect_void (run_exit_minibuf_hook);
529 522
530 /* Now that we can restore all those variables, start changing them. */ 523 /* Now that we can restore all those variables, start changing them. */
531 524
@@ -786,7 +779,7 @@ get_minibuffer (EMACS_INT depth)
786 tail = Fnthcdr (num, Vminibuffer_list); 779 tail = Fnthcdr (num, Vminibuffer_list);
787 if (NILP (tail)) 780 if (NILP (tail))
788 { 781 {
789 tail = Fcons (Qnil, Qnil); 782 tail = list1 (Qnil);
790 Vminibuffer_list = nconc2 (Vminibuffer_list, tail); 783 Vminibuffer_list = nconc2 (Vminibuffer_list, tail);
791 } 784 }
792 buf = Fcar (tail); 785 buf = Fcar (tail);
@@ -821,18 +814,17 @@ get_minibuffer (EMACS_INT depth)
821 return buf; 814 return buf;
822} 815}
823 816
824static Lisp_Object 817static void
825run_exit_minibuf_hook (Lisp_Object data) 818run_exit_minibuf_hook (void)
826{ 819{
827 safe_run_hooks (Qminibuffer_exit_hook); 820 safe_run_hooks (Qminibuffer_exit_hook);
828 return Qnil;
829} 821}
830 822
831/* This function is called on exiting minibuffer, whether normally or 823/* This function is called on exiting minibuffer, whether normally or
832 not, and it restores the current window, buffer, etc. */ 824 not, and it restores the current window, buffer, etc. */
833 825
834static Lisp_Object 826static void
835read_minibuf_unwind (Lisp_Object data) 827read_minibuf_unwind (void)
836{ 828{
837 Lisp_Object old_deactivate_mark; 829 Lisp_Object old_deactivate_mark;
838 Lisp_Object window; 830 Lisp_Object window;
@@ -895,7 +887,6 @@ read_minibuf_unwind (Lisp_Object data)
895 to make sure we don't leave around bindings and stuff which only 887 to make sure we don't leave around bindings and stuff which only
896 made sense during the read_minibuf invocation. */ 888 made sense during the read_minibuf invocation. */
897 call0 (intern ("minibuffer-inactive-mode")); 889 call0 (intern ("minibuffer-inactive-mode"));
898 return Qnil;
899} 890}
900 891
901 892
@@ -1862,7 +1853,7 @@ If FLAG is nil, invoke `try-completion'; if it is t, invoke
1862 else if (EQ (flag, Qlambda)) 1853 else if (EQ (flag, Qlambda))
1863 return Ftest_completion (string, Vbuffer_alist, predicate); 1854 return Ftest_completion (string, Vbuffer_alist, predicate);
1864 else if (EQ (flag, Qmetadata)) 1855 else if (EQ (flag, Qmetadata))
1865 return Fcons (Qmetadata, Fcons (Fcons (Qcategory, Qbuffer), Qnil)); 1856 return list2 (Qmetadata, Fcons (Qcategory, Qbuffer));
1866 else 1857 else
1867 return Qnil; 1858 return Qnil;
1868} 1859}
@@ -2106,8 +2097,7 @@ These are in addition to the basic `field' property, and stickiness
2106properties. */); 2097properties. */);
2107 /* We use `intern' here instead of Qread_only to avoid 2098 /* We use `intern' here instead of Qread_only to avoid
2108 initialization-order problems. */ 2099 initialization-order problems. */
2109 Vminibuffer_prompt_properties 2100 Vminibuffer_prompt_properties = list2 (intern_c_string ("read-only"), Qt);
2110 = Fcons (intern_c_string ("read-only"), Fcons (Qt, Qnil));
2111 2101
2112 defsubr (&Sactive_minibuffer_window); 2102 defsubr (&Sactive_minibuffer_window);
2113 defsubr (&Sset_minibuffer_window); 2103 defsubr (&Sset_minibuffer_window);
diff --git a/src/nsfns.m b/src/nsfns.m
index 6eebb4d2567..121ac539646 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -981,7 +981,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
981/* Handler for signals raised during x_create_frame. 981/* Handler for signals raised during x_create_frame.
982 FRAME is the frame which is partially constructed. */ 982 FRAME is the frame which is partially constructed. */
983 983
984static Lisp_Object 984static void
985unwind_create_frame (Lisp_Object frame) 985unwind_create_frame (Lisp_Object frame)
986{ 986{
987 struct frame *f = XFRAME (frame); 987 struct frame *f = XFRAME (frame);
@@ -990,7 +990,7 @@ unwind_create_frame (Lisp_Object frame)
990 display is disconnected after the frame has become official, but 990 display is disconnected after the frame has become official, but
991 before x_create_frame removes the unwind protect. */ 991 before x_create_frame removes the unwind protect. */
992 if (!FRAME_LIVE_P (f)) 992 if (!FRAME_LIVE_P (f))
993 return Qnil; 993 return;
994 994
995 /* If frame is ``official'', nothing to do. */ 995 /* If frame is ``official'', nothing to do. */
996 if (NILP (Fmemq (frame, Vframe_list))) 996 if (NILP (Fmemq (frame, Vframe_list)))
@@ -1006,10 +1006,7 @@ unwind_create_frame (Lisp_Object frame)
1006 /* Check that reference counts are indeed correct. */ 1006 /* Check that reference counts are indeed correct. */
1007 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); 1007 eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
1008#endif 1008#endif
1009 return Qt;
1010 } 1009 }
1011
1012 return Qnil;
1013} 1010}
1014 1011
1015/* 1012/*
@@ -2022,7 +2019,7 @@ there was no result. */)
2022 ns_string_to_pasteboard (pb, send); 2019 ns_string_to_pasteboard (pb, send);
2023 2020
2024 if (NSPerformService (svcName, pb) == NO) 2021 if (NSPerformService (svcName, pb) == NO)
2025 Fsignal (Qquit, Fcons (build_string ("service not available"), Qnil)); 2022 Fsignal (Qquit, list1 (build_string ("service not available")));
2026 2023
2027 if ([[pb types] count] == 0) 2024 if ([[pb types] count] == 0)
2028 return build_string (""); 2025 return build_string ("");
@@ -2878,7 +2875,7 @@ Example: Install an icon Gnus.tiff and execute the following code
2878 2875
2879When you miniaturize a Group, Summary or Article frame, Gnus.tiff will 2876When you miniaturize a Group, Summary or Article frame, Gnus.tiff will
2880be used as the image of the icon representing the frame. */); 2877be used as the image of the icon representing the frame. */);
2881 Vns_icon_type_alist = Fcons (Qt, Qnil); 2878 Vns_icon_type_alist = list1 (Qt);
2882 2879
2883 DEFVAR_LISP ("ns-version-string", Vns_version_string, 2880 DEFVAR_LISP ("ns-version-string", Vns_version_string,
2884 doc: /* Toolkit version for NS Windowing. */); 2881 doc: /* Toolkit version for NS Windowing. */);
diff --git a/src/nsfont.m b/src/nsfont.m
index a657d01dbe4..df7ef0bb0bc 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -446,7 +446,7 @@ static NSCharacterSet
446 { 446 {
447 Lisp_Object ranges, range_list; 447 Lisp_Object ranges, range_list;
448 448
449 ranges = Fcons (script, Qnil); 449 ranges = list1 (script);
450 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table, 450 map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
451 ranges); 451 ranges);
452 range_list = Fnreverse (XCDR (ranges)); 452 range_list = Fnreverse (XCDR (ranges));
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 22635dca0a2..02fe0b04ca0 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1410,10 +1410,10 @@ struct Popdown_data
1410 EmacsDialogPanel *dialog; 1410 EmacsDialogPanel *dialog;
1411}; 1411};
1412 1412
1413static Lisp_Object 1413static void
1414pop_down_menu (Lisp_Object arg) 1414pop_down_menu (void *arg)
1415{ 1415{
1416 struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0); 1416 struct Popdown_data *unwind_data = arg;
1417 1417
1418 block_input (); 1418 block_input ();
1419 if (popup_activated_flag) 1419 if (popup_activated_flag)
@@ -1427,8 +1427,6 @@ pop_down_menu (Lisp_Object arg)
1427 1427
1428 xfree (unwind_data); 1428 xfree (unwind_data);
1429 unblock_input (); 1429 unblock_input ();
1430
1431 return Qnil;
1432} 1430}
1433 1431
1434 1432
@@ -1492,7 +1490,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1492 if (NILP (Fcar (Fcdr (contents)))) 1490 if (NILP (Fcar (Fcdr (contents))))
1493 /* No buttons specified, add an "Ok" button so users can pop down 1491 /* No buttons specified, add an "Ok" button so users can pop down
1494 the dialog. */ 1492 the dialog. */
1495 contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil)); 1493 contents = list2 (title, Fcons (build_string ("Ok"), Qt));
1496 1494
1497 block_input (); 1495 block_input ();
1498 pool = [[NSAutoreleasePool alloc] init]; 1496 pool = [[NSAutoreleasePool alloc] init];
@@ -1506,7 +1504,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1506 unwind_data->pool = pool; 1504 unwind_data->pool = pool;
1507 unwind_data->dialog = dialog; 1505 unwind_data->dialog = dialog;
1508 1506
1509 record_unwind_protect (pop_down_menu, make_save_pointer (unwind_data)); 1507 record_unwind_protect_ptr (pop_down_menu, unwind_data);
1510 popup_activated_flag = 1; 1508 popup_activated_flag = 1;
1511 tem = [dialog runDialogAt: p]; 1509 tem = [dialog runDialogAt: p];
1512 unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */ 1510 unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */
diff --git a/src/nsselect.m b/src/nsselect.m
index 6053ee9ceb2..d95ff799877 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -219,9 +219,10 @@ ns_get_local_selection (Lisp_Object selection_name,
219 return value; 219 return value;
220 220
221 // FIXME: Why `quit' rather than `error'? 221 // FIXME: Why `quit' rather than `error'?
222 Fsignal (Qquit, Fcons (build_string ( 222 Fsignal (Qquit,
223 "invalid data returned by selection-conversion function"), 223 list3 (build_string ("invalid data returned by"
224 Fcons (handler_fn, Fcons (value, Qnil)))); 224 " selection-conversion function"),
225 handler_fn, value));
225 // FIXME: Beware, `quit' can return!! 226 // FIXME: Beware, `quit' can return!!
226 return Qnil; 227 return Qnil;
227} 228}
@@ -256,8 +257,7 @@ ns_string_from_pasteboard (id pb)
256 if (type == nil) 257 if (type == nil)
257 { 258 {
258 Fsignal (Qquit, 259 Fsignal (Qquit,
259 Fcons (build_string ("empty or unsupported pasteboard type"), 260 list1 (build_string ("empty or unsupported pasteboard type")));
260 Qnil));
261 return Qnil; 261 return Qnil;
262 } 262 }
263 263
@@ -275,8 +275,8 @@ ns_string_from_pasteboard (id pb)
275 else 275 else
276 { 276 {
277 Fsignal (Qquit, 277 Fsignal (Qquit,
278 Fcons (build_string ("pasteboard doesn't contain valid data"), 278 list1 (build_string ("pasteboard doesn't contain"
279 Qnil)); 279 " valid data")));
280 return Qnil; 280 return Qnil;
281 } 281 }
282 } 282 }
@@ -362,7 +362,7 @@ On Nextstep, FRAME is unused. */)
362 362
363 ns_declare_pasteboard (pb); 363 ns_declare_pasteboard (pb);
364 old_value = assq_no_quit (selection, Vselection_alist); 364 old_value = assq_no_quit (selection, Vselection_alist);
365 new_value = Fcons (selection, Fcons (value, Qnil)); 365 new_value = list2 (selection, value);
366 366
367 if (NILP (old_value)) 367 if (NILP (old_value))
368 Vselection_alist = Fcons (new_value, Vselection_alist); 368 Vselection_alist = Fcons (new_value, Vselection_alist);
diff --git a/src/nsterm.m b/src/nsterm.m
index d7cea5c189a..f3c35e95bfe 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -362,7 +362,7 @@ append2 (Lisp_Object list, Lisp_Object item)
362{ 362{
363 Lisp_Object array[2]; 363 Lisp_Object array[2];
364 array[0] = list; 364 array[0] = list;
365 array[1] = Fcons (item, Qnil); 365 array[1] = list1 (item);
366 return Fnconc (2, &array[0]); 366 return Fnconc (2, &array[0]);
367} 367}
368 368
@@ -3777,7 +3777,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3777 } 3777 }
3778 3778
3779 bar = [[EmacsScroller alloc] initFrame: r window: win]; 3779 bar = [[EmacsScroller alloc] initFrame: r window: win];
3780 wset_vertical_scroll_bar (window, make_save_pointer (bar)); 3780 wset_vertical_scroll_bar (window, make_save_ptr (bar));
3781 } 3781 }
3782 else 3782 else
3783 { 3783 {
@@ -4142,7 +4142,7 @@ ns_term_init (Lisp_Object display_name)
4142 4142
4143 if (selfds[0] == -1) 4143 if (selfds[0] == -1)
4144 { 4144 {
4145 if (pipe2 (selfds, O_CLOEXEC) != 0) 4145 if (emacs_pipe (selfds) != 0)
4146 { 4146 {
4147 fprintf (stderr, "Failed to create pipe: %s\n", 4147 fprintf (stderr, "Failed to create pipe: %s\n",
4148 emacs_strerror (errno)); 4148 emacs_strerror (errno));
@@ -5746,9 +5746,10 @@ not_in_argv (NSString *arg)
5746/* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ 5746/* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */
5747{ 5747{
5748 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); 5748 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
5749 BOOL is_focus_frame = dpyinfo->x_focus_frame == emacsframe;
5749 NSTRACE (windowDidResignKey); 5750 NSTRACE (windowDidResignKey);
5750 5751
5751 if (dpyinfo->x_focus_frame == emacsframe) 5752 if (is_focus_frame)
5752 dpyinfo->x_focus_frame = 0; 5753 dpyinfo->x_focus_frame = 0;
5753 5754
5754 ns_frame_rehighlight (emacsframe); 5755 ns_frame_rehighlight (emacsframe);
@@ -5761,10 +5762,10 @@ not_in_argv (NSString *arg)
5761 x_set_frame_alpha (emacsframe); 5762 x_set_frame_alpha (emacsframe);
5762 } 5763 }
5763 5764
5764 if (emacs_event) 5765 if (emacs_event && is_focus_frame)
5765 { 5766 {
5766 [self deleteWorkingText]; 5767 [self deleteWorkingText];
5767 emacs_event->kind = FOCUS_IN_EVENT; 5768 emacs_event->kind = FOCUS_OUT_EVENT;
5768 EV_TRAILER ((id)nil); 5769 EV_TRAILER ((id)nil);
5769 } 5770 }
5770} 5771}
diff --git a/src/print.c b/src/print.c
index f4062f6f48f..e55657d7d8c 100644
--- a/src/print.c
+++ b/src/print.c
@@ -201,11 +201,10 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
201/* This is used to restore the saved contents of print_buffer 201/* This is used to restore the saved contents of print_buffer
202 when there is a recursive call to print. */ 202 when there is a recursive call to print. */
203 203
204static Lisp_Object 204static void
205print_unwind (Lisp_Object saved_text) 205print_unwind (Lisp_Object saved_text)
206{ 206{
207 memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text)); 207 memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text));
208 return Qnil;
209} 208}
210 209
211 210
@@ -772,8 +771,7 @@ append to existing target file. */)
772 { 771 {
773 stderr = initial_stderr_stream; 772 stderr = initial_stderr_stream;
774 initial_stderr_stream = NULL; 773 initial_stderr_stream = NULL;
775 report_file_error ("Cannot open debugging output stream", 774 report_file_error ("Cannot open debugging output stream", file);
776 Fcons (file, Qnil));
777 } 775 }
778 } 776 }
779 return Qnil; 777 return Qnil;
@@ -1303,7 +1301,7 @@ print_prune_string_charset (Lisp_Object string)
1303 if (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND) 1301 if (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND)
1304 { 1302 {
1305 if (NILP (print_prune_charset_plist)) 1303 if (NILP (print_prune_charset_plist))
1306 print_prune_charset_plist = Fcons (Qcharset, Qnil); 1304 print_prune_charset_plist = list1 (Qcharset);
1307 Fremove_text_properties (make_number (0), 1305 Fremove_text_properties (make_number (0),
1308 make_number (SCHARS (string)), 1306 make_number (SCHARS (string)),
1309 print_prune_charset_plist, string); 1307 print_prune_charset_plist, string);
diff --git a/src/process.c b/src/process.c
index 8589acaa8b5..f4ae662468b 100644
--- a/src/process.c
+++ b/src/process.c
@@ -841,7 +841,7 @@ nil, indicating the current buffer's process. */)
841 p->raw_status_new = 0; 841 p->raw_status_new = 0;
842 if (NETCONN1_P (p) || SERIALCONN1_P (p)) 842 if (NETCONN1_P (p) || SERIALCONN1_P (p))
843 { 843 {
844 pset_status (p, Fcons (Qexit, Fcons (make_number (0), Qnil))); 844 pset_status (p, list2 (Qexit, make_number (0)));
845 p->tick = ++process_tick; 845 p->tick = ++process_tick;
846 status_notify (p); 846 status_notify (p);
847 redisplay_preserve_echo_area (13); 847 redisplay_preserve_echo_area (13);
@@ -1206,11 +1206,11 @@ list of keywords. */)
1206 if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt)) 1206 if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt))
1207 return contact; 1207 return contact;
1208 if (NILP (key) && NETCONN_P (process)) 1208 if (NILP (key) && NETCONN_P (process))
1209 return Fcons (Fplist_get (contact, QChost), 1209 return list2 (Fplist_get (contact, QChost),
1210 Fcons (Fplist_get (contact, QCservice), Qnil)); 1210 Fplist_get (contact, QCservice));
1211 if (NILP (key) && SERIALCONN_P (process)) 1211 if (NILP (key) && SERIALCONN_P (process))
1212 return Fcons (Fplist_get (contact, QCport), 1212 return list2 (Fplist_get (contact, QCport),
1213 Fcons (Fplist_get (contact, QCspeed), Qnil)); 1213 Fplist_get (contact, QCspeed));
1214 return Fplist_get (contact, key); 1214 return Fplist_get (contact, key);
1215} 1215}
1216 1216
@@ -1341,7 +1341,7 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0,
1341 1341
1342/* Starting asynchronous inferior processes. */ 1342/* Starting asynchronous inferior processes. */
1343 1343
1344static Lisp_Object start_process_unwind (Lisp_Object proc); 1344static void start_process_unwind (Lisp_Object proc);
1345 1345
1346DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, 1346DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
1347 doc: /* Start a program in a subprocess. Return the process object for it. 1347 doc: /* Start a program in a subprocess. Return the process object for it.
@@ -1397,7 +1397,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1397 current_dir = expand_and_dir_to_file (current_dir, Qnil); 1397 current_dir = expand_and_dir_to_file (current_dir, Qnil);
1398 if (NILP (Ffile_accessible_directory_p (current_dir))) 1398 if (NILP (Ffile_accessible_directory_p (current_dir)))
1399 report_file_error ("Setting current directory", 1399 report_file_error ("Setting current directory",
1400 Fcons (BVAR (current_buffer, directory), Qnil)); 1400 BVAR (current_buffer, directory));
1401 1401
1402 UNGCPRO; 1402 UNGCPRO;
1403 } 1403 }
@@ -1519,7 +1519,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1519 openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK)); 1519 openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK));
1520 UNGCPRO; 1520 UNGCPRO;
1521 if (NILP (tem)) 1521 if (NILP (tem))
1522 report_file_error ("Searching for program", Fcons (program, Qnil)); 1522 report_file_error ("Searching for program", program);
1523 tem = Fexpand_file_name (tem, Qnil); 1523 tem = Fexpand_file_name (tem, Qnil);
1524 } 1524 }
1525 else 1525 else
@@ -1542,7 +1542,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1542 1542
1543 /* Encode the file name and put it in NEW_ARGV. 1543 /* Encode the file name and put it in NEW_ARGV.
1544 That's where the child will use it to execute the program. */ 1544 That's where the child will use it to execute the program. */
1545 tem = Fcons (ENCODE_FILE (tem), Qnil); 1545 tem = list1 (ENCODE_FILE (tem));
1546 1546
1547 /* Here we encode arguments by the coding system used for sending 1547 /* Here we encode arguments by the coding system used for sending
1548 data to the process. We don't support using different coding 1548 data to the process. We don't support using different coding
@@ -1590,7 +1590,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1590 PROC doesn't have its pid set, then we know someone has signaled 1590 PROC doesn't have its pid set, then we know someone has signaled
1591 an error and the process wasn't started successfully, so we should 1591 an error and the process wasn't started successfully, so we should
1592 remove it from the process list. */ 1592 remove it from the process list. */
1593static Lisp_Object 1593static void
1594start_process_unwind (Lisp_Object proc) 1594start_process_unwind (Lisp_Object proc)
1595{ 1595{
1596 if (!PROCESSP (proc)) 1596 if (!PROCESSP (proc))
@@ -1600,8 +1600,6 @@ start_process_unwind (Lisp_Object proc)
1600 -2 is used for a pty with no process, eg for gdb. */ 1600 -2 is used for a pty with no process, eg for gdb. */
1601 if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2) 1601 if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2)
1602 remove_process (proc); 1602 remove_process (proc);
1603
1604 return Qnil;
1605} 1603}
1606 1604
1607static void 1605static void
@@ -1651,11 +1649,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1651 else 1649 else
1652#endif /* HAVE_PTYS */ 1650#endif /* HAVE_PTYS */
1653 { 1651 {
1654 if (pipe2 (sv, O_CLOEXEC) != 0) 1652 if (emacs_pipe (sv) != 0)
1655 report_file_error ("Creating pipe", Qnil); 1653 report_file_error ("Creating pipe", Qnil);
1656 inchannel = sv[0]; 1654 inchannel = sv[0];
1657 forkout = sv[1]; 1655 forkout = sv[1];
1658 if (pipe2 (sv, O_CLOEXEC) != 0) 1656 if (emacs_pipe (sv) != 0)
1659 { 1657 {
1660 int pipe_errno = errno; 1658 int pipe_errno = errno;
1661 emacs_close (inchannel); 1659 emacs_close (inchannel);
@@ -1667,7 +1665,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1667 } 1665 }
1668 1666
1669#ifndef WINDOWSNT 1667#ifndef WINDOWSNT
1670 if (pipe2 (wait_child_setup, O_CLOEXEC) != 0) 1668 if (emacs_pipe (wait_child_setup) != 0)
1671 report_file_error ("Creating pipe", Qnil); 1669 report_file_error ("Creating pipe", Qnil);
1672#endif 1670#endif
1673 1671
@@ -2323,8 +2321,12 @@ set_socket_option (int s, Lisp_Object opt, Lisp_Object val)
2323 } 2321 }
2324 2322
2325 if (ret < 0) 2323 if (ret < 0)
2326 report_file_error ("Cannot set network option", 2324 {
2327 Fcons (opt, Fcons (val, Qnil))); 2325 int setsockopt_errno = errno;
2326 report_file_errno ("Cannot set network option", list2 (opt, val),
2327 setsockopt_errno);
2328 }
2329
2328 return (1 << sopt->optbit); 2330 return (1 << sopt->optbit);
2329} 2331}
2330 2332
@@ -2456,16 +2458,6 @@ usage: (serial-process-configure &rest ARGS) */)
2456 return Qnil; 2458 return Qnil;
2457} 2459}
2458 2460
2459/* Used by make-serial-process to recover from errors. */
2460static Lisp_Object
2461make_serial_process_unwind (Lisp_Object proc)
2462{
2463 if (!PROCESSP (proc))
2464 emacs_abort ();
2465 remove_process (proc);
2466 return Qnil;
2467}
2468
2469DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process, 2461DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process,
2470 0, MANY, 0, 2462 0, MANY, 0,
2471 doc: /* Create and return a serial port process. 2463 doc: /* Create and return a serial port process.
@@ -2571,10 +2563,10 @@ usage: (make-serial-process &rest ARGS) */)
2571 CHECK_STRING (name); 2563 CHECK_STRING (name);
2572 proc = make_process (name); 2564 proc = make_process (name);
2573 specpdl_count = SPECPDL_INDEX (); 2565 specpdl_count = SPECPDL_INDEX ();
2574 record_unwind_protect (make_serial_process_unwind, proc); 2566 record_unwind_protect (remove_process, proc);
2575 p = XPROCESS (proc); 2567 p = XPROCESS (proc);
2576 2568
2577 fd = serial_open (SSDATA (port)); 2569 fd = serial_open (port);
2578 p->infd = fd; 2570 p->infd = fd;
2579 p->outfd = fd; 2571 p->outfd = fd;
2580 if (fd > max_process_desc) 2572 if (fd > max_process_desc)
@@ -3007,7 +2999,7 @@ usage: (make-network-process &rest ARGS) */)
3007#ifdef POLL_FOR_INPUT 2999#ifdef POLL_FOR_INPUT
3008 if (socktype != SOCK_DGRAM) 3000 if (socktype != SOCK_DGRAM)
3009 { 3001 {
3010 record_unwind_protect (unwind_stop_other_atimers, Qnil); 3002 record_unwind_protect_void (run_all_atimers);
3011 bind_polling_period (10); 3003 bind_polling_period (10);
3012 } 3004 }
3013#endif 3005#endif
@@ -3167,7 +3159,7 @@ usage: (make-network-process &rest ARGS) */)
3167#endif 3159#endif
3168 3160
3169 /* Make us close S if quit. */ 3161 /* Make us close S if quit. */
3170 record_unwind_protect (close_file_unwind, make_number (s)); 3162 record_unwind_protect_int (close_file_unwind, s);
3171 3163
3172 /* Parse network options in the arg list. 3164 /* Parse network options in the arg list.
3173 We simply ignore anything which isn't a known option (including other keywords). 3165 We simply ignore anything which isn't a known option (including other keywords).
@@ -3258,16 +3250,16 @@ usage: (make-network-process &rest ARGS) */)
3258 if (errno == EINTR) 3250 if (errno == EINTR)
3259 goto retry_select; 3251 goto retry_select;
3260 else 3252 else
3261 report_file_error ("select failed", Qnil); 3253 report_file_error ("Failed select", Qnil);
3262 } 3254 }
3263 eassert (sc > 0); 3255 eassert (sc > 0);
3264 3256
3265 len = sizeof xerrno; 3257 len = sizeof xerrno;
3266 eassert (FD_ISSET (s, &fdset)); 3258 eassert (FD_ISSET (s, &fdset));
3267 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) 3259 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3268 report_file_error ("getsockopt failed", Qnil); 3260 report_file_error ("Failed getsockopt", Qnil);
3269 if (xerrno) 3261 if (xerrno)
3270 report_file_errno ("error during connect", Qnil, xerrno); 3262 report_file_errno ("Failed connect", Qnil, xerrno);
3271 break; 3263 break;
3272 } 3264 }
3273#endif /* !WINDOWSNT */ 3265#endif /* !WINDOWSNT */
@@ -3534,10 +3526,13 @@ format; see the description of ADDRESS in `make-network-process'. */)
3534 ptrdiff_t buf_size = 512; 3526 ptrdiff_t buf_size = 512;
3535 int s; 3527 int s;
3536 Lisp_Object res; 3528 Lisp_Object res;
3529 ptrdiff_t count;
3537 3530
3538 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3531 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3539 if (s < 0) 3532 if (s < 0)
3540 return Qnil; 3533 return Qnil;
3534 count = SPECPDL_INDEX ();
3535 record_unwind_protect_int (close_file_unwind, s);
3541 3536
3542 do 3537 do
3543 { 3538 {
@@ -3553,9 +3548,7 @@ format; see the description of ADDRESS in `make-network-process'. */)
3553 } 3548 }
3554 while (ifconf.ifc_len == buf_size); 3549 while (ifconf.ifc_len == buf_size);
3555 3550
3556 emacs_close (s); 3551 res = unbind_to (count, Qnil);
3557
3558 res = Qnil;
3559 ifreq = ifconf.ifc_req; 3552 ifreq = ifconf.ifc_req;
3560 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) 3553 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len)
3561 { 3554 {
@@ -3680,6 +3673,7 @@ FLAGS is the current flags of the interface. */)
3680 Lisp_Object elt; 3673 Lisp_Object elt;
3681 int s; 3674 int s;
3682 bool any = 0; 3675 bool any = 0;
3676 ptrdiff_t count;
3683#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ 3677#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
3684 && defined HAVE_GETIFADDRS && defined LLADDR) 3678 && defined HAVE_GETIFADDRS && defined LLADDR)
3685 struct ifaddrs *ifap; 3679 struct ifaddrs *ifap;
@@ -3694,6 +3688,8 @@ FLAGS is the current flags of the interface. */)
3694 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3688 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3695 if (s < 0) 3689 if (s < 0)
3696 return Qnil; 3690 return Qnil;
3691 count = SPECPDL_INDEX ();
3692 record_unwind_protect_int (close_file_unwind, s);
3697 3693
3698 elt = Qnil; 3694 elt = Qnil;
3699#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) 3695#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS)
@@ -3810,9 +3806,7 @@ FLAGS is the current flags of the interface. */)
3810#endif 3806#endif
3811 res = Fcons (elt, res); 3807 res = Fcons (elt, res);
3812 3808
3813 emacs_close (s); 3809 return unbind_to (count, any ? res : Qnil);
3814
3815 return any ? res : Qnil;
3816} 3810}
3817#endif 3811#endif
3818#endif /* defined (HAVE_NET_IF_H) */ 3812#endif /* defined (HAVE_NET_IF_H) */
@@ -3986,6 +3980,7 @@ server_accept_connection (Lisp_Object server, int channel)
3986#endif 3980#endif
3987 } saddr; 3981 } saddr;
3988 socklen_t len = sizeof saddr; 3982 socklen_t len = sizeof saddr;
3983 ptrdiff_t count;
3989 3984
3990 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); 3985 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC);
3991 3986
@@ -4008,6 +4003,9 @@ server_accept_connection (Lisp_Object server, int channel)
4008 return; 4003 return;
4009 } 4004 }
4010 4005
4006 count = SPECPDL_INDEX ();
4007 record_unwind_protect_int (close_file_unwind, s);
4008
4011 connect_counter++; 4009 connect_counter++;
4012 4010
4013 /* Setup a new process to handle the connection. */ 4011 /* Setup a new process to handle the connection. */
@@ -4124,6 +4122,10 @@ server_accept_connection (Lisp_Object server, int channel)
4124 pset_filter (p, ps->filter); 4122 pset_filter (p, ps->filter);
4125 pset_command (p, Qnil); 4123 pset_command (p, Qnil);
4126 p->pid = 0; 4124 p->pid = 0;
4125
4126 /* Discard the unwind protect for closing S. */
4127 specpdl_ptr = specpdl + count;
4128
4127 p->infd = s; 4129 p->infd = s;
4128 p->outfd = s; 4130 p->outfd = s;
4129 pset_status (p, Qrun); 4131 pset_status (p, Qrun);
@@ -4177,11 +4179,10 @@ server_accept_connection (Lisp_Object server, int channel)
4177 when not inside wait_reading_process_output. */ 4179 when not inside wait_reading_process_output. */
4178static int waiting_for_user_input_p; 4180static int waiting_for_user_input_p;
4179 4181
4180static Lisp_Object 4182static void
4181wait_reading_process_output_unwind (Lisp_Object data) 4183wait_reading_process_output_unwind (int data)
4182{ 4184{
4183 waiting_for_user_input_p = XINT (data); 4185 waiting_for_user_input_p = data;
4184 return Qnil;
4185} 4186}
4186 4187
4187/* This is here so breakpoints can be put on it. */ 4188/* This is here so breakpoints can be put on it. */
@@ -4259,8 +4260,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4259 if (wait_proc != NULL) 4260 if (wait_proc != NULL)
4260 wait_channel = wait_proc->infd; 4261 wait_channel = wait_proc->infd;
4261 4262
4262 record_unwind_protect (wait_reading_process_output_unwind, 4263 record_unwind_protect_int (wait_reading_process_output_unwind,
4263 make_number (waiting_for_user_input_p)); 4264 waiting_for_user_input_p);
4264 waiting_for_user_input_p = read_kbd; 4265 waiting_for_user_input_p = read_kbd;
4265 4266
4266 if (time_limit < 0) 4267 if (time_limit < 0)
@@ -4625,7 +4626,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4625 else if (xerrno == EBADF) 4626 else if (xerrno == EBADF)
4626 emacs_abort (); 4627 emacs_abort ();
4627 else 4628 else
4628 error ("select error: %s", emacs_strerror (xerrno)); 4629 report_file_errno ("Failed select", Qnil, xerrno);
4629 } 4630 }
4630 4631
4631 if (no_avail) 4632 if (no_avail)
@@ -5124,9 +5125,7 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
5124 sometimes it's simply wrong to wrap (e.g. when called from 5125 sometimes it's simply wrong to wrap (e.g. when called from
5125 accept-process-output). */ 5126 accept-process-output). */
5126 internal_condition_case_1 (read_process_output_call, 5127 internal_condition_case_1 (read_process_output_call,
5127 Fcons (outstream, 5128 list3 (outstream, make_lisp_proc (p), text),
5128 Fcons (make_lisp_proc (p),
5129 Fcons (text, Qnil))),
5130 !NILP (Vdebug_on_error) ? Qnil : Qerror, 5129 !NILP (Vdebug_on_error) ? Qnil : Qerror,
5131 read_process_output_error_handler); 5130 read_process_output_error_handler);
5132 5131
@@ -5296,7 +5295,7 @@ write_queue_push (struct Lisp_Process *p, Lisp_Object input_obj,
5296 if (front) 5295 if (front)
5297 pset_write_queue (p, Fcons (entry, p->write_queue)); 5296 pset_write_queue (p, Fcons (entry, p->write_queue));
5298 else 5297 else
5299 pset_write_queue (p, nconc2 (p->write_queue, Fcons (entry, Qnil))); 5298 pset_write_queue (p, nconc2 (p->write_queue, list1 (entry)));
5300} 5299}
5301 5300
5302/* Remove the first element in the write_queue of process P, put its 5301/* Remove the first element in the write_queue of process P, put its
@@ -5469,7 +5468,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5469 if (rv >= 0) 5468 if (rv >= 0)
5470 written = rv; 5469 written = rv;
5471 else if (errno == EMSGSIZE) 5470 else if (errno == EMSGSIZE)
5472 report_file_error ("sending datagram", Fcons (proc, Qnil)); 5471 report_file_error ("Sending datagram", proc);
5473 } 5472 }
5474 else 5473 else
5475#endif 5474#endif
@@ -5546,7 +5545,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5546 } 5545 }
5547 else 5546 else
5548 /* This is a real error. */ 5547 /* This is a real error. */
5549 report_file_error ("writing to process", Fcons (proc, Qnil)); 5548 report_file_error ("Writing to process", proc);
5550 } 5549 }
5551 cur_buf += written; 5550 cur_buf += written;
5552 cur_len -= written; 5551 cur_len -= written;
@@ -6040,7 +6039,7 @@ process has been transmitted to the serial port. */)
6040 { 6039 {
6041#ifndef WINDOWSNT 6040#ifndef WINDOWSNT
6042 if (tcdrain (XPROCESS (proc)->outfd) != 0) 6041 if (tcdrain (XPROCESS (proc)->outfd) != 0)
6043 error ("tcdrain() failed: %s", emacs_strerror (errno)); 6042 report_file_error ("Failed tcdrain", Qnil);
6044#endif /* not WINDOWSNT */ 6043#endif /* not WINDOWSNT */
6045 /* Do nothing on Windows because writes are blocking. */ 6044 /* Do nothing on Windows because writes are blocking. */
6046 } 6045 }
@@ -6272,8 +6271,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
6272 running_asynch_code = 1; 6271 running_asynch_code = 1;
6273 6272
6274 internal_condition_case_1 (read_process_output_call, 6273 internal_condition_case_1 (read_process_output_call,
6275 Fcons (sentinel, 6274 list3 (sentinel, proc, reason),
6276 Fcons (proc, Fcons (reason, Qnil))),
6277 !NILP (Vdebug_on_error) ? Qnil : Qerror, 6275 !NILP (Vdebug_on_error) ? Qnil : Qerror,
6278 exec_sentinel_error_handler); 6276 exec_sentinel_error_handler);
6279 6277
@@ -6737,7 +6735,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6737 if (xerrno == EINTR) 6735 if (xerrno == EINTR)
6738 FD_ZERO (&waitchannels); 6736 FD_ZERO (&waitchannels);
6739 else 6737 else
6740 error ("select error: %s", emacs_strerror (xerrno)); 6738 report_file_errno ("Failed select", Qnil, xerrno);
6741 } 6739 }
6742 6740
6743 /* Check for keyboard input */ 6741 /* Check for keyboard input */
diff --git a/src/search.c b/src/search.c
index 19cc08f84c4..0f4d41586a3 100644
--- a/src/search.c
+++ b/src/search.c
@@ -3016,11 +3016,11 @@ restore_search_regs (void)
3016 } 3016 }
3017} 3017}
3018 3018
3019static Lisp_Object 3019static void
3020unwind_set_match_data (Lisp_Object list) 3020unwind_set_match_data (Lisp_Object list)
3021{ 3021{
3022 /* It is NOT ALWAYS safe to free (evaporate) the markers immediately. */ 3022 /* It is NOT ALWAYS safe to free (evaporate) the markers immediately. */
3023 return Fset_match_data (list, Qt); 3023 Fset_match_data (list, Qt);
3024} 3024}
3025 3025
3026/* Called to unwind protect the match data. */ 3026/* Called to unwind protect the match data. */
diff --git a/src/sound.c b/src/sound.c
index 5ce185ea60e..27e06b8abab 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -437,10 +437,10 @@ find_sound_type (struct sound *s)
437} 437}
438 438
439 439
440/* Function installed by play-sound-internal with record_unwind_protect. */ 440/* Function installed by play-sound-internal with record_unwind_protect_void. */
441 441
442static Lisp_Object 442static void
443sound_cleanup (Lisp_Object arg) 443sound_cleanup (void)
444{ 444{
445 if (current_sound_device->close) 445 if (current_sound_device->close)
446 current_sound_device->close (current_sound_device); 446 current_sound_device->close (current_sound_device);
@@ -448,8 +448,6 @@ sound_cleanup (Lisp_Object arg)
448 emacs_close (current_sound->fd); 448 emacs_close (current_sound->fd);
449 xfree (current_sound_device); 449 xfree (current_sound_device);
450 xfree (current_sound); 450 xfree (current_sound);
451
452 return Qnil;
453} 451}
454 452
455/*********************************************************************** 453/***********************************************************************
@@ -1346,13 +1344,13 @@ Internal use only, use `play-sound' instead. */)
1346 GCPRO2 (sound, file); 1344 GCPRO2 (sound, file);
1347 current_sound_device = xzalloc (sizeof *current_sound_device); 1345 current_sound_device = xzalloc (sizeof *current_sound_device);
1348 current_sound = xzalloc (sizeof *current_sound); 1346 current_sound = xzalloc (sizeof *current_sound);
1349 record_unwind_protect (sound_cleanup, Qnil); 1347 record_unwind_protect_void (sound_cleanup);
1350 current_sound->header = alloca (MAX_SOUND_HEADER_BYTES); 1348 current_sound->header = alloca (MAX_SOUND_HEADER_BYTES);
1351 1349
1352 if (STRINGP (attrs[SOUND_FILE])) 1350 if (STRINGP (attrs[SOUND_FILE]))
1353 { 1351 {
1354 /* Open the sound file. */ 1352 /* Open the sound file. */
1355 current_sound->fd = openp (Fcons (Vdata_directory, Qnil), 1353 current_sound->fd = openp (list1 (Vdata_directory),
1356 attrs[SOUND_FILE], Qnil, &file, Qnil); 1354 attrs[SOUND_FILE], Qnil, &file, Qnil);
1357 if (current_sound->fd < 0) 1355 if (current_sound->fd < 0)
1358 sound_perror ("Could not open sound file"); 1356 sound_perror ("Could not open sound file");
diff --git a/src/sysdep.c b/src/sysdep.c
index f614d8bc557..2739583456a 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2201,6 +2201,20 @@ emacs_fopen (char const *file, char const *mode)
2201 return fd < 0 ? 0 : fdopen (fd, mode); 2201 return fd < 0 ? 0 : fdopen (fd, mode);
2202} 2202}
2203 2203
2204/* Create a pipe for Emacs use. */
2205
2206int
2207emacs_pipe (int fd[2])
2208{
2209 int result = pipe2 (fd, O_CLOEXEC);
2210 if (! O_CLOEXEC && result == 0)
2211 {
2212 fcntl (fd[0], F_SETFD, FD_CLOEXEC);
2213 fcntl (fd[1], F_SETFD, FD_CLOEXEC);
2214 }
2215 return result;
2216}
2217
2204/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs. 2218/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs.
2205 For the background behind this mess, please see Austin Group defect 529 2219 For the background behind this mess, please see Austin Group defect 529
2206 <http://austingroupbugs.net/view.php?id=529>. */ 2220 <http://austingroupbugs.net/view.php?id=529>. */
@@ -2422,14 +2436,11 @@ safe_strsignal (int code)
2422#ifndef DOS_NT 2436#ifndef DOS_NT
2423/* For make-serial-process */ 2437/* For make-serial-process */
2424int 2438int
2425serial_open (char *port) 2439serial_open (Lisp_Object port)
2426{ 2440{
2427 int fd = emacs_open (port, O_RDWR | O_NOCTTY | O_NONBLOCK, 0); 2441 int fd = emacs_open (SSDATA (port), O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
2428 if (fd < 0) 2442 if (fd < 0)
2429 { 2443 report_file_error ("Opening serial port", port);
2430 error ("Could not open %s: %s",
2431 port, emacs_strerror (errno));
2432 }
2433#ifdef TIOCEXCL 2444#ifdef TIOCEXCL
2434 ioctl (fd, TIOCEXCL, (char *) 0); 2445 ioctl (fd, TIOCEXCL, (char *) 0);
2435#endif 2446#endif
@@ -2477,7 +2488,7 @@ serial_configure (struct Lisp_Process *p,
2477 /* Read port attributes and prepare default configuration. */ 2488 /* Read port attributes and prepare default configuration. */
2478 err = tcgetattr (p->outfd, &attr); 2489 err = tcgetattr (p->outfd, &attr);
2479 if (err != 0) 2490 if (err != 0)
2480 error ("tcgetattr() failed: %s", emacs_strerror (errno)); 2491 report_file_error ("Failed tcgetattr", Qnil);
2481 cfmakeraw (&attr); 2492 cfmakeraw (&attr);
2482#if defined (CLOCAL) 2493#if defined (CLOCAL)
2483 attr.c_cflag |= CLOCAL; 2494 attr.c_cflag |= CLOCAL;
@@ -2494,8 +2505,7 @@ serial_configure (struct Lisp_Process *p,
2494 CHECK_NUMBER (tem); 2505 CHECK_NUMBER (tem);
2495 err = cfsetspeed (&attr, XINT (tem)); 2506 err = cfsetspeed (&attr, XINT (tem));
2496 if (err != 0) 2507 if (err != 0)
2497 error ("cfsetspeed(%"pI"d) failed: %s", XINT (tem), 2508 report_file_error ("Failed cfsetspeed", tem);
2498 emacs_strerror (errno));
2499 childp2 = Fplist_put (childp2, QCspeed, tem); 2509 childp2 = Fplist_put (childp2, QCspeed, tem);
2500 2510
2501 /* Configure bytesize. */ 2511 /* Configure bytesize. */
@@ -2617,7 +2627,7 @@ serial_configure (struct Lisp_Process *p,
2617 /* Activate configuration. */ 2627 /* Activate configuration. */
2618 err = tcsetattr (p->outfd, TCSANOW, &attr); 2628 err = tcsetattr (p->outfd, TCSANOW, &attr);
2619 if (err != 0) 2629 if (err != 0)
2620 error ("tcsetattr() failed: %s", emacs_strerror (errno)); 2630 report_file_error ("Failed tcsetattr", Qnil);
2621 2631
2622 childp2 = Fplist_put (childp2, QCsummary, build_string (summary)); 2632 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
2623 pset_childp (p, childp2); 2633 pset_childp (p, childp2);
@@ -2797,11 +2807,12 @@ get_up_time (void)
2797static Lisp_Object 2807static Lisp_Object
2798procfs_ttyname (int rdev) 2808procfs_ttyname (int rdev)
2799{ 2809{
2800 FILE *fdev = NULL; 2810 FILE *fdev;
2801 char name[PATH_MAX]; 2811 char name[PATH_MAX];
2802 2812
2803 block_input (); 2813 block_input ();
2804 fdev = emacs_fopen ("/proc/tty/drivers", "r"); 2814 fdev = emacs_fopen ("/proc/tty/drivers", "r");
2815 name[0] = 0;
2805 2816
2806 if (fdev) 2817 if (fdev)
2807 { 2818 {
@@ -2810,7 +2821,7 @@ procfs_ttyname (int rdev)
2810 char minor[25]; /* 2 32-bit numbers + dash */ 2821 char minor[25]; /* 2 32-bit numbers + dash */
2811 char *endp; 2822 char *endp;
2812 2823
2813 while (!feof (fdev) && !ferror (fdev)) 2824 for (; !feof (fdev) && !ferror (fdev); name[0] = 0)
2814 { 2825 {
2815 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 2826 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
2816 && major == MAJOR (rdev)) 2827 && major == MAJOR (rdev))
@@ -2839,7 +2850,7 @@ procfs_ttyname (int rdev)
2839static unsigned long 2850static unsigned long
2840procfs_get_total_memory (void) 2851procfs_get_total_memory (void)
2841{ 2852{
2842 FILE *fmem = NULL; 2853 FILE *fmem;
2843 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ 2854 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
2844 2855
2845 block_input (); 2856 block_input ();
@@ -2882,7 +2893,7 @@ system_process_attributes (Lisp_Object pid)
2882 int cmdsize = sizeof default_cmd - 1; 2893 int cmdsize = sizeof default_cmd - 1;
2883 char *cmdline = NULL; 2894 char *cmdline = NULL;
2884 ptrdiff_t cmdline_size; 2895 ptrdiff_t cmdline_size;
2885 unsigned char c; 2896 char c;
2886 printmax_t proc_id; 2897 printmax_t proc_id;
2887 int ppid, pgrp, sess, tty, tpgid, thcount; 2898 int ppid, pgrp, sess, tty, tpgid, thcount;
2888 uid_t uid; 2899 uid_t uid;
@@ -2893,7 +2904,8 @@ system_process_attributes (Lisp_Object pid)
2893 EMACS_TIME tnow, tstart, tboot, telapsed, us_time; 2904 EMACS_TIME tnow, tstart, tboot, telapsed, us_time;
2894 double pcpu, pmem; 2905 double pcpu, pmem;
2895 Lisp_Object attrs = Qnil; 2906 Lisp_Object attrs = Qnil;
2896 Lisp_Object cmd_str, decoded_cmd, tem; 2907 Lisp_Object cmd_str, decoded_cmd;
2908 ptrdiff_t count;
2897 struct gcpro gcpro1, gcpro2; 2909 struct gcpro gcpro1, gcpro2;
2898 2910
2899 CHECK_NUMBER_OR_FLOAT (pid); 2911 CHECK_NUMBER_OR_FLOAT (pid);
@@ -2921,11 +2933,19 @@ system_process_attributes (Lisp_Object pid)
2921 if (gr) 2933 if (gr)
2922 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); 2934 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
2923 2935
2936 count = SPECPDL_INDEX ();
2924 strcpy (fn, procfn); 2937 strcpy (fn, procfn);
2925 procfn_end = fn + strlen (fn); 2938 procfn_end = fn + strlen (fn);
2926 strcpy (procfn_end, "/stat"); 2939 strcpy (procfn_end, "/stat");
2927 fd = emacs_open (fn, O_RDONLY, 0); 2940 fd = emacs_open (fn, O_RDONLY, 0);
2928 if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0) 2941 if (fd < 0)
2942 nread = 0;
2943 else
2944 {
2945 record_unwind_protect_int (close_file_unwind, fd);
2946 nread = emacs_read (fd, procbuf, sizeof procbuf - 1);
2947 }
2948 if (0 < nread)
2929 { 2949 {
2930 procbuf[nread] = '\0'; 2950 procbuf[nread] = '\0';
2931 p = procbuf; 2951 p = procbuf;
@@ -2949,39 +2969,32 @@ system_process_attributes (Lisp_Object pid)
2949 Vlocale_coding_system, 0); 2969 Vlocale_coding_system, 0);
2950 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); 2970 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
2951 2971
2952 if (q) 2972 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt
2973 utime stime cutime cstime priority nice thcount . start vsize rss */
2974 if (q
2975 && (sscanf (q + 2, ("%c %d %d %d %d %d %*u %lu %lu %lu %lu "
2976 "%Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld"),
2977 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
2978 &minflt, &cminflt, &majflt, &cmajflt,
2979 &u_time, &s_time, &cutime, &cstime,
2980 &priority, &niceness, &thcount, &start, &vsize, &rss)
2981 == 20))
2953 { 2982 {
2954 EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint; 2983 char state_str[2];
2955 p = q + 2; 2984 state_str[0] = c;
2956 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */ 2985 state_str[1] = '\0';
2957 sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld", 2986 attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
2958 &c, &ppid, &pgrp, &sess, &tty, &tpgid, 2987 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid)), attrs);
2959 &minflt, &cminflt, &majflt, &cmajflt, 2988 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp)), attrs);
2960 &u_time, &s_time, &cutime, &cstime, 2989 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess)), attrs);
2961 &priority, &niceness, &thcount, &start, &vsize, &rss);
2962 {
2963 char state_str[2];
2964
2965 state_str[0] = c;
2966 state_str[1] = '\0';
2967 tem = build_string (state_str);
2968 attrs = Fcons (Fcons (Qstate, tem), attrs);
2969 }
2970 /* Stops GCC whining about limited range of data type. */
2971 ppid_eint = ppid;
2972 pgrp_eint = pgrp;
2973 sess_eint = sess;
2974 tpgid_eint = tpgid;
2975 thcount_eint = thcount;
2976 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs);
2977 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs);
2978 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs);
2979 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); 2990 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
2980 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs); 2991 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid)), attrs);
2981 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); 2992 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
2982 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); 2993 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
2983 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs); 2994 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)),
2984 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs); 2995 attrs);
2996 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)),
2997 attrs);
2985 clocks_per_sec = sysconf (_SC_CLK_TCK); 2998 clocks_per_sec = sysconf (_SC_CLK_TCK);
2986 if (clocks_per_sec < 0) 2999 if (clocks_per_sec < 0)
2987 clocks_per_sec = 100; 3000 clocks_per_sec = 100;
@@ -3002,19 +3015,22 @@ system_process_attributes (Lisp_Object pid)
3002 ltime_from_jiffies (cstime, clocks_per_sec)), 3015 ltime_from_jiffies (cstime, clocks_per_sec)),
3003 attrs); 3016 attrs);
3004 attrs = Fcons (Fcons (Qctime, 3017 attrs = Fcons (Fcons (Qctime,
3005 ltime_from_jiffies (cstime+cutime, clocks_per_sec)), 3018 ltime_from_jiffies (cstime + cutime,
3019 clocks_per_sec)),
3006 attrs); 3020 attrs);
3007 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); 3021 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
3008 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); 3022 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
3009 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs); 3023 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)),
3024 attrs);
3010 tnow = current_emacs_time (); 3025 tnow = current_emacs_time ();
3011 telapsed = get_up_time (); 3026 telapsed = get_up_time ();
3012 tboot = sub_emacs_time (tnow, telapsed); 3027 tboot = sub_emacs_time (tnow, telapsed);
3013 tstart = time_from_jiffies (start, clocks_per_sec); 3028 tstart = time_from_jiffies (start, clocks_per_sec);
3014 tstart = add_emacs_time (tboot, tstart); 3029 tstart = add_emacs_time (tboot, tstart);
3015 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); 3030 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
3016 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); 3031 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)),
3017 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); 3032 attrs);
3033 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs);
3018 telapsed = sub_emacs_time (tnow, tstart); 3034 telapsed = sub_emacs_time (tnow, tstart);
3019 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); 3035 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
3020 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); 3036 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
@@ -3029,67 +3045,63 @@ system_process_attributes (Lisp_Object pid)
3029 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); 3045 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
3030 } 3046 }
3031 } 3047 }
3032 if (fd >= 0) 3048 unbind_to (count, Qnil);
3033 emacs_close (fd);
3034 3049
3035 /* args */ 3050 /* args */
3036 strcpy (procfn_end, "/cmdline"); 3051 strcpy (procfn_end, "/cmdline");
3037 fd = emacs_open (fn, O_RDONLY, 0); 3052 fd = emacs_open (fn, O_RDONLY, 0);
3038 if (fd >= 0) 3053 if (fd >= 0)
3039 { 3054 {
3040 char ch; 3055 ptrdiff_t readsize, nread_incr;
3041 for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++) 3056 record_unwind_protect_int (close_file_unwind, fd);
3057 record_unwind_protect_nothing ();
3058 nread = cmdline_size = 0;
3059
3060 do
3042 { 3061 {
3043 if (emacs_read (fd, &ch, 1) != 1) 3062 cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1);
3044 break; 3063 set_unwind_protect_ptr (count + 1, xfree, cmdline);
3045 c = ch; 3064
3046 if (c_isspace (c) || c == '\\') 3065 /* Leave room even if every byte needs escaping below. */
3047 cmdline_size++; /* for later quoting, see below */ 3066 readsize = (cmdline_size >> 1) - nread;
3067
3068 nread_incr = emacs_read (fd, cmdline + nread, readsize);
3069 nread += max (0, nread_incr);
3048 } 3070 }
3049 if (cmdline_size) 3071 while (nread_incr == readsize);
3072
3073 if (nread)
3050 { 3074 {
3051 cmdline = xmalloc (cmdline_size + 1);
3052 lseek (fd, 0L, SEEK_SET);
3053 cmdline[0] = '\0';
3054 if ((nread = read (fd, cmdline, cmdline_size)) >= 0)
3055 cmdline[nread++] = '\0';
3056 else
3057 {
3058 /* Assigning zero to `nread' makes us skip the following
3059 two loops, assign zero to cmdline_size, and enter the
3060 following `if' clause that handles unknown command
3061 lines. */
3062 nread = 0;
3063 }
3064 /* We don't want trailing null characters. */ 3075 /* We don't want trailing null characters. */
3065 for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--) 3076 for (p = cmdline + nread; cmdline < p && !p[-1]; p--)
3066 nread--; 3077 continue;
3067 for (p = cmdline; p < cmdline + nread; p++) 3078
3079 /* Escape-quote whitespace and backslashes. */
3080 q = cmdline + cmdline_size;
3081 while (cmdline < p)
3068 { 3082 {
3069 /* Escape-quote whitespace and backslashes. */ 3083 char c = *--p;
3070 if (c_isspace (*p) || *p == '\\') 3084 *--q = c ? c : ' ';
3071 { 3085 if (c_isspace (c) || c == '\\')
3072 memmove (p + 1, p, nread - (p - cmdline)); 3086 *--q = '\\';
3073 nread++;
3074 *p++ = '\\';
3075 }
3076 else if (*p == '\0')
3077 *p = ' ';
3078 } 3087 }
3079 cmdline_size = nread; 3088
3089 nread = cmdline + cmdline_size - q;
3080 } 3090 }
3081 if (!cmdline_size) 3091
3092 if (!nread)
3082 { 3093 {
3083 cmdline_size = cmdsize + 2; 3094 nread = cmdsize + 2;
3084 cmdline = xmalloc (cmdline_size + 1); 3095 cmdline_size = nread + 1;
3096 q = cmdline = xrealloc (cmdline, cmdline_size);
3097 set_unwind_protect_ptr (count + 1, xfree, cmdline);
3085 sprintf (cmdline, "[%.*s]", cmdsize, cmd); 3098 sprintf (cmdline, "[%.*s]", cmdsize, cmd);
3086 } 3099 }
3087 emacs_close (fd);
3088 /* Command line is encoded in locale-coding-system; decode it. */ 3100 /* Command line is encoded in locale-coding-system; decode it. */
3089 cmd_str = make_unibyte_string (cmdline, cmdline_size); 3101 cmd_str = make_unibyte_string (q, nread);
3090 decoded_cmd = code_convert_string_norecord (cmd_str, 3102 decoded_cmd = code_convert_string_norecord (cmd_str,
3091 Vlocale_coding_system, 0); 3103 Vlocale_coding_system, 0);
3092 xfree (cmdline); 3104 unbind_to (count, Qnil);
3093 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); 3105 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3094 } 3106 }
3095 3107
@@ -3131,8 +3143,9 @@ system_process_attributes (Lisp_Object pid)
3131 uid_t uid; 3143 uid_t uid;
3132 gid_t gid; 3144 gid_t gid;
3133 Lisp_Object attrs = Qnil; 3145 Lisp_Object attrs = Qnil;
3134 Lisp_Object decoded_cmd, tem; 3146 Lisp_Object decoded_cmd;
3135 struct gcpro gcpro1, gcpro2; 3147 struct gcpro gcpro1, gcpro2;
3148 ptrdiff_t count;
3136 3149
3137 CHECK_NUMBER_OR_FLOAT (pid); 3150 CHECK_NUMBER_OR_FLOAT (pid);
3138 CONS_TO_INTEGER (pid, pid_t, proc_id); 3151 CONS_TO_INTEGER (pid, pid_t, proc_id);
@@ -3159,72 +3172,83 @@ system_process_attributes (Lisp_Object pid)
3159 if (gr) 3172 if (gr)
3160 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); 3173 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3161 3174
3175 count = SPECPDL_INDEX ();
3162 strcpy (fn, procfn); 3176 strcpy (fn, procfn);
3163 procfn_end = fn + strlen (fn); 3177 procfn_end = fn + strlen (fn);
3164 strcpy (procfn_end, "/psinfo"); 3178 strcpy (procfn_end, "/psinfo");
3165 fd = emacs_open (fn, O_RDONLY, 0); 3179 fd = emacs_open (fn, O_RDONLY, 0);
3166 if (fd >= 0 3180 if (fd < 0)
3167 && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0)) 3181 nread = 0;
3182 else
3168 { 3183 {
3169 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); 3184 record_unwind_protect (close_file_unwind, fd);
3170 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); 3185 nread = emacs_read (fd, &pinfo, sizeof pinfo);
3171 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3172
3173 {
3174 char state_str[2];
3175 state_str[0] = pinfo.pr_lwp.pr_sname;
3176 state_str[1] = '\0';
3177 tem = build_string (state_str);
3178 attrs = Fcons (Fcons (Qstate, tem), attrs);
3179 }
3180
3181 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3182 need to get a string from it. */
3183
3184 /* FIXME: missing: Qtpgid */
3185
3186 /* FIXME: missing:
3187 Qminflt
3188 Qmajflt
3189 Qcminflt
3190 Qcmajflt
3191
3192 Qutime
3193 Qcutime
3194 Qstime
3195 Qcstime
3196 Are they available? */
3197
3198 attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
3199 attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
3200 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3201 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3202 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
3203
3204 attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
3205 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
3206 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
3207
3208 /* pr_pctcpu and pr_pctmem are unsigned integers in the
3209 range 0 .. 2**15, representing 0.0 .. 1.0. */
3210 attrs = Fcons (Fcons (Qpcpu, make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)), attrs);
3211 attrs = Fcons (Fcons (Qpmem, make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), attrs);
3212
3213 decoded_cmd
3214 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
3215 strlen (pinfo.pr_fname)),
3216 Vlocale_coding_system, 0);
3217 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3218 decoded_cmd
3219 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
3220 strlen (pinfo.pr_psargs)),
3221 Vlocale_coding_system, 0);
3222 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3223 } 3186 }
3224 3187
3225 if (fd >= 0) 3188 if (nread == sizeof pinfo)
3226 emacs_close (fd); 3189 {
3190 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
3191 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
3192 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3227 3193
3194 {
3195 char state_str[2];
3196 state_str[0] = pinfo.pr_lwp.pr_sname;
3197 state_str[1] = '\0';
3198 attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
3199 }
3200
3201 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3202 need to get a string from it. */
3203
3204 /* FIXME: missing: Qtpgid */
3205
3206 /* FIXME: missing:
3207 Qminflt
3208 Qmajflt
3209 Qcminflt
3210 Qcmajflt
3211
3212 Qutime
3213 Qcutime
3214 Qstime
3215 Qcstime
3216 Are they available? */
3217
3218 attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
3219 attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
3220 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3221 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3222 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)),
3223 attrs);
3224
3225 attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
3226 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)),
3227 attrs);
3228 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)),
3229 attrs);
3230
3231 /* pr_pctcpu and pr_pctmem are unsigned integers in the
3232 range 0 .. 2**15, representing 0.0 .. 1.0. */
3233 attrs = Fcons (Fcons (Qpcpu,
3234 make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)),
3235 attrs);
3236 attrs = Fcons (Fcons (Qpmem,
3237 make_float (100.0 / 0x8000 * pinfo.pr_pctmem)),
3238 attrs);
3239
3240 decoded_cmd = (code_convert_string_norecord
3241 (make_unibyte_string (pinfo.pr_fname,
3242 strlen (pinfo.pr_fname)),
3243 Vlocale_coding_system, 0));
3244 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3245 decoded_cmd = (code_convert_string_norecord
3246 (make_unibyte_string (pinfo.pr_psargs,
3247 strlen (pinfo.pr_psargs)),
3248 Vlocale_coding_system, 0));
3249 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3250 }
3251 unbind_to (count, Qnil);
3228 UNGCPRO; 3252 UNGCPRO;
3229 return attrs; 3253 return attrs;
3230} 3254}
diff --git a/src/systty.h b/src/systty.h
index 6d38c980725..b735971c66f 100644
--- a/src/systty.h
+++ b/src/systty.h
@@ -79,5 +79,5 @@ struct emacs_tty {
79}; 79};
80 80
81/* From sysdep.c or w32.c */ 81/* From sysdep.c or w32.c */
82extern int serial_open (char *); 82extern int serial_open (Lisp_Object);
83extern void serial_configure (struct Lisp_Process *, Lisp_Object); 83extern void serial_configure (struct Lisp_Process *, Lisp_Object);
diff --git a/src/term.c b/src/term.c
index b6878a0abd1..376d6e7831a 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2416,15 +2416,20 @@ frame's terminal). */)
2416 t->display_info.tty->input = stdin; 2416 t->display_info.tty->input = stdin;
2417#else /* !MSDOS */ 2417#else /* !MSDOS */
2418 fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0); 2418 fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
2419 t->display_info.tty->input = t->display_info.tty->output
2420 = fd < 0 ? 0 : fdopen (fd, "w+");
2419 2421
2420 if (fd == -1) 2422 if (! t->display_info.tty->input)
2421 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); 2423 {
2424 int open_errno = errno;
2425 emacs_close (fd);
2426 report_file_errno ("Cannot reopen tty device",
2427 build_string (t->display_info.tty->name),
2428 open_errno);
2429 }
2422 2430
2423 if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0) 2431 if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0)
2424 dissociate_if_controlling_tty (fd); 2432 dissociate_if_controlling_tty (fd);
2425
2426 t->display_info.tty->output = fdopen (fd, "w+");
2427 t->display_info.tty->input = t->display_info.tty->output;
2428#endif 2433#endif
2429 2434
2430 add_keyboard_wait_descriptor (fd); 2435 add_keyboard_wait_descriptor (fd);
@@ -2990,7 +2995,6 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
2990 2995
2991 { 2996 {
2992 /* Open the terminal device. */ 2997 /* Open the terminal device. */
2993 FILE *file;
2994 2998
2995 /* If !ctty, don't recognize it as our controlling terminal, and 2999 /* If !ctty, don't recognize it as our controlling terminal, and
2996 don't make it the controlling tty if we don't have one now. 3000 don't make it the controlling tty if we don't have one now.
@@ -3001,30 +3005,21 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
3001 open a frame on the same terminal. */ 3005 open a frame on the same terminal. */
3002 int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY); 3006 int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY);
3003 int fd = emacs_open (name, flags, 0); 3007 int fd = emacs_open (name, flags, 0);
3008 tty->input = tty->output = fd < 0 || ! isatty (fd) ? 0 : fdopen (fd, "w+");
3004 3009
3005 tty->name = xstrdup (name); 3010 if (! tty->input)
3006 terminal->name = xstrdup (name);
3007
3008 if (fd < 0)
3009 maybe_fatal (must_succeed, terminal,
3010 "Could not open file: %s",
3011 "Could not open file: %s",
3012 name);
3013 if (!isatty (fd))
3014 { 3011 {
3015 emacs_close (fd); 3012 char const *diagnostic
3016 maybe_fatal (must_succeed, terminal, 3013 = tty->input ? "Not a tty device: %s" : "Could not open file: %s";
3017 "Not a tty device: %s", 3014 emacs_close (fd);
3018 "Not a tty device: %s", 3015 maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name);
3019 name);
3020 } 3016 }
3021 3017
3018 tty->name = xstrdup (name);
3019 terminal->name = xstrdup (name);
3020
3022 if (!O_IGNORE_CTTY && !ctty) 3021 if (!O_IGNORE_CTTY && !ctty)
3023 dissociate_if_controlling_tty (fd); 3022 dissociate_if_controlling_tty (fd);
3024
3025 file = fdopen (fd, "w+");
3026 tty->input = file;
3027 tty->output = file;
3028 } 3023 }
3029 3024
3030 tty->type = xstrdup (terminal_type); 3025 tty->type = xstrdup (terminal_type);
diff --git a/src/termhooks.h b/src/termhooks.h
index f11f5ae9ffc..b22367b6751 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -172,6 +172,8 @@ enum event_kind
172 `switch-frame' events in kbd_buffer_get_event, if necessary. */ 172 `switch-frame' events in kbd_buffer_get_event, if necessary. */
173 FOCUS_IN_EVENT, 173 FOCUS_IN_EVENT,
174 174
175 FOCUS_OUT_EVENT,
176
175 /* Generated when mouse moves over window not currently selected. */ 177 /* Generated when mouse moves over window not currently selected. */
176 SELECT_WINDOW_EVENT, 178 SELECT_WINDOW_EVENT,
177 179
diff --git a/src/textprop.c b/src/textprop.c
index e5d4fe06c60..282ae11d4ac 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -226,7 +226,7 @@ validate_plist (Lisp_Object list)
226 return list; 226 return list;
227 } 227 }
228 228
229 return Fcons (list, Fcons (Qnil, Qnil)); 229 return list2 (list, Qnil);
230} 230}
231 231
232/* Return true if interval I has all the properties, 232/* Return true if interval I has all the properties,
@@ -436,16 +436,14 @@ add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object,
436 if (set_type == TEXT_PROPERTY_PREPEND) 436 if (set_type == TEXT_PROPERTY_PREPEND)
437 Fsetcar (this_cdr, Fcons (val1, Fcar (this_cdr))); 437 Fsetcar (this_cdr, Fcons (val1, Fcar (this_cdr)));
438 else 438 else
439 nconc2 (Fcar (this_cdr), Fcons (val1, Qnil)); 439 nconc2 (Fcar (this_cdr), list1 (val1));
440 else { 440 else {
441 /* The previous value is a single value, so make it 441 /* The previous value is a single value, so make it
442 into a list. */ 442 into a list. */
443 if (set_type == TEXT_PROPERTY_PREPEND) 443 if (set_type == TEXT_PROPERTY_PREPEND)
444 Fsetcar (this_cdr, 444 Fsetcar (this_cdr, list2 (val1, Fcar (this_cdr)));
445 Fcons (val1, Fcons (Fcar (this_cdr), Qnil)));
446 else 445 else
447 Fsetcar (this_cdr, 446 Fsetcar (this_cdr, list2 (Fcar (this_cdr), val1));
448 Fcons (Fcar (this_cdr), Fcons (val1, Qnil)));
449 } 447 }
450 } 448 }
451 changed = 1; 449 changed = 1;
@@ -1308,9 +1306,7 @@ the current buffer), START and END are buffer positions (integers or
1308markers). If OBJECT is a string, START and END are 0-based indices into it. */) 1306markers). If OBJECT is a string, START and END are 0-based indices into it. */)
1309 (Lisp_Object start, Lisp_Object end, Lisp_Object property, Lisp_Object value, Lisp_Object object) 1307 (Lisp_Object start, Lisp_Object end, Lisp_Object property, Lisp_Object value, Lisp_Object object)
1310{ 1308{
1311 Fadd_text_properties (start, end, 1309 Fadd_text_properties (start, end, list2 (property, value), object);
1312 Fcons (property, Fcons (value, Qnil)),
1313 object);
1314 return Qnil; 1310 return Qnil;
1315} 1311}
1316 1312
@@ -1344,11 +1340,10 @@ into it. */)
1344 (Lisp_Object start, Lisp_Object end, Lisp_Object face, 1340 (Lisp_Object start, Lisp_Object end, Lisp_Object face,
1345 Lisp_Object appendp, Lisp_Object object) 1341 Lisp_Object appendp, Lisp_Object object)
1346{ 1342{
1347 add_text_properties_1 (start, end, 1343 add_text_properties_1 (start, end, list2 (Qface, face), object,
1348 Fcons (Qface, Fcons (face, Qnil)), 1344 (NILP (appendp)
1349 object, 1345 ? TEXT_PROPERTY_PREPEND
1350 NILP (appendp)? TEXT_PROPERTY_PREPEND: 1346 : TEXT_PROPERTY_APPEND));
1351 TEXT_PROPERTY_APPEND);
1352 return Qnil; 1347 return Qnil;
1353} 1348}
1354 1349
@@ -1929,7 +1924,7 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_
1929 { 1924 {
1930 if (EQ (Fcar (plist), prop)) 1925 if (EQ (Fcar (plist), prop))
1931 { 1926 {
1932 plist = Fcons (prop, Fcons (Fcar (Fcdr (plist)), Qnil)); 1927 plist = list2 (prop, Fcar (Fcdr (plist)));
1933 break; 1928 break;
1934 } 1929 }
1935 plist = Fcdr (Fcdr (plist)); 1930 plist = Fcdr (Fcdr (plist));
@@ -1938,10 +1933,8 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_
1938 { 1933 {
1939 /* Must defer modifications to the interval tree in case src 1934 /* Must defer modifications to the interval tree in case src
1940 and dest refer to the same string or buffer. */ 1935 and dest refer to the same string or buffer. */
1941 stuff = Fcons (Fcons (make_number (p), 1936 stuff = Fcons (list3 (make_number (p), make_number (p + len), plist),
1942 Fcons (make_number (p + len), 1937 stuff);
1943 Fcons (plist, Qnil))),
1944 stuff);
1945 } 1938 }
1946 1939
1947 i = next_interval (i); 1940 i = next_interval (i);
@@ -2007,14 +2000,13 @@ text_property_list (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp
2007 for (; CONSP (plist); plist = Fcdr (XCDR (plist))) 2000 for (; CONSP (plist); plist = Fcdr (XCDR (plist)))
2008 if (EQ (XCAR (plist), prop)) 2001 if (EQ (XCAR (plist), prop))
2009 { 2002 {
2010 plist = Fcons (prop, Fcons (Fcar (XCDR (plist)), Qnil)); 2003 plist = list2 (prop, Fcar (XCDR (plist)));
2011 break; 2004 break;
2012 } 2005 }
2013 2006
2014 if (!NILP (plist)) 2007 if (!NILP (plist))
2015 result = Fcons (Fcons (make_number (s), 2008 result = Fcons (list3 (make_number (s), make_number (s + len),
2016 Fcons (make_number (s + len), 2009 plist),
2017 Fcons (plist, Qnil))),
2018 result); 2010 result);
2019 2011
2020 i = next_interval (i); 2012 i = next_interval (i);
@@ -2343,8 +2335,8 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and
2343 /* Text properties `syntax-table'and `display' should be nonsticky 2335 /* Text properties `syntax-table'and `display' should be nonsticky
2344 by default. */ 2336 by default. */
2345 Vtext_property_default_nonsticky 2337 Vtext_property_default_nonsticky
2346 = Fcons (Fcons (intern_c_string ("syntax-table"), Qt), 2338 = list2 (Fcons (intern_c_string ("syntax-table"), Qt),
2347 Fcons (Fcons (intern_c_string ("display"), Qt), Qnil)); 2339 Fcons (intern_c_string ("display"), Qt));
2348 2340
2349 staticpro (&interval_insert_behind_hooks); 2341 staticpro (&interval_insert_behind_hooks);
2350 staticpro (&interval_insert_in_front_hooks); 2342 staticpro (&interval_insert_in_front_hooks);
diff --git a/src/unexaix.c b/src/unexaix.c
index 757ba6f51b3..fc1acc9ab4f 100644
--- a/src/unexaix.c
+++ b/src/unexaix.c
@@ -97,7 +97,7 @@ report_error (const char *file, int fd)
97 int err = errno; 97 int err = errno;
98 if (fd) 98 if (fd)
99 emacs_close (fd); 99 emacs_close (fd);
100 report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err); 100 report_file_errno ("Cannot unexec", build_string (file), err);
101} 101}
102 102
103#define ERROR0(msg) report_error_1 (new, msg) 103#define ERROR0(msg) report_error_1 (new, msg)
diff --git a/src/unexcoff.c b/src/unexcoff.c
index c467e59a665..5ac8ea8c9b0 100644
--- a/src/unexcoff.c
+++ b/src/unexcoff.c
@@ -130,7 +130,7 @@ report_error (const char *file, int fd)
130 int err = errno; 130 int err = errno;
131 if (fd) 131 if (fd)
132 emacs_close (fd); 132 emacs_close (fd);
133 report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err); 133 report_file_errno ("Cannot unexec", build_string (file), err);
134} 134}
135 135
136#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 136#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
diff --git a/src/unexsol.c b/src/unexsol.c
index 470206d5838..cfd515ff504 100644
--- a/src/unexsol.c
+++ b/src/unexsol.c
@@ -20,7 +20,7 @@ unexec (const char *new_name, const char *old_name)
20 if (! dldump (0, new_name, RTLD_MEMORY)) 20 if (! dldump (0, new_name, RTLD_MEMORY))
21 return; 21 return;
22 22
23 data = Fcons (build_string (new_name), Qnil); 23 data = list1 (build_string (new_name));
24 synchronize_system_messages_locale (); 24 synchronize_system_messages_locale ();
25 errstring = code_convert_string_norecord (build_string (dlerror ()), 25 errstring = code_convert_string_norecord (build_string (dlerror ()),
26 Vlocale_coding_system, 0); 26 Vlocale_coding_system, 0);
diff --git a/src/w32.c b/src/w32.c
index 1a3d81bbffc..fb2d7c75972 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -7707,8 +7707,9 @@ globals_of_w32 (void)
7707 7707
7708/* For make-serial-process */ 7708/* For make-serial-process */
7709int 7709int
7710serial_open (char *port) 7710serial_open (Lisp_Object port_obj)
7711{ 7711{
7712 char *port = SSDATA (port_obj);
7712 HANDLE hnd; 7713 HANDLE hnd;
7713 child_process *cp; 7714 child_process *cp;
7714 int fd = -1; 7715 int fd = -1;
diff --git a/src/w32fns.c b/src/w32fns.c
index 3fa23c166e2..675b716f3b0 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -318,7 +318,7 @@ x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
318 318
319 319
320static Lisp_Object unwind_create_frame (Lisp_Object); 320static Lisp_Object unwind_create_frame (Lisp_Object);
321static Lisp_Object unwind_create_tip_frame (Lisp_Object); 321static void unwind_create_tip_frame (Lisp_Object);
322static void my_create_window (struct frame *); 322static void my_create_window (struct frame *);
323static void my_create_tip_window (struct frame *); 323static void my_create_tip_window (struct frame *);
324 324
@@ -4259,6 +4259,12 @@ unwind_create_frame (Lisp_Object frame)
4259} 4259}
4260 4260
4261static void 4261static void
4262do_unwind_create_frame (Lisp_Object frame)
4263{
4264 unwind_create_frame (frame);
4265}
4266
4267static void
4262x_default_font_parameter (struct frame *f, Lisp_Object parms) 4268x_default_font_parameter (struct frame *f, Lisp_Object parms)
4263{ 4269{
4264 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); 4270 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
@@ -4398,7 +4404,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4398/* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */ 4404/* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
4399 4405
4400 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ 4406 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
4401 record_unwind_protect (unwind_create_frame, frame); 4407 record_unwind_protect (do_unwind_create_frame, frame);
4402#ifdef GLYPH_DEBUG 4408#ifdef GLYPH_DEBUG
4403 image_cache_refcount = 4409 image_cache_refcount =
4404 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; 4410 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
@@ -4910,7 +4916,7 @@ w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
4910{ 4916{
4911 Lisp_Object *monitor_list = (Lisp_Object *) dwData; 4917 Lisp_Object *monitor_list = (Lisp_Object *) dwData;
4912 4918
4913 *monitor_list = Fcons (make_save_pointer (monitor), *monitor_list); 4919 *monitor_list = Fcons (make_save_ptr (monitor), *monitor_list);
4914 4920
4915 return TRUE; 4921 return TRUE;
4916} 4922}
@@ -5585,7 +5591,7 @@ Window tip_window;
5585Lisp_Object last_show_tip_args; 5591Lisp_Object last_show_tip_args;
5586 5592
5587 5593
5588static Lisp_Object 5594static void
5589unwind_create_tip_frame (Lisp_Object frame) 5595unwind_create_tip_frame (Lisp_Object frame)
5590{ 5596{
5591 Lisp_Object deleted; 5597 Lisp_Object deleted;
@@ -5596,8 +5602,6 @@ unwind_create_tip_frame (Lisp_Object frame)
5596 tip_window = NULL; 5602 tip_window = NULL;
5597 tip_frame = Qnil; 5603 tip_frame = Qnil;
5598 } 5604 }
5599
5600 return deleted;
5601} 5605}
5602 5606
5603 5607
diff --git a/src/w32term.c b/src/w32term.c
index 732a4f4bfef..2fe3fe07462 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2912,9 +2912,15 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
2912 && CONSP (Vframe_list) 2912 && CONSP (Vframe_list)
2913 && !NILP (XCDR (Vframe_list))) 2913 && !NILP (XCDR (Vframe_list)))
2914 { 2914 {
2915 bufp->kind = FOCUS_IN_EVENT; 2915 bufp->arg = Qt;
2916 XSETFRAME (bufp->frame_or_window, frame);
2917 } 2916 }
2917 else
2918 {
2919 bufp->arg = Qnil;
2920 }
2921
2922 bufp->kind = FOCUS_IN_EVENT;
2923 XSETFRAME (bufp->frame_or_window, frame);
2918 } 2924 }
2919 2925
2920 frame->output_data.x->focus_state |= state; 2926 frame->output_data.x->focus_state |= state;
@@ -2929,7 +2935,10 @@ x_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
2929 { 2935 {
2930 dpyinfo->w32_focus_event_frame = 0; 2936 dpyinfo->w32_focus_event_frame = 0;
2931 x_new_focus_frame (dpyinfo, 0); 2937 x_new_focus_frame (dpyinfo, 0);
2932 } 2938
2939 bufp->kind = FOCUS_OUT_EVENT;
2940 XSETFRAME (bufp->frame_or_window, frame);
2941 }
2933 2942
2934 /* TODO: IME focus? */ 2943 /* TODO: IME focus? */
2935 } 2944 }
diff --git a/src/window.c b/src/window.c
index 5c5d2b8e138..f66099c1b9b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3089,18 +3089,18 @@ run_funs (Lisp_Object funs)
3089 call0 (XCAR (funs)); 3089 call0 (XCAR (funs));
3090} 3090}
3091 3091
3092static Lisp_Object 3092static void
3093select_window_norecord (Lisp_Object window) 3093select_window_norecord (Lisp_Object window)
3094{ 3094{
3095 return WINDOW_LIVE_P (window) 3095 if (WINDOW_LIVE_P (window))
3096 ? Fselect_window (window, Qt) : selected_window; 3096 Fselect_window (window, Qt);
3097} 3097}
3098 3098
3099static Lisp_Object 3099static void
3100select_frame_norecord (Lisp_Object frame) 3100select_frame_norecord (Lisp_Object frame)
3101{ 3101{
3102 return FRAME_LIVE_P (XFRAME (frame)) 3102 if (FRAME_LIVE_P (XFRAME (frame)))
3103 ? Fselect_frame (frame, Qt) : selected_frame; 3103 Fselect_frame (frame, Qt);
3104} 3104}
3105 3105
3106void 3106void
@@ -3413,7 +3413,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3413 Note: Both Fselect_window and select_window_norecord may 3413 Note: Both Fselect_window and select_window_norecord may
3414 set-buffer to the buffer displayed in the window, 3414 set-buffer to the buffer displayed in the window,
3415 so we need to save the current buffer. --stef */ 3415 so we need to save the current buffer. --stef */
3416 record_unwind_protect (Fset_buffer, prev_buffer); 3416 record_unwind_protect (restore_buffer, prev_buffer);
3417 record_unwind_protect (select_window_norecord, prev_window); 3417 record_unwind_protect (select_window_norecord, prev_window);
3418 Fselect_window (window, Qt); 3418 Fselect_window (window, Qt);
3419 Fset_buffer (w->contents); 3419 Fset_buffer (w->contents);
@@ -5879,6 +5879,12 @@ the return value is nil. Otherwise the value is t. */)
5879 return (FRAME_LIVE_P (f) ? Qt : Qnil); 5879 return (FRAME_LIVE_P (f) ? Qt : Qnil);
5880} 5880}
5881 5881
5882void
5883restore_window_configuration (Lisp_Object configuration)
5884{
5885 Fset_window_configuration (configuration);
5886}
5887
5882 5888
5883/* If WINDOW is an internal window, recursively delete all child windows 5889/* If WINDOW is an internal window, recursively delete all child windows
5884 reachable via the next and contents slots of WINDOW. Otherwise setup 5890 reachable via the next and contents slots of WINDOW. Otherwise setup
diff --git a/src/window.h b/src/window.h
index 846831e43d5..5da6165c48d 100644
--- a/src/window.h
+++ b/src/window.h
@@ -886,6 +886,7 @@ extern Lisp_Object make_window (void);
886extern Lisp_Object window_from_coordinates (struct frame *, int, int, 886extern Lisp_Object window_from_coordinates (struct frame *, int, int,
887 enum window_part *, bool); 887 enum window_part *, bool);
888extern void resize_frame_windows (struct frame *, int, bool); 888extern void resize_frame_windows (struct frame *, int, bool);
889extern void restore_window_configuration (Lisp_Object);
889extern void delete_all_child_windows (Lisp_Object); 890extern void delete_all_child_windows (Lisp_Object);
890extern void freeze_window_starts (struct frame *, bool); 891extern void freeze_window_starts (struct frame *, bool);
891extern void grow_mini_window (struct window *, int); 892extern void grow_mini_window (struct window *, int);
diff --git a/src/xdisp.c b/src/xdisp.c
index ab2e065d049..219c2f0de6c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -817,21 +817,20 @@ static void handle_stop (struct it *);
817static void handle_stop_backwards (struct it *, ptrdiff_t); 817static void handle_stop_backwards (struct it *, ptrdiff_t);
818static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0); 818static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
819static void ensure_echo_area_buffers (void); 819static void ensure_echo_area_buffers (void);
820static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object); 820static void unwind_with_echo_area_buffer (Lisp_Object);
821static Lisp_Object with_echo_area_buffer_unwind_data (struct window *); 821static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
822static int with_echo_area_buffer (struct window *, int, 822static int with_echo_area_buffer (struct window *, int,
823 int (*) (ptrdiff_t, Lisp_Object), 823 int (*) (ptrdiff_t, Lisp_Object),
824 ptrdiff_t, Lisp_Object); 824 ptrdiff_t, Lisp_Object);
825static void clear_garbaged_frames (void); 825static void clear_garbaged_frames (void);
826static int current_message_1 (ptrdiff_t, Lisp_Object); 826static int current_message_1 (ptrdiff_t, Lisp_Object);
827static void pop_message (void);
828static int truncate_message_1 (ptrdiff_t, Lisp_Object); 827static int truncate_message_1 (ptrdiff_t, Lisp_Object);
829static void set_message (Lisp_Object); 828static void set_message (Lisp_Object);
830static int set_message_1 (ptrdiff_t, Lisp_Object); 829static int set_message_1 (ptrdiff_t, Lisp_Object);
831static int display_echo_area (struct window *); 830static int display_echo_area (struct window *);
832static int display_echo_area_1 (ptrdiff_t, Lisp_Object); 831static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
833static int resize_mini_window_1 (ptrdiff_t, Lisp_Object); 832static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
834static Lisp_Object unwind_redisplay (Lisp_Object); 833static void unwind_redisplay (void);
835static int string_char_and_length (const unsigned char *, int *); 834static int string_char_and_length (const unsigned char *, int *);
836static struct text_pos display_prop_end (struct it *, Lisp_Object, 835static struct text_pos display_prop_end (struct it *, Lisp_Object,
837 struct text_pos); 836 struct text_pos);
@@ -10202,7 +10201,7 @@ with_echo_area_buffer_unwind_data (struct window *w)
10202/* Restore global state from VECTOR which was created by 10201/* Restore global state from VECTOR which was created by
10203 with_echo_area_buffer_unwind_data. */ 10202 with_echo_area_buffer_unwind_data. */
10204 10203
10205static Lisp_Object 10204static void
10206unwind_with_echo_area_buffer (Lisp_Object vector) 10205unwind_with_echo_area_buffer (Lisp_Object vector)
10207{ 10206{
10208 set_buffer_internal_1 (XBUFFER (AREF (vector, 0))); 10207 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
@@ -10227,7 +10226,6 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
10227 } 10226 }
10228 10227
10229 Vwith_echo_area_save_vector = vector; 10228 Vwith_echo_area_save_vector = vector;
10230 return Qnil;
10231} 10229}
10232 10230
10233 10231
@@ -10626,20 +10624,12 @@ restore_message (void)
10626} 10624}
10627 10625
10628 10626
10629/* Handler for record_unwind_protect calling pop_message. */ 10627/* Handler for unwind-protect calling pop_message. */
10630
10631Lisp_Object
10632pop_message_unwind (Lisp_Object dummy)
10633{
10634 pop_message ();
10635 return Qnil;
10636}
10637
10638/* Pop the top-most entry off Vmessage_stack. */
10639 10628
10640static void 10629void
10641pop_message (void) 10630pop_message_unwind (void)
10642{ 10631{
10632 /* Pop the top-most entry off Vmessage_stack. */
10643 eassert (CONSP (Vmessage_stack)); 10633 eassert (CONSP (Vmessage_stack));
10644 Vmessage_stack = XCDR (Vmessage_stack); 10634 Vmessage_stack = XCDR (Vmessage_stack);
10645} 10635}
@@ -11035,7 +11025,7 @@ format_mode_line_unwind_data (struct frame *target_frame,
11035 return vector; 11025 return vector;
11036} 11026}
11037 11027
11038static Lisp_Object 11028static void
11039unwind_format_mode_line (Lisp_Object vector) 11029unwind_format_mode_line (Lisp_Object vector)
11040{ 11030{
11041 Lisp_Object old_window = AREF (vector, 7); 11031 Lisp_Object old_window = AREF (vector, 7);
@@ -11078,7 +11068,6 @@ unwind_format_mode_line (Lisp_Object vector)
11078 } 11068 }
11079 11069
11080 Vmode_line_unwind_vector = vector; 11070 Vmode_line_unwind_vector = vector;
11081 return Qnil;
11082} 11071}
11083 11072
11084 11073
@@ -11527,7 +11516,7 @@ int last_tool_bar_item;
11527 do_switch_frame. 11516 do_switch_frame.
11528 FIXME: Maybe do_switch_frame should be trimmed down similarly 11517 FIXME: Maybe do_switch_frame should be trimmed down similarly
11529 when `norecord' is set. */ 11518 when `norecord' is set. */
11530static Lisp_Object 11519static void
11531fast_set_selected_frame (Lisp_Object frame) 11520fast_set_selected_frame (Lisp_Object frame)
11532{ 11521{
11533 if (!EQ (selected_frame, frame)) 11522 if (!EQ (selected_frame, frame))
@@ -11535,7 +11524,6 @@ fast_set_selected_frame (Lisp_Object frame)
11535 selected_frame = frame; 11524 selected_frame = frame;
11536 selected_window = XFRAME (frame)->selected_window; 11525 selected_window = XFRAME (frame)->selected_window;
11537 } 11526 }
11538 return Qnil;
11539} 11527}
11540 11528
11541/* Update the tool-bar item list for frame F. This has to be done 11529/* Update the tool-bar item list for frame F. This has to be done
@@ -12055,9 +12043,8 @@ redisplay_tool_bar (struct frame *f)
12055 12043
12056 XSETFRAME (frame, f); 12044 XSETFRAME (frame, f);
12057 Fmodify_frame_parameters (frame, 12045 Fmodify_frame_parameters (frame,
12058 Fcons (Fcons (Qtool_bar_lines, 12046 list1 (Fcons (Qtool_bar_lines,
12059 make_number (nlines)), 12047 make_number (nlines))));
12060 Qnil));
12061 if (WINDOW_TOTAL_LINES (w) != old_height) 12048 if (WINDOW_TOTAL_LINES (w) != old_height)
12062 { 12049 {
12063 clear_glyph_matrix (w->desired_matrix); 12050 clear_glyph_matrix (w->desired_matrix);
@@ -12156,9 +12143,8 @@ redisplay_tool_bar (struct frame *f)
12156 { 12143 {
12157 XSETFRAME (frame, f); 12144 XSETFRAME (frame, f);
12158 Fmodify_frame_parameters (frame, 12145 Fmodify_frame_parameters (frame,
12159 Fcons (Fcons (Qtool_bar_lines, 12146 list1 (Fcons (Qtool_bar_lines,
12160 make_number (nlines)), 12147 make_number (nlines))));
12161 Qnil));
12162 if (WINDOW_TOTAL_LINES (w) != old_height) 12148 if (WINDOW_TOTAL_LINES (w) != old_height)
12163 { 12149 {
12164 clear_glyph_matrix (w->desired_matrix); 12150 clear_glyph_matrix (w->desired_matrix);
@@ -13038,7 +13024,7 @@ redisplay_internal (void)
13038 /* Record a function that clears redisplaying_p 13024 /* Record a function that clears redisplaying_p
13039 when we leave this function. */ 13025 when we leave this function. */
13040 count = SPECPDL_INDEX (); 13026 count = SPECPDL_INDEX ();
13041 record_unwind_protect (unwind_redisplay, selected_frame); 13027 record_unwind_protect_void (unwind_redisplay);
13042 redisplaying_p = 1; 13028 redisplaying_p = 1;
13043 specbind (Qinhibit_free_realized_faces, Qnil); 13029 specbind (Qinhibit_free_realized_faces, Qnil);
13044 13030
@@ -13725,14 +13711,12 @@ redisplay_preserve_echo_area (int from_where)
13725} 13711}
13726 13712
13727 13713
13728/* Function registered with record_unwind_protect in redisplay_internal. 13714/* Function registered with record_unwind_protect in redisplay_internal. */
13729 Clear redisplaying_p. Also select the previously selected frame. */
13730 13715
13731static Lisp_Object 13716static void
13732unwind_redisplay (Lisp_Object old_frame) 13717unwind_redisplay (void)
13733{ 13718{
13734 redisplaying_p = 0; 13719 redisplaying_p = 0;
13735 return Qnil;
13736} 13720}
13737 13721
13738 13722
@@ -21452,7 +21436,7 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_st
21452 if (NILP (face)) 21436 if (NILP (face))
21453 face = mode_line_string_face; 21437 face = mode_line_string_face;
21454 else 21438 else
21455 face = Fcons (face, Fcons (mode_line_string_face, Qnil)); 21439 face = list2 (face, mode_line_string_face);
21456 props = Fplist_put (props, Qface, face); 21440 props = Fplist_put (props, Qface, face);
21457 } 21441 }
21458 Fadd_text_properties (make_number (0), make_number (len), 21442 Fadd_text_properties (make_number (0), make_number (len),
@@ -21476,8 +21460,8 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_st
21476 if (NILP (face)) 21460 if (NILP (face))
21477 face = mode_line_string_face; 21461 face = mode_line_string_face;
21478 else 21462 else
21479 face = Fcons (face, Fcons (mode_line_string_face, Qnil)); 21463 face = list2 (face, mode_line_string_face);
21480 props = Fcons (Qface, Fcons (face, Qnil)); 21464 props = list2 (Qface, face);
21481 if (copy_string) 21465 if (copy_string)
21482 lisp_string = Fcopy_sequence (lisp_string); 21466 lisp_string = Fcopy_sequence (lisp_string);
21483 } 21467 }
@@ -21591,7 +21575,7 @@ are the selected window and the WINDOW's buffer). */)
21591 mode_line_string_list = Qnil; 21575 mode_line_string_list = Qnil;
21592 mode_line_string_face = face; 21576 mode_line_string_face = face;
21593 mode_line_string_face_prop 21577 mode_line_string_face_prop
21594 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil))); 21578 = NILP (face) ? Qnil : list2 (Qface, face);
21595 } 21579 }
21596 21580
21597 push_kboard (FRAME_KBOARD (it.f)); 21581 push_kboard (FRAME_KBOARD (it.f));
@@ -29488,9 +29472,8 @@ syms_of_xdisp (void)
29488 DEFSYM (Qarrow, "arrow"); 29472 DEFSYM (Qarrow, "arrow");
29489 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces"); 29473 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29490 29474
29491 list_of_error = Fcons (Fcons (intern_c_string ("error"), 29475 list_of_error = list1 (list2 (intern_c_string ("error"),
29492 Fcons (intern_c_string ("void-variable"), Qnil)), 29476 intern_c_string ("void-variable")));
29493 Qnil);
29494 staticpro (&list_of_error); 29477 staticpro (&list_of_error);
29495 29478
29496 DEFSYM (Qlast_arrow_position, "last-arrow-position"); 29479 DEFSYM (Qlast_arrow_position, "last-arrow-position");
@@ -29594,7 +29577,7 @@ See also `overlay-arrow-position'. */);
29594The symbols on this list are examined during redisplay to determine 29577The symbols on this list are examined during redisplay to determine
29595where to display overlay arrows. */); 29578where to display overlay arrows. */);
29596 Voverlay_arrow_variable_list 29579 Voverlay_arrow_variable_list
29597 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil); 29580 = list1 (intern_c_string ("overlay-arrow-position"));
29598 29581
29599 DEFVAR_INT ("scroll-step", emacs_scroll_step, 29582 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29600 doc: /* The number of lines to try scrolling a window by when point moves out. 29583 doc: /* The number of lines to try scrolling a window by when point moves out.
diff --git a/src/xfaces.c b/src/xfaces.c
index 4b42cb7dc40..f647ff2e209 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3388,7 +3388,7 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
3388 ASET (lface, LFACE_FONT_INDEX, font); 3388 ASET (lface, LFACE_FONT_INDEX, font);
3389 } 3389 }
3390 f->default_face_done_p = 0; 3390 f->default_face_done_p = 0;
3391 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil)); 3391 Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, font)));
3392 } 3392 }
3393} 3393}
3394 3394
@@ -3709,14 +3709,10 @@ Value is nil if ATTR doesn't have a discrete set of valid values. */)
3709 3709
3710 CHECK_SYMBOL (attr); 3710 CHECK_SYMBOL (attr);
3711 3711
3712 if (EQ (attr, QCunderline)) 3712 if (EQ (attr, QCunderline) || EQ (attr, QCoverline)
3713 result = Fcons (Qt, Fcons (Qnil, Qnil)); 3713 || EQ (attr, QCstrike_through)
3714 else if (EQ (attr, QCoverline)) 3714 || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3715 result = Fcons (Qt, Fcons (Qnil, Qnil)); 3715 result = list2 (Qt, Qnil);
3716 else if (EQ (attr, QCstrike_through))
3717 result = Fcons (Qt, Fcons (Qnil, Qnil));
3718 else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
3719 result = Fcons (Qt, Fcons (Qnil, Qnil));
3720 3716
3721 return result; 3717 return result;
3722} 3718}
@@ -3779,21 +3775,18 @@ Default face attributes override any local face attributes. */)
3779 && newface->font) 3775 && newface->font)
3780 { 3776 {
3781 Lisp_Object name = newface->font->props[FONT_NAME_INDEX]; 3777 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
3782 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name), 3778 Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, name)));
3783 Qnil));
3784 } 3779 }
3785 3780
3786 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX])) 3781 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
3787 Fmodify_frame_parameters (frame, 3782 Fmodify_frame_parameters (frame,
3788 Fcons (Fcons (Qforeground_color, 3783 list1 (Fcons (Qforeground_color,
3789 gvec[LFACE_FOREGROUND_INDEX]), 3784 gvec[LFACE_FOREGROUND_INDEX])));
3790 Qnil));
3791 3785
3792 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX])) 3786 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
3793 Fmodify_frame_parameters (frame, 3787 Fmodify_frame_parameters (frame,
3794 Fcons (Fcons (Qbackground_color, 3788 list1 (Fcons (Qbackground_color,
3795 gvec[LFACE_BACKGROUND_INDEX]), 3789 gvec[LFACE_BACKGROUND_INDEX])));
3796 Qnil));
3797 } 3790 }
3798 } 3791 }
3799 3792
@@ -6290,6 +6283,7 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6290 CHECK_STRING (filename); 6283 CHECK_STRING (filename);
6291 abspath = Fexpand_file_name (filename, Qnil); 6284 abspath = Fexpand_file_name (filename, Qnil);
6292 6285
6286 block_input ();
6293 fp = emacs_fopen (SSDATA (abspath), "rt"); 6287 fp = emacs_fopen (SSDATA (abspath), "rt");
6294 if (fp) 6288 if (fp)
6295 { 6289 {
@@ -6297,29 +6291,24 @@ where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
6297 int red, green, blue; 6291 int red, green, blue;
6298 int num; 6292 int num;
6299 6293
6300 block_input ();
6301
6302 while (fgets (buf, sizeof (buf), fp) != NULL) { 6294 while (fgets (buf, sizeof (buf), fp) != NULL) {
6303 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3) 6295 if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3)
6304 { 6296 {
6305 char *name = buf + num;
6306 num = strlen (name) - 1;
6307 if (num >= 0 && name[num] == '\n')
6308 name[num] = 0;
6309 cmap = Fcons (Fcons (build_string (name),
6310#ifdef HAVE_NTGUI 6297#ifdef HAVE_NTGUI
6311 make_number (RGB (red, green, blue))), 6298 int color = RGB (red, green, blue);
6312#else 6299#else
6313 make_number ((red << 16) | (green << 8) | blue)), 6300 int color = (red << 16) | (green << 8) | blue;
6314#endif 6301#endif
6302 char *name = buf + num;
6303 ptrdiff_t len = strlen (name);
6304 len -= 0 < len && name[len - 1] == '\n';
6305 cmap = Fcons (Fcons (make_string (name, len), make_number (color)),
6315 cmap); 6306 cmap);
6316 } 6307 }
6317 } 6308 }
6318 fclose (fp); 6309 fclose (fp);
6319
6320 unblock_input ();
6321 } 6310 }
6322 6311 unblock_input ();
6323 return cmap; 6312 return cmap;
6324} 6313}
6325#endif 6314#endif
@@ -6483,7 +6472,7 @@ syms_of_xfaces (void)
6483 DEFSYM (Qtty_color_alist, "tty-color-alist"); 6472 DEFSYM (Qtty_color_alist, "tty-color-alist");
6484 DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed"); 6473 DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
6485 6474
6486 Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil); 6475 Vparam_value_alist = list1 (Fcons (Qnil, Qnil));
6487 staticpro (&Vparam_value_alist); 6476 staticpro (&Vparam_value_alist);
6488 Vface_alternative_font_family_alist = Qnil; 6477 Vface_alternative_font_family_alist = Qnil;
6489 staticpro (&Vface_alternative_font_family_alist); 6478 staticpro (&Vface_alternative_font_family_alist);
diff --git a/src/xfns.c b/src/xfns.c
index a1c709a6c26..a3eff1a5cce 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1715,7 +1715,7 @@ x_default_scroll_bar_color_parameter (struct frame *f,
1715#endif /* not USE_TOOLKIT_SCROLL_BARS */ 1715#endif /* not USE_TOOLKIT_SCROLL_BARS */
1716 } 1716 }
1717 1717
1718 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); 1718 x_set_frame_parameters (f, list1 (Fcons (prop, tem)));
1719 return tem; 1719 return tem;
1720} 1720}
1721 1721
@@ -2883,11 +2883,16 @@ unwind_create_frame (Lisp_Object frame)
2883 return Qnil; 2883 return Qnil;
2884} 2884}
2885 2885
2886static Lisp_Object 2886static void
2887do_unwind_create_frame (Lisp_Object frame)
2888{
2889 unwind_create_frame (frame);
2890}
2891
2892static void
2887unwind_create_frame_1 (Lisp_Object val) 2893unwind_create_frame_1 (Lisp_Object val)
2888{ 2894{
2889 inhibit_lisp_code = val; 2895 inhibit_lisp_code = val;
2890 return Qnil;
2891} 2896}
2892 2897
2893static void 2898static void
@@ -2948,7 +2953,7 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
2948 { 2953 {
2949 /* Remember the explicit font parameter, so we can re-apply it after 2954 /* Remember the explicit font parameter, so we can re-apply it after
2950 we've applied the `default' face settings. */ 2955 we've applied the `default' face settings. */
2951 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil)); 2956 x_set_frame_parameters (f, list1 (Fcons (Qfont_param, font_param)));
2952 } 2957 }
2953 2958
2954 /* This call will make X resources override any system font setting. */ 2959 /* This call will make X resources override any system font setting. */
@@ -3090,7 +3095,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3090 FRAME_X_DISPLAY_INFO (f) = dpyinfo; 3095 FRAME_X_DISPLAY_INFO (f) = dpyinfo;
3091 3096
3092 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ 3097 /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
3093 record_unwind_protect (unwind_create_frame, frame); 3098 record_unwind_protect (do_unwind_create_frame, frame);
3094 3099
3095 /* These colors will be set anyway later, but it's important 3100 /* These colors will be set anyway later, but it's important
3096 to get the color reference counts right, so initialize them! */ 3101 to get the color reference counts right, so initialize them! */
@@ -4975,7 +4980,7 @@ Window tip_window;
4975static Lisp_Object last_show_tip_args; 4980static Lisp_Object last_show_tip_args;
4976 4981
4977 4982
4978static Lisp_Object 4983static void
4979unwind_create_tip_frame (Lisp_Object frame) 4984unwind_create_tip_frame (Lisp_Object frame)
4980{ 4985{
4981 Lisp_Object deleted; 4986 Lisp_Object deleted;
@@ -4986,8 +4991,6 @@ unwind_create_tip_frame (Lisp_Object frame)
4986 tip_window = None; 4991 tip_window = None;
4987 tip_frame = Qnil; 4992 tip_frame = Qnil;
4988 } 4993 }
4989
4990 return deleted;
4991} 4994}
4992 4995
4993 4996
@@ -5238,7 +5241,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5238 5241
5239 /* Add `tooltip' frame parameter's default value. */ 5242 /* Add `tooltip' frame parameter's default value. */
5240 if (NILP (Fframe_parameter (frame, Qtooltip))) 5243 if (NILP (Fframe_parameter (frame, Qtooltip)))
5241 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil)); 5244 Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt)));
5242 5245
5243 /* FIXME - can this be done in a similar way to normal frames? 5246 /* FIXME - can this be done in a similar way to normal frames?
5244 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */ 5247 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
@@ -5256,8 +5259,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5256 disptype = intern ("color"); 5259 disptype = intern ("color");
5257 5260
5258 if (NILP (Fframe_parameter (frame, Qdisplay_type))) 5261 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5259 Fmodify_frame_parameters (frame, Fcons (Fcons (Qdisplay_type, disptype), 5262 Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype)));
5260 Qnil));
5261 } 5263 }
5262 5264
5263 /* Set up faces after all frame parameters are known. This call 5265 /* Set up faces after all frame parameters are known. This call
@@ -5276,8 +5278,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5276 call2 (Qface_set_after_frame_default, frame, Qnil); 5278 call2 (Qface_set_after_frame_default, frame, Qnil);
5277 5279
5278 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) 5280 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5279 Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg), 5281 Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg)));
5280 Qnil));
5281 } 5282 }
5282 5283
5283 f->no_split = 1; 5284 f->no_split = 1;
@@ -5766,10 +5767,10 @@ file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5766 *result = XmCR_CANCEL; 5767 *result = XmCR_CANCEL;
5767} 5768}
5768 5769
5769static Lisp_Object 5770static void
5770clean_up_file_dialog (Lisp_Object arg) 5771clean_up_file_dialog (void *arg)
5771{ 5772{
5772 Widget dialog = XSAVE_POINTER (arg, 0); 5773 Widget dialog = arg;
5773 5774
5774 /* Clean up. */ 5775 /* Clean up. */
5775 block_input (); 5776 block_input ();
@@ -5777,8 +5778,6 @@ clean_up_file_dialog (Lisp_Object arg)
5777 XtDestroyWidget (dialog); 5778 XtDestroyWidget (dialog);
5778 x_menu_set_in_use (0); 5779 x_menu_set_in_use (0);
5779 unblock_input (); 5780 unblock_input ();
5780
5781 return Qnil;
5782} 5781}
5783 5782
5784 5783
@@ -5893,7 +5892,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5893 XmStringFree (default_xmstring); 5892 XmStringFree (default_xmstring);
5894 } 5893 }
5895 5894
5896 record_unwind_protect (clean_up_file_dialog, make_save_pointer (dialog)); 5895 record_unwind_protect_ptr (clean_up_file_dialog, dialog);
5897 5896
5898 /* Process events until the user presses Cancel or OK. */ 5897 /* Process events until the user presses Cancel or OK. */
5899 x_menu_set_in_use (1); 5898 x_menu_set_in_use (1);
@@ -5947,12 +5946,10 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5947 5946
5948#ifdef USE_GTK 5947#ifdef USE_GTK
5949 5948
5950static Lisp_Object 5949static void
5951clean_up_dialog (Lisp_Object arg) 5950clean_up_dialog (void)
5952{ 5951{
5953 x_menu_set_in_use (0); 5952 x_menu_set_in_use (0);
5954
5955 return Qnil;
5956} 5953}
5957 5954
5958DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, 5955DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
@@ -5986,7 +5983,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5986 5983
5987 /* Prevent redisplay. */ 5984 /* Prevent redisplay. */
5988 specbind (Qinhibit_redisplay, Qt); 5985 specbind (Qinhibit_redisplay, Qt);
5989 record_unwind_protect (clean_up_dialog, Qnil); 5986 record_unwind_protect_void (clean_up_dialog);
5990 5987
5991 block_input (); 5988 block_input ();
5992 5989
@@ -6041,7 +6038,7 @@ nil, it defaults to the selected frame. */)
6041 6038
6042 /* Prevent redisplay. */ 6039 /* Prevent redisplay. */
6043 specbind (Qinhibit_redisplay, Qt); 6040 specbind (Qinhibit_redisplay, Qt);
6044 record_unwind_protect (clean_up_dialog, Qnil); 6041 record_unwind_protect_void (clean_up_dialog);
6045 6042
6046 block_input (); 6043 block_input ();
6047 6044
diff --git a/src/xfont.c b/src/xfont.c
index 9978aba76de..9647a51ac6e 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -295,9 +295,9 @@ xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
295 295
296 /* Two special cases to avoid opening rather big fonts. */ 296 /* Two special cases to avoid opening rather big fonts. */
297 if (EQ (AREF (props, 2), Qja)) 297 if (EQ (AREF (props, 2), Qja))
298 return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil)); 298 return list2 (intern ("kana"), intern ("han"));
299 if (EQ (AREF (props, 2), Qko)) 299 if (EQ (AREF (props, 2), Qko))
300 return Fcons (intern ("hangul"), Qnil); 300 return list1 (intern ("hangul"));
301 scripts = Fgethash (props, xfont_scripts_cache, Qt); 301 scripts = Fgethash (props, xfont_scripts_cache, Qt);
302 if (EQ (scripts, Qt)) 302 if (EQ (scripts, Qt))
303 { 303 {
diff --git a/src/xmenu.c b/src/xmenu.c
index 48ab3519723..6c0e3dd78a6 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -296,10 +296,10 @@ for instance using the window manager, then this produces a quit and
296 XSETFRAME (frame, f); 296 XSETFRAME (frame, f);
297 XSETINT (x, x_pixel_width (f) / 2); 297 XSETINT (x, x_pixel_width (f) / 2);
298 XSETINT (y, x_pixel_height (f) / 2); 298 XSETINT (y, x_pixel_height (f) / 2);
299 newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil)); 299 newpos = list2 (list2 (x, y), frame);
300 300
301 return Fx_popup_menu (newpos, 301 return Fx_popup_menu (newpos,
302 Fcons (Fcar (contents), Fcons (contents, Qnil))); 302 list2 (Fcar (contents), contents));
303 } 303 }
304#else 304#else
305 { 305 {
@@ -311,15 +311,15 @@ for instance using the window manager, then this produces a quit and
311 /* Decode the dialog items from what was specified. */ 311 /* Decode the dialog items from what was specified. */
312 title = Fcar (contents); 312 title = Fcar (contents);
313 CHECK_STRING (title); 313 CHECK_STRING (title);
314 record_unwind_protect (unuse_menu_items, Qnil); 314 record_unwind_protect_void (unuse_menu_items);
315 315
316 if (NILP (Fcar (Fcdr (contents)))) 316 if (NILP (Fcar (Fcdr (contents))))
317 /* No buttons specified, add an "Ok" button so users can pop down 317 /* No buttons specified, add an "Ok" button so users can pop down
318 the dialog. Also, the lesstif/motif version crashes if there are 318 the dialog. Also, the lesstif/motif version crashes if there are
319 no buttons. */ 319 no buttons. */
320 contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil)); 320 contents = list2 (title, Fcons (build_string ("Ok"), Qt));
321 321
322 list_of_panes (Fcons (contents, Qnil)); 322 list_of_panes (list1 (contents));
323 323
324 /* Display them in a dialog box. */ 324 /* Display them in a dialog box. */
325 block_input (); 325 block_input ();
@@ -1405,14 +1405,13 @@ popup_selection_callback (GtkWidget *widget, gpointer client_data)
1405 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; 1405 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
1406} 1406}
1407 1407
1408static Lisp_Object 1408static void
1409pop_down_menu (Lisp_Object arg) 1409pop_down_menu (void *arg)
1410{ 1410{
1411 popup_activated_flag = 0; 1411 popup_activated_flag = 0;
1412 block_input (); 1412 block_input ();
1413 gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg, 0))); 1413 gtk_widget_destroy (GTK_WIDGET (arg));
1414 unblock_input (); 1414 unblock_input ();
1415 return Qnil;
1416} 1415}
1417 1416
1418/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the 1417/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
@@ -1474,7 +1473,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
1474 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 1473 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i,
1475 timestamp ? timestamp : gtk_get_current_event_time ()); 1474 timestamp ? timestamp : gtk_get_current_event_time ());
1476 1475
1477 record_unwind_protect (pop_down_menu, make_save_pointer (menu)); 1476 record_unwind_protect_ptr (pop_down_menu, menu);
1478 1477
1479 if (gtk_widget_get_mapped (menu)) 1478 if (gtk_widget_get_mapped (menu))
1480 { 1479 {
@@ -1513,7 +1512,7 @@ popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
1513/* ARG is the LWLIB ID of the dialog box, represented 1512/* ARG is the LWLIB ID of the dialog box, represented
1514 as a Lisp object as (HIGHPART . LOWPART). */ 1513 as a Lisp object as (HIGHPART . LOWPART). */
1515 1514
1516static Lisp_Object 1515static void
1517pop_down_menu (Lisp_Object arg) 1516pop_down_menu (Lisp_Object arg)
1518{ 1517{
1519 LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID) 1518 LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
@@ -1523,8 +1522,6 @@ pop_down_menu (Lisp_Object arg)
1523 lw_destroy_all_widgets (id); 1522 lw_destroy_all_widgets (id);
1524 unblock_input (); 1523 unblock_input ();
1525 popup_activated_flag = 0; 1524 popup_activated_flag = 0;
1526
1527 return Qnil;
1528} 1525}
1529 1526
1530/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the 1527/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
@@ -1604,11 +1601,10 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
1604 1601
1605#endif /* not USE_GTK */ 1602#endif /* not USE_GTK */
1606 1603
1607static Lisp_Object 1604static void
1608cleanup_widget_value_tree (Lisp_Object arg) 1605cleanup_widget_value_tree (void *arg)
1609{ 1606{
1610 free_menubar_widget_value_tree (XSAVE_POINTER (arg, 0)); 1607 free_menubar_widget_value_tree (arg);
1611 return Qnil;
1612} 1608}
1613 1609
1614Lisp_Object 1610Lisp_Object
@@ -1822,8 +1818,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
1822 1818
1823 /* Make sure to free the widget_value objects we used to specify the 1819 /* Make sure to free the widget_value objects we used to specify the
1824 contents even with longjmp. */ 1820 contents even with longjmp. */
1825 record_unwind_protect (cleanup_widget_value_tree, 1821 record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
1826 make_save_pointer (first_wv));
1827 1822
1828 /* Actually create and show the menu until popped down. */ 1823 /* Actually create and show the menu until popped down. */
1829 create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp); 1824 create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp);
@@ -1871,7 +1866,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
1871 { 1866 {
1872 int j; 1867 int j;
1873 1868
1874 entry = Fcons (entry, Qnil); 1869 entry = list1 (entry);
1875 if (!NILP (prefix)) 1870 if (!NILP (prefix))
1876 entry = Fcons (prefix, entry); 1871 entry = Fcons (prefix, entry);
1877 for (j = submenu_depth - 1; j >= 0; j--) 1872 for (j = submenu_depth - 1; j >= 0; j--)
@@ -1922,7 +1917,7 @@ create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
1922 if (menu) 1917 if (menu)
1923 { 1918 {
1924 ptrdiff_t specpdl_count = SPECPDL_INDEX (); 1919 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
1925 record_unwind_protect (pop_down_menu, make_save_pointer (menu)); 1920 record_unwind_protect_ptr (pop_down_menu, menu);
1926 1921
1927 /* Display the menu. */ 1922 /* Display the menu. */
1928 gtk_widget_show_all (menu); 1923 gtk_widget_show_all (menu);
@@ -2132,8 +2127,7 @@ xdialog_show (FRAME_PTR f,
2132 2127
2133 /* Make sure to free the widget_value objects we used to specify the 2128 /* Make sure to free the widget_value objects we used to specify the
2134 contents even with longjmp. */ 2129 contents even with longjmp. */
2135 record_unwind_protect (cleanup_widget_value_tree, 2130 record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
2136 make_save_pointer (first_wv));
2137 2131
2138 /* Actually create and show the dialog. */ 2132 /* Actually create and show the dialog. */
2139 create_and_show_dialog (f, first_wv); 2133 create_and_show_dialog (f, first_wv);
@@ -2172,7 +2166,7 @@ xdialog_show (FRAME_PTR f,
2172 { 2166 {
2173 if (keymaps != 0) 2167 if (keymaps != 0)
2174 { 2168 {
2175 entry = Fcons (entry, Qnil); 2169 entry = list1 (entry);
2176 if (!NILP (prefix)) 2170 if (!NILP (prefix))
2177 entry = Fcons (prefix, entry); 2171 entry = Fcons (prefix, entry);
2178 } 2172 }
@@ -2223,14 +2217,12 @@ menu_help_callback (char const *help_string, int pane, int item)
2223 pane_name = first_item[MENU_ITEMS_ITEM_NAME]; 2217 pane_name = first_item[MENU_ITEMS_ITEM_NAME];
2224 2218
2225 /* (menu-item MENU-NAME PANE-NUMBER) */ 2219 /* (menu-item MENU-NAME PANE-NUMBER) */
2226 menu_object = Fcons (Qmenu_item, 2220 menu_object = list3 (Qmenu_item, pane_name, make_number (pane));
2227 Fcons (pane_name,
2228 Fcons (make_number (pane), Qnil)));
2229 show_help_echo (help_string ? build_string (help_string) : Qnil, 2221 show_help_echo (help_string ? build_string (help_string) : Qnil,
2230 Qnil, menu_object, make_number (item)); 2222 Qnil, menu_object, make_number (item));
2231} 2223}
2232 2224
2233static Lisp_Object 2225static void
2234pop_down_menu (Lisp_Object arg) 2226pop_down_menu (Lisp_Object arg)
2235{ 2227{
2236 FRAME_PTR f = XSAVE_POINTER (arg, 0); 2228 FRAME_PTR f = XSAVE_POINTER (arg, 0);
@@ -2257,8 +2249,6 @@ pop_down_menu (Lisp_Object arg)
2257#endif /* HAVE_X_WINDOWS */ 2249#endif /* HAVE_X_WINDOWS */
2258 2250
2259 unblock_input (); 2251 unblock_input ();
2260
2261 return Qnil;
2262} 2252}
2263 2253
2264 2254
@@ -2475,8 +2465,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2475 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f)); 2465 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
2476#endif 2466#endif
2477 2467
2478 record_unwind_protect (pop_down_menu, 2468 record_unwind_protect (pop_down_menu, make_save_ptr_ptr (f, menu));
2479 make_save_value (SAVE_TYPE_PTR_PTR, f, menu));
2480 2469
2481 /* Help display under X won't work because XMenuActivate contains 2470 /* Help display under X won't work because XMenuActivate contains
2482 a loop that doesn't give Emacs a chance to process it. */ 2471 a loop that doesn't give Emacs a chance to process it. */
@@ -2515,7 +2504,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2515 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); 2504 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
2516 if (keymaps) 2505 if (keymaps)
2517 { 2506 {
2518 entry = Fcons (entry, Qnil); 2507 entry = list1 (entry);
2519 if (!NILP (pane_prefix)) 2508 if (!NILP (pane_prefix))
2520 entry = Fcons (pane_prefix, entry); 2509 entry = Fcons (pane_prefix, entry);
2521 } 2510 }
diff --git a/src/xml.c b/src/xml.c
index 4b466dc1bca..c330dce4a4a 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -124,7 +124,7 @@ make_dom (xmlNode *node)
124{ 124{
125 if (node->type == XML_ELEMENT_NODE) 125 if (node->type == XML_ELEMENT_NODE)
126 { 126 {
127 Lisp_Object result = Fcons (intern ((char *) node->name), Qnil); 127 Lisp_Object result = list1 (intern ((char *) node->name));
128 xmlNode *child; 128 xmlNode *child;
129 xmlAttr *property; 129 xmlAttr *property;
130 Lisp_Object plist = Qnil; 130 Lisp_Object plist = Qnil;
diff --git a/src/xselect.c b/src/xselect.c
index b422a22d68b..6a80eddc82c 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -45,26 +45,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45struct prop_location; 45struct prop_location;
46struct selection_data; 46struct selection_data;
47 47
48static Lisp_Object x_atom_to_symbol (Display *dpy, Atom atom);
49static Atom symbol_to_x_atom (struct x_display_info *, Lisp_Object);
50static void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object);
51static Lisp_Object x_get_local_selection (Lisp_Object, Lisp_Object, int,
52 struct x_display_info *);
53static void x_decline_selection_request (struct input_event *); 48static void x_decline_selection_request (struct input_event *);
54static Lisp_Object x_selection_request_lisp_error (Lisp_Object);
55static Lisp_Object queue_selection_requests_unwind (Lisp_Object);
56static Lisp_Object x_catch_errors_unwind (Lisp_Object);
57static void x_reply_selection_request (struct input_event *, struct x_display_info *);
58static int x_convert_selection (struct input_event *, Lisp_Object, Lisp_Object, 49static int x_convert_selection (struct input_event *, Lisp_Object, Lisp_Object,
59 Atom, int, struct x_display_info *); 50 Atom, int, struct x_display_info *);
60static int waiting_for_other_props_on_window (Display *, Window); 51static int waiting_for_other_props_on_window (Display *, Window);
61static struct prop_location *expect_property_change (Display *, Window, 52static struct prop_location *expect_property_change (Display *, Window,
62 Atom, int); 53 Atom, int);
63static void unexpect_property_change (struct prop_location *); 54static void unexpect_property_change (struct prop_location *);
64static Lisp_Object wait_for_property_change_unwind (Lisp_Object);
65static void wait_for_property_change (struct prop_location *); 55static void wait_for_property_change (struct prop_location *);
66static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object,
67 Lisp_Object, Lisp_Object);
68static Lisp_Object x_get_window_property_as_lisp_data (Display *, 56static Lisp_Object x_get_window_property_as_lisp_data (Display *,
69 Window, Atom, 57 Window, Atom,
70 Lisp_Object, Atom); 58 Lisp_Object, Atom);
@@ -74,7 +62,6 @@ static Lisp_Object selection_data_to_lisp_data (Display *,
74static void lisp_data_to_selection_data (Display *, Lisp_Object, 62static void lisp_data_to_selection_data (Display *, Lisp_Object,
75 unsigned char **, Atom *, 63 unsigned char **, Atom *,
76 ptrdiff_t *, int *, int *); 64 ptrdiff_t *, int *, int *);
77static Lisp_Object clean_local_selection_data (Lisp_Object);
78 65
79/* Printing traces to stderr. */ 66/* Printing traces to stderr. */
80 67
@@ -513,8 +500,8 @@ static Atom conversion_fail_tag;
513 an error, we tell the requestor that we were unable to do what they wanted 500 an error, we tell the requestor that we were unable to do what they wanted
514 before we throw to top-level or go into the debugger or whatever. */ 501 before we throw to top-level or go into the debugger or whatever. */
515 502
516static Lisp_Object 503static void
517x_selection_request_lisp_error (Lisp_Object ignore) 504x_selection_request_lisp_error (void)
518{ 505{
519 struct selection_data *cs, *next; 506 struct selection_data *cs, *next;
520 507
@@ -530,16 +517,14 @@ x_selection_request_lisp_error (Lisp_Object ignore)
530 if (x_selection_current_request != 0 517 if (x_selection_current_request != 0
531 && selection_request_dpyinfo->display) 518 && selection_request_dpyinfo->display)
532 x_decline_selection_request (x_selection_current_request); 519 x_decline_selection_request (x_selection_current_request);
533 return Qnil;
534} 520}
535 521
536static Lisp_Object 522static void
537x_catch_errors_unwind (Lisp_Object dummy) 523x_catch_errors_unwind (void)
538{ 524{
539 block_input (); 525 block_input ();
540 x_uncatch_errors (); 526 x_uncatch_errors ();
541 unblock_input (); 527 unblock_input ();
542 return Qnil;
543} 528}
544 529
545 530
@@ -560,11 +545,6 @@ struct prop_location
560 struct prop_location *next; 545 struct prop_location *next;
561}; 546};
562 547
563static struct prop_location *expect_property_change (Display *display, Window window, Atom property, int state);
564static void wait_for_property_change (struct prop_location *location);
565static void unexpect_property_change (struct prop_location *location);
566static int waiting_for_other_props_on_window (Display *display, Window window);
567
568static int prop_location_identifier; 548static int prop_location_identifier;
569 549
570static Lisp_Object property_change_reply; 550static Lisp_Object property_change_reply;
@@ -573,13 +553,6 @@ static struct prop_location *property_change_reply_object;
573 553
574static struct prop_location *property_change_wait_list; 554static struct prop_location *property_change_wait_list;
575 555
576static Lisp_Object
577queue_selection_requests_unwind (Lisp_Object tem)
578{
579 x_stop_queuing_selection_requests ();
580 return Qnil;
581}
582
583 556
584/* Send the reply to a selection request event EVENT. */ 557/* Send the reply to a selection request event EVENT. */
585 558
@@ -614,7 +587,7 @@ x_reply_selection_request (struct input_event *event,
614 /* The protected block contains wait_for_property_change, which can 587 /* The protected block contains wait_for_property_change, which can
615 run random lisp code (process handlers) or signal. Therefore, we 588 run random lisp code (process handlers) or signal. Therefore, we
616 put the x_uncatch_errors call in an unwind. */ 589 put the x_uncatch_errors call in an unwind. */
617 record_unwind_protect (x_catch_errors_unwind, Qnil); 590 record_unwind_protect_void (x_catch_errors_unwind);
618 x_catch_errors (display); 591 x_catch_errors (display);
619 592
620 /* Loop over converted selections, storing them in the requested 593 /* Loop over converted selections, storing them in the requested
@@ -805,12 +778,12 @@ x_handle_selection_request (struct input_event *event)
805 778
806 x_selection_current_request = event; 779 x_selection_current_request = event;
807 selection_request_dpyinfo = dpyinfo; 780 selection_request_dpyinfo = dpyinfo;
808 record_unwind_protect (x_selection_request_lisp_error, Qnil); 781 record_unwind_protect_void (x_selection_request_lisp_error);
809 782
810 /* We might be able to handle nested x_handle_selection_requests, 783 /* We might be able to handle nested x_handle_selection_requests,
811 but this is difficult to test, and seems unimportant. */ 784 but this is difficult to test, and seems unimportant. */
812 x_start_queuing_selection_requests (); 785 x_start_queuing_selection_requests ();
813 record_unwind_protect (queue_selection_requests_unwind, Qnil); 786 record_unwind_protect_void (x_stop_queuing_selection_requests);
814 787
815 TRACE2 ("x_handle_selection_request: selection=%s, target=%s", 788 TRACE2 ("x_handle_selection_request: selection=%s, target=%s",
816 SDATA (SYMBOL_NAME (selection_symbol)), 789 SDATA (SYMBOL_NAME (selection_symbol)),
@@ -1117,15 +1090,14 @@ unexpect_property_change (struct prop_location *location)
1117 1090
1118/* Remove the property change expectation element for IDENTIFIER. */ 1091/* Remove the property change expectation element for IDENTIFIER. */
1119 1092
1120static Lisp_Object 1093static void
1121wait_for_property_change_unwind (Lisp_Object loc) 1094wait_for_property_change_unwind (void *loc)
1122{ 1095{
1123 struct prop_location *location = XSAVE_POINTER (loc, 0); 1096 struct prop_location *location = loc;
1124 1097
1125 unexpect_property_change (location); 1098 unexpect_property_change (location);
1126 if (location == property_change_reply_object) 1099 if (location == property_change_reply_object)
1127 property_change_reply_object = 0; 1100 property_change_reply_object = 0;
1128 return Qnil;
1129} 1101}
1130 1102
1131/* Actually wait for a property change. 1103/* Actually wait for a property change.
@@ -1140,8 +1112,7 @@ wait_for_property_change (struct prop_location *location)
1140 emacs_abort (); 1112 emacs_abort ();
1141 1113
1142 /* Make sure to do unexpect_property_change if we quit or err. */ 1114 /* Make sure to do unexpect_property_change if we quit or err. */
1143 record_unwind_protect (wait_for_property_change_unwind, 1115 record_unwind_protect_ptr (wait_for_property_change_unwind, location);
1144 make_save_pointer (location));
1145 1116
1146 XSETCAR (property_change_reply, Qnil); 1117 XSETCAR (property_change_reply, Qnil);
1147 property_change_reply_object = location; 1118 property_change_reply_object = location;
@@ -1254,7 +1225,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
1254 SelectionNotify. */ 1225 SelectionNotify. */
1255#if 0 1226#if 0
1256 x_start_queuing_selection_requests (); 1227 x_start_queuing_selection_requests ();
1257 record_unwind_protect (queue_selection_requests_unwind, Qnil); 1228 record_unwind_protect_void (x_stop_queuing_selection_requests);
1258#endif 1229#endif
1259 1230
1260 unblock_input (); 1231 unblock_input ();
diff --git a/src/xterm.c b/src/xterm.c
index 547bdbe8333..30399c875e2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3448,9 +3448,15 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
3448 && CONSP (Vframe_list) 3448 && CONSP (Vframe_list)
3449 && !NILP (XCDR (Vframe_list))) 3449 && !NILP (XCDR (Vframe_list)))
3450 { 3450 {
3451 bufp->kind = FOCUS_IN_EVENT; 3451 bufp->arg = Qt;
3452 XSETFRAME (bufp->frame_or_window, frame);
3453 } 3452 }
3453 else
3454 {
3455 bufp->arg = Qnil;
3456 }
3457
3458 bufp->kind = FOCUS_IN_EVENT;
3459 XSETFRAME (bufp->frame_or_window, frame);
3454 } 3460 }
3455 3461
3456 frame->output_data.x->focus_state |= state; 3462 frame->output_data.x->focus_state |= state;
@@ -3468,6 +3474,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
3468 { 3474 {
3469 dpyinfo->x_focus_event_frame = 0; 3475 dpyinfo->x_focus_event_frame = 0;
3470 x_new_focus_frame (dpyinfo, 0); 3476 x_new_focus_frame (dpyinfo, 0);
3477
3478 bufp->kind = FOCUS_OUT_EVENT;
3479 XSETFRAME (bufp->frame_or_window, frame);
3471 } 3480 }
3472 3481
3473#ifdef HAVE_X_I18N 3482#ifdef HAVE_X_I18N
@@ -8386,9 +8395,9 @@ set_wm_state (Lisp_Object frame, int add, Atom atom, Atom value)
8386 (make_number (add ? 1 : 0), 8395 (make_number (add ? 1 : 0),
8387 Fcons 8396 Fcons
8388 (make_fixnum_or_float (atom), 8397 (make_fixnum_or_float (atom),
8389 value != 0 8398 (value != 0
8390 ? Fcons (make_fixnum_or_float (value), Qnil) 8399 ? list1 (make_fixnum_or_float (value))
8391 : Qnil))); 8400 : Qnil))));
8392} 8401}
8393 8402
8394void 8403void