diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.gdbinit | 10 | ||||
-rw-r--r-- | src/ChangeLog | 366 | ||||
-rw-r--r-- | src/alloc.c | 773 | ||||
-rw-r--r-- | src/atimer.c | 38 | ||||
-rw-r--r-- | src/buffer.c | 7 | ||||
-rw-r--r-- | src/callproc.c | 24 | ||||
-rw-r--r-- | src/charset.c | 2 | ||||
-rw-r--r-- | src/chartab.c | 8 | ||||
-rw-r--r-- | src/coding.c | 4 | ||||
-rw-r--r-- | src/coding.h | 2 | ||||
-rw-r--r-- | src/conf_post.h | 4 | ||||
-rw-r--r-- | src/data.c | 5 | ||||
-rw-r--r-- | src/dired.c | 2 | ||||
-rw-r--r-- | src/doc.c | 2 | ||||
-rw-r--r-- | src/dosfns.c | 4 | ||||
-rw-r--r-- | src/emacs.c | 40 | ||||
-rw-r--r-- | src/fileio.c | 16 | ||||
-rw-r--r-- | src/filelock.c | 10 | ||||
-rw-r--r-- | src/fns.c | 151 | ||||
-rw-r--r-- | src/font.c | 42 | ||||
-rw-r--r-- | src/frame.c | 11 | ||||
-rw-r--r-- | src/fringe.c | 2 | ||||
-rw-r--r-- | src/gnutls.c | 12 | ||||
-rw-r--r-- | src/image.c | 16 | ||||
-rw-r--r-- | src/insdel.c | 23 | ||||
-rw-r--r-- | src/keyboard.c | 61 | ||||
-rw-r--r-- | src/keymap.c | 2 | ||||
-rw-r--r-- | src/keymap.h | 2 | ||||
-rw-r--r-- | src/lisp.h | 80 | ||||
-rw-r--r-- | src/macfont.m | 15 | ||||
-rw-r--r-- | src/minibuf.c | 2 | ||||
-rw-r--r-- | src/msdos.c | 4 | ||||
-rw-r--r-- | src/nsfns.m | 2 | ||||
-rw-r--r-- | src/nsterm.m | 3 | ||||
-rw-r--r-- | src/process.c | 18 | ||||
-rw-r--r-- | src/process.h | 4 | ||||
-rw-r--r-- | src/profiler.c | 2 | ||||
-rw-r--r-- | src/puresize.h | 2 | ||||
-rw-r--r-- | src/search.c | 14 | ||||
-rw-r--r-- | src/sound.c | 12 | ||||
-rw-r--r-- | src/sysdep.c | 27 | ||||
-rw-r--r-- | src/syssignal.h | 2 | ||||
-rw-r--r-- | src/term.c | 19 | ||||
-rw-r--r-- | src/unexcoff.c | 2 | ||||
-rw-r--r-- | src/unexcw.c | 10 | ||||
-rw-r--r-- | src/vm-limit.c | 12 | ||||
-rw-r--r-- | src/w32.c | 16 | ||||
-rw-r--r-- | src/w32fns.c | 158 | ||||
-rw-r--r-- | src/w32notify.c | 4 | ||||
-rw-r--r-- | src/w32proc.c | 11 | ||||
-rw-r--r-- | src/w32term.c | 11 | ||||
-rw-r--r-- | src/xdisp.c | 2 | ||||
-rw-r--r-- | src/xfaces.c | 16 | ||||
-rw-r--r-- | src/xfns.c | 142 | ||||
-rw-r--r-- | src/xgselect.c | 2 | ||||
-rw-r--r-- | src/xsmfns.c | 2 | ||||
-rw-r--r-- | src/xterm.c | 26 | ||||
-rw-r--r-- | src/xterm.h | 2 |
58 files changed, 1345 insertions, 916 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index 715744bc18e..fd2e871ff3d 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -49,7 +49,7 @@ define xgetptr else set $bugfix = $arg0 end - set $ptr = ($bugfix & VALMASK) | DATA_SEG_BITS + set $ptr = $bugfix & VALMASK end define xgetint @@ -1093,8 +1093,8 @@ document xprintsym end define xcoding - set $tmp = (struct Lisp_Hash_Table *) ((Vcoding_system_hash_table & VALMASK) | DATA_SEG_BITS) - set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & VALMASK) | DATA_SEG_BITS) + set $tmp = (struct Lisp_Hash_Table *) (Vcoding_system_hash_table & VALMASK) + set $tmp = (struct Lisp_Vector *) ($tmp->key_and_value & VALMASK) set $name = $tmp->contents[$arg0 * 2] print $name pr @@ -1106,8 +1106,8 @@ document xcoding end define xcharset - set $tmp = (struct Lisp_Hash_Table *) ((Vcharset_hash_table & VALMASK) | DATA_SEG_BITS) - set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & VALMASK) | DATA_SEG_BITS) + set $tmp = (struct Lisp_Hash_Table *) (Vcharset_hash_table & VALMASK) + set $tmp = (struct Lisp_Vector *) ($tmp->key_and_value & VALMASK) p $tmp->contents[charset_table[$arg0].hash_index * 2] pr end diff --git a/src/ChangeLog b/src/ChangeLog index 84760abd019..b3cc3ff32ec 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -64,44 +64,57 @@ Move vfork-related portions under #ifndef MSDOS. (syms_of_callproc): Unify templates of MSDOS and WINDOWSNT. -2014-04-15 Stefan Monnier <monnier@iro.umontreal.ca> +2014-04-16 Stefan Monnier <monnier@iro.umontreal.ca> * buffer.c (Foverlays_at): Add argument `sorted'. -2014-04-14 Eli Zaretskii <eliz@gnu.org> +2014-04-16 Eli Zaretskii <eliz@gnu.org> * insdel.c (invalidate_buffer_caches): When deleting or replacing text, invalidate the bidi_paragraph_cache upto and including the preceding newline. -2014-04-13 Paul Eggert <eggert@cs.ucla.edu> +2014-04-16 Paul Eggert <eggert@cs.ucla.edu> Port to IRIX 6.5 (Bug#9684). - * alloc.c (TAGGABLE_NULL): New constant, - for porting to hosts with nontrivial DATA_SEG_BITS settings. - (next_vector, set_next_vector): Use it. * conf_post.h (INET6) [IRIX6_5]: Define. (HAVE_GETADDRINFO) [IRIX6_5]: Undef. * data.c (BITS_PER_ULL): Don't assume ULLONG_MAX is defined. - * lisp.h (lisp_h_XPNTR): Don't OR in bits that aren't masked out, - for consistency with how TAGGABLE_NULL is computed. -2014-04-13 Eli Zaretskii <eliz@gnu.org> +2014-04-16 Eli Zaretskii <eliz@gnu.org> * keyboard.c (Fopen_dribble_file): Encode the dribble file-name before passing it to system APIs. - * puresize.h (BASE_PURESIZE): Bump by 1K. (Bug#17255) - -2014-04-13 Stefan Monnier <monnier@iro.umontreal.ca> +2014-04-16 Stefan Monnier <monnier@iro.umontreal.ca> * bytecode.c (exec_byte_code): Rework the volatiles. Most importantly, make sure stack.byte_string_start is not de-adjusted by pushhandler. -2014-04-12 Paul Eggert <eggert@cs.ucla.edu> +2014-04-16 Paul Eggert <eggert@cs.ucla.edu> * keyboard.c (Fopen_dribble_file): Avoid some races. (Bug#17187) +2014-04-15 Paul Eggert <eggert@cs.ucla.edu> + + Remove DATA_SEG_BITS. + The DATA_SEG_BITS hack was needed for older 32 bit platforms. + As a result of this change, Emacs won't work on IRIX 6.5 with IRIX + cc, but that platform is so old that SGI itself stopped supporting + it in December 2013. If you still need Emacs on IRIX, please + either compile with GCC and port the undumping code, or run + './configure --with-wide-int'. + * alloc.c (gdb_make_enums_visible): Update to match lisp.h. + * lisp.h (GCTYPEBITS): Move definition up, and switch to the + DEFINE_GDB_SYMBOL_START way to define it. + (NONPOINTER_BITS): New macro. + (EMACS_INT): Use it. + [!USE_LSB_TAG && !WIDE_EMACS_INT]: Fail, and suggest reporting + the problem and/or configuring --with-wide-int. + (USE_LSB_TAG): Simplify, based on above changes. + (gdb_DATA_SEG_BITS): Remove. All uses removed. + * vm-limit.c (exceeds_lisp_ptr): Remove. All uses removed. + 2014-04-12 Eli Zaretskii <eliz@gnu.org> * xdisp.c (move_it_by_lines): If a large portion of buffer text is @@ -112,8 +125,6 @@ * indent.c (Fvertical_motion): Handle correctly the case when the display string is preceded by an empty line. -2014-04-11 Eli Zaretskii <eliz@gnu.org> - * w32.c (sys_umask) <WRITE_USER>: Remove redundant constant, and use S_IWRITE instead. @@ -121,10 +132,33 @@ * keyboard.c (Fopen_dribble_file): Make file private. (Bug#17187) -2014-04-09 Ken Brown <kbrown@cornell.edu> +2014-04-11 Ken Brown <kbrown@cornell.edu> * Makefile.in (EMACS_MANIFEST): Revert last change. +2014-04-10 Daniel Colascione <dancol@dancol.org> + + * puresize.h (BASE_PURESIZE): Increase. + +2014-04-09 Stefan Monnier <monnier@iro.umontreal.ca> + + * keyboard.c (syms_of_keyboard): Make deactivate-mark buffer-local. + + * insdel.c (prepare_to_modify_buffer_1): Cancel lock-file checks and + region handling (and don't call signal_before_change) if + inhibit_modification_hooks is set. + (signal_before_change): Don't check inhibit_modification_hooks any more. + +2014-04-08 Daniel Colascione <dancol@dancol.org> + + * alloc.c (sweep_symbols, mark_object): Assert that symbol + function cells contain valid lisp objects. (Modified version of + patch from Dmitry). + + * alloc.c (detect_suspicious_free): Split actual stack capturing + out into new function for easier breakpoint setting. + (note_suspicious_free): New function. + 2014-04-07 Stefan Monnier <monnier@iro.umontreal.ca> * lisp.h (struct Lisp_Symbol): New bitfield `pinned'. @@ -140,58 +174,183 @@ (Fgarbage_collect): Use it. (gc_sweep): Remove hack made unnecessary. -2014-04-05 Glenn Morris <rgm@gnu.org> +2014-04-07 Glenn Morris <rgm@gnu.org> * keyboard.c (Fopen_dribble_file): Doc tweak. -2014-04-04 Jan Djärv <jan.h.d@swipnet.se> +2014-04-07 Ken Brown <kbrown@cornell.edu> - Backport from trunk. - * nsterm.m (updateFrameSize:): If waiting for the tool bar and tool - bar is zero height, just return (Bug#16976). - (initFrameFromEmacs:): Initialize wait_for_tool_bar. - * nsterm.h (EmacsView): Add wait_for_tool_bar. - * nsmenu.m (update_frame_tool_bar): Return early if view or toolbar - is nil. If waiting for toolbar to complete, force a redraw. - (free_frame_tool_bar): Set wait_for_tool_bar = NO (Bug#16976). + * Makefile.in (EMACS_MANIFEST): Update comment. (Bug#17176) -2014-04-03 Ken Brown <kbrown@cornell.edu> +2014-04-07 Paul Eggert <eggert@cs.ucla.edu> - * Makefile.in (EMACS_MANIFEST): Update comment. (Bug#17176) + * alloc.c: Simplify by removing use of HAVE_EXECINFO_H. + We have a substitute execinfo.h on hosts that lack it. + (suspicious_free_history): Make it EXTERNALLY_VISIBLE so it + isn't optimized away. + +2014-04-05 Paul Eggert <eggert@cs.ucla.edu> + + Prefer 'ARRAYELTS (x)' to 'sizeof x / sizeof *x'. + * alloc.c (memory_full): + * charset.c (syms_of_charset): + * doc.c (Fsnarf_documentation): + * emacs.c (main): + * font.c (BUILD_STYLE_TABLE): + * keyboard.c (make_lispy_event): + * profiler.c (setup_cpu_timer): + * xgselect.c (xg_select): + * xterm.c (record_event, STORE_KEYSYM_FOR_DEBUG): + Use ARRAYELTS. + * font.c (FONT_PROPERTY_TABLE_SIZE): Remove. + Replace the only use with ARRAYELTS (font_property_table). + * xfaces.c (DIM): Remove. All uses replaced by ARRAYELTS. + +2014-04-03 Daniel Colascione <dancol@dancol.org> + + * xterm.c (x_term_init): + * xfns.c (best_xim_style): + * xfaces.c (Fdump_colors): + * w32fns.c (w32_default_color_map): + * w32.c (init_environment, N_ENV_VARS): + * unexcw.c (read_exe_header): + * term.c (term_get_fkeys_1): + * sysdep.c (init_baud_rate): + * nsterm.m (ns_convert_key): + * nsfns.m (get_geometry_from_preferences): + * msdos.c (dos_set_window_size, init_environment): + * macfont.m (mac_font_get_glyph_for_cid) + (macfont_store_descriptor_attributes) + (macfont_create_attributes_with_spec, mac_ctfont_get_glyph_for_cid): + * keyboard.c (command_loop_1, read_menu_command, make_lispy_event) + (NUM_MOD_NAMES, read_key_sequence_vs, Fcurrent_input_mode) + (syms_of_keyboard): + * image.c (xpm_str_to_color_key): + * fringe.c (MAX_STANDARD_FRINGE_BITMAPS): + * frame.c (x_set_frame_parameters): + * fileio.c (Ffile_selinux_context): + * emacs.c (sort_args): + * dosfns.c (msdos_stdcolor_name): + * dired.c (file_attributes): + * chartab.c (uniprop_decoder_count, uniprop_encode_count): + Change expressions of the form sizeof(arr) / sizeof(arr[0]) + to ARRAYELTS (arr). + +2014-04-02 Daniel Colascione <dancol@dancol.org> + + * data.c (Ffset): Abort if we're trying to set a function call to + a dead lisp object. + + * lisp.h (ARRAYELTS): New macro. + + * alloc.c: Include execinfo.h if available. + (SUSPICIOUS_OBJECT_CHECKING): New macro; define unconditionally. + (suspicious_free_record): New structure. + (suspicious_objects, suspicious_object_index) + (suspicious_free_history, suspicious_free_history_index): + New variables. + (find_suspicious_object_in_range, detect_suspicious_free) + (Fsuspicious_object): New functions. + (cleanup_vector): Call find_suspicious_object_in_range. 2014-04-02 Martin Rudalics <rudalics@gmx.at> * xterm.c (x_new_font): Don't calculate non-toolkit scrollbar width from font width (Bug#17163). -2014-03-30 Martin Rudalics <rudalics@gmx.at> - * frame.c (x_set_frame_parameters): Calculate default values of new frame sizes only after all other frame parameters have been processed (Bug#17142). -2014-03-28 Ken Brown <kbrown@cornell.edu> +2014-04-02 Ken Brown <kbrown@cornell.edu> * conf_post.h (SYSTEM_PURESIZE_EXTRA) [CYGWIN]: Set to 10000. (Bug#17112) -2014-03-28 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> +2014-04-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> * xterm.c (x_draw_image_glyph_string): Adjust image background width accordingly when its x position is adjusted. (Bug#17115) +2014-04-02 Dmitry Antipov <dmantipov@yandex.ru> + + * font.c (font_list_entities): Do not add empty vector to font cache. + (font_matching_entity): Likewise. If matching entity is found, insert + 1-item vector with this entity instead of entity itself (Bug#17125). + + * xterm.c (x_term_init) [USE_LUCID]: Fix minor memory leak. + +2014-04-01 Paul Eggert <eggert@cs.ucla.edu> + + * fns.c (validate_subarray): Rename from validate_substring, + since it works for vectors too. New arg ARRAY. Optimize for the + non-nil case. Instead of returning bool, throw an error if out of + range, so that the caller needn't do that. All uses changed. + Report original values if out of range. + (Fsubstring, Fsubstring_no_properties, secure_hash): + Also optimize the case where FROM is 0 or TO is the size. + +2014-03-31 Dmitry Antipov <dmantipov@yandex.ru> + + * search.c (Freplace_match): Use make_specified_string. + * xterm.c, w32term.c (x_set_glyph_string_gc): Use emacs_abort + to catch bogus override face of glyph strings. + * fns.c (Fsubstring, Fsubstring_no_properties, secure_hash): + Move common substring range checking code to... + (validate_substring): ...this function. + +2014-03-31 Jan Djärv <jan.h.d@swipnet.se> + + * nsmenu.m (free_frame_tool_bar): Set wait_for_tool_bar = NO (Bug#16976) + +2014-03-30 Jan Djärv <jan.h.d@swipnet.se> + + * nsterm.m (updateFrameSize:): If waiting for the tool bar and tool + bar is zero height, just return (Bug#16976). + (initFrameFromEmacs:): Initialize wait_for_tool_bar. + + * nsterm.h (EmacsView): Add wait_for_tool_bar. + + * nsmenu.m (update_frame_tool_bar): Return early if view or toolbar + is nil. If waiting for toolbar to complete, force a redraw. + +2014-03-28 Glenn Morris <rgm@gnu.org> + + * emacs.c (emacs_version): Use PACKAGE_VERSION rather than VERSION. + (emacs_bugreport): New variable. + (usage_message): Use PACKAGE_BUGREPORT. + (syms_of_emacs) <report-emacs-bug-address>: New variable. + + * emacs.c (syms_of_emacs) <system-configuration-features>: New var. + +2014-03-27 Paul Eggert <eggert@cs.ucla.edu> + + Port recent signal-related changes to FreeBSD. + Problem reported by Herbert J. Skuhra. + * lisp.h (block_tty_out_signal, unblock_tty_out_signal): + Move decls from here ... + * syssignal.h: ... to here, so that lisp.h doesn't depend on signal.h. + 2014-03-27 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> * w32term.c (x_draw_image_glyph_string): Fix computation of height and width of image background when it is displayed with a 'box' face. (Bug#17115) -2014-03-26 Paul Eggert <eggert@penguin.cs.ucla.edu> +2014-03-27 Paul Eggert <eggert@penguin.cs.ucla.edu> More backward-compatible fix to char-equal core dump (Bug#17011). * editfns.c (Fchar_equal): In unibyte buffers, assume values in range 128-255 are raw bytes. Suggested by Eli Zaretskii. +2014-03-27 Juanma Barranquero <lekktu@gmail.com> + + * image.c (init_svg_functions): When loading SVG-related libraries, + free already loaded libraries if the initialization fails. + (rsvg_handle_set_size_callback): Remove declaration, unused. + +2014-03-26 Paul Eggert <eggert@cs.ucla.edu> + Fix core dump in char-equal (Bug#17011). * editfns.c (Fchar_equal): Do not use MAKE_CHAR_MULTIBYTE in unibyte buffers, as we can't tell whether the characters are @@ -199,7 +358,7 @@ * insdel.c (adjust_markers_for_delete): Remove unused local. -2014-03-24 Barry O'Reilly <gundaetiapo@gmail.com> +2014-03-26 Barry O'Reilly <gundaetiapo@gmail.com> Have (MARKER . ADJUSTMENT) undo records always be immediately after their corresponding (TEXT . POS) record in undo list. @@ -227,38 +386,134 @@ (record_point): at_boundary calculation no longer needs to account for marker adjustments. -2014-03-24 Martin Rudalics <rudalics@gmx.at> +2014-03-26 Martin Rudalics <rudalics@gmx.at> * w32term.c (x_set_window_size): Refine fix from 2014-03-14 (Bug#17077). -2014-03-23 Glenn Morris <rgm@gnu.org> +2014-03-26 Glenn Morris <rgm@gnu.org> * fileio.c (Ffile_symlink_p): Doc fix. (Bug#17073) -2014-03-23 Stefan Monnier <monnier@iro.umontreal.ca> +2014-03-26 Stefan Monnier <monnier@iro.umontreal.ca> * buffer.c (struct sortvec): Add field `spriority'. (compare_overlays): Use it. (sort_overlays): Set it. -2014-03-23 Eli Zaretskii <eliz@gnu.org> +2014-03-26 Eli Zaretskii <eliz@gnu.org> * xdisp.c (redisplay_window): If all previous attempts to find the cursor row failed, try a few alternatives before falling back to the top-most row of the window. Use row_containing_pos. (Bug#17047) -2014-03-22 Daniel Colascione <dancol@dancol.org> +2014-03-26 Juanma Barranquero <lekktu@gmail.com> - * process.c (conv_sockaddr_to_lisp): When extracting the string - names of AF_LOCAL sockets, stop before reading uninitialized - memory. + * image.c (x_bitmap_height, x_bitmap_width) [HAVE_X_WINDOWS]: + * sysdep.c (reset_sigio) [!DOS_NT]: Declare conditionally. + + * keyboard.c (read_decoded_event_from_main_queue): #ifdef out + variables on Windows. + + * w32fns.c (Ffile_system_info): Use parenthesis in and/or expression. + + * w32.c (unsetenv): Remove unused var `retval'. + (emacs_gnutls_pull): Remove unused vars `fdset' and `timeout'. + + * w32notify.c (watch_worker): Remove unnecesary var sleep_result. + (start_watching): Remove unused var `thr'. + + * w32proc.c (sys_spawnve): Comment out unused vars `first', `last'. + (find_child_console): Remove unnecesary var `thread_id'. + + * w32term.c (w32_read_socket): Comment out unused vars `row', `columns'. + (x_focus_frame): #ifdef 0 unused variable `dpyinfo'. + +2014-03-26 Glenn Morris <rgm@gnu.org> + + * filelock.c (Flock_buffer): Doc tweak. + + * buffer.c (Frestore_buffer_modified_p, Fkill_buffer): + * emacs.c (shut_down_emacs): + * fileio.c (Finsert_file_contents, write_region): + * filelock.c (top-level, syms_of_filelock): + * insdel.c (prepare_to_modify_buffer_1): + CLASH_DETECTION is always defined now. + +2014-03-25 Eli Zaretskii <eliz@gnu.org> + + * w32.c (w32_delayed_load): Call DisableThreadLibraryCalls on the + DLL handle, to speed up thread startup. + +2014-03-25 Paul Eggert <eggert@cs.ucla.edu> + + Handle sigmask better with nested signal handlers (Bug#15561). + * atimer.c (sigmask_atimers): Remove. + Remaining use rewritten to use body of this function. + * atimer.c (block_atimers, unblock_atimers): + * callproc.c (block_child_signal, unblock_child_signal): + * sysdep.c (block_tty_out_signal, unblock_tty_out_signal): + New arg OLDSET. All callers changed. + * atimer.c (block_atimers, unblock_atimers): + * callproc.c (block_child_signal, unblock_child_signal): + * keyboard.c (handle_interrupt): + * sound.c (vox_configure, vox_close): + Restore the old signal mask rather than unilaterally clearing bits + from the mask, in case a handler is running within another + handler. All callers changed. + * lisp.h, process.c, process.h, term.c: + Adjust decls and callers to match new API. + * sysdep.c (emacs_sigaction_init): Don't worry about masking SIGFPE; + signal handlers aren't supposed to use floating point anyway. + (handle_arith_signal): Unblock just SIGFPE rather than clearing mask. + +2014-03-23 Daniel Colascione <dancol@dancol.org> + + Split gc_sweep into discrete functions for legibility and better + stack traces. + + * alloc.c (sweep_strings, sweep_vectors): Add NO_INLINE + (sweep_vectors): Fix typo in comment. + (sweep_conses, sweep_floats, sweep_intervals) + (sweep_symbols, sweep_misc, sweep_buffers): New functions. + (gc_sweep): Call new functions, to which existing functionality is + moved. + * fns.c (sweep_weak_hash_tables): Add NO_INLINE. + +2014-03-23 Juanma Barranquero <lekktu@gmail.com> + + * w32fns.c (Fw32_shell_execute): Declare `result' only on Cygwin. + +2014-03-23 Daniel Colascione <dancol@dancol.org> + + * xfns.c (create_frame_xic): Pass XNStatusAttributes to XCreateIC + only if xic_style calls for it. This change allows Emacs to work + with ibus. Also, don't leak resources if create_frame_xic fails, + and stop caching xic_style across different displays. + (supported_xim_styles): Make const. + (best_xim_style): Remove first parameter: it's always just + supported_xim_styles. Change to look at supported_xim_styles + directly. + +2014-03-23 Daniel Colascione <dancol@dancol.org> + + * term.c (init_tty): Rearrange condition for clarity; print + appropriate diagnostic. 2014-03-23 Daniel Colascione <dancol@dancol.org> * process.c (DATAGRAM_CONN_P): Don't underflow datagram_address array. (ASAN caught.) +2014-03-22 Glenn Morris <rgm@gnu.org> + + * callproc.c (init_callproc): In etc, look for NEWS rather than GNU. + +2014-03-22 Daniel Colascione <dancol@dancol.org> + + * process.c (conv_sockaddr_to_lisp): When extracting the string + names of AF_LOCAL sockets, stop before reading uninitialized memory. + 2014-03-21 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> Fix regression introduced by patch for Bug#10500. @@ -271,6 +526,33 @@ constrain frame size in SW_SHOWMAXIMIZED case so we can truly maximize a frame for odd default fonts. +2014-03-21 Glenn Morris <rgm@gnu.org> + + * minibuf.c (history-length): Increase default from 30 to 100. + +2014-03-21 Daniel Colascione <dancol@dancol.org> + + * xterm.c (x_bitmap_icon): Stop reading the icon bitmap from disk + every time we switch to minibuffer. + + * alloc.c (lisp_align_malloc, allocate_string_data) + (allocate_vectorlike): Allow mmap allocation of lisp objects. + (pointers_fit_in_lispobj_p, mmap_lisp_allowed_p): New functions. + +2014-03-21 Eli Zaretskii <eliz@gnu.org> + + * w32fns.c (Fw32_shell_execute) [!CYGWIN]: Use ShellExecuteEx, to + support more "verbs". + +2014-03-21 Daniel Colascione <dancol@dancol.org> + + Always prohibit dumping a dumped Emacs. + + * emacs.c (might_dump): New variable. + (Fdump_emacs): Always prohibit dumping of dumped Emacs. + * lisp.h (might_dump): Declare. + * unexcw.c (unexec): Remove now-redundant multiple-dump detection code. + 2014-03-20 Paul Eggert <eggert@cs.ucla.edu> * doc.c (store_function_docstring): Fix pointer signedness mismatch. diff --git a/src/alloc.c b/src/alloc.c index ccb955a547b..6bee0c990c4 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -47,6 +47,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #endif /* HAVE_WINDOW_SYSTEM */ #include <verify.h> +#include <execinfo.h> /* For backtrace. */ #if (defined ENABLE_CHECKING \ && defined HAVE_VALGRIND_VALGRIND_H \ @@ -192,6 +193,35 @@ static ptrdiff_t pure_bytes_used_non_lisp; const char *pending_malloc_warning; +#if 0 /* Normally, pointer sanity only on request... */ +#ifdef ENABLE_CHECKING +#define SUSPICIOUS_OBJECT_CHECKING 1 +#endif +#endif + +/* ... but unconditionally use SUSPICIOUS_OBJECT_CHECKING while the GC + bug is unresolved. */ +#define SUSPICIOUS_OBJECT_CHECKING 1 + +#ifdef SUSPICIOUS_OBJECT_CHECKING +struct suspicious_free_record +{ + void *suspicious_object; + void *backtrace[128]; +}; +static void *suspicious_objects[32]; +static int suspicious_object_index; +struct suspicious_free_record suspicious_free_history[64] EXTERNALLY_VISIBLE; +static int suspicious_free_history_index; +/* Find the first currently-monitored suspicious pointer in range + [begin,end) or NULL if no such pointer exists. */ +static void *find_suspicious_object_in_range (void *begin, void *end); +static void detect_suspicious_free (void *ptr); +#else +# define find_suspicious_object_in_range(begin, end) NULL +# define detect_suspicious_free(ptr) (void) +#endif + /* Maximum amount of C stack to save when a GC happens. */ #ifndef MAX_SAVE_STACK @@ -403,6 +433,23 @@ XFLOAT_INIT (Lisp_Object f, double n) XFLOAT (f)->u.data = n; } +static bool +pointers_fit_in_lispobj_p (void) +{ + return (UINTPTR_MAX <= VAL_MAX) || USE_LSB_TAG; +} + +static bool +mmap_lisp_allowed_p (void) +{ + /* If we can't store all memory addresses in our lisp objects, it's + risky to let the heap use mmap and give us addresses from all + over our address space. We also can't use mmap for lisp objects + if we might dump: unexec doesn't preserve the contents of mmaped + regions. */ + return pointers_fit_in_lispobj_p () && !might_dump; +} + /************************************************************************ Malloc @@ -1073,10 +1120,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) intptr_t aligned; /* int gets warning casting to 64-bit pointer. */ #ifdef DOUG_LEA_MALLOC - /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed - because mapped region contents are not preserved in - a dumped Emacs. */ - mallopt (M_MMAP_MAX, 0); + if (!mmap_lisp_allowed_p ()) + mallopt (M_MMAP_MAX, 0); #endif #ifdef USE_ALIGNED_ALLOC @@ -1097,8 +1142,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) ((void **) abase)[-1] = base; #ifdef DOUG_LEA_MALLOC - /* Back to a reasonable maximum of mmap'ed areas. */ - mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); + if (!mmap_lisp_allowed_p ()) + mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); #endif #if ! USE_LSB_TAG @@ -1733,23 +1778,15 @@ allocate_string_data (struct Lisp_String *s, size_t size = offsetof (struct sblock, data) + needed; #ifdef DOUG_LEA_MALLOC - /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed - because mapped region contents are not preserved in - a dumped Emacs. - - In case you think of allowing it in a dumped Emacs at the - cost of not being able to re-dump, there's another reason: - mmap'ed data typically have an address towards the top of the - address space, which won't fit into an EMACS_INT (at least on - 32-bit systems with the current tagging scheme). --fx */ - mallopt (M_MMAP_MAX, 0); + if (!mmap_lisp_allowed_p ()) + mallopt (M_MMAP_MAX, 0); #endif b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP); #ifdef DOUG_LEA_MALLOC - /* Back to a reasonable maximum of mmap'ed areas. */ - mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); + if (!mmap_lisp_allowed_p ()) + mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); #endif b->next_free = b->data; @@ -1810,6 +1847,7 @@ allocate_string_data (struct Lisp_String *s, /* Sweep and compact strings. */ +NO_INLINE /* For better stack traces */ static void sweep_strings (void) { @@ -2651,20 +2689,16 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, pointer cannot be tagged, represent it with a Lisp 0. Usually you don't want to touch this. */ -enum { TAGGABLE_NULL = (DATA_SEG_BITS & ~VALMASK) == 0 }; - static struct Lisp_Vector * next_vector (struct Lisp_Vector *v) { - if (! TAGGABLE_NULL && EQ (v->contents[0], make_number (0))) - return 0; return XUNTAG (v->contents[0], 0); } static void set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p) { - v->contents[0] = TAGGABLE_NULL || p ? make_lisp_ptr (p, 0) : make_number (0); + v->contents[0] = make_lisp_ptr (p, 0); } /* This value is balanced well enough to avoid too much internal overhead @@ -2920,6 +2954,7 @@ vector_nbytes (struct Lisp_Vector *v) static void cleanup_vector (struct Lisp_Vector *vector) { + detect_suspicious_free (vector); if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX)) @@ -2932,6 +2967,7 @@ cleanup_vector (struct Lisp_Vector *vector) /* Reclaim space used by unmarked vectors. */ +NO_INLINE /* For better stack traces */ static void sweep_vectors (void) { @@ -2986,7 +3022,7 @@ sweep_vectors (void) if (vector == (struct Lisp_Vector *) block->data && !VECTOR_IN_BLOCK (next, block)) - /* This block should be freed because all of it's + /* This block should be freed because all of its space was coalesced into the only free vector. */ free_this_block = 1; else @@ -3056,10 +3092,8 @@ allocate_vectorlike (ptrdiff_t len) size_t nbytes = header_size + len * word_size; #ifdef DOUG_LEA_MALLOC - /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed - because mapped region contents are not preserved in - a dumped Emacs. */ - mallopt (M_MMAP_MAX, 0); + if (!mmap_lisp_allowed_p ()) + mallopt (M_MMAP_MAX, 0); #endif if (nbytes <= VBLOCK_BYTES_MAX) @@ -3076,10 +3110,13 @@ allocate_vectorlike (ptrdiff_t len) } #ifdef DOUG_LEA_MALLOC - /* Back to a reasonable maximum of mmap'ed areas. */ - mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); + if (!mmap_lisp_allowed_p ()) + mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); #endif + if (find_suspicious_object_in_range (p, (char *) p + nbytes)) + emacs_abort (); + consing_since_gc += nbytes; vector_cells_consed += len; } @@ -3734,7 +3771,7 @@ memory_full (size_t nbytes) memory_full_cons_threshold = sizeof (struct cons_block); /* The first time we get here, free the spare memory. */ - for (i = 0; i < sizeof (spare_memory) / sizeof (char *); i++) + for (i = 0; i < ARRAYELTS (spare_memory); i++) if (spare_memory[i]) { if (i == 0) @@ -6185,6 +6222,8 @@ mark_object (Lisp_Object arg) break; CHECK_ALLOCATED_AND_LIVE (live_symbol_p); ptr->gcmarkbit = 1; + /* Attempt to catch bogus objects. */ + eassert (valid_lisp_object_p (ptr->function) >= 1); mark_object (ptr->function); mark_object (ptr->plist); switch (ptr->redirect) @@ -6392,330 +6431,348 @@ survives_gc_p (Lisp_Object obj) -/* Sweep: find all structures not marked, and free them. */ +NO_INLINE /* For better stack traces */ static void -gc_sweep (void) +sweep_conses (void) { - /* Remove or mark entries in weak hash tables. - This must be done before any object is unmarked. */ - sweep_weak_hash_tables (); - - sweep_strings (); - check_string_bytes (!noninteractive); - - /* Put all unmarked conses on free list. */ - { - register struct cons_block *cblk; - struct cons_block **cprev = &cons_block; - register int lim = cons_block_index; - EMACS_INT num_free = 0, num_used = 0; + register struct cons_block *cblk; + struct cons_block **cprev = &cons_block; + register int lim = cons_block_index; + EMACS_INT num_free = 0, num_used = 0; - cons_free_list = 0; + cons_free_list = 0; - for (cblk = cons_block; cblk; cblk = *cprev) - { - register int i = 0; - int this_free = 0; - int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; + for (cblk = cons_block; cblk; cblk = *cprev) + { + register int i = 0; + int this_free = 0; + int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; - /* Scan the mark bits an int at a time. */ - for (i = 0; i < ilim; i++) - { - if (cblk->gcmarkbits[i] == -1) - { - /* Fast path - all cons cells for this int are marked. */ - cblk->gcmarkbits[i] = 0; - num_used += BITS_PER_INT; - } - else - { - /* Some cons cells for this int are not marked. - Find which ones, and free them. */ - int start, pos, stop; - - start = i * BITS_PER_INT; - stop = lim - start; - if (stop > BITS_PER_INT) - stop = BITS_PER_INT; - stop += start; - - for (pos = start; pos < stop; pos++) - { - if (!CONS_MARKED_P (&cblk->conses[pos])) - { - this_free++; - cblk->conses[pos].u.chain = cons_free_list; - cons_free_list = &cblk->conses[pos]; + /* Scan the mark bits an int at a time. */ + for (i = 0; i < ilim; i++) + { + if (cblk->gcmarkbits[i] == -1) + { + /* Fast path - all cons cells for this int are marked. */ + cblk->gcmarkbits[i] = 0; + num_used += BITS_PER_INT; + } + else + { + /* Some cons cells for this int are not marked. + Find which ones, and free them. */ + int start, pos, stop; + + start = i * BITS_PER_INT; + stop = lim - start; + if (stop > BITS_PER_INT) + stop = BITS_PER_INT; + stop += start; + + for (pos = start; pos < stop; pos++) + { + if (!CONS_MARKED_P (&cblk->conses[pos])) + { + this_free++; + cblk->conses[pos].u.chain = cons_free_list; + cons_free_list = &cblk->conses[pos]; #if GC_MARK_STACK - cons_free_list->car = Vdead; + cons_free_list->car = Vdead; #endif - } - else - { - num_used++; - CONS_UNMARK (&cblk->conses[pos]); - } - } - } - } + } + else + { + num_used++; + CONS_UNMARK (&cblk->conses[pos]); + } + } + } + } - lim = CONS_BLOCK_SIZE; - /* If this block contains only free conses and we have already - seen more than two blocks worth of free conses then deallocate - this block. */ - if (this_free == CONS_BLOCK_SIZE && num_free > CONS_BLOCK_SIZE) - { - *cprev = cblk->next; - /* Unhook from the free list. */ - cons_free_list = cblk->conses[0].u.chain; - lisp_align_free (cblk); - } - else - { - num_free += this_free; - cprev = &cblk->next; - } - } - total_conses = num_used; - total_free_conses = num_free; - } + lim = CONS_BLOCK_SIZE; + /* If this block contains only free conses and we have already + seen more than two blocks worth of free conses then deallocate + this block. */ + if (this_free == CONS_BLOCK_SIZE && num_free > CONS_BLOCK_SIZE) + { + *cprev = cblk->next; + /* Unhook from the free list. */ + cons_free_list = cblk->conses[0].u.chain; + lisp_align_free (cblk); + } + else + { + num_free += this_free; + cprev = &cblk->next; + } + } + total_conses = num_used; + total_free_conses = num_free; +} - /* Put all unmarked floats on free list. */ - { - register struct float_block *fblk; - struct float_block **fprev = &float_block; - register int lim = float_block_index; - EMACS_INT num_free = 0, num_used = 0; +NO_INLINE /* For better stack traces */ +static void +sweep_floats (void) +{ + register struct float_block *fblk; + struct float_block **fprev = &float_block; + register int lim = float_block_index; + EMACS_INT num_free = 0, num_used = 0; - float_free_list = 0; + float_free_list = 0; - for (fblk = float_block; fblk; fblk = *fprev) - { - register int i; - int this_free = 0; - for (i = 0; i < lim; i++) - if (!FLOAT_MARKED_P (&fblk->floats[i])) - { - this_free++; - fblk->floats[i].u.chain = float_free_list; - float_free_list = &fblk->floats[i]; - } - else - { - num_used++; - FLOAT_UNMARK (&fblk->floats[i]); - } - lim = FLOAT_BLOCK_SIZE; - /* If this block contains only free floats and we have already - seen more than two blocks worth of free floats then deallocate - this block. */ - if (this_free == FLOAT_BLOCK_SIZE && num_free > FLOAT_BLOCK_SIZE) - { - *fprev = fblk->next; - /* Unhook from the free list. */ - float_free_list = fblk->floats[0].u.chain; - lisp_align_free (fblk); - } - else - { - num_free += this_free; - fprev = &fblk->next; - } - } - total_floats = num_used; - total_free_floats = num_free; - } + for (fblk = float_block; fblk; fblk = *fprev) + { + register int i; + int this_free = 0; + for (i = 0; i < lim; i++) + if (!FLOAT_MARKED_P (&fblk->floats[i])) + { + this_free++; + fblk->floats[i].u.chain = float_free_list; + float_free_list = &fblk->floats[i]; + } + else + { + num_used++; + FLOAT_UNMARK (&fblk->floats[i]); + } + lim = FLOAT_BLOCK_SIZE; + /* If this block contains only free floats and we have already + seen more than two blocks worth of free floats then deallocate + this block. */ + if (this_free == FLOAT_BLOCK_SIZE && num_free > FLOAT_BLOCK_SIZE) + { + *fprev = fblk->next; + /* Unhook from the free list. */ + float_free_list = fblk->floats[0].u.chain; + lisp_align_free (fblk); + } + else + { + num_free += this_free; + fprev = &fblk->next; + } + } + total_floats = num_used; + total_free_floats = num_free; +} - /* Put all unmarked intervals on free list. */ - { - register struct interval_block *iblk; - struct interval_block **iprev = &interval_block; - register int lim = interval_block_index; - EMACS_INT num_free = 0, num_used = 0; +NO_INLINE /* For better stack traces */ +static void +sweep_intervals (void) +{ + register struct interval_block *iblk; + struct interval_block **iprev = &interval_block; + register int lim = interval_block_index; + EMACS_INT num_free = 0, num_used = 0; - interval_free_list = 0; + interval_free_list = 0; - for (iblk = interval_block; iblk; iblk = *iprev) - { - register int i; - int this_free = 0; + for (iblk = interval_block; iblk; iblk = *iprev) + { + register int i; + int this_free = 0; - for (i = 0; i < lim; i++) - { - if (!iblk->intervals[i].gcmarkbit) - { - set_interval_parent (&iblk->intervals[i], interval_free_list); - interval_free_list = &iblk->intervals[i]; - this_free++; - } - else - { - num_used++; - iblk->intervals[i].gcmarkbit = 0; - } - } - lim = INTERVAL_BLOCK_SIZE; - /* If this block contains only free intervals and we have already - seen more than two blocks worth of free intervals then - deallocate this block. */ - if (this_free == INTERVAL_BLOCK_SIZE && num_free > INTERVAL_BLOCK_SIZE) - { - *iprev = iblk->next; - /* Unhook from the free list. */ - interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]); - lisp_free (iblk); - } - else - { - num_free += this_free; - iprev = &iblk->next; - } - } - total_intervals = num_used; - total_free_intervals = num_free; - } + for (i = 0; i < lim; i++) + { + if (!iblk->intervals[i].gcmarkbit) + { + set_interval_parent (&iblk->intervals[i], interval_free_list); + interval_free_list = &iblk->intervals[i]; + this_free++; + } + else + { + num_used++; + iblk->intervals[i].gcmarkbit = 0; + } + } + lim = INTERVAL_BLOCK_SIZE; + /* If this block contains only free intervals and we have already + seen more than two blocks worth of free intervals then + deallocate this block. */ + if (this_free == INTERVAL_BLOCK_SIZE && num_free > INTERVAL_BLOCK_SIZE) + { + *iprev = iblk->next; + /* Unhook from the free list. */ + interval_free_list = INTERVAL_PARENT (&iblk->intervals[0]); + lisp_free (iblk); + } + else + { + num_free += this_free; + iprev = &iblk->next; + } + } + total_intervals = num_used; + total_free_intervals = num_free; +} - /* Put all unmarked symbols on free list. */ - { - register struct symbol_block *sblk; - struct symbol_block **sprev = &symbol_block; - register int lim = symbol_block_index; - EMACS_INT num_free = 0, num_used = 0; +NO_INLINE /* For better stack traces */ +static void +sweep_symbols (void) +{ + register struct symbol_block *sblk; + struct symbol_block **sprev = &symbol_block; + register int lim = symbol_block_index; + EMACS_INT num_free = 0, num_used = 0; - symbol_free_list = NULL; + symbol_free_list = NULL; - for (sblk = symbol_block; sblk; sblk = *sprev) - { - int this_free = 0; - union aligned_Lisp_Symbol *sym = sblk->symbols; - union aligned_Lisp_Symbol *end = sym + lim; + for (sblk = symbol_block; sblk; sblk = *sprev) + { + int this_free = 0; + union aligned_Lisp_Symbol *sym = sblk->symbols; + union aligned_Lisp_Symbol *end = sym + lim; - for (; sym < end; ++sym) - { - if (!sym->s.gcmarkbit) - { - if (sym->s.redirect == SYMBOL_LOCALIZED) - xfree (SYMBOL_BLV (&sym->s)); - sym->s.next = symbol_free_list; - symbol_free_list = &sym->s; + for (; sym < end; ++sym) + { + if (!sym->s.gcmarkbit) + { + if (sym->s.redirect == SYMBOL_LOCALIZED) + xfree (SYMBOL_BLV (&sym->s)); + sym->s.next = symbol_free_list; + symbol_free_list = &sym->s; #if GC_MARK_STACK - symbol_free_list->function = Vdead; + symbol_free_list->function = Vdead; #endif - ++this_free; - } - else - { - ++num_used; - eassert (!STRING_MARKED_P (XSTRING (sym->s.name))); - sym->s.gcmarkbit = 0; - } - } + ++this_free; + } + else + { + ++num_used; + sym->s.gcmarkbit = 0; + /* Attempt to catch bogus objects. */ + eassert (valid_lisp_object_p (sym->s.function) >= 1); + } + } - lim = SYMBOL_BLOCK_SIZE; - /* If this block contains only free symbols and we have already - seen more than two blocks worth of free symbols then deallocate - this block. */ - if (this_free == SYMBOL_BLOCK_SIZE && num_free > SYMBOL_BLOCK_SIZE) - { - *sprev = sblk->next; - /* Unhook from the free list. */ - symbol_free_list = sblk->symbols[0].s.next; - lisp_free (sblk); - } - else - { - num_free += this_free; - sprev = &sblk->next; - } - } - total_symbols = num_used; - total_free_symbols = num_free; - } + lim = SYMBOL_BLOCK_SIZE; + /* If this block contains only free symbols and we have already + seen more than two blocks worth of free symbols then deallocate + this block. */ + if (this_free == SYMBOL_BLOCK_SIZE && num_free > SYMBOL_BLOCK_SIZE) + { + *sprev = sblk->next; + /* Unhook from the free list. */ + symbol_free_list = sblk->symbols[0].s.next; + lisp_free (sblk); + } + else + { + num_free += this_free; + sprev = &sblk->next; + } + } + total_symbols = num_used; + total_free_symbols = num_free; +} - /* Put all unmarked misc's on free list. - For a marker, first unchain it from the buffer it points into. */ - { - register struct marker_block *mblk; - struct marker_block **mprev = &marker_block; - register int lim = marker_block_index; - EMACS_INT num_free = 0, num_used = 0; +NO_INLINE /* For better stack traces */ +static void +sweep_misc (void) +{ + register struct marker_block *mblk; + struct marker_block **mprev = &marker_block; + register int lim = marker_block_index; + EMACS_INT num_free = 0, num_used = 0; - marker_free_list = 0; + /* Put all unmarked misc's on free list. For a marker, first + unchain it from the buffer it points into. */ - for (mblk = marker_block; mblk; mblk = *mprev) - { - register int i; - int this_free = 0; + marker_free_list = 0; - for (i = 0; i < lim; i++) - { - if (!mblk->markers[i].m.u_any.gcmarkbit) - { - if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker) - unchain_marker (&mblk->markers[i].m.u_marker); - /* Set the type of the freed object to Lisp_Misc_Free. - We could leave the type alone, since nobody checks it, - but this might catch bugs faster. */ - mblk->markers[i].m.u_marker.type = Lisp_Misc_Free; - mblk->markers[i].m.u_free.chain = marker_free_list; - marker_free_list = &mblk->markers[i].m; - this_free++; - } - else - { - num_used++; - mblk->markers[i].m.u_any.gcmarkbit = 0; - } - } - lim = MARKER_BLOCK_SIZE; - /* If this block contains only free markers and we have already - seen more than two blocks worth of free markers then deallocate - this block. */ - if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) - { - *mprev = mblk->next; - /* Unhook from the free list. */ - marker_free_list = mblk->markers[0].m.u_free.chain; - lisp_free (mblk); - } - else - { - num_free += this_free; - mprev = &mblk->next; - } - } + for (mblk = marker_block; mblk; mblk = *mprev) + { + register int i; + int this_free = 0; - total_markers = num_used; - total_free_markers = num_free; - } + for (i = 0; i < lim; i++) + { + if (!mblk->markers[i].m.u_any.gcmarkbit) + { + if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker) + unchain_marker (&mblk->markers[i].m.u_marker); + /* Set the type of the freed object to Lisp_Misc_Free. + We could leave the type alone, since nobody checks it, + but this might catch bugs faster. */ + mblk->markers[i].m.u_marker.type = Lisp_Misc_Free; + mblk->markers[i].m.u_free.chain = marker_free_list; + marker_free_list = &mblk->markers[i].m; + this_free++; + } + else + { + num_used++; + mblk->markers[i].m.u_any.gcmarkbit = 0; + } + } + lim = MARKER_BLOCK_SIZE; + /* If this block contains only free markers and we have already + seen more than two blocks worth of free markers then deallocate + this block. */ + if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE) + { + *mprev = mblk->next; + /* Unhook from the free list. */ + marker_free_list = mblk->markers[0].m.u_free.chain; + lisp_free (mblk); + } + else + { + num_free += this_free; + mprev = &mblk->next; + } + } - /* Free all unmarked buffers */ - { - register struct buffer *buffer, **bprev = &all_buffers; + total_markers = num_used; + total_free_markers = num_free; +} - total_buffers = 0; - for (buffer = all_buffers; buffer; buffer = *bprev) - if (!VECTOR_MARKED_P (buffer)) - { - *bprev = buffer->next; - lisp_free (buffer); - } - else - { - VECTOR_UNMARK (buffer); - /* Do not use buffer_(set|get)_intervals here. */ - buffer->text->intervals = balance_intervals (buffer->text->intervals); - total_buffers++; - bprev = &buffer->next; - } - } +NO_INLINE /* For better stack traces */ +static void +sweep_buffers (void) +{ + register struct buffer *buffer, **bprev = &all_buffers; - sweep_vectors (); - check_string_bytes (!noninteractive); + total_buffers = 0; + for (buffer = all_buffers; buffer; buffer = *bprev) + if (!VECTOR_MARKED_P (buffer)) + { + *bprev = buffer->next; + lisp_free (buffer); + } + else + { + VECTOR_UNMARK (buffer); + /* Do not use buffer_(set|get)_intervals here. */ + buffer->text->intervals = balance_intervals (buffer->text->intervals); + total_buffers++; + bprev = &buffer->next; + } } +/* Sweep: find all structures not marked, and free them. */ +static void +gc_sweep (void) +{ + /* Remove or mark entries in weak hash tables. + This must be done before any object is unmarked. */ + sweep_weak_hash_tables (); + sweep_strings (); + check_string_bytes (!noninteractive); + sweep_conses (); + sweep_floats (); + sweep_intervals (); + sweep_symbols (); + sweep_misc (); + sweep_buffers (); + sweep_vectors (); + check_string_bytes (!noninteractive); +} /* Debugging aids. */ @@ -6814,6 +6871,78 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max) return found; } +#ifdef SUSPICIOUS_OBJECT_CHECKING + +static void * +find_suspicious_object_in_range (void *begin, void *end) +{ + char *begin_a = begin; + char *end_a = end; + int i; + + for (i = 0; i < ARRAYELTS (suspicious_objects); ++i) + { + char *suspicious_object = suspicious_objects[i]; + if (begin_a <= suspicious_object && suspicious_object < end_a) + return suspicious_object; + } + + return NULL; +} + +static void +note_suspicious_free (void* ptr) +{ + struct suspicious_free_record* rec; + + rec = &suspicious_free_history[suspicious_free_history_index++]; + if (suspicious_free_history_index == + ARRAYELTS (suspicious_free_history)) + { + suspicious_free_history_index = 0; + } + + memset (rec, 0, sizeof (*rec)); + rec->suspicious_object = ptr; + backtrace (&rec->backtrace[0], ARRAYELTS (rec->backtrace)); +} + +static void +detect_suspicious_free (void* ptr) +{ + int i; + + eassert (ptr != NULL); + + for (i = 0; i < ARRAYELTS (suspicious_objects); ++i) + if (suspicious_objects[i] == ptr) + { + note_suspicious_free (ptr); + suspicious_objects[i] = NULL; + } +} + +#endif /* SUSPICIOUS_OBJECT_CHECKING */ + +DEFUN ("suspicious-object", Fsuspicious_object, Ssuspicious_object, 1, 1, 0, + doc: /* Return OBJ, maybe marking it for extra scrutiny. +If Emacs is compiled with suspicous object checking, capture +a stack trace when OBJ is freed in order to help track down +garbage collection bugs. Otherwise, do nothing and return OBJ. */) + (Lisp_Object obj) +{ +#ifdef SUSPICIOUS_OBJECT_CHECKING + /* Right now, we care only about vectors. */ + if (VECTORLIKEP (obj)) + { + suspicious_objects[suspicious_object_index++] = XVECTOR (obj); + if (suspicious_object_index == ARRAYELTS (suspicious_objects)) + suspicious_object_index = 0; + } +#endif + return obj; +} + #ifdef ENABLE_CHECKING bool suppress_checking; @@ -6984,6 +7113,7 @@ The time is in seconds as a floating point value. */); defsubr (&Sgarbage_collect); defsubr (&Smemory_limit); defsubr (&Smemory_use_counts); + defsubr (&Ssuspicious_object); #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES defsubr (&Sgc_status); @@ -7002,7 +7132,6 @@ union enum char_bits char_bits; enum CHECK_LISP_OBJECT_TYPE CHECK_LISP_OBJECT_TYPE; enum DEFAULT_HASH_SIZE DEFAULT_HASH_SIZE; - enum enum_USE_LSB_TAG enum_USE_LSB_TAG; enum FLOAT_TO_STRING_BUFSIZE FLOAT_TO_STRING_BUFSIZE; enum Lisp_Bits Lisp_Bits; enum Lisp_Compiled Lisp_Compiled; diff --git a/src/atimer.c b/src/atimer.c index d98ddac0171..a5a2b0714e3 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -50,22 +50,17 @@ static bool alarm_timer_ok; /* Block/unblock SIGALRM. */ static void -sigmask_atimers (int how) +block_atimers (sigset_t *oldset) { sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGALRM); - pthread_sigmask (how, &blocked, 0); + pthread_sigmask (SIG_BLOCK, &blocked, oldset); } static void -block_atimers (void) +unblock_atimers (sigset_t const *oldset) { - sigmask_atimers (SIG_BLOCK); -} -static void -unblock_atimers (void) -{ - sigmask_atimers (SIG_UNBLOCK); + pthread_sigmask (SIG_SETMASK, oldset, 0); } /* Function prototypes. */ @@ -98,6 +93,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, atimer_callback fn, void *client_data) { struct atimer *t; + sigset_t oldset; /* Round TIME up to the next full second if we don't have itimers. */ @@ -122,7 +118,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, t->fn = fn; t->client_data = client_data; - block_atimers (); + block_atimers (&oldset); /* Compute the timer's expiration time. */ switch (type) @@ -143,7 +139,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, /* Insert the timer in the list of active atimers. */ schedule_atimer (t); - unblock_atimers (); + unblock_atimers (&oldset); /* Arrange for a SIGALRM at the time the next atimer is ripe. */ set_alarm (); @@ -158,8 +154,9 @@ void cancel_atimer (struct atimer *timer) { int i; + sigset_t oldset; - block_atimers (); + block_atimers (&oldset); for (i = 0; i < 2; ++i) { @@ -186,7 +183,7 @@ cancel_atimer (struct atimer *timer) } } - unblock_atimers (); + unblock_atimers (&oldset); } @@ -217,7 +214,8 @@ append_atimer_lists (struct atimer *list_1, struct atimer *list_2) void stop_other_atimers (struct atimer *t) { - block_atimers (); + sigset_t oldset; + block_atimers (&oldset); if (t) { @@ -242,7 +240,7 @@ stop_other_atimers (struct atimer *t) stopped_atimers = append_atimer_lists (atimers, stopped_atimers); atimers = t; - unblock_atimers (); + unblock_atimers (&oldset); } @@ -256,8 +254,9 @@ run_all_atimers (void) { struct atimer *t = atimers; struct atimer *next; + sigset_t oldset; - block_atimers (); + block_atimers (&oldset); atimers = stopped_atimers; stopped_atimers = NULL; @@ -268,7 +267,7 @@ run_all_atimers (void) t = next; } - unblock_atimers (); + unblock_atimers (&oldset); } } @@ -381,9 +380,10 @@ do_pending_atimers (void) { if (atimers) { - block_atimers (); + sigset_t oldset; + block_atimers (&oldset); run_timers (); - unblock_atimers (); + unblock_atimers (&oldset); } } diff --git a/src/buffer.c b/src/buffer.c index 3e1359707cd..6a1a74ac1ec 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,7 +1,6 @@ /* Buffer manipulation primitives for GNU Emacs. -Copyright (C) 1985-1989, 1993-1995, 1997-2014 Free Software Foundation, -Inc. +Copyright (C) 1985-1989, 1993-1995, 1997-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -1380,7 +1379,6 @@ It is not ensured that mode lines will be updated to show the modified state of the current buffer. Use with care. */) (Lisp_Object flag) { -#ifdef CLASH_DETECTION Lisp_Object fn; /* If buffer becoming modified, lock the file. @@ -1400,7 +1398,6 @@ state of the current buffer. Use with care. */) else if (already && NILP (flag)) unlock_file (fn); } -#endif /* CLASH_DETECTION */ /* Here we have a problem. SAVE_MODIFF is used here to encode buffer-modified-p (as SAVE_MODIFF<MODIFF) as well as @@ -1820,10 +1817,8 @@ cleaning up all windows currently displaying the buffer to be killed. */) /* Now there is no question: we can kill the buffer. */ -#ifdef CLASH_DETECTION /* Unlock this buffer's file, if it is locked. */ unlock_buffer (b); -#endif /* CLASH_DETECTION */ GCPRO1 (buffer); kill_buffer_processes (buffer); diff --git a/src/callproc.c b/src/callproc.c index 9e60ba11bcf..a2c52e5b5ba 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -110,20 +110,20 @@ static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t); /* Block SIGCHLD. */ void -block_child_signal (void) +block_child_signal (sigset_t *oldset) { sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); - pthread_sigmask (SIG_BLOCK, &blocked, 0); + pthread_sigmask (SIG_BLOCK, &blocked, oldset); } /* Unblock SIGCHLD. */ void -unblock_child_signal (void) +unblock_child_signal (sigset_t const *oldset) { - pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + pthread_sigmask (SIG_SETMASK, oldset, 0); } #endif /* !MSDOS */ @@ -167,7 +167,8 @@ void record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) { #ifndef MSDOS - block_child_signal (); + sigset_t oldset; + block_child_signal (&oldset); if (p->alive) { @@ -176,7 +177,7 @@ record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) kill (- p->pid, SIGKILL); } - unblock_child_signal (); + unblock_child_signal (&oldset); #endif /* !MSDOS */ } @@ -321,6 +322,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, char *tempfile = NULL; int pid; #else + sigset_t oldset; pid_t pid; #endif int child_errno; @@ -637,7 +639,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, #ifndef MSDOS block_input (); - block_child_signal (); + block_child_signal (&oldset); #ifdef WINDOWSNT pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); @@ -679,7 +681,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, if (pid == 0) { - unblock_child_signal (); + unblock_child_signal (&oldset); setsid (); @@ -715,7 +717,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, } } - unblock_child_signal (); + unblock_child_signal (&oldset); unblock_input (); if (pid < 0) @@ -1625,13 +1627,13 @@ init_callproc (void) srcdir = Fexpand_file_name (build_string ("../src/"), lispdir); - tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory); + tem = Fexpand_file_name (build_string ("NEWS"), Vdata_directory); tem1 = Ffile_exists_p (tem); if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1)) { Lisp_Object newdir; newdir = Fexpand_file_name (build_string ("../etc/"), lispdir); - tem = Fexpand_file_name (build_string ("GNU"), newdir); + tem = Fexpand_file_name (build_string ("NEWS"), newdir); tem1 = Ffile_exists_p (tem); if (!NILP (tem1)) Vdata_directory = newdir; diff --git a/src/charset.c b/src/charset.c index 3566b156736..baa692232c7 100644 --- a/src/charset.c +++ b/src/charset.c @@ -2386,7 +2386,7 @@ syms_of_charset (void) } charset_table = charset_table_init; - charset_table_size = sizeof charset_table_init / sizeof *charset_table_init; + charset_table_size = ARRAYELTS (charset_table_init); charset_table_used = 0; defsubr (&Scharsetp); diff --git a/src/chartab.c b/src/chartab.c index 2a8bbc6983a..4d4e6381b19 100644 --- a/src/chartab.c +++ b/src/chartab.c @@ -1221,9 +1221,7 @@ uniprop_decode_value_run_length (Lisp_Object table, Lisp_Object value) static uniprop_decoder_t uniprop_decoder [] = { uniprop_decode_value_run_length }; -static int uniprop_decoder_count - = (sizeof uniprop_decoder) / sizeof (uniprop_decoder[0]); - +static const int uniprop_decoder_count = ARRAYELTS (uniprop_decoder); /* Return the decoder of char-table TABLE or nil if none. */ @@ -1301,9 +1299,7 @@ static uniprop_encoder_t uniprop_encoder[] = uniprop_encode_value_run_length, uniprop_encode_value_numeric }; -static int uniprop_encoder_count - = (sizeof uniprop_encoder) / sizeof (uniprop_encoder[0]); - +static const int uniprop_encoder_count = ARRAYELTS (uniprop_encoder); /* Return the encoder of char-table TABLE or nil if none. */ diff --git a/src/coding.c b/src/coding.c index 654e39c0e3d..fbe14f1695f 100644 --- a/src/coding.c +++ b/src/coding.c @@ -8443,11 +8443,11 @@ from_unicode (Lisp_Object str) } Lisp_Object -from_unicode_buffer (const wchar_t* wstr) +from_unicode_buffer (const wchar_t *wstr) { return from_unicode ( make_unibyte_string ( - (char*) wstr, + (char *) wstr, /* we get one of the two final 0 bytes for free. */ 1 + sizeof (wchar_t) * wcslen (wstr))); } diff --git a/src/coding.h b/src/coding.h index 4e8b1056e43..f3efcca031d 100644 --- a/src/coding.h +++ b/src/coding.h @@ -743,7 +743,7 @@ extern wchar_t *to_unicode (Lisp_Object str, Lisp_Object *buf); extern Lisp_Object from_unicode (Lisp_Object str); /* Convert WSTR to an Emacs string. */ -extern Lisp_Object from_unicode_buffer (const wchar_t* wstr); +extern Lisp_Object from_unicode_buffer (const wchar_t *wstr); #endif /* WINDOWSNT || CYGWIN */ diff --git a/src/conf_post.h b/src/conf_post.h index 8fabd60871b..e9101ce1c57 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -87,10 +87,6 @@ typedef bool bool_bf; #ifdef HPUX #undef srandom #undef random -/* We try to avoid checking for random and rint on hpux in - configure.ac, but some other configure test might check for them as - a dependency, so to be safe we also undefine them here. - */ #undef HAVE_RANDOM #undef HAVE_RINT #endif /* HPUX */ diff --git a/src/data.c b/src/data.c index 33dd619a0e1..965ddd215f5 100644 --- a/src/data.c +++ b/src/data.c @@ -727,6 +727,11 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, if (AUTOLOADP (function)) Fput (symbol, Qautoload, XCDR (function)); + /* Convert to eassert or remove after GC bug is found. In the + meantime, check unconditionally, at a slight perf hit. */ + if (valid_lisp_object_p (definition) < 1) + emacs_abort (); + set_symbol_function (symbol, definition); return definition; diff --git a/src/dired.c b/src/dired.c index 55b2f6658c7..d3fe5b4943d 100644 --- a/src/dired.c +++ b/src/dired.c @@ -988,7 +988,7 @@ file_attributes (int fd, char const *name, Lisp_Object id_format) values[10] = INTEGER_TO_CONS (s.st_ino); values[11] = INTEGER_TO_CONS (s.st_dev); - return Flist (sizeof (values) / sizeof (values[0]), values); + return Flist (ARRAYELTS (values), values); } DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0, diff --git a/src/doc.c b/src/doc.c index b6a4cd0a27b..df8cfba3f2a 100644 --- a/src/doc.c +++ b/src/doc.c @@ -595,7 +595,7 @@ the same file name is found in the `doc-directory'. */) { #include "buildobj.h" }; - int i = sizeof buildobj / sizeof *buildobj; + int i = ARRAYELTS (buildobj); while (0 <= --i) Vbuild_files = Fcons (build_string (buildobj[i]), Vbuild_files); Vbuild_files = Fpurecopy (Vbuild_files); diff --git a/src/dosfns.c b/src/dosfns.c index 071d73ea16e..baa0358d725 100644 --- a/src/dosfns.c +++ b/src/dosfns.c @@ -402,7 +402,7 @@ msdos_stdcolor_idx (const char *name) { int i; - for (i = 0; i < sizeof (vga_colors) / sizeof (vga_colors[0]); i++) + for (i = 0; i < ARRAYELTS (vga_colors); i++) if (xstrcasecmp (name, vga_colors[i]) == 0) return i; @@ -422,7 +422,7 @@ msdos_stdcolor_name (int idx) return build_string (unspecified_fg); else if (idx == FACE_TTY_DEFAULT_BG_COLOR) return build_string (unspecified_bg); - else if (idx >= 0 && idx < sizeof (vga_colors) / sizeof (vga_colors[0])) + else if (idx >= 0 && idx < ARRAYELTS (vga_colors)) return build_string (vga_colors[idx]); else return Qunspecified; /* meaning the default */ diff --git a/src/emacs.c b/src/emacs.c index 6a86dea9927..9cfc09469c2 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1,7 +1,7 @@ /* Fully extensible Emacs, running on Unix, intended for GNU. -Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2014 Free Software -Foundation, Inc. +Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2014 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -105,8 +105,9 @@ extern void moncontrol (int mode); #include <sys/personality.h> #endif -static const char emacs_version[] = VERSION; +static const char emacs_version[] = PACKAGE_VERSION; static const char emacs_copyright[] = COPYRIGHT; +static const char emacs_bugreport[] = PACKAGE_BUGREPORT; /* Empty lisp strings. To avoid having to build any others. */ Lisp_Object empty_unibyte_string, empty_multibyte_string; @@ -121,6 +122,9 @@ Lisp_Object Vlibrary_cache; on subsequent starts. */ bool initialized; +/* Set to true if this instance of Emacs might dump. */ +bool might_dump; + #ifdef DARWIN_OS extern void unexec_init_emacs_zone (void); #endif @@ -132,7 +136,7 @@ static void *malloc_state_ptr; /* From glibc, a routine that returns a copy of the malloc internal state. */ extern void *malloc_get_state (void); /* From glibc, a routine that overwrites the malloc internal state. */ -extern int malloc_set_state (void*); +extern int malloc_set_state (void *); /* True if the MALLOC_CHECK_ environment variable was set while dumping. Used to work around a bug in glibc's malloc. */ static bool malloc_using_checking; @@ -321,7 +325,7 @@ abbreviation for a --option.\n\ Various environment variables and window system resources also affect\n\ the operation of Emacs. See the main documentation.\n\ \n\ -Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\ +Report bugs to " PACKAGE_BUGREPORT ". First, please see the Bugs\n\ section of the Emacs manual or the file BUGS.\n" }; @@ -738,6 +742,10 @@ main (int argc, char **argv) xputenv ("G_SLICE=always-malloc"); #endif +#ifndef CANNOT_DUMP + might_dump = !initialized; +#endif + #ifdef GNU_LINUX if (!initialized) { @@ -1007,7 +1015,7 @@ main (int argc, char **argv) { int i; printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]); - for (i = 0; i < sizeof usage_message / sizeof *usage_message; i++) + for (i = 0; i < ARRAYELTS (usage_message); i++) fputs (usage_message[i], stdout); exit (0); } @@ -1816,7 +1824,7 @@ sort_args (int argc, char **argv) } /* Look for a match with a known old-fashioned option. */ - for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++) + for (i = 0; i < ARRAYELTS (standard_args); i++) if (!strcmp (argv[from], standard_args[i].name)) { options[from] = standard_args[i].nargs; @@ -1838,8 +1846,7 @@ sort_args (int argc, char **argv) match = -1; - for (i = 0; - i < sizeof (standard_args) / sizeof (standard_args[0]); i++) + for (i = 0; i < ARRAYELTS (standard_args); i++) if (standard_args[i].longname && !strncmp (argv[from], standard_args[i].longname, thislen)) @@ -2032,9 +2039,7 @@ shut_down_emacs (int sig, Lisp_Object stuff) kill_buffer_processes (Qnil); Fdo_auto_save (Qt, Qnil); -#ifdef CLASH_DETECTION unlock_all_files (); -#endif /* There is a tendency for a SIGIO signal to arrive within exit, and cause a SIGHUP because the input descriptor is already closed. */ @@ -2089,6 +2094,9 @@ You must run Emacs in batch mode in order to dump it. */) if (! noninteractive) error ("Dumping Emacs works only in batch mode"); + if (!might_dump) + error ("Emacs can be dumped only once"); + #ifdef GNU_LINUX /* Warn if the gap between BSS end and heap start is larger than this. */ @@ -2459,6 +2467,12 @@ Emacs is running. */); doc: /* String containing the configuration options Emacs was built with. */); Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS); + DEFVAR_LISP ("system-configuration-features", Vsystem_configuration_features, + doc: /* String listing some of the main features this Emacs was compiled with. +An element of the form \"FOO\" generally means that HAVE_FOO was +defined during the build. */); + Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES); + DEFVAR_BOOL ("noninteractive", noninteractive1, doc: /* Non-nil means Emacs is running without interactive terminal. */); @@ -2536,6 +2550,10 @@ This is nil during initialization. */); doc: /* Version numbers of this version of Emacs. */); Vemacs_version = build_string (emacs_version); + DEFVAR_LISP ("report-emacs-bug-address", Vreport_emacs_bug_address, + doc: /* Address of mailing list for GNU Emacs bugs. */); + Vreport_emacs_bug_address = build_string (emacs_bugreport); + DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist, doc: /* Alist of dynamic libraries vs external files implementing them. Each element is a list (LIBRARY FILE...), where the car is a symbol diff --git a/src/fileio.c b/src/fileio.c index 8aaed3248a7..5659b6555d8 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2909,7 +2909,7 @@ or if SELinux is disabled, or if Emacs lacks SELinux support. */) } #endif - return Flist (sizeof (values) / sizeof (values[0]), values); + return Flist (ARRAYELTS (values), values); } DEFUN ("set-file-selinux-context", Fset_file_selinux_context, @@ -4078,13 +4078,11 @@ by calling `format-decode', which see. */) if (NILP (visit) && total > 0) { -#ifdef CLASH_DETECTION if (!NILP (BVAR (current_buffer, file_truename)) /* Make binding buffer-file-name to nil effective. */ && !NILP (BVAR (current_buffer, filename)) && SAVE_MODIFF >= MODIFF) we_locked_file = 1; -#endif /* CLASH_DETECTION */ prepare_to_modify_buffer (GPT, GPT, NULL); } @@ -4184,10 +4182,8 @@ by calling `format-decode', which see. */) if (inserted == 0) { -#ifdef CLASH_DETECTION if (we_locked_file) unlock_file (BVAR (current_buffer, file_truename)); -#endif Vdeactivate_mark = old_Vdeactivate_mark; } else @@ -4336,14 +4332,12 @@ by calling `format-decode', which see. */) SAVE_MODIFF = MODIFF; BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF; XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); -#ifdef CLASH_DETECTION if (NILP (handler)) { if (!NILP (BVAR (current_buffer, file_truename))) unlock_file (BVAR (current_buffer, file_truename)); unlock_file (filename); } -#endif /* CLASH_DETECTION */ if (not_regular) xsignal2 (Qfile_error, build_string ("not a regular file"), orig_filename); @@ -4813,13 +4807,11 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, if (!STRINGP (start) && !NILP (BVAR (current_buffer, selective_display))) coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; -#ifdef CLASH_DETECTION if (open_and_close_file && !auto_saving) { lock_file (lockname); file_locked = 1; } -#endif /* CLASH_DETECTION */ encoded_filename = ENCODE_FILE (filename); fn = SSDATA (encoded_filename); @@ -4841,10 +4833,8 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, if (desc < 0) { int open_errno = errno; -#ifdef CLASH_DETECTION if (file_locked) unlock_file (lockname); -#endif /* CLASH_DETECTION */ UNGCPRO; report_file_errno ("Opening output file", filename, open_errno); } @@ -4859,10 +4849,8 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, if (ret < 0) { int lseek_errno = errno; -#ifdef CLASH_DETECTION if (file_locked) unlock_file (lockname); -#endif /* CLASH_DETECTION */ UNGCPRO; report_file_errno ("Lseek error", filename, lseek_errno); } @@ -5005,10 +4993,8 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, unbind_to (count, Qnil); -#ifdef CLASH_DETECTION if (file_locked) unlock_file (lockname); -#endif /* CLASH_DETECTION */ /* Do this before reporting IO error to avoid a "file has changed on disk" warning on diff --git a/src/filelock.c b/src/filelock.c index 5252db09104..f857c488143 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -55,8 +55,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "w32.h" /* for dostounix_filename */ #endif -#ifdef CLASH_DETECTION - #ifdef HAVE_UTMP_H #include <utmp.h> #endif @@ -773,7 +771,9 @@ DEFUN ("lock-buffer", Flock_buffer, Slock_buffer, 0, 1, 0, doc: /* Lock FILE, if current buffer is modified. FILE defaults to current buffer's visited file, -or else nothing is done if current buffer isn't visiting a file. */) +or else nothing is done if current buffer isn't visiting a file. + +If the option `create-lockfiles' is nil, this does nothing. */) (Lisp_Object file) { if (NILP (file)) @@ -837,8 +837,6 @@ t if it is locked by you, else a string saying which user has locked it. */) return ret; } -#endif /* CLASH_DETECTION */ - void syms_of_filelock (void) { @@ -850,9 +848,7 @@ syms_of_filelock (void) doc: /* Non-nil means use lockfiles to avoid editing collisions. */); create_lockfiles = 1; -#ifdef CLASH_DETECTION defsubr (&Sunlock_buffer); defsubr (&Slock_buffer); defsubr (&Sfile_locked_p); -#endif } diff --git a/src/fns.c b/src/fns.c index 499e4b490a6..53819ed23aa 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1127,7 +1127,48 @@ Elements of ALIST that are not conses are also shared. */) return alist; } -DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0, +/* Check that ARRAY can have a valid subarray [FROM..TO), + given that its size is SIZE. + If FROM is nil, use 0; if TO is nil, use SIZE. + Count negative values backwards from the end. + Set *IFROM and *ITO to the two indexes used. */ + +static void +validate_subarray (Lisp_Object array, Lisp_Object from, Lisp_Object to, + ptrdiff_t size, EMACS_INT *ifrom, EMACS_INT *ito) +{ + EMACS_INT f, t; + + if (INTEGERP (from)) + { + f = XINT (from); + if (f < 0) + f += size; + } + else if (NILP (from)) + f = 0; + else + wrong_type_argument (Qintegerp, from); + + if (INTEGERP (to)) + { + t = XINT (to); + if (t < 0) + t += size; + } + else if (NILP (to)) + t = size; + else + wrong_type_argument (Qintegerp, to); + + if (! (0 <= f && f <= t && t <= size)) + args_out_of_range_3 (array, from, to); + + *ifrom = f; + *ito = t; +} + +DEFUN ("substring", Fsubstring, Ssubstring, 1, 3, 0, doc: /* Return a new string whose contents are a substring of STRING. The returned string consists of the characters between index FROM \(inclusive) and index TO (exclusive) of STRING. FROM and TO are @@ -1137,52 +1178,38 @@ to the end of STRING. The STRING argument may also be a vector. In that case, the return value is a new vector that contains the elements between index FROM -\(inclusive) and index TO (exclusive) of that vector argument. */) - (Lisp_Object string, register Lisp_Object from, Lisp_Object to) +\(inclusive) and index TO (exclusive) of that vector argument. + +With one argument, just copy STRING (with properties, if any). */) + (Lisp_Object string, Lisp_Object from, Lisp_Object to) { Lisp_Object res; ptrdiff_t size; - EMACS_INT from_char, to_char; - - CHECK_VECTOR_OR_STRING (string); - CHECK_NUMBER (from); + EMACS_INT ifrom, ito; if (STRINGP (string)) size = SCHARS (string); - else + else if (VECTORP (string)) size = ASIZE (string); - - if (NILP (to)) - to_char = size; else - { - CHECK_NUMBER (to); + wrong_type_argument (Qarrayp, string); - to_char = XINT (to); - if (to_char < 0) - to_char += size; - } - - from_char = XINT (from); - if (from_char < 0) - from_char += size; - if (!(0 <= from_char && from_char <= to_char && to_char <= size)) - args_out_of_range_3 (string, make_number (from_char), - make_number (to_char)); + validate_subarray (string, from, to, size, &ifrom, &ito); if (STRINGP (string)) { - ptrdiff_t to_byte = - (NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char)); - ptrdiff_t from_byte = string_char_to_byte (string, from_char); + ptrdiff_t from_byte + = !ifrom ? 0 : string_char_to_byte (string, ifrom); + ptrdiff_t to_byte + = ito == size ? SBYTES (string) : string_char_to_byte (string, ito); res = make_specified_string (SSDATA (string) + from_byte, - to_char - from_char, to_byte - from_byte, + ito - ifrom, to_byte - from_byte, STRING_MULTIBYTE (string)); - copy_text_properties (make_number (from_char), make_number (to_char), + copy_text_properties (make_number (ifrom), make_number (ito), string, make_number (0), res, Qnil); } else - res = Fvector (to_char - from_char, aref_addr (string, from_char)); + res = Fvector (ito - ifrom, aref_addr (string, ifrom)); return res; } @@ -1205,34 +1232,11 @@ With one argument, just copy STRING without its properties. */) CHECK_STRING (string); size = SCHARS (string); + validate_subarray (string, from, to, size, &from_char, &to_char); - if (NILP (from)) - from_char = 0; - else - { - CHECK_NUMBER (from); - from_char = XINT (from); - if (from_char < 0) - from_char += size; - } - - if (NILP (to)) - to_char = size; - else - { - CHECK_NUMBER (to); - to_char = XINT (to); - if (to_char < 0) - to_char += size; - } - - if (!(0 <= from_char && from_char <= to_char && to_char <= size)) - args_out_of_range_3 (string, make_number (from_char), - make_number (to_char)); - - from_byte = NILP (from) ? 0 : string_char_to_byte (string, from_char); + from_byte = !from_char ? 0 : string_char_to_byte (string, from_char); to_byte = - NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char); + to_char == size ? SBYTES (string) : string_char_to_byte (string, to_char); return make_specified_string (SSDATA (string) + from_byte, to_char - from_char, to_byte - from_byte, STRING_MULTIBYTE (string)); @@ -4032,6 +4036,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p) current garbage collection. Remove weak tables that don't survive from Vweak_hash_tables. Called from gc_sweep. */ +NO_INLINE /* For better stack traces */ void sweep_weak_hash_tables (void) { @@ -4612,36 +4617,12 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_ object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); size = SCHARS (object); + validate_subarray (object, start, end, size, &start_char, &end_char); - if (!NILP (start)) - { - CHECK_NUMBER (start); - - start_char = XINT (start); - - if (start_char < 0) - start_char += size; - } - - if (NILP (end)) - end_char = size; - else - { - CHECK_NUMBER (end); - - end_char = XINT (end); - - if (end_char < 0) - end_char += size; - } - - if (!(0 <= start_char && start_char <= end_char && end_char <= size)) - args_out_of_range_3 (object, make_number (start_char), - make_number (end_char)); - - start_byte = NILP (start) ? 0 : string_char_to_byte (object, start_char); - end_byte = - NILP (end) ? SBYTES (object) : string_char_to_byte (object, end_char); + start_byte = !start_char ? 0 : string_char_to_byte (object, start_char); + end_byte = (end_char == size + ? SBYTES (object) + : string_char_to_byte (object, end_char)); } else { diff --git a/src/font.c b/src/font.c index b49664b5f31..5faf477fa90 100644 --- a/src/font.c +++ b/src/font.c @@ -662,10 +662,6 @@ static const struct { &QCotf, font_prop_validate_otf } }; -/* Size (number of elements) of the above table. */ -#define FONT_PROPERTY_TABLE_SIZE \ - ((sizeof font_property_table) / (sizeof *font_property_table)) - /* Return an index number of font property KEY or -1 if KEY is not an already known property. */ @@ -674,7 +670,7 @@ get_font_prop_index (Lisp_Object key) { int i; - for (i = 0; i < FONT_PROPERTY_TABLE_SIZE; i++) + for (i = 0; i < ARRAYELTS (font_property_table); i++) if (EQ (key, *font_property_table[i].key)) return i; return -1; @@ -2753,22 +2749,21 @@ font_list_entities (struct frame *f, Lisp_Object spec) val = XCDR (val); else { - Lisp_Object copy; - val = driver_list->driver->list (f, scratch_font_spec); - if (NILP (val)) - val = zero_vector; - else - val = Fvconcat (1, &val); - copy = copy_font_spec (scratch_font_spec); - ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); - XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); + if (!NILP (val)) + { + Lisp_Object copy = copy_font_spec (scratch_font_spec); + + val = Fvconcat (1, &val); + ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); + XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); + } } - if (ASIZE (val) > 0 + if (VECTORP (val) && ASIZE (val) > 0 && (need_filtering || ! NILP (Vface_ignored_fonts))) val = font_delete_unmatched (val, need_filtering ? spec : Qnil, size); - if (ASIZE (val) > 0) + if (VECTORP (val) && ASIZE (val) > 0) list = Fcons (val, list); } @@ -2804,7 +2799,6 @@ font_matching_entity (struct frame *f, Lisp_Object *attrs, Lisp_Object spec) && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) { Lisp_Object cache = font_get_cache (f, driver_list->driver); - Lisp_Object copy; ASET (work, FONT_TYPE_INDEX, driver_list->driver->type); entity = assoc_no_quit (work, XCDR (cache)); @@ -2813,9 +2807,14 @@ font_matching_entity (struct frame *f, Lisp_Object *attrs, Lisp_Object spec) else { entity = driver_list->driver->match (f, work); - copy = copy_font_spec (work); - ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); - XSETCDR (cache, Fcons (Fcons (copy, entity), XCDR (cache))); + if (!NILP (entity)) + { + Lisp_Object copy = copy_font_spec (work); + Lisp_Object match = Fvector (1, &entity); + + ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); + XSETCDR (cache, Fcons (Fcons (copy, match), XCDR (cache))); + } } if (! NILP (entity)) break; @@ -4932,8 +4931,7 @@ If the named font is not yet loaded, return nil. */) #endif -#define BUILD_STYLE_TABLE(TBL) \ - build_style_table ((TBL), sizeof TBL / sizeof (struct table_entry)) +#define BUILD_STYLE_TABLE(TBL) build_style_table (TBL, ARRAYELTS (TBL)) static Lisp_Object build_style_table (const struct table_entry *entry, int nelement) diff --git a/src/frame.c b/src/frame.c index c5a2f6ab245..08d0efb6ea2 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2867,8 +2867,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) param_index = Fget (prop, Qx_frame_parameter); if (NATNUMP (param_index) - && (XFASTINT (param_index) - < sizeof (frame_parms)/sizeof (frame_parms[0])) + && XFASTINT (param_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)]) (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); } @@ -2916,8 +2915,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) param_index = Fget (prop, Qx_frame_parameter); if (NATNUMP (param_index) - && (XFASTINT (param_index) - < sizeof (frame_parms)/sizeof (frame_parms[0])) + && XFASTINT (param_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)]) (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value); } @@ -3228,8 +3226,7 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu { Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter); if (NATNUMP (parm_index) - && (XFASTINT (parm_index) - < sizeof (frame_parms)/sizeof (frame_parms[0])) + && XFASTINT (parm_index) < ARRAYELTS (frame_parms) && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)]) (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (parm_index)]) (f, bgcolor, Qnil); @@ -4563,7 +4560,7 @@ syms_of_frame (void) { int i; - for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++) + for (i = 0; i < ARRAYELTS (frame_parms); i++) { Lisp_Object v = intern_c_string (frame_parms[i].name); if (frame_parms[i].variable) diff --git a/src/fringe.c b/src/fringe.c index 6325de4128e..1eae6b18493 100644 --- a/src/fringe.c +++ b/src/fringe.c @@ -474,7 +474,7 @@ static struct fringe_bitmap standard_bitmaps[] = #define NO_FRINGE_BITMAP 0 #define UNDEF_FRINGE_BITMAP 1 -#define MAX_STANDARD_FRINGE_BITMAPS (sizeof (standard_bitmaps)/sizeof (standard_bitmaps[0])) +#define MAX_STANDARD_FRINGE_BITMAPS ARRAYELTS (standard_bitmaps) static struct fringe_bitmap **fringe_bitmaps; static Lisp_Object *fringe_faces; diff --git a/src/gnutls.c b/src/gnutls.c index 03c29d03014..d9b417b46ed 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -56,7 +56,7 @@ static Lisp_Object QCgnutls_bootprop_verify_error; static Lisp_Object QCgnutls_bootprop_callbacks_verify; static void gnutls_log_function (int, const char *); -static void gnutls_log_function2 (int, const char*, const char*); +static void gnutls_log_function2 (int, const char *, const char *); #ifdef HAVE_GNUTLS3 static void gnutls_audit_log_function (gnutls_session_t, const char *); #endif @@ -267,7 +267,7 @@ init_gnutls_functions (void) #ifdef HAVE_GNUTLS3 /* Function to log a simple audit message. */ static void -gnutls_audit_log_function (gnutls_session_t session, const char* string) +gnutls_audit_log_function (gnutls_session_t session, const char *string) { if (global_gnutls_log_level >= 1) { @@ -278,21 +278,21 @@ gnutls_audit_log_function (gnutls_session_t session, const char* string) /* Function to log a simple message. */ static void -gnutls_log_function (int level, const char* string) +gnutls_log_function (int level, const char *string) { message ("gnutls.c: [%d] %s", level, string); } /* Function to log a message and a string. */ static void -gnutls_log_function2 (int level, const char* string, const char* extra) +gnutls_log_function2 (int level, const char *string, const char *extra) { message ("gnutls.c: [%d] %s %s", level, string, extra); } /* Function to log a message and an integer. */ static void -gnutls_log_function2i (int level, const char* string, int extra) +gnutls_log_function2i (int level, const char *string, int extra) { message ("gnutls.c: [%d] %s %d", level, string, extra); } @@ -794,7 +794,7 @@ one trustfile (usually a CA bundle). */) Lisp_Object global_init; char const *priority_string_ptr = "NORMAL"; /* default priority string. */ unsigned int peer_verification; - char* c_hostname; + char *c_hostname; /* Placeholders for the property list elements. */ Lisp_Object priority_string; diff --git a/src/image.c b/src/image.c index d6d5ace509d..bfbdfbc86b2 100644 --- a/src/image.c +++ b/src/image.c @@ -160,6 +160,7 @@ XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) /* Functions to access the contents of a bitmap, given an id. */ +#ifdef HAVE_X_WINDOWS static int x_bitmap_height (struct frame *f, ptrdiff_t id) { @@ -171,6 +172,7 @@ x_bitmap_width (struct frame *f, ptrdiff_t id) { return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width; } +#endif #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) ptrdiff_t @@ -3953,9 +3955,7 @@ xpm_str_to_color_key (const char *s) { int i; - for (i = 0; - i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0]; - i++) + for (i = 0; i < ARRAYELTS (xpm_color_key_strings); i++) if (strcmp (xpm_color_key_strings[i], s) == 0) return i; return -1; @@ -8659,7 +8659,6 @@ DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionDat DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **)); DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **)); DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *)); -DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback, (RsvgHandle *, RsvgSizeFunc, gpointer, GDestroyNotify)); DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *)); DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *)); @@ -8681,13 +8680,18 @@ Lisp_Object Qgdk_pixbuf, Qglib, Qgobject; static bool init_svg_functions (void) { - HMODULE library, gdklib, glib, gobject; + HMODULE library, gdklib = NULL, glib = NULL, gobject = NULL; if (!(glib = w32_delayed_load (Qglib)) || !(gobject = w32_delayed_load (Qgobject)) || !(gdklib = w32_delayed_load (Qgdk_pixbuf)) || !(library = w32_delayed_load (Qsvg))) - return 0; + { + if (gdklib) FreeLibrary (gdklib); + if (gobject) FreeLibrary (gobject); + if (glib) FreeLibrary (glib); + return 0; + } LOAD_IMGLIB_FN (library, rsvg_handle_new); LOAD_IMGLIB_FN (library, rsvg_handle_get_dimensions); diff --git a/src/insdel.c b/src/insdel.c index ea5f6301501..82896758a15 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1,6 +1,6 @@ /* Buffer insertion/deletion and gap motion for GNU Emacs. - Copyright (C) 1985-1986, 1993-1995, 1997-2014 Free Software - Foundation, Inc. + +Copyright (C) 1985-1986, 1993-1995, 1997-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -1804,26 +1804,18 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end, else base_buffer = current_buffer; -#ifdef CLASH_DETECTION + if (inhibit_modification_hooks) + return; + if (!NILP (BVAR (base_buffer, file_truename)) /* Make binding buffer-file-name to nil effective. */ && !NILP (BVAR (base_buffer, filename)) && SAVE_MODIFF >= MODIFF) lock_file (BVAR (base_buffer, file_truename)); -#else - /* At least warn if this file has changed on disk since it was visited. */ - if (!NILP (BVAR (base_buffer, filename)) - && SAVE_MODIFF >= MODIFF - && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ())) - && !NILP (Ffile_exists_p (BVAR (base_buffer, filename)))) - call1 (intern ("ask-user-about-supersession-threat"), - BVAR (base_buffer,filename)); -#endif /* not CLASH_DETECTION */ /* If `select-active-regions' is non-nil, save the region text. */ /* FIXME: Move this to Elisp (via before-change-functions). */ if (!NILP (BVAR (current_buffer, mark_active)) - && !inhibit_modification_hooks && XMARKER (BVAR (current_buffer, mark))->buffer && NILP (Vsaved_region_selection) && (EQ (Vselect_active_regions, Qonly) @@ -1960,9 +1952,6 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, ptrdiff_t count = SPECPDL_INDEX (); struct rvoe_arg rvoe_arg; - if (inhibit_modification_hooks) - return; - start = make_number (start_int); end = make_number (end_int); preserve_marker = Qnil; @@ -1973,7 +1962,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, specbind (Qinhibit_modification_hooks, Qt); /* If buffer is unmodified, run a special hook for that case. The - check for Vfirst_change_hook is just a minor optimization. */ + check for Vfirst_change_hook is just a minor optimization. */ if (SAVE_MODIFF >= MODIFF && !NILP (Vfirst_change_hook)) { diff --git a/src/keyboard.c b/src/keyboard.c index 1f4b23d9905..678cf5abcbd 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1446,7 +1446,7 @@ command_loop_1 (void) Vthis_command_keys_shift_translated = Qnil; /* Read next key sequence; i gets its length. */ - i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], + i = read_key_sequence (keybuf, ARRAYELTS (keybuf), Qnil, 0, 1, 1, 0); /* A filter may have run while we were reading the input. */ @@ -1694,7 +1694,7 @@ read_menu_command (void) menus. */ specbind (Qecho_keystrokes, make_number (0)); - i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], + i = read_key_sequence (keybuf, ARRAYELTS (keybuf), Qnil, 0, 1, 1, 1); unbind_to (count, Qnil); @@ -2299,8 +2299,10 @@ read_decoded_event_from_main_queue (struct timespec *end_time, bool *used_mouse_menu) { #define MAX_ENCODED_BYTES 16 +#ifndef WINDOWSNT Lisp_Object events[MAX_ENCODED_BYTES]; int n = 0; +#endif while (true) { Lisp_Object nextevt @@ -5476,14 +5478,13 @@ make_lispy_event (struct input_event *event) case NON_ASCII_KEYSTROKE_EVENT: button_down_time = 0; - for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++) + for (i = 0; i < ARRAYELTS (lispy_accent_codes); i++) if (event->code == lispy_accent_codes[i]) return modify_event_symbol (i, event->modifiers, Qfunction_key, Qnil, lispy_accent_keys, &accent_key_syms, - (sizeof (lispy_accent_keys) - / sizeof (lispy_accent_keys[0]))); + ARRAYELTS (lispy_accent_keys)); #if 0 #ifdef XK_kana_A @@ -5492,8 +5493,7 @@ make_lispy_event (struct input_event *event) event->modifiers & ~shift_modifier, Qfunction_key, Qnil, lispy_kana_keys, &func_key_syms, - (sizeof (lispy_kana_keys) - / sizeof (lispy_kana_keys[0]))); + ARRAYELTS (lispy_kana_keys)); #endif /* XK_kana_A */ #endif /* 0 */ @@ -5504,15 +5504,14 @@ make_lispy_event (struct input_event *event) event->modifiers, Qfunction_key, Qnil, iso_lispy_function_keys, &func_key_syms, - (sizeof (iso_lispy_function_keys) - / sizeof (iso_lispy_function_keys[0]))); + ARRAYELTS (iso_lispy_function_keys)); #endif /* Handle system-specific or unknown keysyms. */ if (event->code & (1 << 28) || event->code - FUNCTION_KEY_OFFSET < 0 || (event->code - FUNCTION_KEY_OFFSET - >= sizeof lispy_function_keys / sizeof *lispy_function_keys) + >= ARRAYELTS (lispy_function_keys)) || !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET]) { /* We need to use an alist rather than a vector as the cache @@ -5531,20 +5530,17 @@ make_lispy_event (struct input_event *event) event->modifiers, Qfunction_key, Qnil, lispy_function_keys, &func_key_syms, - (sizeof (lispy_function_keys) - / sizeof (lispy_function_keys[0]))); + ARRAYELTS (lispy_function_keys)); #ifdef HAVE_NTGUI case MULTIMEDIA_KEY_EVENT: - if (event->code < (sizeof (lispy_multimedia_keys) - / sizeof (lispy_multimedia_keys[0])) + if (event->code < ARRAYELTS (lispy_multimedia_keys) && event->code > 0 && lispy_multimedia_keys[event->code]) { return modify_event_symbol (event->code, event->modifiers, Qfunction_key, Qnil, lispy_multimedia_keys, &func_key_syms, - (sizeof (lispy_multimedia_keys) - / sizeof (lispy_multimedia_keys[0]))); + ARRAYELTS (lispy_multimedia_keys)); } return Qnil; #endif @@ -6266,7 +6262,7 @@ static const char *const modifier_names[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "alt", "super", "hyper", "shift", "control", "meta" }; -#define NUM_MOD_NAMES (sizeof (modifier_names) / sizeof (modifier_names[0])) +#define NUM_MOD_NAMES ARRAYELTS (modifier_names) static Lisp_Object modifier_symbols; @@ -7286,7 +7282,7 @@ store_user_signal_events (void) } -static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*); +static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void *); static Lisp_Object menu_bar_one_keymap_changed_items; /* These variables hold the vector under construction within @@ -7296,7 +7292,7 @@ static Lisp_Object menu_bar_items_vector; static int menu_bar_items_index; -static const char* separator_names[] = { +static const char *separator_names[] = { "space", "no-line", "single-line", @@ -7904,7 +7900,8 @@ static Lisp_Object QCrtl; /* Function prototypes. */ static void init_tool_bar_items (Lisp_Object); -static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void*); +static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, + void *); static bool parse_tool_bar_item (Lisp_Object, Lisp_Object); static void append_tool_bar_item (void); @@ -9756,7 +9753,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, memset (keybuf, 0, sizeof keybuf); GCPRO1 (keybuf[0]); - gcpro1.nvars = (sizeof keybuf / sizeof (keybuf[0])); + gcpro1.nvars = ARRAYELTS (keybuf); if (NILP (continue_echo)) { @@ -9770,7 +9767,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo, cancel_hourglass (); #endif - i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), + i = read_key_sequence (keybuf, ARRAYELTS (keybuf), prompt, ! NILP (dont_downcase_last), ! NILP (can_return_switch_frame), 0, 0); @@ -10305,6 +10302,9 @@ static void handle_interrupt (bool in_signal_handler) { char c; + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGINT); cancel_echoing (); @@ -10316,9 +10316,6 @@ handle_interrupt (bool in_signal_handler) /* If SIGINT isn't blocked, don't let us be interrupted by a SIGINT. It might be harmful due to non-reentrancy in I/O functions. */ - sigset_t blocked; - sigemptyset (&blocked); - sigaddset (&blocked, SIGINT); pthread_sigmask (SIG_BLOCK, &blocked, 0); } @@ -10403,7 +10400,7 @@ handle_interrupt (bool in_signal_handler) struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; immediate_quit = 0; - pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); saved = gl_state; GCPRO4 (saved.object, saved.global_code, saved.current_syntax_table, saved.old_prop); @@ -10424,7 +10421,7 @@ handle_interrupt (bool in_signal_handler) } } - pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); /* TODO: The longjmp in this call throws the NS event loop integration off, and it seems to do fine without this. Probably some attention @@ -10683,7 +10680,7 @@ The elements of this list correspond to the arguments of } XSETFASTINT (val[3], quit_char); - return Flist (sizeof (val) / sizeof (val[0]), val); + return Flist (ARRAYELTS (val), val); } DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0, @@ -11051,7 +11048,7 @@ syms_of_keyboard (void) { int i; - int len = sizeof (head_table) / sizeof (head_table[0]); + int len = ARRAYELTS (head_table); for (i = 0; i < len; i++) { @@ -11067,14 +11064,13 @@ syms_of_keyboard (void) staticpro (&button_down_location); mouse_syms = Fmake_vector (make_number (5), Qnil); staticpro (&mouse_syms); - wheel_syms = Fmake_vector (make_number (sizeof (lispy_wheel_names) - / sizeof (lispy_wheel_names[0])), + wheel_syms = Fmake_vector (make_number (ARRAYELTS (lispy_wheel_names)), Qnil); staticpro (&wheel_syms); { int i; - int len = sizeof (modifier_names) / sizeof (modifier_names[0]); + int len = ARRAYELTS (modifier_names); modifier_symbols = Fmake_vector (make_number (len), Qnil); for (i = 0; i < len; i++) @@ -11393,6 +11389,7 @@ and tests the value when the command returns. Buffer modification stores t in this variable. */); Vdeactivate_mark = Qnil; DEFSYM (Qdeactivate_mark, "deactivate-mark"); + Fmake_variable_buffer_local (Qdeactivate_mark); DEFVAR_LISP ("pre-command-hook", Vpre_command_hook, doc: /* Normal hook run before each command is executed. diff --git a/src/keymap.c b/src/keymap.c index c1416f8a780..663c4661be3 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -1894,7 +1894,7 @@ struct accessible_keymaps_data { static void accessible_keymaps_1 (Lisp_Object key, Lisp_Object cmd, Lisp_Object args, void *data) -/* Use void* data to be compatible with map_keymap_function_t. */ +/* Use void * data to be compatible with map_keymap_function_t. */ { struct accessible_keymaps_data *d = data; /* Cast! */ Lisp_Object maps = d->maps; diff --git a/src/keymap.h b/src/keymap.h index 4a408c6a2a0..b01886dfa61 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -46,7 +46,7 @@ extern void syms_of_keymap (void); extern void keys_of_keymap (void); typedef void (*map_keymap_function_t) - (Lisp_Object key, Lisp_Object val, Lisp_Object args, void* data); + (Lisp_Object key, Lisp_Object val, Lisp_Object args, void *data); extern void map_keymap (Lisp_Object, map_keymap_function_t, Lisp_Object, void *, bool); extern void map_keymap_canonical (Lisp_Object map, diff --git a/src/lisp.h b/src/lisp.h index edc442bb5ab..6ef0f83aea4 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -58,6 +58,26 @@ INLINE_HEADER_BEGIN #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) +/* Number of elements in an array. */ +#define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0]) + +/* Number of bits in a Lisp_Object tag. */ +DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS) +#define GCTYPEBITS 3 +DEFINE_GDB_SYMBOL_END (GCTYPEBITS) + +/* The number of bits needed in an EMACS_INT over and above the number + of bits in a pointer. This is 0 on systems where: + 1. We can specify multiple-of-8 alignment on static variables. + 2. We know malloc returns a multiple of 8. */ +#if (defined alignas \ + && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ + || defined DARWIN_OS || defined __sun)) +# define NONPOINTER_BITS 0 +#else +# define NONPOINTER_BITS GCTYPEBITS +#endif + /* EMACS_INT - signed integer wide enough to hold an Emacs value EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if pI - printf length modifier for EMACS_INT @@ -65,16 +85,18 @@ INLINE_HEADER_BEGIN #ifndef EMACS_INT_MAX # if INTPTR_MAX <= 0 # error "INTPTR_MAX misconfigured" -# elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT +# elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef int EMACS_INT; typedef unsigned int EMACS_UINT; # define EMACS_INT_MAX INT_MAX # define pI "" -# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT +# elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef long int EMACS_INT; typedef unsigned long EMACS_UINT; # define EMACS_INT_MAX LONG_MAX # define pI "l" +/* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS. + In theory this is not safe, but in practice it seems to be OK. */ # elif INTPTR_MAX <= LLONG_MAX typedef long long int EMACS_INT; typedef unsigned long long int EMACS_UINT; @@ -215,12 +237,6 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; enum Lisp_Bits { - /* Number of bits in a Lisp_Object tag. This can be used in #if, - and for GDB's sake also as a regular symbol. */ - GCTYPEBITS = -#define GCTYPEBITS 3 - GCTYPEBITS, - /* 2**GCTYPEBITS. This must be a macro that expands to a literal integer constant, for MSVC. */ #define GCALIGNMENT 8 @@ -244,31 +260,19 @@ enum Lisp_Bits This can be used in #if, e.g., '#if VAL_MAX < UINTPTR_MAX' below. */ #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1)) -/* Unless otherwise specified, use USE_LSB_TAG on systems where: */ -#ifndef USE_LSB_TAG -/* 1. We know malloc returns a multiple of 8. */ -# if (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ - || defined DARWIN_OS || defined __sun) -/* 2. We can specify multiple-of-8 alignment on static variables. */ -# ifdef alignas -/* 3. Pointers-as-ints exceed VAL_MAX. +/* Whether the least-significant bits of an EMACS_INT contain the tag. On hosts where pointers-as-ints do not exceed VAL_MAX, USE_LSB_TAG is: a. unnecessary, because the top bits of an EMACS_INT are unused, and b. slower, because it typically requires extra masking. - So, default USE_LSB_TAG to true only on hosts where it might be useful. */ -# if VAL_MAX < UINTPTR_MAX -# define USE_LSB_TAG true -# endif -# endif -# endif -#endif -#ifdef USE_LSB_TAG -# undef USE_LSB_TAG -enum enum_USE_LSB_TAG { USE_LSB_TAG = true }; -# define USE_LSB_TAG true -#else -enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; -# define USE_LSB_TAG false + So, USE_LSB_TAG is true only on hosts where it might be useful. */ +DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) +#define USE_LSB_TAG (EMACS_INT_MAX >> GCTYPEBITS < INTPTR_MAX) +DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) + +#if !USE_LSB_TAG && !defined WIDE_EMACS_INT +# error "USE_LSB_TAG not supported on this platform; please report this." \ + "Try 'configure --with-wide-int' to work around the problem." +error !; #endif #ifndef alignas @@ -343,8 +347,7 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; #define lisp_h_XCONS(a) \ (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) #define lisp_h_XHASH(a) XUINT (a) -#define lisp_h_XPNTR(a) \ - ((void *) (intptr_t) ((XLI (a) & VALMASK) | (DATA_SEG_BITS & ~VALMASK))) +#define lisp_h_XPNTR(a) ((void *) (intptr_t) (XLI (a) & VALMASK)) #define lisp_h_XSYMBOL(a) \ (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) #ifndef GC_CHECK_CONS_LIST @@ -605,18 +608,8 @@ enum pvec_type PVEC_FONT /* Should be last because it's used for range checking. */ }; -/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers - which were stored in a Lisp_Object. */ -#ifndef DATA_SEG_BITS -# define DATA_SEG_BITS 0 -#endif -enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; -#undef DATA_SEG_BITS - enum More_Lisp_Bits { - DATA_SEG_BITS = gdb_DATA_SEG_BITS, - /* For convenience, we also store the number of elements in these bits. Note that this size is not necessarily the memory-footprint size, but only the number of Lisp_Object fields (that need to be traced by GC). @@ -800,6 +793,7 @@ extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); /* Defined in emacs.c. */ extern bool initialized; +extern bool might_dump; /* Defined in eval.c. */ extern Lisp_Object Qautoload; @@ -4240,8 +4234,6 @@ extern void init_sigio (int); extern void sys_subshell (void); extern void sys_suspend (void); extern void discard_tty_input (void); -extern void block_tty_out_signal (void); -extern void unblock_tty_out_signal (void); extern void init_sys_modes (struct tty_display_info *); extern void reset_sys_modes (struct tty_display_info *); extern void init_all_sys_modes (void); diff --git a/src/macfont.m b/src/macfont.m index 075b512e686..7aa1d40b332 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -237,8 +237,7 @@ mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection, unichar characters[] = {0xfffd}; NSString *string = [NSString stringWithCharacters:characters - length:(sizeof (characters) - / sizeof (characters[0]))]; + length:ARRAYELTS (characters)]; NSGlyphInfo *glyphInfo = [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid collection:collection @@ -826,7 +825,7 @@ macfont_store_descriptor_attributes (FontDescriptorRef desc, {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}}; int i; - for (i = 0; i < sizeof (numeric_traits) / sizeof (numeric_traits[0]); i++) + for (i = 0; i < ARRAYELTS (numeric_traits); i++) { num = CFDictionaryGetValue (dict, numeric_traits[i].trait); if (num && CFNumberGetValue (num, kCFNumberCGFloatType, &floatval)) @@ -1908,7 +1907,7 @@ macfont_create_attributes_with_spec (Lisp_Object spec) if (! traits) goto err; - for (i = 0; i < sizeof (numeric_traits) / sizeof (numeric_traits[0]); i++) + for (i = 0; i < ARRAYELTS (numeric_traits); i++) { tmp = AREF (spec, numeric_traits[i].index); if (INTEGERP (tmp)) @@ -3584,7 +3583,7 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string, { attributes = CFDictionaryCreate (NULL, (const void **) keys, (const void **) values, - sizeof (keys) / sizeof (keys[0]), + ARRAYELTS (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease (values[1]); @@ -3795,8 +3794,8 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, CTLineRef ctline = NULL; string = CFStringCreateWithCharacters (NULL, characters, - sizeof (characters) - / sizeof (characters[0])); + ARRAYELTS (characters)); + if (string) { CTGlyphInfoRef glyph_info = @@ -3811,7 +3810,7 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, attributes = CFDictionaryCreate (NULL, (const void **) keys, (const void **) values, - sizeof (keys) / sizeof (keys[0]), + ARRAYELTS (keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFRelease (glyph_info); diff --git a/src/minibuf.c b/src/minibuf.c index f325381d1ca..8b742cf88ca 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1967,7 +1967,7 @@ A value of t means no truncation. This variable only affects history lists that don't specify their own maximum lengths. Setting the `history-length' property of a history variable overrides this default. */); - XSETFASTINT (Vhistory_length, 30); + XSETFASTINT (Vhistory_length, 100); DEFVAR_BOOL ("history-delete-duplicates", history_delete_duplicates, doc: /* Non-nil means to delete duplicates in history. diff --git a/src/msdos.c b/src/msdos.c index 010a0a3746c..21794341222 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -566,7 +566,7 @@ dos_set_window_size (int *rows, int *cols) }; int i = 0; - while (i < sizeof (std_dimension) / sizeof (std_dimension[0])) + while (i < ARRAYELTS (std_dimension)) { if (std_dimension[i].need_vga <= have_vga && std_dimension[i].rows >= *rows) @@ -3455,7 +3455,7 @@ init_environment (int argc, char **argv, int skip_args) static const char * const tempdirs[] = { "$TMPDIR", "$TEMP", "$TMP", "c:/" }; - const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]); + const int imax = ARRAYELTS (tempdirs); /* Make sure they have a usable $TMPDIR. Many Emacs functions use temporary files and assume "/tmp" if $TMPDIR is unset, which diff --git a/src/nsfns.m b/src/nsfns.m index 58746aed9fa..4c3f7f34c07 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1024,7 +1024,7 @@ get_geometry_from_preferences (struct ns_display_info *dpyinfo, }; int i; - for (i = 0; i < sizeof (r)/sizeof (r[0]); ++i) + for (i = 0; i < ARRAYELTS (r); ++i) { if (NILP (Fassq (r[i].tem, parms))) { diff --git a/src/nsterm.m b/src/nsterm.m index c7cb4faa3b7..842ff194c40 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2012,8 +2012,7 @@ ns_convert_key (unsigned code) Internal call used by NSView-keyDown. -------------------------------------------------------------------------- */ { - const unsigned last_keysym = (sizeof (convert_ns_to_X_keysym) - / sizeof (convert_ns_to_X_keysym[0])); + const unsigned last_keysym = ARRAYELTS (convert_ns_to_X_keysym); unsigned keysym; /* An array would be faster, but less easy to read. */ for (keysym = 0; keysym < last_keysym; keysym += 2) diff --git a/src/process.c b/src/process.c index 2c66b9e976e..fdb0501f9ec 100644 --- a/src/process.c +++ b/src/process.c @@ -1663,6 +1663,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) bool pty_flag = 0; char pty_name[PTY_NAME_SIZE]; Lisp_Object lisp_pty_name = Qnil; + sigset_t oldset; inchannel = outchannel = -1; @@ -1728,7 +1729,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) setup_process_coding_systems (process); block_input (); - block_child_signal (); + block_child_signal (&oldset); #ifndef WINDOWSNT /* vfork, and prevent local vars from being clobbered by the vfork. */ @@ -1852,7 +1853,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) signal (SIGPIPE, SIG_DFL); /* Stop blocking SIGCHLD in the child. */ - unblock_child_signal (); + unblock_child_signal (&oldset); if (pty_flag) child_setup_tty (xforkout); @@ -1871,7 +1872,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) p->alive = 1; /* Stop blocking in the parent. */ - unblock_child_signal (); + unblock_child_signal (&oldset); unblock_input (); if (pid < 0) @@ -2021,11 +2022,11 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, int len) terminator, however. */ if (name_length > 0 && sockun->sun_path[0] != '\0') { - const char* terminator = - memchr (sockun->sun_path, '\0', name_length); + const char *terminator + = memchr (sockun->sun_path, '\0', name_length); if (terminator) - name_length = terminator - (const char*) sockun->sun_path; + name_length = terminator - (const char *) sockun->sun_path; } return make_unibyte_string (sockun->sun_path, name_length); @@ -7071,8 +7072,9 @@ void catch_child_signal (void) { struct sigaction action, old_action; + sigset_t oldset; emacs_sigaction_init (&action, deliver_child_signal); - block_child_signal (); + block_child_signal (&oldset); sigaction (SIGCHLD, &action, &old_action); eassert (! (old_action.sa_flags & SA_SIGINFO)); @@ -7081,7 +7083,7 @@ catch_child_signal (void) = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN ? dummy_handler : old_action.sa_handler); - unblock_child_signal (); + unblock_child_signal (&oldset); } #endif /* subprocesses */ diff --git a/src/process.h b/src/process.h index c3481f295f5..842554bdef4 100644 --- a/src/process.h +++ b/src/process.h @@ -213,8 +213,8 @@ enum /* Defined in callproc.c. */ -extern void block_child_signal (void); -extern void unblock_child_signal (void); +extern void block_child_signal (sigset_t *); +extern void unblock_child_signal (sigset_t const *); extern Lisp_Object encode_current_directory (void); extern void record_kill_process (struct Lisp_Process *, Lisp_Object); diff --git a/src/profiler.c b/src/profiler.c index 8b092dcc818..ff97fe88b7b 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -294,7 +294,7 @@ setup_cpu_timer (Lisp_Object sampling_interval) sigev.sigev_signo = SIGPROF; sigev.sigev_notify = SIGEV_SIGNAL; - for (i = 0; i < sizeof system_clock / sizeof *system_clock; i++) + for (i = 0; i < ARRAYELTS (system_clock); i++) if (timer_create (system_clock[i], &sigev, &profiler_timer) == 0) { profiler_timer_ok = 1; diff --git a/src/puresize.h b/src/puresize.h index 1371fb3cea2..376b11cf75b 100644 --- a/src/puresize.h +++ b/src/puresize.h @@ -40,7 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #endif #ifndef BASE_PURESIZE -#define BASE_PURESIZE (1701000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) +#define BASE_PURESIZE (1800000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) #endif /* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ diff --git a/src/search.c b/src/search.c index 3de194c5056..9bec825abcd 100644 --- a/src/search.c +++ b/src/search.c @@ -2679,18 +2679,8 @@ since only regular expressions have distinguished subexpressions. */) } if (really_changed) - { - if (buf_multibyte) - { - ptrdiff_t nchars = - multibyte_chars_in_text (substed, substed_len); - - newtext = make_multibyte_string ((char *) substed, nchars, - substed_len); - } - else - newtext = make_unibyte_string ((char *) substed, substed_len); - } + newtext = make_specified_string ((const char *) substed, -1, + substed_len, buf_multibyte); xfree (substed); } diff --git a/src/sound.c b/src/sound.c index a95678812e1..7046f4e8e32 100644 --- a/src/sound.c +++ b/src/sound.c @@ -702,7 +702,7 @@ vox_configure (struct sound_device *sd) { int val; #ifdef USABLE_SIGIO - sigset_t blocked; + sigset_t oldset, blocked; #endif eassert (sd->fd >= 0); @@ -714,7 +714,7 @@ vox_configure (struct sound_device *sd) #ifdef USABLE_SIGIO sigemptyset (&blocked); sigaddset (&blocked, SIGIO); - pthread_sigmask (SIG_BLOCK, &blocked, 0); + pthread_sigmask (SIG_BLOCK, &blocked, &oldset); #endif val = sd->format; @@ -748,7 +748,7 @@ vox_configure (struct sound_device *sd) turn_on_atimers (1); #ifdef USABLE_SIGIO - pthread_sigmask (SIG_UNBLOCK, &blocked, 0); + pthread_sigmask (SIG_SETMASK, &oldset, 0); #endif } @@ -764,10 +764,10 @@ vox_close (struct sound_device *sd) be interrupted by a signal. Block the ones we know to cause troubles. */ #ifdef USABLE_SIGIO - sigset_t blocked; + sigset_t blocked, oldset; sigemptyset (&blocked); sigaddset (&blocked, SIGIO); - pthread_sigmask (SIG_BLOCK, &blocked, 0); + pthread_sigmask (SIG_BLOCK, &blocked, &oldset); #endif turn_on_atimers (0); @@ -776,7 +776,7 @@ vox_close (struct sound_device *sd) turn_on_atimers (1); #ifdef USABLE_SIGIO - pthread_sigmask (SIG_UNBLOCK, &blocked, 0); + pthread_sigmask (SIG_SETMASK, &oldset, 0); #endif /* Close the device. */ diff --git a/src/sysdep.c b/src/sysdep.c index 4e86dc903dc..e5b29205e96 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -128,7 +128,7 @@ static const int baud_convert[] = /* Return the current working directory. Returns NULL on errors. Any other returned value must be freed with free. This is used only when get_current_dir_name is not defined on the system. */ -char* +char * get_current_dir_name (void) { char *buf; @@ -255,7 +255,7 @@ init_baud_rate (int fd) #endif /* not DOS_NT */ } - baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0] + baud_rate = (emacs_ospeed < ARRAYELTS (baud_convert) ? baud_convert[emacs_ospeed] : 9600); if (baud_rate == 0) baud_rate = 1200; @@ -603,6 +603,7 @@ init_sigio (int fd) #endif } +#ifndef DOS_NT static void reset_sigio (int fd) { @@ -610,6 +611,7 @@ reset_sigio (int fd) fcntl (fd, F_SETFL, old_fcntl_flags[fd]); #endif } +#endif void request_sigio (void) @@ -692,21 +694,21 @@ init_foreground_group (void) /* Block and unblock SIGTTOU. */ void -block_tty_out_signal (void) +block_tty_out_signal (sigset_t *oldset) { #ifdef SIGTTOU sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGTTOU); - pthread_sigmask (SIG_BLOCK, &blocked, 0); + pthread_sigmask (SIG_BLOCK, &blocked, oldset); #endif } void -unblock_tty_out_signal (void) +unblock_tty_out_signal (sigset_t const *oldset) { #ifdef SIGTTOU - pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + pthread_sigmask (SIG_SETMASK, oldset, 0); #endif } @@ -721,10 +723,11 @@ static void tcsetpgrp_without_stopping (int fd, pid_t pgid) { #ifdef SIGTTOU + sigset_t oldset; block_input (); - block_tty_out_signal (); + block_tty_out_signal (&oldset); tcsetpgrp (fd, pgid); - unblock_tty_out_signal (); + unblock_tty_out_signal (&oldset); unblock_input (); #endif } @@ -1527,9 +1530,6 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) #endif } - if (! IEEE_FLOATING_POINT) - sigaddset (&action->sa_mask, SIGFPE); - action->sa_handler = handler; action->sa_flags = emacs_sigaction_flags (); } @@ -1645,7 +1645,10 @@ deliver_fatal_thread_signal (int sig) static _Noreturn void handle_arith_signal (int sig) { - pthread_sigmask (SIG_SETMASK, &empty_mask, 0); + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, sig); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); xsignal0 (Qarith_error); } diff --git a/src/syssignal.h b/src/syssignal.h index 477ddfc2086..89d6c480e0c 100644 --- a/src/syssignal.h +++ b/src/syssignal.h @@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <signal.h> extern void init_signals (bool); +extern void block_tty_out_signal (sigset_t *); +extern void unblock_tty_out_signal (sigset_t const *); #ifdef HAVE_PTHREAD #include <pthread.h> diff --git a/src/term.c b/src/term.c index 9e6cfe2f41d..47be788f31a 100644 --- a/src/term.c +++ b/src/term.c @@ -1339,7 +1339,7 @@ term_get_fkeys_1 (void) if (!KEYMAPP (KVAR (kboard, Vinput_decode_map))) kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil)); - for (i = 0; i < (sizeof (keys) / sizeof (keys[0])); i++) + for (i = 0; i < ARRAYELTS (keys); i++) { char *sequence = tgetstr (keys[i].cap, address); if (sequence) @@ -3944,9 +3944,10 @@ dissociate_if_controlling_tty (int fd) /* setsid failed, presumably because Emacs is already a process group leader. Fall back on the obsolescent way to dissociate a controlling tty. */ - block_tty_out_signal (); + sigset_t oldset; + block_tty_out_signal (&oldset); ioctl (fd, TIOCNOTTY, 0); - unblock_tty_out_signal (); + unblock_tty_out_signal (&oldset); #endif } } @@ -3970,6 +3971,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) int status; struct tty_display_info *tty = NULL; struct terminal *terminal = NULL; + sigset_t oldset; bool ctty = false; /* True if asked to open controlling tty. */ if (!terminal_type) @@ -4031,12 +4033,15 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) open a frame on the same terminal. */ int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY); int fd = emacs_open (name, flags, 0); - tty->input = tty->output = fd < 0 || ! isatty (fd) ? 0 : fdopen (fd, "w+"); + tty->input = tty->output = + ((fd < 0 || ! isatty (fd)) + ? NULL + : fdopen (fd, "w+")); if (! tty->input) { char const *diagnostic - = tty->input ? "Not a tty device: %s" : "Could not open file: %s"; + = (fd < 0) ? "Could not open file: %s" : "Not a tty device: %s"; emacs_close (fd); maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name); } @@ -4056,11 +4061,11 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) /* On some systems, tgetent tries to access the controlling terminal. */ - block_tty_out_signal (); + block_tty_out_signal (&oldset); status = tgetent (tty->termcap_term_buffer, terminal_type); if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1]) emacs_abort (); - unblock_tty_out_signal (); + unblock_tty_out_signal (&oldset); if (status < 0) { diff --git a/src/unexcoff.c b/src/unexcoff.c index 043f3348d16..0e47bdd8656 100644 --- a/src/unexcoff.c +++ b/src/unexcoff.c @@ -122,7 +122,7 @@ static int pagemask; into an int which is the number of a byte. This is a no-op on ordinary machines, but not on all. */ -#define ADDR_CORRECT(x) ((char *)(x) - (char*)0) +#define ADDR_CORRECT(x) ((char *) (x) - (char *) 0) #include "lisp.h" diff --git a/src/unexcw.c b/src/unexcw.c index fcca5e5cbf2..7636b05a12e 100644 --- a/src/unexcw.c +++ b/src/unexcw.c @@ -81,8 +81,7 @@ read_exe_header (int fd, exe_header_t * exe_header_buffer) #endif assert (exe_header_buffer->file_header.f_nscns > 0); assert (exe_header_buffer->file_header.f_nscns <= - sizeof (exe_header_buffer->section_header) / - sizeof (exe_header_buffer->section_header[0])); + ARRAYELTS (exe_header_buffer->section_header)); assert (exe_header_buffer->file_header.f_opthdr > 0); ret = @@ -286,13 +285,6 @@ unexec (const char *outfile, const char *infile) int ret; int ret2; - if (bss_sbrk_did_unexec) - { - /* can only dump once */ - printf ("You can only dump Emacs once on this platform.\n"); - return; - } - report_sheap_usage (1); infile = add_exe_suffix_if_necessary (infile, infile_buffer); diff --git a/src/vm-limit.c b/src/vm-limit.c index bad1d61e611..f138dc28b2e 100644 --- a/src/vm-limit.c +++ b/src/vm-limit.c @@ -71,15 +71,6 @@ static char *data_space_start; /* Number of bytes of writable memory we can expect to be able to get. */ static size_t lim_data; -/* Return true if PTR cannot be represented as an Emacs Lisp object. */ -static bool -exceeds_lisp_ptr (void *ptr) -{ - return (! USE_LSB_TAG - && VAL_MAX < UINTPTR_MAX - && ((uintptr_t) ptr & ~DATA_SEG_BITS) >> VALBITS != 0); -} - #ifdef HAVE_GETRLIMIT # ifndef RLIMIT_AS @@ -222,9 +213,6 @@ check_memory_limits (void) else if (warnlevel > warned_85 && data_size < five_percent * 18) warnlevel = warned_85; } - - if (exceeds_lisp_ptr (cp)) - (*warn_function) ("Warning: memory in use exceeds lisp pointer size"); } /* Enable memory usage warnings. diff --git a/src/w32.c b/src/w32.c index 0892f932bc2..371cae9cb9b 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1707,7 +1707,7 @@ static unsigned num_of_processors; /* We maintain 1-sec samples for the last 16 minutes in a circular buffer. */ static struct load_sample samples[16*60]; static int first_idx = -1, last_idx = -1; -static int max_idx = sizeof (samples) / sizeof (samples[0]); +static int max_idx = ARRAYELTS (samples); static int buf_next (int from) @@ -2413,7 +2413,6 @@ unsetenv (const char *name) { char *var; size_t name_len; - int retval; if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { @@ -2512,7 +2511,7 @@ init_environment (char ** argv) int i; - const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]); + const int imax = ARRAYELTS (tempdirs); /* Implementation note: This function explicitly works with ANSI file names, not with UTF-8 encoded file names. This is because @@ -2585,7 +2584,7 @@ init_environment (char ** argv) {"LANG", NULL}, }; -#define N_ENV_VARS sizeof (dflt_envvars)/sizeof (dflt_envvars[0]) +#define N_ENV_VARS ARRAYELTS (dflt_envvars) /* We need to copy dflt_envvars[] and work on the copy because we don't want the dumped Emacs to inherit the values of @@ -8697,6 +8696,13 @@ w32_delayed_load (Lisp_Object library_id) /* Possibly truncated */ ? make_specified_string (name, -1, len, 1) : Qnil); + /* This prevents thread start and end notifications + from being sent to the DLL, for every thread we + start. We don't need those notifications because + threads we create never use any of these DLLs, only + the main thread uses them. This is supposed to + speed up thread creation. */ + DisableThreadLibraryCalls (dll_handle); break; } } @@ -9249,8 +9255,6 @@ ssize_t emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz) { int n, err; - SELECT_TYPE fdset; - struct timespec timeout; struct Lisp_Process *process = (struct Lisp_Process *)p; int fd = process->infd; diff --git a/src/w32fns.c b/src/w32fns.c index ffe63a3cf2d..77476757c2f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -723,8 +723,7 @@ w32_default_color_map (void) cmap = Qnil; - for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]); - pc++, i++) + for (i = 0; i < ARRAYELTS (w32_color_map); pc++, i++) cmap = Fcons (Fcons (build_string (pc->name), make_number (pc->colorref)), cmap); @@ -6869,24 +6868,33 @@ operations: specified DOCUMENT. \"find\" - initiate search starting from DOCUMENT, which must specify a directory. + \"delete\" - move DOCUMENT, a file or a directory, to Recycle Bin. + \"copy\" - copy DOCUMENT, which must be a file or a directory, into + the clipboard. + \"cut\" - move DOCUMENT, a file or a directory, into the clipboard. + \"paste\" - paste the file whose name is in the clipboard into DOCUMENT, + which must be a directory. + \"pastelink\" + - create a shortcut in DOCUMENT (which must be a directory) + the file or directory whose name is in the clipboard. \"runas\" - run DOCUMENT, which must be an excutable file, with elevated privileges (a.k.a. \"as Administrator\"). \"properties\" - - open the the property sheet dialog for DOCUMENT; works - for *.lnk desktop shortcuts, and little or nothing else. + - open the the property sheet dialog for DOCUMENT. nil - invoke the default OPERATION, or \"open\" if default is not defined or unavailable. DOCUMENT is typically the name of a document file or a URL, but can also be an executable program to run, or a directory to open in the -Windows Explorer. If it is a file, it must be a local one; this -function does not support remote file names. +Windows Explorer. If it is a file or a directory, it must be a local +one; this function does not support remote file names. If DOCUMENT is an executable program, the optional third arg PARAMETERS -can be a string containing command line parameters that will be passed -to the program. Some values of OPERATION also require parameters (e.g., -\"printto\" requires the printer address). Otherwise, PARAMETERS should -be nil or unspecified. +can be a string containing command line parameters, separated by blanks, +that will be passed to the program. Some values of OPERATION also require +parameters (e.g., \"printto\" requires the printer address). Otherwise, +PARAMETERS should be nil or unspecified. Note that double quote characters +in PARAMETERS must each be enclosed in 2 additional quotes, as in \"\"\". Optional fourth argument SHOW-FLAG can be used to control how the application will be displayed when it is invoked. If SHOW-FLAG is nil @@ -6904,11 +6912,13 @@ a ShowWindow flag: char *errstr; Lisp_Object current_dir = BVAR (current_buffer, directory);; wchar_t *doc_w = NULL, *params_w = NULL, *ops_w = NULL; +#ifdef CYGWIN intptr_t result; -#ifndef CYGWIN +#else int use_unicode = w32_unicode_filenames; char *doc_a = NULL, *params_a = NULL, *ops_a = NULL; Lisp_Object absdoc, handler; + BOOL success; struct gcpro gcpro1; #endif @@ -6936,7 +6946,48 @@ a ShowWindow flag: GUI_SDATA (current_dir), (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT)); + + if (result > 32) + return Qt; + + switch (result) + { + case SE_ERR_ACCESSDENIED: + errstr = w32_strerror (ERROR_ACCESS_DENIED); + break; + case SE_ERR_ASSOCINCOMPLETE: + case SE_ERR_NOASSOC: + errstr = w32_strerror (ERROR_NO_ASSOCIATION); + break; + case SE_ERR_DDEBUSY: + case SE_ERR_DDEFAIL: + errstr = w32_strerror (ERROR_DDE_FAIL); + break; + case SE_ERR_DDETIMEOUT: + errstr = w32_strerror (ERROR_TIMEOUT); + break; + case SE_ERR_DLLNOTFOUND: + errstr = w32_strerror (ERROR_DLL_NOT_FOUND); + break; + case SE_ERR_FNF: + errstr = w32_strerror (ERROR_FILE_NOT_FOUND); + break; + case SE_ERR_OOM: + errstr = w32_strerror (ERROR_NOT_ENOUGH_MEMORY); + break; + case SE_ERR_PNF: + errstr = w32_strerror (ERROR_PATH_NOT_FOUND); + break; + case SE_ERR_SHARE: + errstr = w32_strerror (ERROR_SHARING_VIOLATION); + break; + default: + errstr = w32_strerror (0); + break; + } + #else /* !CYGWIN */ + current_dir = ENCODE_FILE (current_dir); /* We have a situation here. If DOCUMENT is a relative file name, but its name includes leading directories, i.e. it lives not in @@ -6966,6 +7017,7 @@ a ShowWindow flag: if (use_unicode) { wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH]; + SHELLEXECUTEINFOW shexinfo_w; /* Encode filename, current directory and parameters, and convert operation to UTF-16. */ @@ -6999,14 +7051,28 @@ a ShowWindow flag: *d++ = *s++; *d = 0; } - result = (intptr_t) ShellExecuteW (NULL, ops_w, doc_w, params_w, - current_dir_w, - (INTEGERP (show_flag) - ? XINT (show_flag) : SW_SHOWDEFAULT)); + + /* Using ShellExecuteEx and setting the SEE_MASK_INVOKEIDLIST + flag succeeds with more OPERATIONs (a.k.a. "verbs"), as it is + able to invoke verbs from shortcut menu extensions, not just + static verbs listed in the Registry. */ + memset (&shexinfo_w, 0, sizeof (shexinfo_w)); + shexinfo_w.cbSize = sizeof (shexinfo_w); + shexinfo_w.fMask = + SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; + shexinfo_w.hwnd = NULL; + shexinfo_w.lpVerb = ops_w; + shexinfo_w.lpFile = doc_w; + shexinfo_w.lpParameters = params_w; + shexinfo_w.lpDirectory = current_dir_w; + shexinfo_w.nShow = + (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); + success = ShellExecuteExW (&shexinfo_w); } else { char document_a[MAX_PATH], current_dir_a[MAX_PATH]; + SHELLEXECUTEINFOA shexinfo_a; filename_to_ansi (SSDATA (current_dir), current_dir_a); filename_to_ansi (SSDATA (document), document_a); @@ -7021,51 +7087,27 @@ a ShowWindow flag: /* Assume OPERATION is pure ASCII. */ ops_a = SSDATA (operation); } - result = (intptr_t) ShellExecuteA (NULL, ops_a, doc_a, params_a, - current_dir_a, - (INTEGERP (show_flag) - ? XINT (show_flag) : SW_SHOWDEFAULT)); + memset (&shexinfo_a, 0, sizeof (shexinfo_a)); + shexinfo_a.cbSize = sizeof (shexinfo_a); + shexinfo_a.fMask = + SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; + shexinfo_a.hwnd = NULL; + shexinfo_a.lpVerb = ops_a; + shexinfo_a.lpFile = doc_a; + shexinfo_a.lpParameters = params_a; + shexinfo_a.lpDirectory = current_dir_a; + shexinfo_a.nShow = + (INTEGERP (show_flag) ? XINT (show_flag) : SW_SHOWDEFAULT); + success = ShellExecuteExA (&shexinfo_a); } -#endif /* !CYGWIN */ - if (result > 32) + if (success) return Qt; - switch (result) - { - case SE_ERR_ACCESSDENIED: - errstr = w32_strerror (ERROR_ACCESS_DENIED); - break; - case SE_ERR_ASSOCINCOMPLETE: - case SE_ERR_NOASSOC: - errstr = w32_strerror (ERROR_NO_ASSOCIATION); - break; - case SE_ERR_DDEBUSY: - case SE_ERR_DDEFAIL: - errstr = w32_strerror (ERROR_DDE_FAIL); - break; - case SE_ERR_DDETIMEOUT: - errstr = w32_strerror (ERROR_TIMEOUT); - break; - case SE_ERR_DLLNOTFOUND: - errstr = w32_strerror (ERROR_DLL_NOT_FOUND); - break; - case SE_ERR_FNF: - errstr = w32_strerror (ERROR_FILE_NOT_FOUND); - break; - case SE_ERR_OOM: - errstr = w32_strerror (ERROR_NOT_ENOUGH_MEMORY); - break; - case SE_ERR_PNF: - errstr = w32_strerror (ERROR_PATH_NOT_FOUND); - break; - case SE_ERR_SHARE: - errstr = w32_strerror (ERROR_SHARING_VIOLATION); - break; - default: - errstr = w32_strerror (0); - break; - } + errstr = w32_strerror (0); + +#endif /* !CYGWIN */ + /* The error string might be encoded in the locale's encoding. */ if (!NILP (Vlocale_coding_system)) { @@ -7485,8 +7527,8 @@ If the underlying system call fails, value is nil. */) (char *, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) = GetProcAddress (hKernel, "GetDiskFreeSpaceExA"); bool have_pfn_GetDiskFreeSpaceEx = - (w32_unicode_filenames && pfn_GetDiskFreeSpaceExW - || !w32_unicode_filenames && pfn_GetDiskFreeSpaceExA); + ((w32_unicode_filenames && pfn_GetDiskFreeSpaceExW) + || (!w32_unicode_filenames && pfn_GetDiskFreeSpaceExA)); /* On Windows, we may need to specify the root directory of the volume holding FILENAME. */ diff --git a/src/w32notify.c b/src/w32notify.c index 7155f16f3b0..86412b8a974 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -247,7 +247,6 @@ watch_worker (LPVOID arg) do { BOOL status; - DWORD sleep_result; DWORD bytes_ret = 0; if (dirwatch->dir) @@ -275,7 +274,7 @@ watch_worker (LPVOID arg) /* Sleep indefinitely until awoken by the I/O completion, which could be either a change notification or a cancellation of the watch. */ - sleep_result = SleepEx (INFINITE, TRUE); + SleepEx (INFINITE, TRUE); } while (!dirwatch->terminate); return 0; @@ -287,7 +286,6 @@ static struct notification * start_watching (const char *file, HANDLE hdir, BOOL subdirs, DWORD flags) { struct notification *dirwatch = xzalloc (sizeof (struct notification)); - HANDLE thr; dirwatch->signature = DIRWATCH_SIGNATURE; dirwatch->buf = xmalloc (16384); diff --git a/src/w32proc.c b/src/w32proc.c index 96f11657892..426a656f566 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1772,12 +1772,12 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) if (need_quotes) { int escape_char_run = 0; - char * first; - char * last; + /* char * first; */ + /* char * last; */ p = *targ; - first = p; - last = p + strlen (p) - 1; + /* first = p; */ + /* last = p + strlen (p) - 1; */ *parg++ = '"'; #if 0 /* This version does not escape quotes if they occur at the @@ -2249,10 +2249,9 @@ static BOOL CALLBACK find_child_console (HWND hwnd, LPARAM arg) { child_process * cp = (child_process *) arg; - DWORD thread_id; DWORD process_id; - thread_id = GetWindowThreadProcessId (hwnd, &process_id); + GetWindowThreadProcessId (hwnd, &process_id); if (process_id == cp->procinfo.dwProcessId) { char window_class[32]; diff --git a/src/w32term.c b/src/w32term.c index f914b5f8625..3aabf92357a 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -1078,10 +1078,7 @@ x_set_glyph_string_gc (struct glyph_string *s) s->stippled_p = s->face->stipple != 0; } else - { - s->gc = s->face->gc; - s->stippled_p = s->face->stipple != 0; - } + emacs_abort (); /* GC must have been set. */ eassert (s->gc != 0); @@ -4760,8 +4757,8 @@ w32_read_socket (struct terminal *terminal, width = rect.right - rect.left; text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width); text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height); - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); - columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); + /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */ + /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */ /* TODO: Clip size to the screen dimensions. */ @@ -5813,7 +5810,9 @@ x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) void x_focus_frame (struct frame *f) { +#if 0 struct w32_display_info *dpyinfo = &one_w32_display_info; +#endif /* Give input focus to frame. */ block_input (); diff --git a/src/xdisp.c b/src/xdisp.c index eb3a6df1fc5..067d9f6ac0e 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -22662,7 +22662,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, return decode_mode_spec_buf; no_value: { - char* p = decode_mode_spec_buf; + char *p = decode_mode_spec_buf; int pad = width - 2; while (pad-- > 0) *p++ = ' '; diff --git a/src/xfaces.c b/src/xfaces.c index 4271e47c36f..4e599d0bd05 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -273,10 +273,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface) -/* Value is the number of elements of VECTOR. */ - -#define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR)) - /* Size of hash table of realized faces in face caches (should be a prime number). */ @@ -515,7 +511,7 @@ DEFUN ("dump-colors", Fdump_colors, Sdump_colors, 0, 0, 0, fputc ('\n', stderr); - for (i = n = 0; i < sizeof color_count / sizeof color_count[0]; ++i) + for (i = n = 0; i < ARRAYELTS (color_count); ++i) if (color_count[i]) { fprintf (stderr, "%3d: %5d", i, color_count[i]); @@ -5093,14 +5089,14 @@ Value is ORDER. */) { Lisp_Object list; int i; - int indices[DIM (font_sort_order)]; + int indices[ARRAYELTS (font_sort_order)]; CHECK_LIST (order); memset (indices, 0, sizeof indices); i = 0; for (list = order; - CONSP (list) && i < DIM (indices); + CONSP (list) && i < ARRAYELTS (indices); list = XCDR (list), ++i) { Lisp_Object attr = XCAR (list); @@ -5122,9 +5118,9 @@ Value is ORDER. */) indices[i] = xlfd; } - if (!NILP (list) || i != DIM (indices)) + if (!NILP (list) || i != ARRAYELTS (indices)) signal_error ("Invalid font sort order", order); - for (i = 0; i < DIM (font_sort_order); ++i) + for (i = 0; i < ARRAYELTS (font_sort_order); ++i) if (indices[i] == 0) signal_error ("Invalid font sort order", order); @@ -6348,7 +6344,7 @@ DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */) int i; fprintf (stderr, "font selection order: "); - for (i = 0; i < DIM (font_sort_order); ++i) + for (i = 0; i < ARRAYELTS (font_sort_order); ++i) fprintf (stderr, "%d ", font_sort_order[i]); fprintf (stderr, "\n"); diff --git a/src/xfns.c b/src/xfns.c index 5dbc7053fd9..13b4c6e7879 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1641,12 +1641,12 @@ hack_wm_protocols (struct frame *f, Widget widget) #ifdef HAVE_X_I18N static XFontSet xic_create_xfontset (struct frame *); -static XIMStyle best_xim_style (XIMStyles *, XIMStyles *); +static XIMStyle best_xim_style (XIMStyles *); /* Supported XIM styles, ordered by preference. */ -static XIMStyle supported_xim_styles[] = +static const XIMStyle supported_xim_styles[] = { XIMPreeditPosition | XIMStatusArea, XIMPreeditPosition | XIMStatusNothing, @@ -1941,14 +1941,15 @@ xic_free_xfontset (struct frame *f) input method XIM. */ static XIMStyle -best_xim_style (XIMStyles *user, XIMStyles *xim) +best_xim_style (XIMStyles *xim) { int i, j; + int nr_supported = ARRAYELTS (supported_xim_styles); - for (i = 0; i < user->count_styles; ++i) + for (i = 0; i < nr_supported; ++i) for (j = 0; j < xim->count_styles; ++j) - if (user->supported_styles[i] == xim->supported_styles[j]) - return user->supported_styles[i]; + if (supported_xim_styles[i] == xim->supported_styles[j]) + return supported_xim_styles[i]; /* Return the default style. */ return XIMPreeditNothing | XIMStatusNothing; @@ -1956,42 +1957,41 @@ best_xim_style (XIMStyles *user, XIMStyles *xim) /* Create XIC for frame F. */ -static XIMStyle xic_style; - void create_frame_xic (struct frame *f) { XIM xim; XIC xic = NULL; XFontSet xfs = NULL; + XVaNestedList status_attr = NULL; + XVaNestedList preedit_attr = NULL; + XRectangle s_area; + XPoint spot; + XIMStyle xic_style; if (FRAME_XIC (f)) - return; + goto out; - /* Create X fontset. */ - xfs = xic_create_xfontset (f); xim = FRAME_X_XIM (f); - if (xim) - { - XRectangle s_area; - XPoint spot; - XVaNestedList preedit_attr; - XVaNestedList status_attr; + if (!xim) + goto out; - s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1; - spot.x = 0; spot.y = 1; + /* Determine XIC style. */ + xic_style = best_xim_style (FRAME_X_XIM_STYLES (f)); - /* Determine XIC style. */ - if (xic_style == 0) - { - XIMStyles supported_list; - supported_list.count_styles = (sizeof supported_xim_styles - / sizeof supported_xim_styles[0]); - supported_list.supported_styles = supported_xim_styles; - xic_style = best_xim_style (&supported_list, - FRAME_X_XIM_STYLES (f)); - } + /* Create X fontset. */ + if (xic_style & (XIMPreeditPosition | XIMStatusArea)) + { + xfs = xic_create_xfontset (f); + if (!xfs) + goto out; + FRAME_XIC_FONTSET (f) = xfs; + } + + if (xic_style & XIMPreeditPosition) + { + spot.x = 0; spot.y = 1; preedit_attr = XVaCreateNestedList (0, XNFontSet, xfs, XNForeground, @@ -2003,31 +2003,75 @@ create_frame_xic (struct frame *f) : NULL), &spot, NULL); + + if (!preedit_attr) + goto out; + } + + if (xic_style & XIMStatusArea) + { + s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1; status_attr = XVaCreateNestedList (0, - XNArea, - &s_area, - XNFontSet, - xfs, - XNForeground, - FRAME_FOREGROUND_PIXEL (f), - XNBackground, - FRAME_BACKGROUND_PIXEL (f), - NULL); - - xic = XCreateIC (xim, - XNInputStyle, xic_style, - XNClientWindow, FRAME_X_WINDOW (f), - XNFocusWindow, FRAME_X_WINDOW (f), - XNStatusAttributes, status_attr, - XNPreeditAttributes, preedit_attr, - NULL); - XFree (preedit_attr); - XFree (status_attr); + XNArea, + &s_area, + XNFontSet, + xfs, + XNForeground, + FRAME_FOREGROUND_PIXEL (f), + XNBackground, + FRAME_BACKGROUND_PIXEL (f), + NULL); + + if (!status_attr) + goto out; } + if (preedit_attr && status_attr) + xic = XCreateIC (xim, + XNInputStyle, xic_style, + XNClientWindow, FRAME_X_WINDOW (f), + XNFocusWindow, FRAME_X_WINDOW (f), + XNStatusAttributes, status_attr, + XNPreeditAttributes, preedit_attr, + NULL); + else if (preedit_attr) + xic = XCreateIC (xim, + XNInputStyle, xic_style, + XNClientWindow, FRAME_X_WINDOW (f), + XNFocusWindow, FRAME_X_WINDOW (f), + XNPreeditAttributes, preedit_attr, + NULL); + else if (status_attr) + xic = XCreateIC (xim, + XNInputStyle, xic_style, + XNClientWindow, FRAME_X_WINDOW (f), + XNFocusWindow, FRAME_X_WINDOW (f), + XNStatusAttributes, status_attr, + NULL); + else + xic = XCreateIC (xim, + XNInputStyle, xic_style, + XNClientWindow, FRAME_X_WINDOW (f), + XNFocusWindow, FRAME_X_WINDOW (f), + NULL); + + if (!xic) + goto out; + FRAME_XIC (f) = xic; FRAME_XIC_STYLE (f) = xic_style; - FRAME_XIC_FONTSET (f) = xfs; + xfs = NULL; /* Don't free below. */ + + out: + + if (xfs) + free_frame_xic (f); + + if (preedit_attr) + XFree (preedit_attr); + + if (status_attr) + XFree (status_attr); } diff --git a/src/xgselect.c b/src/xgselect.c index 1d3f916c9f8..5f71ff84014 100644 --- a/src/xgselect.c +++ b/src/xgselect.c @@ -41,7 +41,7 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, int have_wfds = wfds != NULL; GPollFD gfds_buf[128]; GPollFD *gfds = gfds_buf; - int gfds_size = sizeof gfds_buf / sizeof *gfds_buf; + int gfds_size = ARRAYELTS (gfds_buf); int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; int i, nfds, tmo_in_millisec; bool need_to_dispatch; diff --git a/src/xsmfns.c b/src/xsmfns.c index 9a31f518f30..81b012690f9 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c @@ -395,7 +395,7 @@ x_session_initialize (struct x_display_info *dpyinfo) { #define SM_ERRORSTRING_LEN 512 char errorstring[SM_ERRORSTRING_LEN]; - char* previous_id = NULL; + char *previous_id = NULL; SmcCallbacks callbacks; ptrdiff_t name_len = 0; diff --git a/src/xterm.c b/src/xterm.c index ae16e589f62..dd71a8a1986 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -308,7 +308,7 @@ int event_record_index; void record_event (char *locus, int type) { - if (event_record_index == sizeof (event_record) / sizeof (struct record)) + if (event_record_index == ARRAYELTS (event_record)) event_record_index = 0; event_record[event_record_index].locus = locus; @@ -968,10 +968,7 @@ x_set_glyph_string_gc (struct glyph_string *s) s->stippled_p = s->face->stipple != 0; } else - { - s->gc = s->face->gc; - s->stippled_p = s->face->stipple != 0; - } + emacs_abort (); /* GC must have been set. */ eassert (s->gc != 0); @@ -5627,7 +5624,7 @@ static int temp_index; static short temp_buffer[100]; #define STORE_KEYSYM_FOR_DEBUG(keysym) \ - if (temp_index == sizeof temp_buffer / sizeof (short)) \ + if (temp_index == ARRAYELTS (temp_buffer)) \ temp_index = 0; \ temp_buffer[temp_index++] = (keysym) @@ -7357,9 +7354,13 @@ x_bitmap_icon (struct frame *f, Lisp_Object file) #ifdef USE_GTK - if (xg_set_icon (f, xg_default_icon_file) - || xg_set_icon_from_xpm_data (f, gnu_xpm_bits)) - return 0; + if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id == -2 + || xg_set_icon (f, xg_default_icon_file) + || xg_set_icon_from_xpm_data (f, gnu_xpm_bits)) + { + FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2; + return 0; + } #elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) @@ -10102,7 +10103,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) }; int i; - const int atom_count = sizeof (atom_refs) / sizeof (atom_refs[0]); + const int atom_count = ARRAYELTS (atom_refs); /* 1 for _XSETTINGS_SN */ const int total_atom_count = 1 + atom_count; Atom *atoms_return = xmalloc (total_atom_count * sizeof *atoms_return); @@ -10161,6 +10162,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) #ifdef USE_LUCID { + XFontStruct *xfont = NULL; XrmValue d, fr, to; Font font; @@ -10174,8 +10176,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) x_catch_errors (dpy); if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL)) emacs_abort (); - if (x_had_errors_p (dpy) || !XQueryFont (dpy, font)) + if (x_had_errors_p (dpy) || !((xfont = XQueryFont (dpy, font)))) XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15"); + if (xfont) + XFreeFont (dpy, xfont); x_uncatch_errors (); } #endif diff --git a/src/xterm.h b/src/xterm.h index 50df88cb592..90d2e131717 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -996,7 +996,7 @@ extern Lisp_Object x_get_focus_frame (struct frame *); #ifdef USE_GTK extern int xg_set_icon (struct frame *, Lisp_Object); -extern int xg_set_icon_from_xpm_data (struct frame *, const char**); +extern int xg_set_icon_from_xpm_data (struct frame *, const char **); #endif /* USE_GTK */ extern void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); |