aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Tromey2013-07-26 14:02:53 -0600
committerTom Tromey2013-07-26 14:02:53 -0600
commitcc231cbe45d27a1906d268fb72d3b4105a2e9c65 (patch)
treec011828e2a3a18e77eaa8849e3cccb805d798f42 /src
parentb34a529f177a6ea32da5cb1254f91bf9d71838db (diff)
parentfec9206062b420aca84f53d05a72c3ee43244022 (diff)
downloademacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.tar.gz
emacs-cc231cbe45d27a1906d268fb72d3b4105a2e9c65.zip
merge from trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog567
-rw-r--r--src/ChangeLog.126
-rw-r--r--src/Makefile.in8
-rw-r--r--src/alloc.c128
-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.c211
-rw-r--r--src/charset.c43
-rw-r--r--src/coding.c94
-rw-r--r--src/composite.c13
-rw-r--r--src/conf_post.h6
-rw-r--r--src/cygw32.c11
-rw-r--r--src/data.c13
-rw-r--r--src/deps.mk2
-rw-r--r--src/dired.c22
-rw-r--r--src/dispnew.c19
-rw-r--r--src/doc.c41
-rw-r--r--src/editfns.c28
-rw-r--r--src/emacs.c9
-rw-r--r--src/emacsgtkfixed.c2
-rw-r--r--src/eval.c420
-rw-r--r--src/fileio.c228
-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.c40
-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.c176
-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.m31
-rw-r--r--src/print.c8
-rw-r--r--src/process.c233
-rw-r--r--src/search.c4
-rw-r--r--src/sound.c12
-rw-r--r--src/sysdep.c335
-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.c31
-rw-r--r--src/window.c20
-rw-r--r--src/window.h1
-rw-r--r--src/xdisp.c80
-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.c22
74 files changed, 2378 insertions, 1604 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 60e7e376729..38fa72b0506 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,566 @@
12013-07-26 Eli Zaretskii <eliz@gnu.org>
2
3 * process.c (Fprocess_list): Doc fix.
4
5 * w32term.c (w32_read_socket) <WM_EMACS_PAINT>: Warn about frame
6 being re-exposed only if it didn't ask to become visible.
7 <WM_SIZE>: Under SIZE_RESTORED, only set the frame visible if it
8 was previously iconified. (Bug#14841)
9 (x_iconify_frame): Mark the frame iconified.
10
112013-07-26 Paul Eggert <eggert@cs.ucla.edu>
12
13 Fix minor problems found by static checking.
14 * eval.c (get_backtrace_frame, backtrace_eval_unrewind): Now static.
15 (backtrace_eval_unrewind): ';' -> '{}' to pacify GCC.
16
172013-07-26 Stefan Monnier <monnier@iro.umontreal.ca>
18
19 * eval.c (set_specpdl_old_value): New function.
20 (unbind_to): Minor simplification.
21 (get_backtrace_frame): New function.
22 (Fbacktrace_frame): Use it. Add `base' argument.
23 (backtrace_eval_unrewind, Fbacktrace_eval): New functions.
24 (syms_of_eval): Export backtrace-eval.
25 * xterm.c (x_focus_changed): Simplify.
26
272013-07-25 Paul Eggert <eggert@cs.ucla.edu>
28
29 * fileio.c (Finsert_file_contents): Avoid double-close (Bug#14936).
30
312013-07-24 Eli Zaretskii <eliz@gnu.org>
32
33 * xdisp.c (redisplay_window): Instead of moving point out of
34 scroll margin, reject the force_start method, and try scrolling
35 instead. (Bug#14780)
36
372013-07-24 Ken Brown <kbrown@cornell.edu>
38
39 * alloc.c (make_save_ptr): Define if HAVE_NTGUI is defined
40 (Bug#14944).
41
422013-07-24 Paul Eggert <eggert@cs.ucla.edu>
43
44 * eval.c (Fprogn): Do not check that BODY is a proper list.
45 This undoes the previous change. The check slows down the
46 interpreter, and is not needed to prevent a crash. See
47 <http://lists.gnu.org/archive/html/emacs-devel/2013-07/msg00693.html>.
48
492013-07-23 Glenn Morris <rgm@gnu.org>
50
51 * Makefile.in ($(etc)/DOC, temacs$(EXEEXT)): Ensure etc/ exists.
52
532013-07-23 Paul Eggert <eggert@cs.ucla.edu>
54
55 Port to GNU/Linux systems with tinfo but not ncurses.
56 * dispnew.c (init_display): Depend on USE_NCURSES, not GNU_LINUX,
57 to decide whether ncurses is being used. Without this change,
58 GCC complains about tgetent not being declared, on a system
59 that has tinfo installed but ncurses not installed.
60
61 * eval.c (Fprogn): Check that BODY is a proper list.
62
63 Tune UNEVALLED functions by using XCAR instead of Fcar, etc.
64 * data.c (Fsetq_default):
65 * eval.c (Fif, Fcond, Fprog1, Fsetq, Fquote, Ffunction, Fdefvar)
66 (Fdefconst, FletX, Flet, Fwhile, Fcatch, Funwind_protect)
67 (Fcondition_case):
68 Tune by taking advantage of the fact that ARGS is always a list
69 when a function is declared to have UNEVALLED args.
70
71 * emacsgtkfixed.c: Port to GCC 4.6.
72 GCC 4.6 complains about -Wunused-local-typedefs, introduced in 4.7.
73
742013-07-23 Juanma Barranquero <lekktu@gmail.com>
75
76 * callproc.c (child_setup)[!WINDOWSNT]: Move exec_errno and pid
77 here to silence compiler warnings.
78
792013-07-22 Paul Eggert <eggert@cs.ucla.edu>
80
81 * sysdep.c (frame) [__FreeBSD__]: #define to freebsd_frame
82 when including <sys/user.h>, to prevent Sparc/ARM machine/frame.h
83 from messing up Emacs's 'struct frame' (Bug#14923).
84
852013-07-21 Paul Eggert <eggert@cs.ucla.edu>
86
87 * alloc.c (make_save_ptr_ptr): Define this function.
88 It was inadvertently omitted. It's needed only if
89 HAVE_MENUS && ! (USE_X_TOOLKIT || USE_GTK).
90
912013-07-21 Jan Djärv <jan.h.d@swipnet.se>
92
93 * nsterm.m (sendEvent:): Skip mouse moved if no dialog and no Emacs
94 frame have focus (Bug#14895).
95
962013-07-21 Paul Eggert <eggert@cs.ucla.edu>
97
98 Avoid vfork-related deadlock more cleanly.
99 * callproc.c (child_setup): When the child's exec fails, output
100 the program name, as that's more useful. Use O_NONBLOCK to avoid
101 deadlock.
102 * process.c (create_process_1): Remove; no longer needed.
103 (create_process): Remove timer hack; no longer needed, now that
104 the child avoids deadlock.
105
1062013-07-20 Glenn Morris <rgm@gnu.org>
107
108 * image.c (Fimage_flush): Fix doc typo.
109
1102013-07-20 Paul Eggert <eggert@cs.ucla.edu>
111
112 Fix array bounds violation when pty allocation fails.
113 * process.c (PTY_NAME_SIZE): New constant.
114 (pty_name): Remove static variable; it's now auto.
115 (allocate_pty): Define even if !HAVE_PTYS; that's simpler.
116 Take pty_name as an arg rather than using a static variable.
117 All callers changed.
118 (create_process): Recover pty_flag from process, not from volatile local.
119 (create_pty): Stay inside array even when pty allocation fails.
120 (Fmake_serial_process): Omit unnecessary initializaiton of pty_flag.
121
122 * lread.c (Fload): Avoid initialization only when lint checking.
123 Mention that it's needed only for older GCCs.
124
1252013-07-20 Kenichi Handa <handa@gnu.org>
126
127 * coding.c (CODING_ISO_FLAG_LEVEL_4): New macro.
128 (decode_coding_iso_2022): Check the single-shift area. (Bug#8522)
129
1302013-07-20 Andreas Schwab <schwab@linux-m68k.org>
131
132 * lread.c (Fload): Avoid uninitialized warning.
133
1342013-07-19 Paul Eggert <eggert@cs.ucla.edu>
135
136 Fix some minor file descriptor leaks and related glitches.
137 * filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC.
138 (create_lock_file): Use write, not emacs_write.
139 * image.c (slurp_file, png_load_body):
140 * process.c (Fnetwork_interface_list, Fnetwork_interface_info)
141 (server_accept_connection):
142 Don't leak an fd on memory allocation failure.
143 * image.c (slurp_file): Add a cheap heuristic for growing files.
144 * xfaces.c (Fx_load_color_file): Block input around the fopen too,
145 as that's what the other routines do. Maybe input need not be
146 blocked at all, but it's better to be consistent.
147 Avoid undefined behavior when strlen is zero.
148
149 * alloc.c (staticpro): Avoid buffer overrun on repeated calls.
150 (NSTATICS): Now a constant; doesn't need to be a macro.
151
1522013-07-19 Richard Stallman <rms@gnu.org>
153
154 * coding.c (decode_coding_utf_8): Add simple loop for fast
155 processing of ASCII characters.
156
1572013-07-19 Paul Eggert <eggert@cs.ucla.edu>
158
159 * conf_post.h (RE_TRANSLATE_P) [emacs]: Remove obsolete optimization.
160
1612013-07-19 Eli Zaretskii <eliz@gnu.org>
162
163 * keyboard.c (kbd_buffer_get_event): Use Display_Info instead of
164 unportable 'struct x_display_info'.
165 (DISPLAY_LIST_INFO): Delete macro: not needed, since Display_Info
166 is a portable type.
167
1682013-07-19 Paul Eggert <eggert@cs.ucla.edu>
169
170 * sysdep.c [GNU_LINUX]: Fix fd and memory leaks and similar issues.
171 (procfs_ttyname): Don't use uninitialized storage if emacs_fopen
172 or fscanf fails.
173 (system_process_attributes): Prefer plain char to unsigned char
174 when either will do. Clean up properly if interrupted or if
175 memory allocations fail. Don't assume sscanf succeeds. Remove
176 no-longer-needed workaround to stop GCC from whining. Read
177 command-line once, instead of multiple times. Check read status a
178 bit more carefully.
179
180 Fix obscure porting bug with varargs functions.
181 The code assumed that int is treated like ptrdiff_t in a vararg
182 function, which is not a portable assumption. There was a similar
183 -- though these days less likely -- porting problem with various
184 assumptions that pointers of different types all smell the same as
185 far as vararg functions is conserved. To make this problem less
186 likely in the future, redo the API to use varargs functions.
187 * alloc.c (make_save_value): Remove this vararg function.
188 All uses changed to ...
189 (make_save_int_int_int, make_save_obj_obj_obj_obj)
190 (make_save_ptr_int, make_save_funcptr_ptr_obj, make_save_memory):
191 New functions.
192 (make_save_ptr): Rename from make_save_pointer, for consistency with
193 the above. Define only on platforms that need it. All uses changed.
194
1952013-07-18 Paul Eggert <eggert@cs.ucla.edu>
196
197 * keyboard.c: Try to fix typos in previous change.
198 (DISPLAY_LIST_INFO): New macro.
199 (kbd_buffer_get_event): Do not access members that are not present
200 in X11. Revert inadvertent change of "!=" to "=".
201
2022013-07-18 Juanma Barranquero <lekktu@gmail.com>
203
204 * keyboard.c (kbd_buffer_get_event):
205 * w32term.c (x_focus_changed): Port FOCUS_(IN|OUT)_EVENT changes to W32.
206 Followup to 2013-07-16T11:41:06Z!jan.h.d@swipnet.se.
207
2082013-07-18 Paul Eggert <eggert@cs.ucla.edu>
209
210 * filelock.c: Fix unlikely file descriptor leaks.
211 (get_boot_time_1): Rework to avoid using emacs_open.
212 This doesn't actually fix a leak, but is better anyway.
213 (read_lock_data): Use read, not emacs_read.
214
215 * doc.c: Fix minor memory and file descriptor leaks.
216 * doc.c (get_doc_string): Fix memory leak when doc file absent.
217 (get_doc_string, Fsnarf_documentation):
218 Fix file descriptor leak on error.
219
220 * term.c: Fix minor fdopen-related file descriptor leaks.
221 * term.c (Fresume_tty) [!MSDOS]: Close fd if fdopen (fd) fails.
222 (init_tty) [!DOS_NT]: Likewise. Also close fd if isatty (fd) fails.
223
224 * charset.c: Fix file descriptor leaks and errno issues.
225 Include <errno.h>.
226 (load_charset_map_from_file): Don't leak file descriptor on error.
227 Use plain record_xmalloc since the allocation is larger than
228 MAX_ALLOCA; that's simpler here. Simplify test for exhaustion
229 of entries.
230 * eval.c (record_unwind_protect_nothing):
231 * fileio.c (fclose_unwind):
232 New functions.
233 * lread.c (load_unwind): Remove. All uses replaced by fclose_unwind.
234 The replacement doesn't block input, but that no longer seems
235 necessary.
236
2372013-07-17 Paul Eggert <eggert@cs.ucla.edu>
238
239 * lread.c: Fix file descriptor leaks and errno issues.
240 (Fload): Close some races that leaked fds or streams when 'load'
241 was interrupted.
242 (Fload, openp): Report error number of last nontrivial failure to open.
243 ENOENT counts as trivial.
244 * eval.c (do_nothing, clear_unwind_protect, set_unwind_protect_ptr):
245 New functions.
246 * fileio.c (close_file_unwind): No need to test whether FD is nonnegative,
247 now that the function is always called with a nonnegative arg.
248 * lisp.h (set_unwind_protect_ptr, set_unwind_protect_int): Remove.
249 All uses replaced with ...
250 (clear_unwind_protect, set_unwind_protect_ptr): New decls.
251
252 A few more minor file errno-reporting bugs.
253 * callproc.c (Fcall_process):
254 * doc.c (Fsnarf_documentation):
255 * fileio.c (Frename_file, Fadd_name_to_file, Fmake_symbolic_link):
256 * process.c (set_socket_option):
257 Don't let a constructor trash errno.
258 * doc.c: Include <errno.h>.
259
2602013-07-16 Juanma Barranquero <lekktu@gmail.com>
261
262 * w32fns.c (unwind_create_tip_frame): Fix declaration.
263
2642013-07-16 Paul Eggert <eggert@cs.ucla.edu>
265
266 Fix w32 bug with call-process-region (Bug#14885).
267 * callproc.c (Fcall_process_region): Pass nil, not "/dev/null",
268 to Fcall_process when the input is empty. This simplifies the
269 code a bit. It makes no difference on POSIXish platforms but
270 apparently it fixes a bug on w32.
271
272 Fix bug where insert-file-contents closes a file twice. (Bug#14839).
273 * fileio.c (close_file_unwind): Don't close if FD is negative;
274 this can happen when unwinding a zapped file descriptor.
275 (Finsert_file_contents): Unwind-protect the fd before the point marker,
276 in case Emacs runs out of memory between the two unwind-protects.
277 Don't trash errno when closing FD.
278 Zap the FD in the specpdl when closing it, instead of deferring
279 the removal of the unwind-protect; this fixes a bug where a child
280 function unwinds the stack past us.
281
282 New unwind-protect flavors to better type-check C callbacks.
283 This also lessens the need to write wrappers for callbacks,
284 and the need for make_save_pointer.
285 * alloca.c (free_save_value):
286 * atimer.c (run_all_atimers):
287 Now extern.
288 * alloc.c (safe_alloca_unwind):
289 * atimer.c (unwind_stop_other_atimers):
290 * keyboard.c (cancel_hourglass_unwind) [HAVE_WINDOW_SYSTEM]:
291 * menu.c (cleanup_popup_menu) [HAVE_NS]:
292 * minibuf.c (choose_minibuf_frame_1):
293 * process.c (make_serial_process_unwind):
294 * xdisp.h (pop_message_unwind):
295 * xselect.c (queue_selection_requests_unwind):
296 Remove no-longer-needed wrapper. All uses replaced by the wrappee.
297 * alloca.c (record_xmalloc):
298 Prefer record_unwind_protect_ptr to record_unwind_protect with
299 make_save_pointer.
300 * alloca.c (Fgarbage_collect):
301 Prefer record_unwind_protect_void to passing a dummy.
302 * buffer.c (restore_buffer):
303 * window.c (restore_window_configuration):
304 * xfns.c, w32fns.c (do_unwind_create_frame)
305 New wrapper. All record-unwind uses of wrappee changed.
306 * buffer.c (set_buffer_if_live):
307 * callproc.c (call_process_cleanup, delete_temp_file):
308 * coding.c (code_conversion_restore):
309 * dired.c (directory_files_internal_w32_unwind) [WINDOWSNT]:
310 * editfns.c (save_excursion_restore)
311 (subst_char_in_region_unwind, subst_char_in_region_unwind_1)
312 (save_restriction_restore):
313 * eval.c (restore_stack_limits, un_autoload):
314 * fns.c (require_unwind):
315 * keyboard.c (recursive_edit_unwind, tracking_off):
316 * lread.c (record_load_unwind, load_warn_old_style_backquotes):
317 * macros.c (pop_kbd_macro, restore_menu_items):
318 * nsfns.m (unwind_create_frame):
319 * print.c (print_unwind):
320 * process.c (start_process_unwind):
321 * search.c (unwind_set_match_data):
322 * window.c (select_window_norecord, select_frame_norecord):
323 * xdisp.c (unwind_with_echo_area_buffer, unwind_format_mode_line)
324 (fast_set_selected_frame):
325 * xfns.c, w32fns.c (unwind_create_tip_frame):
326 Return void, not a dummy Lisp_Object. All uses changed.
327 * buffer.h (set_buffer_if_live): Move decl here from lisp.h.
328 * callproc.c (call_process_kill):
329 * fileio.c (restore_point_unwind, decide_coding_unwind)
330 (build_annotations_unwind):
331 * insdel.c (Fcombine_after_change_execute_1):
332 * keyboard.c (read_char_help_form_unwind):
333 * menu.c (unuse_menu_items):
334 * minibuf.c (run_exit_minibuf_hook, read_minibuf_unwind):
335 * sound.c (sound_cleanup):
336 * xdisp.c (unwind_redisplay):
337 * xfns.c (clean_up_dialog):
338 * xselect.c (x_selection_request_lisp_error, x_catch_errors_unwind):
339 Accept no args and return void, instead of accepting and returning
340 a dummy Lisp_Object. All uses changed.
341 * cygw32.c (fchdir_unwind):
342 * fileio.c (close_file_unwind):
343 * keyboard.c (restore_kboard_configuration):
344 * lread.c (readevalllop_1):
345 * process.c (wait_reading_process_output_unwind):
346 Accept int and return void, rather than accepting an Emacs integer
347 and returning a dummy object. In some cases this fixes an
348 unlikely bug when the corresponding int is outside Emacs integer
349 range. All uses changed.
350 * dired.c (directory_files_internal_unwind):
351 * fileio.c (do_auto_save_unwind):
352 * gtkutil.c (pop_down_dialog):
353 * insdel.c (reset_var_on_error):
354 * lread.c (load_unwind):
355 * xfns.c (clean_up_file_dialog):
356 * xmenu.c, nsmenu.m (pop_down_menu):
357 * xmenu.c (cleanup_widget_value_tree):
358 * xselect.c (wait_for_property_change_unwind):
359 Accept pointer and return void, rather than accepting an Emacs
360 save value encapsulating the pointer and returning a dummy object.
361 All uses changed.
362 * editfns.c (Fformat): Update the saved pointer directly via
363 set_unwind_protect_ptr rather than indirectly via make_save_pointer.
364 * eval.c (specpdl_func): Remove. All uses replaced by definiens.
365 (unwind_body): New function.
366 (record_unwind_protect): First arg is now a function returning void,
367 not a dummy Lisp_Object.
368 (record_unwind_protect_ptr, record_unwind_protect_int)
369 (record_unwind_protect_void): New functions.
370 (unbind_to): Support SPECPDL_UNWIND_PTR etc.
371 * fileio.c (struct auto_save_unwind): New type.
372 (do_auto_save_unwind): Use it.
373 (do_auto_save_unwind_1): Remove; subsumed by new do_auto_save_unwind.
374 * insdel.c (struct rvoe_arg): New type.
375 (reset_var_on_error): Use it.
376 * lisp.h (SPECPDL_UNWIND_PTR, SPECPDL_UNWIND_INT, SPECPDL_UNWIND_VOID):
377 New constants.
378 (specbinding_func): Remove; there are now several such functions.
379 (union specbinding): New members unwind_ptr, unwind_int, unwind_void.
380 (set_unwind_protect_ptr): New function.
381 * xselect.c: Remove unnecessary forward decls, to simplify maintenance.
382
383 Be simpler and more consistent about reporting I/O errors.
384 * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
385 Say "Read error" and "Write error", rather than "I/O error", or
386 "IO error reading", or "IO error writing", when a read or write
387 error occurs.
388 * process.c (Fmake_network_process, wait_reading_process_output)
389 (send_process, Fprocess_send_eof, wait_reading_process_output):
390 Capitalize diagnostics consistently. Put "failed foo" at the
391 start of the diagnostic, so that we don't capitalize the
392 function name "foo". Consistently say "failed" for such
393 diagnostics.
394 * sysdep.c, w32.c (serial_open): Now accepts Lisp string, not C string.
395 All callers changed. This is so it can use report_file_error.
396 * sysdep.c (serial_open, serial_configure): Capitalize I/O
397 diagnostics consistently as above.
398
399 * fileio.c (report_file_errno): Fix errno reporting bug.
400 If the file name is neither null nor a pair, package it up as a
401 singleton list. All callers changed, both to this function and to
402 report_file_error. This fixes a bug where the memory allocator
403 invoked by list1 set errno so that the immediately following
404 report_file_error reported the wrong errno value.
405
406 Fix minor problems found by --enable-gcc-warnings.
407 * frame.c (Fhandle_focus_in, Fhandle_focus_out): Return a value.
408 * keyboard.c (kbd_buffer_get_event): Remove unused local.
409
4102013-07-16 Jan Djärv <jan.h.d@swipnet.se>
411
412 * xterm.c (x_focus_changed): Always generate FOCUS_IN_EVENT.
413 Set event->arg to Qt if switch-event shall be generated.
414 Generate FOCUS_OUT_EVENT for FocusOut if this is the focused frame.
415
416 * termhooks.h (enum event_kind): Add FOCUS_OUT_EVENT.
417
418 * nsterm.m (windowDidResignKey): If this is the focused frame, generate
419 FOCUS_OUT_EVENT.
420
421 * keyboard.c (Qfocus_in, Qfocus_out): New static objects.
422 (make_lispy_focus_in, make_lispy_focus_out): Declare and define.
423 (kbd_buffer_get_event): For FOCUS_IN, make a focus_in event if no
424 switch frame event is made. Check ! NILP (event->arg) if X11 (moved
425 from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11
426 and there is a focused frame.
427 (head_table): Add focus-in and focus-out.
428 (keys_of_keyboard): Add focus-in and focus-out to Vspecial_event_map,
429 bind to handle-focus-in/out.
430
431 * frame.c (Fhandle_focus_in, Fhandle_focus_out): New functions.
432 (Fhandle_switch_frame): Call Fhandle_focus_in.
433 (syms_of_frame): defsubr handle-focus-in/out.
434
4352013-07-16 Paul Eggert <eggert@cs.ucla.edu>
436
437 Fix porting bug to older POSIXish platforms (Bug#14862).
438 * sysdep.c (emacs_pipe): New function, that implements
439 pipe2 (fd, O_CLOEXEC) even on hosts that lack O_CLOEXEC.
440 This should port better to CentOS 5 and to Mac OS X 10.6.
441 All calls to pipe2 changed.
442
443 Prefer list1 (X) to Fcons (X, Qnil) when building lists.
444 This makes the code easier to read and the executable a bit smaller.
445 Do not replace all calls to Fcons that happen to create lists,
446 just calls that are intended to create lists. For example, when
447 creating an alist that maps FOO to nil, use list1 (Fcons (FOO, Qnil))
448 rather than list1 (list1 (FOO)) or Fcons (Fcons (FOO, Qnil), Qnil).
449 Similarly for list2 through list5.
450 * buffer.c (Fget_buffer_create, Fmake_indirect_buffer):
451 * bytecode.c (exec_byte_code):
452 * callint.c (quotify_arg, Fcall_interactively):
453 * callproc.c (Fcall_process, create_temp_file):
454 * charset.c (load_charset_map_from_file)
455 (Fdefine_charset_internal, init_charset):
456 * coding.c (get_translation_table, detect_coding_system)
457 (Fcheck_coding_systems_region)
458 (Fset_terminal_coding_system_internal)
459 (Fdefine_coding_system_internal, Fdefine_coding_system_alias):
460 * composite.c (update_compositions, Ffind_composition_internal):
461 * dired.c (directory_files_internal, file_name_completion)
462 (Fsystem_users):
463 * dispnew.c (Fopen_termscript, bitch_at_user, init_display):
464 * doc.c (Fsnarf_documentation):
465 * editfns.c (Fmessage_box):
466 * emacs.c (main):
467 * eval.c (do_debug_on_call, signal_error, maybe_call_debugger)
468 (Feval, eval_sub, Ffuncall, apply_lambda):
469 * fileio.c (make_temp_name, Fcopy_file, Faccess_file)
470 (Fset_file_selinux_context, Fset_file_acl, Fset_file_modes)
471 (Fset_file_times, Finsert_file_contents)
472 (Fchoose_write_coding_system, Fwrite_region):
473 * fns.c (Flax_plist_put, Fyes_or_no_p, syms_of_fns):
474 * font.c (font_registry_charsets, font_parse_fcname)
475 (font_prepare_cache, font_update_drivers, Flist_fonts):
476 * fontset.c (Fset_fontset_font, Ffontset_info, syms_of_fontset):
477 * frame.c (make_frame, Fmake_terminal_frame)
478 (x_set_frame_parameters, x_report_frame_params)
479 (x_default_parameter, Fx_parse_geometry):
480 * ftfont.c (syms_of_ftfont):
481 * image.c (gif_load):
482 * keyboard.c (command_loop_1):
483 * keymap.c (Fmake_keymap, Fmake_sparse_keymap, access_keymap_1)
484 (Fcopy_keymap, append_key, Fcurrent_active_maps)
485 (Fminor_mode_key_binding, accessible_keymaps_1)
486 (Faccessible_keymaps, Fwhere_is_internal):
487 * lread.c (read_emacs_mule_char):
488 * menu.c (find_and_return_menu_selection):
489 * minibuf.c (get_minibuffer):
490 * nsfns.m (Fns_perform_service):
491 * nsfont.m (ns_script_to_charset):
492 * nsmenu.m (ns_popup_dialog):
493 * nsselect.m (ns_get_local_selection, ns_string_from_pasteboard)
494 (Fx_own_selection_internal):
495 * nsterm.m (append2):
496 * print.c (Fredirect_debugging_output)
497 (print_prune_string_charset):
498 * process.c (Fdelete_process, Fprocess_contact)
499 (Fformat_network_address, set_socket_option)
500 (read_and_dispose_of_process_output, write_queue_push)
501 (send_process, exec_sentinel):
502 * sound.c (Fplay_sound_internal):
503 * textprop.c (validate_plist, add_properties)
504 (Fput_text_property, Fadd_face_text_property)
505 (copy_text_properties, text_property_list, syms_of_textprop):
506 * unexaix.c (report_error):
507 * unexcoff.c (report_error):
508 * unexsol.c (unexec):
509 * xdisp.c (redisplay_tool_bar, store_mode_line_string)
510 (Fformat_mode_line, syms_of_xdisp):
511 * xfaces.c (set_font_frame_param)
512 (Finternal_lisp_face_attribute_values)
513 (Finternal_merge_in_global_face, syms_of_xfaces):
514 * xfns.c (x_default_scroll_bar_color_parameter)
515 (x_default_font_parameter, x_create_tip_frame):
516 * xfont.c (xfont_supported_scripts):
517 * xmenu.c (Fx_popup_dialog, xmenu_show, xdialog_show)
518 (menu_help_callback, xmenu_show):
519 * xml.c (make_dom):
520 * xterm.c (set_wm_state):
521 Prefer list1 (FOO) to Fcons (FOO, Qnil) when creating a list,
522 and similarly for list2 through list5.
523
5242013-07-15 Paul Eggert <eggert@cs.ucla.edu>
525
526 * callproc.c (Fcall_process_region): Fix minor race and tune.
527 (create_temp_file): New function, with the temp-file-creation part
528 of the old Fcall_process_region. Use Fcopy_sequence to create the
529 temp file name, rather than alloca + build_string, for simplicity.
530 Don't bother to block input around the temp file creation;
531 shouldn't be needed. Simplify use of mktemp. Use
532 record_unwind_protect immediately after creating the temp file;
533 this closes an unlikely race where the temp file was not removed.
534 Use memcpy rather than an open-coded loop.
535 (Fcall_process_region): Use the new function. If the input is
536 empty, redirect from /dev/null rather than from a newly created
537 empty temp file; this avoids unnecessary file system traffic.
538
5392013-07-14 Paul Eggert <eggert@cs.ucla.edu>
540
541 * filelock.c (create_lock_file) [!HAVE_MKOSTEMP && !HAVE_MKSTEMP]:
542 Simplify by making this case like the other two. This is a bit
543 slower on obsolete hosts, but the extra complexity isn't worth it.
544
545 * callproc.c (child_setup, relocate_fd) [!DOS_NT]:
546 * process.c (create_process) [!DOS_NT]:
547 Remove now-unnecessary calls to emacs_close.
548
5492013-07-13 Eli Zaretskii <eliz@gnu.org>
550
551 * w32term.c (x_draw_hollow_cursor): Delete the brush object when
552 returning early. (Bug#14850)
553
554 * coding.c (syms_of_coding): Set up inhibit-null-byte-detection
555 and inhibit-iso-escape-detection attributes of 'undecided'.
556 (Bug#14822)
557
12013-07-13 Paul Eggert <eggert@cs.ucla.edu> 5582013-07-13 Paul Eggert <eggert@cs.ucla.edu>
2 559
560 * deps.mk (sysdep.o): Remove dependency on ../lib/ignore-value.h.
561 Reported by Herbert J. Skuhra in
562 <http://lists.gnu.org/archive/html/emacs-devel/2013-07/msg00455.html>.
563
3 Don't lose top specpdl entry when memory is exhausted. 564 Don't lose top specpdl entry when memory is exhausted.
4 * eval.c (grow_specpdl): Increment specpdl top by 1 and check for 565 * eval.c (grow_specpdl): Increment specpdl top by 1 and check for
5 specpdl overflow here, to simplify callers; all callers changed. 566 specpdl overflow here, to simplify callers; all callers changed.
@@ -136,7 +697,7 @@
136 initializers. 697 initializers.
137 698
138 Syntax cleanup, mostly replacing macros with functions. 699 Syntax cleanup, mostly replacing macros with functions.
139` This removes the need for the syntax_temp hack. 700 This removes the need for the syntax_temp hack.
140 * search.c: Include syntax.h after buffer.h, since syntax.h uses BVAR. 701 * search.c: Include syntax.h after buffer.h, since syntax.h uses BVAR.
141 * syntax.c (SYNTAX_INLINE): New macro. 702 * syntax.c (SYNTAX_INLINE): New macro.
142 (SYNTAX_FLAGS_COMSTART_FIRST, SYNTAX_FLAGS_COMSTART_SECOND) 703 (SYNTAX_FLAGS_COMSTART_FIRST, SYNTAX_FLAGS_COMSTART_SECOND)
@@ -234,7 +795,7 @@
234 (emacswrite_sig, emacs_perror): New functions. 795 (emacswrite_sig, emacs_perror): New functions.
235 * xrdb.c (fatal): Don't invoke perror, since errno might be garbage. 796 * xrdb.c (fatal): Don't invoke perror, since errno might be garbage.
236 797
2372013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change). 7982013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change).
238 799
239 * image.c (imagemagick_load_image): Do not use MagickExportImagePixels 800 * image.c (imagemagick_load_image): Do not use MagickExportImagePixels
240 on NS even if it is present. Pixmap on NS is a void*. 801 on NS even if it is present. Pixmap on NS is a void*.
@@ -789,7 +1350,7 @@
789 1350
790 * floatfns.c (Flog10): Move to Lisp (marked obsolete there). 1351 * floatfns.c (Flog10): Move to Lisp (marked obsolete there).
791 1352
7922013-06-20 Rüdiger Sonderfeld <ruediger@c-plusplus.de> 13532013-06-20 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
793 1354
794 * floatfns.c (Flog) [HAVE_LOG2]: Use log2 if available and if the 1355 * floatfns.c (Flog) [HAVE_LOG2]: Use log2 if available and if the
795 base is 2; this is more accurate. 1356 base is 2; this is more accurate.
diff --git a/src/ChangeLog.12 b/src/ChangeLog.12
index 2b22690bb87..053baa3d487 100644
--- a/src/ChangeLog.12
+++ b/src/ChangeLog.12
@@ -69,7 +69,7 @@
69 69
70 * dispnew.c (update_window): Use MATRIX_ROW and MATRIX_MODE_LINE_ROW. 70 * dispnew.c (update_window): Use MATRIX_ROW and MATRIX_MODE_LINE_ROW.
71 71
722013-03-10 handa <handa@gnu.org> 722013-03-10 Kenichi Handa <handa@gnu.org>
73 73
74 * lisp.h (adjust_after_replace): Extern it. 74 * lisp.h (adjust_after_replace): Extern it.
75 75
@@ -11043,7 +11043,7 @@
11043 * nsterm.m (x_free_frame_resources): Move xfree so freed memory isn't 11043 * nsterm.m (x_free_frame_resources): Move xfree so freed memory isn't
11044 referenced (Bug#11583). 11044 referenced (Bug#11583).
11045 11045
110462012-06-16 Aurelien Aptel <aurelien.aptel@gmail.com> 110462012-06-16 Aurélien Aptel <aurelien.aptel@gmail.com>
11047 11047
11048 Implement wave-style variant of underlining. 11048 Implement wave-style variant of underlining.
11049 * dispextern.h (face_underline_type): New enum. 11049 * dispextern.h (face_underline_type): New enum.
@@ -21400,7 +21400,7 @@
21400 21400
21401 * process.c (Fformat_network_address): Doc fix. 21401 * process.c (Fformat_network_address): Doc fix.
21402 21402
214032011-04-08 T.V. Raman <tv.raman.tv@gmail.com> (tiny change) 214032011-04-08 T. V. Raman <tv.raman.tv@gmail.com> (tiny change)
21404 21404
21405 * xml.c (parse_region): Avoid creating spurious whitespace nodes. 21405 * xml.c (parse_region): Avoid creating spurious whitespace nodes.
21406 21406
diff --git a/src/Makefile.in b/src/Makefile.in
index 2bd1fc43239..ce709a6bc44 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,4 +1,4 @@
1# src/Makefile for GNU Emacs. 1### @configure_input@
2 2
3# Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2013 Free Software 3# Copyright (C) 1985, 1987-1988, 1993-1995, 1999-2013 Free Software
4# Foundation, Inc. 4# Foundation, Inc.
@@ -470,6 +470,7 @@ emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \
470## in the contents of the DOC file. 470## in the contents of the DOC file.
471## 471##
472$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(obj) $(lisp) 472$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(obj) $(lisp)
473 $(MKDIR_P) $(etc)
473 -rm -f $(etc)/DOC 474 -rm -f $(etc)/DOC
474 $(libsrc)/make-docfile -d $(srcdir) $(SOME_MACHINE_OBJECTS) $(obj) > $(etc)/DOC 475 $(libsrc)/make-docfile -d $(srcdir) $(SOME_MACHINE_OBJECTS) $(obj) > $(etc)/DOC
475 $(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) `sed -n -e 's| \\\\||' -e 's|^[ ]*$$(lispsource)/||p' $(srcdir)/lisp.mk` 476 $(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) `sed -n -e 's| \\\\||' -e 's|^[ ]*$$(lispsource)/||p' $(srcdir)/lisp.mk`
@@ -498,10 +499,15 @@ $(ALLOBJS): globals.h
498$(lib)/libgnu.a: $(config_h) 499$(lib)/libgnu.a: $(config_h)
499 cd $(lib) && $(MAKE) libgnu.a 500 cd $(lib) && $(MAKE) libgnu.a
500 501
502## We have to create $(etc) here because init_cmdargs tests its
503## existence when setting Vinstallation_directory (FIXME?).
504## This goes on to affect various things, and the emacs binary fails
505## to start if Vinstallation_directory has the wrong value.
501temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \ 506temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
502 $(lib)/libgnu.a $(EMACSRES) 507 $(lib)/libgnu.a $(EMACSRES)
503 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \ 508 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
504 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES) 509 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
510 $(MKDIR_P) $(etc)
505 $(TEMACS_POST_LINK) 511 $(TEMACS_POST_LINK)
506 test "$(CANNOT_DUMP)" = "yes" || \ 512 test "$(CANNOT_DUMP)" = "yes" || \
507 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT) 513 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)
diff --git a/src/alloc.c b/src/alloc.c
index 6ef6af1e3a1..0eb54f8b271 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);
@@ -334,7 +333,7 @@ static struct mem_node *mem_find (void *);
334/* Addresses of staticpro'd variables. Initialize it to a nonzero 333/* Addresses of staticpro'd variables. Initialize it to a nonzero
335 value; otherwise some compilers put it into BSS. */ 334 value; otherwise some compilers put it into BSS. */
336 335
337#define NSTATICS 0x800 336enum { NSTATICS = 2048 };
338static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; 337static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
339 338
340/* Index of next unused slot in staticvec. */ 339/* Index of next unused slot in staticvec. */
@@ -805,22 +804,13 @@ xputenv (char const *string)
805 memory_full (0); 804 memory_full (0);
806} 805}
807 806
808/* Unwind for SAFE_ALLOCA */
809
810Lisp_Object
811safe_alloca_unwind (Lisp_Object arg)
812{
813 free_save_value (arg);
814 return Qnil;
815}
816
817/* Return a newly allocated memory block of SIZE bytes, remembering 807/* Return a newly allocated memory block of SIZE bytes, remembering
818 to free it when unwinding. */ 808 to free it when unwinding. */
819void * 809void *
820record_xmalloc (size_t size) 810record_xmalloc (size_t size)
821{ 811{
822 void *p = xmalloc (size); 812 void *p = xmalloc (size);
823 record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); 813 record_unwind_protect_ptr (xfree, p);
824 return p; 814 return p;
825} 815}
826 816
@@ -3351,67 +3341,101 @@ verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT)
3351 >> SAVE_SLOT_BITS) 3341 >> SAVE_SLOT_BITS)
3352 == 0); 3342 == 0);
3353 3343
3354/* Return a Lisp_Save_Value object with the data saved according to 3344/* Return Lisp_Save_Value objects for the various combinations
3355 DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ 3345 that callers need. */
3356 3346
3357Lisp_Object 3347Lisp_Object
3358make_save_value (enum Lisp_Save_Type save_type, ...) 3348make_save_int_int_int (ptrdiff_t a, ptrdiff_t b, ptrdiff_t c)
3359{ 3349{
3360 va_list ap;
3361 int i;
3362 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3350 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3363 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3351 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3352 p->save_type = SAVE_TYPE_INT_INT_INT;
3353 p->data[0].integer = a;
3354 p->data[1].integer = b;
3355 p->data[2].integer = c;
3356 return val;
3357}
3364 3358
3365 eassert (0 < save_type 3359Lisp_Object
3366 && (save_type < 1 << (SAVE_TYPE_BITS - 1) 3360make_save_obj_obj_obj_obj (Lisp_Object a, Lisp_Object b, Lisp_Object c,
3367 || save_type == SAVE_TYPE_MEMORY)); 3361 Lisp_Object d)
3368 p->save_type = save_type; 3362{
3369 va_start (ap, save_type); 3363 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3370 save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); 3364 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3371 3365 p->save_type = SAVE_TYPE_OBJ_OBJ_OBJ_OBJ;
3372 for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) 3366 p->data[0].object = a;
3373 switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) 3367 p->data[1].object = b;
3374 { 3368 p->data[2].object = c;
3375 case SAVE_POINTER: 3369 p->data[3].object = d;
3376 p->data[i].pointer = va_arg (ap, void *); 3370 return val;
3377 break; 3371}
3378
3379 case SAVE_FUNCPOINTER:
3380 p->data[i].funcpointer = va_arg (ap, voidfuncptr);
3381 break;
3382 3372
3383 case SAVE_INTEGER: 3373#if defined HAVE_NS || defined HAVE_NTGUI
3384 p->data[i].integer = va_arg (ap, ptrdiff_t); 3374Lisp_Object
3385 break; 3375make_save_ptr (void *a)
3376{
3377 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3378 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3379 p->save_type = SAVE_POINTER;
3380 p->data[0].pointer = a;
3381 return val;
3382}
3383#endif
3386 3384
3387 case SAVE_OBJECT: 3385Lisp_Object
3388 p->data[i].object = va_arg (ap, Lisp_Object); 3386make_save_ptr_int (void *a, ptrdiff_t b)
3389 break; 3387{
3388 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3389 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3390 p->save_type = SAVE_TYPE_PTR_INT;
3391 p->data[0].pointer = a;
3392 p->data[1].integer = b;
3393 return val;
3394}
3390 3395
3391 default: 3396#if defined HAVE_MENUS && ! (defined USE_X_TOOLKIT || defined USE_GTK)
3392 emacs_abort (); 3397Lisp_Object
3393 } 3398make_save_ptr_ptr (void *a, void *b)
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_PTR_PTR;
3403 p->data[0].pointer = a;
3404 p->data[1].pointer = b;
3405 return val;
3406}
3407#endif
3394 3408
3395 va_end (ap); 3409Lisp_Object
3410make_save_funcptr_ptr_obj (void (*a) (void), void *b, Lisp_Object c)
3411{
3412 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3413 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3414 p->save_type = SAVE_TYPE_FUNCPTR_PTR_OBJ;
3415 p->data[0].funcpointer = a;
3416 p->data[1].pointer = b;
3417 p->data[2].object = c;
3396 return val; 3418 return val;
3397} 3419}
3398 3420
3399/* The most common task it to save just one C pointer. */ 3421/* Return a Lisp_Save_Value object that represents an array A
3422 of N Lisp objects. */
3400 3423
3401Lisp_Object 3424Lisp_Object
3402make_save_pointer (void *pointer) 3425make_save_memory (Lisp_Object *a, ptrdiff_t n)
3403{ 3426{
3404 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3427 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3405 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3428 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3406 p->save_type = SAVE_POINTER; 3429 p->save_type = SAVE_TYPE_MEMORY;
3407 p->data[0].pointer = pointer; 3430 p->data[0].pointer = a;
3431 p->data[1].integer = n;
3408 return val; 3432 return val;
3409} 3433}
3410 3434
3411/* Free a Lisp_Save_Value object. Do not use this function 3435/* Free a Lisp_Save_Value object. Do not use this function
3412 if SAVE contains pointer other than returned by xmalloc. */ 3436 if SAVE contains pointer other than returned by xmalloc. */
3413 3437
3414static void 3438void
3415free_save_value (Lisp_Object save) 3439free_save_value (Lisp_Object save)
3416{ 3440{
3417 xfree (XSAVE_POINTER (save, 0)); 3441 xfree (XSAVE_POINTER (save, 0));
@@ -4750,7 +4774,7 @@ valid_pointer_p (void *p)
4750 Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may 4774 Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may
4751 not validate p in that case. */ 4775 not validate p in that case. */
4752 4776
4753 if (pipe2 (fd, O_CLOEXEC) == 0) 4777 if (emacs_pipe (fd) == 0)
4754 { 4778 {
4755 bool valid = emacs_write (fd[1], (char *) p, 16) == 16; 4779 bool valid = emacs_write (fd[1], (char *) p, 16) == 16;
4756 emacs_close (fd[1]); 4780 emacs_close (fd[1]);
@@ -5134,9 +5158,9 @@ Does not copy symbols. Copies strings without text properties. */)
5134void 5158void
5135staticpro (Lisp_Object *varaddress) 5159staticpro (Lisp_Object *varaddress)
5136{ 5160{
5137 staticvec[staticidx++] = varaddress;
5138 if (staticidx >= NSTATICS) 5161 if (staticidx >= NSTATICS)
5139 fatal ("NSTATICS too small; try increasing and recompiling Emacs."); 5162 fatal ("NSTATICS too small; try increasing and recompiling Emacs.");
5163 staticvec[staticidx++] = varaddress;
5140} 5164}
5141 5165
5142 5166
@@ -5236,7 +5260,7 @@ See Info node `(elisp)Garbage Collection'. */)
5236 5260
5237 /* Save what's currently displayed in the echo area. */ 5261 /* Save what's currently displayed in the echo area. */
5238 message_p = push_message (); 5262 message_p = push_message ();
5239 record_unwind_protect (pop_message_unwind, Qnil); 5263 record_unwind_protect_void (pop_message_unwind);
5240 5264
5241 /* Save a copy of the contents of the stack, for debugging. */ 5265 /* Save a copy of the contents of the stack, for debugging. */
5242#if MAX_SAVE_STACK > 0 5266#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 19e3982a8a4..3ca1bd98b29 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -611,7 +611,7 @@ even if it is dead. The return value is never nil. */)
611 611
612 /* Put this in the alist of all live buffers. */ 612 /* Put this in the alist of all live buffers. */
613 XSETBUFFER (buffer, b); 613 XSETBUFFER (buffer, b);
614 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil)); 614 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
615 /* And run buffer-list-update-hook. */ 615 /* And run buffer-list-update-hook. */
616 if (!NILP (Vrun_hooks)) 616 if (!NILP (Vrun_hooks))
617 call1 (Vrun_hooks, Qbuffer_list_update_hook); 617 call1 (Vrun_hooks, Qbuffer_list_update_hook);
@@ -822,7 +822,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
822 822
823 /* Put this in the alist of all live buffers. */ 823 /* Put this in the alist of all live buffers. */
824 XSETBUFFER (buf, b); 824 XSETBUFFER (buf, b);
825 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); 825 Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buf)));
826 826
827 bset_mark (b, Fmake_marker ()); 827 bset_mark (b, Fmake_marker ());
828 828
@@ -2207,14 +2207,19 @@ ends when the current command terminates. Use `switch-to-buffer' or
2207 return buffer; 2207 return buffer;
2208} 2208}
2209 2209
2210void
2211restore_buffer (Lisp_Object buffer_or_name)
2212{
2213 Fset_buffer (buffer_or_name);
2214}
2215
2210/* Set the current buffer to BUFFER provided if it is alive. */ 2216/* Set the current buffer to BUFFER provided if it is alive. */
2211 2217
2212Lisp_Object 2218void
2213set_buffer_if_live (Lisp_Object buffer) 2219set_buffer_if_live (Lisp_Object buffer)
2214{ 2220{
2215 if (BUFFER_LIVE_P (XBUFFER (buffer))) 2221 if (BUFFER_LIVE_P (XBUFFER (buffer)))
2216 set_buffer_internal (XBUFFER (buffer)); 2222 set_buffer_internal (XBUFFER (buffer));
2217 return Qnil;
2218} 2223}
2219 2224
2220DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only, 2225DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
diff --git a/src/buffer.h b/src/buffer.h
index 2b0b49dddad..6c0058ee8f3 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1069,6 +1069,8 @@ extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object);
1069extern void record_buffer (Lisp_Object); 1069extern void record_buffer (Lisp_Object);
1070extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t); 1070extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
1071extern void mmap_set_vars (bool); 1071extern void mmap_set_vars (bool);
1072extern void restore_buffer (Lisp_Object);
1073extern void set_buffer_if_live (Lisp_Object);
1072 1074
1073/* Set the current buffer to B. 1075/* Set the current buffer to B.
1074 1076
diff --git a/src/bytecode.c b/src/bytecode.c
index f186f7d1bc3..1be3e5c6188 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -569,9 +569,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
569 if (nargs < mandatory) 569 if (nargs < mandatory)
570 /* Too few arguments. */ 570 /* Too few arguments. */
571 Fsignal (Qwrong_number_of_arguments, 571 Fsignal (Qwrong_number_of_arguments,
572 Fcons (Fcons (make_number (mandatory), 572 list2 (Fcons (make_number (mandatory),
573 rest ? Qand_rest : make_number (nonrest)), 573 rest ? Qand_rest : make_number (nonrest)),
574 Fcons (make_number (nargs), Qnil))); 574 make_number (nargs)));
575 else 575 else
576 { 576 {
577 for (; i < nonrest; i++) 577 for (; i < nonrest; i++)
@@ -590,9 +590,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
590 else 590 else
591 /* Too many arguments. */ 591 /* Too many arguments. */
592 Fsignal (Qwrong_number_of_arguments, 592 Fsignal (Qwrong_number_of_arguments,
593 Fcons (Fcons (make_number (mandatory), 593 list2 (Fcons (make_number (mandatory), make_number (nonrest)),
594 make_number (nonrest)), 594 make_number (nargs)));
595 Fcons (make_number (nargs), Qnil)));
596 } 595 }
597 else if (! NILP (args_template)) 596 else if (! NILP (args_template))
598 /* We should push some arguments on the stack. */ 597 /* We should push some arguments on the stack. */
@@ -1061,8 +1060,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1061 1060
1062 CASE (Bsave_window_excursion): /* Obsolete since 24.1. */ 1061 CASE (Bsave_window_excursion): /* Obsolete since 24.1. */
1063 { 1062 {
1064 register ptrdiff_t count1 = SPECPDL_INDEX (); 1063 ptrdiff_t count1 = SPECPDL_INDEX ();
1065 record_unwind_protect (Fset_window_configuration, 1064 record_unwind_protect (restore_window_configuration,
1066 Fcurrent_window_configuration (Qnil)); 1065 Fcurrent_window_configuration (Qnil));
1067 BEFORE_POTENTIAL_GC (); 1066 BEFORE_POTENTIAL_GC ();
1068 TOP = Fprogn (TOP); 1067 TOP = Fprogn (TOP);
@@ -1087,7 +1086,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1087 } 1086 }
1088 1087
1089 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */ 1088 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
1090 record_unwind_protect (Fprogn, POP); 1089 record_unwind_protect (unwind_body, POP);
1091 NEXT; 1090 NEXT;
1092 1091
1093 CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */ 1092 CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */
@@ -1169,14 +1168,14 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1169 } 1168 }
1170 1169
1171 CASE (Blist1): 1170 CASE (Blist1):
1172 TOP = Fcons (TOP, Qnil); 1171 TOP = list1 (TOP);
1173 NEXT; 1172 NEXT;
1174 1173
1175 CASE (Blist2): 1174 CASE (Blist2):
1176 { 1175 {
1177 Lisp_Object v1; 1176 Lisp_Object v1;
1178 v1 = POP; 1177 v1 = POP;
1179 TOP = Fcons (TOP, Fcons (v1, Qnil)); 1178 TOP = list2 (TOP, v1);
1180 NEXT; 1179 NEXT;
1181 } 1180 }
1182 1181
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 30f9dc58d46..91f29bd589b 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
969Insert output in BUFFER before point; t means current buffer; nil for
970 BUFFER means discard it; 0 means discard and don't wait; and `(:file
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 961
982If BUFFER is 0, `call-process-region' returns immediately with value nil. 962static Lisp_Object
983Otherwise it waits for PROGRAM to terminate 963create_temp_file (ptrdiff_t nargs, Lisp_Object *args)
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}
@@ -1185,9 +1196,11 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1185#ifdef WINDOWSNT 1196#ifdef WINDOWSNT
1186 int cpid; 1197 int cpid;
1187 HANDLE handles[3]; 1198 HANDLE handles[3];
1188#endif /* WINDOWSNT */ 1199#else
1200 int exec_errno;
1189 1201
1190 pid_t pid = getpid (); 1202 pid_t pid = getpid ();
1203#endif /* WINDOWSNT */
1191 1204
1192 /* Note that use of alloca is always safe here. It's obvious for systems 1205 /* Note that use of alloca is always safe here. It's obvious for systems
1193 that do not have true vfork or that have true (stack) alloca. 1206 that do not have true vfork or that have true (stack) alloca.
@@ -1346,32 +1359,27 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1346 } 1359 }
1347 1360
1348#ifndef MSDOS 1361#ifndef MSDOS
1349 emacs_close (0); 1362 /* Redirect file descriptors and clear the close-on-exec flag on the
1350 emacs_close (1); 1363 redirected ones. IN, OUT, and ERR are close-on-exec so they
1351 emacs_close (2); 1364 need not be closed explicitly. */
1352
1353 /* Redirect file descriptors and clear FD_CLOEXEC on the redirected ones. */
1354 dup2 (in, 0); 1365 dup2 (in, 0);
1355 dup2 (out, 1); 1366 dup2 (out, 1);
1356 dup2 (err, 2); 1367 dup2 (err, 2);
1357 1368
1358 emacs_close (in);
1359 if (out != in)
1360 emacs_close (out);
1361 if (err != in && err != out)
1362 emacs_close (err);
1363
1364 setpgid (0, 0); 1369 setpgid (0, 0);
1365 tcsetpgrp (0, pid); 1370 tcsetpgrp (0, pid);
1366 1371
1367 execve (new_argv[0], new_argv, env); 1372 execve (new_argv[0], new_argv, env);
1373 exec_errno = errno;
1368 1374
1369 /* Don't output the program name here, as it can be arbitrarily long, 1375 /* Avoid deadlock if the child's perror writes to a full pipe; the
1370 and a long write from a vforked child to its parent can cause a 1376 pipe's reader is the parent, but with vfork the parent can't
1371 deadlock. */ 1377 run until the child exits. Truncate the diagnostic instead. */
1372 emacs_perror ("child process"); 1378 fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK);
1373 1379
1374 _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); 1380 errno = exec_errno;
1381 emacs_perror (new_argv[0]);
1382 _exit (exec_errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1375 1383
1376#else /* MSDOS */ 1384#else /* MSDOS */
1377 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); 1385 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
@@ -1386,7 +1394,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1386 1394
1387#ifndef WINDOWSNT 1395#ifndef WINDOWSNT
1388/* Move the file descriptor FD so that its number is not less than MINFD. 1396/* Move the file descriptor FD so that its number is not less than MINFD.
1389 If the file descriptor is moved at all, the original is freed. */ 1397 If the file descriptor is moved at all, the original is closed on MSDOS,
1398 but not elsewhere as the caller will close it anyway. */
1390static int 1399static int
1391relocate_fd (int fd, int minfd) 1400relocate_fd (int fd, int minfd)
1392{ 1401{
@@ -1400,7 +1409,9 @@ relocate_fd (int fd, int minfd)
1400 emacs_perror ("while setting up child"); 1409 emacs_perror ("while setting up child");
1401 _exit (EXIT_CANCELED); 1410 _exit (EXIT_CANCELED);
1402 } 1411 }
1412#ifdef MSDOS
1403 emacs_close (fd); 1413 emacs_close (fd);
1414#endif
1404 return new; 1415 return new;
1405 } 1416 }
1406} 1417}
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 1ab59294b98..0cdd8f9cd9e 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -493,6 +493,8 @@ enum iso_code_class_type
493 493
494#define CODING_ISO_FLAG_USE_OLDJIS 0x10000 494#define CODING_ISO_FLAG_USE_OLDJIS 0x10000
495 495
496#define CODING_ISO_FLAG_LEVEL_4 0x20000
497
496#define CODING_ISO_FLAG_FULL_SUPPORT 0x100000 498#define CODING_ISO_FLAG_FULL_SUPPORT 0x100000
497 499
498/* A character to be produced on output if encoding of the original 500/* A character to be produced on output if encoding of the original
@@ -1363,6 +1365,45 @@ decode_coding_utf_8 (struct coding_system *coding)
1363 break; 1365 break;
1364 } 1366 }
1365 1367
1368 /* In the simple case, rapidly handle ordinary characters */
1369 if (multibytep && ! eol_dos
1370 && charbuf < charbuf_end - 6 && src < src_end - 6)
1371 {
1372 while (charbuf < charbuf_end - 6 && src < src_end - 6)
1373 {
1374 c1 = *src;
1375 if (c1 & 0x80)
1376 break;
1377 src++;
1378 consumed_chars++;
1379 *charbuf++ = c1;
1380
1381 c1 = *src;
1382 if (c1 & 0x80)
1383 break;
1384 src++;
1385 consumed_chars++;
1386 *charbuf++ = c1;
1387
1388 c1 = *src;
1389 if (c1 & 0x80)
1390 break;
1391 src++;
1392 consumed_chars++;
1393 *charbuf++ = c1;
1394
1395 c1 = *src;
1396 if (c1 & 0x80)
1397 break;
1398 src++;
1399 consumed_chars++;
1400 *charbuf++ = c1;
1401 }
1402 /* If we handled at least one character, restart the main loop. */
1403 if (src != src_base)
1404 continue;
1405 }
1406
1366 if (byte_after_cr >= 0) 1407 if (byte_after_cr >= 0)
1367 c1 = byte_after_cr, byte_after_cr = -1; 1408 c1 = byte_after_cr, byte_after_cr = -1;
1368 else 1409 else
@@ -3733,7 +3774,10 @@ decode_coding_iso_2022 (struct coding_system *coding)
3733 else 3774 else
3734 charset = CHARSET_FROM_ID (charset_id_2); 3775 charset = CHARSET_FROM_ID (charset_id_2);
3735 ONE_MORE_BYTE (c1); 3776 ONE_MORE_BYTE (c1);
3736 if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) 3777 if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)
3778 || (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)
3779 && ((CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LEVEL_4)
3780 ? c1 >= 0x80 : c1 < 0x80)))
3737 goto invalid_code; 3781 goto invalid_code;
3738 break; 3782 break;
3739 3783
@@ -3747,7 +3791,10 @@ decode_coding_iso_2022 (struct coding_system *coding)
3747 else 3791 else
3748 charset = CHARSET_FROM_ID (charset_id_3); 3792 charset = CHARSET_FROM_ID (charset_id_3);
3749 ONE_MORE_BYTE (c1); 3793 ONE_MORE_BYTE (c1);
3750 if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)) 3794 if (c1 < 0x20 || (c1 >= 0x80 && c1 < 0xA0)
3795 || (! (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_SEVEN_BITS)
3796 && ((CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_LEVEL_4)
3797 ? c1 >= 0x80 : c1 < 0x80)))
3751 goto invalid_code; 3798 goto invalid_code;
3752 break; 3799 break;
3753 3800
@@ -6864,11 +6911,9 @@ get_translation_table (Lisp_Object attrs, bool encodep, int *max_lookup)
6864 if (CHAR_TABLE_P (standard)) 6911 if (CHAR_TABLE_P (standard))
6865 { 6912 {
6866 if (CONSP (translation_table)) 6913 if (CONSP (translation_table))
6867 translation_table = nconc2 (translation_table, 6914 translation_table = nconc2 (translation_table, list1 (standard));
6868 Fcons (standard, Qnil));
6869 else 6915 else
6870 translation_table = Fcons (translation_table, 6916 translation_table = list2 (translation_table, standard);
6871 Fcons (standard, Qnil));
6872 } 6917 }
6873 } 6918 }
6874 6919
@@ -7793,7 +7838,7 @@ make_conversion_work_buffer (bool multibyte)
7793} 7838}
7794 7839
7795 7840
7796static Lisp_Object 7841static void
7797code_conversion_restore (Lisp_Object arg) 7842code_conversion_restore (Lisp_Object arg)
7798{ 7843{
7799 Lisp_Object current, workbuf; 7844 Lisp_Object current, workbuf;
@@ -7811,7 +7856,6 @@ code_conversion_restore (Lisp_Object arg)
7811 } 7856 }
7812 set_buffer_internal (XBUFFER (current)); 7857 set_buffer_internal (XBUFFER (current));
7813 UNGCPRO; 7858 UNGCPRO;
7814 return Qnil;
7815} 7859}
7816 7860
7817Lisp_Object 7861Lisp_Object
@@ -8667,20 +8711,20 @@ detect_coding_system (const unsigned char *src,
8667 { 8711 {
8668 detect_info.found = CATEGORY_MASK_RAW_TEXT; 8712 detect_info.found = CATEGORY_MASK_RAW_TEXT;
8669 id = CODING_SYSTEM_ID (Qno_conversion); 8713 id = CODING_SYSTEM_ID (Qno_conversion);
8670 val = Fcons (make_number (id), Qnil); 8714 val = list1 (make_number (id));
8671 } 8715 }
8672 else if (! detect_info.rejected && ! detect_info.found) 8716 else if (! detect_info.rejected && ! detect_info.found)
8673 { 8717 {
8674 detect_info.found = CATEGORY_MASK_ANY; 8718 detect_info.found = CATEGORY_MASK_ANY;
8675 id = coding_categories[coding_category_undecided].id; 8719 id = coding_categories[coding_category_undecided].id;
8676 val = Fcons (make_number (id), Qnil); 8720 val = list1 (make_number (id));
8677 } 8721 }
8678 else if (highest) 8722 else if (highest)
8679 { 8723 {
8680 if (detect_info.found) 8724 if (detect_info.found)
8681 { 8725 {
8682 detect_info.found = 1 << category; 8726 detect_info.found = 1 << category;
8683 val = Fcons (make_number (this->id), Qnil); 8727 val = list1 (make_number (this->id));
8684 } 8728 }
8685 else 8729 else
8686 for (i = 0; i < coding_category_raw_text; i++) 8730 for (i = 0; i < coding_category_raw_text; i++)
@@ -8688,7 +8732,7 @@ detect_coding_system (const unsigned char *src,
8688 { 8732 {
8689 detect_info.found = 1 << coding_priorities[i]; 8733 detect_info.found = 1 << coding_priorities[i];
8690 id = coding_categories[coding_priorities[i]].id; 8734 id = coding_categories[coding_priorities[i]].id;
8691 val = Fcons (make_number (id), Qnil); 8735 val = list1 (make_number (id));
8692 break; 8736 break;
8693 } 8737 }
8694 } 8738 }
@@ -8705,7 +8749,7 @@ detect_coding_system (const unsigned char *src,
8705 found |= 1 << category; 8749 found |= 1 << category;
8706 id = coding_categories[category].id; 8750 id = coding_categories[category].id;
8707 if (id >= 0) 8751 if (id >= 0)
8708 val = Fcons (make_number (id), val); 8752 val = list1 (make_number (id));
8709 } 8753 }
8710 } 8754 }
8711 for (i = coding_category_raw_text - 1; i >= 0; i--) 8755 for (i = coding_category_raw_text - 1; i >= 0; i--)
@@ -8730,7 +8774,7 @@ detect_coding_system (const unsigned char *src,
8730 this = coding_categories + coding_category_utf_8_sig; 8774 this = coding_categories + coding_category_utf_8_sig;
8731 else 8775 else
8732 this = coding_categories + coding_category_utf_8_nosig; 8776 this = coding_categories + coding_category_utf_8_nosig;
8733 val = Fcons (make_number (this->id), Qnil); 8777 val = list1 (make_number (this->id));
8734 } 8778 }
8735 } 8779 }
8736 else if (base_category == coding_category_utf_16_auto) 8780 else if (base_category == coding_category_utf_16_auto)
@@ -8747,13 +8791,13 @@ detect_coding_system (const unsigned char *src,
8747 this = coding_categories + coding_category_utf_16_be_nosig; 8791 this = coding_categories + coding_category_utf_16_be_nosig;
8748 else 8792 else
8749 this = coding_categories + coding_category_utf_16_le_nosig; 8793 this = coding_categories + coding_category_utf_16_le_nosig;
8750 val = Fcons (make_number (this->id), Qnil); 8794 val = list1 (make_number (this->id));
8751 } 8795 }
8752 } 8796 }
8753 else 8797 else
8754 { 8798 {
8755 detect_info.found = 1 << XINT (CODING_ATTR_CATEGORY (attrs)); 8799 detect_info.found = 1 << XINT (CODING_ATTR_CATEGORY (attrs));
8756 val = Fcons (make_number (coding.id), Qnil); 8800 val = list1 (make_number (coding.id));
8757 } 8801 }
8758 8802
8759 /* Then, detect eol-format if necessary. */ 8803 /* Then, detect eol-format if necessary. */
@@ -9224,7 +9268,7 @@ is nil. */)
9224 attrs = AREF (CODING_SYSTEM_SPEC (elt), 0); 9268 attrs = AREF (CODING_SYSTEM_SPEC (elt), 0);
9225 ASET (attrs, coding_attr_trans_tbl, 9269 ASET (attrs, coding_attr_trans_tbl,
9226 get_translation_table (attrs, 1, NULL)); 9270 get_translation_table (attrs, 1, NULL));
9227 list = Fcons (Fcons (elt, Fcons (attrs, Qnil)), list); 9271 list = Fcons (list2 (elt, attrs), list);
9228 } 9272 }
9229 9273
9230 if (STRINGP (start)) 9274 if (STRINGP (start))
@@ -9635,7 +9679,7 @@ DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_intern
9635 tset_charset_list 9679 tset_charset_list
9636 (term, (terminal_coding->common_flags & CODING_REQUIRE_ENCODING_MASK 9680 (term, (terminal_coding->common_flags & CODING_REQUIRE_ENCODING_MASK
9637 ? coding_charset_list (terminal_coding) 9681 ? coding_charset_list (terminal_coding)
9638 : Fcons (make_number (charset_ascii), Qnil))); 9682 : list1 (make_number (charset_ascii))));
9639 return Qnil; 9683 return Qnil;
9640} 9684}
9641 9685
@@ -10080,9 +10124,9 @@ usage: (define-coding-system-internal ...) */)
10080 { 10124 {
10081 dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp))); 10125 dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp)));
10082 if (dim < dim2) 10126 if (dim < dim2)
10083 tmp = Fcons (XCAR (tail), Fcons (tmp, Qnil)); 10127 tmp = list2 (XCAR (tail), tmp);
10084 else 10128 else
10085 tmp = Fcons (tmp, Fcons (XCAR (tail), Qnil)); 10129 tmp = list2 (tmp, XCAR (tail));
10086 } 10130 }
10087 else 10131 else
10088 { 10132 {
@@ -10093,7 +10137,7 @@ usage: (define-coding-system-internal ...) */)
10093 break; 10137 break;
10094 } 10138 }
10095 if (NILP (tmp2)) 10139 if (NILP (tmp2))
10096 tmp = nconc2 (tmp, Fcons (XCAR (tail), Qnil)); 10140 tmp = nconc2 (tmp, list1 (XCAR (tail)));
10097 else 10141 else
10098 { 10142 {
10099 XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2))); 10143 XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2)));
@@ -10411,7 +10455,7 @@ usage: (define-coding-system-internal ...) */)
10411 && ! EQ (eol_type, Qmac)) 10455 && ! EQ (eol_type, Qmac))
10412 error ("Invalid eol-type"); 10456 error ("Invalid eol-type");
10413 10457
10414 aliases = Fcons (name, Qnil); 10458 aliases = list1 (name);
10415 10459
10416 if (NILP (eol_type)) 10460 if (NILP (eol_type))
10417 { 10461 {
@@ -10421,7 +10465,7 @@ usage: (define-coding-system-internal ...) */)
10421 Lisp_Object this_spec, this_name, this_aliases, this_eol_type; 10465 Lisp_Object this_spec, this_name, this_aliases, this_eol_type;
10422 10466
10423 this_name = AREF (eol_type, i); 10467 this_name = AREF (eol_type, i);
10424 this_aliases = Fcons (this_name, Qnil); 10468 this_aliases = list1 (this_name);
10425 this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac); 10469 this_eol_type = (i == 0 ? Qunix : i == 1 ? Qdos : Qmac);
10426 this_spec = make_uninit_vector (3); 10470 this_spec = make_uninit_vector (3);
10427 ASET (this_spec, 0, attrs); 10471 ASET (this_spec, 0, attrs);
@@ -10536,7 +10580,7 @@ DEFUN ("define-coding-system-alias", Fdefine_coding_system_alias,
10536 list. */ 10580 list. */
10537 while (!NILP (XCDR (aliases))) 10581 while (!NILP (XCDR (aliases)))
10538 aliases = XCDR (aliases); 10582 aliases = XCDR (aliases);
10539 XSETCDR (aliases, Fcons (alias, Qnil)); 10583 XSETCDR (aliases, list1 (alias));
10540 10584
10541 eol_type = AREF (spec, 2); 10585 eol_type = AREF (spec, 2);
10542 if (VECTORP (eol_type)) 10586 if (VECTORP (eol_type))
@@ -11218,6 +11262,8 @@ character.");
11218 plist[13] = build_pure_c_string ("No conversion on encoding, automatic conversion on decoding."); 11262 plist[13] = build_pure_c_string ("No conversion on encoding, automatic conversion on decoding.");
11219 plist[15] = args[coding_arg_eol_type] = Qnil; 11263 plist[15] = args[coding_arg_eol_type] = Qnil;
11220 args[coding_arg_plist] = Flist (16, plist); 11264 args[coding_arg_plist] = Flist (16, plist);
11265 args[coding_arg_undecided_inhibit_null_byte_detection] = make_number (0);
11266 args[coding_arg_undecided_inhibit_iso_escape_detection] = make_number (0);
11221 Fdefine_coding_system_internal (coding_arg_undecided_max, args); 11267 Fdefine_coding_system_internal (coding_arg_undecided_max, args);
11222 } 11268 }
11223 11269
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/data.c b/src/data.c
index ea72a3fc181..25a9e698481 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1515,24 +1515,19 @@ of previous VARs.
1515usage: (setq-default [VAR VALUE]...) */) 1515usage: (setq-default [VAR VALUE]...) */)
1516 (Lisp_Object args) 1516 (Lisp_Object args)
1517{ 1517{
1518 register Lisp_Object args_left; 1518 Lisp_Object args_left, symbol, val;
1519 register Lisp_Object val, symbol;
1520 struct gcpro gcpro1; 1519 struct gcpro gcpro1;
1521 1520
1522 if (NILP (args)) 1521 args_left = val = args;
1523 return Qnil;
1524
1525 args_left = args;
1526 GCPRO1 (args); 1522 GCPRO1 (args);
1527 1523
1528 do 1524 while (CONSP (args_left))
1529 { 1525 {
1530 val = eval_sub (Fcar (Fcdr (args_left))); 1526 val = eval_sub (Fcar (XCDR (args_left)));
1531 symbol = XCAR (args_left); 1527 symbol = XCAR (args_left);
1532 Fset_default (symbol, val); 1528 Fset_default (symbol, val);
1533 args_left = Fcdr (XCDR (args_left)); 1529 args_left = Fcdr (XCDR (args_left));
1534 } 1530 }
1535 while (!NILP (args_left));
1536 1531
1537 UNGCPRO; 1532 UNGCPRO;
1538 return val; 1533 return val;
diff --git a/src/deps.mk b/src/deps.mk
index 83444474c59..39666dca515 100644
--- a/src/deps.mk
+++ b/src/deps.mk
@@ -190,7 +190,7 @@ sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \
190 frame.h atimer.h window.h msdos.h dosfns.h keyboard.h cm.h lisp.h \ 190 frame.h atimer.h window.h msdos.h dosfns.h keyboard.h cm.h lisp.h \
191 globals.h $(config_h) composite.h sysselect.h gnutls.h \ 191 globals.h $(config_h) composite.h sysselect.h gnutls.h \
192 ../lib/allocator.h ../lib/careadlinkat.h \ 192 ../lib/allocator.h ../lib/careadlinkat.h \
193 ../lib/unistd.h ../lib/ignore-value.h 193 ../lib/unistd.h
194term.o: term.c termchar.h termhooks.h termopts.h lisp.h globals.h $(config_h) \ 194term.o: term.c termchar.h termhooks.h termopts.h lisp.h globals.h $(config_h) \
195 cm.h frame.h disptab.h keyboard.h character.h charset.h coding.h ccl.h \ 195 cm.h frame.h disptab.h keyboard.h character.h charset.h coding.h ccl.h \
196 xterm.h msdos.h window.h keymap.h blockinput.h atimer.h systime.h \ 196 xterm.h msdos.h window.h keymap.h blockinput.h atimer.h systime.h \
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 1eb097f05ab..522a0e6a30d 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5619,7 +5619,7 @@ FILE = nil means just close any termscript file currently open. */)
5619 file = Fexpand_file_name (file, Qnil); 5619 file = Fexpand_file_name (file, Qnil);
5620 tty->termscript = emacs_fopen (SSDATA (file), "w"); 5620 tty->termscript = emacs_fopen (SSDATA (file), "w");
5621 if (tty->termscript == 0) 5621 if (tty->termscript == 0)
5622 report_file_error ("Opening termscript", Fcons (file, Qnil)); 5622 report_file_error ("Opening termscript", file);
5623 } 5623 }
5624 return Qnil; 5624 return Qnil;
5625} 5625}
@@ -5699,7 +5699,7 @@ bitch_at_user (void)
5699 { 5699 {
5700 const char *msg 5700 const char *msg
5701 = "Keyboard macro terminated by a command ringing the bell"; 5701 = "Keyboard macro terminated by a command ringing the bell";
5702 Fsignal (Quser_error, Fcons (build_string (msg), Qnil)); 5702 Fsignal (Quser_error, list1 (build_string (msg)));
5703 } 5703 }
5704 else 5704 else
5705 ring_bell (XFRAME (selected_frame)); 5705 ring_bell (XFRAME (selected_frame));
@@ -6041,7 +6041,7 @@ init_display (void)
6041#ifdef HAVE_X11 6041#ifdef HAVE_X11
6042 Vwindow_system_version = make_number (11); 6042 Vwindow_system_version = make_number (11);
6043#endif 6043#endif
6044#ifdef GNU_LINUX 6044#ifdef USE_NCURSES
6045 /* In some versions of ncurses, 6045 /* In some versions of ncurses,
6046 tputs crashes if we have not called tgetent. 6046 tputs crashes if we have not called tgetent.
6047 So call tgetent. */ 6047 So call tgetent. */
@@ -6127,15 +6127,14 @@ init_display (void)
6127 6127
6128 /* Update frame parameters to reflect the new type. */ 6128 /* Update frame parameters to reflect the new type. */
6129 Fmodify_frame_parameters 6129 Fmodify_frame_parameters
6130 (selected_frame, Fcons (Fcons (Qtty_type, 6130 (selected_frame, list1 (Fcons (Qtty_type,
6131 Ftty_type (selected_frame)), Qnil)); 6131 Ftty_type (selected_frame))));
6132 if (t->display_info.tty->name) 6132 if (t->display_info.tty->name)
6133 Fmodify_frame_parameters (selected_frame, 6133 Fmodify_frame_parameters
6134 Fcons (Fcons (Qtty, build_string (t->display_info.tty->name)), 6134 (selected_frame,
6135 Qnil)); 6135 list1 (Fcons (Qtty, build_string (t->display_info.tty->name))));
6136 else 6136 else
6137 Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil), 6137 Fmodify_frame_parameters (selected_frame, list1 (Fcons (Qtty, Qnil)));
6138 Qnil));
6139 } 6138 }
6140 6139
6141 { 6140 {
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 274321482e1..6d406407a9d 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -974,7 +974,7 @@ main (int argc, char **argv)
974 use a pipe for synchronization. The parent waits for the child 974 use a pipe for synchronization. The parent waits for the child
975 to close its end of the pipe (using `daemon-initialized') 975 to close its end of the pipe (using `daemon-initialized')
976 before exiting. */ 976 before exiting. */
977 if (pipe2 (daemon_pipe, O_CLOEXEC) != 0) 977 if (emacs_pipe (daemon_pipe) != 0)
978 { 978 {
979 fprintf (stderr, "Cannot pipe!\n"); 979 fprintf (stderr, "Cannot pipe!\n");
980 exit (1); 980 exit (1);
@@ -1494,12 +1494,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1494 char *file; 1494 char *file;
1495 /* Handle -l loadup, args passed by Makefile. */ 1495 /* Handle -l loadup, args passed by Makefile. */
1496 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args)) 1496 if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
1497 Vtop_level = Fcons (intern_c_string ("load"), 1497 Vtop_level = list2 (intern_c_string ("load"), build_string (file));
1498 Fcons (build_string (file), Qnil));
1499 /* Unless next switch is -nl, load "loadup.el" first thing. */ 1498 /* Unless next switch is -nl, load "loadup.el" first thing. */
1500 if (! no_loadup) 1499 if (! no_loadup)
1501 Vtop_level = Fcons (intern_c_string ("load"), 1500 Vtop_level = list2 (intern_c_string ("load"),
1502 Fcons (build_string ("loadup.el"), Qnil)); 1501 build_string ("loadup.el"));
1503 } 1502 }
1504 1503
1505 if (initialized) 1504 if (initialized)
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 970683da9c4..8b19d89f3a0 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -28,7 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include "xterm.h" 28#include "xterm.h"
29 29
30/* Silence a bogus diagnostic; see GNOME bug 683906. */ 30/* Silence a bogus diagnostic; see GNOME bug 683906. */
31#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 31#if 4 < __GNUC__ + (7 <= __GNUC_MINOR__)
32# pragma GCC diagnostic push 32# pragma GCC diagnostic push
33# pragma GCC diagnostic ignored "-Wunused-local-typedefs" 33# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
34#endif 34#endif
diff --git a/src/eval.c b/src/eval.c
index 97e812dd890..e93c3473ae8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -138,6 +138,13 @@ specpdl_old_value (union specbinding *pdl)
138 return pdl->let.old_value; 138 return pdl->let.old_value;
139} 139}
140 140
141static void
142set_specpdl_old_value (union specbinding *pdl, Lisp_Object val)
143{
144 eassert (pdl->kind >= SPECPDL_LET);
145 pdl->let.old_value = val;
146}
147
141static Lisp_Object 148static Lisp_Object
142specpdl_where (union specbinding *pdl) 149specpdl_where (union specbinding *pdl)
143{ 150{
@@ -159,13 +166,6 @@ specpdl_arg (union specbinding *pdl)
159 return pdl->unwind.arg; 166 return pdl->unwind.arg;
160} 167}
161 168
162static specbinding_func
163specpdl_func (union specbinding *pdl)
164{
165 eassert (pdl->kind == SPECPDL_UNWIND);
166 return pdl->unwind.func;
167}
168
169Lisp_Object 169Lisp_Object
170backtrace_function (union specbinding *pdl) 170backtrace_function (union specbinding *pdl)
171{ 171{
@@ -287,12 +287,11 @@ mark_catchlist (struct catchtag *catch)
287 287
288/* Unwind-protect function used by call_debugger. */ 288/* Unwind-protect function used by call_debugger. */
289 289
290static Lisp_Object 290static void
291restore_stack_limits (Lisp_Object data) 291restore_stack_limits (Lisp_Object data)
292{ 292{
293 max_specpdl_size = XINT (XCAR (data)); 293 max_specpdl_size = XINT (XCAR (data));
294 max_lisp_eval_depth = XINT (XCDR (data)); 294 max_lisp_eval_depth = XINT (XCDR (data));
295 return Qnil;
296} 295}
297 296
298/* Call the Lisp debugger, giving it argument ARG. */ 297/* Call the Lisp debugger, giving it argument ARG. */
@@ -358,7 +357,7 @@ do_debug_on_call (Lisp_Object code)
358{ 357{
359 debug_on_next_call = 0; 358 debug_on_next_call = 0;
360 set_backtrace_debug_on_exit (specpdl_ptr - 1, true); 359 set_backtrace_debug_on_exit (specpdl_ptr - 1, true);
361 call_debugger (Fcons (code, Qnil)); 360 call_debugger (list1 (code));
362} 361}
363 362
364/* NOTE!!! Every function that can call EVAL must protect its args 363/* NOTE!!! Every function that can call EVAL must protect its args
@@ -421,16 +420,16 @@ If COND yields nil, and there are no ELSE's, the value is nil.
421usage: (if COND THEN ELSE...) */) 420usage: (if COND THEN ELSE...) */)
422 (Lisp_Object args) 421 (Lisp_Object args)
423{ 422{
424 register Lisp_Object cond; 423 Lisp_Object cond;
425 struct gcpro gcpro1; 424 struct gcpro gcpro1;
426 425
427 GCPRO1 (args); 426 GCPRO1 (args);
428 cond = eval_sub (Fcar (args)); 427 cond = eval_sub (XCAR (args));
429 UNGCPRO; 428 UNGCPRO;
430 429
431 if (!NILP (cond)) 430 if (!NILP (cond))
432 return eval_sub (Fcar (Fcdr (args))); 431 return eval_sub (Fcar (XCDR (args)));
433 return Fprogn (Fcdr (Fcdr (args))); 432 return Fprogn (XCDR (XCDR (args)));
434} 433}
435 434
436DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0, 435DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0,
@@ -445,18 +444,17 @@ CONDITION's value if non-nil is returned from the cond-form.
445usage: (cond CLAUSES...) */) 444usage: (cond CLAUSES...) */)
446 (Lisp_Object args) 445 (Lisp_Object args)
447{ 446{
448 register Lisp_Object clause, val; 447 Lisp_Object val = args;
449 struct gcpro gcpro1; 448 struct gcpro gcpro1;
450 449
451 val = Qnil;
452 GCPRO1 (args); 450 GCPRO1 (args);
453 while (!NILP (args)) 451 while (CONSP (args))
454 { 452 {
455 clause = Fcar (args); 453 Lisp_Object clause = XCAR (args);
456 val = eval_sub (Fcar (clause)); 454 val = eval_sub (Fcar (clause));
457 if (!NILP (val)) 455 if (!NILP (val))
458 { 456 {
459 if (!EQ (XCDR (clause), Qnil)) 457 if (!NILP (XCDR (clause)))
460 val = Fprogn (XCDR (clause)); 458 val = Fprogn (XCDR (clause));
461 break; 459 break;
462 } 460 }
@@ -470,23 +468,32 @@ usage: (cond CLAUSES...) */)
470DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, 468DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0,
471 doc: /* Eval BODY forms sequentially and return value of last one. 469 doc: /* Eval BODY forms sequentially and return value of last one.
472usage: (progn BODY...) */) 470usage: (progn BODY...) */)
473 (Lisp_Object args) 471 (Lisp_Object body)
474{ 472{
475 register Lisp_Object val = Qnil; 473 Lisp_Object val = Qnil;
476 struct gcpro gcpro1; 474 struct gcpro gcpro1;
477 475
478 GCPRO1 (args); 476 GCPRO1 (body);
479 477
480 while (CONSP (args)) 478 while (CONSP (body))
481 { 479 {
482 val = eval_sub (XCAR (args)); 480 val = eval_sub (XCAR (body));
483 args = XCDR (args); 481 body = XCDR (body);
484 } 482 }
485 483
486 UNGCPRO; 484 UNGCPRO;
487 return val; 485 return val;
488} 486}
489 487
488/* Evaluate BODY sequentially, discarding its value. Suitable for
489 record_unwind_protect. */
490
491void
492unwind_body (Lisp_Object body)
493{
494 Fprogn (body);
495}
496
490DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, 497DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0,
491 doc: /* Eval FIRST and BODY sequentially; return value from FIRST. 498 doc: /* Eval FIRST and BODY sequentially; return value from FIRST.
492The value of FIRST is saved during the evaluation of the remaining args, 499The value of FIRST is saved during the evaluation of the remaining args,
@@ -495,11 +502,11 @@ usage: (prog1 FIRST BODY...) */)
495 (Lisp_Object args) 502 (Lisp_Object args)
496{ 503{
497 Lisp_Object val; 504 Lisp_Object val;
498 register Lisp_Object args_left; 505 Lisp_Object args_left;
499 struct gcpro gcpro1, gcpro2; 506 struct gcpro gcpro1, gcpro2;
500 507
501 args_left = args; 508 args_left = args;
502 val = Qnil; 509 val = args;
503 GCPRO2 (args, val); 510 GCPRO2 (args, val);
504 511
505 val = eval_sub (XCAR (args_left)); 512 val = eval_sub (XCAR (args_left));
@@ -536,36 +543,37 @@ The return value of the `setq' form is the value of the last VAL.
536usage: (setq [SYM VAL]...) */) 543usage: (setq [SYM VAL]...) */)
537 (Lisp_Object args) 544 (Lisp_Object args)
538{ 545{
539 register Lisp_Object args_left; 546 Lisp_Object val, sym, lex_binding;
540 register Lisp_Object val, sym, lex_binding;
541 struct gcpro gcpro1;
542
543 if (NILP (args))
544 return Qnil;
545 547
546 args_left = args; 548 val = args;
547 GCPRO1 (args); 549 if (CONSP (args))
548
549 do
550 { 550 {
551 val = eval_sub (Fcar (Fcdr (args_left))); 551 Lisp_Object args_left = args;
552 sym = Fcar (args_left); 552 struct gcpro gcpro1;
553 GCPRO1 (args);
553 554
554 /* Like for eval_sub, we do not check declared_special here since 555 do
555 it's been done when let-binding. */ 556 {
556 if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */ 557 val = eval_sub (Fcar (XCDR (args_left)));
557 && SYMBOLP (sym) 558 sym = XCAR (args_left);
558 && !NILP (lex_binding 559
559 = Fassq (sym, Vinternal_interpreter_environment))) 560 /* Like for eval_sub, we do not check declared_special here since
560 XSETCDR (lex_binding, val); /* SYM is lexically bound. */ 561 it's been done when let-binding. */
561 else 562 if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */
562 Fset (sym, val); /* SYM is dynamically bound. */ 563 && SYMBOLP (sym)
564 && !NILP (lex_binding
565 = Fassq (sym, Vinternal_interpreter_environment)))
566 XSETCDR (lex_binding, val); /* SYM is lexically bound. */
567 else
568 Fset (sym, val); /* SYM is dynamically bound. */
569
570 args_left = Fcdr (XCDR (args_left));
571 }
572 while (CONSP (args_left));
563 573
564 args_left = Fcdr (Fcdr (args_left)); 574 UNGCPRO;
565 } 575 }
566 while (!NILP (args_left));
567 576
568 UNGCPRO;
569 return val; 577 return val;
570} 578}
571 579
@@ -582,9 +590,9 @@ of unexpected results when a quoted object is modified.
582usage: (quote ARG) */) 590usage: (quote ARG) */)
583 (Lisp_Object args) 591 (Lisp_Object args)
584{ 592{
585 if (!NILP (Fcdr (args))) 593 if (CONSP (XCDR (args)))
586 xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args)); 594 xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args));
587 return Fcar (args); 595 return XCAR (args);
588} 596}
589 597
590DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0, 598DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
@@ -596,7 +604,7 @@ usage: (function ARG) */)
596{ 604{
597 Lisp_Object quoted = XCAR (args); 605 Lisp_Object quoted = XCAR (args);
598 606
599 if (!NILP (Fcdr (args))) 607 if (CONSP (XCDR (args)))
600 xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args)); 608 xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args));
601 609
602 if (!NILP (Vinternal_interpreter_environment) 610 if (!NILP (Vinternal_interpreter_environment)
@@ -698,21 +706,23 @@ To define a user option, use `defcustom' instead of `defvar'.
698usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) 706usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
699 (Lisp_Object args) 707 (Lisp_Object args)
700{ 708{
701 register Lisp_Object sym, tem, tail; 709 Lisp_Object sym, tem, tail;
702 710
703 sym = Fcar (args); 711 sym = XCAR (args);
704 tail = Fcdr (args); 712 tail = XCDR (args);
705 if (!NILP (Fcdr (Fcdr (tail))))
706 error ("Too many arguments");
707 713
708 tem = Fdefault_boundp (sym); 714 if (CONSP (tail))
709 if (!NILP (tail))
710 { 715 {
716 if (CONSP (XCDR (tail)) && CONSP (XCDR (XCDR (tail))))
717 error ("Too many arguments");
718
719 tem = Fdefault_boundp (sym);
720
711 /* Do it before evaluating the initial value, for self-references. */ 721 /* Do it before evaluating the initial value, for self-references. */
712 XSYMBOL (sym)->declared_special = 1; 722 XSYMBOL (sym)->declared_special = 1;
713 723
714 if (NILP (tem)) 724 if (NILP (tem))
715 Fset_default (sym, eval_sub (Fcar (tail))); 725 Fset_default (sym, eval_sub (XCAR (tail)));
716 else 726 else
717 { /* Check if there is really a global binding rather than just a let 727 { /* Check if there is really a global binding rather than just a let
718 binding that shadows the global unboundness of the var. */ 728 binding that shadows the global unboundness of the var. */
@@ -730,7 +740,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
730 } 740 }
731 } 741 }
732 } 742 }
733 tail = Fcdr (tail); 743 tail = XCDR (tail);
734 tem = Fcar (tail); 744 tem = Fcar (tail);
735 if (!NILP (tem)) 745 if (!NILP (tem))
736 { 746 {
@@ -775,18 +785,18 @@ The optional DOCSTRING specifies the variable's documentation string.
775usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) 785usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
776 (Lisp_Object args) 786 (Lisp_Object args)
777{ 787{
778 register Lisp_Object sym, tem; 788 Lisp_Object sym, tem;
779 789
780 sym = Fcar (args); 790 sym = XCAR (args);
781 if (!NILP (Fcdr (Fcdr (Fcdr (args))))) 791 if (CONSP (Fcdr (XCDR (XCDR (args)))))
782 error ("Too many arguments"); 792 error ("Too many arguments");
783 793
784 tem = eval_sub (Fcar (Fcdr (args))); 794 tem = eval_sub (Fcar (XCDR (args)));
785 if (!NILP (Vpurify_flag)) 795 if (!NILP (Vpurify_flag))
786 tem = Fpurecopy (tem); 796 tem = Fpurecopy (tem);
787 Fset_default (sym, tem); 797 Fset_default (sym, tem);
788 XSYMBOL (sym)->declared_special = 1; 798 XSYMBOL (sym)->declared_special = 1;
789 tem = Fcar (Fcdr (Fcdr (args))); 799 tem = Fcar (XCDR (XCDR (args)));
790 if (!NILP (tem)) 800 if (!NILP (tem))
791 { 801 {
792 if (!NILP (Vpurify_flag)) 802 if (!NILP (Vpurify_flag))
@@ -827,7 +837,7 @@ usage: (let* VARLIST BODY...) */)
827 837
828 lexenv = Vinternal_interpreter_environment; 838 lexenv = Vinternal_interpreter_environment;
829 839
830 varlist = Fcar (args); 840 varlist = XCAR (args);
831 while (CONSP (varlist)) 841 while (CONSP (varlist))
832 { 842 {
833 QUIT; 843 QUIT;
@@ -868,7 +878,7 @@ usage: (let* VARLIST BODY...) */)
868 varlist = XCDR (varlist); 878 varlist = XCDR (varlist);
869 } 879 }
870 UNGCPRO; 880 UNGCPRO;
871 val = Fprogn (Fcdr (args)); 881 val = Fprogn (XCDR (args));
872 return unbind_to (count, val); 882 return unbind_to (count, val);
873} 883}
874 884
@@ -888,7 +898,7 @@ usage: (let VARLIST BODY...) */)
888 struct gcpro gcpro1, gcpro2; 898 struct gcpro gcpro1, gcpro2;
889 USE_SAFE_ALLOCA; 899 USE_SAFE_ALLOCA;
890 900
891 varlist = Fcar (args); 901 varlist = XCAR (args);
892 902
893 /* Make space to hold the values to give the bound variables. */ 903 /* Make space to hold the values to give the bound variables. */
894 elt = Flength (varlist); 904 elt = Flength (varlist);
@@ -915,7 +925,7 @@ usage: (let VARLIST BODY...) */)
915 925
916 lexenv = Vinternal_interpreter_environment; 926 lexenv = Vinternal_interpreter_environment;
917 927
918 varlist = Fcar (args); 928 varlist = XCAR (args);
919 for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist)) 929 for (argnum = 0; CONSP (varlist); varlist = XCDR (varlist))
920 { 930 {
921 Lisp_Object var; 931 Lisp_Object var;
@@ -938,7 +948,7 @@ usage: (let VARLIST BODY...) */)
938 /* Instantiate a new lexical environment. */ 948 /* Instantiate a new lexical environment. */
939 specbind (Qinternal_interpreter_environment, lexenv); 949 specbind (Qinternal_interpreter_environment, lexenv);
940 950
941 elt = Fprogn (Fcdr (args)); 951 elt = Fprogn (XCDR (args));
942 SAFE_FREE (); 952 SAFE_FREE ();
943 return unbind_to (count, elt); 953 return unbind_to (count, elt);
944} 954}
@@ -955,8 +965,8 @@ usage: (while TEST BODY...) */)
955 965
956 GCPRO2 (test, body); 966 GCPRO2 (test, body);
957 967
958 test = Fcar (args); 968 test = XCAR (args);
959 body = Fcdr (args); 969 body = XCDR (args);
960 while (!NILP (eval_sub (test))) 970 while (!NILP (eval_sub (test)))
961 { 971 {
962 QUIT; 972 QUIT;
@@ -1053,9 +1063,9 @@ usage: (catch TAG BODY...) */)
1053 struct gcpro gcpro1; 1063 struct gcpro gcpro1;
1054 1064
1055 GCPRO1 (args); 1065 GCPRO1 (args);
1056 tag = eval_sub (Fcar (args)); 1066 tag = eval_sub (XCAR (args));
1057 UNGCPRO; 1067 UNGCPRO;
1058 return internal_catch (tag, Fprogn, Fcdr (args)); 1068 return internal_catch (tag, Fprogn, XCDR (args));
1059} 1069}
1060 1070
1061/* Set up a catch, then call C function FUNC on argument ARG. 1071/* Set up a catch, then call C function FUNC on argument ARG.
@@ -1169,8 +1179,8 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...) */)
1169 Lisp_Object val; 1179 Lisp_Object val;
1170 ptrdiff_t count = SPECPDL_INDEX (); 1180 ptrdiff_t count = SPECPDL_INDEX ();
1171 1181
1172 record_unwind_protect (Fprogn, Fcdr (args)); 1182 record_unwind_protect (unwind_body, XCDR (args));
1173 val = eval_sub (Fcar (args)); 1183 val = eval_sub (XCAR (args));
1174 return unbind_to (count, val); 1184 return unbind_to (count, val);
1175} 1185}
1176 1186
@@ -1202,9 +1212,9 @@ See also the function `signal' for more info.
1202usage: (condition-case VAR BODYFORM &rest HANDLERS) */) 1212usage: (condition-case VAR BODYFORM &rest HANDLERS) */)
1203 (Lisp_Object args) 1213 (Lisp_Object args)
1204{ 1214{
1205 Lisp_Object var = Fcar (args); 1215 Lisp_Object var = XCAR (args);
1206 Lisp_Object bodyform = Fcar (Fcdr (args)); 1216 Lisp_Object bodyform = XCAR (XCDR (args));
1207 Lisp_Object handlers = Fcdr (Fcdr (args)); 1217 Lisp_Object handlers = XCDR (XCDR (args));
1208 1218
1209 return internal_lisp_condition_case (var, bodyform, handlers); 1219 return internal_lisp_condition_case (var, bodyform, handlers);
1210} 1220}
@@ -1631,7 +1641,7 @@ signal_error (const char *s, Lisp_Object arg)
1631 } 1641 }
1632 1642
1633 if (!NILP (hare)) 1643 if (!NILP (hare))
1634 arg = Fcons (arg, Qnil); /* Make it a list. */ 1644 arg = list1 (arg);
1635 1645
1636 xsignal (Qerror, Fcons (build_string (s), arg)); 1646 xsignal (Qerror, Fcons (build_string (s), arg));
1637} 1647}
@@ -1723,7 +1733,7 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data)
1723 /* RMS: What's this for? */ 1733 /* RMS: What's this for? */
1724 && when_entered_debugger < num_nonmacro_input_events) 1734 && when_entered_debugger < num_nonmacro_input_events)
1725 { 1735 {
1726 call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); 1736 call_debugger (list2 (Qerror, combined_data));
1727 return 1; 1737 return 1;
1728 } 1738 }
1729 1739
@@ -1910,10 +1920,10 @@ this does nothing and returns nil. */)
1910 Qnil); 1920 Qnil);
1911} 1921}
1912 1922
1913Lisp_Object 1923void
1914un_autoload (Lisp_Object oldqueue) 1924un_autoload (Lisp_Object oldqueue)
1915{ 1925{
1916 register Lisp_Object queue, first, second; 1926 Lisp_Object queue, first, second;
1917 1927
1918 /* Queue to unwind is current value of Vautoload_queue. 1928 /* Queue to unwind is current value of Vautoload_queue.
1919 oldqueue is the shadowed value to leave in Vautoload_queue. */ 1929 oldqueue is the shadowed value to leave in Vautoload_queue. */
@@ -1930,7 +1940,6 @@ un_autoload (Lisp_Object oldqueue)
1930 Ffset (first, second); 1940 Ffset (first, second);
1931 queue = XCDR (queue); 1941 queue = XCDR (queue);
1932 } 1942 }
1933 return Qnil;
1934} 1943}
1935 1944
1936/* Load an autoloaded function. 1945/* Load an autoloaded function.
@@ -2012,7 +2021,7 @@ If LEXICAL is t, evaluate using lexical scoping. */)
2012{ 2021{
2013 ptrdiff_t count = SPECPDL_INDEX (); 2022 ptrdiff_t count = SPECPDL_INDEX ();
2014 specbind (Qinternal_interpreter_environment, 2023 specbind (Qinternal_interpreter_environment,
2015 CONSP (lexical) || NILP (lexical) ? lexical : Fcons (Qt, Qnil)); 2024 CONSP (lexical) || NILP (lexical) ? lexical : list1 (Qt));
2016 return unbind_to (count, eval_sub (form)); 2025 return unbind_to (count, eval_sub (form));
2017} 2026}
2018 2027
@@ -2277,7 +2286,7 @@ eval_sub (Lisp_Object form)
2277 2286
2278 lisp_eval_depth--; 2287 lisp_eval_depth--;
2279 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2288 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2280 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); 2289 val = call_debugger (list2 (Qexit, val));
2281 specpdl_ptr--; 2290 specpdl_ptr--;
2282 2291
2283 return val; 2292 return val;
@@ -2898,7 +2907,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2898 check_cons_list (); 2907 check_cons_list ();
2899 lisp_eval_depth--; 2908 lisp_eval_depth--;
2900 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2909 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2901 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); 2910 val = call_debugger (list2 (Qexit, val));
2902 specpdl_ptr--; 2911 specpdl_ptr--;
2903 return val; 2912 return val;
2904} 2913}
@@ -2940,7 +2949,7 @@ apply_lambda (Lisp_Object fun, Lisp_Object args)
2940 { 2949 {
2941 /* Don't do it again when we return to eval. */ 2950 /* Don't do it again when we return to eval. */
2942 set_backtrace_debug_on_exit (specpdl_ptr - 1, false); 2951 set_backtrace_debug_on_exit (specpdl_ptr - 1, false);
2943 tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); 2952 tem = call_debugger (list2 (Qexit, tem));
2944 } 2953 }
2945 SAFE_FREE (); 2954 SAFE_FREE ();
2946 return tem; 2955 return tem;
@@ -3255,8 +3264,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3255 } 3264 }
3256} 3265}
3257 3266
3267/* Push unwind-protect entries of various types. */
3268
3258void 3269void
3259record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) 3270record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg)
3260{ 3271{
3261 specpdl_ptr->unwind.kind = SPECPDL_UNWIND; 3272 specpdl_ptr->unwind.kind = SPECPDL_UNWIND;
3262 specpdl_ptr->unwind.func = function; 3273 specpdl_ptr->unwind.func = function;
@@ -3265,6 +3276,32 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
3265} 3276}
3266 3277
3267void 3278void
3279record_unwind_protect_ptr (void (*function) (void *), void *arg)
3280{
3281 specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
3282 specpdl_ptr->unwind_ptr.func = function;
3283 specpdl_ptr->unwind_ptr.arg = arg;
3284 grow_specpdl ();
3285}
3286
3287void
3288record_unwind_protect_int (void (*function) (int), int arg)
3289{
3290 specpdl_ptr->unwind_int.kind = SPECPDL_UNWIND_INT;
3291 specpdl_ptr->unwind_int.func = function;
3292 specpdl_ptr->unwind_int.arg = arg;
3293 grow_specpdl ();
3294}
3295
3296void
3297record_unwind_protect_void (void (*function) (void))
3298{
3299 specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID;
3300 specpdl_ptr->unwind_void.func = function;
3301 grow_specpdl ();
3302}
3303
3304void
3268rebind_for_thread_switch (void) 3305rebind_for_thread_switch (void)
3269{ 3306{
3270 union specbinding *bind; 3307 union specbinding *bind;
@@ -3288,7 +3325,18 @@ do_one_unbind (union specbinding *this_binding, int unwinding)
3288 switch (this_binding->kind) 3325 switch (this_binding->kind)
3289 { 3326 {
3290 case SPECPDL_UNWIND: 3327 case SPECPDL_UNWIND:
3291 specpdl_func (this_binding) (specpdl_arg (this_binding)); 3328 specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg);
3329 break;
3330 case SPECPDL_UNWIND_PTR:
3331 specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg);
3332 break;
3333 case SPECPDL_UNWIND_INT:
3334 specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg);
3335 break;
3336 case SPECPDL_UNWIND_VOID:
3337 specpdl_ptr->unwind_void.func ();
3338 break;
3339 case SPECPDL_BACKTRACE:
3292 break; 3340 break;
3293 case SPECPDL_LET: 3341 case SPECPDL_LET:
3294 /* If variable has a trivial value (no forwarding), we can 3342 /* If variable has a trivial value (no forwarding), we can
@@ -3304,8 +3352,6 @@ do_one_unbind (union specbinding *this_binding, int unwinding)
3304 Fset_default (specpdl_symbol (this_binding), 3352 Fset_default (specpdl_symbol (this_binding),
3305 specpdl_old_value (this_binding)); 3353 specpdl_old_value (this_binding));
3306 break; 3354 break;
3307 case SPECPDL_BACKTRACE:
3308 break;
3309 case SPECPDL_LET_LOCAL: 3355 case SPECPDL_LET_LOCAL:
3310 case SPECPDL_LET_DEFAULT: 3356 case SPECPDL_LET_DEFAULT:
3311 { /* If the symbol is a list, it is really (SYMBOL WHERE 3357 { /* If the symbol is a list, it is really (SYMBOL WHERE
@@ -3331,6 +3377,46 @@ do_one_unbind (union specbinding *this_binding, int unwinding)
3331 } 3377 }
3332} 3378}
3333 3379
3380void
3381do_nothing (void)
3382{}
3383
3384/* Push an unwind-protect entry that does nothing, so that
3385 set_unwind_protect_ptr can overwrite it later. */
3386
3387void
3388record_unwind_protect_nothing (void)
3389{
3390 record_unwind_protect_void (do_nothing);
3391}
3392
3393/* Clear the unwind-protect entry COUNT, so that it does nothing.
3394 It need not be at the top of the stack. */
3395
3396void
3397clear_unwind_protect (ptrdiff_t count)
3398{
3399 union specbinding *p = specpdl + count;
3400 p->unwind_void.kind = SPECPDL_UNWIND_VOID;
3401 p->unwind_void.func = do_nothing;
3402}
3403
3404/* Set the unwind-protect entry COUNT so that it invokes FUNC (ARG).
3405 It need not be at the top of the stack. Discard the entry's
3406 previous value without invoking it. */
3407
3408void
3409set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg)
3410{
3411 union specbinding *p = specpdl + count;
3412 p->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
3413 p->unwind_ptr.func = func;
3414 p->unwind_ptr.arg = arg;
3415}
3416
3417/* Pop and execute entries from the unwind-protect stack until the
3418 depth COUNT is reached. Return VALUE. */
3419
3334Lisp_Object 3420Lisp_Object
3335unbind_to (ptrdiff_t count, Lisp_Object value) 3421unbind_to (ptrdiff_t count, Lisp_Object value)
3336{ 3422{
@@ -3449,7 +3535,30 @@ Output stream used is value of `standard-output'. */)
3449 return Qnil; 3535 return Qnil;
3450} 3536}
3451 3537
3452DEFUN ("backtrace-frame", Fbacktrace_frame, Sbacktrace_frame, 1, 1, NULL, 3538static union specbinding *
3539get_backtrace_frame (Lisp_Object nframes, Lisp_Object base)
3540{
3541 union specbinding *pdl = backtrace_top ();
3542 register EMACS_INT i;
3543
3544 CHECK_NATNUM (nframes);
3545
3546 if (!NILP (base))
3547 { /* Skip up to `base'. */
3548 base = Findirect_function (base, Qt);
3549 while (backtrace_p (pdl)
3550 && !EQ (base, Findirect_function (backtrace_function (pdl), Qt)))
3551 pdl = backtrace_next (pdl);
3552 }
3553
3554 /* Find the frame requested. */
3555 for (i = XFASTINT (nframes); i > 0 && backtrace_p (pdl); i--)
3556 pdl = backtrace_next (pdl);
3557
3558 return pdl;
3559}
3560
3561DEFUN ("backtrace-frame", Fbacktrace_frame, Sbacktrace_frame, 1, 2, NULL,
3453 doc: /* Return the function and arguments NFRAMES up from current execution point. 3562 doc: /* Return the function and arguments NFRAMES up from current execution point.
3454If that frame has not evaluated the arguments yet (or is a special form), 3563If that frame has not evaluated the arguments yet (or is a special form),
3455the value is (nil FUNCTION ARG-FORMS...). 3564the value is (nil FUNCTION ARG-FORMS...).
@@ -3458,17 +3567,12 @@ the value is (t FUNCTION ARG-VALUES...).
3458A &rest arg is represented as the tail of the list ARG-VALUES. 3567A &rest arg is represented as the tail of the list ARG-VALUES.
3459FUNCTION is whatever was supplied as car of evaluated list, 3568FUNCTION is whatever was supplied as car of evaluated list,
3460or a lambda expression for macro calls. 3569or a lambda expression for macro calls.
3461If NFRAMES is more than the number of frames, the value is nil. */) 3570If NFRAMES is more than the number of frames, the value is nil.
3462 (Lisp_Object nframes) 3571If BASE is non-nil, it should be a function and NFRAMES counts from its
3572nearest activation frame. */)
3573 (Lisp_Object nframes, Lisp_Object base)
3463{ 3574{
3464 union specbinding *pdl = backtrace_top (); 3575 union specbinding *pdl = get_backtrace_frame (nframes, base);
3465 register EMACS_INT i;
3466
3467 CHECK_NATNUM (nframes);
3468
3469 /* Find the frame requested. */
3470 for (i = 0; backtrace_p (pdl) && i < XFASTINT (nframes); i++)
3471 pdl = backtrace_next (pdl);
3472 3576
3473 if (!backtrace_p (pdl)) 3577 if (!backtrace_p (pdl))
3474 return Qnil; 3578 return Qnil;
@@ -3483,6 +3587,109 @@ If NFRAMES is more than the number of frames, the value is nil. */)
3483 } 3587 }
3484} 3588}
3485 3589
3590/* For backtrace-eval, we want to temporarily unwind the last few elements of
3591 the specpdl stack, and then rewind them. We store the pre-unwind values
3592 directly in the pre-existing specpdl elements (i.e. we swap the current
3593 value and the old value stored in the specpdl), kind of like the inplace
3594 pointer-reversal trick. As it turns out, the rewind does the same as the
3595 unwind, except it starts from the other end of the spepdl stack, so we use
3596 the same function for both unwind and rewind. */
3597static void
3598backtrace_eval_unrewind (int distance)
3599{
3600 union specbinding *tmp = specpdl_ptr;
3601 int step = -1;
3602 if (distance < 0)
3603 { /* It's a rewind rather than unwind. */
3604 tmp += distance - 1;
3605 step = 1;
3606 distance = -distance;
3607 }
3608
3609 for (; distance > 0; distance--)
3610 {
3611 tmp += step;
3612 /* */
3613 switch (tmp->kind)
3614 {
3615 /* FIXME: Ideally we'd like to "temporarily unwind" (some of) those
3616 unwind_protect, but the problem is that we don't know how to
3617 rewind them afterwards. */
3618 case SPECPDL_UNWIND:
3619 case SPECPDL_UNWIND_PTR:
3620 case SPECPDL_UNWIND_INT:
3621 case SPECPDL_UNWIND_VOID:
3622 case SPECPDL_BACKTRACE:
3623 break;
3624 case SPECPDL_LET:
3625 /* If variable has a trivial value (no forwarding), we can
3626 just set it. No need to check for constant symbols here,
3627 since that was already done by specbind. */
3628 if (XSYMBOL (specpdl_symbol (tmp))->redirect
3629 == SYMBOL_PLAINVAL)
3630 {
3631 struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp));
3632 Lisp_Object old_value = specpdl_old_value (tmp);
3633 set_specpdl_old_value (tmp, SYMBOL_VAL (sym));
3634 SET_SYMBOL_VAL (sym, old_value);
3635 break;
3636 }
3637 else
3638 {
3639 /* FALLTHROUGH!
3640 NOTE: we only ever come here if make_local_foo was used for
3641 the first time on this var within this let. */
3642 }
3643 case SPECPDL_LET_DEFAULT:
3644 {
3645 Lisp_Object sym = specpdl_symbol (tmp);
3646 Lisp_Object old_value = specpdl_old_value (tmp);
3647 set_specpdl_old_value (tmp, Fdefault_value (sym));
3648 Fset_default (sym, old_value);
3649 }
3650 break;
3651 case SPECPDL_LET_LOCAL:
3652 {
3653 Lisp_Object symbol = specpdl_symbol (tmp);
3654 Lisp_Object where = specpdl_where (tmp);
3655 Lisp_Object old_value = specpdl_old_value (tmp);
3656 eassert (BUFFERP (where));
3657
3658 /* If this was a local binding, reset the value in the appropriate
3659 buffer, but only if that buffer's binding still exists. */
3660 if (!NILP (Flocal_variable_p (symbol, where)))
3661 {
3662 set_specpdl_old_value
3663 (tmp, Fbuffer_local_value (symbol, where));
3664 set_internal (symbol, old_value, where, 1);
3665 }
3666 }
3667 break;
3668 }
3669 }
3670}
3671
3672DEFUN ("backtrace-eval", Fbacktrace_eval, Sbacktrace_eval, 2, 3, NULL,
3673 doc: /* Evaluate EXP in the context of some activation frame.
3674NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. */)
3675 (Lisp_Object exp, Lisp_Object nframes, Lisp_Object base)
3676{
3677 union specbinding *pdl = get_backtrace_frame (nframes, base);
3678 ptrdiff_t count = SPECPDL_INDEX ();
3679 ptrdiff_t distance = specpdl_ptr - pdl;
3680 eassert (distance >= 0);
3681
3682 if (!backtrace_p (pdl))
3683 error ("Activation frame not found!");
3684
3685 backtrace_eval_unrewind (distance);
3686 record_unwind_protect_int (backtrace_eval_unrewind, -distance);
3687
3688 /* Use eval_sub rather than Feval since the main motivation behind
3689 backtrace-eval is to be able to get/set the value of lexical variables
3690 from the debugger. */
3691 return unbind_to (count, eval_sub (exp));
3692}
3486 3693
3487void 3694void
3488mark_specpdl (union specbinding *first, union specbinding *ptr) 3695mark_specpdl (union specbinding *first, union specbinding *ptr)
@@ -3729,6 +3936,7 @@ alist of active lexical bindings. */);
3729 defsubr (&Sbacktrace_debug); 3936 defsubr (&Sbacktrace_debug);
3730 defsubr (&Sbacktrace); 3937 defsubr (&Sbacktrace);
3731 defsubr (&Sbacktrace_frame); 3938 defsubr (&Sbacktrace_frame);
3939 defsubr (&Sbacktrace_eval);
3732 defsubr (&Sspecial_variable_p); 3940 defsubr (&Sspecial_variable_p);
3733 defsubr (&Sfunctionp); 3941 defsubr (&Sfunctionp);
3734} 3942}
diff --git a/src/fileio.c b/src/fileio.c
index c3566390130..c47b3533145 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
@@ -3843,7 +3860,8 @@ by calling `format-decode', which see. */)
3843 if (same_at_start - BEGV_BYTE == end_offset - beg_offset) 3860 if (same_at_start - BEGV_BYTE == end_offset - beg_offset)
3844 { 3861 {
3845 emacs_close (fd); 3862 emacs_close (fd);
3846 specpdl_ptr--; 3863 clear_unwind_protect (fd_index);
3864
3847 /* Truncate the buffer to the size of the file. */ 3865 /* Truncate the buffer to the size of the file. */
3848 del_range_1 (same_at_start, same_at_end, 0, 0); 3866 del_range_1 (same_at_start, same_at_end, 0, 0);
3849 goto handled; 3867 goto handled;
@@ -3866,16 +3884,14 @@ by calling `format-decode', which see. */)
3866 /* How much can we scan in the next step? */ 3884 /* How much can we scan in the next step? */
3867 trial = min (curpos, sizeof read_buf); 3885 trial = min (curpos, sizeof read_buf);
3868 if (lseek (fd, curpos - trial, SEEK_SET) < 0) 3886 if (lseek (fd, curpos - trial, SEEK_SET) < 0)
3869 report_file_error ("Setting file position", 3887 report_file_error ("Setting file position", orig_filename);
3870 Fcons (orig_filename, Qnil));
3871 3888
3872 total_read = nread = 0; 3889 total_read = nread = 0;
3873 while (total_read < trial) 3890 while (total_read < trial)
3874 { 3891 {
3875 nread = emacs_read (fd, read_buf + total_read, trial - total_read); 3892 nread = emacs_read (fd, read_buf + total_read, trial - total_read);
3876 if (nread < 0) 3893 if (nread < 0)
3877 error ("IO error reading %s: %s", 3894 report_file_error ("Read error", orig_filename);
3878 SDATA (orig_filename), emacs_strerror (errno));
3879 else if (nread == 0) 3895 else if (nread == 0)
3880 break; 3896 break;
3881 total_read += nread; 3897 total_read += nread;
@@ -3987,8 +4003,7 @@ by calling `format-decode', which see. */)
3987 CONVERSION_BUFFER. */ 4003 CONVERSION_BUFFER. */
3988 4004
3989 if (lseek (fd, beg_offset, SEEK_SET) < 0) 4005 if (lseek (fd, beg_offset, SEEK_SET) < 0)
3990 report_file_error ("Setting file position", 4006 report_file_error ("Setting file position", orig_filename);
3991 Fcons (orig_filename, Qnil));
3992 4007
3993 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */ 4008 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3994 unprocessed = 0; /* Bytes not processed in previous loop. */ 4009 unprocessed = 0; /* Bytes not processed in previous loop. */
@@ -4018,16 +4033,10 @@ by calling `format-decode', which see. */)
4018 memcpy (read_buf, coding.carryover, unprocessed); 4033 memcpy (read_buf, coding.carryover, unprocessed);
4019 } 4034 }
4020 UNGCPRO; 4035 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) 4036 if (this < 0)
4029 error ("IO error reading %s: %s", 4037 report_file_error ("Read error", orig_filename);
4030 SDATA (orig_filename), emacs_strerror (errno)); 4038 emacs_close (fd);
4039 clear_unwind_protect (fd_index);
4031 4040
4032 if (unprocessed > 0) 4041 if (unprocessed > 0)
4033 { 4042 {
@@ -4168,8 +4177,7 @@ by calling `format-decode', which see. */)
4168 if (beg_offset != 0 || !NILP (replace)) 4177 if (beg_offset != 0 || !NILP (replace))
4169 { 4178 {
4170 if (lseek (fd, beg_offset, SEEK_SET) < 0) 4179 if (lseek (fd, beg_offset, SEEK_SET) < 0)
4171 report_file_error ("Setting file position", 4180 report_file_error ("Setting file position", orig_filename);
4172 Fcons (orig_filename, Qnil));
4173 } 4181 }
4174 4182
4175 /* In the following loop, HOW_MUCH contains the total bytes read so 4183 /* In the following loop, HOW_MUCH contains the total bytes read so
@@ -4208,8 +4216,7 @@ by calling `format-decode', which see. */)
4208 to be signaled after decoding the text we read. */ 4216 to be signaled after decoding the text we read. */
4209 nbytes = internal_condition_case_1 4217 nbytes = internal_condition_case_1
4210 (read_non_regular, 4218 (read_non_regular,
4211 make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd, 4219 make_save_int_int_int (fd, inserted, trytry),
4212 inserted, trytry),
4213 Qerror, read_non_regular_quit); 4220 Qerror, read_non_regular_quit);
4214 4221
4215 if (NILP (nbytes)) 4222 if (NILP (nbytes))
@@ -4269,13 +4276,10 @@ by calling `format-decode', which see. */)
4269 Vdeactivate_mark = Qt; 4276 Vdeactivate_mark = Qt;
4270 4277
4271 emacs_close (fd); 4278 emacs_close (fd);
4272 4279 clear_unwind_protect (fd_index);
4273 /* Discard the unwind protect for closing the file. */
4274 specpdl_ptr--;
4275 4280
4276 if (how_much < 0) 4281 if (how_much < 0)
4277 error ("IO error reading %s: %s", 4282 report_file_error ("Read error", orig_filename);
4278 SDATA (orig_filename), emacs_strerror (errno));
4279 4283
4280 /* Make the text read part of the buffer. */ 4284 /* Make the text read part of the buffer. */
4281 GAP_SIZE -= inserted; 4285 GAP_SIZE -= inserted;
@@ -4399,11 +4403,6 @@ by calling `format-decode', which see. */)
4399 4403
4400 handled: 4404 handled:
4401 4405
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)) 4406 if (!NILP (visit))
4408 { 4407 {
4409 if (empty_undo_list_p) 4408 if (empty_undo_list_p)
@@ -4574,8 +4573,7 @@ by calling `format-decode', which see. */)
4574 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 4573 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
4575 { 4574 {
4576 /* If visiting nonexistent file, return nil. */ 4575 /* If visiting nonexistent file, return nil. */
4577 report_file_errno ("Opening input file", Fcons (orig_filename, Qnil), 4576 report_file_errno ("Opening input file", orig_filename, save_errno);
4578 save_errno);
4579 } 4577 }
4580 4578
4581 if (read_quit) 4579 if (read_quit)
@@ -4590,11 +4588,10 @@ by calling `format-decode', which see. */)
4590 4588
4591static Lisp_Object build_annotations (Lisp_Object, Lisp_Object); 4589static Lisp_Object build_annotations (Lisp_Object, Lisp_Object);
4592 4590
4593static Lisp_Object 4591static void
4594build_annotations_unwind (Lisp_Object arg) 4592build_annotations_unwind (Lisp_Object arg)
4595{ 4593{
4596 Vwrite_region_annotation_buffers = arg; 4594 Vwrite_region_annotation_buffers = arg;
4597 return Qnil;
4598} 4595}
4599 4596
4600/* Decide the coding-system to encode the data with. */ 4597/* Decide the coding-system to encode the data with. */
@@ -4631,7 +4628,7 @@ This function is for internal use only. It may prompt the user. */ )
4631 && !NILP (Ffboundp (Vselect_safe_coding_system_function))) 4628 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4632 /* Confirm that VAL can surely encode the current region. */ 4629 /* Confirm that VAL can surely encode the current region. */
4633 val = call5 (Vselect_safe_coding_system_function, 4630 val = call5 (Vselect_safe_coding_system_function,
4634 start, end, Fcons (Qt, Fcons (val, Qnil)), 4631 start, end, list2 (Qt, val),
4635 Qnil, filename); 4632 Qnil, filename);
4636 } 4633 }
4637 else 4634 else
@@ -4834,7 +4831,7 @@ This calls `write-region-annotate-functions' at the start, and
4834 4831
4835 record_unwind_protect (build_annotations_unwind, 4832 record_unwind_protect (build_annotations_unwind,
4836 Vwrite_region_annotation_buffers); 4833 Vwrite_region_annotation_buffers);
4837 Vwrite_region_annotation_buffers = Fcons (Fcurrent_buffer (), Qnil); 4834 Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ());
4838 count1 = SPECPDL_INDEX (); 4835 count1 = SPECPDL_INDEX ();
4839 4836
4840 given_buffer = current_buffer; 4837 given_buffer = current_buffer;
@@ -4901,11 +4898,10 @@ This calls `write-region-annotate-functions' at the start, and
4901 if (!auto_saving) unlock_file (lockname); 4898 if (!auto_saving) unlock_file (lockname);
4902#endif /* CLASH_DETECTION */ 4899#endif /* CLASH_DETECTION */
4903 UNGCPRO; 4900 UNGCPRO;
4904 report_file_errno ("Opening output file", Fcons (filename, Qnil), 4901 report_file_errno ("Opening output file", filename, open_errno);
4905 open_errno);
4906 } 4902 }
4907 4903
4908 record_unwind_protect (close_file_unwind, make_number (desc)); 4904 record_unwind_protect_int (close_file_unwind, desc);
4909 4905
4910 if (NUMBERP (append)) 4906 if (NUMBERP (append))
4911 { 4907 {
@@ -4917,8 +4913,7 @@ This calls `write-region-annotate-functions' at the start, and
4917 if (!auto_saving) unlock_file (lockname); 4913 if (!auto_saving) unlock_file (lockname);
4918#endif /* CLASH_DETECTION */ 4914#endif /* CLASH_DETECTION */
4919 UNGCPRO; 4915 UNGCPRO;
4920 report_file_errno ("Lseek error", Fcons (filename, Qnil), 4916 report_file_errno ("Lseek error", filename, lseek_errno);
4921 lseek_errno);
4922 } 4917 }
4923 } 4918 }
4924 4919
@@ -5071,8 +5066,7 @@ This calls `write-region-annotate-functions' at the start, and
5071 } 5066 }
5072 5067
5073 if (! ok) 5068 if (! ok)
5074 error ("IO error writing %s: %s", SDATA (filename), 5069 report_file_errno ("Write error", filename, save_errno);
5075 emacs_strerror (save_errno));
5076 5070
5077 if (visiting) 5071 if (visiting)
5078 { 5072 {
@@ -5498,11 +5492,18 @@ auto_save_1 (void)
5498 Qnil, Qnil); 5492 Qnil, Qnil);
5499} 5493}
5500 5494
5501static Lisp_Object 5495struct auto_save_unwind
5502do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ 5496{
5497 FILE *stream;
5498 bool auto_raise;
5499};
5503 5500
5501static void
5502do_auto_save_unwind (void *arg)
5504{ 5503{
5505 FILE *stream = XSAVE_POINTER (arg, 0); 5504 struct auto_save_unwind *p = arg;
5505 FILE *stream = p->stream;
5506 minibuffer_auto_raise = p->auto_raise;
5506 auto_saving = 0; 5507 auto_saving = 0;
5507 if (stream != NULL) 5508 if (stream != NULL)
5508 { 5509 {
@@ -5510,15 +5511,6 @@ do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */
5510 fclose (stream); 5511 fclose (stream);
5511 unblock_input (); 5512 unblock_input ();
5512 } 5513 }
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} 5514}
5523 5515
5524static Lisp_Object 5516static Lisp_Object
@@ -5561,6 +5553,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5561 ptrdiff_t count = SPECPDL_INDEX (); 5553 ptrdiff_t count = SPECPDL_INDEX ();
5562 bool orig_minibuffer_auto_raise = minibuffer_auto_raise; 5554 bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
5563 bool old_message_p = 0; 5555 bool old_message_p = 0;
5556 struct auto_save_unwind auto_save_unwind;
5564 struct gcpro gcpro1, gcpro2; 5557 struct gcpro gcpro1, gcpro2;
5565 5558
5566 if (max_specpdl_size < specpdl_size + 40) 5559 if (max_specpdl_size < specpdl_size + 40)
@@ -5572,7 +5565,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5572 if (NILP (no_message)) 5565 if (NILP (no_message))
5573 { 5566 {
5574 old_message_p = push_message (); 5567 old_message_p = push_message ();
5575 record_unwind_protect (pop_message_unwind, Qnil); 5568 record_unwind_protect_void (pop_message_unwind);
5576 } 5569 }
5577 5570
5578 /* Ordinarily don't quit within this function, 5571 /* Ordinarily don't quit within this function,
@@ -5611,10 +5604,9 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5611 stream = emacs_fopen (SSDATA (listfile), "w"); 5604 stream = emacs_fopen (SSDATA (listfile), "w");
5612 } 5605 }
5613 5606
5614 record_unwind_protect (do_auto_save_unwind, 5607 auto_save_unwind.stream = stream;
5615 make_save_pointer (stream)); 5608 auto_save_unwind.auto_raise = minibuffer_auto_raise;
5616 record_unwind_protect (do_auto_save_unwind_1, 5609 record_unwind_protect_ptr (do_auto_save_unwind, &auto_save_unwind);
5617 make_number (minibuffer_auto_raise));
5618 minibuffer_auto_raise = 0; 5610 minibuffer_auto_raise = 0;
5619 auto_saving = 1; 5611 auto_saving = 1;
5620 auto_save_error_occurred = 0; 5612 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..1f8cb520dca 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1569,7 +1569,7 @@ which is then usually a filename. */)
1569 1569
1570DEFUN ("image-flush", Fimage_flush, Simage_flush, 1570DEFUN ("image-flush", Fimage_flush, Simage_flush,
1571 1, 2, 0, 1571 1, 2, 0,
1572 doc: /* Fush the image with specification SPEC on frame FRAME. 1572 doc: /* Flush the image with specification SPEC on frame FRAME.
1573This removes the image from the Emacs image cache. If SPEC specifies 1573This removes the image from the Emacs image cache. If SPEC specifies
1574an image file, the next redisplay of this image will read from the 1574an image file, the next redisplay of this image will read from the
1575current contents of that file. 1575current contents of that file.
@@ -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 b6eb9e6ad15..830f70bc1f5 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;
@@ -356,7 +357,7 @@ Lisp_Object Qvertical_line;
356static Lisp_Object Qvertical_scroll_bar; 357static Lisp_Object Qvertical_scroll_bar;
357Lisp_Object Qmenu_bar; 358Lisp_Object Qmenu_bar;
358 359
359static Lisp_Object recursive_edit_unwind (Lisp_Object buffer); 360static void recursive_edit_unwind (Lisp_Object buffer);
360static Lisp_Object command_loop (void); 361static Lisp_Object command_loop (void);
361static Lisp_Object Qcommand_execute; 362static Lisp_Object Qcommand_execute;
362EMACS_TIME timer_check (void); 363EMACS_TIME timer_check (void);
@@ -420,12 +421,14 @@ static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object,
420 Lisp_Object, const char *const *, 421 Lisp_Object, const char *const *,
421 Lisp_Object *, ptrdiff_t); 422 Lisp_Object *, ptrdiff_t);
422static Lisp_Object make_lispy_switch_frame (Lisp_Object); 423static Lisp_Object make_lispy_switch_frame (Lisp_Object);
424static Lisp_Object make_lispy_focus_in (Lisp_Object);
425static Lisp_Object make_lispy_focus_out (Lisp_Object);
423static bool help_char_p (Lisp_Object); 426static bool help_char_p (Lisp_Object);
424static void save_getcjmp (sys_jmp_buf); 427static void save_getcjmp (sys_jmp_buf);
425static void restore_getcjmp (sys_jmp_buf); 428static void restore_getcjmp (sys_jmp_buf);
426static Lisp_Object apply_modifiers (int, Lisp_Object); 429static Lisp_Object apply_modifiers (int, Lisp_Object);
427static void clear_event (struct input_event *); 430static void clear_event (struct input_event *);
428static Lisp_Object restore_kboard_configuration (Lisp_Object); 431static void restore_kboard_configuration (int);
429#ifdef USABLE_SIGIO 432#ifdef USABLE_SIGIO
430static void deliver_input_available_signal (int signo); 433static void deliver_input_available_signal (int signo);
431#endif 434#endif
@@ -841,7 +844,7 @@ This function is called by the editor initialization to begin editing. */)
841 return unbind_to (count, Qnil); 844 return unbind_to (count, Qnil);
842} 845}
843 846
844Lisp_Object 847void
845recursive_edit_unwind (Lisp_Object buffer) 848recursive_edit_unwind (Lisp_Object buffer)
846{ 849{
847 if (BUFFERP (buffer)) 850 if (BUFFERP (buffer))
@@ -849,7 +852,6 @@ recursive_edit_unwind (Lisp_Object buffer)
849 852
850 command_loop_level--; 853 command_loop_level--;
851 update_mode_lines = 1; 854 update_mode_lines = 1;
852 return Qnil;
853} 855}
854 856
855 857
@@ -946,7 +948,7 @@ pop_kboard (void)
946 from which further input is accepted. If F is non-nil, set its 948 from which further input is accepted. If F is non-nil, set its
947 KBOARD as the current keyboard. 949 KBOARD as the current keyboard.
948 950
949 This function uses record_unwind_protect to return to the previous 951 This function uses record_unwind_protect_int to return to the previous
950 state later. 952 state later.
951 953
952 If Emacs is already in single_kboard mode, and F's keyboard is 954 If Emacs is already in single_kboard mode, and F's keyboard is
@@ -977,8 +979,7 @@ temporarily_switch_to_single_kboard (struct frame *f)
977 else if (f != NULL) 979 else if (f != NULL)
978 current_kboard = FRAME_KBOARD (f); 980 current_kboard = FRAME_KBOARD (f);
979 single_kboard = 1; 981 single_kboard = 1;
980 record_unwind_protect (restore_kboard_configuration, 982 record_unwind_protect_int (restore_kboard_configuration, was_locked);
981 (was_locked ? Qt : Qnil));
982} 983}
983 984
984#if 0 /* This function is not needed anymore. */ 985#if 0 /* This function is not needed anymore. */
@@ -987,26 +988,22 @@ record_single_kboard_state ()
987{ 988{
988 if (single_kboard) 989 if (single_kboard)
989 push_kboard (current_kboard); 990 push_kboard (current_kboard);
990 record_unwind_protect (restore_kboard_configuration, 991 record_unwind_protect_int (restore_kboard_configuration, single_kboard);
991 (single_kboard ? Qt : Qnil));
992} 992}
993#endif 993#endif
994 994
995static Lisp_Object 995static void
996restore_kboard_configuration (Lisp_Object was_locked) 996restore_kboard_configuration (int was_locked)
997{ 997{
998 if (NILP (was_locked)) 998 single_kboard = was_locked;
999 single_kboard = 0; 999 if (was_locked)
1000 else
1001 { 1000 {
1002 struct kboard *prev = current_kboard; 1001 struct kboard *prev = current_kboard;
1003 single_kboard = 1;
1004 pop_kboard (); 1002 pop_kboard ();
1005 /* The pop should not change the kboard. */ 1003 /* The pop should not change the kboard. */
1006 if (single_kboard && current_kboard != prev) 1004 if (single_kboard && current_kboard != prev)
1007 emacs_abort (); 1005 emacs_abort ();
1008 } 1006 }
1009 return Qnil;
1010} 1007}
1011 1008
1012 1009
@@ -1234,7 +1231,7 @@ DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0,
1234/* Restore mouse tracking enablement. See Ftrack_mouse for the only use 1231/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
1235 of this function. */ 1232 of this function. */
1236 1233
1237static Lisp_Object 1234static void
1238tracking_off (Lisp_Object old_value) 1235tracking_off (Lisp_Object old_value)
1239{ 1236{
1240 do_mouse_tracking = old_value; 1237 do_mouse_tracking = old_value;
@@ -1251,7 +1248,6 @@ tracking_off (Lisp_Object old_value)
1251 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW); 1248 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
1252 } 1249 }
1253 } 1250 }
1254 return Qnil;
1255} 1251}
1256 1252
1257DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, 1253DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0,
@@ -1314,17 +1310,6 @@ static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
1314void safe_run_hooks (Lisp_Object); 1310void safe_run_hooks (Lisp_Object);
1315static void adjust_point_for_property (ptrdiff_t, bool); 1311static void adjust_point_for_property (ptrdiff_t, bool);
1316 1312
1317/* Cancel hourglass from protect_unwind.
1318 ARG is not used. */
1319#ifdef HAVE_WINDOW_SYSTEM
1320static Lisp_Object
1321cancel_hourglass_unwind (Lisp_Object arg)
1322{
1323 cancel_hourglass ();
1324 return Qnil;
1325}
1326#endif
1327
1328/* The last boundary auto-added to buffer-undo-list. */ 1313/* The last boundary auto-added to buffer-undo-list. */
1329Lisp_Object last_undo_boundary; 1314Lisp_Object last_undo_boundary;
1330 1315
@@ -1427,7 +1412,7 @@ command_loop_1 (void)
1427 if (!NILP (Vquit_flag)) 1412 if (!NILP (Vquit_flag))
1428 { 1413 {
1429 Vquit_flag = Qnil; 1414 Vquit_flag = Qnil;
1430 Vunread_command_events = Fcons (make_number (quit_char), Qnil); 1415 Vunread_command_events = list1 (make_number (quit_char));
1431 } 1416 }
1432 } 1417 }
1433 1418
@@ -1559,7 +1544,7 @@ command_loop_1 (void)
1559 if (display_hourglass_p 1544 if (display_hourglass_p
1560 && NILP (Vexecuting_kbd_macro)) 1545 && NILP (Vexecuting_kbd_macro))
1561 { 1546 {
1562 record_unwind_protect (cancel_hourglass_unwind, Qnil); 1547 record_unwind_protect_void (cancel_hourglass);
1563 start_hourglass (); 1548 start_hourglass ();
1564 } 1549 }
1565#endif 1550#endif
@@ -2201,14 +2186,13 @@ static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
2201static void record_char (Lisp_Object c); 2186static void record_char (Lisp_Object c);
2202 2187
2203static Lisp_Object help_form_saved_window_configs; 2188static Lisp_Object help_form_saved_window_configs;
2204static Lisp_Object 2189static void
2205read_char_help_form_unwind (Lisp_Object arg) 2190read_char_help_form_unwind (void)
2206{ 2191{
2207 Lisp_Object window_config = XCAR (help_form_saved_window_configs); 2192 Lisp_Object window_config = XCAR (help_form_saved_window_configs);
2208 help_form_saved_window_configs = XCDR (help_form_saved_window_configs); 2193 help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
2209 if (!NILP (window_config)) 2194 if (!NILP (window_config))
2210 Fset_window_configuration (window_config); 2195 Fset_window_configuration (window_config);
2211 return Qnil;
2212} 2196}
2213 2197
2214#define STOP_POLLING \ 2198#define STOP_POLLING \
@@ -2255,9 +2239,9 @@ read_event_from_main_queue (EMACS_TIME *end_time,
2255 emacs_abort (); 2239 emacs_abort ();
2256 } 2240 }
2257 if (!CONSP (last)) 2241 if (!CONSP (last))
2258 kset_kbd_queue (kb, Fcons (c, Qnil)); 2242 kset_kbd_queue (kb, list1 (c));
2259 else 2243 else
2260 XSETCDR (last, Fcons (c, Qnil)); 2244 XSETCDR (last, list1 (c));
2261 kb->kbd_queue_has_data = 1; 2245 kb->kbd_queue_has_data = 1;
2262 c = Qnil; 2246 c = Qnil;
2263 if (single_kboard) 2247 if (single_kboard)
@@ -2679,9 +2663,9 @@ read_char (int commandflag, Lisp_Object map,
2679 emacs_abort (); 2663 emacs_abort ();
2680 } 2664 }
2681 if (!CONSP (last)) 2665 if (!CONSP (last))
2682 kset_kbd_queue (kb, Fcons (c, Qnil)); 2666 kset_kbd_queue (kb, list1 (c));
2683 else 2667 else
2684 XSETCDR (last, Fcons (c, Qnil)); 2668 XSETCDR (last, list1 (c));
2685 kb->kbd_queue_has_data = 1; 2669 kb->kbd_queue_has_data = 1;
2686 current_kboard = kb; 2670 current_kboard = kb;
2687 /* This is going to exit from read_char 2671 /* This is going to exit from read_char
@@ -2999,7 +2983,7 @@ read_char (int commandflag, Lisp_Object map,
2999 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) 2983 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
3000 { 2984 {
3001 /* Change menu-bar to (menu-bar) as the event "position". */ 2985 /* Change menu-bar to (menu-bar) as the event "position". */
3002 POSN_SET_POSN (EVENT_START (c), Fcons (posn, Qnil)); 2986 POSN_SET_POSN (EVENT_START (c), list1 (posn));
3003 2987
3004 also_record = c; 2988 also_record = c;
3005 Vunread_command_events = Fcons (c, Vunread_command_events); 2989 Vunread_command_events = Fcons (c, Vunread_command_events);
@@ -3196,7 +3180,7 @@ read_char (int commandflag, Lisp_Object map,
3196 help_form_saved_window_configs 3180 help_form_saved_window_configs
3197 = Fcons (Fcurrent_window_configuration (Qnil), 3181 = Fcons (Fcurrent_window_configuration (Qnil),
3198 help_form_saved_window_configs); 3182 help_form_saved_window_configs);
3199 record_unwind_protect (read_char_help_form_unwind, Qnil); 3183 record_unwind_protect_void (read_char_help_form_unwind);
3200 call0 (Qhelp_form_show); 3184 call0 (Qhelp_form_show);
3201 3185
3202 cancel_echoing (); 3186 cancel_echoing ();
@@ -3582,8 +3566,8 @@ kbd_buffer_store_event_hold (register struct input_event *event,
3582 if (single_kboard && kb != current_kboard) 3566 if (single_kboard && kb != current_kboard)
3583 { 3567 {
3584 kset_kbd_queue 3568 kset_kbd_queue
3585 (kb, Fcons (make_lispy_switch_frame (event->frame_or_window), 3569 (kb, list2 (make_lispy_switch_frame (event->frame_or_window),
3586 Fcons (make_number (c), Qnil))); 3570 make_number (c)));
3587 kb->kbd_queue_has_data = 1; 3571 kb->kbd_queue_has_data = 1;
3588 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) 3572 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
3589 { 3573 {
@@ -3946,9 +3930,9 @@ kbd_buffer_get_event (KBOARD **kbp,
3946 else if (event->kind == NS_TEXT_EVENT) 3930 else if (event->kind == NS_TEXT_EVENT)
3947 { 3931 {
3948 if (event->code == KEY_NS_PUT_WORKING_TEXT) 3932 if (event->code == KEY_NS_PUT_WORKING_TEXT)
3949 obj = Fcons (intern ("ns-put-working-text"), Qnil); 3933 obj = list1 (intern ("ns-put-working-text"));
3950 else 3934 else
3951 obj = Fcons (intern ("ns-unput-working-text"), Qnil); 3935 obj = list1 (intern ("ns-unput-working-text"));
3952 kbd_fetch_ptr = event + 1; 3936 kbd_fetch_ptr = event + 1;
3953 if (used_mouse_menu) 3937 if (used_mouse_menu)
3954 *used_mouse_menu = 1; 3938 *used_mouse_menu = 1;
@@ -3960,8 +3944,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3960 else if (event->kind == DELETE_WINDOW_EVENT) 3944 else if (event->kind == DELETE_WINDOW_EVENT)
3961 { 3945 {
3962 /* Make an event (delete-frame (FRAME)). */ 3946 /* Make an event (delete-frame (FRAME)). */
3963 obj = Fcons (event->frame_or_window, Qnil); 3947 obj = list2 (Qdelete_frame, list1 (event->frame_or_window));
3964 obj = Fcons (Qdelete_frame, Fcons (obj, Qnil));
3965 kbd_fetch_ptr = event + 1; 3948 kbd_fetch_ptr = event + 1;
3966 } 3949 }
3967#endif 3950#endif
@@ -3970,15 +3953,13 @@ kbd_buffer_get_event (KBOARD **kbp,
3970 else if (event->kind == ICONIFY_EVENT) 3953 else if (event->kind == ICONIFY_EVENT)
3971 { 3954 {
3972 /* Make an event (iconify-frame (FRAME)). */ 3955 /* Make an event (iconify-frame (FRAME)). */
3973 obj = Fcons (event->frame_or_window, Qnil); 3956 obj = list2 (Qiconify_frame, list1 (event->frame_or_window));
3974 obj = Fcons (Qiconify_frame, Fcons (obj, Qnil));
3975 kbd_fetch_ptr = event + 1; 3957 kbd_fetch_ptr = event + 1;
3976 } 3958 }
3977 else if (event->kind == DEICONIFY_EVENT) 3959 else if (event->kind == DEICONIFY_EVENT)
3978 { 3960 {
3979 /* Make an event (make-frame-visible (FRAME)). */ 3961 /* Make an event (make-frame-visible (FRAME)). */
3980 obj = Fcons (event->frame_or_window, Qnil); 3962 obj = list2 (Qmake_frame_visible, list1 (event->frame_or_window));
3981 obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil));
3982 kbd_fetch_ptr = event + 1; 3963 kbd_fetch_ptr = event + 1;
3983 } 3964 }
3984#endif 3965#endif
@@ -4001,11 +3982,11 @@ kbd_buffer_get_event (KBOARD **kbp,
4001#ifdef HAVE_NTGUI 3982#ifdef HAVE_NTGUI
4002 else if (event->kind == LANGUAGE_CHANGE_EVENT) 3983 else if (event->kind == LANGUAGE_CHANGE_EVENT)
4003 { 3984 {
4004 /* Make an event (language-change (FRAME CODEPAGE LANGUAGE-ID)). */ 3985 /* Make an event (language-change FRAME CODEPAGE LANGUAGE-ID). */
4005 obj = Fcons (Qlanguage_change, 3986 obj = list4 (Qlanguage_change,
4006 list3 (event->frame_or_window, 3987 event->frame_or_window,
4007 make_number (event->code), 3988 make_number (event->code),
4008 make_number (event->modifiers))); 3989 make_number (event->modifiers));
4009 kbd_fetch_ptr = event + 1; 3990 kbd_fetch_ptr = event + 1;
4010 } 3991 }
4011#endif 3992#endif
@@ -4014,11 +3995,11 @@ kbd_buffer_get_event (KBOARD **kbp,
4014 { 3995 {
4015#ifdef HAVE_W32NOTIFY 3996#ifdef HAVE_W32NOTIFY
4016 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */ 3997 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
4017 obj = Fcons (Qfile_notify, 3998 obj = list3 (Qfile_notify,
4018 list2 (list3 (make_number (event->code), 3999 list3 (make_number (event->code),
4019 XCAR (event->arg), 4000 XCAR (event->arg),
4020 XCDR (event->arg)), 4001 XCDR (event->arg)),
4021 event->frame_or_window)); 4002 event->frame_or_window);
4022#else 4003#else
4023 obj = make_lispy_event (event); 4004 obj = make_lispy_event (event);
4024#endif 4005#endif
@@ -4027,7 +4008,7 @@ kbd_buffer_get_event (KBOARD **kbp,
4027#endif /* USE_FILE_NOTIFY */ 4008#endif /* USE_FILE_NOTIFY */
4028 else if (event->kind == SAVE_SESSION_EVENT) 4009 else if (event->kind == SAVE_SESSION_EVENT)
4029 { 4010 {
4030 obj = Fcons (Qsave_session, Fcons (event->arg, Qnil)); 4011 obj = list2 (Qsave_session, event->arg);
4031 kbd_fetch_ptr = event + 1; 4012 kbd_fetch_ptr = event + 1;
4032 } 4013 }
4033 /* Just discard these, by returning nil. 4014 /* Just discard these, by returning nil.
@@ -4064,17 +4045,43 @@ kbd_buffer_get_event (KBOARD **kbp,
4064 switch-frame event if necessary. */ 4045 switch-frame event if necessary. */
4065 Lisp_Object frame, focus; 4046 Lisp_Object frame, focus;
4066 4047
4067 frame = event->frame_or_window; 4048 frame = event->frame_or_window;
4068 focus = FRAME_FOCUS_FRAME (XFRAME (frame)); 4049 focus = FRAME_FOCUS_FRAME (XFRAME (frame));
4069 if (FRAMEP (focus)) 4050 if (FRAMEP (focus))
4070 frame = focus; 4051 frame = focus;
4071 4052
4072 if (!EQ (frame, internal_last_event_frame) 4053 if (
4073 && !EQ (frame, selected_frame)) 4054#ifdef HAVE_X11
4074 obj = make_lispy_switch_frame (frame); 4055 ! NILP (event->arg)
4075 internal_last_event_frame = frame; 4056 &&
4076 kbd_fetch_ptr = event + 1; 4057#endif
4077 } 4058 !EQ (frame, internal_last_event_frame)
4059 && !EQ (frame, selected_frame))
4060 obj = make_lispy_switch_frame (frame);
4061 else
4062 obj = make_lispy_focus_in (frame);
4063
4064 internal_last_event_frame = frame;
4065 kbd_fetch_ptr = event + 1;
4066 }
4067 else if (event->kind == FOCUS_OUT_EVENT)
4068 {
4069#ifdef HAVE_WINDOW_SYSTEM
4070
4071 Display_Info *di;
4072 Lisp_Object frame = event->frame_or_window;
4073 bool focused = false;
4074
4075 for (di = x_display_list; di && ! focused; di = di->next)
4076 focused = di->x_highlight_frame != 0;
4077
4078 if (!focused)
4079 obj = make_lispy_focus_out (frame);
4080
4081#endif /* HAVE_WINDOW_SYSTEM */
4082
4083 kbd_fetch_ptr = event + 1;
4084 }
4078#ifdef HAVE_DBUS 4085#ifdef HAVE_DBUS
4079 else if (event->kind == DBUS_EVENT) 4086 else if (event->kind == DBUS_EVENT)
4080 { 4087 {
@@ -5555,14 +5562,12 @@ make_lispy_event (struct input_event *event)
5555 5562
5556 /* ELisp manual 2.4b says (x y) are window relative but 5563 /* ELisp manual 2.4b says (x y) are window relative but
5557 code says they are frame-relative. */ 5564 code says they are frame-relative. */
5558 position 5565 position = list4 (event->frame_or_window,
5559 = Fcons (event->frame_or_window, 5566 Qmenu_bar,
5560 Fcons (Qmenu_bar, 5567 Fcons (event->x, event->y),
5561 Fcons (Fcons (event->x, event->y), 5568 make_number (event->timestamp));
5562 Fcons (make_number (event->timestamp), 5569
5563 Qnil)))); 5570 return list2 (item, position);
5564
5565 return Fcons (item, Fcons (position, Qnil));
5566 } 5571 }
5567#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */ 5572#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */
5568 5573
@@ -5581,12 +5586,9 @@ make_lispy_event (struct input_event *event)
5581 portion_whole = Fcons (event->x, event->y); 5586 portion_whole = Fcons (event->x, event->y);
5582 part = *scroll_bar_parts[(int) event->part]; 5587 part = *scroll_bar_parts[(int) event->part];
5583 5588
5584 position 5589 position = list5 (window, Qvertical_scroll_bar,
5585 = Fcons (window, 5590 portion_whole, make_number (event->timestamp),
5586 Fcons (Qvertical_scroll_bar, 5591 part);
5587 Fcons (portion_whole,
5588 Fcons (make_number (event->timestamp),
5589 Fcons (part, Qnil)))));
5590 } 5592 }
5591#endif /* not USE_TOOLKIT_SCROLL_BARS */ 5593#endif /* not USE_TOOLKIT_SCROLL_BARS */
5592 5594
@@ -5734,19 +5736,11 @@ make_lispy_event (struct input_event *event)
5734 &mouse_syms, 5736 &mouse_syms,
5735 ASIZE (mouse_syms)); 5737 ASIZE (mouse_syms));
5736 if (event->modifiers & drag_modifier) 5738 if (event->modifiers & drag_modifier)
5737 return Fcons (head, 5739 return list3 (head, start_pos, position);
5738 Fcons (start_pos,
5739 Fcons (position,
5740 Qnil)));
5741 else if (event->modifiers & (double_modifier | triple_modifier)) 5740 else if (event->modifiers & (double_modifier | triple_modifier))
5742 return Fcons (head, 5741 return list3 (head, position, make_number (double_click_count));
5743 Fcons (position,
5744 Fcons (make_number (double_click_count),
5745 Qnil)));
5746 else 5742 else
5747 return Fcons (head, 5743 return list2 (head, position);
5748 Fcons (position,
5749 Qnil));
5750 } 5744 }
5751 } 5745 }
5752 5746
@@ -5845,14 +5839,9 @@ make_lispy_event (struct input_event *event)
5845 } 5839 }
5846 5840
5847 if (event->modifiers & (double_modifier | triple_modifier)) 5841 if (event->modifiers & (double_modifier | triple_modifier))
5848 return Fcons (head, 5842 return list3 (head, position, make_number (double_click_count));
5849 Fcons (position,
5850 Fcons (make_number (double_click_count),
5851 Qnil)));
5852 else 5843 else
5853 return Fcons (head, 5844 return list2 (head, position);
5854 Fcons (position,
5855 Qnil));
5856 } 5845 }
5857 5846
5858 5847
@@ -5883,12 +5872,8 @@ make_lispy_event (struct input_event *event)
5883 portion_whole = Fcons (event->x, event->y); 5872 portion_whole = Fcons (event->x, event->y);
5884 part = *scroll_bar_parts[(int) event->part]; 5873 part = *scroll_bar_parts[(int) event->part];
5885 5874
5886 position 5875 position = list5 (window, Qvertical_scroll_bar, portion_whole,
5887 = Fcons (window, 5876 make_number (event->timestamp), part);
5888 Fcons (Qvertical_scroll_bar,
5889 Fcons (portion_whole,
5890 Fcons (make_number (event->timestamp),
5891 Fcons (part, Qnil)))));
5892 5877
5893 /* Always treat scroll bar events as clicks. */ 5878 /* Always treat scroll bar events as clicks. */
5894 event->modifiers |= click_modifier; 5879 event->modifiers |= click_modifier;
@@ -5906,7 +5891,7 @@ make_lispy_event (struct input_event *event)
5906 Vlispy_mouse_stem, 5891 Vlispy_mouse_stem,
5907 NULL, &mouse_syms, 5892 NULL, &mouse_syms,
5908 ASIZE (mouse_syms)); 5893 ASIZE (mouse_syms));
5909 return Fcons (head, Fcons (position, Qnil)); 5894 return list2 (head, position);
5910 } 5895 }
5911 5896
5912#endif /* USE_TOOLKIT_SCROLL_BARS */ 5897#endif /* USE_TOOLKIT_SCROLL_BARS */
@@ -5932,10 +5917,7 @@ make_lispy_event (struct input_event *event)
5932 Qdrag_n_drop, Qnil, 5917 Qdrag_n_drop, Qnil,
5933 lispy_drag_n_drop_names, 5918 lispy_drag_n_drop_names,
5934 &drag_n_drop_syms, 1); 5919 &drag_n_drop_syms, 1);
5935 return Fcons (head, 5920 return list3 (head, position, files);
5936 Fcons (position,
5937 Fcons (files,
5938 Qnil)));
5939 } 5921 }
5940 5922
5941#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ 5923#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
@@ -5945,22 +5927,20 @@ make_lispy_event (struct input_event *event)
5945 /* This is the prefix key. We translate this to 5927 /* This is the prefix key. We translate this to
5946 `(menu_bar)' because the code in keyboard.c for menu 5928 `(menu_bar)' because the code in keyboard.c for menu
5947 events, which we use, relies on this. */ 5929 events, which we use, relies on this. */
5948 return Fcons (Qmenu_bar, Qnil); 5930 return list1 (Qmenu_bar);
5949 return event->arg; 5931 return event->arg;
5950#endif 5932#endif
5951 5933
5952 case SELECT_WINDOW_EVENT: 5934 case SELECT_WINDOW_EVENT:
5953 /* Make an event (select-window (WINDOW)). */ 5935 /* Make an event (select-window (WINDOW)). */
5954 return Fcons (Qselect_window, 5936 return list2 (Qselect_window, list1 (event->frame_or_window));
5955 Fcons (Fcons (event->frame_or_window, Qnil),
5956 Qnil));
5957 5937
5958 case TOOL_BAR_EVENT: 5938 case TOOL_BAR_EVENT:
5959 if (EQ (event->arg, event->frame_or_window)) 5939 if (EQ (event->arg, event->frame_or_window))
5960 /* This is the prefix key. We translate this to 5940 /* This is the prefix key. We translate this to
5961 `(tool_bar)' because the code in keyboard.c for tool bar 5941 `(tool_bar)' because the code in keyboard.c for tool bar
5962 events, which we use, relies on this. */ 5942 events, which we use, relies on this. */
5963 return Fcons (Qtool_bar, Qnil); 5943 return list1 (Qtool_bar);
5964 else if (SYMBOLP (event->arg)) 5944 else if (SYMBOLP (event->arg))
5965 return apply_modifiers (event->modifiers, event->arg); 5945 return apply_modifiers (event->modifiers, event->arg);
5966 return event->arg; 5946 return event->arg;
@@ -5992,9 +5972,8 @@ make_lispy_event (struct input_event *event)
5992#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */ 5972#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
5993 5973
5994 case CONFIG_CHANGED_EVENT: 5974 case CONFIG_CHANGED_EVENT:
5995 return Fcons (Qconfig_changed_event, 5975 return list3 (Qconfig_changed_event,
5996 Fcons (event->arg, 5976 event->arg, event->frame_or_window);
5997 Fcons (event->frame_or_window, Qnil)));
5998#ifdef HAVE_GPM 5977#ifdef HAVE_GPM
5999 case GPM_CLICK_EVENT: 5978 case GPM_CLICK_EVENT:
6000 { 5979 {
@@ -6035,24 +6014,13 @@ make_lispy_event (struct input_event *event)
6035 ASIZE (mouse_syms)); 6014 ASIZE (mouse_syms));
6036 6015
6037 if (event->modifiers & drag_modifier) 6016 if (event->modifiers & drag_modifier)
6038 return Fcons (head, 6017 return list3 (head, start_pos, position);
6039 Fcons (start_pos,
6040 Fcons (position,
6041 Qnil)));
6042 else if (event->modifiers & double_modifier) 6018 else if (event->modifiers & double_modifier)
6043 return Fcons (head, 6019 return list3 (head, position, make_number (2));
6044 Fcons (position,
6045 Fcons (make_number (2),
6046 Qnil)));
6047 else if (event->modifiers & triple_modifier) 6020 else if (event->modifiers & triple_modifier)
6048 return Fcons (head, 6021 return list3 (head, position, make_number (3));
6049 Fcons (position,
6050 Fcons (make_number (3),
6051 Qnil)));
6052 else 6022 else
6053 return Fcons (head, 6023 return list2 (head, position);
6054 Fcons (position,
6055 Qnil));
6056 } 6024 }
6057#endif /* HAVE_GPM */ 6025#endif /* HAVE_GPM */
6058 6026
@@ -6072,13 +6040,12 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
6072 Lisp_Object part_sym; 6040 Lisp_Object part_sym;
6073 6041
6074 part_sym = *scroll_bar_parts[(int) part]; 6042 part_sym = *scroll_bar_parts[(int) part];
6075 return Fcons (Qscroll_bar_movement, 6043 return list2 (Qscroll_bar_movement,
6076 Fcons (list5 (bar_window, 6044 list5 (bar_window,
6077 Qvertical_scroll_bar, 6045 Qvertical_scroll_bar,
6078 Fcons (x, y), 6046 Fcons (x, y),
6079 make_number (t), 6047 make_number (t),
6080 part_sym), 6048 part_sym));
6081 Qnil));
6082 } 6049 }
6083 /* Or is it an ordinary mouse movement? */ 6050 /* Or is it an ordinary mouse movement? */
6084 else 6051 else
@@ -6093,7 +6060,18 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
6093static Lisp_Object 6060static Lisp_Object
6094make_lispy_switch_frame (Lisp_Object frame) 6061make_lispy_switch_frame (Lisp_Object frame)
6095{ 6062{
6096 return Fcons (Qswitch_frame, Fcons (frame, Qnil)); 6063 return list2 (Qswitch_frame, frame);
6064}
6065
6066static Lisp_Object
6067make_lispy_focus_in (Lisp_Object frame)
6068{
6069 return list2 (Qfocus_in, frame);
6070}
6071static Lisp_Object
6072make_lispy_focus_out (Lisp_Object frame)
6073{
6074 return list2 (Qfocus_out, frame);
6097} 6075}
6098 6076
6099/* Manipulating modifiers. */ 6077/* Manipulating modifiers. */
@@ -6326,7 +6304,7 @@ parse_modifiers (Lisp_Object symbol)
6326 if (modifiers & ~INTMASK) 6304 if (modifiers & ~INTMASK)
6327 emacs_abort (); 6305 emacs_abort ();
6328 XSETFASTINT (mask, modifiers); 6306 XSETFASTINT (mask, modifiers);
6329 elements = Fcons (unmodified, Fcons (mask, Qnil)); 6307 elements = list2 (unmodified, mask);
6330 6308
6331 /* Cache the parsing results on SYMBOL. */ 6309 /* Cache the parsing results on SYMBOL. */
6332 Fput (symbol, Qevent_symbol_element_mask, 6310 Fput (symbol, Qevent_symbol_element_mask,
@@ -6399,7 +6377,7 @@ apply_modifiers (int modifiers, Lisp_Object base)
6399 the caches: 6377 the caches:
6400 XSETFASTINT (idx, modifiers); 6378 XSETFASTINT (idx, modifiers);
6401 Fput (new_symbol, Qevent_symbol_element_mask, 6379 Fput (new_symbol, Qevent_symbol_element_mask,
6402 Fcons (base, Fcons (idx, Qnil))); 6380 list2 (base, idx));
6403 Fput (new_symbol, Qevent_symbol_elements, 6381 Fput (new_symbol, Qevent_symbol_elements,
6404 Fcons (base, lispy_modifier_list (modifiers))); 6382 Fcons (base, lispy_modifier_list (modifiers)));
6405 Sadly, this is only correct if `base' is indeed a base event, 6383 Sadly, this is only correct if `base' is indeed a base event,
@@ -7551,7 +7529,7 @@ menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dumm
7551 ASET (menu_bar_items_vector, i, key); i++; 7529 ASET (menu_bar_items_vector, i, key); i++;
7552 ASET (menu_bar_items_vector, i, 7530 ASET (menu_bar_items_vector, i,
7553 AREF (item_properties, ITEM_PROPERTY_NAME)); i++; 7531 AREF (item_properties, ITEM_PROPERTY_NAME)); i++;
7554 ASET (menu_bar_items_vector, i, Fcons (item, Qnil)); i++; 7532 ASET (menu_bar_items_vector, i, list1 (item)); i++;
7555 ASET (menu_bar_items_vector, i, make_number (0)); i++; 7533 ASET (menu_bar_items_vector, i, make_number (0)); i++;
7556 menu_bar_items_index = i; 7534 menu_bar_items_index = i;
7557 } 7535 }
@@ -8106,7 +8084,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
8106 8084
8107 /* As an exception, allow old-style menu separators. */ 8085 /* As an exception, allow old-style menu separators. */
8108 if (STRINGP (XCAR (item))) 8086 if (STRINGP (XCAR (item)))
8109 item = Fcons (XCAR (item), Qnil); 8087 item = list1 (XCAR (item));
8110 else if (!EQ (XCAR (item), Qmenu_item) 8088 else if (!EQ (XCAR (item), Qmenu_item)
8111 || (item = XCDR (item), !CONSP (item))) 8089 || (item = XCDR (item), !CONSP (item)))
8112 return 0; 8090 return 0;
@@ -9338,8 +9316,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9338 9316
9339 /* Zap the position in key, so we know that we've 9317 /* Zap the position in key, so we know that we've
9340 expanded it, and don't try to do so again. */ 9318 expanded it, and don't try to do so again. */
9341 POSN_SET_POSN (EVENT_START (key), 9319 POSN_SET_POSN (EVENT_START (key), list1 (posn));
9342 Fcons (posn, Qnil));
9343 9320
9344 mock_input = t + 2; 9321 mock_input = t + 2;
9345 goto replay_sequence; 9322 goto replay_sequence;
@@ -9494,8 +9471,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9494 9471
9495 new_head 9472 new_head
9496 = apply_modifiers (modifiers, XCAR (breakdown)); 9473 = apply_modifiers (modifiers, XCAR (breakdown));
9497 new_click 9474 new_click = list2 (new_head, EVENT_START (key));
9498 = Fcons (new_head, Fcons (EVENT_START (key), Qnil));
9499 9475
9500 /* Look for a binding for this new key. */ 9476 /* Look for a binding for this new key. */
9501 new_binding = follow_key (current_binding, new_click); 9477 new_binding = follow_key (current_binding, new_click);
@@ -10131,7 +10107,7 @@ The file will be closed when Emacs exits. */)
10131 file = Fexpand_file_name (file, Qnil); 10107 file = Fexpand_file_name (file, Qnil);
10132 dribble = emacs_fopen (SSDATA (file), "w"); 10108 dribble = emacs_fopen (SSDATA (file), "w");
10133 if (dribble == 0) 10109 if (dribble == 0)
10134 report_file_error ("Opening dribble", Fcons (file, Qnil)); 10110 report_file_error ("Opening dribble", file);
10135 } 10111 }
10136 return Qnil; 10112 return Qnil;
10137} 10113}
@@ -10196,8 +10172,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10196 reset_all_sys_modes (); 10172 reset_all_sys_modes ();
10197 /* sys_suspend can get an error if it tries to fork a subshell 10173 /* sys_suspend can get an error if it tries to fork a subshell
10198 and the system resources aren't available for that. */ 10174 and the system resources aren't available for that. */
10199 record_unwind_protect ((Lisp_Object (*) (Lisp_Object)) init_all_sys_modes, 10175 record_unwind_protect_void (init_all_sys_modes);
10200 Qnil);
10201 stuff_buffered_input (stuffstring); 10176 stuff_buffered_input (stuffstring);
10202 if (cannot_suspend) 10177 if (cannot_suspend)
10203 sys_subshell (); 10178 sys_subshell ();
@@ -10956,6 +10931,8 @@ static const struct event_head head_table[] = {
10956 {&Qmouse_movement, "mouse-movement", &Qmouse_movement}, 10931 {&Qmouse_movement, "mouse-movement", &Qmouse_movement},
10957 {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement}, 10932 {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement},
10958 {&Qswitch_frame, "switch-frame", &Qswitch_frame}, 10933 {&Qswitch_frame, "switch-frame", &Qswitch_frame},
10934 {&Qfocus_in, "focus-in", &Qfocus_in},
10935 {&Qfocus_out, "focus-out", &Qfocus_out},
10959 {&Qdelete_frame, "delete-frame", &Qdelete_frame}, 10936 {&Qdelete_frame, "delete-frame", &Qdelete_frame},
10960 {&Qiconify_frame, "iconify-frame", &Qiconify_frame}, 10937 {&Qiconify_frame, "iconify-frame", &Qiconify_frame},
10961 {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible}, 10938 {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible},
@@ -11079,7 +11056,7 @@ syms_of_keyboard (void)
11079 *p->var = intern_c_string (p->name); 11056 *p->var = intern_c_string (p->name);
11080 staticpro (p->var); 11057 staticpro (p->var);
11081 Fput (*p->var, Qevent_kind, *p->kind); 11058 Fput (*p->var, Qevent_kind, *p->kind);
11082 Fput (*p->var, Qevent_symbol_elements, Fcons (*p->var, Qnil)); 11059 Fput (*p->var, Qevent_symbol_elements, list1 (*p->var));
11083 } 11060 }
11084 } 11061 }
11085 11062
@@ -11474,7 +11451,7 @@ and the minor mode maps regardless of `overriding-local-map'. */);
11474 11451
11475 DEFVAR_LISP ("special-event-map", Vspecial_event_map, 11452 DEFVAR_LISP ("special-event-map", Vspecial_event_map,
11476 doc: /* Keymap defining bindings for special events to execute at low level. */); 11453 doc: /* Keymap defining bindings for special events to execute at low level. */);
11477 Vspecial_event_map = Fcons (intern_c_string ("keymap"), Qnil); 11454 Vspecial_event_map = list1 (intern_c_string ("keymap"));
11478 11455
11479 DEFVAR_LISP ("track-mouse", do_mouse_tracking, 11456 DEFVAR_LISP ("track-mouse", do_mouse_tracking,
11480 doc: /* Non-nil means generate motion events for mouse motion. */); 11457 doc: /* Non-nil means generate motion events for mouse motion. */);
@@ -11770,6 +11747,10 @@ keys_of_keyboard (void)
11770 initial_define_lispy_key (Vspecial_event_map, "language-change", 11747 initial_define_lispy_key (Vspecial_event_map, "language-change",
11771 "ignore"); 11748 "ignore");
11772#endif 11749#endif
11750 initial_define_lispy_key (Vspecial_event_map, "focus-in",
11751 "handle-focus-in");
11752 initial_define_lispy_key (Vspecial_event_map, "focus-out",
11753 "handle-focus-out");
11773} 11754}
11774 11755
11775/* Mark the pointers in the kboard objects. 11756/* 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 acd21089655..952991a32d9 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -443,8 +443,7 @@ enum Lisp_Fwd_Type
443 displayed to users. These are Lisp_Save_Value, a Lisp_Misc 443 displayed to users. These are Lisp_Save_Value, a Lisp_Misc
444 subtype; and PVEC_OTHER, a kind of vectorlike object. The former 444 subtype; and PVEC_OTHER, a kind of vectorlike object. The former
445 is suitable for temporarily stashing away pointers and integers in 445 is suitable for temporarily stashing away pointers and integers in
446 a Lisp object (see the existing uses of make_save_value and 446 a Lisp object. The latter is useful for vector-like Lisp objects
447 XSAVE_VALUE). The latter is useful for vector-like Lisp objects
448 that need to be used as part of other objects, but which are never 447 that need to be used as part of other objects, but which are never
449 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for 448 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for
450 an example). 449 an example).
@@ -1851,46 +1850,27 @@ enum Lisp_Save_Type
1851/* Special object used to hold a different values for later use. 1850/* Special object used to hold a different values for later use.
1852 1851
1853 This is mostly used to package C integers and pointers to call 1852 This is mostly used to package C integers and pointers to call
1854 record_unwind_protect. A typical task is to pass just one C object 1853 record_unwind_protect when two or more values need to be saved.
1855 pointer to the unwind function. You should pack an object pointer with 1854 For example:
1856 make_save_pointer and then get it back with XSAVE_POINTER, e.g.:
1857 1855
1858 ... 1856 ...
1859 struct my_data *md = get_my_data (); 1857 struct my_data *md = get_my_data ();
1860 record_unwind_protect (my_unwind, make_save_pointer (md)); 1858 ptrdiff_t mi = get_my_integer ();
1859 record_unwind_protect (my_unwind, make_save_ptr_int (md, mi));
1861 ... 1860 ...
1862 1861
1863 Lisp_Object my_unwind (Lisp_Object arg) 1862 Lisp_Object my_unwind (Lisp_Object arg)
1864 { 1863 {
1865 struct my_data *md = XSAVE_POINTER (arg, 0); 1864 struct my_data *md = XSAVE_POINTER (arg, 0);
1866 ... 1865 ptrdiff_t mi = XSAVE_INTEGER (arg, 1);
1867 }
1868
1869 If you need to pass something else you can use make_save_value,
1870 which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers,
1871 function pointers or Lisp_Objects and conveniently get them back
1872 with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and
1873 XSAVE_OBJECT macros:
1874
1875 ...
1876 struct my_data *md = get_my_data ();
1877 Lisp_Object my_object = get_my_object ();
1878 record_unwind_protect
1879 (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object));
1880 ...
1881
1882 Lisp_Object my_unwind (Lisp_Object arg)
1883 {
1884 struct my_data *md = XSAVE_POINTER (arg, 0);
1885 Lisp_Object my_object = XSAVE_OBJECT (arg, 1);
1886 ... 1866 ...
1887 } 1867 }
1888 1868
1889 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the 1869 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the
1890 saved objects and raise eassert if type of the saved object doesn't match 1870 saved objects and raise eassert if type of the saved object doesn't match
1891 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) 1871 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2)
1892 or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and 1872 and XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and
1893 Lisp_Object was saved in slot 1 of ARG. */ 1873 slot 0 is a pointer. */
1894 1874
1895typedef void (*voidfuncptr) (void); 1875typedef void (*voidfuncptr) (void);
1896 1876
@@ -1900,12 +1880,13 @@ struct Lisp_Save_Value
1900 unsigned gcmarkbit : 1; 1880 unsigned gcmarkbit : 1;
1901 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS); 1881 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
1902 1882
1903 /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of 1883 /* V->data may hold up to SAVE_VALUE_SLOTS entries. The type of
1904 V's Ith entry is given by save_type (V, I). E.g., if save_type 1884 V's data entries are determined by V->save_type. E.g., if
1905 (V, 3) == SAVE_INTEGER, V->data[3].integer is in use. 1885 V->save_type == SAVE_TYPE_PTR_OBJ, V->data[0] is a pointer,
1886 V->data[1] is an integer, and V's other data entries are unused.
1906 1887
1907 If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of 1888 If V->save_type == SAVE_TYPE_MEMORY, V->data[0].pointer is the address of
1908 a memory area containing DATA[1].integer potential Lisp_Objects. */ 1889 a memory area containing V->data[1].integer potential Lisp_Objects. */
1909 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; 1890 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS;
1910 union { 1891 union {
1911 void *pointer; 1892 void *pointer;
@@ -2775,10 +2756,11 @@ typedef jmp_buf sys_jmp_buf;
2775 used all over the place, needs to be fast, and needs to know the size of 2756 used all over the place, needs to be fast, and needs to know the size of
2776 union specbinding. But only eval.c should access it. */ 2757 union specbinding. But only eval.c should access it. */
2777 2758
2778typedef Lisp_Object (*specbinding_func) (Lisp_Object);
2779
2780enum specbind_tag { 2759enum specbind_tag {
2781 SPECPDL_UNWIND, /* An unwind_protect function. */ 2760 SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */
2761 SPECPDL_UNWIND_PTR, /* Likewise, on void *. */
2762 SPECPDL_UNWIND_INT, /* Likewise, on int. */
2763 SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */
2782 SPECPDL_BACKTRACE, /* An element of the backtrace. */ 2764 SPECPDL_BACKTRACE, /* An element of the backtrace. */
2783 SPECPDL_LET, /* A plain and simple dynamic let-binding. */ 2765 SPECPDL_LET, /* A plain and simple dynamic let-binding. */
2784 /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */ 2766 /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */
@@ -2791,11 +2773,25 @@ union specbinding
2791 ENUM_BF (specbind_tag) kind : CHAR_BIT; 2773 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2792 struct { 2774 struct {
2793 ENUM_BF (specbind_tag) kind : CHAR_BIT; 2775 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2776 void (*func) (Lisp_Object);
2794 Lisp_Object arg; 2777 Lisp_Object arg;
2795 specbinding_func func;
2796 } unwind; 2778 } unwind;
2797 struct { 2779 struct {
2798 ENUM_BF (specbind_tag) kind : CHAR_BIT; 2780 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2781 void (*func) (void *);
2782 void *arg;
2783 } unwind_ptr;
2784 struct {
2785 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2786 void (*func) (int);
2787 int arg;
2788 } unwind_int;
2789 struct {
2790 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2791 void (*func) (void);
2792 } unwind_void;
2793 struct {
2794 ENUM_BF (specbind_tag) kind : CHAR_BIT;
2799 /* `where' is not used in the case of SPECPDL_LET. */ 2795 /* `where' is not used in the case of SPECPDL_LET. */
2800 Lisp_Object symbol, old_value, where; 2796 Lisp_Object symbol, old_value, where;
2801 /* Normally this is unused; but it is set to the symbol's 2797 /* Normally this is unused; but it is set to the symbol's
@@ -3487,7 +3483,7 @@ extern void add_to_log (const char *, Lisp_Object, Lisp_Object);
3487extern void check_message_stack (void); 3483extern void check_message_stack (void);
3488extern void setup_echo_area_for_printing (int); 3484extern void setup_echo_area_for_printing (int);
3489extern bool push_message (void); 3485extern bool push_message (void);
3490extern Lisp_Object pop_message_unwind (Lisp_Object); 3486extern void pop_message_unwind (void);
3491extern Lisp_Object restore_message_unwind (Lisp_Object); 3487extern Lisp_Object restore_message_unwind (Lisp_Object);
3492extern void restore_message (void); 3488extern void restore_message (void);
3493extern Lisp_Object current_message (void); 3489extern Lisp_Object current_message (void);
@@ -3652,8 +3648,16 @@ extern bool abort_on_gc;
3652extern Lisp_Object make_float (double); 3648extern Lisp_Object make_float (double);
3653extern void display_malloc_warning (void); 3649extern void display_malloc_warning (void);
3654extern ptrdiff_t inhibit_garbage_collection (void); 3650extern ptrdiff_t inhibit_garbage_collection (void);
3655extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...); 3651extern Lisp_Object make_save_int_int_int (ptrdiff_t, ptrdiff_t, ptrdiff_t);
3656extern Lisp_Object make_save_pointer (void *); 3652extern Lisp_Object make_save_obj_obj_obj_obj (Lisp_Object, Lisp_Object,
3653 Lisp_Object, Lisp_Object);
3654extern Lisp_Object make_save_ptr (void *);
3655extern Lisp_Object make_save_ptr_int (void *, ptrdiff_t);
3656extern Lisp_Object make_save_ptr_ptr (void *, void *);
3657extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *,
3658 Lisp_Object);
3659extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t);
3660extern void free_save_value (Lisp_Object);
3657extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3661extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
3658extern void free_marker (Lisp_Object); 3662extern void free_marker (Lisp_Object);
3659extern void free_cons (struct Lisp_Cons *); 3663extern void free_cons (struct Lisp_Cons *);
@@ -3811,14 +3815,20 @@ extern Lisp_Object internal_condition_case_n
3811 (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, 3815 (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *,
3812 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); 3816 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
3813extern void specbind (Lisp_Object, Lisp_Object); 3817extern void specbind (Lisp_Object, Lisp_Object);
3814extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object); 3818extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
3819extern void record_unwind_protect_int (void (*) (int), int);
3820extern void record_unwind_protect_ptr (void (*) (void *), void *);
3821extern void record_unwind_protect_void (void (*) (void));
3822extern void record_unwind_protect_nothing (void);
3823extern void clear_unwind_protect (ptrdiff_t);
3824extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
3815extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); 3825extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
3816extern void rebind_for_thread_switch (void); 3826extern void rebind_for_thread_switch (void);
3817extern void unbind_for_thread_switch (void); 3827extern void unbind_for_thread_switch (void);
3818extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); 3828extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
3819extern _Noreturn void verror (const char *, va_list) 3829extern _Noreturn void verror (const char *, va_list)
3820 ATTRIBUTE_FORMAT_PRINTF (1, 0); 3830 ATTRIBUTE_FORMAT_PRINTF (1, 0);
3821extern Lisp_Object un_autoload (Lisp_Object); 3831extern void un_autoload (Lisp_Object);
3822extern Lisp_Object call_debugger (Lisp_Object arg); 3832extern Lisp_Object call_debugger (Lisp_Object arg);
3823extern void init_eval_once (void); 3833extern void init_eval_once (void);
3824extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...); 3834extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
@@ -3826,6 +3836,7 @@ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
3826extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object); 3836extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
3827extern void init_eval (void); 3837extern void init_eval (void);
3828extern void syms_of_eval (void); 3838extern void syms_of_eval (void);
3839extern void unwind_body (Lisp_Object);
3829extern void record_in_backtrace (Lisp_Object function, 3840extern void record_in_backtrace (Lisp_Object function,
3830 Lisp_Object *args, ptrdiff_t nargs); 3841 Lisp_Object *args, ptrdiff_t nargs);
3831extern void mark_specpdl (union specbinding *first, union specbinding *ptr); 3842extern void mark_specpdl (union specbinding *first, union specbinding *ptr);
@@ -3844,8 +3855,8 @@ extern void insert1 (Lisp_Object);
3844extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object); 3855extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
3845extern Lisp_Object save_excursion_save (void); 3856extern Lisp_Object save_excursion_save (void);
3846extern Lisp_Object save_restriction_save (void); 3857extern Lisp_Object save_restriction_save (void);
3847extern Lisp_Object save_excursion_restore (Lisp_Object); 3858extern void save_excursion_restore (Lisp_Object);
3848extern Lisp_Object save_restriction_restore (Lisp_Object); 3859extern void save_restriction_restore (Lisp_Object);
3849extern _Noreturn void time_overflow (void); 3860extern _Noreturn void time_overflow (void);
3850extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); 3861extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
3851extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, 3862extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
@@ -3864,7 +3875,6 @@ extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool,
3864 Lisp_Object, Lisp_Object, Lisp_Object); 3875 Lisp_Object, Lisp_Object, Lisp_Object);
3865extern bool overlay_touches_p (ptrdiff_t); 3876extern bool overlay_touches_p (ptrdiff_t);
3866extern Lisp_Object Vbuffer_alist; 3877extern Lisp_Object Vbuffer_alist;
3867extern Lisp_Object set_buffer_if_live (Lisp_Object);
3868extern Lisp_Object other_buffer_safely (Lisp_Object); 3878extern Lisp_Object other_buffer_safely (Lisp_Object);
3869extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; 3879extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string;
3870extern Lisp_Object get_truename_buffer (Lisp_Object); 3880extern Lisp_Object get_truename_buffer (Lisp_Object);
@@ -3898,8 +3908,9 @@ extern Lisp_Object Qinsert_file_contents;
3898extern Lisp_Object Qfile_name_history; 3908extern Lisp_Object Qfile_name_history;
3899extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); 3909extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
3900EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ 3910EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */
3901extern Lisp_Object close_file_unwind (Lisp_Object); 3911extern void close_file_unwind (int);
3902extern Lisp_Object restore_point_unwind (Lisp_Object); 3912extern void fclose_unwind (void *);
3913extern void restore_point_unwind (Lisp_Object);
3903extern _Noreturn void report_file_errno (const char *, Lisp_Object, int); 3914extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
3904extern _Noreturn void report_file_error (const char *, Lisp_Object); 3915extern _Noreturn void report_file_error (const char *, Lisp_Object);
3905extern bool internal_delete_file (Lisp_Object); 3916extern bool internal_delete_file (Lisp_Object);
@@ -4171,6 +4182,7 @@ extern void init_random (void);
4171extern void emacs_backtrace (int); 4182extern void emacs_backtrace (int);
4172extern _Noreturn void emacs_abort (void) NO_INLINE; 4183extern _Noreturn void emacs_abort (void) NO_INLINE;
4173extern int emacs_open (const char *, int, int); 4184extern int emacs_open (const char *, int, int);
4185extern int emacs_pipe (int[2]);
4174extern int emacs_close (int); 4186extern int emacs_close (int);
4175extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); 4187extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
4176extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); 4188extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t);
@@ -4334,7 +4346,6 @@ extern void init_system_name (void);
4334 4346
4335enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; 4347enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
4336 4348
4337extern Lisp_Object safe_alloca_unwind (Lisp_Object);
4338extern void *record_xmalloc (size_t); 4349extern void *record_xmalloc (size_t);
4339 4350
4340#define USE_SAFE_ALLOCA \ 4351#define USE_SAFE_ALLOCA \
@@ -4358,8 +4369,7 @@ extern void *record_xmalloc (size_t);
4358 { \ 4369 { \
4359 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ 4370 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
4360 sa_must_free = 1; \ 4371 sa_must_free = 1; \
4361 record_unwind_protect (safe_alloca_unwind, \ 4372 record_unwind_protect_ptr (xfree, buf); \
4362 make_save_pointer (buf)); \
4363 } \ 4373 } \
4364 } while (0) 4374 } while (0)
4365 4375
@@ -4384,9 +4394,9 @@ extern void *record_xmalloc (size_t);
4384 { \ 4394 { \
4385 Lisp_Object arg_; \ 4395 Lisp_Object arg_; \
4386 buf = xmalloc ((nelt) * word_size); \ 4396 buf = xmalloc ((nelt) * word_size); \
4387 arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \ 4397 arg_ = make_save_memory (buf, nelt); \
4388 sa_must_free = 1; \ 4398 sa_must_free = 1; \
4389 record_unwind_protect (safe_alloca_unwind, arg_); \ 4399 record_unwind_protect (free_save_value, arg_); \
4390 } \ 4400 } \
4391 else \ 4401 else \
4392 memory_full (SIZE_MAX); \ 4402 memory_full (SIZE_MAX); \
diff --git a/src/lread.c b/src/lread.c
index f0423f166dd..57c7df74127 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,17 @@ Return t if the file exists and loads successfully. */)
1164#endif 1175#endif
1165 } 1176 }
1166 1177
1178 if (fd < 0)
1179 {
1180 /* Pacify older GCC with --enable-gcc-warnings. */
1181 IF_LINT (fd_index = 0);
1182 }
1183 else
1184 {
1185 fd_index = SPECPDL_INDEX ();
1186 record_unwind_protect_int (close_file_unwind, fd);
1187 }
1188
1167 /* Check if we're stuck in a recursive load cycle. 1189 /* Check if we're stuck in a recursive load cycle.
1168 1190
1169 2000-09-21: It's not possible to just check for the file loaded 1191 2000-09-21: It's not possible to just check for the file loaded
@@ -1179,11 +1201,7 @@ Return t if the file exists and loads successfully. */)
1179 Lisp_Object tem; 1201 Lisp_Object tem;
1180 for (tem = Vloads_in_progress; CONSP (tem); tem = XCDR (tem)) 1202 for (tem = Vloads_in_progress; CONSP (tem); tem = XCDR (tem))
1181 if (!NILP (Fequal (found, XCAR (tem))) && (++load_count > 3)) 1203 if (!NILP (Fequal (found, XCAR (tem))) && (++load_count > 3))
1182 { 1204 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); 1205 record_unwind_protect (record_load_unwind, Vloads_in_progress);
1188 Vloads_in_progress = Fcons (found, Vloads_in_progress); 1206 Vloads_in_progress = Fcons (found, Vloads_in_progress);
1189 } 1207 }
@@ -1196,9 +1214,8 @@ Return t if the file exists and loads successfully. */)
1196 1214
1197 /* Get the name for load-history. */ 1215 /* Get the name for load-history. */
1198 hist_file_name = (! NILP (Vpurify_flag) 1216 hist_file_name = (! NILP (Vpurify_flag)
1199 ? Fconcat (2, (tmp[0] = Ffile_name_directory (file), 1217 ? concat2 (Ffile_name_directory (file),
1200 tmp[1] = Ffile_name_nondirectory (found), 1218 Ffile_name_nondirectory (found))
1201 tmp))
1202 : found) ; 1219 : found) ;
1203 1220
1204 version = -1; 1221 version = -1;
@@ -1224,12 +1241,7 @@ Return t if the file exists and loads successfully. */)
1224 { 1241 {
1225 safe_p = 0; 1242 safe_p = 0;
1226 if (!load_dangerous_libraries) 1243 if (!load_dangerous_libraries)
1227 { 1244 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) 1245 else if (!NILP (nomessage) && !force_load_messages)
1234 message_with_string ("File `%s' not compiled in Emacs", found, 1); 1246 message_with_string ("File `%s' not compiled in Emacs", found, 1);
1235 } 1247 }
@@ -1275,7 +1287,10 @@ Return t if the file exists and loads successfully. */)
1275 Lisp_Object val; 1287 Lisp_Object val;
1276 1288
1277 if (fd >= 0) 1289 if (fd >= 0)
1278 emacs_close (fd); 1290 {
1291 emacs_close (fd);
1292 clear_unwind_protect (fd_index);
1293 }
1279 val = call4 (Vload_source_file_function, found, hist_file_name, 1294 val = call4 (Vload_source_file_function, found, hist_file_name,
1280 NILP (noerror) ? Qnil : Qt, 1295 NILP (noerror) ? Qnil : Qt,
1281 (NILP (nomessage) || force_load_messages) ? Qnil : Qt); 1296 (NILP (nomessage) || force_load_messages) ? Qnil : Qt);
@@ -1285,26 +1300,28 @@ Return t if the file exists and loads successfully. */)
1285 1300
1286 GCPRO3 (file, found, hist_file_name); 1301 GCPRO3 (file, found, hist_file_name);
1287 1302
1288#ifdef WINDOWSNT 1303 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 { 1304 {
1295 emacs_close (fd); 1305 /* We somehow got here with fd == -2, meaning the file is deemed
1296 stream = emacs_fopen (SSDATA (efound), fmode); 1306 to be remote. Don't even try to reopen the file locally;
1307 just force a failure. */
1308 stream = NULL;
1309 errno = EINVAL;
1297 } 1310 }
1298 else 1311 else
1299 stream = NULL;
1300#else /* not WINDOWSNT */
1301 stream = fdopen (fd, fmode);
1302#endif /* not WINDOWSNT */
1303 if (stream == 0)
1304 { 1312 {
1313#ifdef WINDOWSNT
1305 emacs_close (fd); 1314 emacs_close (fd);
1306 error ("Failure to create stdio stream for %s", SDATA (file)); 1315 clear_unwind_protect (fd_index);
1316 efound = ENCODE_FILE (found);
1317 stream = emacs_fopen (SSDATA (efound), fmode);
1318#else
1319 stream = fdopen (fd, fmode);
1320#endif
1307 } 1321 }
1322 if (! stream)
1323 report_file_error ("Opening stdio stream", file);
1324 set_unwind_protect_ptr (fd_index, fclose_unwind, stream);
1308 1325
1309 if (! NILP (Vpurify_flag)) 1326 if (! NILP (Vpurify_flag))
1310 Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list); 1327 Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list);
@@ -1323,7 +1340,6 @@ Return t if the file exists and loads successfully. */)
1323 message_with_string ("Loading %s...", file, 1); 1340 message_with_string ("Loading %s...", file, 1);
1324 } 1341 }
1325 1342
1326 record_unwind_protect (load_unwind, make_save_pointer (stream));
1327 specbind (Qload_file_name, found); 1343 specbind (Qload_file_name, found);
1328 specbind (Qinhibit_file_name_operation, Qnil); 1344 specbind (Qinhibit_file_name_operation, Qnil);
1329 specbind (Qload_in_progress, Qt); 1345 specbind (Qload_in_progress, Qt);
@@ -1375,19 +1391,6 @@ Return t if the file exists and loads successfully. */)
1375 1391
1376 return Qt; 1392 return Qt;
1377} 1393}
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 1394
1392static bool 1395static bool
1393complete_filename_p (Lisp_Object pathname) 1396complete_filename_p (Lisp_Object pathname)
@@ -1494,7 +1497,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1494 fn = alloca (fn_size = 100 + want_length); 1497 fn = alloca (fn_size = 100 + want_length);
1495 1498
1496 /* Loop over suffixes. */ 1499 /* Loop over suffixes. */
1497 for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes; 1500 for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
1498 CONSP (tail); tail = XCDR (tail)) 1501 CONSP (tail); tail = XCDR (tail))
1499 { 1502 {
1500 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); 1503 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
@@ -1523,7 +1526,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1523 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1526 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1524 { 1527 {
1525 bool exists; 1528 bool exists;
1526 last_errno = ENOENT;
1527 if (NILP (predicate)) 1529 if (NILP (predicate))
1528 exists = !NILP (Ffile_readable_p (string)); 1530 exists = !NILP (Ffile_readable_p (string));
1529 else 1531 else
@@ -1578,7 +1580,10 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1578 { 1580 {
1579 fd = emacs_open (pfn, O_RDONLY, 0); 1581 fd = emacs_open (pfn, O_RDONLY, 0);
1580 if (fd < 0) 1582 if (fd < 0)
1581 last_errno = errno; 1583 {
1584 if (errno != ENOENT)
1585 last_errno = errno;
1586 }
1582 else 1587 else
1583 { 1588 {
1584 struct stat st; 1589 struct stat st;
@@ -1682,11 +1687,10 @@ build_load_history (Lisp_Object filename, bool entire)
1682 Vload_history); 1687 Vload_history);
1683} 1688}
1684 1689
1685static Lisp_Object 1690static void
1686readevalloop_1 (Lisp_Object old) 1691readevalloop_1 (int old)
1687{ 1692{
1688 load_convert_to_unibyte = ! NILP (old); 1693 load_convert_to_unibyte = old;
1689 return Qnil;
1690} 1694}
1691 1695
1692/* Signal an `end-of-file' error, if possible with file name 1696/* Signal an `end-of-file' error, if possible with file name
@@ -1756,7 +1760,7 @@ readevalloop (Lisp_Object readcharfun,
1756 1760
1757 specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */ 1761 specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */
1758 specbind (Qcurrent_load_list, Qnil); 1762 specbind (Qcurrent_load_list, Qnil);
1759 record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); 1763 record_unwind_protect_int (readevalloop_1, load_convert_to_unibyte);
1760 load_convert_to_unibyte = !NILP (unibyte); 1764 load_convert_to_unibyte = !NILP (unibyte);
1761 1765
1762 /* If lexical binding is active (either because it was specified in 1766 /* If lexical binding is active (either because it was specified in
@@ -1764,8 +1768,8 @@ readevalloop (Lisp_Object readcharfun,
1764 lexical environment, otherwise, turn off lexical binding. */ 1768 lexical environment, otherwise, turn off lexical binding. */
1765 lex_bound = find_symbol_value (Qlexical_binding); 1769 lex_bound = find_symbol_value (Qlexical_binding);
1766 specbind (Qinternal_interpreter_environment, 1770 specbind (Qinternal_interpreter_environment,
1767 NILP (lex_bound) || EQ (lex_bound, Qunbound) 1771 (NILP (lex_bound) || EQ (lex_bound, Qunbound)
1768 ? Qnil : Fcons (Qt, Qnil)); 1772 ? Qnil : list1 (Qt)));
1769 1773
1770 GCPRO4 (sourcename, readfun, start, end); 1774 GCPRO4 (sourcename, readfun, start, end);
1771 1775
@@ -2724,7 +2728,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2724 if (c == '$') 2728 if (c == '$')
2725 return Vload_file_name; 2729 return Vload_file_name;
2726 if (c == '\'') 2730 if (c == '\'')
2727 return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil)); 2731 return list2 (Qfunction, read0 (readcharfun));
2728 /* #:foo is the uninterned symbol named foo. */ 2732 /* #:foo is the uninterned symbol named foo. */
2729 if (c == ':') 2733 if (c == ':')
2730 { 2734 {
@@ -2819,9 +2823,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2819 goto retry; 2823 goto retry;
2820 2824
2821 case '\'': 2825 case '\'':
2822 { 2826 return list2 (Qquote, read0 (readcharfun));
2823 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
2824 }
2825 2827
2826 case '`': 2828 case '`':
2827 { 2829 {
@@ -2851,7 +2853,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2851 value = read0 (readcharfun); 2853 value = read0 (readcharfun);
2852 new_backquote_flag = saved_new_backquote_flag; 2854 new_backquote_flag = saved_new_backquote_flag;
2853 2855
2854 return Fcons (Qbackquote, Fcons (value, Qnil)); 2856 return list2 (Qbackquote, value);
2855 } 2857 }
2856 } 2858 }
2857 case ',': 2859 case ',':
@@ -2889,7 +2891,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2889 } 2891 }
2890 2892
2891 value = read0 (readcharfun); 2893 value = read0 (readcharfun);
2892 return Fcons (comma_type, Fcons (value, Qnil)); 2894 return list2 (comma_type, value);
2893 } 2895 }
2894 else 2896 else
2895 { 2897 {
@@ -3665,7 +3667,7 @@ read_list (bool flag, Lisp_Object readcharfun)
3665 } 3667 }
3666 invalid_syntax ("] in a list"); 3668 invalid_syntax ("] in a list");
3667 } 3669 }
3668 tem = Fcons (elt, Qnil); 3670 tem = list1 (elt);
3669 if (!NILP (tail)) 3671 if (!NILP (tail))
3670 XSETCDR (tail, tem); 3672 XSETCDR (tail, tem);
3671 else 3673 else
@@ -4232,7 +4234,7 @@ init_lread (void)
4232 points to the eventual installed lisp, leim 4234 points to the eventual installed lisp, leim
4233 directories. We should not use those now, even 4235 directories. We should not use those now, even
4234 if they exist, so start over from a clean slate. */ 4236 if they exist, so start over from a clean slate. */
4235 Vload_path = Fcons (tem, Qnil); 4237 Vload_path = list1 (tem);
4236 } 4238 }
4237 } 4239 }
4238 else 4240 else
@@ -4459,8 +4461,8 @@ otherwise to default specified by file `epaths.h' when Emacs was built. */);
4459This list should not include the empty string. 4461This list should not include the empty string.
4460`load' and related functions try to append these suffixes, in order, 4462`load' and related functions try to append these suffixes, in order,
4461to the specified file name if a Lisp suffix is allowed or required. */); 4463to the specified file name if a Lisp suffix is allowed or required. */);
4462 Vload_suffixes = Fcons (build_pure_c_string (".elc"), 4464 Vload_suffixes = list2 (build_pure_c_string (".elc"),
4463 Fcons (build_pure_c_string (".el"), Qnil)); 4465 build_pure_c_string (".el"));
4464 DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes, 4466 DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes,
4465 doc: /* List of suffixes that indicate representations of \ 4467 doc: /* List of suffixes that indicate representations of \
4466the same file. 4468the same file.
@@ -4474,7 +4476,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 4476in order to do so. However, if you want to customize which suffixes
4475the loading functions recognize as compression suffixes, you should 4477the loading functions recognize as compression suffixes, you should
4476customize `jka-compr-load-suffixes' rather than the present variable. */); 4478customize `jka-compr-load-suffixes' rather than the present variable. */);
4477 Vload_file_rep_suffixes = Fcons (empty_unibyte_string, Qnil); 4479 Vload_file_rep_suffixes = list1 (empty_unibyte_string);
4478 4480
4479 DEFVAR_BOOL ("load-in-progress", load_in_progress, 4481 DEFVAR_BOOL ("load-in-progress", load_in_progress,
4480 doc: /* Non-nil if inside of `load'. */); 4482 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..61538798337 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));
@@ -4416,6 +4416,7 @@ ns_term_shutdown (int sig)
4416{ 4416{
4417 int type = [theEvent type]; 4417 int type = [theEvent type];
4418 NSWindow *window = [theEvent window]; 4418 NSWindow *window = [theEvent window];
4419
4419/* NSTRACE (sendEvent); */ 4420/* NSTRACE (sendEvent); */
4420/*fprintf (stderr, "received event of type %d\t%d\n", type);*/ 4421/*fprintf (stderr, "received event of type %d\t%d\n", type);*/
4421 4422
@@ -4469,6 +4470,23 @@ ns_term_shutdown (int sig)
4469 } 4470 }
4470 } 4471 }
4471 4472
4473
4474#ifdef NS_IMPL_COCOA
4475 /* If no dialog and none of our frames have focus and it is a move, skip it.
4476 It is a mouse move in an auxillary menu, i.e. on the top right on OSX,
4477 such as Wifi, sound, date or similar.
4478 This prevents "spooky" highlightning in the frame under the menu. */
4479 if (type == NSMouseMoved && [NSApp modalWindow] == nil)
4480 {
4481 struct ns_display_info *di;
4482 BOOL has_focus = NO;
4483 for (di = x_display_list; ! has_focus && di; di = di->next)
4484 has_focus = di->x_focus_frame != 0;
4485 if (! has_focus)
4486 return;
4487 }
4488#endif
4489
4472 [super sendEvent: theEvent]; 4490 [super sendEvent: theEvent];
4473} 4491}
4474 4492
@@ -5746,9 +5764,10 @@ not_in_argv (NSString *arg)
5746/* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ 5764/* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */
5747{ 5765{
5748 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); 5766 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
5767 BOOL is_focus_frame = dpyinfo->x_focus_frame == emacsframe;
5749 NSTRACE (windowDidResignKey); 5768 NSTRACE (windowDidResignKey);
5750 5769
5751 if (dpyinfo->x_focus_frame == emacsframe) 5770 if (is_focus_frame)
5752 dpyinfo->x_focus_frame = 0; 5771 dpyinfo->x_focus_frame = 0;
5753 5772
5754 ns_frame_rehighlight (emacsframe); 5773 ns_frame_rehighlight (emacsframe);
@@ -5761,10 +5780,10 @@ not_in_argv (NSString *arg)
5761 x_set_frame_alpha (emacsframe); 5780 x_set_frame_alpha (emacsframe);
5762 } 5781 }
5763 5782
5764 if (emacs_event) 5783 if (emacs_event && is_focus_frame)
5765 { 5784 {
5766 [self deleteWorkingText]; 5785 [self deleteWorkingText];
5767 emacs_event->kind = FOCUS_IN_EVENT; 5786 emacs_event->kind = FOCUS_OUT_EVENT;
5768 EV_TRAILER ((id)nil); 5787 EV_TRAILER ((id)nil);
5769 } 5788 }
5770} 5789}
diff --git a/src/print.c b/src/print.c
index 01e490dcbad..ec14b7be93c 100644
--- a/src/print.c
+++ b/src/print.c
@@ -199,11 +199,10 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
199/* This is used to restore the saved contents of print_buffer 199/* This is used to restore the saved contents of print_buffer
200 when there is a recursive call to print. */ 200 when there is a recursive call to print. */
201 201
202static Lisp_Object 202static void
203print_unwind (Lisp_Object saved_text) 203print_unwind (Lisp_Object saved_text)
204{ 204{
205 memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text)); 205 memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text));
206 return Qnil;
207} 206}
208 207
209 208
@@ -770,8 +769,7 @@ append to existing target file. */)
770 { 769 {
771 stderr = initial_stderr_stream; 770 stderr = initial_stderr_stream;
772 initial_stderr_stream = NULL; 771 initial_stderr_stream = NULL;
773 report_file_error ("Cannot open debugging output stream", 772 report_file_error ("Cannot open debugging output stream", file);
774 Fcons (file, Qnil));
775 } 773 }
776 } 774 }
777 return Qnil; 775 return Qnil;
@@ -1301,7 +1299,7 @@ print_prune_string_charset (Lisp_Object string)
1301 if (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND) 1299 if (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND)
1302 { 1300 {
1303 if (NILP (print_prune_charset_plist)) 1301 if (NILP (print_prune_charset_plist))
1304 print_prune_charset_plist = Fcons (Qcharset, Qnil); 1302 print_prune_charset_plist = list1 (Qcharset);
1305 Fremove_text_properties (make_number (0), 1303 Fremove_text_properties (make_number (0),
1306 make_number (SCHARS (string)), 1304 make_number (SCHARS (string)),
1307 print_prune_charset_plist, string); 1305 print_prune_charset_plist, string);
diff --git a/src/process.c b/src/process.c
index dc37bfe7067..33d8ccbbc35 100644
--- a/src/process.c
+++ b/src/process.c
@@ -785,19 +785,16 @@ status_message (struct Lisp_Process *p)
785 return Fcopy_sequence (Fsymbol_name (symbol)); 785 return Fcopy_sequence (Fsymbol_name (symbol));
786} 786}
787 787
788#ifdef HAVE_PTYS 788enum { PTY_NAME_SIZE = 24 };
789
790/* The file name of the pty opened by allocate_pty. */
791static char pty_name[24];
792 789
793/* Open an available pty, returning a file descriptor. 790/* Open an available pty, returning a file descriptor.
794 Return -1 on failure. 791 Store into PTY_NAME the file name of the terminal corresponding to the pty.
795 The file name of the terminal corresponding to the pty 792 Return -1 on failure. */
796 is left in the variable pty_name. */
797 793
798static int 794static int
799allocate_pty (void) 795allocate_pty (char pty_name[PTY_NAME_SIZE])
800{ 796{
797#ifdef HAVE_PTYS
801 int fd; 798 int fd;
802 799
803#ifdef PTY_ITERATION 800#ifdef PTY_ITERATION
@@ -842,9 +839,9 @@ allocate_pty (void)
842 return fd; 839 return fd;
843 } 840 }
844 } 841 }
842#endif /* HAVE_PTYS */
845 return -1; 843 return -1;
846} 844}
847#endif /* HAVE_PTYS */
848 845
849static Lisp_Object 846static Lisp_Object
850make_process (Lisp_Object name) 847make_process (Lisp_Object name)
@@ -1008,7 +1005,7 @@ nil, indicating the current buffer's process. */)
1008 p->raw_status_new = 0; 1005 p->raw_status_new = 0;
1009 if (NETCONN1_P (p) || SERIALCONN1_P (p)) 1006 if (NETCONN1_P (p) || SERIALCONN1_P (p))
1010 { 1007 {
1011 pset_status (p, Fcons (Qexit, Fcons (make_number (0), Qnil))); 1008 pset_status (p, list2 (Qexit, make_number (0)));
1012 p->tick = ++process_tick; 1009 p->tick = ++process_tick;
1013 status_notify (p); 1010 status_notify (p);
1014 redisplay_preserve_echo_area (13); 1011 redisplay_preserve_echo_area (13);
@@ -1403,11 +1400,11 @@ list of keywords. */)
1403 if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt)) 1400 if ((!NETCONN_P (process) && !SERIALCONN_P (process)) || EQ (key, Qt))
1404 return contact; 1401 return contact;
1405 if (NILP (key) && NETCONN_P (process)) 1402 if (NILP (key) && NETCONN_P (process))
1406 return Fcons (Fplist_get (contact, QChost), 1403 return list2 (Fplist_get (contact, QChost),
1407 Fcons (Fplist_get (contact, QCservice), Qnil)); 1404 Fplist_get (contact, QCservice));
1408 if (NILP (key) && SERIALCONN_P (process)) 1405 if (NILP (key) && SERIALCONN_P (process))
1409 return Fcons (Fplist_get (contact, QCport), 1406 return list2 (Fplist_get (contact, QCport),
1410 Fcons (Fplist_get (contact, QCspeed), Qnil)); 1407 Fplist_get (contact, QCspeed));
1411 return Fplist_get (contact, key); 1408 return Fplist_get (contact, key);
1412} 1409}
1413 1410
@@ -1530,7 +1527,7 @@ Returns nil if format of ADDRESS is invalid. */)
1530} 1527}
1531 1528
1532DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, 1529DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0,
1533 doc: /* Return a list of all processes. */) 1530 doc: /* Return a list of all processes that are Emacs sub-processes. */)
1534 (void) 1531 (void)
1535{ 1532{
1536 return Fmapcar (Qcdr, Vprocess_alist); 1533 return Fmapcar (Qcdr, Vprocess_alist);
@@ -1538,7 +1535,7 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0,
1538 1535
1539/* Starting asynchronous inferior processes. */ 1536/* Starting asynchronous inferior processes. */
1540 1537
1541static Lisp_Object start_process_unwind (Lisp_Object proc); 1538static void start_process_unwind (Lisp_Object proc);
1542 1539
1543DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, 1540DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
1544 doc: /* Start a program in a subprocess. Return the process object for it. 1541 doc: /* Start a program in a subprocess. Return the process object for it.
@@ -1594,7 +1591,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1594 current_dir = expand_and_dir_to_file (current_dir, Qnil); 1591 current_dir = expand_and_dir_to_file (current_dir, Qnil);
1595 if (NILP (Ffile_accessible_directory_p (current_dir))) 1592 if (NILP (Ffile_accessible_directory_p (current_dir)))
1596 report_file_error ("Setting current directory", 1593 report_file_error ("Setting current directory",
1597 Fcons (BVAR (current_buffer, directory), Qnil)); 1594 BVAR (current_buffer, directory));
1598 1595
1599 UNGCPRO; 1596 UNGCPRO;
1600 } 1597 }
@@ -1716,7 +1713,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1716 openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK)); 1713 openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK));
1717 UNGCPRO; 1714 UNGCPRO;
1718 if (NILP (tem)) 1715 if (NILP (tem))
1719 report_file_error ("Searching for program", Fcons (program, Qnil)); 1716 report_file_error ("Searching for program", program);
1720 tem = Fexpand_file_name (tem, Qnil); 1717 tem = Fexpand_file_name (tem, Qnil);
1721 } 1718 }
1722 else 1719 else
@@ -1739,7 +1736,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1739 1736
1740 /* Encode the file name and put it in NEW_ARGV. 1737 /* Encode the file name and put it in NEW_ARGV.
1741 That's where the child will use it to execute the program. */ 1738 That's where the child will use it to execute the program. */
1742 tem = Fcons (ENCODE_FILE (tem), Qnil); 1739 tem = list1 (ENCODE_FILE (tem));
1743 1740
1744 /* Here we encode arguments by the coding system used for sending 1741 /* Here we encode arguments by the coding system used for sending
1745 data to the process. We don't support using different coding 1742 data to the process. We don't support using different coding
@@ -1787,7 +1784,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1787 PROC doesn't have its pid set, then we know someone has signaled 1784 PROC doesn't have its pid set, then we know someone has signaled
1788 an error and the process wasn't started successfully, so we should 1785 an error and the process wasn't started successfully, so we should
1789 remove it from the process list. */ 1786 remove it from the process list. */
1790static Lisp_Object 1787static void
1791start_process_unwind (Lisp_Object proc) 1788start_process_unwind (Lisp_Object proc)
1792{ 1789{
1793 if (!PROCESSP (proc)) 1790 if (!PROCESSP (proc))
@@ -1797,14 +1794,6 @@ start_process_unwind (Lisp_Object proc)
1797 -2 is used for a pty with no process, eg for gdb. */ 1794 -2 is used for a pty with no process, eg for gdb. */
1798 if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2) 1795 if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2)
1799 remove_process (proc); 1796 remove_process (proc);
1800
1801 return Qnil;
1802}
1803
1804static void
1805create_process_1 (struct atimer *timer)
1806{
1807 /* Nothing to do. */
1808} 1797}
1809 1798
1810 1799
@@ -1820,14 +1809,14 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1820#endif 1809#endif
1821 int forkin, forkout; 1810 int forkin, forkout;
1822 bool pty_flag = 0; 1811 bool pty_flag = 0;
1812 char pty_name[PTY_NAME_SIZE];
1823 Lisp_Object lisp_pty_name = Qnil; 1813 Lisp_Object lisp_pty_name = Qnil;
1824 Lisp_Object encoded_current_dir; 1814 Lisp_Object encoded_current_dir;
1825 1815
1826 inchannel = outchannel = -1; 1816 inchannel = outchannel = -1;
1827 1817
1828#ifdef HAVE_PTYS
1829 if (!NILP (Vprocess_connection_type)) 1818 if (!NILP (Vprocess_connection_type))
1830 outchannel = inchannel = allocate_pty (); 1819 outchannel = inchannel = allocate_pty (pty_name);
1831 1820
1832 if (inchannel >= 0) 1821 if (inchannel >= 0)
1833 { 1822 {
@@ -1846,13 +1835,12 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1846 lisp_pty_name = build_string (pty_name); 1835 lisp_pty_name = build_string (pty_name);
1847 } 1836 }
1848 else 1837 else
1849#endif /* HAVE_PTYS */
1850 { 1838 {
1851 if (pipe2 (sv, O_CLOEXEC) != 0) 1839 if (emacs_pipe (sv) != 0)
1852 report_file_error ("Creating pipe", Qnil); 1840 report_file_error ("Creating pipe", Qnil);
1853 inchannel = sv[0]; 1841 inchannel = sv[0];
1854 forkout = sv[1]; 1842 forkout = sv[1];
1855 if (pipe2 (sv, O_CLOEXEC) != 0) 1843 if (emacs_pipe (sv) != 0)
1856 { 1844 {
1857 int pipe_errno = errno; 1845 int pipe_errno = errno;
1858 emacs_close (inchannel); 1846 emacs_close (inchannel);
@@ -1864,7 +1852,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1864 } 1852 }
1865 1853
1866#ifndef WINDOWSNT 1854#ifndef WINDOWSNT
1867 if (pipe2 (wait_child_setup, O_CLOEXEC) != 0) 1855 if (emacs_pipe (wait_child_setup) != 0)
1868 report_file_error ("Creating pipe", Qnil); 1856 report_file_error ("Creating pipe", Qnil);
1869#endif 1857#endif
1870 1858
@@ -1900,7 +1888,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1900 Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; 1888 Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir;
1901 Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; 1889 Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name;
1902 Lisp_Object volatile process_volatile = process; 1890 Lisp_Object volatile process_volatile = process;
1903 bool volatile pty_flag_volatile = pty_flag;
1904 char **volatile new_argv_volatile = new_argv; 1891 char **volatile new_argv_volatile = new_argv;
1905 int volatile forkin_volatile = forkin; 1892 int volatile forkin_volatile = forkin;
1906 int volatile forkout_volatile = forkout; 1893 int volatile forkout_volatile = forkout;
@@ -1912,12 +1899,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1912 encoded_current_dir = encoded_current_dir_volatile; 1899 encoded_current_dir = encoded_current_dir_volatile;
1913 lisp_pty_name = lisp_pty_name_volatile; 1900 lisp_pty_name = lisp_pty_name_volatile;
1914 process = process_volatile; 1901 process = process_volatile;
1915 pty_flag = pty_flag_volatile;
1916 new_argv = new_argv_volatile; 1902 new_argv = new_argv_volatile;
1917 forkin = forkin_volatile; 1903 forkin = forkin_volatile;
1918 forkout = forkout_volatile; 1904 forkout = forkout_volatile;
1919 wait_child_setup[0] = wait_child_setup_0_volatile; 1905 wait_child_setup[0] = wait_child_setup_0_volatile;
1920 wait_child_setup[1] = wait_child_setup_1_volatile; 1906 wait_child_setup[1] = wait_child_setup_1_volatile;
1907
1908 pty_flag = XPROCESS (process)->pty_flag;
1921 } 1909 }
1922 1910
1923 if (pid == 0) 1911 if (pid == 0)
@@ -1987,15 +1975,15 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1987 if (pty_flag) 1975 if (pty_flag)
1988 { 1976 {
1989 1977
1990 /* I wonder if emacs_close (emacs_open (pty_name, ...)) 1978 /* I wonder if emacs_close (emacs_open (SSDATA (lisp_pty_name), ...))
1991 would work? */ 1979 would work? */
1992 if (xforkin >= 0) 1980 if (xforkin >= 0)
1993 emacs_close (xforkin); 1981 emacs_close (xforkin);
1994 xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0); 1982 xforkout = xforkin = emacs_open (SSDATA (lisp_pty_name), O_RDWR, 0);
1995 1983
1996 if (xforkin < 0) 1984 if (xforkin < 0)
1997 { 1985 {
1998 emacs_perror (pty_name); 1986 emacs_perror (SSDATA (lisp_pty_name));
1999 _exit (EXIT_CANCELED); 1987 _exit (EXIT_CANCELED);
2000 } 1988 }
2001 1989
@@ -2025,7 +2013,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2025 pid = child_setup (xforkin, xforkout, xforkout, 2013 pid = child_setup (xforkin, xforkout, xforkout,
2026 new_argv, 1, encoded_current_dir); 2014 new_argv, 1, encoded_current_dir);
2027#else /* not WINDOWSNT */ 2015#else /* not WINDOWSNT */
2028 emacs_close (wait_child_setup[0]);
2029 child_setup (xforkin, xforkout, xforkout, 2016 child_setup (xforkin, xforkout, xforkout,
2030 new_argv, 1, encoded_current_dir); 2017 new_argv, 1, encoded_current_dir);
2031#endif /* not WINDOWSNT */ 2018#endif /* not WINDOWSNT */
@@ -2042,14 +2029,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2042 unblock_child_signal (); 2029 unblock_child_signal ();
2043 unblock_input (); 2030 unblock_input ();
2044 2031
2032 if (forkin >= 0)
2033 emacs_close (forkin);
2034 if (forkin != forkout && forkout >= 0)
2035 emacs_close (forkout);
2036
2045 if (pid < 0) 2037 if (pid < 0)
2046 { 2038 report_file_errno ("Doing vfork", Qnil, vfork_errno);
2047 if (forkin >= 0)
2048 emacs_close (forkin);
2049 if (forkin != forkout && forkout >= 0)
2050 emacs_close (forkout);
2051 report_file_errno ("Doing vfork", Qnil, vfork_errno);
2052 }
2053 else 2039 else
2054 { 2040 {
2055 /* vfork succeeded. */ 2041 /* vfork succeeded. */
@@ -2058,26 +2044,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2058 register_child (pid, inchannel); 2044 register_child (pid, inchannel);
2059#endif /* WINDOWSNT */ 2045#endif /* WINDOWSNT */
2060 2046
2061 /* If the subfork execv fails, and it exits,
2062 this close hangs. I don't know why.
2063 So have an interrupt jar it loose. */
2064 {
2065 struct atimer *timer;
2066 EMACS_TIME offset = make_emacs_time (1, 0);
2067
2068 stop_polling ();
2069 timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
2070
2071 if (forkin >= 0)
2072 emacs_close (forkin);
2073
2074 cancel_atimer (timer);
2075 start_polling ();
2076 }
2077
2078 if (forkin != forkout && forkout >= 0)
2079 emacs_close (forkout);
2080
2081 pset_tty_name (XPROCESS (process), lisp_pty_name); 2047 pset_tty_name (XPROCESS (process), lisp_pty_name);
2082 2048
2083#ifndef WINDOWSNT 2049#ifndef WINDOWSNT
@@ -2096,17 +2062,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2096 } 2062 }
2097} 2063}
2098 2064
2099void 2065static void
2100create_pty (Lisp_Object process) 2066create_pty (Lisp_Object process)
2101{ 2067{
2068 char pty_name[PTY_NAME_SIZE];
2102 int inchannel, outchannel; 2069 int inchannel, outchannel;
2103 bool pty_flag = 0;
2104 2070
2105 inchannel = outchannel = -1; 2071 inchannel = outchannel = -1;
2106 2072
2107#ifdef HAVE_PTYS
2108 if (!NILP (Vprocess_connection_type)) 2073 if (!NILP (Vprocess_connection_type))
2109 outchannel = inchannel = allocate_pty (); 2074 outchannel = inchannel = allocate_pty (pty_name);
2110 2075
2111 if (inchannel >= 0) 2076 if (inchannel >= 0)
2112 { 2077 {
@@ -2125,37 +2090,29 @@ create_pty (Lisp_Object process)
2125 child_setup_tty (forkout); 2090 child_setup_tty (forkout);
2126#endif /* DONT_REOPEN_PTY */ 2091#endif /* DONT_REOPEN_PTY */
2127#endif /* not USG, or USG_SUBTTY_WORKS */ 2092#endif /* not USG, or USG_SUBTTY_WORKS */
2128 pty_flag = 1;
2129 }
2130#endif /* HAVE_PTYS */
2131 2093
2132 fcntl (inchannel, F_SETFL, O_NONBLOCK); 2094 fcntl (inchannel, F_SETFL, O_NONBLOCK);
2133 fcntl (outchannel, F_SETFL, O_NONBLOCK); 2095 fcntl (outchannel, F_SETFL, O_NONBLOCK);
2134 2096
2135 /* Record this as an active process, with its channels. 2097 /* Record this as an active process, with its channels.
2136 As a result, child_setup will close Emacs's side of the pipes. */ 2098 As a result, child_setup will close Emacs's side of the pipes. */
2137 chan_process[inchannel] = process; 2099 chan_process[inchannel] = process;
2138 XPROCESS (process)->infd = inchannel; 2100 XPROCESS (process)->infd = inchannel;
2139 XPROCESS (process)->outfd = outchannel; 2101 XPROCESS (process)->outfd = outchannel;
2140 2102
2141 /* Previously we recorded the tty descriptor used in the subprocess. 2103 /* Previously we recorded the tty descriptor used in the subprocess.
2142 It was only used for getting the foreground tty process, so now 2104 It was only used for getting the foreground tty process, so now
2143 we just reopen the device (see emacs_get_tty_pgrp) as this is 2105 we just reopen the device (see emacs_get_tty_pgrp) as this is
2144 more portable (see USG_SUBTTY_WORKS above). */ 2106 more portable (see USG_SUBTTY_WORKS above). */
2145 2107
2146 XPROCESS (process)->pty_flag = pty_flag; 2108 XPROCESS (process)->pty_flag = 1;
2147 pset_status (XPROCESS (process), Qrun); 2109 pset_status (XPROCESS (process), Qrun);
2148 setup_process_coding_systems (process); 2110 setup_process_coding_systems (process);
2149 2111
2150 add_process_read_fd (inchannel); 2112 pset_tty_name (XPROCESS (process), build_string (pty_name));
2113 }
2151 2114
2152 XPROCESS (process)->pid = -2; 2115 XPROCESS (process)->pid = -2;
2153#ifdef HAVE_PTYS
2154 if (pty_flag)
2155 pset_tty_name (XPROCESS (process), build_string (pty_name));
2156 else
2157#endif
2158 pset_tty_name (XPROCESS (process), Qnil);
2159} 2116}
2160 2117
2161 2118
@@ -2515,8 +2472,12 @@ set_socket_option (int s, Lisp_Object opt, Lisp_Object val)
2515 } 2472 }
2516 2473
2517 if (ret < 0) 2474 if (ret < 0)
2518 report_file_error ("Cannot set network option", 2475 {
2519 Fcons (opt, Fcons (val, Qnil))); 2476 int setsockopt_errno = errno;
2477 report_file_errno ("Cannot set network option", list2 (opt, val),
2478 setsockopt_errno);
2479 }
2480
2520 return (1 << sopt->optbit); 2481 return (1 << sopt->optbit);
2521} 2482}
2522 2483
@@ -2648,16 +2609,6 @@ usage: (serial-process-configure &rest ARGS) */)
2648 return Qnil; 2609 return Qnil;
2649} 2610}
2650 2611
2651/* Used by make-serial-process to recover from errors. */
2652static Lisp_Object
2653make_serial_process_unwind (Lisp_Object proc)
2654{
2655 if (!PROCESSP (proc))
2656 emacs_abort ();
2657 remove_process (proc);
2658 return Qnil;
2659}
2660
2661DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process, 2612DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process,
2662 0, MANY, 0, 2613 0, MANY, 0,
2663 doc: /* Create and return a serial port process. 2614 doc: /* Create and return a serial port process.
@@ -2763,10 +2714,10 @@ usage: (make-serial-process &rest ARGS) */)
2763 CHECK_STRING (name); 2714 CHECK_STRING (name);
2764 proc = make_process (name); 2715 proc = make_process (name);
2765 specpdl_count = SPECPDL_INDEX (); 2716 specpdl_count = SPECPDL_INDEX ();
2766 record_unwind_protect (make_serial_process_unwind, proc); 2717 record_unwind_protect (remove_process, proc);
2767 p = XPROCESS (proc); 2718 p = XPROCESS (proc);
2768 2719
2769 fd = serial_open (SSDATA (port)); 2720 fd = serial_open (port);
2770 p->infd = fd; 2721 p->infd = fd;
2771 p->outfd = fd; 2722 p->outfd = fd;
2772 if (fd > max_desc) 2723 if (fd > max_desc)
@@ -2789,7 +2740,7 @@ usage: (make-serial-process &rest ARGS) */)
2789 p->kill_without_query = 1; 2740 p->kill_without_query = 1;
2790 if (tem = Fplist_get (contact, QCstop), !NILP (tem)) 2741 if (tem = Fplist_get (contact, QCstop), !NILP (tem))
2791 pset_command (p, Qt); 2742 pset_command (p, Qt);
2792 p->pty_flag = 0; 2743 eassert (! p->pty_flag);
2793 2744
2794 if (!EQ (p->command, Qt)) 2745 if (!EQ (p->command, Qt))
2795 add_non_keyboard_read_fd (fd); 2746 add_non_keyboard_read_fd (fd);
@@ -3196,7 +3147,7 @@ usage: (make-network-process &rest ARGS) */)
3196#ifdef POLL_FOR_INPUT 3147#ifdef POLL_FOR_INPUT
3197 if (socktype != SOCK_DGRAM) 3148 if (socktype != SOCK_DGRAM)
3198 { 3149 {
3199 record_unwind_protect (unwind_stop_other_atimers, Qnil); 3150 record_unwind_protect_void (run_all_atimers);
3200 bind_polling_period (10); 3151 bind_polling_period (10);
3201 } 3152 }
3202#endif 3153#endif
@@ -3356,7 +3307,7 @@ usage: (make-network-process &rest ARGS) */)
3356#endif 3307#endif
3357 3308
3358 /* Make us close S if quit. */ 3309 /* Make us close S if quit. */
3359 record_unwind_protect (close_file_unwind, make_number (s)); 3310 record_unwind_protect_int (close_file_unwind, s);
3360 3311
3361 /* Parse network options in the arg list. 3312 /* Parse network options in the arg list.
3362 We simply ignore anything which isn't a known option (including other keywords). 3313 We simply ignore anything which isn't a known option (including other keywords).
@@ -3447,16 +3398,16 @@ usage: (make-network-process &rest ARGS) */)
3447 if (errno == EINTR) 3398 if (errno == EINTR)
3448 goto retry_select; 3399 goto retry_select;
3449 else 3400 else
3450 report_file_error ("select failed", Qnil); 3401 report_file_error ("Failed select", Qnil);
3451 } 3402 }
3452 eassert (sc > 0); 3403 eassert (sc > 0);
3453 3404
3454 len = sizeof xerrno; 3405 len = sizeof xerrno;
3455 eassert (FD_ISSET (s, &fdset)); 3406 eassert (FD_ISSET (s, &fdset));
3456 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) 3407 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3457 report_file_error ("getsockopt failed", Qnil); 3408 report_file_error ("Failed getsockopt", Qnil);
3458 if (xerrno) 3409 if (xerrno)
3459 report_file_errno ("error during connect", Qnil, xerrno); 3410 report_file_errno ("Failed connect", Qnil, xerrno);
3460 break; 3411 break;
3461 } 3412 }
3462#endif /* !WINDOWSNT */ 3413#endif /* !WINDOWSNT */
@@ -3716,10 +3667,13 @@ format; see the description of ADDRESS in `make-network-process'. */)
3716 ptrdiff_t buf_size = 512; 3667 ptrdiff_t buf_size = 512;
3717 int s; 3668 int s;
3718 Lisp_Object res; 3669 Lisp_Object res;
3670 ptrdiff_t count;
3719 3671
3720 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3672 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3721 if (s < 0) 3673 if (s < 0)
3722 return Qnil; 3674 return Qnil;
3675 count = SPECPDL_INDEX ();
3676 record_unwind_protect_int (close_file_unwind, s);
3723 3677
3724 do 3678 do
3725 { 3679 {
@@ -3735,9 +3689,7 @@ format; see the description of ADDRESS in `make-network-process'. */)
3735 } 3689 }
3736 while (ifconf.ifc_len == buf_size); 3690 while (ifconf.ifc_len == buf_size);
3737 3691
3738 emacs_close (s); 3692 res = unbind_to (count, Qnil);
3739
3740 res = Qnil;
3741 ifreq = ifconf.ifc_req; 3693 ifreq = ifconf.ifc_req;
3742 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) 3694 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len)
3743 { 3695 {
@@ -3862,6 +3814,7 @@ FLAGS is the current flags of the interface. */)
3862 Lisp_Object elt; 3814 Lisp_Object elt;
3863 int s; 3815 int s;
3864 bool any = 0; 3816 bool any = 0;
3817 ptrdiff_t count;
3865#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ 3818#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
3866 && defined HAVE_GETIFADDRS && defined LLADDR) 3819 && defined HAVE_GETIFADDRS && defined LLADDR)
3867 struct ifaddrs *ifap; 3820 struct ifaddrs *ifap;
@@ -3876,6 +3829,8 @@ FLAGS is the current flags of the interface. */)
3876 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3829 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3877 if (s < 0) 3830 if (s < 0)
3878 return Qnil; 3831 return Qnil;
3832 count = SPECPDL_INDEX ();
3833 record_unwind_protect_int (close_file_unwind, s);
3879 3834
3880 elt = Qnil; 3835 elt = Qnil;
3881#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) 3836#if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS)
@@ -3992,9 +3947,7 @@ FLAGS is the current flags of the interface. */)
3992#endif 3947#endif
3993 res = Fcons (elt, res); 3948 res = Fcons (elt, res);
3994 3949
3995 emacs_close (s); 3950 return unbind_to (count, any ? res : Qnil);
3996
3997 return any ? res : Qnil;
3998} 3951}
3999#endif 3952#endif
4000#endif /* defined (HAVE_NET_IF_H) */ 3953#endif /* defined (HAVE_NET_IF_H) */
@@ -4164,6 +4117,7 @@ server_accept_connection (Lisp_Object server, int channel)
4164#endif 4117#endif
4165 } saddr; 4118 } saddr;
4166 socklen_t len = sizeof saddr; 4119 socklen_t len = sizeof saddr;
4120 ptrdiff_t count;
4167 4121
4168 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); 4122 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC);
4169 4123
@@ -4186,6 +4140,9 @@ server_accept_connection (Lisp_Object server, int channel)
4186 return; 4140 return;
4187 } 4141 }
4188 4142
4143 count = SPECPDL_INDEX ();
4144 record_unwind_protect_int (close_file_unwind, s);
4145
4189 connect_counter++; 4146 connect_counter++;
4190 4147
4191 /* Setup a new process to handle the connection. */ 4148 /* Setup a new process to handle the connection. */
@@ -4302,6 +4259,10 @@ server_accept_connection (Lisp_Object server, int channel)
4302 pset_filter (p, ps->filter); 4259 pset_filter (p, ps->filter);
4303 pset_command (p, Qnil); 4260 pset_command (p, Qnil);
4304 p->pid = 0; 4261 p->pid = 0;
4262
4263 /* Discard the unwind protect for closing S. */
4264 specpdl_ptr = specpdl + count;
4265
4305 p->infd = s; 4266 p->infd = s;
4306 p->outfd = s; 4267 p->outfd = s;
4307 pset_status (p, Qrun); 4268 pset_status (p, Qrun);
@@ -4338,12 +4299,11 @@ server_accept_connection (Lisp_Object server, int channel)
4338 build_string ("\n"))); 4299 build_string ("\n")));
4339} 4300}
4340 4301
4341static Lisp_Object 4302static void
4342wait_reading_process_output_unwind (Lisp_Object data) 4303wait_reading_process_output_unwind (int data)
4343{ 4304{
4344 clear_waiting_thread_info (); 4305 clear_waiting_thread_info ();
4345 waiting_for_user_input_p = XINT (data); 4306 waiting_for_user_input_p = data;
4346 return Qnil;
4347} 4307}
4348 4308
4349/* This is here so breakpoints can be put on it. */ 4309/* This is here so breakpoints can be put on it. */
@@ -4425,8 +4385,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4425 if (wait_proc != NULL) 4385 if (wait_proc != NULL)
4426 wait_channel = wait_proc->infd; 4386 wait_channel = wait_proc->infd;
4427 4387
4428 record_unwind_protect (wait_reading_process_output_unwind, 4388 record_unwind_protect_int (wait_reading_process_output_unwind,
4429 make_number (waiting_for_user_input_p)); 4389 waiting_for_user_input_p);
4430 waiting_for_user_input_p = read_kbd; 4390 waiting_for_user_input_p = read_kbd;
4431 4391
4432 if (time_limit < 0) 4392 if (time_limit < 0)
@@ -4791,7 +4751,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4791 else if (xerrno == EBADF) 4751 else if (xerrno == EBADF)
4792 emacs_abort (); 4752 emacs_abort ();
4793 else 4753 else
4794 error ("select error: %s", emacs_strerror (xerrno)); 4754 report_file_errno ("Failed select", Qnil, xerrno);
4795 } 4755 }
4796 4756
4797 if (no_avail) 4757 if (no_avail)
@@ -5284,9 +5244,7 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
5284 sometimes it's simply wrong to wrap (e.g. when called from 5244 sometimes it's simply wrong to wrap (e.g. when called from
5285 accept-process-output). */ 5245 accept-process-output). */
5286 internal_condition_case_1 (read_process_output_call, 5246 internal_condition_case_1 (read_process_output_call,
5287 Fcons (outstream, 5247 list3 (outstream, make_lisp_proc (p), text),
5288 Fcons (make_lisp_proc (p),
5289 Fcons (text, Qnil))),
5290 !NILP (Vdebug_on_error) ? Qnil : Qerror, 5248 !NILP (Vdebug_on_error) ? Qnil : Qerror,
5291 read_process_output_error_handler); 5249 read_process_output_error_handler);
5292 5250
@@ -5456,7 +5414,7 @@ write_queue_push (struct Lisp_Process *p, Lisp_Object input_obj,
5456 if (front) 5414 if (front)
5457 pset_write_queue (p, Fcons (entry, p->write_queue)); 5415 pset_write_queue (p, Fcons (entry, p->write_queue));
5458 else 5416 else
5459 pset_write_queue (p, nconc2 (p->write_queue, Fcons (entry, Qnil))); 5417 pset_write_queue (p, nconc2 (p->write_queue, list1 (entry)));
5460} 5418}
5461 5419
5462/* Remove the first element in the write_queue of process P, put its 5420/* Remove the first element in the write_queue of process P, put its
@@ -5629,7 +5587,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5629 if (rv >= 0) 5587 if (rv >= 0)
5630 written = rv; 5588 written = rv;
5631 else if (errno == EMSGSIZE) 5589 else if (errno == EMSGSIZE)
5632 report_file_error ("sending datagram", Fcons (proc, Qnil)); 5590 report_file_error ("Sending datagram", proc);
5633 } 5591 }
5634 else 5592 else
5635#endif 5593#endif
@@ -5706,7 +5664,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5706 } 5664 }
5707 else 5665 else
5708 /* This is a real error. */ 5666 /* This is a real error. */
5709 report_file_error ("writing to process", Fcons (proc, Qnil)); 5667 report_file_error ("Writing to process", proc);
5710 } 5668 }
5711 cur_buf += written; 5669 cur_buf += written;
5712 cur_len -= written; 5670 cur_len -= written;
@@ -6196,7 +6154,7 @@ process has been transmitted to the serial port. */)
6196 { 6154 {
6197#ifndef WINDOWSNT 6155#ifndef WINDOWSNT
6198 if (tcdrain (XPROCESS (proc)->outfd) != 0) 6156 if (tcdrain (XPROCESS (proc)->outfd) != 0)
6199 error ("tcdrain() failed: %s", emacs_strerror (errno)); 6157 report_file_error ("Failed tcdrain", Qnil);
6200#endif /* not WINDOWSNT */ 6158#endif /* not WINDOWSNT */
6201 /* Do nothing on Windows because writes are blocking. */ 6159 /* Do nothing on Windows because writes are blocking. */
6202 } 6160 }
@@ -6425,8 +6383,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
6425 running_asynch_code = 1; 6383 running_asynch_code = 1;
6426 6384
6427 internal_condition_case_1 (read_process_output_call, 6385 internal_condition_case_1 (read_process_output_call,
6428 Fcons (sentinel, 6386 list3 (sentinel, proc, reason),
6429 Fcons (proc, Fcons (reason, Qnil))),
6430 !NILP (Vdebug_on_error) ? Qnil : Qerror, 6387 !NILP (Vdebug_on_error) ? Qnil : Qerror,
6431 exec_sentinel_error_handler); 6388 exec_sentinel_error_handler);
6432 6389
@@ -6890,7 +6847,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6890 if (xerrno == EINTR) 6847 if (xerrno == EINTR)
6891 FD_ZERO (&waitchannels); 6848 FD_ZERO (&waitchannels);
6892 else 6849 else
6893 error ("select error: %s", emacs_strerror (xerrno)); 6850 report_file_errno ("Failed select", Qnil, xerrno);
6894 } 6851 }
6895 6852
6896 /* Check for keyboard input */ 6853 /* Check for keyboard input */
diff --git a/src/search.c b/src/search.c
index ff47bb2fecf..e1147aca858 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..11a6f4a76ce 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -42,9 +42,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
42#endif 42#endif
43 43
44#ifdef __FreeBSD__ 44#ifdef __FreeBSD__
45#include <sys/user.h> 45/* Sparc/ARM machine/frame.h has 'struct frame' which conflicts with Emacs's
46#include <sys/resource.h> 46 'struct frame', so rename it. */
47#include <math.h> 47# define frame freebsd_frame
48# include <sys/user.h>
49# undef frame
50
51# include <sys/resource.h>
52# include <math.h>
48#endif 53#endif
49 54
50#ifdef WINDOWSNT 55#ifdef WINDOWSNT
@@ -2201,6 +2206,20 @@ emacs_fopen (char const *file, char const *mode)
2201 return fd < 0 ? 0 : fdopen (fd, mode); 2206 return fd < 0 ? 0 : fdopen (fd, mode);
2202} 2207}
2203 2208
2209/* Create a pipe for Emacs use. */
2210
2211int
2212emacs_pipe (int fd[2])
2213{
2214 int result = pipe2 (fd, O_CLOEXEC);
2215 if (! O_CLOEXEC && result == 0)
2216 {
2217 fcntl (fd[0], F_SETFD, FD_CLOEXEC);
2218 fcntl (fd[1], F_SETFD, FD_CLOEXEC);
2219 }
2220 return result;
2221}
2222
2204/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs. 2223/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs.
2205 For the background behind this mess, please see Austin Group defect 529 2224 For the background behind this mess, please see Austin Group defect 529
2206 <http://austingroupbugs.net/view.php?id=529>. */ 2225 <http://austingroupbugs.net/view.php?id=529>. */
@@ -2422,14 +2441,11 @@ safe_strsignal (int code)
2422#ifndef DOS_NT 2441#ifndef DOS_NT
2423/* For make-serial-process */ 2442/* For make-serial-process */
2424int 2443int
2425serial_open (char *port) 2444serial_open (Lisp_Object port)
2426{ 2445{
2427 int fd = emacs_open (port, O_RDWR | O_NOCTTY | O_NONBLOCK, 0); 2446 int fd = emacs_open (SSDATA (port), O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
2428 if (fd < 0) 2447 if (fd < 0)
2429 { 2448 report_file_error ("Opening serial port", port);
2430 error ("Could not open %s: %s",
2431 port, emacs_strerror (errno));
2432 }
2433#ifdef TIOCEXCL 2449#ifdef TIOCEXCL
2434 ioctl (fd, TIOCEXCL, (char *) 0); 2450 ioctl (fd, TIOCEXCL, (char *) 0);
2435#endif 2451#endif
@@ -2477,7 +2493,7 @@ serial_configure (struct Lisp_Process *p,
2477 /* Read port attributes and prepare default configuration. */ 2493 /* Read port attributes and prepare default configuration. */
2478 err = tcgetattr (p->outfd, &attr); 2494 err = tcgetattr (p->outfd, &attr);
2479 if (err != 0) 2495 if (err != 0)
2480 error ("tcgetattr() failed: %s", emacs_strerror (errno)); 2496 report_file_error ("Failed tcgetattr", Qnil);
2481 cfmakeraw (&attr); 2497 cfmakeraw (&attr);
2482#if defined (CLOCAL) 2498#if defined (CLOCAL)
2483 attr.c_cflag |= CLOCAL; 2499 attr.c_cflag |= CLOCAL;
@@ -2494,8 +2510,7 @@ serial_configure (struct Lisp_Process *p,
2494 CHECK_NUMBER (tem); 2510 CHECK_NUMBER (tem);
2495 err = cfsetspeed (&attr, XINT (tem)); 2511 err = cfsetspeed (&attr, XINT (tem));
2496 if (err != 0) 2512 if (err != 0)
2497 error ("cfsetspeed(%"pI"d) failed: %s", XINT (tem), 2513 report_file_error ("Failed cfsetspeed", tem);
2498 emacs_strerror (errno));
2499 childp2 = Fplist_put (childp2, QCspeed, tem); 2514 childp2 = Fplist_put (childp2, QCspeed, tem);
2500 2515
2501 /* Configure bytesize. */ 2516 /* Configure bytesize. */
@@ -2617,7 +2632,7 @@ serial_configure (struct Lisp_Process *p,
2617 /* Activate configuration. */ 2632 /* Activate configuration. */
2618 err = tcsetattr (p->outfd, TCSANOW, &attr); 2633 err = tcsetattr (p->outfd, TCSANOW, &attr);
2619 if (err != 0) 2634 if (err != 0)
2620 error ("tcsetattr() failed: %s", emacs_strerror (errno)); 2635 report_file_error ("Failed tcsetattr", Qnil);
2621 2636
2622 childp2 = Fplist_put (childp2, QCsummary, build_string (summary)); 2637 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
2623 pset_childp (p, childp2); 2638 pset_childp (p, childp2);
@@ -2797,11 +2812,12 @@ get_up_time (void)
2797static Lisp_Object 2812static Lisp_Object
2798procfs_ttyname (int rdev) 2813procfs_ttyname (int rdev)
2799{ 2814{
2800 FILE *fdev = NULL; 2815 FILE *fdev;
2801 char name[PATH_MAX]; 2816 char name[PATH_MAX];
2802 2817
2803 block_input (); 2818 block_input ();
2804 fdev = emacs_fopen ("/proc/tty/drivers", "r"); 2819 fdev = emacs_fopen ("/proc/tty/drivers", "r");
2820 name[0] = 0;
2805 2821
2806 if (fdev) 2822 if (fdev)
2807 { 2823 {
@@ -2810,7 +2826,7 @@ procfs_ttyname (int rdev)
2810 char minor[25]; /* 2 32-bit numbers + dash */ 2826 char minor[25]; /* 2 32-bit numbers + dash */
2811 char *endp; 2827 char *endp;
2812 2828
2813 while (!feof (fdev) && !ferror (fdev)) 2829 for (; !feof (fdev) && !ferror (fdev); name[0] = 0)
2814 { 2830 {
2815 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3 2831 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
2816 && major == MAJOR (rdev)) 2832 && major == MAJOR (rdev))
@@ -2839,7 +2855,7 @@ procfs_ttyname (int rdev)
2839static unsigned long 2855static unsigned long
2840procfs_get_total_memory (void) 2856procfs_get_total_memory (void)
2841{ 2857{
2842 FILE *fmem = NULL; 2858 FILE *fmem;
2843 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ 2859 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
2844 2860
2845 block_input (); 2861 block_input ();
@@ -2882,7 +2898,7 @@ system_process_attributes (Lisp_Object pid)
2882 int cmdsize = sizeof default_cmd - 1; 2898 int cmdsize = sizeof default_cmd - 1;
2883 char *cmdline = NULL; 2899 char *cmdline = NULL;
2884 ptrdiff_t cmdline_size; 2900 ptrdiff_t cmdline_size;
2885 unsigned char c; 2901 char c;
2886 printmax_t proc_id; 2902 printmax_t proc_id;
2887 int ppid, pgrp, sess, tty, tpgid, thcount; 2903 int ppid, pgrp, sess, tty, tpgid, thcount;
2888 uid_t uid; 2904 uid_t uid;
@@ -2893,7 +2909,8 @@ system_process_attributes (Lisp_Object pid)
2893 EMACS_TIME tnow, tstart, tboot, telapsed, us_time; 2909 EMACS_TIME tnow, tstart, tboot, telapsed, us_time;
2894 double pcpu, pmem; 2910 double pcpu, pmem;
2895 Lisp_Object attrs = Qnil; 2911 Lisp_Object attrs = Qnil;
2896 Lisp_Object cmd_str, decoded_cmd, tem; 2912 Lisp_Object cmd_str, decoded_cmd;
2913 ptrdiff_t count;
2897 struct gcpro gcpro1, gcpro2; 2914 struct gcpro gcpro1, gcpro2;
2898 2915
2899 CHECK_NUMBER_OR_FLOAT (pid); 2916 CHECK_NUMBER_OR_FLOAT (pid);
@@ -2921,11 +2938,19 @@ system_process_attributes (Lisp_Object pid)
2921 if (gr) 2938 if (gr)
2922 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); 2939 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
2923 2940
2941 count = SPECPDL_INDEX ();
2924 strcpy (fn, procfn); 2942 strcpy (fn, procfn);
2925 procfn_end = fn + strlen (fn); 2943 procfn_end = fn + strlen (fn);
2926 strcpy (procfn_end, "/stat"); 2944 strcpy (procfn_end, "/stat");
2927 fd = emacs_open (fn, O_RDONLY, 0); 2945 fd = emacs_open (fn, O_RDONLY, 0);
2928 if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0) 2946 if (fd < 0)
2947 nread = 0;
2948 else
2949 {
2950 record_unwind_protect_int (close_file_unwind, fd);
2951 nread = emacs_read (fd, procbuf, sizeof procbuf - 1);
2952 }
2953 if (0 < nread)
2929 { 2954 {
2930 procbuf[nread] = '\0'; 2955 procbuf[nread] = '\0';
2931 p = procbuf; 2956 p = procbuf;
@@ -2949,39 +2974,32 @@ system_process_attributes (Lisp_Object pid)
2949 Vlocale_coding_system, 0); 2974 Vlocale_coding_system, 0);
2950 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); 2975 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
2951 2976
2952 if (q) 2977 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt
2978 utime stime cutime cstime priority nice thcount . start vsize rss */
2979 if (q
2980 && (sscanf (q + 2, ("%c %d %d %d %d %d %*u %lu %lu %lu %lu "
2981 "%Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld"),
2982 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
2983 &minflt, &cminflt, &majflt, &cmajflt,
2984 &u_time, &s_time, &cutime, &cstime,
2985 &priority, &niceness, &thcount, &start, &vsize, &rss)
2986 == 20))
2953 { 2987 {
2954 EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint; 2988 char state_str[2];
2955 p = q + 2; 2989 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 */ 2990 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", 2991 attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
2958 &c, &ppid, &pgrp, &sess, &tty, &tpgid, 2992 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid)), attrs);
2959 &minflt, &cminflt, &majflt, &cmajflt, 2993 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp)), attrs);
2960 &u_time, &s_time, &cutime, &cstime, 2994 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); 2995 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
2980 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs); 2996 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid)), attrs);
2981 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); 2997 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
2982 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); 2998 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
2983 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs); 2999 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)),
2984 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs); 3000 attrs);
3001 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)),
3002 attrs);
2985 clocks_per_sec = sysconf (_SC_CLK_TCK); 3003 clocks_per_sec = sysconf (_SC_CLK_TCK);
2986 if (clocks_per_sec < 0) 3004 if (clocks_per_sec < 0)
2987 clocks_per_sec = 100; 3005 clocks_per_sec = 100;
@@ -3002,19 +3020,22 @@ system_process_attributes (Lisp_Object pid)
3002 ltime_from_jiffies (cstime, clocks_per_sec)), 3020 ltime_from_jiffies (cstime, clocks_per_sec)),
3003 attrs); 3021 attrs);
3004 attrs = Fcons (Fcons (Qctime, 3022 attrs = Fcons (Fcons (Qctime,
3005 ltime_from_jiffies (cstime+cutime, clocks_per_sec)), 3023 ltime_from_jiffies (cstime + cutime,
3024 clocks_per_sec)),
3006 attrs); 3025 attrs);
3007 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); 3026 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
3008 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); 3027 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
3009 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs); 3028 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)),
3029 attrs);
3010 tnow = current_emacs_time (); 3030 tnow = current_emacs_time ();
3011 telapsed = get_up_time (); 3031 telapsed = get_up_time ();
3012 tboot = sub_emacs_time (tnow, telapsed); 3032 tboot = sub_emacs_time (tnow, telapsed);
3013 tstart = time_from_jiffies (start, clocks_per_sec); 3033 tstart = time_from_jiffies (start, clocks_per_sec);
3014 tstart = add_emacs_time (tboot, tstart); 3034 tstart = add_emacs_time (tboot, tstart);
3015 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); 3035 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
3016 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs); 3036 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)),
3017 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs); 3037 attrs);
3038 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs);
3018 telapsed = sub_emacs_time (tnow, tstart); 3039 telapsed = sub_emacs_time (tnow, tstart);
3019 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); 3040 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
3020 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); 3041 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
@@ -3029,67 +3050,63 @@ system_process_attributes (Lisp_Object pid)
3029 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs); 3050 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
3030 } 3051 }
3031 } 3052 }
3032 if (fd >= 0) 3053 unbind_to (count, Qnil);
3033 emacs_close (fd);
3034 3054
3035 /* args */ 3055 /* args */
3036 strcpy (procfn_end, "/cmdline"); 3056 strcpy (procfn_end, "/cmdline");
3037 fd = emacs_open (fn, O_RDONLY, 0); 3057 fd = emacs_open (fn, O_RDONLY, 0);
3038 if (fd >= 0) 3058 if (fd >= 0)
3039 { 3059 {
3040 char ch; 3060 ptrdiff_t readsize, nread_incr;
3041 for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++) 3061 record_unwind_protect_int (close_file_unwind, fd);
3062 record_unwind_protect_nothing ();
3063 nread = cmdline_size = 0;
3064
3065 do
3042 { 3066 {
3043 if (emacs_read (fd, &ch, 1) != 1) 3067 cmdline = xpalloc (cmdline, &cmdline_size, 2, STRING_BYTES_BOUND, 1);
3044 break; 3068 set_unwind_protect_ptr (count + 1, xfree, cmdline);
3045 c = ch; 3069
3046 if (c_isspace (c) || c == '\\') 3070 /* Leave room even if every byte needs escaping below. */
3047 cmdline_size++; /* for later quoting, see below */ 3071 readsize = (cmdline_size >> 1) - nread;
3072
3073 nread_incr = emacs_read (fd, cmdline + nread, readsize);
3074 nread += max (0, nread_incr);
3048 } 3075 }
3049 if (cmdline_size) 3076 while (nread_incr == readsize);
3077
3078 if (nread)
3050 { 3079 {
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. */ 3080 /* We don't want trailing null characters. */
3065 for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--) 3081 for (p = cmdline + nread; cmdline < p && !p[-1]; p--)
3066 nread--; 3082 continue;
3067 for (p = cmdline; p < cmdline + nread; p++) 3083
3084 /* Escape-quote whitespace and backslashes. */
3085 q = cmdline + cmdline_size;
3086 while (cmdline < p)
3068 { 3087 {
3069 /* Escape-quote whitespace and backslashes. */ 3088 char c = *--p;
3070 if (c_isspace (*p) || *p == '\\') 3089 *--q = c ? c : ' ';
3071 { 3090 if (c_isspace (c) || c == '\\')
3072 memmove (p + 1, p, nread - (p - cmdline)); 3091 *--q = '\\';
3073 nread++;
3074 *p++ = '\\';
3075 }
3076 else if (*p == '\0')
3077 *p = ' ';
3078 } 3092 }
3079 cmdline_size = nread; 3093
3094 nread = cmdline + cmdline_size - q;
3080 } 3095 }
3081 if (!cmdline_size) 3096
3097 if (!nread)
3082 { 3098 {
3083 cmdline_size = cmdsize + 2; 3099 nread = cmdsize + 2;
3084 cmdline = xmalloc (cmdline_size + 1); 3100 cmdline_size = nread + 1;
3101 q = cmdline = xrealloc (cmdline, cmdline_size);
3102 set_unwind_protect_ptr (count + 1, xfree, cmdline);
3085 sprintf (cmdline, "[%.*s]", cmdsize, cmd); 3103 sprintf (cmdline, "[%.*s]", cmdsize, cmd);
3086 } 3104 }
3087 emacs_close (fd);
3088 /* Command line is encoded in locale-coding-system; decode it. */ 3105 /* Command line is encoded in locale-coding-system; decode it. */
3089 cmd_str = make_unibyte_string (cmdline, cmdline_size); 3106 cmd_str = make_unibyte_string (q, nread);
3090 decoded_cmd = code_convert_string_norecord (cmd_str, 3107 decoded_cmd = code_convert_string_norecord (cmd_str,
3091 Vlocale_coding_system, 0); 3108 Vlocale_coding_system, 0);
3092 xfree (cmdline); 3109 unbind_to (count, Qnil);
3093 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); 3110 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3094 } 3111 }
3095 3112
@@ -3131,8 +3148,9 @@ system_process_attributes (Lisp_Object pid)
3131 uid_t uid; 3148 uid_t uid;
3132 gid_t gid; 3149 gid_t gid;
3133 Lisp_Object attrs = Qnil; 3150 Lisp_Object attrs = Qnil;
3134 Lisp_Object decoded_cmd, tem; 3151 Lisp_Object decoded_cmd;
3135 struct gcpro gcpro1, gcpro2; 3152 struct gcpro gcpro1, gcpro2;
3153 ptrdiff_t count;
3136 3154
3137 CHECK_NUMBER_OR_FLOAT (pid); 3155 CHECK_NUMBER_OR_FLOAT (pid);
3138 CONS_TO_INTEGER (pid, pid_t, proc_id); 3156 CONS_TO_INTEGER (pid, pid_t, proc_id);
@@ -3159,72 +3177,83 @@ system_process_attributes (Lisp_Object pid)
3159 if (gr) 3177 if (gr)
3160 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); 3178 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3161 3179
3180 count = SPECPDL_INDEX ();
3162 strcpy (fn, procfn); 3181 strcpy (fn, procfn);
3163 procfn_end = fn + strlen (fn); 3182 procfn_end = fn + strlen (fn);
3164 strcpy (procfn_end, "/psinfo"); 3183 strcpy (procfn_end, "/psinfo");
3165 fd = emacs_open (fn, O_RDONLY, 0); 3184 fd = emacs_open (fn, O_RDONLY, 0);
3166 if (fd >= 0 3185 if (fd < 0)
3167 && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0)) 3186 nread = 0;
3187 else
3168 { 3188 {
3169 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); 3189 record_unwind_protect (close_file_unwind, fd);
3170 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); 3190 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 } 3191 }
3224 3192
3225 if (fd >= 0) 3193 if (nread == sizeof pinfo)
3226 emacs_close (fd); 3194 {
3195 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
3196 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
3197 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3227 3198
3199 {
3200 char state_str[2];
3201 state_str[0] = pinfo.pr_lwp.pr_sname;
3202 state_str[1] = '\0';
3203 attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs);
3204 }
3205
3206 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3207 need to get a string from it. */
3208
3209 /* FIXME: missing: Qtpgid */
3210
3211 /* FIXME: missing:
3212 Qminflt
3213 Qmajflt
3214 Qcminflt
3215 Qcmajflt
3216
3217 Qutime
3218 Qcutime
3219 Qstime
3220 Qcstime
3221 Are they available? */
3222
3223 attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
3224 attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
3225 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3226 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3227 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)),
3228 attrs);
3229
3230 attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
3231 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)),
3232 attrs);
3233 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)),
3234 attrs);
3235
3236 /* pr_pctcpu and pr_pctmem are unsigned integers in the
3237 range 0 .. 2**15, representing 0.0 .. 1.0. */
3238 attrs = Fcons (Fcons (Qpcpu,
3239 make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)),
3240 attrs);
3241 attrs = Fcons (Fcons (Qpmem,
3242 make_float (100.0 / 0x8000 * pinfo.pr_pctmem)),
3243 attrs);
3244
3245 decoded_cmd = (code_convert_string_norecord
3246 (make_unibyte_string (pinfo.pr_fname,
3247 strlen (pinfo.pr_fname)),
3248 Vlocale_coding_system, 0));
3249 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3250 decoded_cmd = (code_convert_string_norecord
3251 (make_unibyte_string (pinfo.pr_psargs,
3252 strlen (pinfo.pr_psargs)),
3253 Vlocale_coding_system, 0));
3254 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3255 }
3256 unbind_to (count, Qnil);
3228 UNGCPRO; 3257 UNGCPRO;
3229 return attrs; 3258 return attrs;
3230} 3259}
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 0190478c254..b49a7bc706b 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 c9951ca1d52..0b22fd178e4 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 }
@@ -4351,8 +4360,9 @@ w32_read_socket (struct terminal *terminal,
4351 SET_FRAME_VISIBLE (f, 1); 4360 SET_FRAME_VISIBLE (f, 1);
4352 SET_FRAME_ICONIFIED (f, 0); 4361 SET_FRAME_ICONIFIED (f, 0);
4353 SET_FRAME_GARBAGED (f); 4362 SET_FRAME_GARBAGED (f);
4354 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, 4363 if (!f->output_data.w32->asked_for_visible)
4355 SDATA (f->name))); 4364 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
4365 SDATA (f->name)));
4356 4366
4357 /* WM_PAINT serves as MapNotify as well, so report 4367 /* WM_PAINT serves as MapNotify as well, so report
4358 visibility changes properly. */ 4368 visibility changes properly. */
@@ -4810,7 +4820,8 @@ w32_read_socket (struct terminal *terminal,
4810 { 4820 {
4811 bool iconified = FRAME_ICONIFIED_P (f); 4821 bool iconified = FRAME_ICONIFIED_P (f);
4812 4822
4813 SET_FRAME_VISIBLE (f, 1); 4823 if (iconified)
4824 SET_FRAME_VISIBLE (f, 1);
4814 SET_FRAME_ICONIFIED (f, 0); 4825 SET_FRAME_ICONIFIED (f, 0);
4815 4826
4816 /* wait_reading_process_output will notice this 4827 /* wait_reading_process_output will notice this
@@ -5174,7 +5185,10 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
5174 the current matrix is invalid or such, give up. */ 5185 the current matrix is invalid or such, give up. */
5175 cursor_glyph = get_phys_cursor_glyph (w); 5186 cursor_glyph = get_phys_cursor_glyph (w);
5176 if (cursor_glyph == NULL) 5187 if (cursor_glyph == NULL)
5177 return; 5188 {
5189 DeleteObject (hb);
5190 return;
5191 }
5178 5192
5179 /* Compute frame-relative coordinates for phys cursor. */ 5193 /* Compute frame-relative coordinates for phys cursor. */
5180 get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h); 5194 get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
@@ -6117,6 +6131,9 @@ x_iconify_frame (struct frame *f)
6117 /* Simulate the user minimizing the frame. */ 6131 /* Simulate the user minimizing the frame. */
6118 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0); 6132 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
6119 6133
6134 SET_FRAME_VISIBLE (f, 0);
6135 SET_FRAME_ICONIFIED (f, 1);
6136
6120 unblock_input (); 6137 unblock_input ();
6121} 6138}
6122 6139
diff --git a/src/window.c b/src/window.c
index ba9728f09af..bf4ce1dbe39 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3086,18 +3086,18 @@ run_funs (Lisp_Object funs)
3086 call0 (XCAR (funs)); 3086 call0 (XCAR (funs));
3087} 3087}
3088 3088
3089static Lisp_Object 3089static void
3090select_window_norecord (Lisp_Object window) 3090select_window_norecord (Lisp_Object window)
3091{ 3091{
3092 return WINDOW_LIVE_P (window) 3092 if (WINDOW_LIVE_P (window))
3093 ? Fselect_window (window, Qt) : selected_window; 3093 Fselect_window (window, Qt);
3094} 3094}
3095 3095
3096static Lisp_Object 3096static void
3097select_frame_norecord (Lisp_Object frame) 3097select_frame_norecord (Lisp_Object frame)
3098{ 3098{
3099 return FRAME_LIVE_P (XFRAME (frame)) 3099 if (FRAME_LIVE_P (XFRAME (frame)))
3100 ? Fselect_frame (frame, Qt) : selected_frame; 3100 Fselect_frame (frame, Qt);
3101} 3101}
3102 3102
3103void 3103void
@@ -3410,7 +3410,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3410 Note: Both Fselect_window and select_window_norecord may 3410 Note: Both Fselect_window and select_window_norecord may
3411 set-buffer to the buffer displayed in the window, 3411 set-buffer to the buffer displayed in the window,
3412 so we need to save the current buffer. --stef */ 3412 so we need to save the current buffer. --stef */
3413 record_unwind_protect (Fset_buffer, prev_buffer); 3413 record_unwind_protect (restore_buffer, prev_buffer);
3414 record_unwind_protect (select_window_norecord, prev_window); 3414 record_unwind_protect (select_window_norecord, prev_window);
3415 Fselect_window (window, Qt); 3415 Fselect_window (window, Qt);
3416 Fset_buffer (w->contents); 3416 Fset_buffer (w->contents);
@@ -5873,6 +5873,12 @@ the return value is nil. Otherwise the value is t. */)
5873 return (FRAME_LIVE_P (f) ? Qt : Qnil); 5873 return (FRAME_LIVE_P (f) ? Qt : Qnil);
5874} 5874}
5875 5875
5876void
5877restore_window_configuration (Lisp_Object configuration)
5878{
5879 Fset_window_configuration (configuration);
5880}
5881
5876 5882
5877/* If WINDOW is an internal window, recursively delete all child windows 5883/* If WINDOW is an internal window, recursively delete all child windows
5878 reachable via the next and contents slots of WINDOW. Otherwise setup 5884 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 12b294e6800..1da7de5759c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -813,21 +813,20 @@ static void handle_stop (struct it *);
813static void handle_stop_backwards (struct it *, ptrdiff_t); 813static void handle_stop_backwards (struct it *, ptrdiff_t);
814static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0); 814static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
815static void ensure_echo_area_buffers (void); 815static void ensure_echo_area_buffers (void);
816static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object); 816static void unwind_with_echo_area_buffer (Lisp_Object);
817static Lisp_Object with_echo_area_buffer_unwind_data (struct window *); 817static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
818static int with_echo_area_buffer (struct window *, int, 818static int with_echo_area_buffer (struct window *, int,
819 int (*) (ptrdiff_t, Lisp_Object), 819 int (*) (ptrdiff_t, Lisp_Object),
820 ptrdiff_t, Lisp_Object); 820 ptrdiff_t, Lisp_Object);
821static void clear_garbaged_frames (void); 821static void clear_garbaged_frames (void);
822static int current_message_1 (ptrdiff_t, Lisp_Object); 822static int current_message_1 (ptrdiff_t, Lisp_Object);
823static void pop_message (void);
824static int truncate_message_1 (ptrdiff_t, Lisp_Object); 823static int truncate_message_1 (ptrdiff_t, Lisp_Object);
825static void set_message (Lisp_Object); 824static void set_message (Lisp_Object);
826static int set_message_1 (ptrdiff_t, Lisp_Object); 825static int set_message_1 (ptrdiff_t, Lisp_Object);
827static int display_echo_area (struct window *); 826static int display_echo_area (struct window *);
828static int display_echo_area_1 (ptrdiff_t, Lisp_Object); 827static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
829static int resize_mini_window_1 (ptrdiff_t, Lisp_Object); 828static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
830static Lisp_Object unwind_redisplay (Lisp_Object); 829static void unwind_redisplay (void);
831static int string_char_and_length (const unsigned char *, int *); 830static int string_char_and_length (const unsigned char *, int *);
832static struct text_pos display_prop_end (struct it *, Lisp_Object, 831static struct text_pos display_prop_end (struct it *, Lisp_Object,
833 struct text_pos); 832 struct text_pos);
@@ -10146,7 +10145,7 @@ with_echo_area_buffer_unwind_data (struct window *w)
10146/* Restore global state from VECTOR which was created by 10145/* Restore global state from VECTOR which was created by
10147 with_echo_area_buffer_unwind_data. */ 10146 with_echo_area_buffer_unwind_data. */
10148 10147
10149static Lisp_Object 10148static void
10150unwind_with_echo_area_buffer (Lisp_Object vector) 10149unwind_with_echo_area_buffer (Lisp_Object vector)
10151{ 10150{
10152 set_buffer_internal_1 (XBUFFER (AREF (vector, 0))); 10151 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
@@ -10171,7 +10170,6 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
10171 } 10170 }
10172 10171
10173 Vwith_echo_area_save_vector = vector; 10172 Vwith_echo_area_save_vector = vector;
10174 return Qnil;
10175} 10173}
10176 10174
10177 10175
@@ -10570,20 +10568,12 @@ restore_message (void)
10570} 10568}
10571 10569
10572 10570
10573/* Handler for record_unwind_protect calling pop_message. */ 10571/* Handler for unwind-protect calling pop_message. */
10574
10575Lisp_Object
10576pop_message_unwind (Lisp_Object dummy)
10577{
10578 pop_message ();
10579 return Qnil;
10580}
10581
10582/* Pop the top-most entry off Vmessage_stack. */
10583 10572
10584static void 10573void
10585pop_message (void) 10574pop_message_unwind (void)
10586{ 10575{
10576 /* Pop the top-most entry off Vmessage_stack. */
10587 eassert (CONSP (Vmessage_stack)); 10577 eassert (CONSP (Vmessage_stack));
10588 Vmessage_stack = XCDR (Vmessage_stack); 10578 Vmessage_stack = XCDR (Vmessage_stack);
10589} 10579}
@@ -10979,7 +10969,7 @@ format_mode_line_unwind_data (struct frame *target_frame,
10979 return vector; 10969 return vector;
10980} 10970}
10981 10971
10982static Lisp_Object 10972static void
10983unwind_format_mode_line (Lisp_Object vector) 10973unwind_format_mode_line (Lisp_Object vector)
10984{ 10974{
10985 Lisp_Object old_window = AREF (vector, 7); 10975 Lisp_Object old_window = AREF (vector, 7);
@@ -11022,7 +11012,6 @@ unwind_format_mode_line (Lisp_Object vector)
11022 } 11012 }
11023 11013
11024 Vmode_line_unwind_vector = vector; 11014 Vmode_line_unwind_vector = vector;
11025 return Qnil;
11026} 11015}
11027 11016
11028 11017
@@ -11471,7 +11460,7 @@ int last_tool_bar_item;
11471 do_switch_frame. 11460 do_switch_frame.
11472 FIXME: Maybe do_switch_frame should be trimmed down similarly 11461 FIXME: Maybe do_switch_frame should be trimmed down similarly
11473 when `norecord' is set. */ 11462 when `norecord' is set. */
11474static Lisp_Object 11463static void
11475fast_set_selected_frame (Lisp_Object frame) 11464fast_set_selected_frame (Lisp_Object frame)
11476{ 11465{
11477 if (!EQ (selected_frame, frame)) 11466 if (!EQ (selected_frame, frame))
@@ -11479,7 +11468,6 @@ fast_set_selected_frame (Lisp_Object frame)
11479 selected_frame = frame; 11468 selected_frame = frame;
11480 selected_window = XFRAME (frame)->selected_window; 11469 selected_window = XFRAME (frame)->selected_window;
11481 } 11470 }
11482 return Qnil;
11483} 11471}
11484 11472
11485/* Update the tool-bar item list for frame F. This has to be done 11473/* Update the tool-bar item list for frame F. This has to be done
@@ -11999,9 +11987,8 @@ redisplay_tool_bar (struct frame *f)
11999 11987
12000 XSETFRAME (frame, f); 11988 XSETFRAME (frame, f);
12001 Fmodify_frame_parameters (frame, 11989 Fmodify_frame_parameters (frame,
12002 Fcons (Fcons (Qtool_bar_lines, 11990 list1 (Fcons (Qtool_bar_lines,
12003 make_number (nlines)), 11991 make_number (nlines))));
12004 Qnil));
12005 if (WINDOW_TOTAL_LINES (w) != old_height) 11992 if (WINDOW_TOTAL_LINES (w) != old_height)
12006 { 11993 {
12007 clear_glyph_matrix (w->desired_matrix); 11994 clear_glyph_matrix (w->desired_matrix);
@@ -12100,9 +12087,8 @@ redisplay_tool_bar (struct frame *f)
12100 { 12087 {
12101 XSETFRAME (frame, f); 12088 XSETFRAME (frame, f);
12102 Fmodify_frame_parameters (frame, 12089 Fmodify_frame_parameters (frame,
12103 Fcons (Fcons (Qtool_bar_lines, 12090 list1 (Fcons (Qtool_bar_lines,
12104 make_number (nlines)), 12091 make_number (nlines))));
12105 Qnil));
12106 if (WINDOW_TOTAL_LINES (w) != old_height) 12092 if (WINDOW_TOTAL_LINES (w) != old_height)
12107 { 12093 {
12108 clear_glyph_matrix (w->desired_matrix); 12094 clear_glyph_matrix (w->desired_matrix);
@@ -12982,7 +12968,7 @@ redisplay_internal (void)
12982 /* Record a function that clears redisplaying_p 12968 /* Record a function that clears redisplaying_p
12983 when we leave this function. */ 12969 when we leave this function. */
12984 count = SPECPDL_INDEX (); 12970 count = SPECPDL_INDEX ();
12985 record_unwind_protect (unwind_redisplay, selected_frame); 12971 record_unwind_protect_void (unwind_redisplay);
12986 redisplaying_p = 1; 12972 redisplaying_p = 1;
12987 specbind (Qinhibit_free_realized_faces, Qnil); 12973 specbind (Qinhibit_free_realized_faces, Qnil);
12988 12974
@@ -13662,14 +13648,12 @@ redisplay_preserve_echo_area (int from_where)
13662} 13648}
13663 13649
13664 13650
13665/* Function registered with record_unwind_protect in redisplay_internal. 13651/* Function registered with record_unwind_protect in redisplay_internal. */
13666 Clear redisplaying_p. Also select the previously selected frame. */
13667 13652
13668static Lisp_Object 13653static void
13669unwind_redisplay (Lisp_Object old_frame) 13654unwind_redisplay (void)
13670{ 13655{
13671 redisplaying_p = 0; 13656 redisplaying_p = 0;
13672 return Qnil;
13673} 13657}
13674 13658
13675 13659
@@ -15624,10 +15608,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15624 the Y coordinate of the _next_ row, see the definition of 15608 the Y coordinate of the _next_ row, see the definition of
15625 MATRIX_ROW_BOTTOM_Y. */ 15609 MATRIX_ROW_BOTTOM_Y. */
15626 if (w->cursor.vpos < margin + header_line) 15610 if (w->cursor.vpos < margin + header_line)
15627 new_vpos 15611 {
15628 = pixel_margin + (header_line 15612 w->cursor.vpos = -1;
15629 ? CURRENT_HEADER_LINE_HEIGHT (w) 15613 clear_glyph_matrix (w->desired_matrix);
15630 : 0) + frame_line_height; 15614 goto try_to_scroll;
15615 }
15631 else 15616 else
15632 { 15617 {
15633 int window_height = window_box_height (w); 15618 int window_height = window_box_height (w);
@@ -15635,7 +15620,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15635 if (header_line) 15620 if (header_line)
15636 window_height += CURRENT_HEADER_LINE_HEIGHT (w); 15621 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15637 if (w->cursor.y >= window_height - pixel_margin) 15622 if (w->cursor.y >= window_height - pixel_margin)
15638 new_vpos = window_height - pixel_margin; 15623 {
15624 w->cursor.vpos = -1;
15625 clear_glyph_matrix (w->desired_matrix);
15626 goto try_to_scroll;
15627 }
15639 } 15628 }
15640 } 15629 }
15641 15630
@@ -21345,7 +21334,7 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_st
21345 if (NILP (face)) 21334 if (NILP (face))
21346 face = mode_line_string_face; 21335 face = mode_line_string_face;
21347 else 21336 else
21348 face = Fcons (face, Fcons (mode_line_string_face, Qnil)); 21337 face = list2 (face, mode_line_string_face);
21349 props = Fplist_put (props, Qface, face); 21338 props = Fplist_put (props, Qface, face);
21350 } 21339 }
21351 Fadd_text_properties (make_number (0), make_number (len), 21340 Fadd_text_properties (make_number (0), make_number (len),
@@ -21369,8 +21358,8 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_st
21369 if (NILP (face)) 21358 if (NILP (face))
21370 face = mode_line_string_face; 21359 face = mode_line_string_face;
21371 else 21360 else
21372 face = Fcons (face, Fcons (mode_line_string_face, Qnil)); 21361 face = list2 (face, mode_line_string_face);
21373 props = Fcons (Qface, Fcons (face, Qnil)); 21362 props = list2 (Qface, face);
21374 if (copy_string) 21363 if (copy_string)
21375 lisp_string = Fcopy_sequence (lisp_string); 21364 lisp_string = Fcopy_sequence (lisp_string);
21376 } 21365 }
@@ -21484,7 +21473,7 @@ are the selected window and the WINDOW's buffer). */)
21484 mode_line_string_list = Qnil; 21473 mode_line_string_list = Qnil;
21485 mode_line_string_face = face; 21474 mode_line_string_face = face;
21486 mode_line_string_face_prop 21475 mode_line_string_face_prop
21487 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil))); 21476 = NILP (face) ? Qnil : list2 (Qface, face);
21488 } 21477 }
21489 21478
21490 push_kboard (FRAME_KBOARD (it.f)); 21479 push_kboard (FRAME_KBOARD (it.f));
@@ -29234,9 +29223,8 @@ syms_of_xdisp (void)
29234 DEFSYM (Qarrow, "arrow"); 29223 DEFSYM (Qarrow, "arrow");
29235 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces"); 29224 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29236 29225
29237 list_of_error = Fcons (Fcons (intern_c_string ("error"), 29226 list_of_error = list1 (list2 (intern_c_string ("error"),
29238 Fcons (intern_c_string ("void-variable"), Qnil)), 29227 intern_c_string ("void-variable")));
29239 Qnil);
29240 staticpro (&list_of_error); 29228 staticpro (&list_of_error);
29241 29229
29242 DEFSYM (Qlast_arrow_position, "last-arrow-position"); 29230 DEFSYM (Qlast_arrow_position, "last-arrow-position");
@@ -29340,7 +29328,7 @@ See also `overlay-arrow-position'. */);
29340The symbols on this list are examined during redisplay to determine 29328The symbols on this list are examined during redisplay to determine
29341where to display overlay arrows. */); 29329where to display overlay arrows. */);
29342 Voverlay_arrow_variable_list 29330 Voverlay_arrow_variable_list
29343 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil); 29331 = list1 (intern_c_string ("overlay-arrow-position"));
29344 29332
29345 DEFVAR_INT ("scroll-step", emacs_scroll_step, 29333 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29346 doc: /* The number of lines to try scrolling a window by when point moves out. 29334 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 818b69cc41d..b3534871da9 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3435,13 +3435,12 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
3435 /* Don't stop displaying the initial startup message 3435 /* Don't stop displaying the initial startup message
3436 for a switch-frame event we don't need. */ 3436 for a switch-frame event we don't need. */
3437 /* When run as a daemon, Vterminal_frame is always NIL. */ 3437 /* When run as a daemon, Vterminal_frame is always NIL. */
3438 if ((NILP (Vterminal_frame) || EQ (Fdaemonp(), Qt)) 3438 bufp->arg = (((NILP (Vterminal_frame) || EQ (Fdaemonp (), Qt))
3439 && CONSP (Vframe_list) 3439 && CONSP (Vframe_list)
3440 && !NILP (XCDR (Vframe_list))) 3440 && !NILP (XCDR (Vframe_list)))
3441 { 3441 ? Qt : Qnil);
3442 bufp->kind = FOCUS_IN_EVENT; 3442 bufp->kind = FOCUS_IN_EVENT;
3443 XSETFRAME (bufp->frame_or_window, frame); 3443 XSETFRAME (bufp->frame_or_window, frame);
3444 }
3445 } 3444 }
3446 3445
3447 frame->output_data.x->focus_state |= state; 3446 frame->output_data.x->focus_state |= state;
@@ -3459,6 +3458,9 @@ x_focus_changed (int type, int state, struct x_display_info *dpyinfo, struct fra
3459 { 3458 {
3460 dpyinfo->x_focus_event_frame = 0; 3459 dpyinfo->x_focus_event_frame = 0;
3461 x_new_focus_frame (dpyinfo, 0); 3460 x_new_focus_frame (dpyinfo, 0);
3461
3462 bufp->kind = FOCUS_OUT_EVENT;
3463 XSETFRAME (bufp->frame_or_window, frame);
3462 } 3464 }
3463 3465
3464#ifdef HAVE_X_I18N 3466#ifdef HAVE_X_I18N
@@ -8372,9 +8374,9 @@ set_wm_state (Lisp_Object frame, int add, Atom atom, Atom value)
8372 (make_number (add ? 1 : 0), 8374 (make_number (add ? 1 : 0),
8373 Fcons 8375 Fcons
8374 (make_fixnum_or_float (atom), 8376 (make_fixnum_or_float (atom),
8375 value != 0 8377 (value != 0
8376 ? Fcons (make_fixnum_or_float (value), Qnil) 8378 ? list1 (make_fixnum_or_float (value))
8377 : Qnil))); 8379 : Qnil))));
8378} 8380}
8379 8381
8380void 8382void