aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <[email protected]>2011-09-03 16:03:38 -0700
committerPaul Eggert <[email protected]>2011-09-03 16:03:38 -0700
commitb49e353d9d01adbe60bc5d0b1658b4ef978b0b06 (patch)
tree9f2ffa6f7a6562abf661a4951012b488ad8b1ae7 /src
parent74b880cbc18bd0194c7b1fc44c4a983ee05adae2 (diff)
parentbc3200871917d5c54c8c4299a06bf8f8ba2ea02d (diff)
Merge from trunk.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog1021
-rw-r--r--src/Makefile.in5
-rw-r--r--src/alloc.c106
-rw-r--r--src/bidi.c257
-rw-r--r--src/bidimirror.h365
-rw-r--r--src/biditype.h447
-rw-r--r--src/buffer.c101
-rw-r--r--src/callproc.c14
-rw-r--r--src/category.c2
-rw-r--r--src/ccl.c41
-rw-r--r--src/character.c10
-rw-r--r--src/character.h22
-rw-r--r--src/charset.c89
-rw-r--r--src/charset.h4
-rw-r--r--src/chartab.c29
-rw-r--r--src/cmds.c5
-rw-r--r--src/coding.c17
-rw-r--r--src/coding.h2
-rw-r--r--src/composite.c69
-rw-r--r--src/composite.h12
-rw-r--r--src/deps.mk2
-rw-r--r--src/dispextern.h43
-rw-r--r--src/dispnew.c134
-rw-r--r--src/doc.c37
-rw-r--r--src/editfns.c21
-rw-r--r--src/emacs.c41
-rw-r--r--src/eval.c65
-rw-r--r--src/fileio.c6
-rw-r--r--src/fns.c18
-rw-r--r--src/fontset.c10
-rw-r--r--src/frame.c38
-rw-r--r--src/frame.h4
-rw-r--r--src/fringe.c13
-rw-r--r--src/ftfont.c38
-rw-r--r--src/gmalloc.c64
-rw-r--r--src/gnutls.c416
-rw-r--r--src/gtkutil.c53
-rw-r--r--src/gtkutil.h7
-rw-r--r--src/image.c327
-rw-r--r--src/indent.c27
-rw-r--r--src/keyboard.c103
-rw-r--r--src/keyboard.h2
-rw-r--r--src/keymap.c48
-rw-r--r--src/keymap.h2
-rw-r--r--src/lisp.h31
-rw-r--r--src/lread.c48
-rw-r--r--src/macros.c4
-rw-r--r--src/makefile.w32-in3
-rw-r--r--src/minibuf.c2
-rw-r--r--src/nsfns.m42
-rw-r--r--src/nsfont.m2
-rw-r--r--src/nsmenu.m2
-rw-r--r--src/nsterm.h7
-rw-r--r--src/nsterm.m29
-rw-r--r--src/process.c121
-rw-r--r--src/regex.c11
-rw-r--r--src/region-cache.c84
-rw-r--r--src/region-cache.h12
-rw-r--r--src/scroll.c34
-rw-r--r--src/search.c61
-rw-r--r--src/syntax.c5
-rw-r--r--src/sysdep.c8
-rw-r--r--src/syssignal.h2
-rw-r--r--src/term.c175
-rw-r--r--src/termcap.c17
-rw-r--r--src/termhooks.h6
-rw-r--r--src/tparam.c26
-rw-r--r--src/unexcw.c5
-rw-r--r--src/unexmacosx.c37
-rw-r--r--src/w32term.c16
-rw-r--r--src/window.c20
-rw-r--r--src/xdisp.c639
-rw-r--r--src/xfaces.c178
-rw-r--r--src/xfns.c39
-rw-r--r--src/xgselect.c7
-rw-r--r--src/xml.c1
-rw-r--r--src/xrdb.c16
-rw-r--r--src/xselect.c316
-rw-r--r--src/xsmfns.c4
-rw-r--r--src/xterm.c93
80 files changed, 3539 insertions, 2701 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9e8aedfd36..f395363080 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,918 @@
+2011-09-03 Lars Magne Ingebrigtsen <[email protected]>
+
+ * Require libxml/parser.h to avoid compilation warning.
+
+ * emacs.c (shut_down_emacs): Call xmlCleanupParser on shutdown.
+
+ * xml.c (parse_region): Don't call xmlCleanupParser after parsing,
+ since this reportedly can destroy thread storage.
+
+2011-08-30 Chong Yidong <[email protected]>
+
+ * syntax.c (find_defun_start): Update all cache variables if
+ exiting early (Bug#9401).
+
+2011-08-30 Eli Zaretskii <[email protected]>
+
+ * image.c (x_bitmap_pixmap): Cast to int to avoid compiler warnings.
+
+ * xdisp.c (produce_stretch_glyph): No longer static, compiled also
+ when HAVE_WINDOW_SYSTEM is not defined. Support both GUI and TTY
+ frames. Call tty_append_glyph in the TTY case. (Bug#9402)
+
+ * term.c (tty_append_glyph): New function.
+ (produce_stretch_glyph): Static function and its prototype deleted.
+
+ * dispextern.h (produce_stretch_glyph, tty_append_glyph): Add
+ prototypes.
+
+2011-08-29 Paul Eggert <[email protected]>
+
+ * image.c (parse_image_spec): Check for nonnegative, not for positive,
+ when checking :margin (Bug#9390).
+ (IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR):
+ Renamed from IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
+ so that the name doesn't mislead. All uses changed.
+
+2011-08-28 Johan Bockgård <[email protected]>
+
+ * term.c (init_tty) [HAVE_GPM]: Move mouse settings after
+ set_tty_hooks.
+
+2011-08-27 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (move_it_to): Don't bail out early when reaching
+ position beyond to_charpos, if we are scanning backwards.
+ (move_it_vertically_backward): When DY == 0, make sure we get to
+ the first character in the line after the newline.
+
+2011-08-27 Paul Eggert <[email protected]>
+
+ * ccl.c: Improve and simplify overflow checking (Bug#9196).
+ (ccl_driver): Do not generate an out-of-range pointer.
+ (Fccl_execute_on_string): Remove unnecessary check for
+ integer overflow, noted by Stefan Monnier in
+ <http://lists.gnu.org/archive/html/emacs-devel/2011-08/msg00979.html>.
+ Remove a FIXME that didn't need fixing.
+ Simplify the newly-introduced buffer reallocation code.
+
+2011-08-27 Juanma Barranquero <[email protected]>
+
+ * makefile.w32-in ($(BLD)/alloc.$(O)): Depend on lib/verify.h.
+
+2011-08-26 Paul Eggert <[email protected]>
+
+ Integer and memory overflow issues (Bug#9196).
+
+ * doc.c (get_doc_string): Rework so that
+ get_doc_string_buffer_size is the actual buffer size, rather than
+ being 1 less than the actual buffer size; this makes xpalloc more
+ convenient.
+
+ * image.c (x_allocate_bitmap_record, cache_image):
+ * xselect.c (Fx_register_dnd_atom):
+ Simplify previous changes by using xpalloc.
+
+ * buffer.c (overlay_str_len): Now ptrdiff_t, not EMACS_INT,
+ since either will do and ptrdiff_t is convenient with xpalloc.
+
+ * charset.c (charset_table_size)
+ (struct charset_sort_data.priority): Now ptrdiff_t.
+ (charset_compare): Don't overflow if priorities differ greatly.
+ (Fsort_charsets): Don't assume list length fits in int.
+ Check for size-calculation overflow when allocating sort data.
+ (syms_of_charset): Allocate an initial charset table that is
+ just under 64 KiB, to avoid problems with glibc malloc and mmap.
+
+ * cmds.c (internal_self_insert): Check for size-calculation overflow.
+
+ * composite.h (struct composition.glyph_len): Now int, not unsigned.
+ The actual value is always <= INT_MAX, and leaving it unsigned made
+ overflow checking harder.
+
+ * dispextern.h (struct glyph_matrix.rows_allocated)
+ (struct face_cache.size): Now ptrdiff_t, for convenience in use
+ with xpalloc. The values are still always <= INT_MAX.
+
+ * indent.c (compute_motion): Adjust to region_cache_forward sig change.
+
+ * lisp.h (xnmalloc, xnrealloc, xpalloc): New decls.
+ (SAFE_NALLOCA): New macro.
+
+ * region-cache.c (struct boundary.pos, find_cache_boundary)
+ (move_cache_gap, insert_cache_boundary, delete_cache_boundaries)
+ (set_cache_region, invalidate_region_cache)
+ (revalidate_region_cache, know_region_cache, region_cache_forward)
+ (region_cache_backward, pp_cache):
+ Use ptrdiff_t, not EMACS_INT, since either will do. This is needed
+ so that ptrdiff_t * can be passed to xpalloc.
+ (struct region_cache): Similarly, for gap_start, gap_len, cache_len,
+ beg_unchanged, end_unchanged, buffer_beg, buffer_end members.
+ (pp_cache): Don't assume cache_len fits in int.
+ * region-cache.h: Adjust extern decls to match.
+
+ * search.c (scan_buffer, Freplace_match): Use ptrdiff_t, not
+ EMACS_INT, since either will do, for xpalloc.
+
+ * alloc.c: Include verify.h, and check that int fits in ptrdiff_t.
+ (xnmalloc, xnrealloc, xpalloc): New functions.
+
+ * bidi.c (bidi_shelve_header_size): New constant.
+ (bidi_cache_ensure_space, bidi_shelve_cache): Use it.
+ (bidi_cache_ensure_space): Avoid integer overflow when allocating.
+
+ * bidi.c (bidi_cache_shrink):
+ * buffer.c (overlays_at, overlays_in, record_overlay_string)
+ (overlay_strings):
+ Don't update size of array until after memory allocation succeeds,
+ because xmalloc/xrealloc may not return.
+ (struct sortstrlist.bytes): Now ptrdiff_t, as EMACS_INT doesn't help
+ now that we have proper integer overflow checking.
+ (record_overlay_string, overlay_strings): Catch overflows when
+ calculating size of overlay_str_buf.
+
+ * callproc.c (Fcall_process): Check for size overflow when
+ calculating size of args2.
+ (child_setup): Avoid overflow by using size_t rather than ptrdiff_t.
+ Normally we prefer signed values, but sticking with ptrdiff_t would
+ require adding more-complicated checks.
+
+ * ccl.c (Fccl_execute_on_string): Check for memory overflow.
+ Use ptrdiff_t rather than EMACS_INT where ptrdiff_t will do.
+ Redo buffer-overflow calculations to avoid integer overflow.
+ Add a FIXME comment where memory seems to be over-allocated.
+
+ * character.c (Fstring): Check for size-calculation overflow.
+
+ * coding.c (produce_chars): Redo buffer-overflow calculations to avoid
+ unnecessary integer overflow. Check for size overflow.
+ (encode_coding_object): Don't update size until xmalloc succeeds.
+
+ * composite.c (get_composition_id): Check for overflow in glyph
+ length calculations.
+
+ Integer and memory overflow fixes for display code.
+ * dispextern.h (struct glyph_pool.nglyphs): Now ptrdiff_t, not int.
+ * dispnew.c (adjust_glyph_matrix, realloc_glyph_pool)
+ (scrolling_window): Check for overflow in size calculations.
+ (line_draw_cost, realloc_glyph_pool, add_row_entry):
+ Don't assume glyph table len fits in int.
+ (struct row_entry.bucket, row_entry_pool_size, row_entry_idx)
+ (row_table_size): Now ptrdiff_t, not int.
+ (scrolling_window): Avoid overflow in size calculations.
+ Don't update size until allocation succeeds.
+ * fns.c (concat): Check for overflow in size calculations.
+ (next_almost_prime): Verify NEXT_ALMOST_PRIME_LIMIT.
+ * lisp.h (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros.
+ (NEXT_ALMOST_PRIME_LIMIT): New constant.
+
+ * doc.c (get_doc_string_buffer_size): Now ptrdiff_t, not int.
+ (get_doc_string): Check for size calculation overflow.
+ Don't update size until allocation succeeds.
+ (get_doc_string, Fsubstitute_command_keys): Use ptrdiff_t, not
+ EMACS_INT, where ptrdiff_t will do.
+ (Fsubstitute_command_keys): Check for string overflow.
+
+ * editfns.c (set_time_zone_rule): Don't assume environment length
+ fits in int.
+ (message_length): Now ptrdiff_t, not int.
+ (Fmessage_box): Don't update size until allocation succeeds.
+ Don't assume message length fits in int.
+ (Fformat): Use ptrdiff_t, not EMACS_INT, where ptrdiff_t will do.
+
+ * emacs.c (main): Do not reallocate argv, since there is a null at
+ the end that can be overwritten, and this way there's no need to
+ worry about size-calculation overflow.
+ (sort_args): Check for size-calculation overflow.
+
+ * eval.c (init_eval_once, grow_specpdl): Don't update size until
+ alloc succeeds.
+ (call_debugger, grow_specpdl): Redo calculations to avoid overflow.
+
+ * frame.c (set_menu_bar_lines, x_set_frame_parameters)
+ (x_set_scroll_bar_width, x_figure_window_size):
+ Check for integer overflow.
+ (x_set_alpha): Do not assume XINT fits in int.
+
+ * frame.h (struct frame): Use int, not EMACS_INT, where int works.
+ This is for the members text_lines, text_cols, total_lines, total_cols,
+ where the system imposes an 'int' limit.
+
+ * fringe.c (Fdefine_fringe_bitmap):
+ Don't update size until alloc works.
+
+ * ftfont.c (ftfont_get_open_type_spec, setup_otf_gstring)
+ (ftfont_shape_by_flt): Check for integer overflow in size calculations.
+
+ * gtkutil.c (get_utf8_string, xg_store_widget_in_map):
+ Check for size-calculation overflow.
+ (get_utf8_string): Use ptrdiff_t, not size_t, where either will
+ do, as we prefer signed integers.
+ (id_to_widget.max_size, id_to_widget.used)
+ (xg_store_widget_in_map, xg_remove_widget_from_map)
+ (xg_get_widget_from_map, xg_get_scroll_id_for_window)
+ (xg_remove_scroll_bar, xg_update_scrollbar_pos):
+ Use and return ptrdiff_t, not int.
+ (xg_gtk_scroll_destroy): Don't assume ptrdiff_t fits in int.
+ * gtkutil.h: Change prototypes to match the above.
+
+ * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these
+ are duplicate now that they've been promoted to lisp.h.
+ (x_allocate_bitmap_record, x_alloc_image_color)
+ (make_image_cache, cache_image, xpm_load):
+ Don't update size until alloc is done.
+ (xpm_load, lookup_rgb_color, lookup_pixel_color, x_to_xcolors)
+ (x_detect_edges):
+ Check for size calculation overflow.
+ (ct_colors_allocated_max): New constant.
+ (x_to_xcolors, x_detect_edges): Reorder multiplicands to avoid
+ overflow.
+
+ * keyboard.c (read_char, menu_bar_items, tool_bar_items)
+ (read_char_x_menu_prompt, read_char_minibuf_menu_width)
+ (read_char_minibuf_menu_prompt, follow_key, read_key_sequence):
+ Use ptrdiff_t, not int, to count maps.
+ (read_char_minibuf_menu_prompt): Check for overflow in size
+ calculations. Don't update size until allocation succeeds. Redo
+ calculations to avoid overflow.
+ * keyboard.h: Change prototypes to match the above.
+
+ * keymap.c (cmm_size, current_minor_maps): Use ptrdiff_t, not int,
+ to count maps.
+ (current_minor_maps): Check for size calculation overflow.
+ * keymap.h: Change prototypes to match the above.
+
+ * lread.c (read1, init_obarray): Don't update size until alloc done.
+
+ * macros.c (Fstart_kbd_macro): Don't update size until alloc done.
+ (store_kbd_macro_char): Reorder multiplicands to avoid overflow.
+
+ * nsterm.h (struct ns_color_table.size, struct ns_color_table.avail):
+ Now ptrdiff_t, not int.
+ * nsterm.m (ns_index_color): Use ptrdiff_t, not int, for table indexes.
+ (ns_draw_fringe_bitmap): Rewrite to avoid overflow.
+
+ * process.c (Fnetwork_interface_list): Check for overflow
+ in size calculation.
+
+ * region-cache.c (move_cache_gap): Check for size calculation overflow.
+
+ * scroll.c (do_line_insertion_deletion_costs): Check for size calc
+ overflow. Don't bother calling xmalloc when xrealloc will do.
+
+ * search.c (Freplace_match): Check for size calculation overflow.
+ (Fset_match_data): Don't assume list lengths fit in 'int'.
+
+ * sysdep.c (system_process_attributes): Use ptrdiff_t, not int,
+ for command line length. Do not attempt to address one before the
+ beginning of an array, as that's not portable.
+
+ * term.c (max_frame_lines): Remove; unused.
+ (encode_terminal_src_size, encode_terminal_dst_size): Now ptrdiff_t,
+ not int.
+ (encode_terminal_code, calculate_costs): Check for size
+ calculation overflow.
+ (encode_terminal_code): Use ptrdiff_t, not int, to record glyph
+ table lengths and related sizes. Don't update size until alloc
+ done. Redo calculations to avoid overflow.
+ (calculate_costs): Don't bother calling xmalloc when xrealloc will do.
+
+ * termcap.c (tgetent): Use ptrdiff_t, not int, to record results of
+ subtracting pointers.
+ (gobble_line): Check for overflow more carefully. Don't update size
+ until alloc done.
+
+ * tparam.c (tparam1): Use ptrdiff_t, not int, for sizes.
+ Don't update size until alloc done.
+ Redo size calculations to avoid overflow.
+ Check for size calculation overflow.
+ (main) [DEBUG]: Fix typo in invoking tparam1.
+
+ * xdisp.c (store_mode_line_noprop_char, x_consider_frame_title):
+ Use ptrdiff_t, not int, for sizes.
+ (store_mode_line_noprop_char): Don't update size until alloc done.
+
+ * xfaces.c (lface_id_to_name_size, Finternal_make_lisp_face):
+ Use ptrdiff_t, not int, for sizes.
+ (Finternal_make_lisp_face, cache_face):
+ Check for size calculation overflow.
+ (cache_face): Treat size calculation overflows as if they were
+ memory exhaustion (the usual treatment), rather than aborting.
+
+ * xfns.c (x_encode_text, x_set_name_internal)
+ (Fx_change_window_property): Use ptrdiff_t, not int, to count
+ sizes, since they can exceed INT_MAX in size. Check for size
+ calculation overflow.
+
+ * xgselect.c (gfds_size): Now ptrdiff_t, for convenience with xpalloc.
+ (xg_select): Check for size calculation overflow.
+ Don't update size until alloc done.
+
+ * xrdb.c (get_environ_db): Don't assume path length fits in int,
+ as sprintf is limited to int lengths.
+
+ * xselect.c (X_LONG_SIZE, X_SHRT_MAX, X_SHRT_MIN, X_LONG_MAX)
+ (X_LONG_MIN): New macros.
+ Use them to make the following changes clearer.
+ (MAX_SELECTION_QUANTUM): Make the other bounds on this value clearer.
+ This change doesn't affect the value now, but it may help remind
+ future maintainers not to raise the value too much later.
+ (SELECTION_QUANTUM): Remove, replacing with ...
+ (selection_quantum): ... new function, which avoids overflow.
+ All uses changed.
+ (struct selection_data.size): Now ptrdiff_t, not int, to avoid
+ assumption that selection length fits in 'int'.
+ (x_reply_selection_request, x_handle_selection_request)
+ (x_get_window_property, receive_incremental_selection)
+ (x_get_window_property_as_lisp_data, selection_data_to_lisp_data)
+ (lisp_data_to_selection_data, clean_local_selection_data):
+ Use ptrdiff_t, not int, to record length of selection.
+ (x_reply_selection_request, x_get_window_property)
+ (receive_incremental_selection, x_property_data_to_lisp):
+ Redo calculations to avoid overflow.
+ (x_reply_selection_request): When sending hint, ceiling it at
+ X_LONG_MAX rather than relying on wraparound overflow to send
+ something.
+ (x_get_window_property, receive_incremental_selection)
+ (lisp_data_to_selection_data, x_property_data_to_lisp):
+ Check for size-calculation overflow.
+ (x_get_window_property, receive_incremental_selection)
+ (lisp_data_to_selection_data, Fx_register_dnd_atom):
+ Don't store size until memory allocation succeeds.
+ (x_get_window_property): Plug memory leak on memory exhaustion.
+ Don't double-block input; malloc is safe here. Don't assume 2**34
+ - 4 fits in unsigned long. Add an xassert to check
+ XGetWindowProperty overflow. Be more careful about overflow
+ calculations, and distinguish size from memory overflow better.
+ (receive_incremental_selection): When tracing, don't assume
+ unsigned int is less than INT_MAX.
+ (x_selection_data_to_lisp_data): Remove unnecessary (and in theory
+ harmful) conversions of unsigned short to int.
+ (lisp_data_to_selection_data): Don't assume that integers
+ in the range -65535 through -1 fit in an X unsigned short.
+ Don't assume that ULONG_MAX == X_ULONG_MAX. Don't store into
+ result parameters unless successful. Rely on cons_to_unsigned
+ to report problems with elements; the old code wasn't right anyway.
+ (x_check_property_data): Check for int overflow; we cannot use
+ a wider type due to X limits.
+ (x_handle_dnd_message): Use unsigned int, to avoid int overflow.
+
+ * xsmfns.c (smc_save_yourself_CB): Check for size calc overflow.
+
+ * xterm.c (x_color_cells, x_send_scrollbar_event, handle_one_xevent)
+ (x_term_init): Check for size calculation overflow.
+ (x_color_cells): Don't store size until memory allocation succeeds.
+ (handle_one_xevent): Use ptrdiff_t, not int, for byte counts.
+ Don't assume alloca size is less than MAX_ALLOCA.
+ (x_term_init): Don't assume length fits in int (sprintf is limited
+ to int size).
+
+ Use ptrdiff_t for composition IDs.
+ * character.c (lisp_string_width):
+ * composite.c (composition_table_size, n_compositions)
+ (get_composition_id, composition_gstring_from_id):
+ * dispextern.h (struct glyph_string.cmp_id, struct composition_it.id):
+ * xdisp.c (BUILD_COMPOSITE_GLYPH_STRING):
+ * window.c (Frecenter):
+ Use ptrdiff_t, not int, for composition IDs.
+ * composite.c (get_composition_id): Check for integer overflow.
+ * composite.h: Adjust prototypes to match the above changes.
+
+ Use ptrdiff_t for hash table indexes.
+ * category.c (hash_get_category_set):
+ * ccl.c (ccl_driver):
+ * charset.h (struct charset.hash_index, CHECK_CHARSET_GET_ID):
+ * coding.c (coding_system_charset_list, detect_coding_system):
+ * coding.h (struct coding_system.id):
+ * composite.c (get_composition_id, gstring_lookup_cache):
+ * fns.c (hash_lookup, hash_put, Fgethash, Fputhash):
+ * image.c (xpm_get_color_table_h):
+ * lisp.h (hash_lookup, hash_put):
+ * minibuf.c (Ftest_completion):
+ Use ptrdiff_t for hash table indexes, not int (which is too
+ narrow, on 64-bit hosts) or EMACS_INT (which is too wide, on
+ 32-bit --with-wide-int hosts).
+
+ * charset.c (Fdefine_charset_internal): Check for integer overflow.
+ Add a FIXME comment about memory leaks.
+ (syms_of_charset): Don't assume xmalloc returns.
+
+ Don't assume that stated character widths fit in int.
+ * character.c (Fchar_width, c_string_width, lisp_string_width):
+ * character.h (CHAR_WIDTH):
+ * indent.c (MULTIBYTE_BYTES_WIDTH):
+ Use sanitize_char_width to avoid undefined and/or bad behavior
+ with outlandish widths.
+ * character.h (sanitize_tab_width): Renamed from sanitize_width,
+ now that we have two such functions. All uses changed.
+ (sanitize_char_width): New inline function.
+
+ Don't assume that tab-width fits in int.
+ * character.h (sanitize_width): New inline function.
+ (SANE_TAB_WIDTH): New macro.
+ (ASCII_CHAR_WIDTH): Use it.
+ * indent.c (sane_tab_width): Remove. All uses replaced by
+ SANE_TAB_WIDTH (current_buffer).
+ * xdisp.c (init_iterator): Use SANE_TAB_WIDTH.
+
+ * fileio.c: Integer overflow issues with file modes.
+ (Fset_file_modes, auto_save_1): Don't assume EMACS_INT fits in int.
+
+ * charset.c (read_hex): New arg OVERFLOW. All uses changed.
+ Remove unreachable code.
+ (read_hex, load_charset_map_from_file): Check for integer overflow.
+
+ * xterm.c: don't go over XClientMessageEvent limit
+ (scroll_bar_windows_size): Now ptrdiff_t, as we prefer signed.
+ (x_send_scroll_bar_event): Likewise. Check that the size does not
+ exceed limits imposed by XClientMessageEvent, as well as the usual
+ ptrdiff_t and size_t limits.
+
+ * keyboard.c: Overflow, signedness and related fixes.
+ (make_lispy_movement): Use same integer type in forward decl
+ that is used in the definition.
+ (read_key_sequence, keyremap_step):
+ Change bufsize argument back to int, undoing my 2011-03-30 change.
+ We prefer signed types, and int is wide enough here.
+ (parse_tool_bar_item): Don't assume tool_bar_max_label_size is less
+ than TYPE_MAXIMUM (EMACS_INT) / 2. Don't let the label size grow
+ larger than STRING_BYTES_BOUND. Use ptrdiff_t for Emacs string
+ length, not size_t. Use ptrdiff_t for index, not int.
+ (keyremap_step, read_key_sequence): Redo bufsize check to avoid
+ possibility of integer overflow.
+
+ Overflow, signedness and related fixes for images.
+
+ * dispextern.h (struct it.stack[0].u.image.image_id)
+ (struct_it.image_id, struct image.id, struct image_cache.size)
+ (struct image_cache.used, struct image_cache.ref_count):
+ * gtkutil.c (update_frame_tool_bar):
+ * image.c (x_reference_bitmap, Fimage_size, Fimage_mask_p)
+ (Fimage_metadata, free_image_cache, clear_image_cache, lookup_image)
+ (cache_image, mark_image_cache, x_kill_gs_process, Flookup_image):
+ * nsmenu.m (update_frame_tool_bar):
+ * xdisp.c (calc_pixel_width_or_height):
+ * xfns.c (image_cache_refcount):
+ Image IDs are now ptrdiff_t, not int, to avoid arbitrary limits
+ on typical 64-bit hosts.
+
+ * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros.
+ (x_bitmap_pixmap, x_create_x_image_and_pixmap):
+ Omit unnecessary casts to int.
+ (parse_image_spec): Check that integers fall into 'int' range
+ when the callers expect that.
+ (image_ascent): Redo ascent calculation to avoid int overflow.
+ (clear_image_cache): Avoid overflow when sqrt (INT_MAX) < nimages.
+ (lookup_image): Remove unnecessary tests.
+ (xbm_image_p): Locals are now of int, not EMACS_INT,
+ since parse_image_check makes sure they fit into int.
+ (png_load, gif_load, svg_load_image):
+ Prefer int to unsigned where either will do.
+ (tiff_handler): New function, combining the cores of the
+ old tiff_error_handler and tiff_warning_handler. This
+ function is rewritten to use vsnprintf and thereby avoid
+ stack buffer overflows. It uses only the features of vsnprintf
+ that are common to both POSIX and native Microsoft.
+ (tiff_error_handler, tiff_warning_handler): Use it.
+ (tiff_load, gif_load, imagemagick_load_image):
+ Don't assume :index value fits in 'int'.
+ (gif_load): Omit unnecessary cast to double, and avoid double-rounding.
+ (imagemagick_load_image): Check that crop parameters fit into
+ the integer types that MagickCropImage accepts. Don't assume
+ Vimagemagick_render_type has a nonnegative value. Don't assume
+ size_t fits in 'long'.
+ (gs_load): Use printmax_t to print the widest integers possible.
+ Check for integer overflow when computing image height and width.
+
+2011-08-26 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (redisplay_window): Don't force window start if point
+ will be invisible in the resulting window. (Bug#9324)
+
+2011-08-25 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (compute_display_string_pos): Return 2 in DISP_PROP when
+ the display spec is of the form `(space ...)'.
+ (handle_display_spec): Return the value returned by
+ handle_single_display_spec, not just 1 or zero.
+ (handle_single_display_spec): If the display spec is of the form
+ `(space ...)', and specifies display in the text area, return 2
+ rather than 1.
+ (try_cursor_movement): Check for the need to scroll more
+ accurately, and prefer exact match for point under bidi. Don't
+ advance `row' beyond the last row of the window.
+
+ * dispextern.h (struct bidi_it): Rename the disp_prop_p member
+ into disp_prop; all users changed.
+
+ * bidi.c (bidi_fetch_char): If compute_display_string_pos returns
+ DISP_PROP = 2, substitute the u+2029 PARAGRAPH SEPARATOR character
+ for the text covered by the display property.
+
+2011-08-25 Chong Yidong <[email protected]>
+
+ * buffer.c (Fbury_buffer_internal): Rename from Funrecord_buffer.
+ Change return value to nil.
+ (Frecord_buffer): Delete unused function.
+
+2011-08-24 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (Fcurrent_bidi_paragraph_direction): For unibyte
+ buffers, return left-to-right.
+ (set_cursor_from_row): Consider candidate row a win if its glyph
+ represents a newline and point is on that newline. Fixes cursor
+ positioning on the newline at EOL of R2L text within L2R
+ paragraph, and vice versa.
+ (try_cursor_movement): Check continued rows, in addition to
+ continuation rows. Fixes unwarranted scroll when point enters a
+ continued line of R2L text within an L2R paragraph, or vice versa.
+ (cursor_row_p): Consider the case of point being equal to
+ MATRIX_ROW_END_CHARPOS. Prevents cursor being stuck when moving
+ from the end of a short line to the beginning of a continued line
+ of R2L text within L2R paragraph.
+ (RECORD_MAX_MIN_POS): For max_pos, use IT_CHARPOS even for
+ composed characters.
+
+ * bidi.c (bidi_check_type): Use xassert.
+ (bidi_cache_iterator_state): Update the disp_pos and disp_prop_p
+ members.
+
+2011-08-23 Eli Zaretskii <[email protected]>
+
+ * bidi.c (bidi_get_type): Abort if we get zero as the bidi type of
+ a character.
+
+2011-08-23 Chong Yidong <[email protected]>
+
+ * nsfont.m (ns_otf_to_script): Fix typo.
+
+2011-08-22 Kenichi Handa <[email protected]>
+
+ * chartab.c (Fset_char_table_extra_slot): Do not inhibit setting a
+ extra slot even if the purpose is char-code-property-table.
+
+2011-08-23 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (redisplay_window): When computing centering_position,
+ account for the height of the header line. (Bug#8874)
+
+ * dispnew.c (buffer_posn_from_coords): Use buf_charpos_to_bytepos
+ instead of CHAR_TO_BYTE. Fixes a crash when a completion
+ candidate is selected by the mouse, and that candidate has a
+ composed character under the mouse.
+
+ * xdisp.c (x_produce_glyphs): Set it->nglyphs to 1. Fixes pixel
+ coordinates reported by pos-visible-in-window-p for a composed
+ character in column zero.
+
+2011-08-23 Stefan Monnier <[email protected]>
+
+ * cmds.c (Fself_insert_command): Mention post-self-insert-hook.
+
+2011-08-22 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (BUFFER_POS_REACHED_P): If this is a composition,
+ consider it a hit if to_charpos is anywhere in the range of the
+ composed buffer positions.
+
+2011-08-22 Chong Yidong <[email protected]>
+
+ * image.c (gif_load): Don't assume that each subimage has the same
+ dimensions as the base image. Handle disposal method that is
+ "undefined" by the gif spec (Bug#9335).
+
+2011-08-20 Chong Yidong <[email protected]>
+
+ * eval.c (Fsignal): Handle `debug' symbol in error handler (Bug#9329).
+ (Fcondition_case): Document `debug' symbol in error handler.
+
+2011-08-19 Eli Zaretskii <[email protected]>
+
+ * xfaces.c (face_at_buffer_position): Avoid repeated evaluation of
+ face ID by FACE_FROM_ID, and avoid a crash when mouse is moved
+ from an Org mode buffer to a Speedbar frame.
+
+ * xdisp.c (RECORD_MAX_MIN_POS): If the display element comes from
+ a composition, take its buffer position from IT->cmp_it.charpos.
+ Fixes cursor positioning at the beginning of a line that begins
+ with a composed character.
+
+2011-08-18 Eli Zaretskii <[email protected]>
+
+ * bidi.c (bidi_get_type): If bidi_type_table reports zero as the
+ character bidirectional type, use STRONG_L instead. Fixes crashes
+ in a buffer produced by `describe-categories'.
+
+ * dispextern.h (struct bidi_it): Move disp_pos and disp_prop_p
+ members before the level stack, so they would be saved and
+ restored when copying iterator state. Fixes incorrect reordering
+ around TABs covered by display properties.
+
+2011-08-18 Andreas Schwab <[email protected]>
+
+ * process.c (Fnetwork_interface_list): Correctly determine buffer
+ size.
+
+2011-08-17 Chong Yidong <[email protected]>
+
+ * eval.c (internal_condition_case, internal_condition_case_1)
+ (internal_condition_case_2, internal_condition_case_n):
+ Remove unnecessary aborts (Bug#9081).
+
+2011-08-17 Eli Zaretskii <[email protected]>
+
+ * lread.c (Fload) [DOS_NT]: If `openp' returns -2, but the file
+ has no `load' handler, try opening the file locally. (Bug#9311)
+
+2011-08-16 Ken Brown <[email protected]>
+
+ * gmalloc.c: Expand comment.
+
+2011-08-16 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (set_cursor_from_row): Don't accept a previous candidate
+ if it fails the cursor_row_p test. Fixes cursor positioning at ZV.
+
+2011-08-16 Ken Brown <[email protected]>
+
+ Fix memory allocation problems in Cygwin build (Bug#9273).
+
+ * unexcw.c ( __malloc_initialized): Declare external variable.
+ (fixup_executable): Force the dumped emacs to reinitialize malloc.
+
+ * gmalloc.c [CYGWIN] (bss_sbrk_heapbase, bss_sbrk_heapinfo):
+ New variables.
+ (malloc_initialize_1) [CYGWIN]: Prepare for reinitializing the
+ dumped emacs.
+ (_free_internal_nolock) [CYGWIN]: Ignore requests to free storage
+ in the static heap.
+ [CYGWIN] (special_realloc): New function.
+ (_realloc_internal_nolock) [CYGWIN]: Use the new function on
+ requests to realloc storage in the static heap.
+
+2011-08-15 Paul Eggert <[email protected]>
+
+ * bidi.c (bidi_initialize): Remove unused local.
+
+2011-08-15 Eli Zaretskii <[email protected]>
+
+ * biditype.h: File removed.
+
+ * bidimirror.h: File removed.
+
+ * deps.mk (bidi.o): Remove biditype.h and
+ bidimirror.h.
+
+ * makefile.w32-in ($(BLD)/bidi.$(O)): Remove biditype.h and
+ bidimirror.h.
+
+ * dispextern.h: Fix a typo in the comment to bidi_type_t.
+
+ * chartab.c: Improve commentary for the uniprop_table API.
+
+ * bidi.c (bidi_paragraph_init): Support zero value of
+ bidi_ignore_explicit_marks_for_paragraph_level.
+ (bidi_initialize): Use uniprop_table instead of including
+ biditype.h and bidimirror.h.
+
+ * xdisp.c (move_it_in_display_line_to): Don't reset pixel
+ coordinates of the iterator when restoring from ppos_it.
+ (Bug#9296)
+
+2011-08-14 Kenichi Handa <[email protected]>
+
+ * process.c (create_process): Call setup_process_coding_systems
+ after the pid of the process is set to -1 (Bug#8162).
+
+2011-08-14 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (move_it_in_display_line_to): Don't invoke
+ IT_RESET_X_ASCENT_DESCENT when iterator position was restored from
+ ppos_it. Fixes vertical cursor motion when line beginning is
+ covered by an image. (Bug#9296)
+
+2011-08-14 Jan Djärv <[email protected]>
+
+ * nsterm.h (ns_run_ascript): Declare.
+ (NSAPP_DATA2_RUNASSCRIPT): Define.
+
+ * nsfns.m (as_script, as_result, as_status): New static variables.
+ (ns_run_ascript): New function.
+ (Fns_do_applescript): Set variables as_*. Make an NSApplicationDefined
+ event with data2 set to NSAPP_DATA2_RUNASSCRIPT, post it and then start
+ the event loop. Get status from as_status (Bug#7276).
+
+ * nsterm.m (sendEvent): If event is NSApplicationDefined and
+ data2 is NSAPP_DATA2_RUNASSCRIPT, call ns_run_ascript and then exit
+ the event loop (Bug#7276).
+
+2011-08-14 Andreas Schwab <[email protected]>
+
+ * gnutls.c (QCgnutls_bootprop_priority)
+ (QCgnutls_bootprop_trustfiles, QCgnutls_bootprop_keylist)
+ (QCgnutls_bootprop_crlfiles, QCgnutls_bootprop_callbacks)
+ (QCgnutls_bootprop_loglevel, QCgnutls_bootprop_hostname)
+ (QCgnutls_bootprop_min_prime_bits, QCgnutls_bootprop_verify_flags)
+ (QCgnutls_bootprop_verify_hostname_error)
+ (QCgnutls_bootprop_callbacks_verify): Rename from
+ Qgnutls_bootprop_..., all uses changed.
+
+ * xfaces.c (QCignore_defface): Rename from Qignore_defface, all
+ uses changed.
+
+2011-08-14 Paul Eggert <[email protected]>
+
+ * xfaces.c (Qframe_set_background_mode): Now static.
+ * dispextern.h (Qframe_set_background_mode): Remove decl.
+
+ * process.c (Fnetwork_interface_info): Declare local only if needed.
+
+2011-08-13 Jan Djärv <[email protected]>
+
+ * process.c: Include ifaddrs.h and net/if_dl.h if available (Bug#8477).
+ (Fnetwork_interface_list): Allocate in increments of bytes instead
+ of sizeof (struct ifreq). Iterate over ifconf.ifc_req by counting
+ bytes (Bug#8477). Count bytes correctly when ifr_addr is a struct
+ sockaddr.
+ (struct ifflag_def): notrailers is smart on OSX.
+ (Fnetwork_interface_info): Handle case when ifr_flags is negative.
+ Get hardware address with getifaddrs if available.
+
+2011-08-12 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (iterate_out_of_display_property): xassert that
+ IT->position is set to within IT->object's boundaries. Break from
+ the loop as soon as EOB is reached; avoids infloops in redisplay
+ when IT->position is set up wrongly due to some bug.
+ Set IT->current to match the bidi iterator unconditionally.
+ (push_display_prop): Allow GET_FROM_STRING as IT->method on
+ entry. Force push_it to save on the stack the current
+ buffer/string position, to be restored by pop_it. Fix flags in
+ the iterator structure wrt the object coming from a display
+ property, as `line-prefix' and `wrap-prefix' are not ``replacing''
+ properties. (Bug#9284)
+
+2011-08-09 Andreas Schwab <[email protected]>
+
+ * fontset.c (fontset_get_font_group): Add proper type checks.
+ (Bug#9172)
+
+2011-08-09 YAMAMOTO Mitsuharu <[email protected]>
+
+ * unexmacosx.c (print_load_command_name): Add cases LC_FUNCTION_STARTS
+ and LC_VERSION_MIN_MACOSX.
+ (copy_linkedit_data) [LC_FUNCTION_STARTS]: New function.
+ (dump_it) [LC_FUNCTION_STARTS]: Use it.
+
+2011-08-08 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (forward_to_next_line_start): Allow to use the
+ no-display-properties-and-no-overlays under bidi display.
+ Set disp_pos in the bidi iterator to avoid searches for display
+ properties and overlays.
+
+2011-08-08 Chong Yidong <[email protected]>
+
+ * editfns.c (Fset_time_zone_rule): Document relationship with the
+ setenv function.
+
+ * ftfont.c (ftfont_pattern_entity): Copy the extras argument to
+ the font entity extracted from the cache (Bug#8109).
+
+2011-08-07 Chong Yidong <[email protected]>
+
+ * composite.c (autocmp_chars): Don't reset point. That is done by
+ restore_point_unwind (Bug#5984).
+
+2011-08-07 Juri Linkov <[email protected]>
+
+ * editfns.c (Fformat_time_string): Doc fix, add tag `usage:'
+ to show the arg `TIME' instead of `TIMEVAL'.
+
+2011-08-06 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (set_cursor_from_row): Fix cursor positioning when a
+ display property strides EOL and includes a newline, as in
+ longlines-mode. (Bug#9254)
+ (move_it_in_display_line_to): Fix vertical-motion in a buffer with
+ word-wrap under bidirectional display. (Bug#9224)
+
+ * bidi.c (bidi_unshelve_cache): Don't reset the cache if JUST_FREE
+ is non-zero, even if the data buffer is NULL. Fixes a crash in
+ vertical-motion with longlines-mode. (Bug#9254)
+
+2011-08-05 Eli Zaretskii <[email protected]>
+
+ * bidi.c <bidi_cache_total_alloc>: Now static.
+ (bidi_initialize): Initialize bidi_cache_total_alloc.
+
+ * xdisp.c (display_line): Release buffer allocated for shelved bidi
+ cache. (Bug#9221)
+
+ * bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total
+ amount allocated this far in `bidi_cache_total_alloc'.
+ (bidi_unshelve_cache): Accept an additional argument JUST_FREE; if
+ non-zero, only free the data buffer without restoring the cache
+ contents. All callers changed.
+
+ * dispextern.h (bidi_unshelve_cache): Update prototype.
+
+ * xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to)
+ (move_it_in_display_line, move_it_to)
+ (move_it_vertically_backward, move_it_by_lines): Replace the call
+ to xfree to an equivalent call to bidi_unshelve_cache.
+ (move_it_in_display_line_to): Fix logic of returning
+ MOVE_POS_MATCH_OR_ZV in the bidi case. (Bug#9224)
+
+2011-08-05 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (set_cursor_from_row): Prefer the candidate glyph that
+ came from a string character with a `cursor' property. (Bug#9229)
+
+2011-08-04 Jan Djärv <[email protected]>
+
+ * Makefile.in (LIB_PTHREAD): New variable.
+ (LIBES): Add LIB_PTHREAD (Bug#9216).
+
+ * alloc.c, emacs.c, gmalloc.c, gtkutil.c, keyboard.c, syssignal.h:
+ Rename HAVE_GTK_AND_PTHREAD to HAVE_PTHREAD (Bug#9216).
+
+2011-08-04 Andreas Schwab <[email protected]>
+
+ * regex.c (re_iswctype): Remove some redundant boolean
+ conversions.
+
+2011-08-04 Jan Djärv <[email protected]>
+
+ * xterm.c (x_find_topmost_parent): New function.
+ (x_set_frame_alpha): Find topmost parent window with
+ x_find_topmost_parent and set the property there also (bug#9181).
+ (handle_one_xevent): Call x_set_frame_alpha on ReparentNotify.
+
+2011-08-04 Paul Eggert <[email protected]>
+
+ * callproc.c (Fcall_process): Avoid vfork clobbering
+ the local vars buffer, coding_systems, current_dir.
+
+2011-08-03 Stefan Monnier <[email protected]>
+
+ * keymap.c (Fmake_composed_keymap): Move to subr.el.
+
+2011-08-03 Paul Eggert <[email protected]>
+
+ * fontset.c (dump_fontset) [FONTSET_DEBUG]: Declare EXTERNALLY_VISIBLE
+ so that it is not optimized away.
+
+ * xdisp.c (compute_display_string_pos): Remove unused local.
+
+2011-08-02 Eli Zaretskii <[email protected]>
+
+ Fix slow cursor motion and scrolling in large buffers with
+ selective display, like Org Mode buffers. (Bug#9218)
+
+ * dispextern.h (struct bidi_it): New member disp_prop_p.
+
+ * xdisp.c: Remove one-slot cache of display string positions.
+ (compute_display_string_pos): Accept an additional argument
+ DISP_PROP_P; callers changed. Scan at most 5K characters forward
+ for a display string or property. If found, set DISP_PROP_P
+ non-zero.
+
+ * bidi.c (bidi_fetch_char): Accept an additional argument
+ DISP_PROP_P, and pass it to compute_display_string_pos.
+ Only handle text covered by a display string if DISP_PROP_P is returned
+ non-zero. All callers of bidi_fetch_char changed.
+
+2011-08-02 Stefan Monnier <[email protected]>
+
+ * keymap.c (Fdefine_key): Fix Lisp_Object/int mixup; apply some CSE.
+
+2010-12-03 Don March <[email protected]>
+
+ * keymap.c (Fdefine_key): Fix non-prefix key error message when
+ last character M-[char] is translated to ESC [char] (bug#7541).
+
+2011-08-02 Kenichi Handa <[email protected]>
+
+ * lisp.h (uniprop_table): Extern it.
+
+ * chartab.c (uniprop_table): Make it non-static.
+
+2011-08-01 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (forward_to_next_line_start): Accept additional argument
+ BIDI_IT_PREV, and store into it the state of the bidi iterator had
+ on the newline.
+ (reseat_at_next_visible_line_start): Use the bidi iterator state
+ returned by forward_to_next_line_start to restore the state of
+ it->bidi_it after backing up to previous newline. (Bug#9212)
+
+2011-07-30 Andreas Schwab <[email protected]>
+
+ * regex.c (re_comp): Protoize.
+ (re_exec): Fix return type.
+ (regexec): Fix type of `ret'. (Bug#9203)
+
2011-07-29 Paul Eggert <[email protected]>
* Makefile.in (gl-stamp): move-if-change now in build-aux (Bug#9169).
@@ -315,8 +1230,8 @@
* xdisp.c (move_it_in_display_line_to): Record the best matching
position for TO_CHARPOS while scanning the line, and restore it on
- exit if none of the characters scanned was an exact match. Fixes
- vertical-motion and pos-visible-in-window-p under bidi redisplay
+ exit if none of the characters scanned was an exact match.
+ Fixes vertical-motion and pos-visible-in-window-p under bidi redisplay
when exact match is impossible due to invisible text, and the
lines are truncated.
@@ -501,8 +1416,8 @@
(reseat_to_string): Initialize bidi_it->string.s and
bidi_it->string.schars.
(Fcurrent_bidi_paragraph_direction): Initialize itb.string.s to
- NULL (avoids a crash in bidi_paragraph_init). Initialize
- itb.string.lstring.
+ NULL (avoids a crash in bidi_paragraph_init).
+ Initialize itb.string.lstring.
(init_iterator): Call bidi_init_it only of a valid
buffer position was specified. Initialize paragraph_embedding to
L2R.
@@ -518,12 +1433,12 @@
(init_iterator, reseat_1, reseat_to_string): Initialize the
string.bufpos member to 0 (zero, for compatibility with IT_CHARPOS
when iterating on a string not from display properties).
- (compute_display_string_pos, compute_display_string_end): Fix
- calculation of the object to scan. Fixes an error when using
+ (compute_display_string_pos, compute_display_string_end):
+ Fix calculation of the object to scan. Fixes an error when using
arrow keys.
(next_element_from_buffer): Don't abort when IT_CHARPOS is before
- base_level_stop; instead, set base_level_stop to BEGV. Fixes
- crashes in vertical-motion.
+ base_level_stop; instead, set base_level_stop to BEGV.
+ Fixes crashes in vertical-motion.
(next_element_from_buffer): Improve commentary for when
the iterator is before prev_stop.
(init_iterator): Initialize bidi_p from the default value of
@@ -536,8 +1451,8 @@
(next_element_from_string): Support bidi reordering of Lisp
strings.
(handle_stop_backwards): Support Lisp strings as well.
- (display_string): Support display of R2L glyph rows. Use
- IT_STRING_CHARPOS when displaying from a Lisp string.
+ (display_string): Support display of R2L glyph rows.
+ Use IT_STRING_CHARPOS when displaying from a Lisp string.
(init_iterator): Don't initialize it->bidi_p for strings
here.
(reseat_to_string): Initialize it->bidi_p for strings here.
@@ -619,8 +1534,8 @@
displayed in margins. (Bug#8133) (Bug#8867)
Return MOVE_POS_MATCH_OR_ZV only if iterator position is past
TO_CHARPOS.
- (pos_visible_p): Support positions in bidi-reordered lines. Save
- and restore bidi cache.
+ (pos_visible_p): Support positions in bidi-reordered lines.
+ Save and restore bidi cache.
* bidi.c (bidi_level_of_next_char): clen should be EMACS_NT, not int.
(bidi_paragraph_info): Delete unused struct.
@@ -640,8 +1555,8 @@
`len' according to what STRING_CHAR_AND_LENGTH expects.
(bidi_paragraph_init, bidi_resolve_explicit_1)
(bidi_resolve_explicit, bidi_resolve_weak)
- (bidi_level_of_next_char, bidi_move_to_visually_next): Support
- iteration over a string.
+ (bidi_level_of_next_char, bidi_move_to_visually_next):
+ Support iteration over a string.
(bidi_set_sor_type, bidi_resolve_explicit_1)
(bidi_resolve_explicit, bidi_type_of_next_char): ignore_bn_limit
can now be zero (for strings); special values 0 and -1 were
@@ -672,20 +1587,20 @@
(bidi_cache_fetch_state, bidi_cache_search)
(bidi_cache_find_level_change, bidi_cache_ensure_space)
(bidi_cache_iterator_state, bidi_cache_find)
- (bidi_find_other_level_edge, bidi_cache_start_stack): All
- variables related to cache indices are now EMACS_INT.
+ (bidi_find_other_level_edge, bidi_cache_start_stack):
+ All variables related to cache indices are now EMACS_INT.
* dispextern.h (struct bidi_string_data): New structure.
(struct bidi_it): New member `string'. Make flag members be 1-bit
fields, and put them last in the struct.
- (compute_display_string_pos, compute_display_string_end): Update
- prototypes.
+ (compute_display_string_pos, compute_display_string_end):
+ Update prototypes.
(bidi_push_it, bidi_pop_it): Add prototypes.
(struct iterator_stack_entry): New members bidi_p,
paragraph_embedding, and from_disp_prop_p.
(struct it): Member bidi_p is now a bit field 1 bit wide.
- (bidi_shelve_cache, bidi_unshelve_cache): Declare
- prototypes.
+ (bidi_shelve_cache, bidi_unshelve_cache):
+ Declare prototypes.
* .gdbinit (xvectype, xvector, xcompiled, xchartable, xboolvector)
(xpr, xfont, xbacktrace): Use "header.size" when accessing vectors
@@ -967,7 +1882,7 @@
(char_table_set_range): Adjuted for the above change.
(map_sub_char_table): Delete args default_val and parent. Add arg
top. Give decoded values to a Lisp function.
- (map_char_table): Adjusted for the above change. Give decoded
+ (map_char_table): Adjust for the above change. Give decoded
values to a Lisp function. Gcpro more variables.
(uniprop_table_uncompress)
(uniprop_decode_value_run_length): New functions.
@@ -984,10 +1899,10 @@
and Sput_unicode_property_internal. Defvar_lisp
char-code-property-alist.
- * composite.c (CHAR_COMPOSABLE_P): Adjusted for the change of
+ * composite.c (CHAR_COMPOSABLE_P): Adjust for the change of
Vunicode_category_table.
- * font.c (font_range): Adjusted for the change of
+ * font.c (font_range): Adjust for the change of
Vunicode_category_table.
2011-07-07 Dan Nicolaescu <[email protected]>
@@ -1016,14 +1931,14 @@
(store_monospaced_changed): Add comment. Call dpyinfo_valid.
(struct xsettings): Move font inside HAVE_XFT.
(GSETTINGS_TOOL_BAR_STYLE, GSETTINGS_FONT_NAME): New defines.
- (GSETTINGS_MONO_FONT): Renamed from SYSTEM_MONO_FONT.
+ (GSETTINGS_MONO_FONT): Rename from SYSTEM_MONO_FONT.
Move inside HAVE_XFT.
- (something_changed_gsettingsCB): Renamed from something_changedCB.
+ (something_changed_gsettingsCB): Rename from something_changedCB.
Check for changes in GSETTINGS_TOOL_BAR_STYLE and GSETTINGS_FONT_NAME
also.
(GCONF_TOOL_BAR_STYLE, GCONF_FONT_NAME): New defines.
- (GCONF_MONO_FONT): Renamed from SYSTEM_MONO_FONT. Move inside HAVE_XFT.
- (something_changed_gconfCB): Renamed from something_changedCB.
+ (GCONF_MONO_FONT): Rename from SYSTEM_MONO_FONT. Move inside HAVE_XFT.
+ (something_changed_gconfCB): Rename from something_changedCB.
Check for changes in GCONF_TOOL_BAR_STYLE and GCONF_FONT_NAME also.
(parse_settings): Move check for font inside HAVE_XFT.
(read_settings, apply_xft_settings): Add comment.
@@ -1036,8 +1951,8 @@
(init_gconf): Add comment. Get values for GCONF_TOOL_BAR_STYLE
and GCONF_FONT_NAME. Move check for fonts within HAVE_XFT.
(xsettings_initialize): Call init_gsettings last.
- (xsettings_get_system_font, xsettings_get_system_normal_font): Add
- comment.
+ (xsettings_get_system_font, xsettings_get_system_normal_font):
+ Add comment.
2011-07-05 Paul Eggert <[email protected]>
@@ -1220,7 +2135,7 @@
(syms_of_xsettings): Initialize gsettings_client, gsettings_obj
to NULL.
- * Makefile.in (SETTINGS_CFLAGS, SETTINGS_LIBS): Renamed from
+ * Makefile.in (SETTINGS_CFLAGS, SETTINGS_LIBS): Rename from
GCONF_CFLAGS/LIBS.
2011-06-29 Martin Rudalics <[email protected]>
@@ -1967,7 +2882,7 @@
* character.c, coding.c, doprnt.c, editfns.c, eval.c:
All uses of STRING_BYTES_MAX replaced by STRING_BYTES_BOUND.
- * lisp.h (STRING_BYTES_BOUND): Renamed from STRING_BYTES_MAX.
+ * lisp.h (STRING_BYTES_BOUND): Rename from STRING_BYTES_MAX.
* character.c (string_escape_byte8): Fix nbytes/nchars typo.
@@ -2076,8 +2991,8 @@
Qclone_number. Remove external declaration of Qdelete_window.
(Fbuffer_list): Rewrite doc-string. Minor restructuring of
code.
- (Fget_buffer_create, Fmake_indirect_buffer, Frename_buffer): Run
- Qbuffer_list_update_hook if allowed.
+ (Fget_buffer_create, Fmake_indirect_buffer, Frename_buffer):
+ Run Qbuffer_list_update_hook if allowed.
(Fother_buffer): Rewrite doc-string. Major rewrite for new
buffer list implementation.
(other_buffer_safely): New function.
@@ -2088,8 +3003,8 @@
(record_buffer): Inhibit quitting and rewrite using quittable
functions. Run Qbuffer_list_update_hook if allowed.
(Frecord_buffer, Funrecord_buffer): New functions.
- (switch_to_buffer_1, Fswitch_to_buffer): Remove. Move
- switch-to-buffer to window.el.
+ (switch_to_buffer_1, Fswitch_to_buffer): Remove.
+ Move switch-to-buffer to window.el.
(bury-buffer): Move to window.el.
(Vbuffer_list_update_hook): New variable.
@@ -2117,8 +3032,8 @@
(select_window_norecord, select_frame_norecord): Move in front
of run_window_configuration_change_hook. Remove now obsolete
declarations.
- (Fset_window_buffer): Rewrite doc-string. Call
- Qrecord_window_buffer.
+ (Fset_window_buffer): Rewrite doc-string.
+ Call Qrecord_window_buffer.
(keys_of_window): Move binding for other-window to window.el.
2011-06-11 Chong Yidong <[email protected]>
@@ -2200,8 +3115,8 @@
orig_total_lines.
(Fdelete_window, delete_window): Remove. Window deletion is
handled by window.el.
- (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace
- Fdelete_window calls with calls to Qdelete_window.
+ (window_loop): Remove DELETE_OTHER_WINDOWS case.
+ Replace Fdelete_window calls with calls to Qdelete_window.
(Fdelete_other_windows): Remove. Deleting other windows is
handled by window.el.
(window_fixed_size_p): Remove. Fixed-sizeness of windows is
@@ -2224,8 +3139,8 @@
(grow_mini_window, shrink_mini_window): Implement by calling
Qresize_root_window_vertically, resize_window_check and
resize_window_apply.
- (saved_window, Fset_window_configuration, save_window_save): Do
- not handle orig_top_line, orig_total_lines, and
+ (saved_window, Fset_window_configuration, save_window_save):
+ Do not handle orig_top_line, orig_total_lines, and
resize_proportionally.
(window_min_height, window_min_width): Move to window.el.
(keys_of_window): Move bindings for delete-other-windows,
@@ -2245,8 +3160,8 @@
* xdisp.c (init_xdisp): Don't use set_window_height but set
heights directly.
- * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use
- resize_frame_windows instead of change_window_heights and run
+ * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines):
+ Use resize_frame_windows instead of change_window_heights and run
run_window_configuration_change_hook.
* w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows
@@ -2268,8 +3183,8 @@
(Frun_window_configuration_change_hook, make_parent_window)
(resize_window_check, resize_window_apply, Fresize_window_apply)
(resize_frame_windows, Fsplit_window_internal)
- (Fdelete_window_internal, Fresize_mini_window_internal): New
- functions.
+ (Fdelete_window_internal, Fresize_mini_window_internal):
+ New functions.
(syms_of_window): New variables Vwindow_splits and Vwindow_nest.
2011-06-08 Martin Rudalics <[email protected]>
@@ -2289,8 +3204,8 @@
(Fwindow_nest, Fset_window_nest, Fwindow_new_total)
(Fwindow_normal_size, Fwindow_new_normal, Fwindow_prev_buffers)
(Fset_window_prev_buffers, Fwindow_next_buffers)
- (Fset_window_next_buffers, Fset_window_clone_number): New
- functions.
+ (Fset_window_next_buffers, Fset_window_clone_number):
+ New functions.
(Fwindow_hscroll, Fwindow_at, Fwindow_point, Fwindow_start)
(Fwindow_end, Fwindow_line_height, Fset_window_dedicated_p):
Doc-string fixes.
@@ -2316,10 +3231,10 @@
(Fwindow_top_line, window_body_lines, Fwindow_body_size)
(Fwindow_list_1): New functions.
(window_box_text_cols): Replace with window_body_cols.
- (Fwindow_width, Fscroll_left, Fscroll_right): Use
- window_body_cols instead of window_box_text_cols.
- (delete_window, Fset_window_configuration): Call
- delete_all_subwindows with window as argument.
+ (Fwindow_width, Fscroll_left, Fscroll_right):
+ Use window_body_cols instead of window_box_text_cols.
+ (delete_window, Fset_window_configuration):
+ Call delete_all_subwindows with window as argument.
(delete_all_subwindows): Take a window as argument and not a
structure. Rewrite.
(window_loop): Remove handling of GET_LRU_WINDOW and
@@ -2330,8 +3245,8 @@
window_box_text_cols. delete_all_subwindows now takes a
Lisp_Object as argument.
- * indent.c (compute_motion, Fcompute_motion): Use
- window_body_cols instead of window_box_text_cols.
+ * indent.c (compute_motion, Fcompute_motion):
+ Use window_body_cols instead of window_box_text_cols.
* frame.c (delete_frame): Call delete_all_subwindows with root
window as argument.
diff --git a/src/Makefile.in b/src/Makefile.in
index 67a5175b79..3be10c388c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -130,6 +130,9 @@ START_FILES = @START_FILES@
## -lm, or empty.
LIB_MATH=@LIB_MATH@
+## -lpthreads, or empty.
+LIB_PTHREAD=@LIB_PTHREAD@
+
LIBTIFF=@LIBTIFF@
LIBJPEG=@LIBJPEG@
LIBPNG=@LIBPNG@
@@ -385,7 +388,7 @@ LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
- $(LIBGNUTLS_LIBS) $(LIB_PTHREAD_SIGMASK) \
+ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
$(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC)
all: emacs$(EXEEXT) $(OTHER_FILES)
diff --git a/src/alloc.c b/src/alloc.c
index b96fc1f064..2d25680046 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -24,7 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <signal.h>
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
@@ -46,6 +46,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "syssignal.h"
#include "termhooks.h" /* For struct terminal. */
#include <setjmp.h>
+#include <verify.h>
/* GC_MALLOC_CHECK defined means perform validity checks of malloc'd
memory. Can do this only if using gmalloc.c. */
@@ -84,13 +85,15 @@ extern size_t __malloc_extra_blocks;
#endif /* not DOUG_LEA_MALLOC */
#if ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
/* When GTK uses the file chooser dialog, different backends can be loaded
dynamically. One such a backend is the Gnome VFS backend that gets loaded
if you run Gnome. That backend creates several threads and also allocates
memory with malloc.
+ Also, gconf and gsettings may create several threads.
+
If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
functions below are called from malloc, there is a chance that one
of these threads preempts the Emacs main thread and the hook variables
@@ -122,12 +125,12 @@ static pthread_mutex_t alloc_mutex;
} \
while (0)
-#else /* ! defined HAVE_GTK_AND_PTHREAD */
+#else /* ! defined HAVE_PTHREAD */
#define BLOCK_INPUT_ALLOC BLOCK_INPUT
#define UNBLOCK_INPUT_ALLOC UNBLOCK_INPUT
-#endif /* ! defined HAVE_GTK_AND_PTHREAD */
+#endif /* ! defined HAVE_PTHREAD */
#endif /* ! defined SYSTEM_MALLOC && ! defined SYNC_INPUT */
/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
@@ -731,6 +734,93 @@ xfree (POINTER_TYPE *block)
}
+/* Other parts of Emacs pass large int values to allocator functions
+ expecting ptrdiff_t. This is portable in practice, but check it to
+ be safe. */
+verify (INT_MAX <= PTRDIFF_MAX);
+
+
+/* Allocate an array of NITEMS items, each of size ITEM_SIZE.
+ Signal an error on memory exhaustion, and block interrupt input. */
+
+void *
+xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
+{
+ xassert (0 <= nitems && 0 < item_size);
+ if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
+ memory_full (SIZE_MAX);
+ return xmalloc (nitems * item_size);
+}
+
+
+/* Reallocate an array PA to make it of NITEMS items, each of size ITEM_SIZE.
+ Signal an error on memory exhaustion, and block interrupt input. */
+
+void *
+xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
+{
+ xassert (0 <= nitems && 0 < item_size);
+ if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
+ memory_full (SIZE_MAX);
+ return xrealloc (pa, nitems * item_size);
+}
+
+
+/* Grow PA, which points to an array of *NITEMS items, and return the
+ location of the reallocated array, updating *NITEMS to reflect its
+ new size. The new array will contain at least NITEMS_INCR_MIN more
+ items, but will not contain more than NITEMS_MAX items total.
+ ITEM_SIZE is the size of each item, in bytes.
+
+ ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be
+ nonnegative. If NITEMS_MAX is -1, it is treated as if it were
+ infinity.
+
+ If PA is null, then allocate a new array instead of reallocating
+ the old one. Thus, to grow an array A without saving its old
+ contents, invoke xfree (A) immediately followed by xgrowalloc (0,
+ &NITEMS, ...).
+
+ Block interrupt input as needed. If memory exhaustion occurs, set
+ *NITEMS to zero if PA is null, and signal an error (i.e., do not
+ return). */
+
+void *
+xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
+ ptrdiff_t nitems_max, ptrdiff_t item_size)
+{
+ /* The approximate size to use for initial small allocation
+ requests. This is the largest "small" request for the GNU C
+ library malloc. */
+ enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
+
+ /* If the array is tiny, grow it to about (but no greater than)
+ DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. */
+ ptrdiff_t n = *nitems;
+ ptrdiff_t tiny_max = DEFAULT_MXFAST / item_size - n;
+ ptrdiff_t half_again = n >> 1;
+ ptrdiff_t incr_estimate = max (tiny_max, half_again);
+
+ /* Adjust the increment according to three constraints: NITEMS_INCR_MIN,
+ NITEMS_MAX, and what the C language can represent safely. */
+ ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / item_size;
+ ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
+ ? nitems_max : C_language_max);
+ ptrdiff_t nitems_incr_max = n_max - n;
+ ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max));
+
+ xassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max);
+ if (! pa)
+ *nitems = 0;
+ if (nitems_incr_max < incr)
+ memory_full (SIZE_MAX);
+ n += incr;
+ pa = xrealloc (pa, n * item_size);
+ *nitems = n;
+ return pa;
+}
+
+
/* Like strdup, but uses xmalloc. */
char *
@@ -1265,7 +1355,7 @@ emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2)
}
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a
normal malloc. Some thread implementations need this as they call
malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then
@@ -1278,7 +1368,7 @@ reset_malloc_hooks (void)
__malloc_hook = old_malloc_hook;
__realloc_hook = old_realloc_hook;
}
-#endif /* HAVE_GTK_AND_PTHREAD */
+#endif /* HAVE_PTHREAD */
/* Called from main to set up malloc to use our hooks. */
@@ -1286,7 +1376,7 @@ reset_malloc_hooks (void)
void
uninterrupt_malloc (void)
{
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
#ifdef DOUG_LEA_MALLOC
pthread_mutexattr_t attr;
@@ -1300,7 +1390,7 @@ uninterrupt_malloc (void)
and the bundled gmalloc.c doesn't require it. */
pthread_mutex_init (&alloc_mutex, NULL);
#endif /* !DOUG_LEA_MALLOC */
-#endif /* HAVE_GTK_AND_PTHREAD */
+#endif /* HAVE_PTHREAD */
if (__free_hook != emacs_blocked_free)
old_free_hook = __free_hook;
diff --git a/src/bidi.c b/src/bidi.c
index 697ebb9285..bb29647ea8 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -79,6 +79,11 @@ typedef enum {
STRONG
} bidi_category_t;
+/* UAX#9 says to search only for L, AL, or R types of characters, and
+ ignore RLE, RLO, LRE, and LRO, when determining the base paragraph
+ level. Yudit indeed ignores them. This variable is therefore set
+ by default to ignore them, but setting it to zero will take them
+ into account. */
extern int bidi_ignore_explicit_marks_for_paragraph_level EXTERNALLY_VISIBLE;
int bidi_ignore_explicit_marks_for_paragraph_level = 1;
@@ -103,6 +108,12 @@ bidi_get_type (int ch, bidi_dir_t override)
abort ();
default_type = (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch));
+ /* Every valid character code, even those that are unassigned by the
+ UCD, have some bidi-class property, according to
+ DerivedBidiClass.txt file. Therefore, if we ever get UNKNOWN_BT
+ (= zero) code from CHAR_TABLE_REF, that's a bug. */
+ if (default_type == UNKNOWN_BT)
+ abort ();
if (override == NEUTRAL_DIR)
return default_type;
@@ -135,11 +146,10 @@ bidi_get_type (int ch, bidi_dir_t override)
}
}
-static void
+static inline void
bidi_check_type (bidi_type_t type)
{
- if (type < UNKNOWN_BT || type > NEUTRAL_ON)
- abort ();
+ xassert (UNKNOWN_BT <= type && type <= NEUTRAL_ON);
}
/* Given a bidi TYPE of a character, return its category. */
@@ -306,6 +316,21 @@ static ptrdiff_t bidi_cache_last_idx; /* slot of last cache hit */
static ptrdiff_t bidi_cache_start = 0; /* start of cache for this
"stack" level */
+/* 5-slot stack for saving the start of the previous level of the
+ cache. xdisp.c maintains a 5-slot stack for its iterator state,
+ and we need the same size of our stack. */
+static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE];
+static int bidi_cache_sp;
+
+/* Size of header used by bidi_shelve_cache. */
+enum
+ {
+ bidi_shelve_header_size =
+ (sizeof (bidi_cache_idx) + sizeof (bidi_cache_start_stack)
+ + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
+ + sizeof (bidi_cache_last_idx))
+ };
+
/* Reset the cache state to the empty state. We only reset the part
of the cache relevant to iteration of the current object. Previous
objects, which are pushed on the display iterator's stack, are left
@@ -328,9 +353,9 @@ bidi_cache_shrink (void)
{
if (bidi_cache_size > BIDI_CACHE_CHUNK)
{
- bidi_cache_size = BIDI_CACHE_CHUNK;
bidi_cache =
- (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
+ (struct bidi_it *) xrealloc (bidi_cache, BIDI_CACHE_CHUNK * elsz);
+ bidi_cache_size = BIDI_CACHE_CHUNK;
}
bidi_cache_reset ();
}
@@ -463,21 +488,19 @@ bidi_cache_ensure_space (ptrdiff_t idx)
/* Enlarge the cache as needed. */
if (idx >= bidi_cache_size)
{
- ptrdiff_t new_size;
-
/* The bidi cache cannot be larger than the largest Lisp string
or buffer. */
ptrdiff_t string_or_buffer_bound =
max (BUF_BYTES_MAX, STRING_BYTES_BOUND);
/* Also, it cannot be larger than what C can represent. */
- ptrdiff_t c_bound = min (PTRDIFF_MAX, SIZE_MAX) / elsz;
+ ptrdiff_t c_bound =
+ (min (PTRDIFF_MAX, SIZE_MAX) - bidi_shelve_header_size) / elsz;
- if (min (string_or_buffer_bound, c_bound) <= idx)
- memory_full (SIZE_MAX);
- new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK;
- bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz);
- bidi_cache_size = new_size;
+ bidi_cache =
+ xpalloc (bidi_cache, &bidi_cache_size,
+ max (BIDI_CACHE_CHUNK, idx - bidi_cache_size + 1),
+ min (string_or_buffer_bound, c_bound), elsz);
}
}
@@ -529,6 +552,8 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
bidi_cache[idx].next_for_neutral = bidi_it->next_for_neutral;
bidi_cache[idx].next_for_ws = bidi_it->next_for_ws;
bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit;
+ bidi_cache[idx].disp_pos = bidi_it->disp_pos;
+ bidi_cache[idx].disp_prop = bidi_it->disp_prop;
}
bidi_cache_last_idx = idx;
@@ -568,11 +593,6 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it)
/***********************************************************************
Pushing and popping the bidi iterator state
***********************************************************************/
-/* 5-slot stack for saving the start of the previous level of the
- cache. xdisp.c maintains a 5-slot stack for its iterator state,
- and we need the same size of our stack. */
-static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE];
-static int bidi_cache_sp;
/* Push the bidi iterator state in preparation for reordering a
different object, e.g. display string found at certain buffer
@@ -620,20 +640,24 @@ bidi_pop_it (struct bidi_it *bidi_it)
bidi_cache_last_idx = -1;
}
+static ptrdiff_t bidi_cache_total_alloc;
+
/* Stash away a copy of the cache and its control variables. */
void *
bidi_shelve_cache (void)
{
unsigned char *databuf;
+ ptrdiff_t alloc;
+ /* Empty cache. */
if (bidi_cache_idx == 0)
return NULL;
- databuf = xmalloc (sizeof (bidi_cache_idx)
- + bidi_cache_idx * sizeof (struct bidi_it)
- + sizeof (bidi_cache_start_stack)
- + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
- + sizeof (bidi_cache_last_idx));
+ alloc = (bidi_shelve_header_size
+ + bidi_cache_idx * sizeof (struct bidi_it));
+ databuf = xmalloc (alloc);
+ bidi_cache_total_alloc += alloc;
+
memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx));
memcpy (databuf + sizeof (bidi_cache_idx),
bidi_cache, bidi_cache_idx * sizeof (struct bidi_it));
@@ -657,45 +681,65 @@ bidi_shelve_cache (void)
return databuf;
}
-/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */
+/* Restore the cache state from a copy stashed away by
+ bidi_shelve_cache, and free the buffer used to stash that copy.
+ JUST_FREE non-zero means free the buffer, but don't restore the
+ cache; used when the corresponding iterator is discarded instead of
+ being restored. */
void
-bidi_unshelve_cache (void *databuf)
+bidi_unshelve_cache (void *databuf, int just_free)
{
unsigned char *p = databuf;
if (!p)
{
- /* A NULL pointer means an empty cache. */
- bidi_cache_start = 0;
- bidi_cache_sp = 0;
- bidi_cache_reset ();
+ if (!just_free)
+ {
+ /* A NULL pointer means an empty cache. */
+ bidi_cache_start = 0;
+ bidi_cache_sp = 0;
+ bidi_cache_reset ();
+ }
}
else
{
- memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx));
- bidi_cache_ensure_space (bidi_cache_idx);
- memcpy (bidi_cache, p + sizeof (bidi_cache_idx),
- bidi_cache_idx * sizeof (struct bidi_it));
- memcpy (bidi_cache_start_stack,
- p + sizeof (bidi_cache_idx)
- + bidi_cache_idx * sizeof (struct bidi_it),
- sizeof (bidi_cache_start_stack));
- memcpy (&bidi_cache_sp,
- p + sizeof (bidi_cache_idx)
- + bidi_cache_idx * sizeof (struct bidi_it)
- + sizeof (bidi_cache_start_stack),
- sizeof (bidi_cache_sp));
- memcpy (&bidi_cache_start,
- p + sizeof (bidi_cache_idx)
- + bidi_cache_idx * sizeof (struct bidi_it)
- + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
- sizeof (bidi_cache_start));
- memcpy (&bidi_cache_last_idx,
- p + sizeof (bidi_cache_idx)
- + bidi_cache_idx * sizeof (struct bidi_it)
- + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
- + sizeof (bidi_cache_start),
- sizeof (bidi_cache_last_idx));
+ if (just_free)
+ {
+ ptrdiff_t idx;
+
+ memcpy (&idx, p, sizeof (bidi_cache_idx));
+ bidi_cache_total_alloc -=
+ bidi_shelve_header_size + idx * sizeof (struct bidi_it);
+ }
+ else
+ {
+ memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx));
+ bidi_cache_ensure_space (bidi_cache_idx);
+ memcpy (bidi_cache, p + sizeof (bidi_cache_idx),
+ bidi_cache_idx * sizeof (struct bidi_it));
+ memcpy (bidi_cache_start_stack,
+ p + sizeof (bidi_cache_idx)
+ + bidi_cache_idx * sizeof (struct bidi_it),
+ sizeof (bidi_cache_start_stack));
+ memcpy (&bidi_cache_sp,
+ p + sizeof (bidi_cache_idx)
+ + bidi_cache_idx * sizeof (struct bidi_it)
+ + sizeof (bidi_cache_start_stack),
+ sizeof (bidi_cache_sp));
+ memcpy (&bidi_cache_start,
+ p + sizeof (bidi_cache_idx)
+ + bidi_cache_idx * sizeof (struct bidi_it)
+ + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
+ sizeof (bidi_cache_start));
+ memcpy (&bidi_cache_last_idx,
+ p + sizeof (bidi_cache_idx)
+ + bidi_cache_idx * sizeof (struct bidi_it)
+ + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
+ + sizeof (bidi_cache_start),
+ sizeof (bidi_cache_last_idx));
+ bidi_cache_total_alloc -=
+ bidi_shelve_header_size + bidi_cache_idx * sizeof (struct bidi_it);
+ }
xfree (p);
}
@@ -708,26 +752,16 @@ bidi_unshelve_cache (void *databuf)
static void
bidi_initialize (void)
{
-
-#include "biditype.h"
-#include "bidimirror.h"
-
- int i;
-
- bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L));
+ bidi_type_table = uniprop_table (intern ("bidi-class"));
+ if (NILP (bidi_type_table))
+ abort ();
staticpro (&bidi_type_table);
- for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++)
- char_table_set_range (bidi_type_table, bidi_type[i].from, bidi_type[i].to,
- make_number (bidi_type[i].type));
-
- bidi_mirror_table = Fmake_char_table (Qnil, Qnil);
+ bidi_mirror_table = uniprop_table (intern ("mirroring"));
+ if (NILP (bidi_mirror_table))
+ abort ();
staticpro (&bidi_mirror_table);
- for (i = 0; i < sizeof bidi_mirror / sizeof bidi_mirror[0]; i++)
- char_table_set (bidi_mirror_table, bidi_mirror[i].from,
- make_number (bidi_mirror[i].to));
-
Qparagraph_start = intern ("paragraph-start");
staticpro (&Qparagraph_start);
paragraph_start_re = Fsymbol_value (Qparagraph_start);
@@ -742,6 +776,7 @@ bidi_initialize (void)
staticpro (&paragraph_separate_re);
bidi_cache_sp = 0;
+ bidi_cache_total_alloc = 0;
bidi_initialized = 1;
}
@@ -792,6 +827,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */
bidi_it->disp_pos = -1; /* invalid/unknown */
+ bidi_it->disp_prop = 0;
/* We can only shrink the cache if we are at the bottom level of its
"stack". */
if (bidi_cache_start == 0)
@@ -871,17 +907,21 @@ bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte)
/* Fetch and return the character at BYTEPOS/CHARPOS. If that
character is covered by a display string, treat the entire run of
- covered characters as a single character u+FFFC, and return their
- combined length in CH_LEN and NCHARS. DISP_POS specifies the
- character position of the next display string, or -1 if not yet
- computed. When the next character is at or beyond that position,
- the function updates DISP_POS with the position of the next display
- string. STRING->s is the C string to iterate, or NULL if iterating
- over a buffer or a Lisp string; in the latter case, STRING->lstring
- is the Lisp string. */
+ covered characters as a single character, either u+2029 or u+FFFC,
+ and return their combined length in CH_LEN and NCHARS. DISP_POS
+ specifies the character position of the next display string, or -1
+ if not yet computed. When the next character is at or beyond that
+ position, the function updates DISP_POS with the position of the
+ next display string. DISP_PROP non-zero means that there's really
+ a display string at DISP_POS, as opposed to when we searched till
+ DISP_POS without finding one. If DISP_PROP is 2, it means the
+ display spec is of the form `(space ...)', which is replaced with
+ u+2029 to handle it as a paragraph separator. STRING->s is the C
+ string to iterate, or NULL if iterating over a buffer or a Lisp
+ string; in the latter case, STRING->lstring is the Lisp string. */
static inline int
bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
- struct bidi_string_data *string,
+ int *disp_prop, struct bidi_string_data *string,
int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars)
{
int ch;
@@ -894,7 +934,8 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
if (charpos < endpos && charpos > *disp_pos)
{
SET_TEXT_POS (pos, charpos, bytepos);
- *disp_pos = compute_display_string_pos (&pos, string, frame_window_p);
+ *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
+ disp_prop);
}
/* Fetch the character at BYTEPOS. */
@@ -904,8 +945,9 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
*ch_len = 1;
*nchars = 1;
*disp_pos = endpos;
+ *disp_prop = 0;
}
- else if (charpos >= *disp_pos)
+ else if (charpos >= *disp_pos && *disp_prop)
{
EMACS_INT disp_end_pos;
@@ -913,9 +955,23 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
property. Hopefully, it will never be needed. */
if (charpos > *disp_pos)
abort ();
- /* Return the Unicode Object Replacement Character to represent
- the entire run of characters covered by the display string. */
- ch = 0xFFFC;
+ /* Text covered by `display' properties and overlays with
+ display properties or display strings is handled as a single
+ character that represents the entire run of characters
+ covered by the display property. */
+ if (*disp_prop == 2)
+ {
+ /* `(space ...)' display specs are handled as paragraph
+ separators for the purposes of the reordering; see UAX#9
+ section 3 and clause HL1 in section 4.3 there. */
+ ch = 0x2029;
+ }
+ else
+ {
+ /* All other display specs are handled as the Unicode Object
+ Replacement Character. */
+ ch = 0xFFFC;
+ }
disp_end_pos = compute_display_string_end (*disp_pos, string);
*nchars = disp_end_pos - *disp_pos;
if (*nchars <= 0)
@@ -972,10 +1028,12 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
/* If we just entered a run of characters covered by a display
string, compute the position of the next display string. */
- if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos)
+ if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos
+ && *disp_prop)
{
SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
- *disp_pos = compute_display_string_pos (&pos, string, frame_window_p);
+ *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
+ disp_prop);
}
return ch;
@@ -1083,6 +1141,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
int ch;
EMACS_INT ch_len, nchars;
EMACS_INT pos, disp_pos = -1;
+ int disp_prop = 0;
bidi_type_t type;
const unsigned char *s;
@@ -1130,15 +1189,12 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
bytepos = pstartbyte;
if (!string_p)
pos = BYTE_TO_CHAR (bytepos);
- ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string,
+ ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop,
+ &bidi_it->string,
bidi_it->frame_window_p, &ch_len, &nchars);
type = bidi_get_type (ch, NEUTRAL_DIR);
for (pos += nchars, bytepos += ch_len;
- /* NOTE: UAX#9 says to search only for L, AL, or R types
- of characters, and ignore RLE, RLO, LRE, and LRO.
- However, I'm not sure it makes sense to omit those 4;
- should try with and without that to see the effect. */
(bidi_get_category (type) != STRONG)
|| (bidi_ignore_explicit_marks_for_paragraph_level
&& (type == RLE || type == RLO
@@ -1157,14 +1213,19 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
&& bidi_at_paragraph_end (pos, bytepos) >= -1)
break;
/* Fetch next character and advance to get past it. */
- ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string,
+ ch = bidi_fetch_char (bytepos, pos, &disp_pos,
+ &disp_prop, &bidi_it->string,
bidi_it->frame_window_p, &ch_len, &nchars);
pos += nchars;
bytepos += ch_len;
}
- if (type == STRONG_R || type == STRONG_AL) /* P3 */
+ if ((type == STRONG_R || type == STRONG_AL) /* P3 */
+ || (!bidi_ignore_explicit_marks_for_paragraph_level
+ && (type == RLO || type == RLE)))
bidi_it->paragraph_dir = R2L;
- else if (type == STRONG_L)
+ else if (type == STRONG_L
+ || (!bidi_ignore_explicit_marks_for_paragraph_level
+ && (type == LRO || type == LRE)))
bidi_it->paragraph_dir = L2R;
if (!string_p
&& no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR)
@@ -1290,6 +1351,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
bidi_it->ch_len = 1;
bidi_it->nchars = 1;
bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV);
+ bidi_it->disp_prop = 0;
}
else
{
@@ -1297,8 +1359,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
display string, treat the entire run of covered characters as
a single character u+FFFC. */
curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
- &bidi_it->disp_pos, &bidi_it->string,
- bidi_it->frame_window_p,
+ &bidi_it->disp_pos, &bidi_it->disp_prop,
+ &bidi_it->string, bidi_it->frame_window_p,
&bidi_it->ch_len, &bidi_it->nchars);
}
bidi_it->ch = curchar;
@@ -2032,12 +2094,13 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
struct bidi_string_data bs = bidi_it->string;
bidi_type_t chtype;
int fwp = bidi_it->frame_window_p;
+ int dpp = bidi_it->disp_prop;
if (bidi_it->nchars <= 0)
abort ();
do {
- ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &bs, fwp,
- &clen, &nc);
+ ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs,
+ fwp, &clen, &nc);
if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */)
chtype = NEUTRAL_B;
else
diff --git a/src/bidimirror.h b/src/bidimirror.h
deleted file mode 100644
index 477f983ad6..0000000000
--- a/src/bidimirror.h
+++ /dev/null
@@ -1,365 +0,0 @@
- struct {
- int from, to;
- } bidi_mirror[] = {
- { 0x0028, 0x0029 },
- { 0x0029, 0x0028 },
- { 0x003C, 0x003E },
- { 0x003E, 0x003C },
- { 0x005B, 0x005D },
- { 0x005D, 0x005B },
- { 0x007B, 0x007D },
- { 0x007D, 0x007B },
- { 0x00AB, 0x00BB },
- { 0x00BB, 0x00AB },
- { 0x0F3A, 0x0F3B },
- { 0x0F3B, 0x0F3A },
- { 0x0F3C, 0x0F3D },
- { 0x0F3D, 0x0F3C },
- { 0x169B, 0x169C },
- { 0x169C, 0x169B },
- { 0x2039, 0x203A },
- { 0x203A, 0x2039 },
- { 0x2045, 0x2046 },
- { 0x2046, 0x2045 },
- { 0x207D, 0x207E },
- { 0x207E, 0x207D },
- { 0x208D, 0x208E },
- { 0x208E, 0x208D },
- { 0x2208, 0x220B },
- { 0x2209, 0x220C },
- { 0x220A, 0x220D },
- { 0x220B, 0x2208 },
- { 0x220C, 0x2209 },
- { 0x220D, 0x220A },
- { 0x2215, 0x29F5 },
- { 0x223C, 0x223D },
- { 0x223D, 0x223C },
- { 0x2243, 0x22CD },
- { 0x2252, 0x2253 },
- { 0x2253, 0x2252 },
- { 0x2254, 0x2255 },
- { 0x2255, 0x2254 },
- { 0x2264, 0x2265 },
- { 0x2265, 0x2264 },
- { 0x2266, 0x2267 },
- { 0x2267, 0x2266 },
- { 0x2268, 0x2269 },
- { 0x2269, 0x2268 },
- { 0x226A, 0x226B },
- { 0x226B, 0x226A },
- { 0x226E, 0x226F },
- { 0x226F, 0x226E },
- { 0x2270, 0x2271 },
- { 0x2271, 0x2270 },
- { 0x2272, 0x2273 },
- { 0x2273, 0x2272 },
- { 0x2274, 0x2275 },
- { 0x2275, 0x2274 },
- { 0x2276, 0x2277 },
- { 0x2277, 0x2276 },
- { 0x2278, 0x2279 },
- { 0x2279, 0x2278 },
- { 0x227A, 0x227B },
- { 0x227B, 0x227A },
- { 0x227C, 0x227D },
- { 0x227D, 0x227C },
- { 0x227E, 0x227F },
- { 0x227F, 0x227E },
- { 0x2280, 0x2281 },
- { 0x2281, 0x2280 },
- { 0x2282, 0x2283 },
- { 0x2283, 0x2282 },
- { 0x2284, 0x2285 },
- { 0x2285, 0x2284 },
- { 0x2286, 0x2287 },
- { 0x2287, 0x2286 },
- { 0x2288, 0x2289 },
- { 0x2289, 0x2288 },
- { 0x228A, 0x228B },
- { 0x228B, 0x228A },
- { 0x228F, 0x2290 },
- { 0x2290, 0x228F },
- { 0x2291, 0x2292 },
- { 0x2292, 0x2291 },
- { 0x2298, 0x29B8 },
- { 0x22A2, 0x22A3 },
- { 0x22A3, 0x22A2 },
- { 0x22A6, 0x2ADE },
- { 0x22A8, 0x2AE4 },
- { 0x22A9, 0x2AE3 },
- { 0x22AB, 0x2AE5 },
- { 0x22B0, 0x22B1 },
- { 0x22B1, 0x22B0 },
- { 0x22B2, 0x22B3 },
- { 0x22B3, 0x22B2 },
- { 0x22B4, 0x22B5 },
- { 0x22B5, 0x22B4 },
- { 0x22B6, 0x22B7 },
- { 0x22B7, 0x22B6 },
- { 0x22C9, 0x22CA },
- { 0x22CA, 0x22C9 },
- { 0x22CB, 0x22CC },
- { 0x22CC, 0x22CB },
- { 0x22CD, 0x2243 },
- { 0x22D0, 0x22D1 },
- { 0x22D1, 0x22D0 },
- { 0x22D6, 0x22D7 },
- { 0x22D7, 0x22D6 },
- { 0x22D8, 0x22D9 },
- { 0x22D9, 0x22D8 },
- { 0x22DA, 0x22DB },
- { 0x22DB, 0x22DA },
- { 0x22DC, 0x22DD },
- { 0x22DD, 0x22DC },
- { 0x22DE, 0x22DF },
- { 0x22DF, 0x22DE },
- { 0x22E0, 0x22E1 },
- { 0x22E1, 0x22E0 },
- { 0x22E2, 0x22E3 },
- { 0x22E3, 0x22E2 },
- { 0x22E4, 0x22E5 },
- { 0x22E5, 0x22E4 },
- { 0x22E6, 0x22E7 },
- { 0x22E7, 0x22E6 },
- { 0x22E8, 0x22E9 },
- { 0x22E9, 0x22E8 },
- { 0x22EA, 0x22EB },
- { 0x22EB, 0x22EA },
- { 0x22EC, 0x22ED },
- { 0x22ED, 0x22EC },
- { 0x22F0, 0x22F1 },
- { 0x22F1, 0x22F0 },
- { 0x22F2, 0x22FA },
- { 0x22F3, 0x22FB },
- { 0x22F4, 0x22FC },
- { 0x22F6, 0x22FD },
- { 0x22F7, 0x22FE },
- { 0x22FA, 0x22F2 },
- { 0x22FB, 0x22F3 },
- { 0x22FC, 0x22F4 },
- { 0x22FD, 0x22F6 },
- { 0x22FE, 0x22F7 },
- { 0x2308, 0x2309 },
- { 0x2309, 0x2308 },
- { 0x230A, 0x230B },
- { 0x230B, 0x230A },
- { 0x2329, 0x232A },
- { 0x232A, 0x2329 },
- { 0x2768, 0x2769 },
- { 0x2769, 0x2768 },
- { 0x276A, 0x276B },
- { 0x276B, 0x276A },
- { 0x276C, 0x276D },
- { 0x276D, 0x276C },
- { 0x276E, 0x276F },
- { 0x276F, 0x276E },
- { 0x2770, 0x2771 },
- { 0x2771, 0x2770 },
- { 0x2772, 0x2773 },
- { 0x2773, 0x2772 },
- { 0x2774, 0x2775 },
- { 0x2775, 0x2774 },
- { 0x27C3, 0x27C4 },
- { 0x27C4, 0x27C3 },
- { 0x27C5, 0x27C6 },
- { 0x27C6, 0x27C5 },
- { 0x27C8, 0x27C9 },
- { 0x27C9, 0x27C8 },
- { 0x27D5, 0x27D6 },
- { 0x27D6, 0x27D5 },
- { 0x27DD, 0x27DE },
- { 0x27DE, 0x27DD },
- { 0x27E2, 0x27E3 },
- { 0x27E3, 0x27E2 },
- { 0x27E4, 0x27E5 },
- { 0x27E5, 0x27E4 },
- { 0x27E6, 0x27E7 },
- { 0x27E7, 0x27E6 },
- { 0x27E8, 0x27E9 },
- { 0x27E9, 0x27E8 },
- { 0x27EA, 0x27EB },
- { 0x27EB, 0x27EA },
- { 0x27EC, 0x27ED },
- { 0x27ED, 0x27EC },
- { 0x27EE, 0x27EF },
- { 0x27EF, 0x27EE },
- { 0x2983, 0x2984 },
- { 0x2984, 0x2983 },
- { 0x2985, 0x2986 },
- { 0x2986, 0x2985 },
- { 0x2987, 0x2988 },
- { 0x2988, 0x2987 },
- { 0x2989, 0x298A },
- { 0x298A, 0x2989 },
- { 0x298B, 0x298C },
- { 0x298C, 0x298B },
- { 0x298D, 0x2990 },
- { 0x298E, 0x298F },
- { 0x298F, 0x298E },
- { 0x2990, 0x298D },
- { 0x2991, 0x2992 },
- { 0x2992, 0x2991 },
- { 0x2993, 0x2994 },
- { 0x2994, 0x2993 },
- { 0x2995, 0x2996 },
- { 0x2996, 0x2995 },
- { 0x2997, 0x2998 },
- { 0x2998, 0x2997 },
- { 0x29B8, 0x2298 },
- { 0x29C0, 0x29C1 },
- { 0x29C1, 0x29C0 },
- { 0x29C4, 0x29C5 },
- { 0x29C5, 0x29C4 },
- { 0x29CF, 0x29D0 },
- { 0x29D0, 0x29CF },
- { 0x29D1, 0x29D2 },
- { 0x29D2, 0x29D1 },
- { 0x29D4, 0x29D5 },
- { 0x29D5, 0x29D4 },
- { 0x29D8, 0x29D9 },
- { 0x29D9, 0x29D8 },
- { 0x29DA, 0x29DB },
- { 0x29DB, 0x29DA },
- { 0x29F5, 0x2215 },
- { 0x29F8, 0x29F9 },
- { 0x29F9, 0x29F8 },
- { 0x29FC, 0x29FD },
- { 0x29FD, 0x29FC },
- { 0x2A2B, 0x2A2C },
- { 0x2A2C, 0x2A2B },
- { 0x2A2D, 0x2A2E },
- { 0x2A2E, 0x2A2D },
- { 0x2A34, 0x2A35 },
- { 0x2A35, 0x2A34 },
- { 0x2A3C, 0x2A3D },
- { 0x2A3D, 0x2A3C },
- { 0x2A64, 0x2A65 },
- { 0x2A65, 0x2A64 },
- { 0x2A79, 0x2A7A },
- { 0x2A7A, 0x2A79 },
- { 0x2A7D, 0x2A7E },
- { 0x2A7E, 0x2A7D },
- { 0x2A7F, 0x2A80 },
- { 0x2A80, 0x2A7F },
- { 0x2A81, 0x2A82 },
- { 0x2A82, 0x2A81 },
- { 0x2A83, 0x2A84 },
- { 0x2A84, 0x2A83 },
- { 0x2A8B, 0x2A8C },
- { 0x2A8C, 0x2A8B },
- { 0x2A91, 0x2A92 },
- { 0x2A92, 0x2A91 },
- { 0x2A93, 0x2A94 },
- { 0x2A94, 0x2A93 },
- { 0x2A95, 0x2A96 },
- { 0x2A96, 0x2A95 },
- { 0x2A97, 0x2A98 },
- { 0x2A98, 0x2A97 },
- { 0x2A99, 0x2A9A },
- { 0x2A9A, 0x2A99 },
- { 0x2A9B, 0x2A9C },
- { 0x2A9C, 0x2A9B },
- { 0x2AA1, 0x2AA2 },
- { 0x2AA2, 0x2AA1 },
- { 0x2AA6, 0x2AA7 },
- { 0x2AA7, 0x2AA6 },
- { 0x2AA8, 0x2AA9 },
- { 0x2AA9, 0x2AA8 },
- { 0x2AAA, 0x2AAB },
- { 0x2AAB, 0x2AAA },
- { 0x2AAC, 0x2AAD },
- { 0x2AAD, 0x2AAC },
- { 0x2AAF, 0x2AB0 },
- { 0x2AB0, 0x2AAF },
- { 0x2AB3, 0x2AB4 },
- { 0x2AB4, 0x2AB3 },
- { 0x2ABB, 0x2ABC },
- { 0x2ABC, 0x2ABB },
- { 0x2ABD, 0x2ABE },
- { 0x2ABE, 0x2ABD },
- { 0x2ABF, 0x2AC0 },
- { 0x2AC0, 0x2ABF },
- { 0x2AC1, 0x2AC2 },
- { 0x2AC2, 0x2AC1 },
- { 0x2AC3, 0x2AC4 },
- { 0x2AC4, 0x2AC3 },
- { 0x2AC5, 0x2AC6 },
- { 0x2AC6, 0x2AC5 },
- { 0x2ACD, 0x2ACE },
- { 0x2ACE, 0x2ACD },
- { 0x2ACF, 0x2AD0 },
- { 0x2AD0, 0x2ACF },
- { 0x2AD1, 0x2AD2 },
- { 0x2AD2, 0x2AD1 },
- { 0x2AD3, 0x2AD4 },
- { 0x2AD4, 0x2AD3 },
- { 0x2AD5, 0x2AD6 },
- { 0x2AD6, 0x2AD5 },
- { 0x2ADE, 0x22A6 },
- { 0x2AE3, 0x22A9 },
- { 0x2AE4, 0x22A8 },
- { 0x2AE5, 0x22AB },
- { 0x2AEC, 0x2AED },
- { 0x2AED, 0x2AEC },
- { 0x2AF7, 0x2AF8 },
- { 0x2AF8, 0x2AF7 },
- { 0x2AF9, 0x2AFA },
- { 0x2AFA, 0x2AF9 },
- { 0x2E02, 0x2E03 },
- { 0x2E03, 0x2E02 },
- { 0x2E04, 0x2E05 },
- { 0x2E05, 0x2E04 },
- { 0x2E09, 0x2E0A },
- { 0x2E0A, 0x2E09 },
- { 0x2E0C, 0x2E0D },
- { 0x2E0D, 0x2E0C },
- { 0x2E1C, 0x2E1D },
- { 0x2E1D, 0x2E1C },
- { 0x2E20, 0x2E21 },
- { 0x2E21, 0x2E20 },
- { 0x2E22, 0x2E23 },
- { 0x2E23, 0x2E22 },
- { 0x2E24, 0x2E25 },
- { 0x2E25, 0x2E24 },
- { 0x2E26, 0x2E27 },
- { 0x2E27, 0x2E26 },
- { 0x2E28, 0x2E29 },
- { 0x2E29, 0x2E28 },
- { 0x3008, 0x3009 },
- { 0x3009, 0x3008 },
- { 0x300A, 0x300B },
- { 0x300B, 0x300A },
- { 0x300C, 0x300D },
- { 0x300D, 0x300C },
- { 0x300E, 0x300F },
- { 0x300F, 0x300E },
- { 0x3010, 0x3011 },
- { 0x3011, 0x3010 },
- { 0x3014, 0x3015 },
- { 0x3015, 0x3014 },
- { 0x3016, 0x3017 },
- { 0x3017, 0x3016 },
- { 0x3018, 0x3019 },
- { 0x3019, 0x3018 },
- { 0x301A, 0x301B },
- { 0x301B, 0x301A },
- { 0xFE59, 0xFE5A },
- { 0xFE5A, 0xFE59 },
- { 0xFE5B, 0xFE5C },
- { 0xFE5C, 0xFE5B },
- { 0xFE5D, 0xFE5E },
- { 0xFE5E, 0xFE5D },
- { 0xFE64, 0xFE65 },
- { 0xFE65, 0xFE64 },
- { 0xFF08, 0xFF09 },
- { 0xFF09, 0xFF08 },
- { 0xFF1C, 0xFF1E },
- { 0xFF1E, 0xFF1C },
- { 0xFF3B, 0xFF3D },
- { 0xFF3D, 0xFF3B },
- { 0xFF5B, 0xFF5D },
- { 0xFF5D, 0xFF5B },
- { 0xFF5F, 0xFF60 },
- { 0xFF60, 0xFF5F },
- { 0xFF62, 0xFF63 },
- { 0xFF63, 0xFF62 } };
diff --git a/src/biditype.h b/src/biditype.h
deleted file mode 100644
index 868aabd9ea..0000000000
--- a/src/biditype.h
+++ /dev/null
@@ -1,447 +0,0 @@
- struct {
- int from, to;
- bidi_type_t type;
- } bidi_type[] = {
- { 0x0000, 0x0008, WEAK_BN },
- { 0x0009, 0x0009, NEUTRAL_S },
- { 0x000A, 0x000A, NEUTRAL_B },
- { 0x000B, 0x000B, NEUTRAL_S },
- { 0x000C, 0x000C, NEUTRAL_WS },
- { 0x000D, 0x000D, NEUTRAL_B },
- { 0x000E, 0x001B, WEAK_BN },
- { 0x001C, 0x001E, NEUTRAL_B },
- { 0x001F, 0x001F, NEUTRAL_S },
- { 0x0020, 0x0020, NEUTRAL_WS },
- { 0x0021, 0x0022, NEUTRAL_ON },
- { 0x0023, 0x0025, WEAK_ET },
- { 0x0026, 0x002A, NEUTRAL_ON },
- { 0x002B, 0x002B, WEAK_ES },
- { 0x002C, 0x002C, WEAK_CS },
- { 0x002D, 0x002D, WEAK_ES },
- { 0x002E, 0x002F, WEAK_CS },
- { 0x0030, 0x0039, WEAK_EN },
- { 0x003A, 0x003A, WEAK_CS },
- { 0x003B, 0x0040, NEUTRAL_ON },
- { 0x005B, 0x0060, NEUTRAL_ON },
- { 0x007B, 0x007E, NEUTRAL_ON },
- { 0x007F, 0x0084, WEAK_BN },
- { 0x0085, 0x0085, NEUTRAL_B },
- { 0x0086, 0x009F, WEAK_BN },
- { 0x00A0, 0x00A0, WEAK_CS },
- { 0x00A1, 0x00A1, NEUTRAL_ON },
- { 0x00A2, 0x00A5, WEAK_ET },
- { 0x00A6, 0x00A9, NEUTRAL_ON },
- { 0x00AB, 0x00AC, NEUTRAL_ON },
- { 0x00AD, 0x00AD, WEAK_BN },
- { 0x00AE, 0x00AF, NEUTRAL_ON },
- { 0x00B0, 0x00B1, WEAK_ET },
- { 0x00B2, 0x00B3, WEAK_EN },
- { 0x00B4, 0x00B4, NEUTRAL_ON },
- { 0x00B6, 0x00B8, NEUTRAL_ON },
- { 0x00B9, 0x00B9, WEAK_EN },
- { 0x00BB, 0x00BF, NEUTRAL_ON },
- { 0x00D7, 0x00D7, NEUTRAL_ON },
- { 0x00F7, 0x00F7, NEUTRAL_ON },
- { 0x02B9, 0x02BA, NEUTRAL_ON },
- { 0x02C2, 0x02CF, NEUTRAL_ON },
- { 0x02D2, 0x02DF, NEUTRAL_ON },
- { 0x02E5, 0x02ED, NEUTRAL_ON },
- { 0x02EF, 0x02FF, NEUTRAL_ON },
- { 0x0300, 0x036F, WEAK_NSM },
- { 0x0374, 0x0375, NEUTRAL_ON },
- { 0x037E, 0x0385, NEUTRAL_ON },
- { 0x0387, 0x0387, NEUTRAL_ON },
- { 0x03F6, 0x03F6, NEUTRAL_ON },
- { 0x0483, 0x0489, WEAK_NSM },
- { 0x058A, 0x058A, NEUTRAL_ON },
- { 0x0591, 0x05BD, WEAK_NSM },
- { 0x05BE, 0x05BE, STRONG_R },
- { 0x05BF, 0x05BF, WEAK_NSM },
- { 0x05C0, 0x05C0, STRONG_R },
- { 0x05C1, 0x05C2, WEAK_NSM },
- { 0x05C3, 0x05C3, STRONG_R },
- { 0x05C4, 0x05C5, WEAK_NSM },
- { 0x05C6, 0x05C6, STRONG_R },
- { 0x05C7, 0x05C7, WEAK_NSM },
- { 0x05D0, 0x05F4, STRONG_R },
- { 0x0600, 0x0603, WEAK_AN },
- { 0x0606, 0x0607, NEUTRAL_ON },
- { 0x0608, 0x0608, STRONG_AL },
- { 0x0609, 0x060A, WEAK_ET },
- { 0x060B, 0x060B, STRONG_AL },
- { 0x060C, 0x060C, WEAK_CS },
- { 0x060D, 0x060D, STRONG_AL },
- { 0x060E, 0x060F, NEUTRAL_ON },
- { 0x0610, 0x061A, WEAK_NSM },
- { 0x061B, 0x064A, STRONG_AL },
- { 0x064B, 0x065F, WEAK_NSM },
- { 0x0660, 0x0669, WEAK_AN },
- { 0x066A, 0x066A, WEAK_ET },
- { 0x066B, 0x066C, WEAK_AN },
- { 0x066D, 0x066F, STRONG_AL },
- { 0x0670, 0x0670, WEAK_NSM },
- { 0x0671, 0x06D5, STRONG_AL },
- { 0x06D6, 0x06DC, WEAK_NSM },
- { 0x06DD, 0x06DD, WEAK_AN },
- { 0x06DE, 0x06DE, NEUTRAL_ON },
- { 0x06DF, 0x06E4, WEAK_NSM },
- { 0x06E5, 0x06E6, STRONG_AL },
- { 0x06E7, 0x06E8, WEAK_NSM },
- { 0x06E9, 0x06E9, NEUTRAL_ON },
- { 0x06EA, 0x06ED, WEAK_NSM },
- { 0x06EE, 0x06EF, STRONG_AL },
- { 0x06F0, 0x06F9, WEAK_EN },
- { 0x06FA, 0x070D, STRONG_AL },
- { 0x070F, 0x070F, WEAK_AN },
- { 0x0710, 0x0710, STRONG_AL },
- { 0x0711, 0x0711, WEAK_NSM },
- { 0x0712, 0x072F, STRONG_AL },
- { 0x0730, 0x074A, WEAK_NSM },
- { 0x074D, 0x07A5, STRONG_AL },
- { 0x07A6, 0x07B0, WEAK_NSM },
- { 0x07B1, 0x07B1, STRONG_AL },
- { 0x07C0, 0x07EA, STRONG_R },
- { 0x07EB, 0x07F3, WEAK_NSM },
- { 0x07F4, 0x07F5, STRONG_R },
- { 0x07F6, 0x07F9, NEUTRAL_ON },
- { 0x07FA, 0x0815, STRONG_R },
- { 0x0816, 0x0819, WEAK_NSM },
- { 0x081A, 0x081A, STRONG_R },
- { 0x081B, 0x0823, WEAK_NSM },
- { 0x0824, 0x0824, STRONG_R },
- { 0x0825, 0x0827, WEAK_NSM },
- { 0x0828, 0x0828, STRONG_R },
- { 0x0829, 0x082D, WEAK_NSM },
- { 0x0830, 0x0858, STRONG_R },
- { 0x0859, 0x085B, WEAK_NSM },
- { 0x085E, 0x085E, STRONG_R },
- { 0x0900, 0x0902, WEAK_NSM },
- { 0x093A, 0x093A, WEAK_NSM },
- { 0x093C, 0x093C, WEAK_NSM },
- { 0x0941, 0x0948, WEAK_NSM },
- { 0x094D, 0x094D, WEAK_NSM },
- { 0x0951, 0x0957, WEAK_NSM },
- { 0x0962, 0x0963, WEAK_NSM },
- { 0x0981, 0x0981, WEAK_NSM },
- { 0x09BC, 0x09BC, WEAK_NSM },
- { 0x09C1, 0x09C4, WEAK_NSM },
- { 0x09CD, 0x09CD, WEAK_NSM },
- { 0x09E2, 0x09E3, WEAK_NSM },
- { 0x09F2, 0x09F3, WEAK_ET },
- { 0x09FB, 0x09FB, WEAK_ET },
- { 0x0A01, 0x0A02, WEAK_NSM },
- { 0x0A3C, 0x0A3C, WEAK_NSM },
- { 0x0A41, 0x0A51, WEAK_NSM },
- { 0x0A70, 0x0A71, WEAK_NSM },
- { 0x0A75, 0x0A82, WEAK_NSM },
- { 0x0ABC, 0x0ABC, WEAK_NSM },
- { 0x0AC1, 0x0AC8, WEAK_NSM },
- { 0x0ACD, 0x0ACD, WEAK_NSM },
- { 0x0AE2, 0x0AE3, WEAK_NSM },
- { 0x0AF1, 0x0AF1, WEAK_ET },
- { 0x0B01, 0x0B01, WEAK_NSM },
- { 0x0B3C, 0x0B3C, WEAK_NSM },
- { 0x0B3F, 0x0B3F, WEAK_NSM },
- { 0x0B41, 0x0B44, WEAK_NSM },
- { 0x0B4D, 0x0B56, WEAK_NSM },
- { 0x0B62, 0x0B63, WEAK_NSM },
- { 0x0B82, 0x0B82, WEAK_NSM },
- { 0x0BC0, 0x0BC0, WEAK_NSM },
- { 0x0BCD, 0x0BCD, WEAK_NSM },
- { 0x0BF3, 0x0BF8, NEUTRAL_ON },
- { 0x0BF9, 0x0BF9, WEAK_ET },
- { 0x0BFA, 0x0BFA, NEUTRAL_ON },
- { 0x0C3E, 0x0C40, WEAK_NSM },
- { 0x0C46, 0x0C56, WEAK_NSM },
- { 0x0C62, 0x0C63, WEAK_NSM },
- { 0x0C78, 0x0C7E, NEUTRAL_ON },
- { 0x0CBC, 0x0CBC, WEAK_NSM },
- { 0x0CCC, 0x0CCD, WEAK_NSM },
- { 0x0CE2, 0x0CE3, WEAK_NSM },
- { 0x0D41, 0x0D44, WEAK_NSM },
- { 0x0D4D, 0x0D4D, WEAK_NSM },
- { 0x0D62, 0x0D63, WEAK_NSM },
- { 0x0DCA, 0x0DCA, WEAK_NSM },
- { 0x0DD2, 0x0DD6, WEAK_NSM },
- { 0x0E31, 0x0E31, WEAK_NSM },
- { 0x0E34, 0x0E3A, WEAK_NSM },
- { 0x0E3F, 0x0E3F, WEAK_ET },
- { 0x0E47, 0x0E4E, WEAK_NSM },
- { 0x0EB1, 0x0EB1, WEAK_NSM },
- { 0x0EB4, 0x0EBC, WEAK_NSM },
- { 0x0EC8, 0x0ECD, WEAK_NSM },
- { 0x0F18, 0x0F19, WEAK_NSM },
- { 0x0F35, 0x0F35, WEAK_NSM },
- { 0x0F37, 0x0F37, WEAK_NSM },
- { 0x0F39, 0x0F39, WEAK_NSM },
- { 0x0F3A, 0x0F3D, NEUTRAL_ON },
- { 0x0F71, 0x0F7E, WEAK_NSM },
- { 0x0F80, 0x0F84, WEAK_NSM },
- { 0x0F86, 0x0F87, WEAK_NSM },
- { 0x0F8D, 0x0FBC, WEAK_NSM },
- { 0x0FC6, 0x0FC6, WEAK_NSM },
- { 0x102D, 0x1030, WEAK_NSM },
- { 0x1032, 0x1037, WEAK_NSM },
- { 0x1039, 0x103A, WEAK_NSM },
- { 0x103D, 0x103E, WEAK_NSM },
- { 0x1058, 0x1059, WEAK_NSM },
- { 0x105E, 0x1060, WEAK_NSM },
- { 0x1071, 0x1074, WEAK_NSM },
- { 0x1082, 0x1082, WEAK_NSM },
- { 0x1085, 0x1086, WEAK_NSM },
- { 0x108D, 0x108D, WEAK_NSM },
- { 0x109D, 0x109D, WEAK_NSM },
- { 0x135D, 0x135F, WEAK_NSM },
- { 0x1390, 0x1399, NEUTRAL_ON },
- { 0x1400, 0x1400, NEUTRAL_ON },
- { 0x1680, 0x1680, NEUTRAL_WS },
- { 0x169B, 0x169C, NEUTRAL_ON },
- { 0x1712, 0x1714, WEAK_NSM },
- { 0x1732, 0x1734, WEAK_NSM },
- { 0x1752, 0x1753, WEAK_NSM },
- { 0x1772, 0x1773, WEAK_NSM },
- { 0x17B7, 0x17BD, WEAK_NSM },
- { 0x17C6, 0x17C6, WEAK_NSM },
- { 0x17C9, 0x17D3, WEAK_NSM },
- { 0x17DB, 0x17DB, WEAK_ET },
- { 0x17DD, 0x17DD, WEAK_NSM },
- { 0x17F0, 0x180A, NEUTRAL_ON },
- { 0x180B, 0x180D, WEAK_NSM },
- { 0x180E, 0x180E, NEUTRAL_WS },
- { 0x18A9, 0x18A9, WEAK_NSM },
- { 0x1920, 0x1922, WEAK_NSM },
- { 0x1927, 0x1928, WEAK_NSM },
- { 0x1932, 0x1932, WEAK_NSM },
- { 0x1939, 0x193B, WEAK_NSM },
- { 0x1940, 0x1945, NEUTRAL_ON },
- { 0x19DE, 0x19FF, NEUTRAL_ON },
- { 0x1A17, 0x1A18, WEAK_NSM },
- { 0x1A56, 0x1A56, WEAK_NSM },
- { 0x1A58, 0x1A60, WEAK_NSM },
- { 0x1A62, 0x1A62, WEAK_NSM },
- { 0x1A65, 0x1A6C, WEAK_NSM },
- { 0x1A73, 0x1A7F, WEAK_NSM },
- { 0x1B00, 0x1B03, WEAK_NSM },
- { 0x1B34, 0x1B34, WEAK_NSM },
- { 0x1B36, 0x1B3A, WEAK_NSM },
- { 0x1B3C, 0x1B3C, WEAK_NSM },
- { 0x1B42, 0x1B42, WEAK_NSM },
- { 0x1B6B, 0x1B73, WEAK_NSM },
- { 0x1B80, 0x1B81, WEAK_NSM },
- { 0x1BA2, 0x1BA5, WEAK_NSM },
- { 0x1BA8, 0x1BA9, WEAK_NSM },
- { 0x1BE6, 0x1BE6, WEAK_NSM },
- { 0x1BE8, 0x1BE9, WEAK_NSM },
- { 0x1BED, 0x1BED, WEAK_NSM },
- { 0x1BEF, 0x1BF1, WEAK_NSM },
- { 0x1C2C, 0x1C33, WEAK_NSM },
- { 0x1C36, 0x1C37, WEAK_NSM },
- { 0x1CD0, 0x1CD2, WEAK_NSM },
- { 0x1CD4, 0x1CE0, WEAK_NSM },
- { 0x1CE2, 0x1CE8, WEAK_NSM },
- { 0x1CED, 0x1CED, WEAK_NSM },
- { 0x1DC0, 0x1DFF, WEAK_NSM },
- { 0x1FBD, 0x1FBD, NEUTRAL_ON },
- { 0x1FBF, 0x1FC1, NEUTRAL_ON },
- { 0x1FCD, 0x1FCF, NEUTRAL_ON },
- { 0x1FDD, 0x1FDF, NEUTRAL_ON },
- { 0x1FED, 0x1FEF, NEUTRAL_ON },
- { 0x1FFD, 0x1FFE, NEUTRAL_ON },
- { 0x2000, 0x200A, NEUTRAL_WS },
- { 0x200B, 0x200D, WEAK_BN },
- { 0x200F, 0x200F, STRONG_R },
- { 0x2010, 0x2027, NEUTRAL_ON },
- { 0x2028, 0x2028, NEUTRAL_WS },
- { 0x2029, 0x2029, NEUTRAL_B },
- { 0x202A, 0x202A, LRE },
- { 0x202B, 0x202B, RLE },
- { 0x202C, 0x202C, PDF },
- { 0x202D, 0x202D, LRO },
- { 0x202E, 0x202E, RLO },
- { 0x202F, 0x202F, WEAK_CS },
- { 0x2030, 0x2034, WEAK_ET },
- { 0x2035, 0x2043, NEUTRAL_ON },
- { 0x2044, 0x2044, WEAK_CS },
- { 0x2045, 0x205E, NEUTRAL_ON },
- { 0x205F, 0x205F, NEUTRAL_WS },
- { 0x2060, 0x206F, WEAK_BN },
- { 0x2070, 0x2070, WEAK_EN },
- { 0x2074, 0x2079, WEAK_EN },
- { 0x207A, 0x207B, WEAK_ES },
- { 0x207C, 0x207E, NEUTRAL_ON },
- { 0x2080, 0x2089, WEAK_EN },
- { 0x208A, 0x208B, WEAK_ES },
- { 0x208C, 0x208E, NEUTRAL_ON },
- { 0x20A0, 0x20B9, WEAK_ET },
- { 0x20D0, 0x20F0, WEAK_NSM },
- { 0x2100, 0x2101, NEUTRAL_ON },
- { 0x2103, 0x2106, NEUTRAL_ON },
- { 0x2108, 0x2109, NEUTRAL_ON },
- { 0x2114, 0x2114, NEUTRAL_ON },
- { 0x2116, 0x2118, NEUTRAL_ON },
- { 0x211E, 0x2123, NEUTRAL_ON },
- { 0x2125, 0x2125, NEUTRAL_ON },
- { 0x2127, 0x2127, NEUTRAL_ON },
- { 0x2129, 0x2129, NEUTRAL_ON },
- { 0x212E, 0x212E, WEAK_ET },
- { 0x213A, 0x213B, NEUTRAL_ON },
- { 0x2140, 0x2144, NEUTRAL_ON },
- { 0x214A, 0x214D, NEUTRAL_ON },
- { 0x2150, 0x215F, NEUTRAL_ON },
- { 0x2189, 0x2211, NEUTRAL_ON },
- { 0x2212, 0x2212, WEAK_ES },
- { 0x2213, 0x2213, WEAK_ET },
- { 0x2214, 0x2335, NEUTRAL_ON },
- { 0x237B, 0x2394, NEUTRAL_ON },
- { 0x2396, 0x2487, NEUTRAL_ON },
- { 0x2488, 0x249B, WEAK_EN },
- { 0x24EA, 0x26AB, NEUTRAL_ON },
- { 0x26AD, 0x27FF, NEUTRAL_ON },
- { 0x2900, 0x2B59, NEUTRAL_ON },
- { 0x2CE5, 0x2CEA, NEUTRAL_ON },
- { 0x2CEF, 0x2CF1, WEAK_NSM },
- { 0x2CF9, 0x2CFF, NEUTRAL_ON },
- { 0x2D7F, 0x2D7F, WEAK_NSM },
- { 0x2DE0, 0x2DFF, WEAK_NSM },
- { 0x2E00, 0x2FFB, NEUTRAL_ON },
- { 0x3000, 0x3000, NEUTRAL_WS },
- { 0x3001, 0x3004, NEUTRAL_ON },
- { 0x3008, 0x3020, NEUTRAL_ON },
- { 0x302A, 0x302F, WEAK_NSM },
- { 0x3030, 0x3030, NEUTRAL_ON },
- { 0x3036, 0x3037, NEUTRAL_ON },
- { 0x303D, 0x303F, NEUTRAL_ON },
- { 0x3099, 0x309A, WEAK_NSM },
- { 0x309B, 0x309C, NEUTRAL_ON },
- { 0x30A0, 0x30A0, NEUTRAL_ON },
- { 0x30FB, 0x30FB, NEUTRAL_ON },
- { 0x31C0, 0x31E3, NEUTRAL_ON },
- { 0x321D, 0x321E, NEUTRAL_ON },
- { 0x3250, 0x325F, NEUTRAL_ON },
- { 0x327C, 0x327E, NEUTRAL_ON },
- { 0x32B1, 0x32BF, NEUTRAL_ON },
- { 0x32CC, 0x32CF, NEUTRAL_ON },
- { 0x3377, 0x337A, NEUTRAL_ON },
- { 0x33DE, 0x33DF, NEUTRAL_ON },
- { 0x33FF, 0x33FF, NEUTRAL_ON },
- { 0x4DC0, 0x4DFF, NEUTRAL_ON },
- { 0xA490, 0xA4C6, NEUTRAL_ON },
- { 0xA60D, 0xA60F, NEUTRAL_ON },
- { 0xA66F, 0xA672, WEAK_NSM },
- { 0xA673, 0xA673, NEUTRAL_ON },
- { 0xA67C, 0xA67D, WEAK_NSM },
- { 0xA67E, 0xA67F, NEUTRAL_ON },
- { 0xA6F0, 0xA6F1, WEAK_NSM },
- { 0xA700, 0xA721, NEUTRAL_ON },
- { 0xA788, 0xA788, NEUTRAL_ON },
- { 0xA802, 0xA802, WEAK_NSM },
- { 0xA806, 0xA806, WEAK_NSM },
- { 0xA80B, 0xA80B, WEAK_NSM },
- { 0xA825, 0xA826, WEAK_NSM },
- { 0xA828, 0xA82B, NEUTRAL_ON },
- { 0xA838, 0xA839, WEAK_ET },
- { 0xA874, 0xA877, NEUTRAL_ON },
- { 0xA8C4, 0xA8C4, WEAK_NSM },
- { 0xA8E0, 0xA8F1, WEAK_NSM },
- { 0xA926, 0xA92D, WEAK_NSM },
- { 0xA947, 0xA951, WEAK_NSM },
- { 0xA980, 0xA982, WEAK_NSM },
- { 0xA9B3, 0xA9B3, WEAK_NSM },
- { 0xA9B6, 0xA9B9, WEAK_NSM },
- { 0xA9BC, 0xA9BC, WEAK_NSM },
- { 0xAA29, 0xAA2E, WEAK_NSM },
- { 0xAA31, 0xAA32, WEAK_NSM },
- { 0xAA35, 0xAA36, WEAK_NSM },
- { 0xAA43, 0xAA43, WEAK_NSM },
- { 0xAA4C, 0xAA4C, WEAK_NSM },
- { 0xAAB0, 0xAAB0, WEAK_NSM },
- { 0xAAB2, 0xAAB4, WEAK_NSM },
- { 0xAAB7, 0xAAB8, WEAK_NSM },
- { 0xAABE, 0xAABF, WEAK_NSM },
- { 0xAAC1, 0xAAC1, WEAK_NSM },
- { 0xABE5, 0xABE5, WEAK_NSM },
- { 0xABE8, 0xABE8, WEAK_NSM },
- { 0xABED, 0xABED, WEAK_NSM },
- { 0xFB1D, 0xFB1D, STRONG_R },
- { 0xFB1E, 0xFB1E, WEAK_NSM },
- { 0xFB1F, 0xFB28, STRONG_R },
- { 0xFB29, 0xFB29, WEAK_ES },
- { 0xFB2A, 0xFB4F, STRONG_R },
- { 0xFB50, 0xFD3D, STRONG_AL },
- { 0xFD3E, 0xFD3F, NEUTRAL_ON },
- { 0xFD50, 0xFDFC, STRONG_AL },
- { 0xFDFD, 0xFDFD, NEUTRAL_ON },
- { 0xFE00, 0xFE0F, WEAK_NSM },
- { 0xFE10, 0xFE19, NEUTRAL_ON },
- { 0xFE20, 0xFE26, WEAK_NSM },
- { 0xFE30, 0xFE4F, NEUTRAL_ON },
- { 0xFE50, 0xFE50, WEAK_CS },
- { 0xFE51, 0xFE51, NEUTRAL_ON },
- { 0xFE52, 0xFE52, WEAK_CS },
- { 0xFE54, 0xFE54, NEUTRAL_ON },
- { 0xFE55, 0xFE55, WEAK_CS },
- { 0xFE56, 0xFE5E, NEUTRAL_ON },
- { 0xFE5F, 0xFE5F, WEAK_ET },
- { 0xFE60, 0xFE61, NEUTRAL_ON },
- { 0xFE62, 0xFE63, WEAK_ES },
- { 0xFE64, 0xFE68, NEUTRAL_ON },
- { 0xFE69, 0xFE6A, WEAK_ET },
- { 0xFE6B, 0xFE6B, NEUTRAL_ON },
- { 0xFE70, 0xFEFC, STRONG_AL },
- { 0xFEFF, 0xFEFF, WEAK_BN },
- { 0xFF01, 0xFF02, NEUTRAL_ON },
- { 0xFF03, 0xFF05, WEAK_ET },
- { 0xFF06, 0xFF0A, NEUTRAL_ON },
- { 0xFF0B, 0xFF0B, WEAK_ES },
- { 0xFF0C, 0xFF0C, WEAK_CS },
- { 0xFF0D, 0xFF0D, WEAK_ES },
- { 0xFF0E, 0xFF0F, WEAK_CS },
- { 0xFF10, 0xFF19, WEAK_EN },
- { 0xFF1A, 0xFF1A, WEAK_CS },
- { 0xFF1B, 0xFF20, NEUTRAL_ON },
- { 0xFF3B, 0xFF40, NEUTRAL_ON },
- { 0xFF5B, 0xFF65, NEUTRAL_ON },
- { 0xFFE0, 0xFFE1, WEAK_ET },
- { 0xFFE2, 0xFFE4, NEUTRAL_ON },
- { 0xFFE5, 0xFFE6, WEAK_ET },
- { 0xFFE8, 0xFFFD, NEUTRAL_ON },
- { 0x10101, 0x10101, NEUTRAL_ON },
- { 0x10140, 0x1019B, NEUTRAL_ON },
- { 0x101FD, 0x101FD, WEAK_NSM },
- { 0x10800, 0x1091B, STRONG_R },
- { 0x1091F, 0x1091F, NEUTRAL_ON },
- { 0x10920, 0x10A00, STRONG_R },
- { 0x10A01, 0x10A0F, WEAK_NSM },
- { 0x10A10, 0x10A33, STRONG_R },
- { 0x10A38, 0x10A3F, WEAK_NSM },
- { 0x10A40, 0x10B35, STRONG_R },
- { 0x10B39, 0x10B3F, NEUTRAL_ON },
- { 0x10B40, 0x10C48, STRONG_R },
- { 0x10E60, 0x10E7E, WEAK_AN },
- { 0x11001, 0x11001, WEAK_NSM },
- { 0x11038, 0x11046, WEAK_NSM },
- { 0x11052, 0x11065, NEUTRAL_ON },
- { 0x11080, 0x11081, WEAK_NSM },
- { 0x110B3, 0x110B6, WEAK_NSM },
- { 0x110B9, 0x110BA, WEAK_NSM },
- { 0x1D167, 0x1D169, WEAK_NSM },
- { 0x1D173, 0x1D17A, WEAK_BN },
- { 0x1D17B, 0x1D182, WEAK_NSM },
- { 0x1D185, 0x1D18B, WEAK_NSM },
- { 0x1D1AA, 0x1D1AD, WEAK_NSM },
- { 0x1D200, 0x1D241, NEUTRAL_ON },
- { 0x1D242, 0x1D244, WEAK_NSM },
- { 0x1D245, 0x1D356, NEUTRAL_ON },
- { 0x1D6DB, 0x1D6DB, NEUTRAL_ON },
- { 0x1D715, 0x1D715, NEUTRAL_ON },
- { 0x1D74F, 0x1D74F, NEUTRAL_ON },
- { 0x1D789, 0x1D789, NEUTRAL_ON },
- { 0x1D7C3, 0x1D7C3, NEUTRAL_ON },
- { 0x1D7CE, 0x1D7FF, WEAK_EN },
- { 0x1F000, 0x1F0DF, NEUTRAL_ON },
- { 0x1F100, 0x1F10A, WEAK_EN },
- { 0x1F300, 0x1F48B, NEUTRAL_ON },
- { 0x1F48D, 0x1F523, NEUTRAL_ON },
- { 0x1F525, 0x1F773, NEUTRAL_ON },
- { 0xE0001, 0xE007F, WEAK_BN },
- { 0xE0100, 0xE01EF, WEAK_NSM } };
diff --git a/src/buffer.c b/src/buffer.c
index 45d6fa36d0..37d2975c8c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1698,27 +1698,16 @@ record_buffer (Lisp_Object buffer)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
}
-DEFUN ("record-buffer", Frecord_buffer, Srecord_buffer, 1, 1, 0,
- doc: /* Move BUFFER to the front of the buffer list.
-Return BUFFER. */)
- (Lisp_Object buffer)
-{
- CHECK_BUFFER (buffer);
-
- record_buffer (buffer);
-
- return buffer;
-}
- /* Move BUFFER to the end of the buffer (a)lists. Do nothing if the
- buffer is killed. For the selected frame's buffer list this moves
- BUFFER to its end even if it was never shown in that frame. If
- this happens we have a feature, hence `unrecord-buffer' should be
- called only when BUFFER was shown in the selected frame. */
+/* Move BUFFER to the end of the buffer (a)lists. Do nothing if the
+ buffer is killed. For the selected frame's buffer list this moves
+ BUFFER to its end even if it was never shown in that frame. If
+ this happens we have a feature, hence `unrecord-buffer' should be
+ called only when BUFFER was shown in the selected frame. */
-DEFUN ("unrecord-buffer", Funrecord_buffer, Sunrecord_buffer, 1, 1, 0,
- doc: /* Move BUFFER to the end of the buffer list.
-Return BUFFER. */)
+DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
+ 1, 1, 0,
+ doc: /* Move BUFFER to the end of the buffer list. */)
(Lisp_Object buffer)
{
Lisp_Object aelt, aelt_cons, tem;
@@ -1746,7 +1735,7 @@ Return BUFFER. */)
if (!NILP (Vrun_hooks))
call1 (Vrun_hooks, Qbuffer_list_update_hook);
- return buffer;
+ return Qnil;
}
DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
@@ -2568,13 +2557,10 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
Either make it bigger, or don't store any more in it. */
if (extend)
{
- if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
- memory_full (SIZE_MAX);
- /* Make it work with an initial len == 0. */
- len = len * 2 + 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
@@ -2611,13 +2597,10 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
{
if (extend)
{
- if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
- memory_full (SIZE_MAX);
- /* Make it work with an initial len == 0. */
- len = len * 2 + 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
@@ -2708,13 +2691,10 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
Either make it bigger, or don't store any more in it. */
if (extend)
{
- if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
- memory_full (SIZE_MAX);
- /* Make it work with an initial len == 0. */
- len = len * 2 + 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
@@ -2756,13 +2736,10 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
{
if (extend)
{
- if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
- memory_full (SIZE_MAX);
- /* Make it work with an initial len == 0. */
- len = len * 2 + 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
@@ -2944,7 +2921,7 @@ struct sortstrlist
struct sortstr *buf; /* An array that expands as needed; never freed. */
ptrdiff_t size; /* Allocated length of that array. */
ptrdiff_t used; /* How much of the array is currently in use. */
- EMACS_INT bytes; /* Total length of the strings in buf. */
+ ptrdiff_t bytes; /* Total length of the strings in buf. */
};
/* Buffers for storing information about the overlays touching a given
@@ -2955,7 +2932,7 @@ static struct sortstrlist overlay_heads, overlay_tails;
static unsigned char *overlay_str_buf;
/* Allocated length of overlay_str_buf. */
-static EMACS_INT overlay_str_len;
+static ptrdiff_t overlay_str_len;
/* A comparison function suitable for passing to qsort. */
static int
@@ -2977,17 +2954,7 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
EMACS_INT nbytes;
if (ssl->used == ssl->size)
- {
- if (min (PTRDIFF_MAX, SIZE_MAX) / (sizeof (struct sortstr) * 2)
- < ssl->size)
- memory_full (SIZE_MAX);
- else if (0 < ssl->size)
- ssl->size *= 2;
- else
- ssl->size = 5;
- ssl->buf = ((struct sortstr *)
- xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
- }
+ ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf);
ssl->buf[ssl->used].string = str;
ssl->buf[ssl->used].string2 = str2;
ssl->buf[ssl->used].size = size;
@@ -3002,6 +2969,8 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
else
nbytes = SBYTES (str);
+ if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+ memory_full (SIZE_MAX);
ssl->bytes += nbytes;
if (STRINGP (str2))
@@ -3014,6 +2983,8 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
else
nbytes = SBYTES (str2);
+ if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+ memory_full (SIZE_MAX);
ssl->bytes += nbytes;
}
}
@@ -3107,14 +3078,15 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
Lisp_Object tem;
EMACS_INT i;
unsigned char *p;
- EMACS_INT total = overlay_heads.bytes + overlay_tails.bytes;
+ ptrdiff_t total;
+ if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes))
+ memory_full (SIZE_MAX);
+ total = overlay_heads.bytes + overlay_tails.bytes;
if (total > overlay_str_len)
- {
- overlay_str_len = total;
- overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
- total);
- }
+ overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
+ total - overlay_str_len, -1, 1);
+
p = overlay_str_buf;
for (i = overlay_tails.used; --i >= 0;)
{
@@ -6034,8 +6006,7 @@ Functions running this hook are `get-buffer-create',
defsubr (&Sother_buffer);
defsubr (&Sbuffer_enable_undo);
defsubr (&Skill_buffer);
- defsubr (&Srecord_buffer);
- defsubr (&Sunrecord_buffer);
+ defsubr (&Sbury_buffer_internal);
defsubr (&Sset_buffer_major_mode);
defsubr (&Scurrent_buffer);
defsubr (&Sset_buffer);
diff --git a/src/callproc.c b/src/callproc.c
index f148f6233d..1bdb57a27d 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -252,7 +252,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
val = Qraw_text;
else
{
- SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
+ SAFE_NALLOCA (args2, 1, nargs + 1);
args2[0] = Qcall_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
@@ -603,6 +603,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
/* vfork, and prevent local vars from being clobbered by the vfork. */
{
+ Lisp_Object volatile buffer_volatile = buffer;
+ Lisp_Object volatile coding_systems_volatile = coding_systems;
+ Lisp_Object volatile current_dir_volatile = current_dir;
int volatile fd1_volatile = fd1;
int volatile fd_error_volatile = fd_error;
int volatile fd_output_volatile = fd_output;
@@ -611,6 +614,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
pid = vfork ();
+ buffer = buffer_volatile;
+ coding_systems = coding_systems_volatile;
+ current_dir = current_dir_volatile;
fd1 = fd1_volatile;
fd_error = fd_error_volatile;
fd_output = fd_output_volatile;
@@ -720,7 +726,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
{
ptrdiff_t i;
- SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
+ SAFE_NALLOCA (args2, 1, nargs + 1);
args2[0] = Qcall_process;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
coding_systems
@@ -1018,7 +1024,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
else
{
USE_SAFE_ALLOCA;
- SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
+ SAFE_NALLOCA (args2, 1, nargs + 1);
args2[0] = Qcall_process_region;
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
@@ -1147,7 +1153,7 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L
cleaned up in the usual way. */
{
register char *temp;
- register int i;
+ size_t i; /* size_t, because ptrdiff_t might overflow here! */
i = SBYTES (current_dir);
#ifdef MSDOS
diff --git a/src/category.c b/src/category.c
index 08eadb0473..a822bb654b 100644
--- a/src/category.c
+++ b/src/category.c
@@ -67,7 +67,7 @@ static Lisp_Object
hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
{
struct Lisp_Hash_Table *h;
- EMACS_INT i;
+ ptrdiff_t i;
EMACS_UINT hash;
if (NILP (XCHAR_TABLE (table)->extras[1]))
diff --git a/src/ccl.c b/src/ccl.c
index 9cfcbfe870..b28a284f70 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -1303,7 +1303,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case CCL_LookupIntConstTbl:
{
- EMACS_INT eop;
+ ptrdiff_t eop;
struct Lisp_Hash_Table *h;
GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
(VECTORP (Vtranslation_hash_table_vector)
@@ -1329,7 +1329,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case CCL_LookupCharConstTbl:
{
- EMACS_INT eop;
+ ptrdiff_t eop;
struct Lisp_Hash_Table *h;
GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
(VECTORP (Vtranslation_hash_table_vector)
@@ -1770,7 +1770,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
}
msglen = strlen (msg);
- if (dst + msglen <= dst_end)
+ if (msglen <= dst_end - dst)
{
for (i = 0; i < msglen; i++)
*dst++ = msg[i];
@@ -2061,12 +2061,13 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
Lisp_Object val;
struct ccl_program ccl;
int i;
- EMACS_INT outbufsize;
+ ptrdiff_t outbufsize;
unsigned char *outbuf, *outp;
- EMACS_INT str_chars, str_bytes;
+ ptrdiff_t str_chars, str_bytes;
#define CCL_EXECUTE_BUF_SIZE 1024
int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE];
- EMACS_INT consumed_chars, consumed_bytes, produced_chars;
+ ptrdiff_t consumed_chars, consumed_bytes, produced_chars;
+ int buf_magnification;
if (setup_ccl_program (&ccl, ccl_prog) < 0)
error ("Invalid CCL program");
@@ -2093,6 +2094,10 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
ccl.ic = i;
}
+ buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1;
+
+ if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes)
+ memory_full (SIZE_MAX);
outbufsize = (ccl.buf_magnification
? str_bytes * ccl.buf_magnification + 256
: str_bytes + 256);
@@ -2122,31 +2127,25 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
src_size = j;
while (1)
{
+ int max_expansion = NILP (unibyte_p) ? MAX_MULTIBYTE_LENGTH : 1;
+ ptrdiff_t offset, shortfall;
ccl_driver (&ccl, src, destination, src_size, CCL_EXECUTE_BUF_SIZE,
Qnil);
produced_chars += ccl.produced;
+ offset = outp - outbuf;
+ shortfall = ccl.produced * max_expansion - (outbufsize - offset);
+ if (0 < shortfall)
+ {
+ outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1);
+ outp = outbuf + offset;
+ }
if (NILP (unibyte_p))
{
- if (outp - outbuf + MAX_MULTIBYTE_LENGTH * ccl.produced
- > outbufsize)
- {
- EMACS_INT offset = outp - outbuf;
- outbufsize += MAX_MULTIBYTE_LENGTH * ccl.produced;
- outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
- outp = outbuf + offset;
- }
for (j = 0; j < ccl.produced; j++)
CHAR_STRING_ADVANCE (destination[j], outp);
}
else
{
- if (outp - outbuf + ccl.produced > outbufsize)
- {
- EMACS_INT offset = outp - outbuf;
- outbufsize += ccl.produced;
- outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
- outp = outbuf + offset;
- }
for (j = 0; j < ccl.produced; j++)
*outp++ = destination[j];
}
diff --git a/src/character.c b/src/character.c
index 8e9b3e3775..fb9b8a9b93 100644
--- a/src/character.c
+++ b/src/character.c
@@ -326,7 +326,7 @@ usage: (char-width CHAR) */)
disp = dp ? DISP_CHAR_VECTOR (dp, c) : Qnil;
if (VECTORP (disp))
- width = ASIZE (disp);
+ width = sanitize_char_width (ASIZE (disp));
else
width = CHAR_WIDTH (c);
@@ -358,7 +358,7 @@ c_string_width (const unsigned char *str, EMACS_INT len, int precision,
{
val = DISP_CHAR_VECTOR (dp, c);
if (VECTORP (val))
- thiswidth = ASIZE (val);
+ thiswidth = sanitize_char_width (ASIZE (val));
else
thiswidth = CHAR_WIDTH (c);
}
@@ -423,7 +423,7 @@ lisp_string_width (Lisp_Object string, EMACS_INT precision,
{
EMACS_INT chars, bytes, thiswidth;
Lisp_Object val;
- int cmp_id;
+ ptrdiff_t cmp_id;
EMACS_INT ignore, end;
if (find_composition (i, -1, &ignore, &end, &val, string)
@@ -451,7 +451,7 @@ lisp_string_width (Lisp_Object string, EMACS_INT precision,
{
val = DISP_CHAR_VECTOR (dp, c);
if (VECTORP (val))
- thiswidth = ASIZE (val);
+ thiswidth = sanitize_char_width (ASIZE (val));
else
thiswidth = CHAR_WIDTH (c);
}
@@ -902,7 +902,7 @@ usage: (string &rest CHARACTERS) */)
Lisp_Object str;
USE_SAFE_ALLOCA;
- SAFE_ALLOCA (buf, unsigned char *, MAX_MULTIBYTE_LENGTH * n);
+ SAFE_NALLOCA (buf, MAX_MULTIBYTE_LENGTH, n);
p = buf;
for (i = 0; i < n; i++)
diff --git a/src/character.h b/src/character.h
index 063b5147dc..09bcf17ab9 100644
--- a/src/character.h
+++ b/src/character.h
@@ -556,6 +556,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
} while (0)
+/* Return a non-outlandish value for the tab width. */
+
+#define SANE_TAB_WIDTH(buf) \
+ sanitize_tab_width (XFASTINT (BVAR (buf, tab_width)))
+static inline int
+sanitize_tab_width (EMACS_INT width)
+{
+ return 0 < width && width <= 1000 ? width : 8;
+}
+
/* Return the width of ASCII character C. The width is measured by
how many columns C will occupy on the screen when displayed in the
current buffer. */
@@ -563,12 +573,20 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define ASCII_CHAR_WIDTH(c) \
(c < 0x20 \
? (c == '\t' \
- ? XFASTINT (BVAR (current_buffer, tab_width)) \
+ ? SANE_TAB_WIDTH (current_buffer) \
: (c == '\n' ? 0 : (NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2))) \
: (c < 0x7f \
? 1 \
: ((NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2))))
+/* Return a non-outlandish value for a character width. */
+
+static inline int
+sanitize_char_width (EMACS_INT width)
+{
+ return 0 <= width && width <= 1000 ? width : 1000;
+}
+
/* Return the width of character C. The width is measured by how many
columns C will occupy on the screen when displayed in the current
buffer. */
@@ -576,7 +594,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define CHAR_WIDTH(c) \
(ASCII_CHAR_P (c) \
? ASCII_CHAR_WIDTH (c) \
- : XINT (CHAR_TABLE_REF (Vchar_width_table, c)))
+ : sanitize_char_width (XINT (CHAR_TABLE_REF (Vchar_width_table, c))))
/* If C is a variation selector, return the index numnber of the
variation selector (1..256). Otherwise, return 0. */
diff --git a/src/charset.c b/src/charset.c
index 55234aa76a..6967b9df61 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -61,7 +61,7 @@ Lisp_Object Vcharset_hash_table;
/* Table of struct charset. */
struct charset *charset_table;
-static int charset_table_size;
+static ptrdiff_t charset_table_size;
static int charset_table_used;
Lisp_Object Qcharsetp;
@@ -419,7 +419,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
paying attention to comment character '#'. */
static inline unsigned
-read_hex (FILE *fp, int *eof)
+read_hex (FILE *fp, int *eof, int *overflow)
{
int c;
unsigned n;
@@ -441,15 +441,16 @@ read_hex (FILE *fp, int *eof)
*eof = 1;
return 0;
}
- *eof = 0;
n = 0;
- if (c == 'x')
- while ((c = getc (fp)) != EOF && isxdigit (c))
+ while (isxdigit (c = getc (fp)))
+ {
+ if (UINT_MAX >> 4 < n)
+ *overflow = 1;
n = ((n << 4)
- | (c <= '9' ? c - '0' : c <= 'F' ? c - 'A' + 10 : c - 'a' + 10));
- else
- while ((c = getc (fp)) != EOF && isdigit (c))
- n = (n * 10) + c - '0';
+ | (c - ('0' <= c && c <= '9' ? '0'
+ : 'A' <= c && c <= 'F' ? 'A' - 10
+ : 'a' - 10)));
+ }
if (c != EOF)
ungetc (c, fp);
return n;
@@ -479,7 +480,6 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
unsigned max_code = CHARSET_MAX_CODE (charset);
int fd;
FILE *fp;
- int eof;
Lisp_Object suffixes;
struct charset_map_entries *head, *entries;
int n_entries, count;
@@ -504,22 +504,27 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
memset (entries, 0, sizeof (struct charset_map_entries));
n_entries = 0;
- eof = 0;
while (1)
{
- unsigned from, to;
- int c;
+ unsigned from, to, c;
int idx;
+ int eof = 0, overflow = 0;
- from = read_hex (fp, &eof);
+ from = read_hex (fp, &eof, &overflow);
if (eof)
break;
if (getc (fp) == '-')
- to = read_hex (fp, &eof);
+ to = read_hex (fp, &eof, &overflow);
else
to = from;
- c = (int) read_hex (fp, &eof);
+ if (eof)
+ break;
+ c = read_hex (fp, &eof, &overflow);
+ if (eof)
+ break;
+ if (overflow)
+ continue;
if (from < min_code || to > max_code || from > to || c > MAX_CHAR)
continue;
@@ -1145,13 +1150,25 @@ usage: (define-charset-internal ...) */)
hash_code);
if (charset_table_used == charset_table_size)
{
- struct charset *new_table
- = (struct charset *) xmalloc (sizeof (struct charset)
- * (charset_table_size + 16));
- memcpy (new_table, charset_table,
- sizeof (struct charset) * charset_table_size);
- charset_table_size += 16;
+ /* Ensure that charset IDs fit into 'int' as well as into the
+ restriction imposed by fixnums. Although the 'int' restriction
+ could be removed, too much other code would need altering; for
+ example, the IDs are stuffed into struct
+ coding_system.charbuf[i] entries, which are 'int'. */
+ int old_size = charset_table_size;
+ struct charset *new_table =
+ xpalloc (0, &charset_table_size, 1,
+ min (INT_MAX, MOST_POSITIVE_FIXNUM),
+ sizeof *charset_table);
+ memcpy (new_table, charset_table, old_size * sizeof *new_table);
charset_table = new_table;
+ /* FIXME: Doesn't this leak memory? The old charset_table becomes
+ unreachable. It could be that this is intentional, because the
+ old charset table may be in a dumped emacs, and reallocating such
+ a table may not work. If the memory leak is intentional, a
+ comment should be added to explain this. If not, the old
+ charset_table should be freed, by passing it as the 1st argument
+ to xpalloc and removing the memcpy. */
}
id = charset_table_used++;
new_definition_p = 1;
@@ -2210,14 +2227,16 @@ struct charset_sort_data
{
Lisp_Object charset;
int id;
- int priority;
+ ptrdiff_t priority;
};
static int
charset_compare (const void *d1, const void *d2)
{
const struct charset_sort_data *data1 = d1, *data2 = d2;
- return (data1->priority - data2->priority);
+ if (data1->priority != data2->priority)
+ return data1->priority < data2->priority ? -1 : 1;
+ return 0;
}
DEFUN ("sort-charsets", Fsort_charsets, Ssort_charsets, 1, 1, 0,
@@ -2227,7 +2246,8 @@ See also `charset-priority-list' and `set-charset-priority'. */)
(Lisp_Object charsets)
{
Lisp_Object len = Flength (charsets);
- int n = XFASTINT (len), i, j, done;
+ ptrdiff_t n = XFASTINT (len), i, j;
+ int done;
Lisp_Object tail, elt, attrs;
struct charset_sort_data *sort_data;
int id, min_id = INT_MAX, max_id = INT_MIN;
@@ -2235,7 +2255,7 @@ See also `charset-priority-list' and `set-charset-priority'. */)
if (n == 0)
return Qnil;
- SAFE_ALLOCA (sort_data, struct charset_sort_data *, sizeof (*sort_data) * n);
+ SAFE_NALLOCA (sort_data, 1, n);
for (tail = charsets, i = 0; CONSP (tail); tail = XCDR (tail), i++)
{
elt = XCAR (tail);
@@ -2310,6 +2330,17 @@ init_charset_once (void)
void
syms_of_charset (void)
{
+ /* Allocate an initial charset table that is just under 64 KiB in size.
+ This should be large enough so that the charset table need not be
+ reallocated during an initial bootstrap. Allocating anything larger than
+ 64 KiB in an initial run may not work, because glibc malloc might use
+ mmap for larger allocations, and these don't work well across dumped
+ systems. */
+ enum {
+ initial_malloc_max = (1 << 16) - 1,
+ charset_table_size_init = initial_malloc_max / sizeof (struct charset)
+ };
+
DEFSYM (Qcharsetp, "charsetp");
DEFSYM (Qascii, "ascii");
@@ -2342,9 +2373,9 @@ syms_of_charset (void)
Vcharset_hash_table = Fmake_hash_table (2, args);
}
- charset_table_size = 128;
- charset_table = ((struct charset *)
- xmalloc (sizeof (struct charset) * charset_table_size));
+ charset_table = (struct charset *) xmalloc (sizeof (struct charset)
+ * charset_table_size_init);
+ charset_table_size = charset_table_size_init;
charset_table_used = 0;
defsubr (&Scharsetp);
diff --git a/src/charset.h b/src/charset.h
index c2a52a38e7..be02bc0fea 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -148,7 +148,7 @@ struct charset
int id;
/* Index to Vcharset_hash_table. */
- EMACS_INT hash_index;
+ ptrdiff_t hash_index;
/* Dimension of the charset: 1, 2, 3, or 4. */
int dimension;
@@ -341,7 +341,7 @@ extern int emacs_mule_charset[256];
number of the charset. Otherwise, signal an error. */
#define CHECK_CHARSET_GET_ID(x, id) \
do { \
- int idx; \
+ ptrdiff_t idx; \
\
if (! SYMBOLP (x) || (idx = CHARSET_SYMBOL_HASH_INDEX (x)) < 0) \
wrong_type_argument (Qcharsetp, (x)); \
diff --git a/src/chartab.c b/src/chartab.c
index efe23eca83..1d4ac04312 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -589,8 +589,6 @@ DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
(Lisp_Object char_table, Lisp_Object n, Lisp_Object value)
{
CHECK_CHAR_TABLE (char_table);
- if (EQ (XCHAR_TABLE (char_table)->purpose, Qchar_code_property_table))
- error ("Can't change extra-slot of char-code-property-table");
CHECK_NUMBER (n);
if (XINT (n) < 0
|| XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
@@ -1095,22 +1093,31 @@ map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
/* Unicode character property tables.
- This section provides a convenient and efficient way to get a
- Unicode character property from C code (from Lisp, you must use
- get-char-code-property).
+ This section provides a convenient and efficient way to get Unicode
+ character properties of characters from C code (from Lisp, you must
+ use get-char-code-property).
- The typical usage is to get a char-table for a specific property at
- a proper initialization time as this:
+ The typical usage is to get a char-table object for a specific
+ property like this (use of the "bidi-class" property below is just
+ an example):
Lisp_Object bidi_class_table = uniprop_table (intern ("bidi-class"));
- and get a property value for character CH as this:
+ (uniprop_table can return nil if it fails to find data for the
+ named property, or if it fails to load the appropriate Lisp support
+ file, so the return value should be tested to be non-nil, before it
+ is used.)
- Lisp_Object bidi_class = CHAR_TABLE_REF (CH, bidi_class_table);
+ To get a property value for character CH use CHAR_TABLE_REF:
+
+ Lisp_Object bidi_class = CHAR_TABLE_REF (bidi_class_table, CH);
In this case, what you actually get is an index number to the
vector of property values (symbols nil, L, R, etc).
+ The full list of Unicode character properties supported by Emacs is
+ documented in the ELisp manual, in the node "Character Properties".
+
A table for Unicode character property has these characteristics:
o The purpose is `char-code-property-table', which implies that the
@@ -1122,7 +1129,7 @@ map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
means that we don't have to decode values.
o The third extra slot is a Lisp function, an index (integer) to
- the array uniprop_enncoder[], or nil. If it is a Lisp function, we
+ the array uniprop_encoder[], or nil. If it is a Lisp function, we
can't use such a table from C (at the moment). If it is nil, it
means that we don't have to encode values. */
@@ -1310,7 +1317,7 @@ uniprop_get_encoder (Lisp_Object table)
function may load a Lisp file and thus may cause
garbage-collection. */
-static Lisp_Object
+Lisp_Object
uniprop_table (Lisp_Object prop)
{
Lisp_Object val, table, result;
diff --git a/src/cmds.c b/src/cmds.c
index f49cfc221b..5a155ac77a 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -271,7 +271,8 @@ Whichever character you type to run this command is inserted.
Before insertion, `expand-abbrev' is executed if the inserted character does
not have word syntax and the previous character in the buffer does.
After insertion, the value of `auto-fill-function' is called if the
-`auto-fill-chars' table has a non-nil value for the inserted character. */)
+`auto-fill-chars' table has a non-nil value for the inserted character.
+At the end, it runs `post-self-insert-hook'. */)
(Lisp_Object n)
{
int remove_boundary = 1;
@@ -471,7 +472,7 @@ internal_self_insert (int c, EMACS_INT n)
{
USE_SAFE_ALLOCA;
char *strn, *p;
- SAFE_ALLOCA (strn, char *, n * len);
+ SAFE_NALLOCA (strn, len, n);
for (p = strn; n > 0; n--, p += len)
memcpy (p, str, len);
insert_and_inherit (strn, p - strn);
diff --git a/src/coding.c b/src/coding.c
index 65c8a767c2..5fd59d394d 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -5838,7 +5838,7 @@ coding_charset_list (struct coding_system *coding)
Lisp_Object
coding_system_charset_list (Lisp_Object coding_system)
{
- int id;
+ ptrdiff_t id;
Lisp_Object attrs, charset_list;
CHECK_CODING_SYSTEM_GET_ID (coding_system, id);
@@ -6683,8 +6683,12 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
break;
}
- if (dst + MAX_MULTIBYTE_LENGTH * to_nchars > dst_end)
+ if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
{
+ if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
+ / MAX_MULTIBYTE_LENGTH)
+ < to_nchars)
+ memory_full (SIZE_MAX);
dst = alloc_destination (coding,
buf_end - buf
+ MAX_MULTIBYTE_LENGTH * to_nchars,
@@ -7888,11 +7892,10 @@ encode_coding_object (struct coding_system *coding,
}
else if (EQ (dst_object, Qt))
{
+ ptrdiff_t dst_bytes = max (1, coding->src_chars);
coding->dst_object = Qnil;
- coding->dst_bytes = coding->src_chars;
- if (coding->dst_bytes == 0)
- coding->dst_bytes = 1;
- coding->destination = (unsigned char *) xmalloc (coding->dst_bytes);
+ coding->destination = (unsigned char *) xmalloc (dst_bytes);
+ coding->dst_bytes = dst_bytes;
coding->dst_multibyte = 0;
}
else
@@ -8076,7 +8079,7 @@ detect_coding_system (const unsigned char *src,
Lisp_Object attrs, eol_type;
Lisp_Object val = Qnil;
struct coding_system coding;
- int id;
+ ptrdiff_t id;
struct coding_detection_info detect_info;
enum coding_category base_category;
int null_byte_found = 0, eight_bit_found = 0;
diff --git a/src/coding.h b/src/coding.h
index 85e153dcc3..fdf9b762e7 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -415,7 +415,7 @@ struct coding_system
setup_coding_system. At the early stage of building time, this
value is -1 in the array coding_categories to indicate that no
coding-system of that category is yet defined. */
- int id;
+ ptrdiff_t id;
/* Flag bits of the coding system. The meaning of each bit is common
to all types of coding systems. */
diff --git a/src/composite.c b/src/composite.c
index d402d5ad0c..2a3fbe2955 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -142,10 +142,10 @@ Lisp_Object Qcomposition;
struct composition **composition_table;
/* The current size of `composition_table'. */
-static int composition_table_size;
+static ptrdiff_t composition_table_size;
/* Number of compositions currently made. */
-int n_compositions;
+ptrdiff_t n_compositions;
/* Hash table for compositions. The key is COMPONENTS-VEC of
`composition' property. The value is the corresponding
@@ -172,19 +172,30 @@ Lisp_Object composition_temp;
If the composition is invalid, return -1. */
-int
+ptrdiff_t
get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
Lisp_Object prop, Lisp_Object string)
{
Lisp_Object id, length, components, key, *key_contents;
- int glyph_len;
+ ptrdiff_t glyph_len;
struct Lisp_Hash_Table *hash_table = XHASH_TABLE (composition_hash_table);
- EMACS_INT hash_index;
+ ptrdiff_t hash_index;
EMACS_UINT hash_code;
+ enum composition_method method;
struct composition *cmp;
EMACS_INT i;
int ch;
+ /* Maximum length of a string of glyphs. XftGlyphExtents limits
+ this to INT_MAX, and Emacs limits it further. Divide INT_MAX - 1
+ by 2 because x_produce_glyphs computes glyph_len * 2 + 1. Divide
+ the size by MAX_MULTIBYTE_LENGTH because encode_terminal_code
+ multiplies glyph_len by MAX_MULTIBYTE_LENGTH. */
+ enum {
+ GLYPH_LEN_MAX = min ((INT_MAX - 1) / 2,
+ min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH)
+ };
+
/* PROP should be
Form-A: ((LENGTH . COMPONENTS) . MODIFICATION-FUNC)
or
@@ -258,21 +269,9 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
/* This composition is a new one. We must register it. */
/* Check if we have sufficient memory to store this information. */
- if (composition_table_size == 0)
- {
- composition_table_size = 256;
- composition_table
- = (struct composition **) xmalloc (sizeof (composition_table[0])
- * composition_table_size);
- }
- else if (composition_table_size <= n_compositions)
- {
- composition_table_size += 256;
- composition_table
- = (struct composition **) xrealloc (composition_table,
- sizeof (composition_table[0])
- * composition_table_size);
- }
+ if (composition_table_size <= n_compositions)
+ composition_table = xpalloc (composition_table, &composition_table_size,
+ 1, -1, sizeof *composition_table);
key_contents = XVECTOR (key)->contents;
@@ -316,20 +315,26 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
/* Register the composition in composition_hash_table. */
hash_index = hash_put (hash_table, key, id, hash_code);
+ method = (NILP (components)
+ ? COMPOSITION_RELATIVE
+ : ((INTEGERP (components) || STRINGP (components))
+ ? COMPOSITION_WITH_ALTCHARS
+ : COMPOSITION_WITH_RULE_ALTCHARS));
+
+ glyph_len = (method == COMPOSITION_WITH_RULE_ALTCHARS
+ ? (ASIZE (key) + 1) / 2
+ : ASIZE (key));
+
+ if (GLYPH_LEN_MAX < glyph_len)
+ memory_full (SIZE_MAX);
+
/* Register the composition in composition_table. */
cmp = (struct composition *) xmalloc (sizeof (struct composition));
- cmp->method = (NILP (components)
- ? COMPOSITION_RELATIVE
- : ((INTEGERP (components) || STRINGP (components))
- ? COMPOSITION_WITH_ALTCHARS
- : COMPOSITION_WITH_RULE_ALTCHARS));
+ cmp->method = method;
cmp->hash_index = hash_index;
- glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
- ? (ASIZE (key) + 1) / 2
- : ASIZE (key));
cmp->glyph_len = glyph_len;
- cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2);
+ cmp->offsets = xnmalloc (glyph_len, 2 * sizeof *cmp->offsets);
cmp->font = NULL;
if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
@@ -656,7 +661,7 @@ static Lisp_Object
gstring_lookup_cache (Lisp_Object header)
{
struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
- EMACS_INT i = hash_lookup (h, header, NULL);
+ ptrdiff_t i = hash_lookup (h, header, NULL);
return (i >= 0 ? HASH_VALUE (h, i) : Qnil);
}
@@ -691,7 +696,7 @@ composition_gstring_put_cache (Lisp_Object gstring, EMACS_INT len)
}
Lisp_Object
-composition_gstring_from_id (int id)
+composition_gstring_from_id (ptrdiff_t id)
{
struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
@@ -960,8 +965,6 @@ autocmp_chars (Lisp_Object rule, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT
args[4] = font_object;
args[5] = string;
lgstring = safe_call (6, args);
- if (NILP (string))
- TEMP_SET_PT_BOTH (pt, pt_byte);
}
return unbind_to (count, lgstring);
}
diff --git a/src/composite.h b/src/composite.h
index 8cedfdbe35..c57e2a0e9b 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -170,7 +170,7 @@ extern Lisp_Object composition_temp;
struct composition {
/* Number of glyphs of the composition components. */
- unsigned glyph_len;
+ int glyph_len;
/* Width, ascent, and descent pixels of the composition. */
short pixel_width, ascent, descent;
@@ -193,7 +193,7 @@ struct composition {
void *font;
/* Pointer to an array of x-offset and y-offset (by pixels) of
- glyphs. This points to a sufficient memory space (sizeof (int) *
+ glyphs. This points to a sufficient memory space (sizeof (short) *
glyph_len * 2) that is allocated when the composition is
registered in composition_table. X-offset and Y-offset of Nth
glyph are (2N)th and (2N+1)th elements respectively. */
@@ -204,7 +204,7 @@ struct composition {
COMPOSITION-ID. */
extern struct composition **composition_table;
/* Number of the currently registered compositions. */
-extern int n_compositions;
+extern ptrdiff_t n_compositions;
/* Mask bits for CHECK_MASK arg to update_compositions.
For a change in the region FROM and TO, check compositions ... */
@@ -216,8 +216,8 @@ extern int n_compositions;
extern Lisp_Object Qcomposition;
extern Lisp_Object composition_hash_table;
-extern int get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT,
- Lisp_Object, Lisp_Object);
+extern ptrdiff_t get_composition_id (EMACS_INT, EMACS_INT, EMACS_INT,
+ Lisp_Object, Lisp_Object);
extern int find_composition (EMACS_INT, EMACS_INT, EMACS_INT *, EMACS_INT *,
Lisp_Object *, Lisp_Object);
extern void update_compositions (EMACS_INT, EMACS_INT, int);
@@ -299,7 +299,7 @@ struct face;
struct font_metrics;
extern Lisp_Object composition_gstring_put_cache (Lisp_Object, EMACS_INT);
-extern Lisp_Object composition_gstring_from_id (int);
+extern Lisp_Object composition_gstring_from_id (ptrdiff_t);
extern int composition_gstring_p (Lisp_Object);
extern int composition_gstring_width (Lisp_Object, EMACS_INT, EMACS_INT,
struct font_metrics *);
diff --git a/src/deps.mk b/src/deps.mk
index 080144ae1e..c61b01a95c 100644
--- a/src/deps.mk
+++ b/src/deps.mk
@@ -39,7 +39,7 @@
atimer.o: atimer.c atimer.h syssignal.h systime.h lisp.h blockinput.h \
globals.h ../lib/unistd.h $(config_h)
bidi.o: bidi.c buffer.h character.h dispextern.h msdos.h lisp.h \
- biditype.h bidimirror.h globals.h $(config_h)
+ globals.h $(config_h)
buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
$(INTERVALS_H) blockinput.h atimer.h systime.h character.h ../lib/unistd.h \
indent.h keyboard.h coding.h keymap.h frame.h lisp.h globals.h $(config_h)
diff --git a/src/dispextern.h b/src/dispextern.h
index dc44c69816..831803f58f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -575,7 +575,7 @@ struct glyph_pool
struct glyph *glyphs;
/* Allocated size of `glyphs'. */
- int nglyphs;
+ ptrdiff_t nglyphs;
/* Number of rows and columns in a matrix. */
int nrows, ncolumns;
@@ -625,7 +625,7 @@ struct glyph_matrix
struct glyph_row *rows;
/* Number of elements allocated for the vector rows above. */
- int rows_allocated;
+ ptrdiff_t rows_allocated;
/* The number of rows used by the window if all lines were displayed
with the smallest possible character height. */
@@ -1240,7 +1240,7 @@ struct glyph_string
struct composition *cmp;
/* If not negative, this string describes a compos. */
- int cmp_id;
+ ptrdiff_t cmp_id;
/* Start and end glyph indices in a glyph-string. */
int cmp_from, cmp_to;
@@ -1708,7 +1708,8 @@ struct face_cache
struct face **faces_by_id;
/* The allocated size, and number of used slots of faces_by_id. */
- int size, used;
+ ptrdiff_t size;
+ int used;
/* Flag indicating that attributes of the `menu' face have been
changed. */
@@ -1776,7 +1777,7 @@ extern int face_change_count;
3 bits for it, so we cannot use there values larger than 7.
The order of members must be in sync with the 8th element of the
- member of unidata-prop-alist (in admin/unidata/unidata-getn.el) for
+ member of unidata-prop-alist (in admin/unidata/unidata-gen.el) for
Unicode character property `bidi-class'. */
typedef enum {
UNKNOWN_BT = 0,
@@ -1859,6 +1860,10 @@ struct bidi_it {
EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */
bidi_dir_t sor; /* direction of start-of-run in effect */
int scan_dir; /* direction of text scan, 1: forw, -1: back */
+ EMACS_INT disp_pos; /* position of display string after ch */
+ int disp_prop; /* if non-zero, there really is a
+ `display' property/string at disp_pos;
+ if 2, the property is a `space' spec */
int stack_idx; /* index of current data on the stack */
/* Note: Everything from here on is not copied/saved when the bidi
iterator state is saved, pushed, or popped. So only put here
@@ -1867,7 +1872,6 @@ struct bidi_it {
struct bidi_string_data string; /* string to reorder */
bidi_dir_t paragraph_dir; /* current paragraph direction */
EMACS_INT separator_limit; /* where paragraph separator should end */
- EMACS_INT disp_pos; /* position of display string after ch */
unsigned first_elt : 1; /* if non-zero, examine current char first */
unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */
unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */
@@ -2056,7 +2060,7 @@ struct composition_it
EMACS_INT stop_pos;
/* ID number of the composition or glyph-string. If negative, we
are not iterating over a composition now. */
- int id;
+ ptrdiff_t id;
/* If non-negative, character that triggers the automatic
composition at `stop_pos', and this is an automatic composition.
If negative, this is a static composition. This is set to -2
@@ -2246,7 +2250,7 @@ struct it
struct {
Lisp_Object object;
struct it_slice slice;
- int image_id;
+ ptrdiff_t image_id;
} image;
/* method == GET_FROM_COMPOSITION */
struct {
@@ -2376,7 +2380,7 @@ struct it
enum glyphless_display_method glyphless_method;
/* If what == IT_IMAGE, the id of the image to display. */
- int image_id;
+ ptrdiff_t image_id;
/* Values from `slice' property. */
struct it_slice slice;
@@ -2826,7 +2830,7 @@ struct image
EMACS_UINT hash;
/* Image id of this image. */
- int id;
+ ptrdiff_t id;
/* Hash collision chain. */
struct image *next, *prev;
@@ -2845,13 +2849,13 @@ struct image_cache
struct image **images;
/* Allocated size of `images'. */
- unsigned size;
+ ptrdiff_t size;
/* Number of images in the cache. */
- unsigned used;
+ ptrdiff_t used;
/* Reference count (number of frames sharing this cache). */
- int refcount;
+ ptrdiff_t refcount;
};
@@ -2976,7 +2980,7 @@ extern int bidi_mirror_char (int);
extern void bidi_push_it (struct bidi_it *);
extern void bidi_pop_it (struct bidi_it *);
extern void *bidi_shelve_cache (void);
-extern void bidi_unshelve_cache (void *);
+extern void bidi_unshelve_cache (void *, int);
/* Defined in xdisp.c */
@@ -3035,9 +3039,12 @@ extern Lisp_Object lookup_glyphless_char_display (int, struct it *);
extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object,
struct font *, int, int *);
extern EMACS_INT compute_display_string_pos (struct text_pos *,
- struct bidi_string_data *, int);
+ struct bidi_string_data *,
+ int, int *);
extern EMACS_INT compute_display_string_end (EMACS_INT,
struct bidi_string_data *);
+extern void produce_stretch_glyph (struct it *);
+
#ifdef HAVE_WINDOW_SYSTEM
@@ -3117,7 +3124,7 @@ void w32_reset_fringes (void);
extern int x_bitmap_height (struct frame *, ptrdiff_t);
extern int x_bitmap_width (struct frame *, ptrdiff_t);
extern int x_bitmap_pixmap (struct frame *, ptrdiff_t);
-extern void x_reference_bitmap (struct frame *, int);
+extern void x_reference_bitmap (struct frame *, ptrdiff_t);
extern ptrdiff_t x_create_bitmap_from_data (struct frame *, char *,
unsigned int, unsigned int);
extern ptrdiff_t x_create_bitmap_from_file (struct frame *, Lisp_Object);
@@ -3138,7 +3145,7 @@ void clear_image_caches (Lisp_Object);
void mark_image_cache (struct image_cache *);
int valid_image_p (Lisp_Object);
void prepare_image_for_display (struct frame *, struct image *);
-int lookup_image (struct frame *, Lisp_Object);
+ptrdiff_t lookup_image (struct frame *, Lisp_Object);
unsigned long image_background (struct image *, struct frame *,
XImagePtr_or_DC ximg);
@@ -3199,7 +3206,6 @@ int merge_faces (struct frame *, Lisp_Object, EMACS_INT, int);
int compute_char_face (struct frame *, int, Lisp_Object);
void free_all_realized_faces (Lisp_Object);
extern Lisp_Object Qforeground_color, Qbackground_color;
-extern Lisp_Object Qframe_set_background_mode;
extern char unspecified_fg[], unspecified_bg[];
/* Defined in xfns.c */
@@ -3333,6 +3339,7 @@ extern struct terminal *get_named_tty (const char *);
EXFUN (Ftty_type, 1);
extern void create_tty_output (struct frame *);
extern struct terminal *init_tty (const char *, const char *, int);
+extern void tty_append_glyph (struct it *);
/* Defined in scroll.c */
diff --git a/src/dispnew.c b/src/dispnew.c
index b2f416701c..e96583e002 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -499,12 +499,12 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
/* Enlarge MATRIX->rows if necessary. New rows are cleared. */
if (matrix->rows_allocated < dim.height)
{
- ptrdiff_t size = dim.height * sizeof (struct glyph_row);
+ int old_alloc = matrix->rows_allocated;
new_rows = dim.height - matrix->rows_allocated;
- matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
- memset (matrix->rows + matrix->rows_allocated, 0,
- new_rows * sizeof *matrix->rows);
- matrix->rows_allocated = dim.height;
+ matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
+ new_rows, INT_MAX, sizeof *matrix->rows);
+ memset (matrix->rows + old_alloc, 0,
+ (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
}
else
new_rows = 0;
@@ -576,9 +576,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
while (row < end)
{
row->glyphs[LEFT_MARGIN_AREA]
- = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
- (dim.width
- * sizeof (struct glyph)));
+ = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
+ dim.width, sizeof (struct glyph));
/* The mode line never has marginal areas. */
if (row == matrix->rows + dim.height - 1
@@ -1217,7 +1216,7 @@ line_draw_cost (struct glyph_matrix *matrix, int vpos)
struct glyph *end = beg + row->used[TEXT_AREA];
int len;
Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
- int glyph_table_len = GLYPH_TABLE_LENGTH;
+ ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
/* Ignore trailing and leading spaces if we can. */
if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
@@ -1391,7 +1390,7 @@ free_glyph_pool (struct glyph_pool *pool)
static int
realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
{
- int needed;
+ ptrdiff_t needed;
int changed_p;
changed_p = (pool->glyphs == 0
@@ -1399,24 +1398,17 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
|| matrix_dim.width != pool->ncolumns);
/* Enlarge the glyph pool. */
- needed = matrix_dim.width * matrix_dim.height;
+ needed = matrix_dim.width;
+ if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
+ memory_full (SIZE_MAX);
+ needed *= matrix_dim.height;
if (needed > pool->nglyphs)
{
- ptrdiff_t size = needed * sizeof (struct glyph);
-
- if (pool->glyphs)
- {
- pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
- memset (pool->glyphs + pool->nglyphs, 0,
- size - pool->nglyphs * sizeof (struct glyph));
- }
- else
- {
- pool->glyphs = (struct glyph *) xmalloc (size);
- memset (pool->glyphs, 0, size);
- }
-
- pool->nglyphs = needed;
+ ptrdiff_t old_nglyphs = pool->nglyphs;
+ pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
+ needed - old_nglyphs, -1, sizeof *pool->glyphs);
+ memset (pool->glyphs + old_nglyphs, 0,
+ (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
}
/* Remember the number of rows and columns because (a) we use them
@@ -4166,7 +4158,7 @@ struct row_entry
int new_line_number;
/* Bucket index of this row_entry in the hash table row_table. */
- int bucket;
+ ptrdiff_t bucket;
/* The row described by this entry. */
struct glyph_row *row;
@@ -4180,29 +4172,29 @@ struct row_entry
that we need a larger one. */
static struct row_entry *row_entry_pool;
-static int row_entry_pool_size;
+static ptrdiff_t row_entry_pool_size;
/* Index of next free entry in row_entry_pool. */
-static int row_entry_idx;
+static ptrdiff_t row_entry_idx;
/* The hash table used during scrolling, and the table's size. This
table is used to quickly identify equal rows in the desired and
current matrix. */
static struct row_entry **row_table;
-static int row_table_size;
+static ptrdiff_t row_table_size;
/* Vectors of pointers to row_entry structures belonging to the
current and desired matrix, and the size of the vectors. */
static struct row_entry **old_lines, **new_lines;
-static int old_lines_size, new_lines_size;
+static ptrdiff_t old_lines_size, new_lines_size;
/* A pool to allocate run structures from, and its size. */
static struct run *run_pool;
-static int runs_size;
+static ptrdiff_t runs_size;
/* A vector of runs of lines found during scrolling. */
@@ -4214,7 +4206,7 @@ static inline struct row_entry *
add_row_entry (struct glyph_row *row)
{
struct row_entry *entry;
- int i = row->hash % row_table_size;
+ ptrdiff_t i = row->hash % row_table_size;
entry = row_table[i];
while (entry && !row_equal_p (entry->row, row, 1))
@@ -4267,9 +4259,10 @@ scrolling_window (struct window *w, int header_line_p)
struct glyph_matrix *desired_matrix = w->desired_matrix;
struct glyph_matrix *current_matrix = w->current_matrix;
int yb = window_text_bottom_y (w);
- int i, j, first_old, first_new, last_old, last_new;
- int nruns, n, run_idx;
- ptrdiff_t nbytes;
+ ptrdiff_t i;
+ int j, first_old, first_new, last_old, last_new;
+ int nruns, run_idx;
+ ptrdiff_t n;
struct row_entry *entry;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
@@ -4354,45 +4347,59 @@ scrolling_window (struct window *w, int header_line_p)
if (last_new == first_new)
return 0;
+ /* Check for integer overflow in size calculation.
+
+ If next_almost_prime checks (N) for divisibility by 2..10, then
+ it can return at most N + 10, e.g., next_almost_prime (1) == 11.
+ So, set next_almost_prime_increment_max to 10.
+
+ It's just a coincidence that next_almost_prime_increment_max ==
+ NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were
+ 13, then next_almost_prime_increment_max would be 14, e.g.,
+ because next_almost_prime (113) would be 127. */
+ {
+ verify (NEXT_ALMOST_PRIME_LIMIT == 11);
+ enum { next_almost_prime_increment_max = 10 };
+ ptrdiff_t row_table_max =
+ (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
+ - next_almost_prime_increment_max);
+ ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
+ if (current_nrows_max < current_matrix->nrows)
+ memory_full (SIZE_MAX);
+ }
+
/* Reallocate vectors, tables etc. if necessary. */
if (current_matrix->nrows > old_lines_size)
- {
- old_lines_size = current_matrix->nrows;
- nbytes = old_lines_size * sizeof *old_lines;
- old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
- }
+ old_lines = xpalloc (old_lines, &old_lines_size,
+ current_matrix->nrows - old_lines_size,
+ INT_MAX, sizeof *old_lines);
if (desired_matrix->nrows > new_lines_size)
- {
- new_lines_size = desired_matrix->nrows;
- nbytes = new_lines_size * sizeof *new_lines;
- new_lines = (struct row_entry **) xrealloc (new_lines, nbytes);
- }
+ new_lines = xpalloc (new_lines, &new_lines_size,
+ desired_matrix->nrows - new_lines_size,
+ INT_MAX, sizeof *new_lines);
- n = desired_matrix->nrows + current_matrix->nrows;
- if (3 * n > row_table_size)
+ n = desired_matrix->nrows;
+ n += current_matrix->nrows;
+ if (row_table_size < 3 * n)
{
- row_table_size = next_almost_prime (3 * n);
- nbytes = row_table_size * sizeof *row_table;
- row_table = (struct row_entry **) xrealloc (row_table, nbytes);
- memset (row_table, 0, nbytes);
+ ptrdiff_t size = next_almost_prime (3 * n);
+ row_table = xnrealloc (row_table, size, sizeof *row_table);
+ row_table_size = size;
+ memset (row_table, 0, size * sizeof *row_table);
}
if (n > row_entry_pool_size)
- {
- row_entry_pool_size = n;
- nbytes = row_entry_pool_size * sizeof *row_entry_pool;
- row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes);
- }
+ row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
+ n - row_entry_pool_size,
+ -1, sizeof *row_entry_pool);
if (desired_matrix->nrows > runs_size)
{
+ runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
+ run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
runs_size = desired_matrix->nrows;
- nbytes = runs_size * sizeof *runs;
- runs = (struct run **) xrealloc (runs, nbytes);
- nbytes = runs_size * sizeof *run_pool;
- run_pool = (struct run *) xrealloc (run_pool, nbytes);
}
nruns = run_idx = 0;
@@ -5282,7 +5289,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
argument is ZV to prevent move_it_in_display_line from matching
based on buffer positions. */
move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
Fset_buffer (old_current_buffer);
@@ -5307,7 +5314,8 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
if (STRINGP (it.string))
BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
else
- BYTEPOS (pos->pos) = CHAR_TO_BYTE (CHARPOS (pos->pos));
+ BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer),
+ CHARPOS (pos->pos));
}
#ifdef HAVE_WINDOW_SYSTEM
diff --git a/src/doc.c b/src/doc.c
index 69646f5af5..83e943c42b 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -39,7 +39,7 @@ Lisp_Object Qfunction_documentation;
extern Lisp_Object Qclosure;
/* Buffer used for reading from documentation file. */
static char *get_doc_string_buffer;
-static int get_doc_string_buffer_size;
+static ptrdiff_t get_doc_string_buffer_size;
static unsigned char *read_bytecode_pointer;
static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object,
@@ -166,20 +166,19 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition)
p = get_doc_string_buffer;
while (1)
{
- EMACS_INT space_left = (get_doc_string_buffer_size
+ ptrdiff_t space_left = (get_doc_string_buffer_size - 1
- (p - get_doc_string_buffer));
int nread;
/* Allocate or grow the buffer if we need to. */
- if (space_left == 0)
+ if (space_left <= 0)
{
- EMACS_INT in_buffer = p - get_doc_string_buffer;
- get_doc_string_buffer_size += 16 * 1024;
- get_doc_string_buffer
- = (char *) xrealloc (get_doc_string_buffer,
- get_doc_string_buffer_size + 1);
+ ptrdiff_t in_buffer = p - get_doc_string_buffer;
+ get_doc_string_buffer =
+ xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
+ 16 * 1024, -1, 1);
p = get_doc_string_buffer + in_buffer;
- space_left = (get_doc_string_buffer_size
+ space_left = (get_doc_string_buffer_size - 1
- (p - get_doc_string_buffer));
}
@@ -713,16 +712,16 @@ a new string, without any text properties, is returned. */)
int changed = 0;
register unsigned char *strp;
register char *bufp;
- EMACS_INT idx;
- EMACS_INT bsize;
+ ptrdiff_t idx;
+ ptrdiff_t bsize;
Lisp_Object tem;
Lisp_Object keymap;
unsigned char *start;
- EMACS_INT length, length_byte;
+ ptrdiff_t length, length_byte;
Lisp_Object name;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int multibyte;
- EMACS_INT nchars;
+ ptrdiff_t nchars;
if (NILP (string))
return Qnil;
@@ -774,7 +773,7 @@ a new string, without any text properties, is returned. */)
}
else if (strp[0] == '\\' && strp[1] == '[')
{
- EMACS_INT start_idx;
+ ptrdiff_t start_idx;
int follow_remap = 1;
changed = 1;
@@ -813,7 +812,9 @@ a new string, without any text properties, is returned. */)
if (NILP (tem)) /* but not on any keys */
{
- EMACS_INT offset = bufp - buf;
+ ptrdiff_t offset = bufp - buf;
+ if (STRING_BYTES_BOUND - 4 < bsize)
+ string_overflow ();
buf = (char *) xrealloc (buf, bsize += 4);
bufp = buf + offset;
memcpy (bufp, "M-x ", 4);
@@ -836,7 +837,7 @@ a new string, without any text properties, is returned. */)
else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<'))
{
struct buffer *oldbuf;
- EMACS_INT start_idx;
+ ptrdiff_t start_idx;
/* This is for computing the SHADOWS arg for describe_map_tree. */
Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil);
Lisp_Object earlier_maps;
@@ -907,7 +908,9 @@ a new string, without any text properties, is returned. */)
length_byte = SBYTES (tem);
subst:
{
- EMACS_INT offset = bufp - buf;
+ ptrdiff_t offset = bufp - buf;
+ if (STRING_BYTES_BOUND - length_byte < bsize)
+ string_overflow ();
buf = (char *) xrealloc (buf, bsize += length_byte);
bufp = buf + offset;
memcpy (bufp, start, length_byte);
diff --git a/src/editfns.c b/src/editfns.c
index 577263c5ae..6759016766 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1695,7 +1695,9 @@ The modifiers are `E' and `O'. For certain characters X,
%EX is a locale's alternative version of %X;
%OX is like %X, but uses the locale's number symbols.
-For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
+For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
+
+usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
(Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
{
time_t value;
@@ -2051,7 +2053,12 @@ static char *initial_tz;
DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
If TZ is nil, use implementation-defined default time zone information.
-If TZ is t, use Universal Time. */)
+If TZ is t, use Universal Time.
+
+Instead of calling this function, you typically want (setenv "TZ" TZ).
+That changes both the environment of the Emacs process and the
+variable `process-environment', whereas `set-time-zone-rule' affects
+only the former. */)
(Lisp_Object tz)
{
const char *tzstring;
@@ -2100,7 +2107,7 @@ static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
void
set_time_zone_rule (const char *tzstring)
{
- int envptrs;
+ ptrdiff_t envptrs;
char **from, **to, **newenv;
/* Make the ENVIRON vector longer with room for TZSTRING. */
@@ -3350,7 +3357,7 @@ usage: (save-restriction &rest BODY) */)
static char *message_text;
/* Allocated length of that buffer. */
-static int message_length;
+static ptrdiff_t message_length;
DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
doc: /* Display a message at the bottom of the screen.
@@ -3432,8 +3439,8 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
}
if (SBYTES (val) > message_length)
{
+ message_text = (char *) xrealloc (message_text, SBYTES (val));
message_length = SBYTES (val);
- message_text = (char *)xrealloc (message_text, message_length);
}
memcpy (message_text, SDATA (val), SBYTES (val));
message2 (message_text, SBYTES (val),
@@ -3882,7 +3889,7 @@ usage: (format STRING &rest OBJECTS) */)
: -1)),
/* Maximum number of bytes generated by any format, if
- precision is no more than DBL_USEFUL_PRECISION_MAX.
+ precision is no more than USEFUL_PRECISION_MAX.
On all practical hosts, %f is the worst case. */
SPRINTF_BUFSIZE =
sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX,
@@ -4158,7 +4165,7 @@ usage: (format STRING &rest OBJECTS) */)
character. CONVBYTES says how much room is needed. Allocate
enough room (and then some) and do it again. */
{
- EMACS_INT used = p - buf;
+ ptrdiff_t used = p - buf;
if (max_bufsize - used < convbytes)
string_overflow ();
diff --git a/src/emacs.c b/src/emacs.c
index 39870ec007..4cc476290c 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -82,6 +82,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/personality.h>
#endif
+#ifdef HAVE_LIBXML2
+#include <libxml/parser.h>
+#endif
+
#ifndef O_RDWR
#define O_RDWR 2
#endif
@@ -1120,7 +1124,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#if defined (USG5) && defined (INTERRUPT_INPUT)
setpgrp ();
#endif
-#if defined (HAVE_GTK_AND_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
+#if defined (HAVE_PTHREAD) && !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
{
extern void malloc_enable_thread (void);
@@ -1358,24 +1362,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
/* If we have the form --display=NAME,
convert it into -d name.
This requires inserting a new element into argv. */
- if (displayname != 0 && skip_args - count_before == 1)
+ if (displayname && count_before < skip_args)
{
- char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
- int j;
-
- for (j = 0; j < count_before + 1; j++)
- new[j] = argv[j];
- new[count_before + 1] = (char *) "-d";
- new[count_before + 2] = displayname;
- for (j = count_before + 2; j <argc; j++)
- new[j + 1] = argv[j];
- argv = new;
- argc++;
+ if (skip_args == count_before + 1)
+ {
+ memmove (argv + count_before + 3, argv + count_before + 2,
+ (argc - (count_before + 2)) * sizeof *argv);
+ argv[count_before + 2] = displayname;
+ argc++;
+ }
+ argv[count_before + 1] = (char *) "-d";
}
- /* Change --display to -d, when its arg is separate. */
- else if (displayname != 0 && skip_args > count_before
- && argv[count_before + 1][1] == '-')
- argv[count_before + 1] = (char *) "-d";
if (! no_site_lisp)
{
@@ -1838,8 +1835,8 @@ sort_args (int argc, char **argv)
0 for an option that takes no arguments,
1 for an option that takes one argument, etc.
-1 for an ordinary non-option argument. */
- int *options = (int *) xmalloc (sizeof (int) * argc);
- int *priority = (int *) xmalloc (sizeof (int) * argc);
+ int *options = xnmalloc (argc, sizeof *options);
+ int *priority = xnmalloc (argc, sizeof *priority);
int to = 1;
int incoming_used = 1;
int from;
@@ -2104,6 +2101,10 @@ shut_down_emacs (int sig, int no_x, Lisp_Object stuff)
#ifdef HAVE_NS
ns_term_shutdown (sig);
#endif
+
+#ifdef HAVE_LIBXML2
+ xmlCleanupParser ();
+#endif
}
@@ -2185,7 +2186,7 @@ You must run Emacs in batch mode in order to dump it. */)
memory_warnings (my_edata, malloc_warning);
}
#endif /* not WINDOWSNT */
-#if defined (HAVE_GTK_AND_PTHREAD) && !defined SYNC_INPUT
+#if defined (HAVE_PTHREAD) && !defined SYNC_INPUT
/* Pthread may call malloc before main, and then we will get an endless
loop, because pthread_self (see alloc.c) calls malloc the first time
it is called on some systems. */
diff --git a/src/eval.c b/src/eval.c
index ef169e80e2..e722b53fb7 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -133,8 +133,9 @@ static Lisp_Object Ffetch_bytecode (Lisp_Object);
void
init_eval_once (void)
{
- specpdl_size = 50;
- specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding));
+ enum { size = 50 };
+ specpdl = (struct specbinding *) xmalloc (size * sizeof (struct specbinding));
+ specpdl_size = size;
specpdl_ptr = specpdl;
/* Don't forget to update docs (lispref node "Local Variables"). */
max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */
@@ -192,7 +193,7 @@ call_debugger (Lisp_Object arg)
if (lisp_eval_depth + 40 > max_lisp_eval_depth)
max_lisp_eval_depth = lisp_eval_depth + 40;
- if (SPECPDL_INDEX () + 100 > max_specpdl_size)
+ if (max_specpdl_size - 100 < SPECPDL_INDEX ())
max_specpdl_size = SPECPDL_INDEX () + 100;
#ifdef HAVE_WINDOW_SYSTEM
@@ -1357,8 +1358,12 @@ A handler is applicable to an error
if CONDITION-NAME is one of the error's condition names.
If an error happens, the first applicable handler is run.
-The car of a handler may be a list of condition names
-instead of a single condition name. Then it handles all of them.
+The car of a handler may be a list of condition names instead of a
+single condition name; then it handles all of them. If the special
+condition name `debug' is present in this list, it allows another
+condition in the list to run the debugger if `debug-on-error' and the
+other usual mechanisms says it should (otherwise, `condition-case'
+suppresses the debugger).
When a handler handles an error, control returns to the `condition-case'
and it executes the handler's BODY...
@@ -1461,13 +1466,6 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers,
struct catchtag c;
struct handler h;
- /* Since Fsignal will close off all calls to x_catch_errors,
- we will get the wrong results if some are not closed now. */
-#if HAVE_X_WINDOWS
- if (x_catching_errors ())
- abort ();
-#endif
-
c.tag = Qnil;
c.val = Qnil;
c.backlist = backtrace_list;
@@ -1506,13 +1504,6 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg,
struct catchtag c;
struct handler h;
- /* Since Fsignal will close off all calls to x_catch_errors,
- we will get the wrong results if some are not closed now. */
-#if HAVE_X_WINDOWS
- if (x_catching_errors ())
- abort ();
-#endif
-
c.tag = Qnil;
c.val = Qnil;
c.backlist = backtrace_list;
@@ -1555,13 +1546,6 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object),
struct catchtag c;
struct handler h;
- /* Since Fsignal will close off all calls to x_catch_errors,
- we will get the wrong results if some are not closed now. */
-#if HAVE_X_WINDOWS
- if (x_catching_errors ())
- abort ();
-#endif
-
c.tag = Qnil;
c.val = Qnil;
c.backlist = backtrace_list;
@@ -1604,13 +1588,6 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
struct catchtag c;
struct handler h;
- /* Since Fsignal will close off all calls to x_catch_errors,
- we will get the wrong results if some are not closed now. */
-#if HAVE_X_WINDOWS
- if (x_catching_errors ())
- abort ();
-#endif
-
c.tag = Qnil;
c.val = Qnil;
c.backlist = backtrace_list;
@@ -1727,6 +1704,10 @@ See also the function `condition-case'. */)
&& (!NILP (Vdebug_on_signal)
/* If no handler is present now, try to run the debugger. */
|| NILP (clause)
+ /* A `debug' symbol in the handler list disables the normal
+ suppression of the debugger. */
+ || (CONSP (clause) && CONSP (XCAR (clause))
+ && !NILP (Fmemq (Qdebug, XCAR (clause))))
/* Special handler that means "print a message and run debugger
if requested". */
|| EQ (h->handler, Qerror)))
@@ -3274,17 +3255,21 @@ static void
grow_specpdl (void)
{
register int count = SPECPDL_INDEX ();
- if (specpdl_size >= max_specpdl_size)
+ int max_size =
+ min (max_specpdl_size,
+ min (max (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct specbinding),
+ INT_MAX));
+ int size;
+ if (max_size <= specpdl_size)
{
if (max_specpdl_size < 400)
- max_specpdl_size = 400;
- if (specpdl_size >= max_specpdl_size)
+ max_size = max_specpdl_size = 400;
+ if (max_size <= specpdl_size)
signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
}
- specpdl_size *= 2;
- if (specpdl_size > max_specpdl_size)
- specpdl_size = max_specpdl_size;
- specpdl = (struct specbinding *) xrealloc (specpdl, specpdl_size * sizeof (struct specbinding));
+ size = specpdl_size < max_size / 2 ? 2 * specpdl_size : max_size;
+ specpdl = xnrealloc (specpdl, size, sizeof *specpdl);
+ specpdl_size = size;
specpdl_ptr = specpdl + count;
}
diff --git a/src/fileio.c b/src/fileio.c
index 6171368935..60ee35bb39 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2912,7 +2912,7 @@ symbolic notation, like the `chmod' command from GNU Coreutils. */)
encoded_absname = ENCODE_FILE (absname);
- if (chmod (SSDATA (encoded_absname), XINT (mode)) < 0)
+ if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0)
report_file_error ("Doing chmod", Fcons (absname, Qnil));
return Qnil;
@@ -5114,11 +5114,11 @@ auto_save_1 (void)
{
if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0)
/* But make sure we can overwrite it later! */
- auto_save_mode_bits = st.st_mode | 0600;
+ auto_save_mode_bits = (st.st_mode | 0600) & 0777;
else if ((modes = Ffile_modes (BVAR (current_buffer, filename)),
INTEGERP (modes)))
/* Remote files don't cooperate with stat. */
- auto_save_mode_bits = XINT (modes) | 0600;
+ auto_save_mode_bits = (XINT (modes) | 0600) & 0777;
}
return
diff --git a/src/fns.c b/src/fns.c
index 9c9d19fe26..a3af6b8c15 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -602,7 +602,7 @@ concat (ptrdiff_t nargs, Lisp_Object *args,
prev = Qnil;
if (STRINGP (val))
- SAFE_ALLOCA (textprops, struct textprop_rec *, sizeof (struct textprop_rec) * nargs);
+ SAFE_NALLOCA (textprops, 1, nargs);
for (argnum = 0; argnum < nargs; argnum++)
{
@@ -3395,11 +3395,13 @@ check_hash_table (Lisp_Object obj)
/* Value is the next integer I >= N, N >= 0 which is "almost" a prime
- number. */
+ number. A number is "almost" a prime number if it is not divisible
+ by any integer in the range 2 .. (NEXT_ALMOST_PRIME_LIMIT - 1). */
EMACS_INT
next_almost_prime (EMACS_INT n)
{
+ verify (NEXT_ALMOST_PRIME_LIMIT == 11);
for (n |= 1; ; n += 2)
if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0)
return n;
@@ -3787,11 +3789,11 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
the hash code of KEY. Value is the index of the entry in H
matching KEY, or -1 if not found. */
-EMACS_INT
+ptrdiff_t
hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
{
EMACS_UINT hash_code;
- EMACS_INT start_of_bucket;
+ ptrdiff_t start_of_bucket;
Lisp_Object idx;
hash_code = h->hashfn (h, key);
@@ -3821,11 +3823,11 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
HASH is a previously computed hash code of KEY.
Value is the index of the entry in H matching KEY. */
-EMACS_INT
+ptrdiff_t
hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
EMACS_UINT hash)
{
- EMACS_INT start_of_bucket, i;
+ ptrdiff_t start_of_bucket, i;
xassert ((hash & ~INTMASK) == 0);
@@ -4482,7 +4484,7 @@ If KEY is not found, return DFLT which defaults to nil. */)
(Lisp_Object key, Lisp_Object table, Lisp_Object dflt)
{
struct Lisp_Hash_Table *h = check_hash_table (table);
- EMACS_INT i = hash_lookup (h, key, NULL);
+ ptrdiff_t i = hash_lookup (h, key, NULL);
return i >= 0 ? HASH_VALUE (h, i) : dflt;
}
@@ -4494,7 +4496,7 @@ VALUE. In any case, return VALUE. */)
(Lisp_Object key, Lisp_Object value, Lisp_Object table)
{
struct Lisp_Hash_Table *h = check_hash_table (table);
- EMACS_INT i;
+ ptrdiff_t i;
EMACS_UINT hash;
i = hash_lookup (h, key, &hash);
diff --git a/src/fontset.c b/src/fontset.c
index 3091f43d6e..c8ae1e7484 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -447,7 +447,7 @@ reorder_font_vector (Lisp_Object font_group, struct font *font)
/* Return a font-group (actually a cons (-1 . FONT-GROUP-VECTOR)) for
character C in FONTSET. If C is -1, return a fallback font-group.
If C is not -1, the value may be Qt (FONTSET doesn't have a font
- for C even in the fallback group, or 0 (a font for C may be found
+ for C even in the fallback group), or 0 (a font for C may be found
only in the fallback group). */
static Lisp_Object
@@ -465,7 +465,9 @@ fontset_get_font_group (Lisp_Object fontset, int c)
if (! NILP (font_group))
return font_group;
base_fontset = FONTSET_BASE (fontset);
- if (c >= 0)
+ if (NILP (base_fontset))
+ font_group = Qnil;
+ else if (c >= 0)
font_group = char_table_ref_and_range (base_fontset, c, &from, &to);
else
font_group = FONTSET_FALLBACK (base_fontset);
@@ -476,6 +478,8 @@ fontset_get_font_group (Lisp_Object fontset, int c)
char_table_set_range (fontset, from, to, font_group);
return font_group;
}
+ if (!VECTORP (font_group))
+ return font_group;
font_group = Fcopy_sequence (font_group);
for (i = 0; i < ASIZE (font_group); i++)
if (! NILP (AREF (font_group, i)))
@@ -2100,6 +2104,8 @@ DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
#ifdef FONTSET_DEBUG
+Lisp_Object dump_fontset (Lisp_Object) EXTERNALLY_VISIBLE;
+
Lisp_Object
dump_fontset (Lisp_Object fontset)
{
diff --git a/src/frame.c b/src/frame.c
index 19ce78dfd9..711109a70c 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -160,7 +160,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
if (FRAME_MINIBUF_ONLY_P (f))
return;
- if (INTEGERP (value))
+ if (TYPE_RANGED_INTEGERP (int, value))
nlines = XINT (value);
else
nlines = 0;
@@ -2992,7 +2992,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
f->size_hint_flags &= ~ (XNegative | YNegative);
if (EQ (left, Qminus))
f->size_hint_flags |= XNegative;
- else if (INTEGERP (left))
+ else if (TYPE_RANGED_INTEGERP (int, left))
{
leftpos = XINT (left);
if (leftpos < 0)
@@ -3000,21 +3000,21 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
}
else if (CONSP (left) && EQ (XCAR (left), Qminus)
&& CONSP (XCDR (left))
- && INTEGERP (XCAR (XCDR (left))))
+ && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
{
leftpos = - XINT (XCAR (XCDR (left)));
f->size_hint_flags |= XNegative;
}
else if (CONSP (left) && EQ (XCAR (left), Qplus)
&& CONSP (XCDR (left))
- && INTEGERP (XCAR (XCDR (left))))
+ && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
{
leftpos = XINT (XCAR (XCDR (left)));
}
if (EQ (top, Qminus))
f->size_hint_flags |= YNegative;
- else if (INTEGERP (top))
+ else if (TYPE_RANGED_INTEGERP (int, top))
{
toppos = XINT (top);
if (toppos < 0)
@@ -3022,14 +3022,14 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
}
else if (CONSP (top) && EQ (XCAR (top), Qminus)
&& CONSP (XCDR (top))
- && INTEGERP (XCAR (XCDR (top))))
+ && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
{
toppos = - XINT (XCAR (XCDR (top)));
f->size_hint_flags |= YNegative;
}
else if (CONSP (top) && EQ (XCAR (top), Qplus)
&& CONSP (XCDR (top))
- && INTEGERP (XCAR (XCDR (top))))
+ && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
{
toppos = XINT (XCAR (XCDR (top)));
}
@@ -3481,7 +3481,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
do_pending_window_change (0);
}
- else if (INTEGERP (arg) && XINT (arg) > 0
+ else if (RANGED_INTEGERP (1, arg, INT_MAX)
&& XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
{
if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
@@ -3520,7 +3520,7 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
double alpha = 1.0;
double newval[2];
- int i, ialpha;
+ int i;
Lisp_Object item;
for (i = 0; i < 2; i++)
@@ -3544,7 +3544,7 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
}
else if (INTEGERP (item))
{
- ialpha = XINT (item);
+ EMACS_INT ialpha = XINT (item);
if (ialpha < 0 || 100 < ialpha)
args_out_of_range (make_number (0), make_number (100));
else
@@ -4031,11 +4031,15 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
if (!EQ (tem0, Qunbound))
{
CHECK_NUMBER (tem0);
+ if (! (0 <= XINT (tem0) && XINT (tem0) <= INT_MAX))
+ xsignal1 (Qargs_out_of_range, tem0);
FRAME_LINES (f) = XINT (tem0);
}
if (!EQ (tem1, Qunbound))
{
CHECK_NUMBER (tem1);
+ if (! (0 <= XINT (tem1) && XINT (tem1) <= INT_MAX))
+ xsignal1 (Qargs_out_of_range, tem1);
SET_FRAME_COLS (f, XINT (tem1));
}
if (!NILP (tem2) && !EQ (tem2, Qunbound))
@@ -4066,12 +4070,10 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
- if (INTEGERP (Vtool_bar_button_margin)
- && XINT (Vtool_bar_button_margin) > 0)
+ if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX))
margin = XFASTINT (Vtool_bar_button_margin);
else if (CONSP (Vtool_bar_button_margin)
- && INTEGERP (XCDR (Vtool_bar_button_margin))
- && XINT (XCDR (Vtool_bar_button_margin)) > 0)
+ && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX))
margin = XFASTINT (XCDR (Vtool_bar_button_margin));
else
margin = 0;
@@ -4097,14 +4099,14 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
}
else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
&& CONSP (XCDR (tem0))
- && INTEGERP (XCAR (XCDR (tem0))))
+ && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem0)), INT_MAX))
{
f->top_pos = - XINT (XCAR (XCDR (tem0)));
window_prompting |= YNegative;
}
else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
&& CONSP (XCDR (tem0))
- && INTEGERP (XCAR (XCDR (tem0))))
+ && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem0))))
{
f->top_pos = XINT (XCAR (XCDR (tem0)));
}
@@ -4125,14 +4127,14 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
}
else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
&& CONSP (XCDR (tem1))
- && INTEGERP (XCAR (XCDR (tem1))))
+ && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem1)), INT_MAX))
{
f->left_pos = - XINT (XCAR (XCDR (tem1)));
window_prompting |= XNegative;
}
else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
&& CONSP (XCDR (tem1))
- && INTEGERP (XCAR (XCDR (tem1))))
+ && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem1))))
{
f->left_pos = XINT (XCAR (XCDR (tem1)));
}
diff --git a/src/frame.h b/src/frame.h
index 8dccfb8540..3775403810 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -258,11 +258,11 @@ struct frame
/* Size of this frame, excluding fringes, scroll bars etc.,
in units of canonical characters. */
- EMACS_INT text_lines, text_cols;
+ int text_lines, text_cols;
/* Total size of this frame (i.e. its native window), in units of
canonical characters. */
- EMACS_INT total_lines, total_cols;
+ int total_lines, total_cols;
/* New text height and width for pending size change.
0 if no change pending. */
diff --git a/src/fringe.c b/src/fringe.c
index a4dc9433af..5878c54124 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1610,22 +1610,25 @@ If BITMAP already exists, the existing definition is replaced. */)
if (n == max_fringe_bitmaps)
{
- if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
+ int bitmaps = max_fringe_bitmaps + 20;
+ if (MAX_FRINGE_BITMAPS < bitmaps)
error ("No free fringe bitmap slots");
i = max_fringe_bitmaps;
- max_fringe_bitmaps += 20;
fringe_bitmaps
= ((struct fringe_bitmap **)
- xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
+ xrealloc (fringe_bitmaps, bitmaps * sizeof *fringe_bitmaps));
fringe_faces
- = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
+ = (Lisp_Object *) xrealloc (fringe_faces,
+ bitmaps * sizeof *fringe_faces);
- for (; i < max_fringe_bitmaps; i++)
+ for (i = max_fringe_bitmaps; i < bitmaps; i++)
{
fringe_bitmaps[i] = NULL;
fringe_faces[i] = Qnil;
}
+
+ max_fringe_bitmaps = bitmaps;
}
}
diff --git a/src/ftfont.c b/src/ftfont.c
index 4e313a8902..7858a31be2 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -214,6 +214,10 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra)
for (i = 0; i < FONT_OBJLIST_INDEX; i++)
ASET (val, i, AREF (entity, i));
+
+ ASET (val, FONT_EXTRA_INDEX, Fcopy_sequence (extra));
+ font_put_extra (val, QCfont_entity, key);
+
return val;
}
entity = font_make_entity ();
@@ -682,7 +686,10 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec)
if (NILP (val))
continue;
len = Flength (val);
- spec->features[i] = malloc (sizeof (int) * XINT (len));
+ spec->features[i] =
+ (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len)
+ ? 0
+ : malloc (sizeof (int) * XINT (len)));
if (! spec->features[i])
{
if (i > 0 && spec->features[0])
@@ -1761,15 +1768,10 @@ static OTF_GlyphString otf_gstring;
static void
setup_otf_gstring (int size)
{
- if (otf_gstring.size == 0)
- {
- otf_gstring.glyphs = (OTF_Glyph *) xmalloc (sizeof (OTF_Glyph) * size);
- otf_gstring.size = size;
- }
- else if (otf_gstring.size < size)
+ if (otf_gstring.size < size)
{
- otf_gstring.glyphs = xrealloc (otf_gstring.glyphs,
- sizeof (OTF_Glyph) * size);
+ otf_gstring.glyphs = xnrealloc (otf_gstring.glyphs,
+ size, sizeof (OTF_Glyph));
otf_gstring.size = size;
}
otf_gstring.used = size;
@@ -2445,17 +2447,19 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
}
}
+ if (INT_MAX / 2 < len)
+ memory_full (SIZE_MAX);
+
if (gstring.allocated == 0)
{
- gstring.allocated = len * 2;
gstring.glyph_size = sizeof (MFLTGlyph);
- gstring.glyphs = xmalloc (sizeof (MFLTGlyph) * gstring.allocated);
+ gstring.glyphs = xnmalloc (len * 2, sizeof (MFLTGlyph));
+ gstring.allocated = len * 2;
}
else if (gstring.allocated < len * 2)
{
+ gstring.glyphs = xnrealloc (gstring.glyphs, len * 2, sizeof (MFLTGlyph));
gstring.allocated = len * 2;
- gstring.glyphs = xrealloc (gstring.glyphs,
- sizeof (MFLTGlyph) * gstring.allocated);
}
memset (gstring.glyphs, 0, sizeof (MFLTGlyph) * len);
for (i = 0; i < len; i++)
@@ -2504,9 +2508,11 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt);
if (result != -2)
break;
- gstring.allocated += gstring.allocated;
- gstring.glyphs = xrealloc (gstring.glyphs,
- sizeof (MFLTGlyph) * gstring.allocated);
+ if (INT_MAX / 2 < gstring.allocated)
+ memory_full (SIZE_MAX);
+ gstring.glyphs = xnrealloc (gstring.glyphs,
+ gstring.allocated, 2 * sizeof (MFLTGlyph));
+ gstring.allocated *= 2;
}
if (gstring.used > LGSTRING_GLYPH_LEN (lgstring))
return Qnil;
diff --git a/src/gmalloc.c b/src/gmalloc.c
index fa4aa1fdf6..d49259b8ed 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -37,7 +37,7 @@ Fifth Floor, Boston, MA 02110-1301, USA.
#include <config.h>
#endif
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
#define USE_PTHREAD
#endif
@@ -351,10 +351,21 @@ Fifth Floor, Boston, MA 02110-1301, USA.
#endif
#include <errno.h>
-/* How to really get more memory. */
-#if defined(CYGWIN)
+/* On Cygwin there are two heaps. temacs uses the static heap
+ (defined in sheap.c and managed with bss_sbrk), and the dumped
+ emacs uses the Cygwin heap (managed with sbrk). When emacs starts
+ on Cygwin, it reinitializes malloc, and we save the old info for
+ use by free and realloc if they're called with a pointer into the
+ static heap.
+
+ Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if
+ this is changed in the future, we'll have to similarly deal with
+ reinitializing ralloc. */
+#ifdef CYGWIN
extern __ptr_t bss_sbrk PP ((ptrdiff_t __size));
extern int bss_sbrk_did_unexec;
+char *bss_sbrk_heapbase; /* _heapbase for static heap */
+malloc_info *bss_sbrk_heapinfo; /* _heapinfo for static heap */
#endif
__ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore;
@@ -584,6 +595,16 @@ malloc_initialize_1 ()
mcheck (NULL);
#endif
+#ifdef CYGWIN
+ if (bss_sbrk_did_unexec)
+ /* we're reinitializing the dumped emacs */
+ {
+ bss_sbrk_heapbase = _heapbase;
+ bss_sbrk_heapinfo = _heapinfo;
+ memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
+ }
+#endif
+
if (__malloc_initialize_hook)
(*__malloc_initialize_hook) ();
@@ -1054,6 +1075,12 @@ _free_internal_nolock (ptr)
if (ptr == NULL)
return;
+#ifdef CYGWIN
+ if (ptr < _heapbase)
+ /* We're being asked to free something in the static heap. */
+ return;
+#endif
+
PROTECT_MALLOC_STATE (0);
LOCK_ALIGNED_BLOCKS ();
@@ -1349,6 +1376,31 @@ Fifth Floor, Boston, MA 02110-1301, USA.
#define min(A, B) ((A) < (B) ? (A) : (B))
+/* On Cygwin the dumped emacs may try to realloc storage allocated in
+ the static heap. We just malloc space in the new heap and copy the
+ data. */
+#ifdef CYGWIN
+__ptr_t
+special_realloc (ptr, size)
+ __ptr_t ptr;
+ __malloc_size_t size;
+{
+ __ptr_t result;
+ int type;
+ __malloc_size_t block, oldsize;
+
+ block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1;
+ type = bss_sbrk_heapinfo[block].busy.type;
+ oldsize =
+ type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE
+ : (__malloc_size_t) 1 << type;
+ result = _malloc_internal_nolock (size);
+ if (result != NULL)
+ memcpy (result, ptr, min (oldsize, size));
+ return result;
+}
+#endif
+
/* Debugging hook for realloc. */
__ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size));
@@ -1375,6 +1427,12 @@ _realloc_internal_nolock (ptr, size)
else if (ptr == NULL)
return _malloc_internal_nolock (size);
+#ifdef CYGWIN
+ if (ptr < _heapbase)
+ /* ptr points into the static heap */
+ return special_realloc (ptr, size);
+#endif
+
block = BLOCK (ptr);
PROTECT_MALLOC_STATE (0);
diff --git a/src/gnutls.c b/src/gnutls.c
index fc651d2c7e..0743ef3f4e 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -42,19 +42,19 @@ static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
static int gnutls_global_initialized;
/* The following are for the property list of `gnutls-boot'. */
-static Lisp_Object Qgnutls_bootprop_priority;
-static Lisp_Object Qgnutls_bootprop_trustfiles;
-static Lisp_Object Qgnutls_bootprop_keylist;
-static Lisp_Object Qgnutls_bootprop_crlfiles;
-static Lisp_Object Qgnutls_bootprop_callbacks;
-static Lisp_Object Qgnutls_bootprop_loglevel;
-static Lisp_Object Qgnutls_bootprop_hostname;
-static Lisp_Object Qgnutls_bootprop_min_prime_bits;
-static Lisp_Object Qgnutls_bootprop_verify_flags;
-static Lisp_Object Qgnutls_bootprop_verify_hostname_error;
+static Lisp_Object QCgnutls_bootprop_priority;
+static Lisp_Object QCgnutls_bootprop_trustfiles;
+static Lisp_Object QCgnutls_bootprop_keylist;
+static Lisp_Object QCgnutls_bootprop_crlfiles;
+static Lisp_Object QCgnutls_bootprop_callbacks;
+static Lisp_Object QCgnutls_bootprop_loglevel;
+static Lisp_Object QCgnutls_bootprop_hostname;
+static Lisp_Object QCgnutls_bootprop_min_prime_bits;
+static Lisp_Object QCgnutls_bootprop_verify_flags;
+static Lisp_Object QCgnutls_bootprop_verify_hostname_error;
/* Callback keys for `gnutls-boot'. Unused currently. */
-static Lisp_Object Qgnutls_bootprop_callbacks_verify;
+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*);
@@ -72,41 +72,41 @@ static void gnutls_log_function2 (int, const char*, const char*);
}
DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get,
- (gnutls_session_t));
+ (gnutls_session_t));
DEF_GNUTLS_FN (const char *, gnutls_alert_get_name,
- (gnutls_alert_description_t));
+ (gnutls_alert_description_t));
DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials,
- (gnutls_anon_client_credentials_t *));
+ (gnutls_anon_client_credentials_t *));
DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials,
- (gnutls_anon_client_credentials_t));
+ (gnutls_anon_client_credentials_t));
DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials,
- (gnutls_certificate_credentials_t *));
+ (gnutls_certificate_credentials_t *));
DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials,
- (gnutls_certificate_credentials_t));
+ (gnutls_certificate_credentials_t));
DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
- (gnutls_session_t, unsigned int *));
+ (gnutls_session_t, unsigned int *));
DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags,
- (gnutls_certificate_credentials_t, unsigned int));
+ (gnutls_certificate_credentials_t, unsigned int));
DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file,
- (gnutls_certificate_credentials_t, const char *,
- gnutls_x509_crt_fmt_t));
+ (gnutls_certificate_credentials_t, const char *,
+ gnutls_x509_crt_fmt_t));
DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file,
- (gnutls_certificate_credentials_t, const char *, const char *,
- gnutls_x509_crt_fmt_t));
+ (gnutls_certificate_credentials_t, const char *, const char *,
+ gnutls_x509_crt_fmt_t));
DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file,
- (gnutls_certificate_credentials_t, const char *,
- gnutls_x509_crt_fmt_t));
+ (gnutls_certificate_credentials_t, const char *,
+ gnutls_x509_crt_fmt_t));
DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
- (gnutls_session_t));
+ (gnutls_session_t));
DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2,
- (gnutls_session_t, unsigned int *));
+ (gnutls_session_t, unsigned int *));
DEF_GNUTLS_FN (int, gnutls_credentials_set,
- (gnutls_session_t, gnutls_credentials_type_t, void *));
+ (gnutls_session_t, gnutls_credentials_type_t, void *));
DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
DEF_GNUTLS_FN (void, gnutls_dh_set_prime_bits,
- (gnutls_session_t, unsigned int));
+ (gnutls_session_t, unsigned int));
DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
DEF_GNUTLS_FN (int, gnutls_global_init, (void));
DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
@@ -118,27 +118,27 @@ DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions,
DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t));
DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
- (gnutls_session_t, const char *, const char **));
+ (gnutls_session_t, const char *, const char **));
DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
DEF_GNUTLS_FN (ssize_t, gnutls_record_send,
- (gnutls_session_t, const void *, size_t));
+ (gnutls_session_t, const void *, size_t));
DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2,
- (gnutls_session_t, gnutls_transport_ptr_t,
- gnutls_transport_ptr_t));
+ (gnutls_session_t, gnutls_transport_ptr_t,
+ gnutls_transport_ptr_t));
DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function,
- (gnutls_session_t, gnutls_pull_func));
+ (gnutls_session_t, gnutls_pull_func));
DEF_GNUTLS_FN (void, gnutls_transport_set_push_function,
- (gnutls_session_t, gnutls_push_func));
+ (gnutls_session_t, gnutls_push_func));
DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname,
- (gnutls_x509_crt_t, const char *));
+ (gnutls_x509_crt_t, const char *));
DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
- (gnutls_x509_crt_t, const gnutls_datum_t *,
- gnutls_x509_crt_fmt_t));
+ (gnutls_x509_crt_t, const gnutls_datum_t *,
+ gnutls_x509_crt_fmt_t));
DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
static int
@@ -196,7 +196,7 @@ init_gnutls_functions (Lisp_Object libraries)
max_log_level = global_gnutls_log_level;
GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
- SDATA (Fget (Qgnutls_dll, QCloaded_from)));
+ SDATA (Fget (Qgnutls_dll, QCloaded_from)));
return 1;
}
@@ -267,29 +267,29 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
{
#ifdef WINDOWSNT
/* On W32 we cannot transfer socket handles between different runtime
- libraries, so we tell GnuTLS to use our special push/pull
- functions. */
+ libraries, so we tell GnuTLS to use our special push/pull
+ functions. */
fn_gnutls_transport_set_ptr2 (state,
- (gnutls_transport_ptr_t) proc,
- (gnutls_transport_ptr_t) proc);
+ (gnutls_transport_ptr_t) proc,
+ (gnutls_transport_ptr_t) proc);
fn_gnutls_transport_set_push_function (state, &emacs_gnutls_push);
fn_gnutls_transport_set_pull_function (state, &emacs_gnutls_pull);
/* For non blocking sockets or other custom made pull/push
- functions the gnutls_transport_set_lowat must be called, with
- a zero low water mark value. (GnuTLS 2.10.4 documentation)
+ functions the gnutls_transport_set_lowat must be called, with
+ a zero low water mark value. (GnuTLS 2.10.4 documentation)
- (Note: this is probably not strictly necessary as the lowat
- value is only used when no custom pull/push functions are
- set.) */
+ (Note: this is probably not strictly necessary as the lowat
+ value is only used when no custom pull/push functions are
+ set.) */
fn_gnutls_transport_set_lowat (state, 0);
#else
/* This is how GnuTLS takes sockets: as file descriptors passed
- in. For an Emacs process socket, infd and outfd are the
- same but we use this two-argument version for clarity. */
+ in. For an Emacs process socket, infd and outfd are the
+ same but we use this two-argument version for clarity. */
fn_gnutls_transport_set_ptr2 (state,
- (gnutls_transport_ptr_t) (long) proc->infd,
- (gnutls_transport_ptr_t) (long) proc->outfd);
+ (gnutls_transport_ptr_t) (long) proc->infd,
+ (gnutls_transport_ptr_t) (long) proc->outfd);
#endif
proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
@@ -352,12 +352,12 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte)
rtnval = fn_gnutls_record_send (state, buf, nbyte);
if (rtnval < 0)
- {
- if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED)
- continue;
- else
- break;
- }
+ {
+ if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED)
+ continue;
+ else
+ break;
+ }
buf += rtnval;
nbyte -= rtnval;
@@ -716,17 +716,17 @@ one trustfile (usually a CA bundle). */)
return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED);
}
- hostname = Fplist_get (proplist, Qgnutls_bootprop_hostname);
- priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority);
- trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles);
- keylist = Fplist_get (proplist, Qgnutls_bootprop_keylist);
- crlfiles = Fplist_get (proplist, Qgnutls_bootprop_crlfiles);
- /* callbacks = Fplist_get (proplist, Qgnutls_bootprop_callbacks); */
- loglevel = Fplist_get (proplist, Qgnutls_bootprop_loglevel);
- verify_flags = Fplist_get (proplist, Qgnutls_bootprop_verify_flags);
- /* verify_error = Fplist_get (proplist, Qgnutls_bootprop_verify_error); */
- verify_hostname_error = Fplist_get (proplist, Qgnutls_bootprop_verify_hostname_error);
- prime_bits = Fplist_get (proplist, Qgnutls_bootprop_min_prime_bits);
+ hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname);
+ priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority);
+ trustfiles = Fplist_get (proplist, QCgnutls_bootprop_trustfiles);
+ keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
+ crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
+ /* callbacks = Fplist_get (proplist, QCgnutls_bootprop_callbacks); */
+ loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
+ verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
+ /* verify_error = Fplist_get (proplist, QCgnutls_bootprop_verify_error); */
+ verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error);
+ prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
if (!STRINGP (hostname))
error ("gnutls-boot: invalid :hostname parameter");
@@ -756,26 +756,26 @@ one trustfile (usually a CA bundle). */)
if (EQ (type, Qgnutls_x509pki))
{
- GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
- x509_cred = XPROCESS (proc)->gnutls_x509_cred;
- fn_gnutls_certificate_free_credentials (x509_cred);
+ GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
+ x509_cred = XPROCESS (proc)->gnutls_x509_cred;
+ fn_gnutls_certificate_free_credentials (x509_cred);
}
else if (EQ (type, Qgnutls_anon))
{
- GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
- anon_cred = XPROCESS (proc)->gnutls_anon_cred;
- fn_gnutls_anon_free_client_credentials (anon_cred);
+ GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
+ anon_cred = XPROCESS (proc)->gnutls_anon_cred;
+ fn_gnutls_anon_free_client_credentials (anon_cred);
}
else
{
- error ("unknown credential type");
- ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
+ error ("unknown credential type");
+ ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
}
if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
{
- GNUTLS_LOG (1, max_log_level, "deallocating x509 credentials");
- Fgnutls_deinit (proc);
+ GNUTLS_LOG (1, max_log_level, "deallocating x509 credentials");
+ Fgnutls_deinit (proc);
}
}
@@ -790,20 +790,20 @@ one trustfile (usually a CA bundle). */)
fn_gnutls_certificate_allocate_credentials (&x509_cred);
if (NUMBERP (verify_flags))
- {
- gnutls_verify_flags = XINT (verify_flags);
- GNUTLS_LOG (2, max_log_level, "setting verification flags");
- }
+ {
+ gnutls_verify_flags = XINT (verify_flags);
+ GNUTLS_LOG (2, max_log_level, "setting verification flags");
+ }
else if (NILP (verify_flags))
- {
- /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
- GNUTLS_LOG (2, max_log_level, "using default verification flags");
- }
+ {
+ /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
+ GNUTLS_LOG (2, max_log_level, "using default verification flags");
+ }
else
- {
- /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
- GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
- }
+ {
+ /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
+ GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
+ }
fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
}
else if (EQ (type, Qgnutls_anon))
@@ -828,76 +828,76 @@ one trustfile (usually a CA bundle). */)
for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail))
{
Lisp_Object trustfile = Fcar (tail);
- if (STRINGP (trustfile))
- {
- GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
- SSDATA (trustfile));
- ret = fn_gnutls_certificate_set_x509_trust_file
- (x509_cred,
- SSDATA (trustfile),
- file_format);
-
- if (ret < GNUTLS_E_SUCCESS)
- return gnutls_make_error (ret);
- }
- else
- {
- error ("Sorry, GnuTLS can't use non-string trustfile %s",
- SDATA (trustfile));
- }
- }
+ if (STRINGP (trustfile))
+ {
+ GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
+ SSDATA (trustfile));
+ ret = fn_gnutls_certificate_set_x509_trust_file
+ (x509_cred,
+ SSDATA (trustfile),
+ file_format);
+
+ if (ret < GNUTLS_E_SUCCESS)
+ return gnutls_make_error (ret);
+ }
+ else
+ {
+ error ("Sorry, GnuTLS can't use non-string trustfile %s",
+ SDATA (trustfile));
+ }
+ }
for (tail = crlfiles; !NILP (tail); tail = Fcdr (tail))
{
Lisp_Object crlfile = Fcar (tail);
- if (STRINGP (crlfile))
- {
- GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
- SSDATA (crlfile));
- ret = fn_gnutls_certificate_set_x509_crl_file
- (x509_cred,
- SSDATA (crlfile),
- file_format);
-
- if (ret < GNUTLS_E_SUCCESS)
- return gnutls_make_error (ret);
- }
- else
- {
- error ("Sorry, GnuTLS can't use non-string CRL file %s",
- SDATA (crlfile));
- }
- }
+ if (STRINGP (crlfile))
+ {
+ GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
+ SSDATA (crlfile));
+ ret = fn_gnutls_certificate_set_x509_crl_file
+ (x509_cred,
+ SSDATA (crlfile),
+ file_format);
+
+ if (ret < GNUTLS_E_SUCCESS)
+ return gnutls_make_error (ret);
+ }
+ else
+ {
+ error ("Sorry, GnuTLS can't use non-string CRL file %s",
+ SDATA (crlfile));
+ }
+ }
for (tail = keylist; !NILP (tail); tail = Fcdr (tail))
{
Lisp_Object keyfile = Fcar (Fcar (tail));
Lisp_Object certfile = Fcar (Fcdr (tail));
- if (STRINGP (keyfile) && STRINGP (certfile))
- {
- GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
- SSDATA (keyfile));
- GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
- SSDATA (certfile));
- ret = fn_gnutls_certificate_set_x509_key_file
- (x509_cred,
- SSDATA (certfile),
- SSDATA (keyfile),
- file_format);
-
- if (ret < GNUTLS_E_SUCCESS)
- return gnutls_make_error (ret);
- }
- else
- {
- if (STRINGP (keyfile))
- error ("Sorry, GnuTLS can't use non-string client cert file %s",
- SDATA (certfile));
- else
- error ("Sorry, GnuTLS can't use non-string client key file %s",
- SDATA (keyfile));
- }
- }
+ if (STRINGP (keyfile) && STRINGP (certfile))
+ {
+ GNUTLS_LOG2 (1, max_log_level, "setting the client key file: ",
+ SSDATA (keyfile));
+ GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
+ SSDATA (certfile));
+ ret = fn_gnutls_certificate_set_x509_key_file
+ (x509_cred,
+ SSDATA (certfile),
+ SSDATA (keyfile),
+ file_format);
+
+ if (ret < GNUTLS_E_SUCCESS)
+ return gnutls_make_error (ret);
+ }
+ else
+ {
+ if (STRINGP (keyfile))
+ error ("Sorry, GnuTLS can't use non-string client cert file %s",
+ SDATA (certfile));
+ else
+ error ("Sorry, GnuTLS can't use non-string client key file %s",
+ SDATA (keyfile));
+ }
+ }
}
GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
@@ -925,19 +925,19 @@ one trustfile (usually a CA bundle). */)
{
priority_string_ptr = SSDATA (priority_string);
GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
- priority_string_ptr);
+ priority_string_ptr);
}
else
{
GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
- priority_string_ptr);
+ priority_string_ptr);
}
GNUTLS_LOG (1, max_log_level, "setting the priority string");
ret = fn_gnutls_priority_set_direct (state,
- priority_string_ptr,
- NULL);
+ priority_string_ptr,
+ NULL);
if (ret < GNUTLS_E_SUCCESS)
return gnutls_make_error (ret);
@@ -990,44 +990,44 @@ one trustfile (usually a CA bundle). */)
if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID)
message ("%s certificate could not be verified.",
- c_hostname);
+ c_hostname);
if (peer_verification & GNUTLS_CERT_REVOKED)
GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):",
- c_hostname);
+ c_hostname);
if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:",
- c_hostname);
+ c_hostname);
if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA)
GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:",
- c_hostname);
+ c_hostname);
if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM)
GNUTLS_LOG2 (1, max_log_level,
- "certificate was signed with an insecure algorithm:",
- c_hostname);
+ "certificate was signed with an insecure algorithm:",
+ c_hostname);
if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED)
GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:",
- c_hostname);
+ c_hostname);
if (peer_verification & GNUTLS_CERT_EXPIRED)
GNUTLS_LOG2 (1, max_log_level, "certificate has expired:",
- c_hostname);
+ c_hostname);
if (peer_verification != 0)
{
if (NILP (verify_hostname_error))
{
- GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
- c_hostname);
+ GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
+ c_hostname);
}
else
{
- error ("Certificate validation failed %s, verification code %d",
- c_hostname, peer_verification);
+ error ("Certificate validation failed %s, verification code %d",
+ c_hostname, peer_verification);
}
}
@@ -1039,41 +1039,41 @@ one trustfile (usually a CA bundle). */)
ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
if (ret < GNUTLS_E_SUCCESS)
- return gnutls_make_error (ret);
+ return gnutls_make_error (ret);
gnutls_verify_cert_list =
- fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
+ fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
if (NULL == gnutls_verify_cert_list)
- {
- error ("No x509 certificate was found!\n");
- }
+ {
+ error ("No x509 certificate was found!\n");
+ }
/* We only check the first certificate in the given chain. */
ret = fn_gnutls_x509_crt_import (gnutls_verify_cert,
- &gnutls_verify_cert_list[0],
- GNUTLS_X509_FMT_DER);
+ &gnutls_verify_cert_list[0],
+ GNUTLS_X509_FMT_DER);
if (ret < GNUTLS_E_SUCCESS)
- {
- fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
- return gnutls_make_error (ret);
- }
+ {
+ fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
+ return gnutls_make_error (ret);
+ }
if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
- {
- if (NILP (verify_hostname_error))
- {
- GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
- c_hostname);
- }
- else
- {
- fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
- error ("The x509 certificate does not match \"%s\"",
- c_hostname);
- }
- }
+ {
+ if (NILP (verify_hostname_error))
+ {
+ GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
+ c_hostname);
+ }
+ else
+ {
+ fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
+ error ("The x509 certificate does not match \"%s\"",
+ c_hostname);
+ }
+ }
fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
}
@@ -1105,7 +1105,7 @@ This function may also return `gnutls-e-again', or
state = XPROCESS (proc)->gnutls_state;
ret = fn_gnutls_bye (state,
- NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
+ NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
return gnutls_make_error (ret);
}
@@ -1119,33 +1119,33 @@ syms_of_gnutls (void)
DEFSYM (Qgnutls_code, "gnutls-code");
DEFSYM (Qgnutls_anon, "gnutls-anon");
DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
- DEFSYM (Qgnutls_bootprop_hostname, ":hostname");
- DEFSYM (Qgnutls_bootprop_priority, ":priority");
- DEFSYM (Qgnutls_bootprop_trustfiles, ":trustfiles");
- DEFSYM (Qgnutls_bootprop_keylist, ":keylist");
- DEFSYM (Qgnutls_bootprop_crlfiles, ":crlfiles");
- DEFSYM (Qgnutls_bootprop_callbacks, ":callbacks");
- DEFSYM (Qgnutls_bootprop_callbacks_verify, "verify");
- DEFSYM (Qgnutls_bootprop_min_prime_bits, ":min-prime-bits");
- DEFSYM (Qgnutls_bootprop_loglevel, ":loglevel");
- DEFSYM (Qgnutls_bootprop_verify_flags, ":verify-flags");
- DEFSYM (Qgnutls_bootprop_verify_hostname_error, ":verify-hostname-error");
+ DEFSYM (QCgnutls_bootprop_hostname, ":hostname");
+ DEFSYM (QCgnutls_bootprop_priority, ":priority");
+ DEFSYM (QCgnutls_bootprop_trustfiles, ":trustfiles");
+ DEFSYM (QCgnutls_bootprop_keylist, ":keylist");
+ DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles");
+ DEFSYM (QCgnutls_bootprop_callbacks, ":callbacks");
+ DEFSYM (QCgnutls_bootprop_callbacks_verify, "verify");
+ DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
+ DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
+ DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
+ DEFSYM (QCgnutls_bootprop_verify_hostname_error, ":verify-hostname-error");
DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
Fput (Qgnutls_e_interrupted, Qgnutls_code,
- make_number (GNUTLS_E_INTERRUPTED));
+ make_number (GNUTLS_E_INTERRUPTED));
DEFSYM (Qgnutls_e_again, "gnutls-e-again");
Fput (Qgnutls_e_again, Qgnutls_code,
- make_number (GNUTLS_E_AGAIN));
+ make_number (GNUTLS_E_AGAIN));
DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
Fput (Qgnutls_e_invalid_session, Qgnutls_code,
- make_number (GNUTLS_E_INVALID_SESSION));
+ make_number (GNUTLS_E_INVALID_SESSION));
DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
- make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
+ make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
defsubr (&Sgnutls_get_initstage);
defsubr (&Sgnutls_errorp);
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 8826b08851..c39119c815 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -487,7 +487,8 @@ get_utf8_string (const char *str)
if (!utf8_str)
{
/* Probably some control characters in str. Escape them. */
- size_t nr_bad = 0;
+ ptrdiff_t len;
+ ptrdiff_t nr_bad = 0;
gsize bytes_read;
gsize bytes_written;
unsigned char *p = (unsigned char *)str;
@@ -511,7 +512,10 @@ get_utf8_string (const char *str)
}
if (cp) g_free (cp);
- up = utf8_str = xmalloc (strlen (str) + nr_bad * 4 + 1);
+ len = strlen (str);
+ if ((min (PTRDIFF_MAX, SIZE_MAX) - len - 1) / 4 < nr_bad)
+ memory_full (SIZE_MAX);
+ up = utf8_str = xmalloc (len + nr_bad * 4 + 1);
p = (unsigned char *)str;
while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read,
@@ -1907,12 +1911,12 @@ xg_get_file_name (FRAME_PTR f,
int filesel_done = 0;
xg_get_file_func func;
-#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
+#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
/* I really don't know why this is needed, but without this the GLIBC add on
library linuxthreads hangs when the Gnome file chooser backend creates
threads. */
sigblock (sigmask (__SIGRTMIN));
-#endif /* HAVE_GTK_AND_PTHREAD */
+#endif /* HAVE_PTHREAD */
#ifdef HAVE_GTK_FILE_SELECTION_NEW
@@ -1932,7 +1936,7 @@ xg_get_file_name (FRAME_PTR f,
filesel_done = xg_dialog_run (f, w);
-#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
+#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
sigunblock (sigmask (__SIGRTMIN));
#endif
@@ -1960,9 +1964,9 @@ xg_get_font_name (FRAME_PTR f, const char *default_name)
char *fontname = NULL;
int done = 0;
-#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
+#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
sigblock (sigmask (__SIGRTMIN));
-#endif /* HAVE_GTK_AND_PTHREAD */
+#endif /* HAVE_PTHREAD */
w = gtk_font_selection_dialog_new ("Pick a font");
if (!default_name)
@@ -1974,7 +1978,7 @@ xg_get_font_name (FRAME_PTR f, const char *default_name)
done = xg_dialog_run (f, w);
-#if defined (HAVE_GTK_AND_PTHREAD) && defined (__SIGRTMIN)
+#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
sigunblock (sigmask (__SIGRTMIN));
#endif
@@ -3296,8 +3300,8 @@ static int scroll_bar_width_for_theme;
static struct
{
GtkWidget **widgets;
- int max_size;
- int used;
+ ptrdiff_t max_size;
+ ptrdiff_t used;
} id_to_widget;
/* Grow this much every time we need to allocate more */
@@ -3306,17 +3310,20 @@ static struct
/* Store the widget pointer W in id_to_widget and return the integer index. */
-static int
+static ptrdiff_t
xg_store_widget_in_map (GtkWidget *w)
{
- int i;
+ ptrdiff_t i;
if (id_to_widget.max_size == id_to_widget.used)
{
- int new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR;
+ ptrdiff_t new_size;
+ if (TYPE_MAXIMUM (Window) - ID_TO_WIDGET_INCR < id_to_widget.max_size)
+ memory_full (SIZE_MAX);
- id_to_widget.widgets = xrealloc (id_to_widget.widgets,
- sizeof (GtkWidget *)*new_size);
+ new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR;
+ id_to_widget.widgets = xnrealloc (id_to_widget.widgets,
+ new_size, sizeof (GtkWidget *));
for (i = id_to_widget.max_size; i < new_size; ++i)
id_to_widget.widgets[i] = 0;
@@ -3345,7 +3352,7 @@ xg_store_widget_in_map (GtkWidget *w)
Called when scroll bar is destroyed. */
static void
-xg_remove_widget_from_map (int idx)
+xg_remove_widget_from_map (ptrdiff_t idx)
{
if (idx < id_to_widget.max_size && id_to_widget.widgets[idx] != 0)
{
@@ -3357,7 +3364,7 @@ xg_remove_widget_from_map (int idx)
/* Get the widget pointer at IDX from id_to_widget. */
static GtkWidget *
-xg_get_widget_from_map (int idx)
+xg_get_widget_from_map (ptrdiff_t idx)
{
if (idx < id_to_widget.max_size && id_to_widget.widgets[idx] != 0)
return id_to_widget.widgets[idx];
@@ -3396,10 +3403,10 @@ xg_get_default_scrollbar_width (void)
/* Return the scrollbar id for X Window WID on display DPY.
Return -1 if WID not in id_to_widget. */
-int
+ptrdiff_t
xg_get_scroll_id_for_window (Display *dpy, Window wid)
{
- int idx;
+ ptrdiff_t idx;
GtkWidget *w;
w = xg_win_to_widget (dpy, wid);
@@ -3421,7 +3428,7 @@ xg_get_scroll_id_for_window (Display *dpy, Window wid)
static void
xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data)
{
- int id = (intptr_t) data;
+ intptr_t id = (intptr_t) data;
xg_remove_widget_from_map (id);
}
@@ -3496,7 +3503,7 @@ xg_create_scroll_bar (FRAME_PTR f,
/* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */
void
-xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id)
+xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id)
{
GtkWidget *w = xg_get_widget_from_map (scrollbar_id);
if (w)
@@ -3515,7 +3522,7 @@ xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id)
void
xg_update_scrollbar_pos (FRAME_PTR f,
- int scrollbar_id,
+ ptrdiff_t scrollbar_id,
int top,
int left,
int width,
@@ -4429,7 +4436,7 @@ update_frame_tool_bar (FRAME_PTR f)
int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
int idx;
- int img_id;
+ ptrdiff_t img_id;
int icon_size = 0;
struct image *img = NULL;
Lisp_Object image;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 769e56da91..2dfb3a5ed6 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -114,17 +114,17 @@ extern int xg_event_is_for_menubar (FRAME_PTR f, XEvent *event);
extern int xg_have_tear_offs (void);
-extern int xg_get_scroll_id_for_window (Display *dpy, Window wid);
+extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
extern void xg_create_scroll_bar (FRAME_PTR f,
struct scroll_bar *bar,
GCallback scroll_callback,
GCallback end_callback,
const char *scroll_bar_name);
-extern void xg_remove_scroll_bar (FRAME_PTR f, int scrollbar_id);
+extern void xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id);
extern void xg_update_scrollbar_pos (FRAME_PTR f,
- int scrollbar_id,
+ ptrdiff_t scrollbar_id,
int top,
int left,
int width,
@@ -185,4 +185,3 @@ extern int xg_ignore_gtk_scrollbar;
#endif /* USE_GTK */
#endif /* GTKUTIL_H */
-
diff --git a/src/image.c b/src/image.c
index d1091aec6f..c5dcbb32e5 100644
--- a/src/image.c
+++ b/src/image.c
@@ -196,6 +196,7 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
int
x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
{
+ /* HAVE_NTGUI needs the explicit cast here. */
return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
}
#endif
@@ -216,15 +217,6 @@ x_allocate_bitmap_record (FRAME_PTR f)
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
ptrdiff_t i;
- if (dpyinfo->bitmaps == NULL)
- {
- dpyinfo->bitmaps_size = 10;
- dpyinfo->bitmaps
- = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
- dpyinfo->bitmaps_last = 1;
- return 1;
- }
-
if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
return ++dpyinfo->bitmaps_last;
@@ -232,20 +224,16 @@ x_allocate_bitmap_record (FRAME_PTR f)
if (dpyinfo->bitmaps[i].refcount == 0)
return i + 1;
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2
- < dpyinfo->bitmaps_size)
- memory_full (SIZE_MAX);
- dpyinfo->bitmaps_size *= 2;
- dpyinfo->bitmaps
- = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
- dpyinfo->bitmaps_size * sizeof (Bitmap_Record));
+ dpyinfo->bitmaps =
+ xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
+ 10, -1, sizeof *dpyinfo->bitmaps);
return ++dpyinfo->bitmaps_last;
}
/* Add one reference to the reference count of the bitmap with id ID. */
void
-x_reference_bitmap (FRAME_PTR f, int id)
+x_reference_bitmap (FRAME_PTR f, ptrdiff_t id)
{
++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
}
@@ -704,7 +692,7 @@ enum image_value_type
IMAGE_STRING_OR_NIL_VALUE,
IMAGE_SYMBOL_VALUE,
IMAGE_POSITIVE_INTEGER_VALUE,
- IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
+ IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
IMAGE_NON_NEGATIVE_INTEGER_VALUE,
IMAGE_ASCENT_VALUE,
IMAGE_INTEGER_VALUE,
@@ -807,29 +795,30 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
break;
case IMAGE_POSITIVE_INTEGER_VALUE:
- if (!INTEGERP (value) || XINT (value) <= 0)
+ if (! RANGED_INTEGERP (1, value, INT_MAX))
return 0;
break;
- case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR:
- if (INTEGERP (value) && XINT (value) >= 0)
+ case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
+ if (RANGED_INTEGERP (0, value, INT_MAX))
break;
if (CONSP (value)
- && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value))
- && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0)
+ && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
+ && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
break;
return 0;
case IMAGE_ASCENT_VALUE:
if (SYMBOLP (value) && EQ (value, Qcenter))
break;
- else if (INTEGERP (value)
- && XINT (value) >= 0
- && XINT (value) <= 100)
+ else if (RANGED_INTEGERP (0, value, 100))
break;
return 0;
case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
+ /* Unlike the other integer-related cases, this one does not
+ verify that VALUE fits in 'int'. This is because callers
+ want EMACS_INT. */
if (!INTEGERP (value) || XINT (value) < 0)
return 0;
break;
@@ -849,7 +838,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
break;
case IMAGE_INTEGER_VALUE:
- if (!INTEGERP (value))
+ if (! TYPE_RANGED_INTEGERP (int, value))
return 0;
break;
@@ -919,7 +908,7 @@ or omitted means use the selected frame. */)
if (valid_image_p (spec))
{
struct frame *f = check_x_frame (frame);
- int id = lookup_image (f, spec);
+ ptrdiff_t id = lookup_image (f, spec);
struct image *img = IMAGE_FROM_ID (f, id);
int width = img->width + 2 * img->hmargin;
int height = img->height + 2 * img->vmargin;
@@ -949,7 +938,7 @@ or omitted means use the selected frame. */)
if (valid_image_p (spec))
{
struct frame *f = check_x_frame (frame);
- int id = lookup_image (f, spec);
+ ptrdiff_t id = lookup_image (f, spec);
struct image *img = IMAGE_FROM_ID (f, id);
if (img->mask)
mask = Qt;
@@ -972,7 +961,7 @@ or omitted means use the selected frame. */)
if (valid_image_p (spec))
{
struct frame *f = check_x_frame (frame);
- int id = lookup_image (f, spec);
+ ptrdiff_t id = lookup_image (f, spec);
struct image *img = IMAGE_FROM_ID (f, id);
ext = img->lisp_data;
}
@@ -1125,7 +1114,7 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
ascent = height / 2;
}
else
- ascent = (int) (height * img->ascent / 100.0);
+ ascent = height * (img->ascent / 100.0);
return ascent;
}
@@ -1371,11 +1360,12 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
{
/* This isn't called frequently so we get away with simply
reallocating the color vector to the needed size, here. */
- ++img->ncolors;
+ ptrdiff_t ncolors = img->ncolors + 1;
img->colors =
(unsigned long *) xrealloc (img->colors,
- img->ncolors * sizeof *img->colors);
- img->colors[img->ncolors - 1] = color.pixel;
+ ncolors * sizeof *img->colors);
+ img->colors[ncolors - 1] = color.pixel;
+ img->ncolors = ncolors;
result = color.pixel;
}
else
@@ -1403,8 +1393,9 @@ make_image_cache (void)
int size;
memset (c, 0, sizeof *c);
- c->size = 50;
- c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
+ size = 50;
+ c->images = (struct image **) xmalloc (size * sizeof *c->images);
+ c->size = size;
size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
c->buckets = (struct image **) xmalloc (size);
memset (c->buckets, 0, size);
@@ -1470,7 +1461,7 @@ free_image_cache (struct frame *f)
struct image_cache *c = FRAME_IMAGE_CACHE (f);
if (c)
{
- int i;
+ ptrdiff_t i;
/* Cache should not be referenced by any frame when freed. */
xassert (c->refcount == 0);
@@ -1500,7 +1491,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
if (c)
{
- int i, nfreed = 0;
+ ptrdiff_t i, nfreed = 0;
/* Block input so that we won't be interrupted by a SIGIO
while being in an inconsistent state. */
@@ -1524,8 +1515,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
{
/* Free cache based on timestamp. */
EMACS_TIME t;
- time_t old;
- int delay, nimages = 0;
+ double old, delay;
+ ptrdiff_t nimages = 0;
for (i = 0; i < c->used; ++i)
if (c->images[i])
@@ -1533,9 +1524,10 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
/* If the number of cached images has grown unusually large,
decrease the cache eviction delay (Bug#6230). */
- delay = XFASTINT (Vimage_cache_eviction_delay);
+ delay = XINT (Vimage_cache_eviction_delay);
if (nimages > 40)
- delay = max (1, 1600 * delay / (nimages*nimages));
+ delay = 1600 * delay / nimages / nimages;
+ delay = max (delay, 1);
EMACS_GET_TIME (t);
old = EMACS_SECS (t) - delay;
@@ -1711,7 +1703,7 @@ postprocess_image (struct frame *f, struct image *img)
/* Return the id of image with Lisp specification SPEC on frame F.
SPEC must be a valid Lisp image specification (see valid_image_p). */
-int
+ptrdiff_t
lookup_image (struct frame *f, Lisp_Object spec)
{
struct image *img;
@@ -1770,15 +1762,12 @@ lookup_image (struct frame *f, Lisp_Object spec)
img->ascent = CENTERED_IMAGE_ASCENT;
margin = image_spec_value (spec, QCmargin, NULL);
- if (INTEGERP (margin) && XINT (margin) >= 0)
+ if (INTEGERP (margin))
img->vmargin = img->hmargin = XFASTINT (margin);
- else if (CONSP (margin) && INTEGERP (XCAR (margin))
- && INTEGERP (XCDR (margin)))
+ else if (CONSP (margin))
{
- if (XINT (XCAR (margin)) > 0)
- img->hmargin = XFASTINT (XCAR (margin));
- if (XINT (XCDR (margin)) > 0)
- img->vmargin = XFASTINT (XCDR (margin));
+ img->hmargin = XFASTINT (XCAR (margin));
+ img->vmargin = XFASTINT (XCDR (margin));
}
relief = image_spec_value (spec, QCrelief, NULL);
@@ -1825,7 +1814,7 @@ static void
cache_image (struct frame *f, struct image *img)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
- int i;
+ ptrdiff_t i;
/* Find a free slot in c->images. */
for (i = 0; i < c->used; ++i)
@@ -1834,13 +1823,7 @@ cache_image (struct frame *f, struct image *img)
/* If no free slot found, maybe enlarge c->images. */
if (i == c->used && c->used == c->size)
- {
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size)
- memory_full (SIZE_MAX);
- c->size *= 2;
- c->images = (struct image **) xrealloc (c->images,
- c->size * sizeof *c->images);
- }
+ c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
/* Add IMG to c->images, and assign IMG an id. */
c->images[i] = img;
@@ -1879,7 +1862,7 @@ mark_image_cache (struct image_cache *c)
{
if (c)
{
- int i;
+ ptrdiff_t i;
for (i = 0; i < c->used; ++i)
if (c->images[i])
mark_image (c->images[i]);
@@ -2076,7 +2059,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
DWORD err = GetLastError ();
Lisp_Object errcode;
/* All system errors are < 10000, so the following is safe. */
- XSETINT (errcode, (int) err);
+ XSETINT (errcode, err);
image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
x_destroy_x_image (*ximg);
return 0;
@@ -2274,7 +2257,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
{":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
{":background", IMAGE_STRING_OR_NIL_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -2355,7 +2338,7 @@ xbm_image_p (Lisp_Object object)
else
{
Lisp_Object data;
- EMACS_INT width, height;
+ int width, height;
/* Entries for `:width', `:height' and `:data' must be present. */
if (!kw[XBM_WIDTH].count
@@ -3069,7 +3052,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
{":file", IMAGE_STRING_VALUE, 0},
{":data", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -3587,9 +3570,8 @@ xpm_load (struct frame *f, struct image *img)
#endif /* HAVE_NTGUI */
/* Remember allocated colors. */
+ img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
img->ncolors = attrs.nalloc_pixels;
- img->colors = (unsigned long *) xmalloc (img->ncolors
- * sizeof *img->colors);
for (i = 0; i < attrs.nalloc_pixels; ++i)
{
img->colors[i] = attrs.alloc_pixels[i];
@@ -3813,8 +3795,8 @@ xpm_get_color_table_h (Lisp_Object color_table,
int chars_len)
{
struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
- int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len),
- NULL);
+ ptrdiff_t i =
+ hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL);
return i >= 0 ? HASH_VALUE (table, i) : Qnil;
}
@@ -4163,6 +4145,12 @@ static struct ct_color **ct_table;
/* Number of entries in the color table. */
static int ct_colors_allocated;
+enum
+{
+ ct_colors_allocated_max =
+ min (INT_MAX,
+ min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long))
+};
/* Initialize the color table. */
@@ -4249,7 +4237,14 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
XColor color;
Colormap cmap;
int rc;
+#else
+ COLORREF color;
+#endif
+ if (ct_colors_allocated_max <= ct_colors_allocated)
+ return FRAME_FOREGROUND_PIXEL (f);
+
+#ifdef HAVE_X_WINDOWS
color.red = r;
color.green = g;
color.blue = b;
@@ -4271,7 +4266,6 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
return FRAME_FOREGROUND_PIXEL (f);
#else
- COLORREF color;
#ifdef HAVE_NTGUI
color = PALETTERGB (r, g, b);
#else
@@ -4312,6 +4306,9 @@ lookup_pixel_color (struct frame *f, unsigned long pixel)
Colormap cmap;
int rc;
+ if (ct_colors_allocated_max <= ct_colors_allocated)
+ return FRAME_FOREGROUND_PIXEL (f);
+
#ifdef HAVE_X_WINDOWS
cmap = FRAME_X_COLORMAP (f);
color.pixel = pixel;
@@ -4450,7 +4447,9 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p)
HGDIOBJ prev;
#endif /* HAVE_NTGUI */
- colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
+ memory_full (SIZE_MAX);
+ colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height);
#ifndef HAVE_NTGUI
/* Get the X image IMG->pixmap. */
@@ -4602,7 +4601,9 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus
#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
- new = (XColor *) xmalloc (img->width * img->height * sizeof *new);
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
+ memory_full (SIZE_MAX);
+ new = (XColor *) xmalloc (sizeof *new * img->width * img->height);
for (y = 0; y < img->height; ++y)
{
@@ -4980,7 +4981,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
{":file", IMAGE_STRING_VALUE, 0},
{":data", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -5395,7 +5396,7 @@ static const struct image_keyword png_format[PNG_LAST] =
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -5880,7 +5881,7 @@ png_load (struct frame *f, struct image *img)
for (x = 0; x < width; ++x)
{
- unsigned r, g, b;
+ int r, g, b;
r = *p++ << 8;
g = *p++ << 8;
@@ -6015,7 +6016,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -6565,7 +6566,7 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -6745,17 +6746,29 @@ tiff_size_of_memory (thandle_t data)
}
+static void tiff_handler (const char *, const char *, const char *, va_list)
+ ATTRIBUTE_FORMAT_PRINTF (3, 0);
+static void
+tiff_handler (const char *log_format, const char *title,
+ const char *format, va_list ap)
+{
+ /* doprnt is not suitable here, as TIFF handlers are called from
+ libtiff and are passed arbitrary printf directives. Instead, use
+ vsnprintf, taking care to be portable to nonstandard environments
+ where vsnprintf returns -1 on buffer overflow. Since it's just a
+ log entry, it's OK to truncate it. */
+ char buf[4000];
+ int len = vsnprintf (buf, sizeof buf, format, ap);
+ add_to_log (log_format, build_string (title),
+ make_string (buf, max (0, min (len, sizeof buf - 1))));
+}
+
static void tiff_error_handler (const char *, const char *, va_list)
ATTRIBUTE_FORMAT_PRINTF (2, 0);
static void
tiff_error_handler (const char *title, const char *format, va_list ap)
{
- char buf[512];
- int len;
-
- len = sprintf (buf, "TIFF error: %s ", title);
- vsprintf (buf + len, format, ap);
- add_to_log (buf, Qnil, Qnil);
+ tiff_handler ("TIFF error: %s %s", title, format, ap);
}
@@ -6764,12 +6777,7 @@ static void tiff_warning_handler (const char *, const char *, va_list)
static void
tiff_warning_handler (const char *title, const char *format, va_list ap)
{
- char buf[512];
- int len;
-
- len = sprintf (buf, "TIFF warning: %s ", title);
- vsprintf (buf + len, format, ap);
- add_to_log (buf, Qnil, Qnil);
+ tiff_handler ("TIFF warning: %s %s", title, format, ap);
}
@@ -6845,8 +6853,9 @@ tiff_load (struct frame *f, struct image *img)
image = image_spec_value (img->spec, QCindex, NULL);
if (INTEGERP (image))
{
- int ino = XFASTINT (image);
- if (!fn_TIFFSetDirectory (tiff, ino))
+ EMACS_INT ino = XFASTINT (image);
+ if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
+ && fn_TIFFSetDirectory (tiff, ino)))
{
image_error ("Invalid image number `%s' in image `%s'",
image, img->spec);
@@ -6994,7 +7003,7 @@ static const struct image_keyword gif_format[GIF_LAST] =
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -7139,13 +7148,12 @@ gif_load (struct frame *f, struct image *img)
ColorMapObject *gif_color_map;
unsigned long pixel_colors[256];
GifFileType *gif;
- int image_height, image_width;
gif_memory_source memsrc;
Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
unsigned long bgcolor = 0;
- int idx;
+ EMACS_INT idx;
if (NILP (specified_data))
{
@@ -7216,19 +7224,13 @@ gif_load (struct frame *f, struct image *img)
}
}
- img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top;
- img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left;
- image_height = gif->SavedImages[idx].ImageDesc.Height;
- img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
- image_width = gif->SavedImages[idx].ImageDesc.Width;
- img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
+ width = img->width = gif->SWidth;
+ height = img->height = gif->SHeight;
- width = img->width = max (gif->SWidth,
- max (gif->Image.Left + gif->Image.Width,
- img->corners[RIGHT_CORNER]));
- height = img->height = max (gif->SHeight,
- max (gif->Image.Top + gif->Image.Height,
- img->corners[BOT_CORNER]));
+ img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
+ img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
+ img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + height;
+ img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + width;
if (!check_image_size (f, width, height))
{
@@ -7283,6 +7285,10 @@ gif_load (struct frame *f, struct image *img)
unsigned char *raster = (unsigned char *) subimage->RasterBits;
int transparency_color_index = -1;
int disposal = 0;
+ int subimg_width = subimage->ImageDesc.Width;
+ int subimg_height = subimage->ImageDesc.Height;
+ int subimg_top = subimage->ImageDesc.Top;
+ int subimg_left = subimage->ImageDesc.Left;
/* Find the Graphic Control Extension block for this sub-image.
Extract the disposal method and transparency color. */
@@ -7306,6 +7312,13 @@ gif_load (struct frame *f, struct image *img)
if (j == 0)
disposal = 2;
+ /* For disposal == 0, the spec says "No disposal specified. The
+ decoder is not required to take any action." In practice, it
+ seems we need to treat this like "keep in place", see e.g.
+ http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
+ if (disposal == 0)
+ disposal = 1;
+
/* Allocate subimage colors. */
memset (pixel_colors, 0, sizeof pixel_colors);
gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7333,34 +7346,34 @@ gif_load (struct frame *f, struct image *img)
int row, pass;
for (y = 0, row = interlace_start[0], pass = 0;
- y < image_height;
+ y < subimg_height;
y++, row += interlace_increment[pass])
{
- if (row >= image_height)
+ if (row >= subimg_height)
{
row = interlace_start[++pass];
- while (row >= image_height)
+ while (row >= subimg_height)
row = interlace_start[++pass];
}
- for (x = 0; x < image_width; x++)
+ for (x = 0; x < subimg_width; x++)
{
- int c = raster[y * image_width + x];
+ int c = raster[y * subimg_width + x];
if (transparency_color_index != c || disposal != 1)
- XPutPixel (ximg, x + img->corners[LEFT_CORNER],
- row + img->corners[TOP_CORNER], pixel_colors[c]);
+ XPutPixel (ximg, x + subimg_left, row + subimg_top,
+ pixel_colors[c]);
}
}
}
else
{
- for (y = 0; y < image_height; ++y)
- for (x = 0; x < image_width; ++x)
+ for (y = 0; y < subimg_height; ++y)
+ for (x = 0; x < subimg_width; ++x)
{
- int c = raster[y * image_width + x];
+ int c = raster[y * subimg_width + x];
if (transparency_color_index != c || disposal != 1)
- XPutPixel (ximg, x + img->corners[LEFT_CORNER],
- y + img->corners[TOP_CORNER], pixel_colors[c]);
+ XPutPixel (ximg, x + subimg_left, y + subimg_top,
+ pixel_colors[c]);
}
}
}
@@ -7375,7 +7388,7 @@ gif_load (struct frame *f, struct image *img)
img->lisp_data = Qnil;
if (gif->SavedImages[idx].ExtensionBlockCount > 0)
{
- unsigned int delay = 0;
+ int delay = 0;
ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
/* Append (... FUNCTION "BYTES") */
@@ -7396,7 +7409,7 @@ gif_load (struct frame *f, struct image *img)
if (delay)
img->lisp_data
= Fcons (Qdelay,
- Fcons (make_float (((double) delay) * 0.01),
+ Fcons (make_float (delay / 100.0),
img->lisp_data));
}
@@ -7475,7 +7488,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -7572,10 +7585,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
Lisp_Object image;
Lisp_Object value;
Lisp_Object crop;
- long ino;
+ EMACS_INT ino;
int desired_width, desired_height;
double rotation;
- int imagemagick_rendermethod;
+ EMACS_INT imagemagick_rendermethod;
int pixelwidth;
ImageInfo *image_info;
ExceptionInfo *exception;
@@ -7602,7 +7615,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
status = MagickPingImageBlob (ping_wand, contents, size);
}
- if (ino >= MagickGetNumberImages (ping_wand))
+ if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
{
image_error ("Invalid image number `%s' in image `%s'",
image, img->spec);
@@ -7677,28 +7690,28 @@ imagemagick_load_image (struct frame *f, struct image *img,
efficient. */
crop = image_spec_value (img->spec, QCcrop, NULL);
- if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
{
/* After some testing, it seems MagickCropImage is the fastest crop
function in ImageMagick. This crop function seems to do less copying
than the alternatives, but it still reads the entire image into memory
- before croping, which is aparently difficult to avoid when using
+ before cropping, which is apparently difficult to avoid when using
imagemagick. */
- int w, h;
- w = XFASTINT (XCAR (crop));
+ size_t crop_width = XINT (XCAR (crop));
crop = XCDR (crop);
- if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
{
- h = XFASTINT (XCAR (crop));
+ size_t crop_height = XINT (XCAR (crop));
crop = XCDR (crop);
- if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
{
- x = XFASTINT (XCAR (crop));
+ ssize_t crop_x = XINT (XCAR (crop));
crop = XCDR (crop);
- if (CONSP (crop) && INTEGERP (XCAR (crop)))
+ if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
{
- y = XFASTINT (XCAR (crop));
- MagickCropImage (image_wand, w, h, x, y);
+ ssize_t crop_y = XINT (XCAR (crop));
+ MagickCropImage (image_wand, crop_width, crop_height,
+ crop_x, crop_y);
}
}
}
@@ -7744,9 +7757,11 @@ imagemagick_load_image (struct frame *f, struct image *img,
init_color_table ();
imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
- ? XFASTINT (Vimagemagick_render_type) : 0);
+ ? XINT (Vimagemagick_render_type) : 0);
if (imagemagick_rendermethod == 0)
{
+ size_t image_height;
+
/* Try to create a x pixmap to hold the imagemagick pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0,
&ximg, &img->pixmap))
@@ -7775,7 +7790,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
goto imagemagick_error;
}
- for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++)
+ image_height = MagickGetImageHeight (image_wand);
+ for (y = 0; y < image_height; y++)
{
pixels = PixelGetNextIteratorRow (iterator, &width);
if (pixels == (PixelWand **) NULL)
@@ -7995,7 +8011,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
{":data", IMAGE_STRING_VALUE, 0},
{":file", IMAGE_STRING_VALUE, 0},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -8281,10 +8297,10 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
{
for (x = 0; x < width; ++x)
{
- unsigned red;
- unsigned green;
- unsigned blue;
- unsigned opacity;
+ int red;
+ int green;
+ int blue;
+ int opacity;
red = *pixels++;
green = *pixels++;
@@ -8390,7 +8406,7 @@ static const struct image_keyword gs_format[GS_LAST] =
{":loader", IMAGE_FUNCTION_VALUE, 0},
{":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
{":ascent", IMAGE_ASCENT_VALUE, 0},
- {":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
+ {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
@@ -8465,7 +8481,8 @@ gs_image_p (Lisp_Object object)
static int
gs_load (struct frame *f, struct image *img)
{
- char buffer[100];
+ uprintmax_t printnum1, printnum2;
+ char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)];
Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
Lisp_Object frame;
double in_width, in_height;
@@ -8477,16 +8494,19 @@ gs_load (struct frame *f, struct image *img)
info. */
pt_width = image_spec_value (img->spec, QCpt_width, NULL);
in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
- img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
+ in_width *= FRAME_X_DISPLAY_INFO (f)->resx;
pt_height = image_spec_value (img->spec, QCpt_height, NULL);
in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
- img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
+ in_height *= FRAME_X_DISPLAY_INFO (f)->resy;
- if (!check_image_size (f, img->width, img->height))
+ if (! (in_width <= INT_MAX && in_height <= INT_MAX
+ && check_image_size (f, in_width, in_height)))
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
return 0;
}
+ img->width = in_width;
+ img->height = in_height;
/* Create the pixmap. */
xassert (img->pixmap == NO_PIXMAP);
@@ -8511,14 +8531,14 @@ gs_load (struct frame *f, struct image *img)
if successful. We do not record_unwind_protect here because
other places in redisplay like calling window scroll functions
don't either. Let the Lisp loader use `unwind-protect' instead. */
- sprintf (buffer, "%lu %lu",
- (unsigned long) FRAME_X_WINDOW (f),
- (unsigned long) img->pixmap);
+ printnum1 = FRAME_X_WINDOW (f);
+ printnum2 = img->pixmap;
+ sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
window_and_pixmap_id = build_string (buffer);
- sprintf (buffer, "%lu %lu",
- FRAME_FOREGROUND_PIXEL (f),
- FRAME_BACKGROUND_PIXEL (f));
+ printnum1 = FRAME_FOREGROUND_PIXEL (f);
+ printnum2 = FRAME_BACKGROUND_PIXEL (f);
+ sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
pixel_colors = build_string (buffer);
XSETFRAME (frame, f);
@@ -8543,7 +8563,8 @@ void
x_kill_gs_process (Pixmap pixmap, struct frame *f)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
- int class, i;
+ int class;
+ ptrdiff_t i;
struct image *img;
/* Find the image containing PIXMAP. */
@@ -8647,7 +8668,7 @@ DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
(Lisp_Object spec)
{
- int id = -1;
+ ptrdiff_t id = -1;
if (valid_image_p (spec))
id = lookup_image (SELECTED_FRAME (), spec);
diff --git a/src/indent.c b/src/indent.c
index aaeaaf591e..313315e908 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -284,7 +284,7 @@ skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Ob
else \
{ \
if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
- width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \
+ width = sanitize_char_width (ASIZE (DISP_CHAR_VECTOR (dp, ch))); \
else \
width = CHAR_WIDTH (ch); \
} \
@@ -318,15 +318,6 @@ invalidate_current_column (void)
last_known_column_point = 0;
}
-/* Return a non-outlandish value for the tab width. */
-
-static int
-sane_tab_width (void)
-{
- EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width));
- return 0 < n && n <= 1000 ? n : 8;
-}
-
EMACS_INT
current_column (void)
{
@@ -335,7 +326,7 @@ current_column (void)
register int tab_seen;
EMACS_INT post_tab;
register int c;
- int tab_width = sane_tab_width ();
+ int tab_width = SANE_TAB_WIDTH (current_buffer);
int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
register struct Lisp_Char_Table *dp = buffer_display_table ();
@@ -515,7 +506,7 @@ check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos)
static void
scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol)
{
- int tab_width = sane_tab_width ();
+ int tab_width = SANE_TAB_WIDTH (current_buffer);
register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
register struct Lisp_Char_Table *dp = buffer_display_table ();
int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
@@ -732,7 +723,7 @@ string_display_width (Lisp_Object string, Lisp_Object beg, Lisp_Object end)
register int tab_seen;
int post_tab;
register int c;
- int tab_width = sane_tab_width ();
+ int tab_width = SANE_TAB_WIDTH (current_buffer);
int ctl_arrow = !NILP (current_buffer->ctl_arrow);
register struct Lisp_Char_Table *dp = buffer_display_table ();
int b, e;
@@ -808,7 +799,7 @@ The return value is COLUMN. */)
{
EMACS_INT mincol;
register EMACS_INT fromcol;
- int tab_width = sane_tab_width ();
+ int tab_width = SANE_TAB_WIDTH (current_buffer);
CHECK_NUMBER (column);
if (NILP (minimum))
@@ -867,7 +858,7 @@ static EMACS_INT
position_indentation (register int pos_byte)
{
register EMACS_INT column = 0;
- int tab_width = sane_tab_width ();
+ int tab_width = SANE_TAB_WIDTH (current_buffer);
register unsigned char *p;
register unsigned char *stop;
unsigned char *start;
@@ -1116,7 +1107,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_
register EMACS_INT pos;
EMACS_INT pos_byte;
register int c = 0;
- int tab_width = sane_tab_width ();
+ int tab_width = SANE_TAB_WIDTH (current_buffer);
register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
register struct Lisp_Char_Table *dp = window_display_table (win);
EMACS_INT selective
@@ -1432,7 +1423,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_
the text character-by-character. */
if (current_buffer->width_run_cache && pos >= next_width_run)
{
- EMACS_INT run_end;
+ ptrdiff_t run_end;
int common_width
= region_cache_forward (current_buffer,
current_buffer->width_run_cache,
@@ -2135,7 +2126,7 @@ whether or not it is currently displayed in some window. */)
}
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
}
if (BUFFERP (old_buffer))
diff --git a/src/keyboard.c b/src/keyboard.c
index 7e144b80a0..ab93e0ccd2 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -44,7 +44,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "process.h"
#include <errno.h>
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
#ifdef MSDOS
@@ -435,16 +435,16 @@ static void (*keyboard_init_hook) (void);
static int read_avail_input (int);
static void get_input_pending (int *, int);
static int readable_events (int);
-static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *,
+static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
Lisp_Object, int *);
-static Lisp_Object read_char_minibuf_menu_prompt (int, int,
+static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
Lisp_Object *);
static Lisp_Object make_lispy_event (struct input_event *);
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
enum scroll_bar_part,
Lisp_Object, Lisp_Object,
- unsigned long);
+ Time);
#endif
static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object,
Lisp_Object, const char *const *,
@@ -1300,7 +1300,7 @@ some_mouse_moved (void)
/* This is the actual command reading loop,
sans error-handling encapsulation. */
-static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object,
+static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
int, int, int);
void safe_run_hooks (Lisp_Object);
static void adjust_point_for_property (EMACS_INT, int);
@@ -2267,7 +2267,8 @@ do { if (polling_stopped_here) start_polling (); \
Value is t if we showed a menu and the user rejected it. */
Lisp_Object
-read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
+read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
+ Lisp_Object prev_event,
int *used_mouse_menu, struct timeval *end_time)
{
volatile Lisp_Object c;
@@ -7405,7 +7406,7 @@ menu_bar_items (Lisp_Object old)
{
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
- int nmaps;
+ ptrdiff_t nmaps;
/* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
in the current keymaps, or nil where it is not a prefix. */
@@ -7413,7 +7414,7 @@ menu_bar_items (Lisp_Object old)
Lisp_Object def, tail;
- int mapno;
+ ptrdiff_t mapno;
Lisp_Object oquit;
/* In order to build the menus, we need to call the keymap
@@ -7458,7 +7459,7 @@ menu_bar_items (Lisp_Object old)
recognized when the menu-bar (or mode-line) is updated,
which does not normally happen after every command. */
Lisp_Object tem;
- int nminor;
+ ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
nmaps = 0;
@@ -7962,7 +7963,7 @@ Lisp_Object
tool_bar_items (Lisp_Object reuse, int *nitems)
{
Lisp_Object *maps;
- int nmaps, i;
+ ptrdiff_t nmaps, i;
Lisp_Object oquit;
Lisp_Object *tmaps;
@@ -8002,7 +8003,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
recognized when the tool-bar (or mode-line) is updated,
which does not normally happen after every command. */
Lisp_Object tem;
- int nminor;
+ ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
nmaps = 0;
@@ -8274,10 +8275,11 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION);
const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : "";
const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
- EMACS_INT max_lbl = 2 * tool_bar_max_label_size;
+ ptrdiff_t max_lbl =
+ 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
char *buf = (char *) xmalloc (max_lbl + 1);
Lisp_Object new_lbl;
- size_t caption_len = strlen (capt);
+ ptrdiff_t caption_len = strlen (capt);
if (caption_len <= max_lbl && capt[0] != '\0')
{
@@ -8290,7 +8292,7 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
if (strlen (label) <= max_lbl && label[0] != '\0')
{
- int j;
+ ptrdiff_t j;
if (label != buf)
strcpy (buf, label);
@@ -8399,10 +8401,10 @@ append_tool_bar_item (void)
and do auto-saving in the inner call of read_char. */
static Lisp_Object
-read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
- int *used_mouse_menu)
+read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
+ Lisp_Object prev_event, int *used_mouse_menu)
{
- int mapno;
+ ptrdiff_t mapno;
if (used_mouse_menu)
*used_mouse_menu = 0;
@@ -8430,7 +8432,7 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
Lisp_Object *realmaps
= (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
Lisp_Object value;
- int nmaps1 = 0;
+ ptrdiff_t nmaps1 = 0;
/* Use the maps that are not nil. */
for (mapno = 0; mapno < nmaps; mapno++)
@@ -8481,17 +8483,18 @@ read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
We make this bigger when necessary, and never free it. */
static char *read_char_minibuf_menu_text;
/* Size of that buffer. */
-static int read_char_minibuf_menu_width;
+static ptrdiff_t read_char_minibuf_menu_width;
static Lisp_Object
-read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
+read_char_minibuf_menu_prompt (int commandflag,
+ ptrdiff_t nmaps, Lisp_Object *maps)
{
- int mapno;
+ ptrdiff_t mapno;
register Lisp_Object name;
- int nlength;
+ ptrdiff_t nlength;
/* FIXME: Use the minibuffer's frame width. */
- int width = FRAME_COLS (SELECTED_FRAME ()) - 4;
- int idx = -1;
+ ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
+ ptrdiff_t idx = -1;
int nobindings = 1;
Lisp_Object rest, vector;
char *menu;
@@ -8516,16 +8519,13 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
/* Make sure we have a big enough buffer for the menu text. */
width = max (width, SBYTES (name));
- if (read_char_minibuf_menu_text == 0)
+ if (STRING_BYTES_BOUND - 4 < width)
+ memory_full (SIZE_MAX);
+ if (width + 4 > read_char_minibuf_menu_width)
{
- read_char_minibuf_menu_width = width + 4;
- read_char_minibuf_menu_text = (char *) xmalloc (width + 4);
- }
- else if (width + 4 > read_char_minibuf_menu_width)
- {
- read_char_minibuf_menu_width = width + 4;
read_char_minibuf_menu_text
= (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
+ read_char_minibuf_menu_width = width + 4;
}
menu = read_char_minibuf_menu_text;
@@ -8544,7 +8544,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
while (1)
{
int notfirst = 0;
- int i = nlength;
+ ptrdiff_t i = nlength;
Lisp_Object obj;
Lisp_Object orig_defn_macro;
@@ -8643,7 +8643,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
< width
|| !notfirst)
{
- int thiswidth;
+ ptrdiff_t thiswidth;
/* Punctuate between strings. */
if (notfirst)
@@ -8659,9 +8659,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
if (! char_matches)
{
/* Add as much of string as fits. */
- thiswidth = SCHARS (desc);
- if (thiswidth + i > width)
- thiswidth = width - i;
+ thiswidth = min (SCHARS (desc), width - i);
memcpy (menu + i, SDATA (desc), thiswidth);
i += thiswidth;
strcpy (menu + i, " = ");
@@ -8669,9 +8667,7 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
}
/* Add as much of string as fits. */
- thiswidth = SCHARS (s);
- if (thiswidth + i > width)
- thiswidth = width - i;
+ thiswidth = min (SCHARS (s), width - i);
memcpy (menu + i, SDATA (s), thiswidth);
i += thiswidth;
menu[i] = 0;
@@ -8746,10 +8742,10 @@ read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
NEXT may be the same array as CURRENT. */
static int
-follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs,
- Lisp_Object *next)
+follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current,
+ Lisp_Object *defs, Lisp_Object *next)
{
- int i, first_binding;
+ ptrdiff_t i, first_binding;
first_binding = nmaps;
for (i = nmaps - 1; i >= 0; i--)
@@ -8849,7 +8845,7 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
The return value is non-zero if the remapping actually took place. */
static int
-keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
+keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
int input, int doit, int *diff, Lisp_Object prompt)
{
Lisp_Object next, key;
@@ -8871,7 +8867,7 @@ keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
*diff = len - (fkey->end - fkey->start);
- if (input + *diff >= bufsize)
+ if (bufsize - input <= *diff)
error ("Key sequence too long");
/* Shift the keys that follow fkey->end. */
@@ -8942,7 +8938,7 @@ keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
from the selected window's buffer. */
static int
-read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
+read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
int dont_downcase_last, int can_return_switch_frame,
int fix_current_buffer)
{
@@ -8959,8 +8955,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
- int nmaps;
- int nmaps_allocated = 0;
+ ptrdiff_t nmaps;
+ ptrdiff_t nmaps_allocated = 0;
/* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
the current keymaps. */
@@ -8984,7 +8980,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
/* The index in submaps[] of the first keymap that has a binding for
this key sequence. In other words, the lowest i such that
submaps[i] is non-nil. */
- int first_binding;
+ ptrdiff_t first_binding;
/* Index of the first key that has no binding.
It is useless to try fkey.start larger than that. */
int first_unbound;
@@ -9145,8 +9141,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
}
else
{
- int nminor;
- int total;
+ ptrdiff_t nminor;
+ ptrdiff_t total;
Lisp_Object *maps;
nminor = current_minor_maps (0, &maps);
@@ -9212,7 +9208,8 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
echo_local_start and keys_local_start allow us to throw away
just one key. */
int echo_local_start IF_LINT (= 0);
- int keys_local_start, local_first_binding;
+ int keys_local_start;
+ ptrdiff_t local_first_binding;
eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
eassert (indec.start <= indec.end);
@@ -9549,7 +9546,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
&& (NILP (fake_prefixed_keys)
|| NILP (Fmemq (key, fake_prefixed_keys))))
{
- if (t + 1 >= bufsize)
+ if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
@@ -9630,7 +9627,7 @@ read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
{
- if (t + 1 >= bufsize)
+ if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
keybuf[t+1] = key;
diff --git a/src/keyboard.h b/src/keyboard.h
index 69c804c873..d4339d0529 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -440,7 +440,7 @@ struct input_event;
extern Lisp_Object parse_modifiers (Lisp_Object);
extern Lisp_Object reorder_modifiers (Lisp_Object);
-extern Lisp_Object read_char (int, int, Lisp_Object *, Lisp_Object,
+extern Lisp_Object read_char (int, ptrdiff_t, Lisp_Object *, Lisp_Object,
int *, EMACS_TIME *);
extern int parse_solitary_modifier (Lisp_Object symbol);
diff --git a/src/keymap.c b/src/keymap.c
index 0169276bef..32b531daac 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -150,17 +150,6 @@ in case you use it as a menu with `x-popup-menu'. */)
return Fcons (Qkeymap, Qnil);
}
-DEFUN ("make-composed-keymap", Fmake_composed_keymap, Smake_composed_keymap,
- 0, MANY, 0,
- doc: /* Construct and return a new keymap composed of KEYMAPS.
-When looking up a key in the returned map, the key is looked in each
-keymap in turn until a binding is found.
-usage: (make-composed-keymap &rest KEYMAPS) */)
- (ptrdiff_t nargs, Lisp_Object *args)
-{
- return Fcons (Qkeymap, Flist (nargs, args));
-}
-
/* This function is used for installing the standard key bindings
at initialization time.
@@ -1216,13 +1205,20 @@ binding KEY to DEF is added at the front of KEYMAP. */)
keymap = get_keymap (cmd, 0, 1);
if (!CONSP (keymap))
- /* We must use Fkey_description rather than just passing key to
- error; key might be a vector, not a string. */
- error ("Key sequence %s starts with non-prefix key %s",
- SDATA (Fkey_description (key, Qnil)),
- SDATA (Fkey_description (Fsubstring (key, make_number (0),
- make_number (idx)),
- Qnil)));
+ {
+ const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized)
+ ? (idx == 0 ? "ESC" : " ESC")
+ : "");
+
+ /* We must use Fkey_description rather than just passing key to
+ error; key might be a vector, not a string. */
+ error ("Key sequence %s starts with non-prefix key %s%s",
+ SDATA (Fkey_description (key, Qnil)),
+ SDATA (Fkey_description (Fsubstring (key, make_number (0),
+ make_number (idx)),
+ Qnil)),
+ trailing_esc);
+ }
}
}
@@ -1403,7 +1399,7 @@ silly_event_symbol_error (Lisp_Object c)
some systems, static gets macro-defined to be the empty string.
Ickypoo. */
static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL;
-static int cmm_size = 0;
+static ptrdiff_t cmm_size = 0;
/* Store a pointer to an array of the currently active minor modes in
*modeptr, a pointer to an array of the keymaps of the currently
@@ -1423,10 +1419,10 @@ static int cmm_size = 0;
loop. Instead, we'll use realloc/malloc and silently truncate the
list, let the key sequence be read, and hope some other piece of
code signals the error. */
-int
+ptrdiff_t
current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
{
- int i = 0;
+ ptrdiff_t i = 0;
int list_number = 0;
Lisp_Object alist, assoc, var, val;
Lisp_Object emulation_alists;
@@ -1469,9 +1465,16 @@ current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
if (i >= cmm_size)
{
- int newsize, allocsize;
+ ptrdiff_t newsize, allocsize;
Lisp_Object *newmodes, *newmaps;
+ /* Check for size calculation overflow. Other code
+ (e.g., read_key_sequence) adds 3 to the count
+ later, so subtract 3 from the limit here. */
+ if (min (PTRDIFF_MAX, SIZE_MAX) / (2 * sizeof *newmodes) - 3
+ < cmm_size)
+ break;
+
newsize = cmm_size == 0 ? 30 : cmm_size * 2;
allocsize = newsize * sizeof *newmodes;
@@ -3754,7 +3757,6 @@ be preferred. */);
defsubr (&Sset_keymap_parent);
defsubr (&Smake_keymap);
defsubr (&Smake_sparse_keymap);
- defsubr (&Smake_composed_keymap);
defsubr (&Smap_keymap_internal);
defsubr (&Smap_keymap);
defsubr (&Scopy_keymap);
diff --git a/src/keymap.h b/src/keymap.h
index 2c826b64e1..ec9d4cadbb 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -38,7 +38,7 @@ extern Lisp_Object get_keymap (Lisp_Object, int, int);
EXFUN (Fset_keymap_parent, 2);
extern int describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object,
const char *, int, int, int, int);
-extern int current_minor_maps (Lisp_Object **, Lisp_Object **);
+extern ptrdiff_t current_minor_maps (Lisp_Object **, Lisp_Object **);
extern void initial_define_key (Lisp_Object, int, const char *);
extern void initial_define_lispy_key (Lisp_Object, const char *, const char *);
extern void syms_of_keymap (void);
diff --git a/src/lisp.h b/src/lisp.h
index 1e141dbb5d..9955511804 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1704,6 +1704,11 @@ typedef struct {
#define NUMBERP(x) (INTEGERP (x) || FLOATP (x))
#define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0)
+#define RANGED_INTEGERP(lo, x, hi) \
+ (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi))
+#define TYPE_RANGED_INTEGERP(type, x) \
+ RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type))
+
#define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x))))
#define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol)
#define MISCP(x) (XTYPE ((x)) == Lisp_Misc)
@@ -2551,6 +2556,7 @@ extern void syms_of_syntax (void);
/* Defined in fns.c */
extern Lisp_Object QCrehash_size, QCrehash_threshold;
+enum { NEXT_ALMOST_PRIME_LIMIT = 11 };
extern EMACS_INT next_almost_prime (EMACS_INT);
extern Lisp_Object larger_vector (Lisp_Object, EMACS_INT, Lisp_Object);
extern void sweep_weak_hash_tables (void);
@@ -2562,8 +2568,8 @@ EMACS_UINT sxhash (Lisp_Object, int);
Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
-EMACS_INT hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
-EMACS_INT hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
+ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
+ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
EMACS_UINT);
void init_weak_hash_tables (void);
extern void init_fns (void);
@@ -2861,6 +2867,7 @@ extern void map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Ob
Lisp_Object, Lisp_Object,
Lisp_Object, struct charset *,
unsigned, unsigned);
+extern Lisp_Object uniprop_table (Lisp_Object);
extern void syms_of_chartab (void);
/* Defined in print.c */
@@ -3568,6 +3575,9 @@ extern int immediate_quit; /* Nonzero means ^G can quit instantly */
extern POINTER_TYPE *xmalloc (size_t);
extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t);
extern void xfree (POINTER_TYPE *);
+extern void *xnmalloc (ptrdiff_t, ptrdiff_t);
+extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
+extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
extern char *xstrdup (const char *);
@@ -3685,6 +3695,23 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object);
} \
} while (0)
+/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
+ NITEMS items, each of the same type as *BUF. MULTIPLIER must
+ positive. The code is tuned for MULTIPLIER being a constant. */
+
+#define SAFE_NALLOCA(buf, multiplier, nitems) \
+ do { \
+ if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \
+ (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \
+ else \
+ { \
+ (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
+ sa_must_free = 1; \
+ record_unwind_protect (safe_alloca_unwind, \
+ make_save_value (buf, 0)); \
+ } \
+ } while (0)
+
/* SAFE_FREE frees xmalloced memory and enables GC as needed. */
#define SAFE_FREE() \
diff --git a/src/lread.c b/src/lread.c
index 78ff195e99..d24da729df 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1124,6 +1124,22 @@ Return t if the file exists and loads successfully. */)
handler = Ffind_file_name_handler (found, Qload);
if (! NILP (handler))
return call5 (handler, Qload, found, noerror, nomessage, Qt);
+#ifdef DOS_NT
+ /* Tramp has to deal with semi-broken packages that prepend
+ drive letters to remote files. For that reason, Tramp
+ catches file operations that test for file existence, which
+ makes openp think X:/foo.elc files are remote. However,
+ Tramp does not catch `load' operations for such files, so we
+ end up with a nil as the `load' handler above. If we would
+ continue with fd = -2, we will behave wrongly, and in
+ particular try reading a .elc file in the "rt" mode instead
+ of "rb". See bug #9311 for the results. To work around
+ this, we try to open the file locally, and go with that if it
+ succeeds. */
+ fd = emacs_open (SSDATA (ENCODE_FILE (found)), O_RDONLY, 0);
+ if (fd == -1)
+ fd = -2;
+#endif
}
/* Check if we're stuck in a recursive load cycle.
@@ -1247,9 +1263,17 @@ Return t if the file exists and loads successfully. */)
GCPRO3 (file, found, hist_file_name);
#ifdef WINDOWSNT
- emacs_close (fd);
efound = ENCODE_FILE (found);
- stream = fopen (SSDATA (efound), fmode);
+ /* If we somehow got here with fd == -2, meaning the file is deemed
+ to be remote, don't even try to reopen the file locally; just
+ force a failure instead. */
+ if (fd >= 0)
+ {
+ emacs_close (fd);
+ stream = fopen (SSDATA (efound), fmode);
+ }
+ else
+ stream = NULL;
#else /* not WINDOWSNT */
stream = fdopen (fd, fmode);
#endif /* not WINDOWSNT */
@@ -2613,14 +2637,14 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
if (saved_doc_string_size == 0)
{
+ saved_doc_string = (char *) xmalloc (nskip + extra);
saved_doc_string_size = nskip + extra;
- saved_doc_string = (char *) xmalloc (saved_doc_string_size);
}
if (nskip > saved_doc_string_size)
{
- saved_doc_string_size = nskip + extra;
saved_doc_string = (char *) xrealloc (saved_doc_string,
- saved_doc_string_size);
+ nskip + extra);
+ saved_doc_string_size = nskip + extra;
}
saved_doc_string_position = file_tell (instream);
@@ -2883,7 +2907,8 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
memory_full (SIZE_MAX);
read_buffer = (char *) xrealloc (read_buffer,
- read_buffer_size *= 2);
+ read_buffer_size * 2);
+ read_buffer_size *= 2;
p = read_buffer + offset;
end = read_buffer + read_buffer_size;
}
@@ -3026,7 +3051,8 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
memory_full (SIZE_MAX);
read_buffer = (char *) xrealloc (read_buffer,
- read_buffer_size *= 2);
+ read_buffer_size * 2);
+ read_buffer_size *= 2;
p = read_buffer + offset;
end = read_buffer + read_buffer_size;
}
@@ -3056,7 +3082,8 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
memory_full (SIZE_MAX);
read_buffer = (char *) xrealloc (read_buffer,
- read_buffer_size *= 2);
+ read_buffer_size * 2);
+ read_buffer_size *= 2;
p = read_buffer + offset;
end = read_buffer + read_buffer_size;
}
@@ -3938,6 +3965,7 @@ void
init_obarray (void)
{
Lisp_Object oblength;
+ ptrdiff_t size = 100 + MAX_MULTIBYTE_LENGTH;
XSETFASTINT (oblength, OBARRAY_SIZE);
@@ -3970,8 +3998,8 @@ init_obarray (void)
DEFSYM (Qvariable_documentation, "variable-documentation");
- read_buffer_size = 100 + MAX_MULTIBYTE_LENGTH;
- read_buffer = (char *) xmalloc (read_buffer_size);
+ read_buffer = (char *) xmalloc (size);
+ read_buffer_size = size;
}
void
diff --git a/src/macros.c b/src/macros.c
index 60f30c3fbb..f6cd3a3cca 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -62,9 +62,9 @@ macro before appending to it. */)
if (!current_kboard->kbd_macro_buffer)
{
- current_kboard->kbd_macro_bufsize = 30;
current_kboard->kbd_macro_buffer
= (Lisp_Object *)xmalloc (30 * sizeof (Lisp_Object));
+ current_kboard->kbd_macro_bufsize = 30;
}
update_mode_lines++;
if (NILP (append))
@@ -202,7 +202,7 @@ store_kbd_macro_char (Lisp_Object c)
if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *kb->kbd_macro_buffer / 2
< kb->kbd_macro_bufsize)
memory_full (SIZE_MAX);
- nbytes = kb->kbd_macro_bufsize * 2 * sizeof *kb->kbd_macro_buffer;
+ nbytes = kb->kbd_macro_bufsize * (2 * sizeof *kb->kbd_macro_buffer);
kb->kbd_macro_buffer
= (Lisp_Object *) xrealloc (kb->kbd_macro_buffer, nbytes);
kb->kbd_macro_bufsize *= 2;
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index fd29dec909..53cb5f857a 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -469,6 +469,7 @@ $(BLD)/alloc.$(O) : \
$(SRC)/syssignal.h \
$(SRC)/w32.h \
$(NT_INC)/unistd.h \
+ $(GNU_LIB)/verify.h \
$(BLOCKINPUT_H) \
$(CHARACTER_H) \
$(CONFIG_H) \
@@ -493,8 +494,6 @@ $(BLD)/atimer.$(O) : \
$(BLD)/bidi.$(O) : \
$(SRC)/bidi.c \
- $(SRC)/bidimirror.h \
- $(SRC)/biditype.h \
$(SRC)/buffer.h \
$(CHARACTER_H) \
$(CONFIG_H) \
diff --git a/src/minibuf.c b/src/minibuf.c
index 7e59cf157b..eb564a10ec 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1723,7 +1723,7 @@ the values STRING, PREDICATE and `lambda'. */)
(Lisp_Object string, Lisp_Object collection, Lisp_Object predicate)
{
Lisp_Object regexps, tail, tem = Qnil;
- EMACS_INT i = 0;
+ ptrdiff_t i = 0;
CHECK_STRING (string);
diff --git a/src/nsfns.m b/src/nsfns.m
index 85246a4c25..a09011d846 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -97,6 +97,9 @@ Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
extern BOOL ns_in_resize;
+/* Static variables to handle applescript execution. */
+static Lisp_Object as_script, *as_result;
+static int as_status;
/* ==========================================================================
@@ -2052,6 +2055,15 @@ ns_do_applescript (Lisp_Object script, Lisp_Object *result)
return 0;
}
+/* Helper function called from sendEvent to run applescript
+ from within the main event loop. */
+
+void
+ns_run_ascript (void)
+{
+ as_status = ns_do_applescript (as_script, as_result);
+}
+
DEFUN ("ns-do-applescript", Fns_do_applescript, Sns_do_applescript, 1, 1, 0,
doc: /* Execute AppleScript SCRIPT and return the result.
If compilation and execution are successful, the resulting script value
@@ -2061,12 +2073,37 @@ In case the execution fails, an error is signaled. */)
{
Lisp_Object result;
int status;
+ NSEvent *nxev;
CHECK_STRING (script);
check_ns ();
BLOCK_INPUT;
- status = ns_do_applescript (script, &result);
+
+ as_script = script;
+ as_result = &result;
+
+ /* executing apple script requires the event loop to run, otherwise
+ errors aren't returned and executeAndReturnError hangs forever.
+ Post an event that runs applescript and then start the event loop.
+ The event loop is exited when the script is done. */
+ nxev = [NSEvent otherEventWithType: NSApplicationDefined
+ location: NSMakePoint (0, 0)
+ modifierFlags: 0
+ timestamp: 0
+ windowNumber: [[NSApp mainWindow] windowNumber]
+ context: [NSApp context]
+ subtype: 0
+ data1: 0
+ data2: NSAPP_DATA2_RUNASSCRIPT];
+
+ [NSApp postEvent: nxev atStart: NO];
+ [NSApp run];
+
+ status = as_status;
+ as_status = 0;
+ as_script = Qnil;
+ as_result = 0;
UNBLOCK_INPUT;
if (status == 0)
return result;
@@ -2670,4 +2707,7 @@ be used as the image of the icon representing the frame. */);
/* used only in fontset.c */
check_window_system_func = check_ns;
+ as_status = 0;
+ as_script = Qnil;
+ as_result = 0;
}
diff --git a/src/nsfont.m b/src/nsfont.m
index 60f8c5321a..c4d9123fae 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -303,7 +303,7 @@ static NSString
{
Lisp_Object script = assq_no_quit (XCAR (otf), Votf_script_alist);
return CONSP (script)
- ? [NSString stringWithUTF8String: SDATA (SYMBOL_NAME XCDR ((script)))]
+ ? [NSString stringWithUTF8String: SDATA (SYMBOL_NAME (XCDR ((script))))]
: @"";
}
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 6bde229ed4..951282910a 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1014,7 +1014,7 @@ update_frame_tool_bar (FRAME_PTR f)
BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P));
BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P));
int idx;
- int img_id;
+ ptrdiff_t img_id;
struct image *img;
Lisp_Object image;
Lisp_Object helpObj;
diff --git a/src/nsterm.h b/src/nsterm.h
index 6ea9161c92..188ec732e8 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -416,8 +416,8 @@ struct ns_bitmap_record
/* this to map between emacs color indices and NSColor objects */
struct ns_color_table
{
- unsigned int size;
- unsigned int avail;
+ ptrdiff_t size;
+ ptrdiff_t avail;
#ifdef __OBJC__
NSColor **colors;
NSMutableSet *empty_indices;
@@ -795,6 +795,9 @@ extern void x_set_tool_bar_lines (struct frame *f,
extern void x_activate_menubar (struct frame *);
extern void free_frame_menubar (struct frame *);
+#define NSAPP_DATA2_RUNASSCRIPT 10
+extern void ns_run_ascript (void);
+
extern void ns_init_paths (void);
extern void syms_of_nsterm (void);
extern void syms_of_nsfns (void);
diff --git a/src/nsterm.m b/src/nsterm.m
index d4b1a3f847..4c9574c35b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1341,7 +1341,7 @@ unsigned long
ns_index_color (NSColor *color, struct frame *f)
{
struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table;
- int idx;
+ ptrdiff_t idx;
NSNumber *index;
if (!color_table->colors)
@@ -1356,7 +1356,7 @@ ns_index_color (NSColor *color, struct frame *f)
/* do we already have this color ? */
{
- int i;
+ ptrdiff_t i;
for (i = 1; i < color_table->avail; i++)
{
if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
@@ -1371,17 +1371,14 @@ ns_index_color (NSColor *color, struct frame *f)
{
index = [color_table->empty_indices anyObject];
[color_table->empty_indices removeObject: index];
- idx = [index unsignedIntValue];
+ idx = [index unsignedLongValue];
}
else
{
if (color_table->avail == color_table->size)
- {
- color_table->size += NS_COLOR_CAPACITY;
- color_table->colors
- = (NSColor **)xrealloc (color_table->colors,
- color_table->size * sizeof (NSColor *));
- }
+ color_table->colors =
+ xpalloc (color_table->colors, &color_table->size, 1,
+ min (ULONG_MAX, PTRDIFF_MAX), sizeof *color_table->colors);
idx = color_table->avail++;
}
@@ -2321,7 +2318,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
if (!img)
{
unsigned short *bits = p->bits + p->dh;
- int len = 8 * p->h/8;
+ int len = p->h;
int i;
unsigned char *cbits = xmalloc (len);
@@ -4257,6 +4254,16 @@ ns_term_shutdown (int sig)
/* NSTRACE (sendEvent); */
/*fprintf (stderr, "received event of type %d\t%d\n", type);*/
+#ifdef NS_IMPL_COCOA
+ if (type == NSApplicationDefined
+ && [theEvent data2] == NSAPP_DATA2_RUNASSCRIPT)
+ {
+ ns_run_ascript ();
+ [self stop: self];
+ return;
+ }
+#endif
+
if (type == NSCursorUpdate && window == nil)
{
fprintf (stderr, "Dropping external cursor update event.\n");
@@ -4857,7 +4864,7 @@ ns_term_shutdown (int sig)
}
}
-
+
#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
/* if we get here we should send the key for input manager processing */
if (firstTime && [[NSInputManager currentInputManager]
diff --git a/src/process.c b/src/process.c
index 236c27e5c3..a808832214 100644
--- a/src/process.c
+++ b/src/process.c
@@ -58,6 +58,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <net/if.h>
#endif /* HAVE_NET_IF_H */
+#if defined(HAVE_IFADDRS_H)
+/* Must be after net/if.h */
+#include <ifaddrs.h>
+
+/* We only use structs from this header when we use getifaddrs. */
+#if defined(HAVE_NET_IF_DL_H)
+#include <net/if_dl.h>
+#endif
+
+#endif
+
#ifdef NEED_BSDTTY
#include <bsdtty.h>
#endif
@@ -1632,7 +1643,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
XPROCESS (process)->pty_flag = pty_flag;
XPROCESS (process)->status = Qrun;
- setup_process_coding_systems (process);
/* Delay interrupts until we have a chance to store
the new fork's pid in its process structure */
@@ -1667,6 +1677,10 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
processes to get their return values scrambled. */
XPROCESS (process)->pid = -1;
+ /* This must be called after the above line because it may signal an
+ error. */
+ setup_process_coding_systems (process);
+
BLOCK_INPUT;
{
@@ -3557,46 +3571,53 @@ format; see the description of ADDRESS in `make-network-process'. */)
(void)
{
struct ifconf ifconf;
- struct ifreq *ifreqs = NULL;
- int ifaces = 0;
- int buf_size, s;
+ struct ifreq *ifreq;
+ void *buf = NULL;
+ ptrdiff_t buf_size = 512;
+ int s, i;
Lisp_Object res;
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0)
return Qnil;
- again:
- ifaces += 25;
- buf_size = ifaces * sizeof (ifreqs[0]);
- ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size);
- if (!ifreqs)
+ do
{
- close (s);
- return Qnil;
- }
-
- ifconf.ifc_len = buf_size;
- ifconf.ifc_req = ifreqs;
- if (ioctl (s, SIOCGIFCONF, &ifconf))
- {
- close (s);
- return Qnil;
+ buf = xpalloc (buf, &buf_size, 1, INT_MAX, 1);
+ ifconf.ifc_buf = buf;
+ ifconf.ifc_len = buf_size;
+ if (ioctl (s, SIOCGIFCONF, &ifconf))
+ {
+ close (s);
+ xfree (buf);
+ return Qnil;
+ }
}
-
- if (ifconf.ifc_len == buf_size)
- goto again;
+ while (ifconf.ifc_len == buf_size);
close (s);
- ifaces = ifconf.ifc_len / sizeof (ifreqs[0]);
res = Qnil;
- while (--ifaces >= 0)
+ ifreq = ifconf.ifc_req;
+ while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len)
{
- struct ifreq *ifq = &ifreqs[ifaces];
+ struct ifreq *ifq = ifreq;
+#ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN
+#define SIZEOF_IFREQ(sif) \
+ ((sif)->ifr_addr.sa_len < sizeof (struct sockaddr) \
+ ? sizeof (*(sif)) : sizeof ((sif)->ifr_name) + (sif)->ifr_addr.sa_len)
+
+ int len = SIZEOF_IFREQ (ifq);
+#else
+ int len = sizeof (*ifreq);
+#endif
char namebuf[sizeof (ifq->ifr_name) + 1];
+ i += len;
+ ifreq = (struct ifreq *) ((char *) ifreq + len);
+
if (ifq->ifr_addr.sa_family != AF_INET)
continue;
+
memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name));
namebuf[sizeof (ifq->ifr_name)] = 0;
res = Fcons (Fcons (build_string (namebuf),
@@ -3605,6 +3626,7 @@ format; see the description of ADDRESS in `make-network-process'. */)
res);
}
+ xfree (buf);
return res;
}
#endif /* SIOCGIFCONF */
@@ -3642,8 +3664,13 @@ static const struct ifflag_def ifflag_table[] = {
{ IFF_PROMISC, "promisc" },
#endif
#ifdef IFF_NOTRAILERS
+#ifdef NS_IMPL_COCOA
+ /* Really means smart, notrailers is obsolete */
+ { IFF_NOTRAILERS, "smart" },
+#else
{ IFF_NOTRAILERS, "notrailers" },
#endif
+#endif
#ifdef IFF_ALLMULTI
{ IFF_ALLMULTI, "allmulti" },
#endif
@@ -3696,6 +3723,10 @@ FLAGS is the current flags of the interface. */)
Lisp_Object elt;
int s;
int any = 0;
+#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
+ && defined HAVE_GETIFADDRS && defined LLADDR)
+ struct ifaddrs *ifap;
+#endif
CHECK_STRING (ifname);
@@ -3714,6 +3745,12 @@ FLAGS is the current flags of the interface. */)
const struct ifflag_def *fp;
int fnum;
+ /* If flags is smaller than int (i.e. short) it may have the high bit set
+ due to IFF_MULTICAST. In that case, sign extending it into
+ an int is wrong. */
+ if (flags < 0 && sizeof (rq.ifr_flags) < sizeof (flags))
+ flags = (unsigned short) rq.ifr_flags;
+
any = 1;
for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++)
{
@@ -3747,7 +3784,38 @@ FLAGS is the current flags of the interface. */)
p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]);
elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr);
}
+#elif defined(HAVE_GETIFADDRS) && defined(LLADDR)
+ if (getifaddrs (&ifap) != -1)
+ {
+ Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil);
+ register struct Lisp_Vector *p = XVECTOR (hwaddr);
+ struct ifaddrs *it;
+
+ for (it = ifap; it != NULL; it = it->ifa_next)
+ {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl*) it->ifa_addr;
+ unsigned char linkaddr[6];
+ int n;
+
+ if (it->ifa_addr->sa_family != AF_LINK
+ || strcmp (it->ifa_name, SSDATA (ifname)) != 0
+ || sdl->sdl_alen != 6)
+ continue;
+
+ memcpy (linkaddr, LLADDR(sdl), sdl->sdl_alen);
+ for (n = 0; n < 6; n++)
+ p->contents[n] = make_number (linkaddr[n]);
+
+ elt = Fcons (make_number (it->ifa_addr->sa_family), hwaddr);
+ break;
+ }
+ }
+#ifdef HAVE_FREEIFADDRS
+ freeifaddrs (ifap);
#endif
+
+#endif /* HAVE_GETIFADDRS && LLADDR */
+
res = Fcons (elt, res);
elt = Qnil;
@@ -5093,6 +5161,9 @@ read_process_output (Lisp_Object proc, register int channel)
p->decoding_carryover = coding->carryover_bytes;
}
if (SBYTES (text) > 0)
+ /* FIXME: It's wrong to wrap or not based on debug-on-error, and
+ sometimes it's simply wrong to wrap (e.g. when called from
+ accept-process-output). */
internal_condition_case_1 (read_process_output_call,
Fcons (outstream,
Fcons (proc, Fcons (text, Qnil))),
diff --git a/src/regex.c b/src/regex.c
index 862f848976..d1b835621d 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -2106,9 +2106,9 @@ re_iswctype (int ch, re_wctype_t cc)
case RECC_UPPER: return ISUPPER (ch) != 0;
case RECC_XDIGIT: return ISXDIGIT (ch) != 0;
case RECC_ASCII: return IS_REAL_ASCII (ch) != 0;
- case RECC_NONASCII: return !IS_REAL_ASCII (ch) != 0;
+ case RECC_NONASCII: return !IS_REAL_ASCII (ch);
case RECC_UNIBYTE: return ISUNIBYTE (ch) != 0;
- case RECC_MULTIBYTE: return !ISUNIBYTE (ch) != 0;
+ case RECC_MULTIBYTE: return !ISUNIBYTE (ch);
case RECC_WORD: return ISWORD (ch) != 0;
case RECC_ERROR: return false;
default:
@@ -6381,8 +6381,7 @@ char *
regcomp/regexec below without link errors. */
weak_function
# endif
-re_comp (s)
- const char *s;
+re_comp (const char *s)
{
reg_errcode_t ret;
@@ -6421,7 +6420,7 @@ re_comp (s)
}
-regoff_t
+int
# ifdef _LIBC
weak_function
# endif
@@ -6558,7 +6557,7 @@ reg_errcode_t
regexec (const regex_t *__restrict preg, const char *__restrict string,
size_t nmatch, regmatch_t pmatch[__restrict_arr], int eflags)
{
- reg_errcode_t ret;
+ regoff_t ret;
struct re_registers regs;
regex_t private_preg;
size_t len = strlen (string);
diff --git a/src/region-cache.c b/src/region-cache.c
index d701f4d71b..ed7a07a670 100644
--- a/src/region-cache.c
+++ b/src/region-cache.c
@@ -63,7 +63,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
revalidate_region_cache to see how this helps. */
struct boundary {
- EMACS_INT pos;
+ ptrdiff_t pos;
int value;
};
@@ -73,16 +73,16 @@ struct region_cache {
struct boundary *boundaries;
/* boundaries[gap_start ... gap_start + gap_len - 1] is the gap. */
- EMACS_INT gap_start, gap_len;
+ ptrdiff_t gap_start, gap_len;
/* The number of elements allocated to boundaries, not including the
gap. */
- EMACS_INT cache_len;
+ ptrdiff_t cache_len;
/* The areas that haven't changed since the last time we cleaned out
invalid entries from the cache. These overlap when the buffer is
entirely unchanged. */
- EMACS_INT beg_unchanged, end_unchanged;
+ ptrdiff_t beg_unchanged, end_unchanged;
/* The first and last positions in the buffer. Because boundaries
store their positions relative to the start (BEG) and end (Z) of
@@ -92,7 +92,7 @@ struct region_cache {
Yes, buffer_beg is always 1. It's there for symmetry with
buffer_end and the BEG and BUF_BEG macros. */
- EMACS_INT buffer_beg, buffer_end;
+ ptrdiff_t buffer_beg, buffer_end;
};
/* Return the position of boundary i in cache c. */
@@ -173,17 +173,17 @@ free_region_cache (struct region_cache *c)
This operation should be logarithmic in the number of cache
entries. It would be nice if it took advantage of locality of
reference, too, by searching entries near the last entry found. */
-static EMACS_INT
-find_cache_boundary (struct region_cache *c, EMACS_INT pos)
+static ptrdiff_t
+find_cache_boundary (struct region_cache *c, ptrdiff_t pos)
{
- EMACS_INT low = 0, high = c->cache_len;
+ ptrdiff_t low = 0, high = c->cache_len;
while (low + 1 < high)
{
/* mid is always a valid index, because low < high and ">> 1"
rounds down. */
- EMACS_INT mid = (low + high) >> 1;
- EMACS_INT boundary = BOUNDARY_POS (c, mid);
+ ptrdiff_t mid = (low >> 1) + (high >> 1) + (low & high & 1);
+ ptrdiff_t boundary = BOUNDARY_POS (c, mid);
if (pos < boundary)
high = mid;
@@ -208,13 +208,13 @@ find_cache_boundary (struct region_cache *c, EMACS_INT pos)
/* Move the gap of cache C to index POS, and make sure it has space
for at least MIN_SIZE boundaries. */
static void
-move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
+move_cache_gap (struct region_cache *c, ptrdiff_t pos, ptrdiff_t min_size)
{
/* Copy these out of the cache and into registers. */
- EMACS_INT gap_start = c->gap_start;
- EMACS_INT gap_len = c->gap_len;
- EMACS_INT buffer_beg = c->buffer_beg;
- EMACS_INT buffer_end = c->buffer_end;
+ ptrdiff_t gap_start = c->gap_start;
+ ptrdiff_t gap_len = c->gap_len;
+ ptrdiff_t buffer_beg = c->buffer_beg;
+ ptrdiff_t buffer_end = c->buffer_end;
if (pos < 0
|| pos > c->cache_len)
@@ -246,17 +246,11 @@ move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
when the portion after the gap is smallest. */
if (gap_len < min_size)
{
- EMACS_INT i;
-
- /* Always make at least NEW_CACHE_GAP elements, as long as we're
- expanding anyway. */
- if (min_size < NEW_CACHE_GAP)
- min_size = NEW_CACHE_GAP;
+ ptrdiff_t i;
c->boundaries =
- (struct boundary *) xrealloc (c->boundaries,
- ((min_size + c->cache_len)
- * sizeof (*c->boundaries)));
+ xpalloc (c->boundaries, &c->cache_len, min_size, -1,
+ sizeof *c->boundaries);
/* Some systems don't provide a version of the copy routine that
can be trusted to shift memory upward into an overlapping
@@ -293,7 +287,7 @@ move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
/* Insert a new boundary in cache C; it will have cache index I,
and have the specified POS and VALUE. */
static void
-insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos,
+insert_cache_boundary (struct region_cache *c, ptrdiff_t i, ptrdiff_t pos,
int value)
{
/* i must be a valid cache index. */
@@ -331,9 +325,9 @@ insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos,
static void
delete_cache_boundaries (struct region_cache *c,
- EMACS_INT start, EMACS_INT end)
+ ptrdiff_t start, ptrdiff_t end)
{
- EMACS_INT len = end - start;
+ ptrdiff_t len = end - start;
/* Gotta be in range. */
if (start < 0
@@ -384,7 +378,7 @@ delete_cache_boundaries (struct region_cache *c,
/* Set the value in cache C for the region START..END to VALUE. */
static void
set_cache_region (struct region_cache *c,
- EMACS_INT start, EMACS_INT end, int value)
+ ptrdiff_t start, ptrdiff_t end, int value)
{
if (start > end)
abort ();
@@ -407,8 +401,8 @@ set_cache_region (struct region_cache *c,
index of the earliest boundary after the last character in
start..end. (This tortured terminology is intended to answer
all the "< or <=?" sort of questions.) */
- EMACS_INT start_ix = find_cache_boundary (c, start);
- EMACS_INT end_ix = find_cache_boundary (c, end - 1) + 1;
+ ptrdiff_t start_ix = find_cache_boundary (c, start);
+ ptrdiff_t end_ix = find_cache_boundary (c, end - 1) + 1;
/* We must remember the value established by the last boundary
before end; if that boundary's domain stretches beyond end,
@@ -486,7 +480,7 @@ set_cache_region (struct region_cache *c,
args to pass are the same before and after such an operation.) */
void
invalidate_region_cache (struct buffer *buf, struct region_cache *c,
- EMACS_INT head, EMACS_INT tail)
+ ptrdiff_t head, ptrdiff_t tail)
{
/* Let chead = c->beg_unchanged, and
ctail = c->end_unchanged.
@@ -624,7 +618,7 @@ revalidate_region_cache (struct buffer *buf, struct region_cache *c)
corresponds to the modified region of the buffer. */
else
{
- EMACS_INT modified_ix;
+ ptrdiff_t modified_ix;
/* These positions are correct, relative to both the cache basis
and the buffer basis. */
@@ -693,7 +687,7 @@ revalidate_region_cache (struct buffer *buf, struct region_cache *c)
no newlines", in the case of the line cache). */
void
know_region_cache (struct buffer *buf, struct region_cache *c,
- EMACS_INT start, EMACS_INT end)
+ ptrdiff_t start, ptrdiff_t end)
{
revalidate_region_cache (buf, c);
@@ -708,14 +702,14 @@ know_region_cache (struct buffer *buf, struct region_cache *c,
position after POS where the knownness changes. */
int
region_cache_forward (struct buffer *buf, struct region_cache *c,
- EMACS_INT pos, EMACS_INT *next)
+ ptrdiff_t pos, ptrdiff_t *next)
{
revalidate_region_cache (buf, c);
{
- EMACS_INT i = find_cache_boundary (c, pos);
+ ptrdiff_t i = find_cache_boundary (c, pos);
int i_value = BOUNDARY_VALUE (c, i);
- EMACS_INT j;
+ ptrdiff_t j;
/* Beyond the end of the buffer is unknown, by definition. */
if (pos >= BUF_Z (buf))
@@ -744,7 +738,7 @@ region_cache_forward (struct buffer *buf, struct region_cache *c,
the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest
position before POS where the knownness changes. */
int region_cache_backward (struct buffer *buf, struct region_cache *c,
- EMACS_INT pos, EMACS_INT *next)
+ ptrdiff_t pos, ptrdiff_t *next)
{
revalidate_region_cache (buf, c);
@@ -757,9 +751,9 @@ int region_cache_backward (struct buffer *buf, struct region_cache *c,
}
{
- EMACS_INT i = find_cache_boundary (c, pos - 1);
+ ptrdiff_t i = find_cache_boundary (c, pos - 1);
int i_value = BOUNDARY_VALUE (c, i);
- EMACS_INT j;
+ ptrdiff_t j;
if (next)
{
@@ -785,18 +779,18 @@ void pp_cache (struct region_cache *) EXTERNALLY_VISIBLE;
void
pp_cache (struct region_cache *c)
{
- int i;
- EMACS_INT beg_u = c->buffer_beg + c->beg_unchanged;
- EMACS_INT end_u = c->buffer_end - c->end_unchanged;
+ ptrdiff_t i;
+ ptrdiff_t beg_u = c->buffer_beg + c->beg_unchanged;
+ ptrdiff_t end_u = c->buffer_end - c->end_unchanged;
fprintf (stderr,
- "basis: %"pI"d..%"pI"d modified: %"pI"d..%"pI"d\n",
+ "basis: %"pD"d..%"pD"d modified: %"pD"d..%"pD"d\n",
c->buffer_beg, c->buffer_end,
beg_u, end_u);
for (i = 0; i < c->cache_len; i++)
{
- EMACS_INT pos = BOUNDARY_POS (c, i);
+ ptrdiff_t pos = BOUNDARY_POS (c, i);
putc (((pos < beg_u) ? 'v'
: (pos == beg_u) ? '-'
@@ -806,6 +800,6 @@ pp_cache (struct region_cache *c)
: (pos == end_u) ? '-'
: ' '),
stderr);
- fprintf (stderr, "%"pI"d : %d\n", pos, BOUNDARY_VALUE (c, i));
+ fprintf (stderr, "%"pD"d : %d\n", pos, BOUNDARY_VALUE (c, i));
}
}
diff --git a/src/region-cache.h b/src/region-cache.h
index ea767ed0dc..8e1be71677 100644
--- a/src/region-cache.h
+++ b/src/region-cache.h
@@ -72,7 +72,7 @@ void free_region_cache (struct region_cache *);
no newlines", in the case of the line cache). */
extern void know_region_cache (struct buffer *BUF,
struct region_cache *CACHE,
- EMACS_INT START, EMACS_INT END);
+ ptrdiff_t START, ptrdiff_t END);
/* Indicate that a section of BUF has changed, to invalidate CACHE.
HEAD is the number of chars unchanged at the beginning of the buffer.
@@ -84,7 +84,7 @@ extern void know_region_cache (struct buffer *BUF,
args to pass are the same before and after such an operation.) */
extern void invalidate_region_cache (struct buffer *BUF,
struct region_cache *CACHE,
- EMACS_INT HEAD, EMACS_INT TAIL);
+ ptrdiff_t HEAD, ptrdiff_t TAIL);
/* The scanning functions.
@@ -100,13 +100,13 @@ extern void invalidate_region_cache (struct buffer *BUF,
position after POS where the knownness changes. */
extern int region_cache_forward (struct buffer *BUF,
struct region_cache *CACHE,
- EMACS_INT POS,
- EMACS_INT *NEXT);
+ ptrdiff_t POS,
+ ptrdiff_t *NEXT);
/* Return true if the text immediately before POS in BUF is known, for
the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest
position before POS where the knownness changes. */
extern int region_cache_backward (struct buffer *BUF,
struct region_cache *CACHE,
- EMACS_INT POS,
- EMACS_INT *NEXT);
+ ptrdiff_t POS,
+ ptrdiff_t *NEXT);
diff --git a/src/scroll.c b/src/scroll.c
index 6291936a54..05f6fdf85f 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -969,32 +969,14 @@ do_line_insertion_deletion_costs (FRAME_PTR frame,
const char *cleanup_string,
int coefficient)
{
- if (FRAME_INSERT_COST (frame) != 0)
- {
- FRAME_INSERT_COST (frame) =
- (int *) xrealloc (FRAME_INSERT_COST (frame),
- FRAME_LINES (frame) * sizeof (int));
- FRAME_DELETEN_COST (frame) =
- (int *) xrealloc (FRAME_DELETEN_COST (frame),
- FRAME_LINES (frame) * sizeof (int));
- FRAME_INSERTN_COST (frame) =
- (int *) xrealloc (FRAME_INSERTN_COST (frame),
- FRAME_LINES (frame) * sizeof (int));
- FRAME_DELETE_COST (frame) =
- (int *) xrealloc (FRAME_DELETE_COST (frame),
- FRAME_LINES (frame) * sizeof (int));
- }
- else
- {
- FRAME_INSERT_COST (frame) =
- (int *) xmalloc (FRAME_LINES (frame) * sizeof (int));
- FRAME_DELETEN_COST (frame) =
- (int *) xmalloc (FRAME_LINES (frame) * sizeof (int));
- FRAME_INSERTN_COST (frame) =
- (int *) xmalloc (FRAME_LINES (frame) * sizeof (int));
- FRAME_DELETE_COST (frame) =
- (int *) xmalloc (FRAME_LINES (frame) * sizeof (int));
- }
+ FRAME_INSERT_COST (frame) =
+ xnrealloc (FRAME_INSERT_COST (frame), FRAME_LINES (frame), sizeof (int));
+ FRAME_DELETEN_COST (frame) =
+ xnrealloc (FRAME_DELETEN_COST (frame), FRAME_LINES (frame), sizeof (int));
+ FRAME_INSERTN_COST (frame) =
+ xnrealloc (FRAME_INSERTN_COST (frame), FRAME_LINES (frame), sizeof (int));
+ FRAME_DELETE_COST (frame) =
+ xnrealloc (FRAME_DELETE_COST (frame), FRAME_LINES (frame), sizeof (int));
ins_del_costs (frame,
ins_line_string, multi_ins_string,
diff --git a/src/search.c b/src/search.c
index a56df784cd..d892792cba 100644
--- a/src/search.c
+++ b/src/search.c
@@ -683,7 +683,7 @@ scan_buffer (register int target, EMACS_INT start, EMACS_INT end,
to see where we can avoid some scanning. */
if (target == '\n' && newline_cache)
{
- EMACS_INT next_change;
+ ptrdiff_t next_change;
immediate_quit = 0;
while (region_cache_forward
(current_buffer, newline_cache, start_byte, &next_change))
@@ -755,7 +755,7 @@ scan_buffer (register int target, EMACS_INT start, EMACS_INT end,
/* Consult the newline cache, if appropriate. */
if (target == '\n' && newline_cache)
{
- EMACS_INT next_change;
+ ptrdiff_t next_change;
immediate_quit = 0;
while (region_cache_backward
(current_buffer, newline_cache, start_byte, &next_change))
@@ -2640,15 +2640,17 @@ since only regular expressions have distinguished subexpressions. */)
perform substitution on the replacement string. */
if (NILP (literal))
{
- EMACS_INT length = SBYTES (newtext);
+ ptrdiff_t length = SBYTES (newtext);
unsigned char *substed;
- EMACS_INT substed_alloc_size, substed_len;
+ ptrdiff_t substed_alloc_size, substed_len;
int buf_multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
int str_multibyte = STRING_MULTIBYTE (newtext);
int really_changed = 0;
- substed_alloc_size = length * 2 + 100;
- substed = (unsigned char *) xmalloc (substed_alloc_size + 1);
+ substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length
+ ? STRING_BYTES_BOUND
+ : length * 2 + 100);
+ substed = (unsigned char *) xmalloc (substed_alloc_size);
substed_len = 0;
/* Go thru NEWTEXT, producing the actual text to insert in
@@ -2659,7 +2661,7 @@ since only regular expressions have distinguished subexpressions. */)
{
unsigned char str[MAX_MULTIBYTE_LENGTH];
const unsigned char *add_stuff = NULL;
- EMACS_INT add_len = 0;
+ ptrdiff_t add_len = 0;
int idx = -1;
if (str_multibyte)
@@ -2723,7 +2725,7 @@ since only regular expressions have distinguished subexpressions. */)
set up ADD_STUFF and ADD_LEN to point to it. */
if (idx >= 0)
{
- EMACS_INT begbyte = CHAR_TO_BYTE (search_regs.start[idx]);
+ ptrdiff_t begbyte = CHAR_TO_BYTE (search_regs.start[idx]);
add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte;
if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx])
move_gap (search_regs.start[idx]);
@@ -2734,12 +2736,11 @@ since only regular expressions have distinguished subexpressions. */)
is invariably ADD_LEN bytes starting at ADD_STUFF. */
/* Make sure SUBSTED is big enough. */
- if (substed_len + add_len >= substed_alloc_size)
- {
- substed_alloc_size = substed_len + add_len + 500;
- substed = (unsigned char *) xrealloc (substed,
- substed_alloc_size + 1);
- }
+ if (substed_alloc_size - substed_len < add_len)
+ substed =
+ xpalloc (substed, &substed_alloc_size,
+ add_len - (substed_alloc_size - substed_len),
+ STRING_BYTES_BOUND, 1);
/* Now add to the end of SUBSTED. */
if (add_stuff)
@@ -2973,7 +2974,7 @@ LIST should have been created by calling `match-data' previously.
If optional arg RESEAT is non-nil, make markers on LIST point nowhere. */)
(register Lisp_Object list, Lisp_Object reseat)
{
- register int i;
+ ptrdiff_t i;
register Lisp_Object marker;
if (running_asynch_code)
@@ -2987,31 +2988,21 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere. */)
/* Allocate registers if they don't already exist. */
{
- int length = XFASTINT (Flength (list)) / 2;
+ ptrdiff_t length = XFASTINT (Flength (list)) / 2;
if (length > search_regs.num_regs)
{
- if (search_regs.num_regs == 0)
- {
- search_regs.start
- = (regoff_t *) xmalloc (length * sizeof (regoff_t));
- search_regs.end
- = (regoff_t *) xmalloc (length * sizeof (regoff_t));
- }
- else
- {
- search_regs.start
- = (regoff_t *) xrealloc (search_regs.start,
- length * sizeof (regoff_t));
- search_regs.end
- = (regoff_t *) xrealloc (search_regs.end,
- length * sizeof (regoff_t));
- }
-
- for (i = search_regs.num_regs; i < length; i++)
+ ptrdiff_t num_regs = search_regs.num_regs;
+ search_regs.start =
+ xpalloc (search_regs.start, &num_regs, length - num_regs,
+ min (PTRDIFF_MAX, UINT_MAX), sizeof (regoff_t));
+ search_regs.end =
+ xrealloc (search_regs.end, num_regs * sizeof (regoff_t));
+
+ for (i = search_regs.num_regs; i < num_regs; i++)
search_regs.start[i] = -1;
- search_regs.num_regs = length;
+ search_regs.num_regs = num_regs;
}
for (i = 0; CONSP (list); i++)
diff --git a/src/syntax.c b/src/syntax.c
index 8c2d5ded21..3e51099794 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -398,7 +398,12 @@ find_defun_start (EMACS_INT pos, EMACS_INT pos_byte)
if (!open_paren_in_column_0_is_defun_start)
{
+ find_start_value = BEGV;
find_start_value_byte = BEGV_BYTE;
+ find_start_buffer = current_buffer;
+ find_start_modiff = MODIFF;
+ find_start_begv = BEGV;
+ find_start_pos = pos;
return BEGV;
}
diff --git a/src/sysdep.c b/src/sysdep.c
index 4bd1f54b9e..57fff94f55 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2640,7 +2640,7 @@ system_process_attributes (Lisp_Object pid)
ssize_t nread;
const char *cmd = NULL;
char *cmdline = NULL;
- size_t cmdsize = 0, cmdline_size;
+ ptrdiff_t cmdsize = 0, cmdline_size;
unsigned char c;
int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount;
unsigned long long u_time, s_time, cutime, cstime, start;
@@ -2822,8 +2822,10 @@ system_process_attributes (Lisp_Object pid)
if (fd >= 0)
{
char ch;
- for (cmdline_size = 0; emacs_read (fd, &ch, 1) == 1; cmdline_size++)
+ for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++)
{
+ if (emacs_read (fd, &ch, 1) != 1)
+ break;
c = ch;
if (isspace (c) || c == '\\')
cmdline_size++; /* for later quoting, see below */
@@ -2844,7 +2846,7 @@ system_process_attributes (Lisp_Object pid)
nread = 0;
}
/* We don't want trailing null characters. */
- for (p = cmdline + nread - 1; p > cmdline && !*p; p--)
+ for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--)
nread--;
for (p = cmdline; p < cmdline + nread; p++)
{
diff --git a/src/syssignal.h b/src/syssignal.h
index c5c749407c..7533a5a64f 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -18,7 +18,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
extern void init_signals (void);
-#if defined (HAVE_GTK_AND_PTHREAD) || defined (HAVE_NS)
+#ifdef HAVE_PTHREAD
#include <pthread.h>
/* If defined, asynchronous signals delivered to a non-main thread are
forwarded to the main thread. */
diff --git a/src/term.c b/src/term.c
index 22056451cb..837ab39915 100644
--- a/src/term.c
+++ b/src/term.c
@@ -136,10 +136,6 @@ enum no_color_bit
static int max_frame_cols;
-/* The largest frame height in any call to calculate_costs. */
-
-static int max_frame_lines;
-
/* Non-zero if we have dropped our controlling tty and therefore
should not open a frame on stdout. */
static int no_controlling_tty;
@@ -497,8 +493,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
static unsigned char *encode_terminal_src;
static unsigned char *encode_terminal_dst;
/* Allocated sizes of the above buffers. */
-static int encode_terminal_src_size;
-static int encode_terminal_dst_size;
+static ptrdiff_t encode_terminal_src_size;
+static ptrdiff_t encode_terminal_dst_size;
/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
Set CODING->produced to the byte-length of the resulting byte
@@ -509,8 +505,8 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
{
struct glyph *src_end = src + src_len;
unsigned char *buf;
- int nchars, nbytes, required;
- register int tlen = GLYPH_TABLE_LENGTH;
+ ptrdiff_t nchars, nbytes, required;
+ ptrdiff_t tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
Lisp_Object charset_list;
@@ -518,13 +514,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
multibyte-form. But, it may be enlarged on demand if
Vglyph_table contains a string or a composite glyph is
encountered. */
- required = MAX_MULTIBYTE_LENGTH * src_len;
+ if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len)
+ memory_full (SIZE_MAX);
+ required = src_len;
+ required *= MAX_MULTIBYTE_LENGTH;
if (encode_terminal_src_size < required)
{
- if (encode_terminal_src)
- encode_terminal_src = xrealloc (encode_terminal_src, required);
- else
- encode_terminal_src = xmalloc (required);
+ encode_terminal_src = xrealloc (encode_terminal_src, required);
encode_terminal_src_size = required;
}
@@ -544,19 +540,21 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
if (src->u.cmp.automatic)
{
gstring = composition_gstring_from_id (src->u.cmp.id);
- required = src->slice.cmp.to + 1 - src->slice.cmp.from;
+ required = src->slice.cmp.to - src->slice.cmp.from + 1;
}
else
{
cmp = composition_table[src->u.cmp.id];
- required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+ required = cmp->glyph_len;
+ required *= MAX_MULTIBYTE_LENGTH;
}
- if (encode_terminal_src_size < nbytes + required)
+ if (encode_terminal_src_size - nbytes < required)
{
- encode_terminal_src_size = nbytes + required;
- encode_terminal_src = xrealloc (encode_terminal_src,
- encode_terminal_src_size);
+ encode_terminal_src =
+ xpalloc (encode_terminal_src, &encode_terminal_src_size,
+ required - (encode_terminal_src_size - nbytes),
+ -1, 1);
buf = encode_terminal_src + nbytes;
}
@@ -627,11 +625,11 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
if (NILP (string))
{
nbytes = buf - encode_terminal_src;
- if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH)
+ if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH)
{
- encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH;
- encode_terminal_src = xrealloc (encode_terminal_src,
- encode_terminal_src_size);
+ encode_terminal_src =
+ xpalloc (encode_terminal_src, &encode_terminal_src_size,
+ MAX_MULTIBYTE_LENGTH, -1, 1);
buf = encode_terminal_src + nbytes;
}
if (CHAR_BYTE8_P (c)
@@ -659,11 +657,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
if (! STRING_MULTIBYTE (string))
string = string_to_multibyte (string);
nbytes = buf - encode_terminal_src;
- if (encode_terminal_src_size < nbytes + SBYTES (string))
+ if (encode_terminal_src_size - nbytes < SBYTES (string))
{
- encode_terminal_src_size = nbytes + SBYTES (string);
- encode_terminal_src = xrealloc (encode_terminal_src,
- encode_terminal_src_size);
+ encode_terminal_src =
+ xpalloc (encode_terminal_src, &encode_terminal_src_size,
+ (SBYTES (string)
+ - (encode_terminal_src_size - nbytes)),
+ -1, 1);
buf = encode_terminal_src + nbytes;
}
memcpy (buf, SDATA (string), SBYTES (string));
@@ -684,12 +684,9 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
coding->source = encode_terminal_src;
if (encode_terminal_dst_size == 0)
{
+ encode_terminal_dst = xrealloc (encode_terminal_dst,
+ encode_terminal_src_size);
encode_terminal_dst_size = encode_terminal_src_size;
- if (encode_terminal_dst)
- encode_terminal_dst = xrealloc (encode_terminal_dst,
- encode_terminal_dst_size);
- else
- encode_terminal_dst = xmalloc (encode_terminal_dst_size);
}
coding->destination = encode_terminal_dst;
coding->dst_bytes = encode_terminal_dst_size;
@@ -1156,21 +1153,17 @@ calculate_costs (struct frame *frame)
char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
X turns off char_ins_del_ok. */
- max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
+ if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2
+ < max_frame_cols)
+ memory_full (SIZE_MAX);
- if (char_ins_del_vector != 0)
- char_ins_del_vector
- = (int *) xrealloc (char_ins_del_vector,
- (sizeof (int)
- + 2 * max_frame_cols * sizeof (int)));
- else
- char_ins_del_vector
- = (int *) xmalloc (sizeof (int)
- + 2 * max_frame_cols * sizeof (int));
+ char_ins_del_vector =
+ xrealloc (char_ins_del_vector,
+ (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
memset (char_ins_del_vector, 0,
- (sizeof (int) + 2 * max_frame_cols * sizeof (int)));
+ (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
if (f && (!tty->TS_ins_line && !tty->TS_del_line))
@@ -1447,7 +1440,6 @@ term_get_fkeys_1 (void)
Character Display Information
***********************************************************************/
static void append_glyph (struct it *);
-static void produce_stretch_glyph (struct it *);
static void append_composite_glyph (struct it *);
static void produce_composite_glyph (struct it *);
static void append_glyphless_glyph (struct it *, int, const char *);
@@ -1519,6 +1511,14 @@ append_glyph (struct it *it)
}
}
+/* For external use. */
+void
+tty_append_glyph (struct it *it)
+{
+ append_glyph (it);
+}
+
+
/* Produce glyphs for the display element described by IT. *IT
specifies what we want to produce a glyph for (character, image, ...),
and where in the glyph matrix we currently are (glyph row and hpos).
@@ -1645,83 +1645,6 @@ produce_glyphs (struct it *it)
it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
}
-
-/* Produce a stretch glyph for iterator IT. IT->object is the value
- of the glyph property displayed. The value must be a list
- `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
- being recognized:
-
- 1. `:width WIDTH' specifies that the space should be WIDTH *
- canonical char width wide. WIDTH may be an integer or floating
- point number.
-
- 2. `:align-to HPOS' specifies that the space should be wide enough
- to reach HPOS, a value in canonical character units. */
-
-static void
-produce_stretch_glyph (struct it *it)
-{
- /* (space :width WIDTH ...) */
- Lisp_Object prop, plist;
- int width = 0, align_to = -1;
- int zero_width_ok_p = 0;
- double tem;
-
- /* List should start with `space'. */
- xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
- plist = XCDR (it->object);
-
- /* Compute the width of the stretch. */
- if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
- && calc_pixel_width_or_height (&tem, it, prop, 0, 1, 0))
- {
- /* Absolute width `:width WIDTH' specified and valid. */
- zero_width_ok_p = 1;
- width = (int)(tem + 0.5);
- }
- else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
- && calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
- {
- if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
- align_to = (align_to < 0
- ? 0
- : align_to - window_box_left_offset (it->w, TEXT_AREA));
- else if (align_to < 0)
- align_to = window_box_left_offset (it->w, TEXT_AREA);
- width = max (0, (int)(tem + 0.5) + align_to - it->current_x);
- zero_width_ok_p = 1;
- }
- else
- /* Nothing specified -> width defaults to canonical char width. */
- width = FRAME_COLUMN_WIDTH (it->f);
-
- if (width <= 0 && (width < 0 || !zero_width_ok_p))
- width = 1;
-
- if (width > 0 && it->line_wrap != TRUNCATE
- && it->current_x + width > it->last_visible_x)
- width = it->last_visible_x - it->current_x - 1;
-
- if (width > 0 && it->glyph_row)
- {
- Lisp_Object o_object = it->object;
- Lisp_Object object = it->stack[it->sp - 1].string;
- int n = width;
-
- if (!STRINGP (object))
- object = it->w->buffer;
- it->object = object;
- it->char_to_display = ' ';
- it->pixel_width = it->len = 1;
- while (n--)
- append_glyph (it);
- it->object = o_object;
- }
- it->pixel_width = width;
- it->nglyphs = width;
-}
-
-
/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
Called from produce_composite_glyph for terminal frames if
IT->glyph_row != NULL. IT->face_id contains the character's
@@ -3145,11 +3068,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
encode_terminal_src_size = 0;
encode_terminal_dst_size = 0;
-#ifdef HAVE_GPM
- terminal->mouse_position_hook = term_mouse_position;
- tty->mouse_highlight.mouse_face_window = Qnil;
-#endif
-
#ifndef DOS_NT
set_tty_hooks (terminal);
@@ -3409,6 +3327,11 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
#endif /* DOS_NT */
+#ifdef HAVE_GPM
+ terminal->mouse_position_hook = term_mouse_position;
+ tty->mouse_highlight.mouse_face_window = Qnil;
+#endif
+
terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
KVAR (terminal->kboard, Vwindow_system) = Qnil;
diff --git a/src/termcap.c b/src/termcap.c
index 96b9303d62..6f24817fa7 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -480,7 +480,7 @@ tgetent (char *bp, const char *name)
/* If BP is malloc'd by us, make sure it is big enough. */
if (malloc_size)
{
- int offset1 = bp1 - bp, offset2 = tc_search_point - bp;
+ ptrdiff_t offset1 = bp1 - bp, offset2 = tc_search_point - bp;
malloc_size = offset1 + buf.size;
bp = termcap_name = (char *) xrealloc (bp, malloc_size);
bp1 = termcap_name + offset1;
@@ -619,7 +619,6 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
register char *end;
register int nread;
register char *buf = bufp->beg;
- register char *tem;
if (!append_end)
append_end = bufp->ptr;
@@ -636,14 +635,14 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
{
if (bufp->full == bufp->size)
{
- if ((PTRDIFF_MAX - 1) / 2 < bufp->size)
- memory_full (SIZE_MAX);
- bufp->size *= 2;
+ ptrdiff_t ptr_offset = bufp->ptr - buf;
+ ptrdiff_t append_end_offset = append_end - buf;
/* Add 1 to size to ensure room for terminating null. */
- tem = (char *) xrealloc (buf, bufp->size + 1);
- bufp->ptr = (bufp->ptr - buf) + tem;
- append_end = (append_end - buf) + tem;
- bufp->beg = buf = tem;
+ ptrdiff_t size = bufp->size + 1;
+ bufp->beg = buf = xpalloc (buf, &size, 1, -1, 1);
+ bufp->size = size - 1;
+ bufp->ptr = buf + ptr_offset;
+ append_end = buf + append_end_offset;
}
}
else
diff --git a/src/termhooks.h b/src/termhooks.h
index 6a58517a85..63d166b641 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -288,12 +288,12 @@ enum {
/* The next four modifier bits are used also in keyboard events at
the Lisp level.
- It's probably not the greatest idea to use the 2^23 bit for any
+ It's probably not the greatest idea to use the 2^28 bit for any
modifier. It may or may not be the sign bit, depending on
- VALBITS, so using it to represent a modifier key means that
+ FIXNUM_BITS, so using it to represent a modifier key means that
characters thus modified have different integer equivalents
depending on the architecture they're running on. Oh, and
- applying XINT to a character whose 2^23 bit is set sign-extends
+ applying XINT to a character whose 2^28 bit is set might sign-extend
it, so you get a bunch of bits in the mask you didn't want.
The CHAR_ macros are defined in lisp.h. */
diff --git a/src/tparam.c b/src/tparam.c
index ed28cd7397..ac21667d65 100644
--- a/src/tparam.c
+++ b/src/tparam.c
@@ -79,24 +79,25 @@ tparam1 (const char *string, char *outstring, int len,
register const char *p = string;
register char *op = outstring;
char *outend;
- int outlen = 0;
+ char *new = 0;
+ ptrdiff_t outlen = 0;
register int tem;
int *old_argp = argp; /* can move */
int *fixed_argp = argp; /* never moves */
int explicit_param_p = 0; /* set by %p */
- int doleft = 0;
- int doup = 0;
+ ptrdiff_t doleft = 0;
+ ptrdiff_t doup = 0;
+ ptrdiff_t append_len = 0;
outend = outstring + len;
while (1)
{
/* If the buffer might be too short, make it bigger. */
- if (op + 5 >= outend)
+ while (outend - op - append_len <= 5)
{
- register char *new;
- int offset = op - outstring;
+ ptrdiff_t offset = op - outstring;
if (outlen == 0)
{
@@ -106,8 +107,7 @@ tparam1 (const char *string, char *outstring, int len,
}
else
{
- outlen *= 2;
- new = (char *) xrealloc (outstring, outlen);
+ new = xpalloc (outstring, &outlen, 1, -1, 1);
}
op = new + offset;
@@ -167,11 +167,15 @@ tparam1 (const char *string, char *outstring, int len,
and this is one of them, increment it. */
while (tem == 0 || tem == '\n' || tem == '\t')
{
+ ptrdiff_t append_len_incr;
tem++;
if (argp == old_argp)
- doup++, outend -= strlen (up);
+ doup++, append_len_incr = strlen (up);
else
- doleft++, outend -= strlen (left);
+ doleft++, append_len_incr = strlen (left);
+ if (INT_ADD_OVERFLOW (append_len, append_len_incr))
+ memory_full (SIZE_MAX);
+ append_len += append_len_incr;
}
}
*op++ = tem ? tem : 0200;
@@ -273,7 +277,7 @@ main (int argc, char **argv)
args[0] = atoi (argv[2]);
args[1] = atoi (argv[3]);
args[2] = atoi (argv[4]);
- tparam1 (argv[1], buf, "LEFT", "UP", args);
+ tparam1 (argv[1], buf, 50, "LEFT", "UP", args);
printf ("%s\n", buf);
return 0;
}
diff --git a/src/unexcw.c b/src/unexcw.c
index f643c196de..62df82ec3b 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -33,6 +33,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
extern int bss_sbrk_did_unexec;
+extern int __malloc_initialized;
+
/* emacs symbols that indicate where bss and data end for emacs internals */
extern char my_endbss[];
extern char my_edata[];
@@ -210,9 +212,12 @@ fixup_executable (int fd)
lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
SEEK_SET);
assert (ret != -1);
+ /* force the dumped emacs to reinitialize malloc */
+ __malloc_initialized = 0;
ret =
write (fd, (char *) start_address,
my_endbss - (char *) start_address);
+ __malloc_initialized = 1;
assert (ret == (my_endbss - (char *) start_address));
if (debug_unexcw)
printf (" .bss, mem start 0x%08x mem length %d\n",
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index 04e3edf463..0751eeacb9 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -599,6 +599,16 @@ print_load_command_name (int lc)
printf ("LC_DYLD_INFO_ONLY");
break;
#endif
+#ifdef LC_VERSION_MIN_MACOSX
+ case LC_VERSION_MIN_MACOSX:
+ printf ("LC_VERSION_MIN_MACOSX");
+ break;
+#endif
+#ifdef LC_FUNCTION_STARTS
+ case LC_FUNCTION_STARTS:
+ printf ("LC_FUNCTION_STARTS");
+ break;
+#endif
default:
printf ("unknown ");
}
@@ -1135,6 +1145,28 @@ copy_dyld_info (struct load_command *lc, long delta)
}
#endif
+#ifdef LC_FUNCTION_STARTS
+/* Copy a LC_FUNCTION_STARTS load command from the input file to the
+ output file, adjusting the data offset field. */
+static void
+copy_linkedit_data (struct load_command *lc, long delta)
+{
+ struct linkedit_data_command *ldp = (struct linkedit_data_command *) lc;
+
+ if (ldp->dataoff > 0)
+ ldp->dataoff += delta;
+
+ printf ("Writing ");
+ print_load_command_name (lc->cmd);
+ printf (" command\n");
+
+ if (!unexec_write (curr_header_offset, lc, lc->cmdsize))
+ unexec_error ("cannot write linkedit data command to header");
+
+ curr_header_offset += lc->cmdsize;
+}
+#endif
+
/* Copy other kinds of load commands from the input file to the output
file, ones that do not require adjustments of file offsets. */
static void
@@ -1207,6 +1239,11 @@ dump_it (void)
copy_dyld_info (lca[i], linkedit_delta);
break;
#endif
+#ifdef LC_FUNCTION_STARTS
+ case LC_FUNCTION_STARTS:
+ copy_linkedit_data (lca[i], linkedit_delta);
+ break;
+#endif
default:
copy_other (lca[i]);
break;
diff --git a/src/w32term.c b/src/w32term.c
index b7c0d61b63..98c4a39195 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1439,7 +1439,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
Nominally, highlight colors for `3d' faces are calculated by
brightening an object's color by a constant scale factor, but this
- doesn't yield good results for dark colors, so for colors who's
+ doesn't yield good results for dark colors, so for colors whose
brightness is less than this value (on a scale of 0-255) have to
use an additional additive factor.
@@ -1618,8 +1618,9 @@ x_setup_relief_colors (struct glyph_string *s)
static void
w32_draw_relief_rect (struct frame *f,
- int left_x, int top_y, int right_x, int bottom_y, int width,
- int raised_p, int top_p, int bot_p, int left_p, int right_p,
+ int left_x, int top_y, int right_x, int bottom_y,
+ int width, int raised_p,
+ int top_p, int bot_p, int left_p, int right_p,
RECT *clip_rect)
{
int i;
@@ -1880,7 +1881,8 @@ x_draw_image_relief (struct glyph_string *s)
if (s->hl == DRAW_IMAGE_SUNKEN
|| s->hl == DRAW_IMAGE_RAISED)
{
- thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
+ thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief
+ : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
raised_p = s->hl == DRAW_IMAGE_RAISED;
}
else
@@ -3486,7 +3488,7 @@ my_destroy_window (struct frame * f, HWND hwnd)
/* Create a scroll bar and return the scroll bar vector for it. W is
the Emacs window on which to create the scroll bar. TOP, LEFT,
- WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
+ WIDTH and HEIGHT are the pixel coordinates and dimensions of the
scroll bar. */
static struct scroll_bar *
@@ -3872,7 +3874,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
si.fMask = SIF_POS;
si.nPos = y;
/* Remember apparent position (we actually lag behind the real
- position, so don't set that directly. */
+ position, so don't set that directly). */
last_scroll_bar_drag_pos = y;
SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
@@ -4771,7 +4773,7 @@ w32_read_socket (struct terminal *terminal, int expected,
pending_autoraise_frame = 0;
}
- /* Check which frames are still visisble, if we have enqueued any user
+ /* Check which frames are still visible, if we have enqueued any user
events or been notified of events that may affect visibility. We
do this here because there doesn't seem to be any direct
notification from Windows that the visibility of a window has
diff --git a/src/window.c b/src/window.c
index 3f5a743f5c..96b1144acf 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1379,7 +1379,7 @@ if it isn't already recorded. */)
if (it.current_y < it.last_visible_y)
move_it_past_eol (&it);
value = make_number (IT_CHARPOS (it));
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
if (old_buffer)
set_buffer_internal (old_buffer);
@@ -4273,7 +4273,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
}
start = it.current.pos;
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
}
else if (auto_window_vscroll_p)
{
@@ -4417,7 +4417,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
}
else
{
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
if (noerror)
return;
else if (n < 0) /* could happen with empty buffers */
@@ -4434,7 +4434,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
w->vscroll = 0;
else
{
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
if (noerror)
return;
else
@@ -4583,7 +4583,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
SET_PT_BOTH (charpos, bytepos);
}
}
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
}
@@ -5010,7 +5010,7 @@ displayed_window_lines (struct window *w)
start_display (&it, w, start);
move_it_vertically (&it, height);
bottom_y = line_bottom_y (&it);
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
/* rms: On a non-window display,
the value of it.vpos at the bottom of the screen
@@ -5069,7 +5069,7 @@ and redisplay normally--don't erase and redraw the frame. */)
&& (!EQ (Vrecenter_redisplay, Qtty)
|| !NILP (Ftty_type (selected_frame))))
{
- int i;
+ ptrdiff_t i;
/* Invalidate pixel data calculated for all compositions. */
for (i = 0; i < n_compositions; i++)
@@ -5116,7 +5116,7 @@ and redisplay normally--don't erase and redraw the frame. */)
move_it_vertically_backward (&it, window_box_height (w) / 2);
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
}
else if (iarg < 0)
{
@@ -5164,7 +5164,7 @@ and redisplay normally--don't erase and redraw the frame. */)
}
if (h <= 0)
{
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
return Qnil;
}
@@ -5187,7 +5187,7 @@ and redisplay normally--don't erase and redraw the frame. */)
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
}
else
{
diff --git a/src/xdisp.c b/src/xdisp.c
index 84c75bd91d..1716cc8218 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -604,7 +604,7 @@ int current_mode_line_height, current_header_line_height;
#define SAVE_IT(ITCOPY,ITORIG,CACHE) \
do { \
if (CACHE) \
- xfree (CACHE); \
+ bidi_unshelve_cache (CACHE, 1); \
ITCOPY = ITORIG; \
CACHE = bidi_shelve_cache(); \
} while (0)
@@ -613,7 +613,7 @@ int current_mode_line_height, current_header_line_height;
do { \
if (pITORIG != pITCOPY) \
*(pITORIG) = *(pITCOPY); \
- bidi_unshelve_cache (CACHE); \
+ bidi_unshelve_cache (CACHE, 0); \
CACHE = NULL; \
} while (0)
@@ -899,7 +899,7 @@ static void init_to_row_start (struct it *, struct window *,
static int init_to_row_end (struct it *, struct window *,
struct glyph_row *);
static void back_to_previous_line_start (struct it *);
-static int forward_to_next_line_start (struct it *, int *);
+static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
static struct text_pos string_pos_nchars_ahead (struct text_pos,
Lisp_Object, EMACS_INT);
static struct text_pos string_pos (EMACS_INT, Lisp_Object);
@@ -1341,9 +1341,9 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
*vpos = it2.vpos;
}
else
- xfree (it2data);
+ bidi_unshelve_cache (it2data, 1);
}
- bidi_unshelve_cache (itdata);
+ bidi_unshelve_cache (itdata, 0);
if (old_buffer)
set_buffer_internal_1 (old_buffer);
@@ -2478,10 +2478,7 @@ init_iterator (struct it *it, struct window *w,
else if (INTEGERP (w->redisplay_end_trigger))
it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
- /* Correct bogus values of tab_width. */
- it->tab_width = XINT (BVAR (current_buffer, tab_width));
- if (it->tab_width <= 0 || it->tab_width > 1000)
- it->tab_width = 8;
+ it->tab_width = SANE_TAB_WIDTH (current_buffer);
/* Are lines in the display truncated? */
if (base_face_id != DEFAULT_FACE_ID
@@ -2627,7 +2624,7 @@ init_iterator (struct it *it, struct window *w,
it->paragraph_embedding = R2L;
else
it->paragraph_embedding = NEUTRAL_DIR;
- bidi_unshelve_cache (NULL);
+ bidi_unshelve_cache (NULL, 0);
bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
&it->bidi_it);
}
@@ -3134,13 +3131,10 @@ next_overlay_change (EMACS_INT pos)
return endpos;
}
-/* Record one cached display string position found recently by
- compute_display_string_pos. */
-static EMACS_INT cached_disp_pos;
-static EMACS_INT cached_prev_pos = -1;
-static struct buffer *cached_disp_buffer;
-static int cached_disp_modiff;
-static int cached_disp_overlay_modiff;
+/* How many characters forward to search for a display property or
+ display string. Enough for a screenful of 100 lines x 50
+ characters in a line. */
+#define MAX_DISP_SCAN 5000
/* Return the character position of a display string at or after
position specified by POSITION. If no display string exists at or
@@ -3149,21 +3143,30 @@ static int cached_disp_overlay_modiff;
text property whose value is a string. STRING is data about the
string to iterate; if STRING->lstring is nil, we are iterating a
buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
- on a GUI frame. */
+ on a GUI frame. DISP_PROP is set to zero if we searched
+ MAX_DISP_SCAN characters forward without finding any display
+ strings, non-zero otherwise. It is set to 2 if the display string
+ uses any kind of `(space ...)' spec that will produce a stretch of
+ white space in the text area. */
EMACS_INT
compute_display_string_pos (struct text_pos *position,
- struct bidi_string_data *string, int frame_window_p)
+ struct bidi_string_data *string,
+ int frame_window_p, int *disp_prop)
{
/* OBJECT = nil means current buffer. */
Lisp_Object object =
(string && STRINGP (string->lstring)) ? string->lstring : Qnil;
- Lisp_Object pos, spec;
+ Lisp_Object pos, spec, limpos;
int string_p = (string && (STRINGP (string->lstring) || string->s));
EMACS_INT eob = string_p ? string->schars : ZV;
EMACS_INT begb = string_p ? 0 : BEGV;
EMACS_INT bufpos, charpos = CHARPOS (*position);
+ EMACS_INT lim =
+ (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
struct text_pos tpos;
- struct buffer *b;
+ int rv = 0;
+
+ *disp_prop = 1;
if (charpos >= eob
/* We don't support display properties whose values are strings
@@ -3171,38 +3174,9 @@ compute_display_string_pos (struct text_pos *position,
|| string->from_disp_str
/* C strings cannot have display properties. */
|| (string->s && !STRINGP (object)))
- return eob;
-
- /* Check the cached values. */
- if (!STRINGP (object))
{
- if (NILP (object))
- b = current_buffer;
- else
- b = XBUFFER (object);
- if (b == cached_disp_buffer
- && BUF_MODIFF (b) == cached_disp_modiff
- && BUF_OVERLAY_MODIFF (b) == cached_disp_overlay_modiff
- && !b->clip_changed)
- {
- if (cached_prev_pos >= 0
- && cached_prev_pos < charpos && charpos <= cached_disp_pos)
- return cached_disp_pos;
- /* Handle overstepping either end of the known interval. */
- if (charpos > cached_disp_pos)
- cached_prev_pos = cached_disp_pos;
- else /* charpos <= cached_prev_pos */
- cached_prev_pos = max (charpos - 1, 0);
- }
-
- /* Record new values in the cache. */
- if (b != cached_disp_buffer)
- {
- cached_disp_buffer = b;
- cached_prev_pos = max (charpos - 1, 0);
- }
- cached_disp_modiff = BUF_MODIFF (b);
- cached_disp_overlay_modiff = BUF_OVERLAY_MODIFF (b);
+ *disp_prop = 0;
+ return eob;
}
/* If the character at CHARPOS is where the display string begins,
@@ -3218,34 +3192,38 @@ compute_display_string_pos (struct text_pos *position,
|| !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
object),
spec))
- && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
- frame_window_p))
+ && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
+ frame_window_p)))
{
- if (!STRINGP (object))
- cached_disp_pos = charpos;
+ if (rv == 2)
+ *disp_prop = 2;
return charpos;
}
/* Look forward for the first character with a `display' property
that will replace the underlying text when displayed. */
+ limpos = make_number (lim);
do {
- pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos);
CHARPOS (tpos) = XFASTINT (pos);
+ if (CHARPOS (tpos) >= lim)
+ {
+ *disp_prop = 0;
+ break;
+ }
if (STRINGP (object))
BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
else
BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
- if (CHARPOS (tpos) >= eob)
- break;
spec = Fget_char_property (pos, Qdisplay, object);
if (!STRINGP (object))
bufpos = CHARPOS (tpos);
} while (NILP (spec)
- || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
- frame_window_p));
+ || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
+ bufpos, frame_window_p)));
+ if (rv == 2)
+ *disp_prop = 2;
- if (!STRINGP (object))
- cached_disp_pos = CHARPOS (tpos);
return CHARPOS (tpos);
}
@@ -4106,7 +4084,9 @@ handle_display_prop (struct it *it)
/* Subroutine of handle_display_prop. Returns non-zero if the display
specification in SPEC is a replacing specification, i.e. it would
replace the text covered by `display' property with something else,
- such as an image or a display string.
+ such as an image or a display string. If SPEC includes any kind or
+ `(space ...) specification, the value is 2; this is used by
+ compute_display_string_pos, which see.
See handle_single_display_spec for documentation of arguments.
frame_window_p is non-zero if the window being redisplayed is on a
@@ -4123,6 +4103,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
EMACS_INT bufpos, int frame_window_p)
{
int replacing_p = 0;
+ int rv;
if (CONSP (spec)
/* Simple specerties. */
@@ -4141,11 +4122,11 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
{
for (; CONSP (spec); spec = XCDR (spec))
{
- if (handle_single_display_spec (it, XCAR (spec), object, overlay,
- position, bufpos, replacing_p,
- frame_window_p))
+ if ((rv = handle_single_display_spec (it, XCAR (spec), object,
+ overlay, position, bufpos,
+ replacing_p, frame_window_p)))
{
- replacing_p = 1;
+ replacing_p = rv;
/* If some text in a string is replaced, `position' no
longer points to the position of `object'. */
if (!it || STRINGP (object))
@@ -4157,11 +4138,11 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
{
int i;
for (i = 0; i < ASIZE (spec); ++i)
- if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
- position, bufpos, replacing_p,
- frame_window_p))
+ if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
+ overlay, position, bufpos,
+ replacing_p, frame_window_p)))
{
- replacing_p = 1;
+ replacing_p = rv;
/* If some text in a string is replaced, `position' no
longer points to the position of `object'. */
if (!it || STRINGP (object))
@@ -4170,9 +4151,10 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
}
else
{
- if (handle_single_display_spec (it, spec, object, overlay,
- position, bufpos, 0, frame_window_p))
- replacing_p = 1;
+ if ((rv = handle_single_display_spec (it, spec, object, overlay,
+ position, bufpos, 0,
+ frame_window_p)))
+ replacing_p = rv;
}
return replacing_p;
@@ -4548,8 +4530,17 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
if (valid_p && !display_replaced_p)
{
+ int retval = 1;
+
if (!it)
- return 1;
+ {
+ /* Callers need to know whether the display spec is any kind
+ of `(space ...)' spec that is about to affect text-area
+ display. */
+ if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
+ retval = 2;
+ return retval;
+ }
/* Save current settings of IT so that we can restore them
when we are finished with the glyph property value. */
@@ -4607,6 +4598,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
it->method = GET_FROM_STRETCH;
it->object = value;
*position = it->position = start_pos;
+ retval = 1 + (it->area == TEXT_AREA);
}
#ifdef HAVE_WINDOW_SYSTEM
else
@@ -4624,7 +4616,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
}
#endif /* HAVE_WINDOW_SYSTEM */
- return 1;
+ return retval;
}
/* Invalid property or property not supported. Restore
@@ -5354,6 +5346,8 @@ iterate_out_of_display_property (struct it *it)
EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
EMACS_INT bob = (buffer_p ? BEGV : 0);
+ xassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
+
/* Maybe initialize paragraph direction. If we are at the beginning
of a new paragraph, next_element_from_buffer may not have a
chance to do that. */
@@ -5362,7 +5356,8 @@ iterate_out_of_display_property (struct it *it)
/* prev_stop can be zero, so check against BEGV as well. */
while (it->bidi_it.charpos >= bob
&& it->prev_stop <= it->bidi_it.charpos
- && it->bidi_it.charpos < CHARPOS (it->position))
+ && it->bidi_it.charpos < CHARPOS (it->position)
+ && it->bidi_it.charpos < eob)
bidi_move_to_visually_next (&it->bidi_it);
/* Record the stop_pos we just crossed, for when we cross it
back, maybe. */
@@ -5371,14 +5366,11 @@ iterate_out_of_display_property (struct it *it)
/* If we ended up not where pop_it put us, resync IT's
positional members with the bidi iterator. */
if (it->bidi_it.charpos != CHARPOS (it->position))
- {
- SET_TEXT_POS (it->position,
- it->bidi_it.charpos, it->bidi_it.bytepos);
- if (buffer_p)
- it->current.pos = it->position;
- else
- it->current.string_pos = it->position;
- }
+ SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
+ if (buffer_p)
+ it->current.pos = it->position;
+ else
+ it->current.string_pos = it->position;
}
/* Restore IT's settings from IT->stack. Called, for example, when no
@@ -5494,6 +5486,9 @@ back_to_previous_line_start (struct it *it)
continuously over the text). Otherwise, don't change the value
of *SKIPPED_P.
+ If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
+ iterator on the newline, if it was found.
+
Newlines may come from buffer text, overlay strings, or strings
displayed via the `display' property. That's the reason we can't
simply use find_next_newline_no_quit.
@@ -5506,7 +5501,8 @@ back_to_previous_line_start (struct it *it)
leads to wrong cursor motion. */
static int
-forward_to_next_line_start (struct it *it, int *skipped_p)
+forward_to_next_line_start (struct it *it, int *skipped_p,
+ struct bidi_it *bidi_it_prev)
{
EMACS_INT old_selective;
int newline_found_p, n;
@@ -5518,6 +5514,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
&& it->c == '\n'
&& CHARPOS (it->position) == IT_CHARPOS (*it))
{
+ if (it->bidi_p && bidi_it_prev)
+ *bidi_it_prev = it->bidi_it;
set_iterator_to_next (it, 0);
it->c = 0;
return 1;
@@ -5539,6 +5537,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
if (!get_next_display_element (it))
return 0;
newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
+ if (newline_found_p && it->bidi_p && bidi_it_prev)
+ *bidi_it_prev = it->bidi_it;
set_iterator_to_next (it, 0);
}
@@ -5552,19 +5552,42 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
xassert (!STRINGP (it->string));
- /* If we are not bidi-reordering, and there isn't any `display'
- property in sight, and no overlays, we can just use the
- position of the newline in buffer text. */
- if (!it->bidi_p
- && (it->stop_charpos >= limit
- || ((pos = Fnext_single_property_change (make_number (start),
- Qdisplay, Qnil,
- make_number (limit)),
- NILP (pos))
- && next_overlay_change (start) == ZV)))
- {
- IT_CHARPOS (*it) = limit;
- IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
+ /* If there isn't any `display' property in sight, and no
+ overlays, we can just use the position of the newline in
+ buffer text. */
+ if (it->stop_charpos >= limit
+ || ((pos = Fnext_single_property_change (make_number (start),
+ Qdisplay, Qnil,
+ make_number (limit)),
+ NILP (pos))
+ && next_overlay_change (start) == ZV))
+ {
+ if (!it->bidi_p)
+ {
+ IT_CHARPOS (*it) = limit;
+ IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
+ }
+ else
+ {
+ struct bidi_it bprev;
+
+ /* Help bidi.c avoid expensive searches for display
+ properties and overlays, by telling it that there are
+ none up to `limit'. */
+ if (it->bidi_it.disp_pos < limit)
+ {
+ it->bidi_it.disp_pos = limit;
+ it->bidi_it.disp_prop = 0;
+ }
+ do {
+ bprev = it->bidi_it;
+ bidi_move_to_visually_next (&it->bidi_it);
+ } while (it->bidi_it.charpos != limit);
+ IT_CHARPOS (*it) = limit;
+ IT_BYTEPOS (*it) = it->bidi_it.bytepos;
+ if (bidi_it_prev)
+ *bidi_it_prev = bprev;
+ }
*skipped_p = newline_found_p = 1;
}
else
@@ -5573,6 +5596,8 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
&& !newline_found_p)
{
newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
+ if (newline_found_p && it->bidi_p && bidi_it_prev)
+ *bidi_it_prev = it->bidi_it;
set_iterator_to_next (it, 0);
}
}
@@ -5636,7 +5661,7 @@ back_to_previous_visible_line_start (struct it *it)
pos = --IT_CHARPOS (it2);
--IT_BYTEPOS (it2);
it2.sp = 0;
- bidi_unshelve_cache (NULL);
+ bidi_unshelve_cache (NULL, 0);
it2.string_from_display_prop_p = 0;
it2.from_disp_prop_p = 0;
if (handle_display_prop (&it2) == HANDLED_RETURN
@@ -5696,8 +5721,9 @@ static void
reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
{
int newline_found_p, skipped_p = 0;
+ struct bidi_it bidi_it_prev;
- newline_found_p = forward_to_next_line_start (it, &skipped_p);
+ newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
/* Skip over lines that are invisible because they are indented
more than the value of IT->selective. */
@@ -5708,7 +5734,8 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
{
xassert (IT_BYTEPOS (*it) == BEGV
|| FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
- newline_found_p = forward_to_next_line_start (it, &skipped_p);
+ newline_found_p =
+ forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
}
/* Position on the newline if that's what's requested. */
@@ -5724,11 +5751,14 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
--IT_STRING_BYTEPOS (*it);
}
else
- /* Setting this flag will cause
- bidi_move_to_visually_next not to advance, but
- instead deliver the current character (newline),
- which is what the ON_NEWLINE_P flag wants. */
- it->bidi_it.first_elt = 1;
+ {
+ /* We need to restore the bidi iterator to the state
+ it had on the newline, and resync the IT's
+ position with that. */
+ it->bidi_it = bidi_it_prev;
+ IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
+ IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
+ }
}
}
else if (IT_CHARPOS (*it) > BEGV)
@@ -5738,9 +5768,14 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
--IT_CHARPOS (*it);
--IT_BYTEPOS (*it);
}
- /* With bidi iteration, the call to `reseat' will cause
- bidi_move_to_visually_next deliver the current character,
- the newline, instead of advancing. */
+ else
+ {
+ /* We need to restore the bidi iterator to the state it
+ had on the newline and resync IT with that. */
+ it->bidi_it = bidi_it_prev;
+ IT_CHARPOS (*it) = it->bidi_it.charpos;
+ IT_BYTEPOS (*it) = it->bidi_it.bytepos;
+ }
reseat (it, it->current.pos, 0);
}
}
@@ -5836,7 +5871,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
{
bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
&it->bidi_it);
- bidi_unshelve_cache (NULL);
+ bidi_unshelve_cache (NULL, 0);
it->bidi_it.paragraph_dir = NEUTRAL_DIR;
it->bidi_it.string.s = NULL;
it->bidi_it.string.lstring = Qnil;
@@ -7684,7 +7719,12 @@ move_it_in_display_line_to (struct it *it,
((op & MOVE_TO_POS) != 0 \
&& BUFFERP (it->object) \
&& (IT_CHARPOS (*it) == to_charpos \
- || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
+ || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos) \
+ || (it->what == IT_COMPOSITION \
+ && ((IT_CHARPOS (*it) > to_charpos \
+ && to_charpos >= it->cmp_it.charpos) \
+ || (IT_CHARPOS (*it) < to_charpos \
+ && to_charpos <= it->cmp_it.charpos)))) \
&& (it->method == GET_FROM_BUFFER \
|| (it->method == GET_FROM_DISPLAY_VECTOR \
&& it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
@@ -8017,13 +8057,23 @@ move_it_in_display_line_to (struct it *it,
positions smaller than TO_CHARPOS, return
MOVE_POS_MATCH_OR_ZV, like the unidirectional display
did. */
- if ((op & MOVE_TO_POS) != 0
- && !saw_smaller_pos
- && IT_CHARPOS (*it) > to_charpos)
+ if (it->bidi_p && (op & MOVE_TO_POS) != 0)
{
- result = MOVE_POS_MATCH_OR_ZV;
- if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
- RESTORE_IT (it, &ppos_it, ppos_data);
+ if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
+ {
+ if (IT_CHARPOS (ppos_it) < ZV)
+ {
+ RESTORE_IT (it, &ppos_it, ppos_data);
+ result = MOVE_POS_MATCH_OR_ZV;
+ }
+ else
+ goto buffer_pos_reached;
+ }
+ else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
+ && IT_CHARPOS (*it) > to_charpos)
+ goto buffer_pos_reached;
+ else
+ result = MOVE_NEWLINE_OR_CR;
}
else
result = MOVE_NEWLINE_OR_CR;
@@ -8062,13 +8112,13 @@ move_it_in_display_line_to (struct it *it,
character positions smaller than TO_CHARPOS,
return MOVE_POS_MATCH_OR_ZV, like the
unidirectional display did. */
- || ((op & MOVE_TO_POS) != 0
+ || (it->bidi_p && (op & MOVE_TO_POS) != 0
&& !saw_smaller_pos
&& IT_CHARPOS (*it) > to_charpos))
{
- result = MOVE_POS_MATCH_OR_ZV;
- if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
+ if (!at_eob_p && IT_CHARPOS (ppos_it) < ZV)
RESTORE_IT (it, &ppos_it, ppos_data);
+ result = MOVE_POS_MATCH_OR_ZV;
break;
}
if (ITERATOR_AT_END_OF_LINE_P (it))
@@ -8077,13 +8127,13 @@ move_it_in_display_line_to (struct it *it,
break;
}
}
- else if ((op & MOVE_TO_POS) != 0
+ else if (it->bidi_p && (op & MOVE_TO_POS) != 0
&& !saw_smaller_pos
&& IT_CHARPOS (*it) > to_charpos)
{
- result = MOVE_POS_MATCH_OR_ZV;
- if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
+ if (IT_CHARPOS (ppos_it) < ZV)
RESTORE_IT (it, &ppos_it, ppos_data);
+ result = MOVE_POS_MATCH_OR_ZV;
break;
}
result = MOVE_LINE_TRUNCATED;
@@ -8104,13 +8154,13 @@ move_it_in_display_line_to (struct it *it,
done:
if (atpos_data)
- xfree (atpos_data);
+ bidi_unshelve_cache (atpos_data, 1);
if (atx_data)
- xfree (atx_data);
+ bidi_unshelve_cache (atx_data, 1);
if (wrap_data)
- xfree (wrap_data);
+ bidi_unshelve_cache (wrap_data, 1);
if (ppos_data)
- xfree (ppos_data);
+ bidi_unshelve_cache (ppos_data, 1);
/* Restore the iterator settings altered at the beginning of this
function. */
@@ -8145,7 +8195,7 @@ move_it_in_display_line (struct it *it,
(it, -1, prev_x, MOVE_TO_X);
}
else
- xfree (save_data);
+ bidi_unshelve_cache (save_data, 1);
}
else
move_it_in_display_line_to (it, to_charpos, to_x, op);
@@ -8310,7 +8360,14 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
else if (BUFFERP (it->object)
&& (it->method == GET_FROM_BUFFER
|| it->method == GET_FROM_STRETCH)
- && IT_CHARPOS (*it) >= to_charpos)
+ && IT_CHARPOS (*it) >= to_charpos
+ /* Under bidi iteration, a call to set_iterator_to_next
+ can scan far beyond to_charpos if the initial
+ portion of the next line needs to be reordered. In
+ that case, give move_it_in_display_line_to another
+ chance below. */
+ && !(it->bidi_p
+ && it->bidi_it.scan_dir == -1))
skip = MOVE_POS_MATCH_OR_ZV;
else
skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
@@ -8404,7 +8461,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
}
if (backup_data)
- xfree (backup_data);
+ bidi_unshelve_cache (backup_data, 1);
TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
}
@@ -8445,7 +8502,8 @@ move_it_vertically_backward (struct it *it, int dy)
reseat_1 (it, it->current.pos, 1);
/* We are now surely at a line start. */
- it->current_x = it->hpos = 0;
+ it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
+ reordering is in effect. */
it->continuation_lines_width = 0;
/* Move forward and see what y-distance we moved. First move to the
@@ -8479,11 +8537,26 @@ move_it_vertically_backward (struct it *it, int dy)
if (dy == 0)
{
/* DY == 0 means move to the start of the screen line. The
- value of nlines is > 0 if continuation lines were involved. */
+ value of nlines is > 0 if continuation lines were involved,
+ or if the original IT position was at start of a line. */
RESTORE_IT (it, it, it2data);
if (nlines > 0)
move_it_by_lines (it, nlines);
- xfree (it3data);
+ /* The above code moves us to some position NLINES down,
+ usually to its first glyph (leftmost in an L2R line), but
+ that's not necessarily the start of the line, under bidi
+ reordering. We want to get to the character position
+ that is immediately after the newline of the previous
+ line. */
+ if (it->bidi_p && IT_CHARPOS (*it) > BEGV
+ && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
+ {
+ EMACS_INT nl_pos =
+ find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
+
+ move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
+ }
+ bidi_unshelve_cache (it3data, 1);
}
else
{
@@ -8679,7 +8752,7 @@ move_it_by_lines (struct it *it, int dvpos)
if (IT_CHARPOS (*it) >= start_charpos)
RESTORE_IT (it, &it2, it2data);
else
- xfree (it2data);
+ bidi_unshelve_cache (it2data, 1);
}
else
RESTORE_IT (it, it, it2data);
@@ -10387,13 +10460,14 @@ static void
store_mode_line_noprop_char (char c)
{
/* If output position has reached the end of the allocated buffer,
- double the buffer's size. */
+ increase the buffer's size. */
if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
{
- int len = MODE_LINE_NOPROP_LEN (0);
- int new_size = 2 * len * sizeof *mode_line_noprop_buf;
- mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
- mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
+ ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
+ ptrdiff_t size = len;
+ mode_line_noprop_buf =
+ xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
+ mode_line_noprop_buf_end = mode_line_noprop_buf + size;
mode_line_noprop_ptr = mode_line_noprop_buf + len;
}
@@ -10455,9 +10529,9 @@ x_consider_frame_title (Lisp_Object frame)
/* Do we have more than one visible frame on this X display? */
Lisp_Object tail;
Lisp_Object fmt;
- int title_start;
+ ptrdiff_t title_start;
char *title;
- int len;
+ ptrdiff_t len;
struct it it;
int count = SPECPDL_INDEX ();
@@ -13295,6 +13369,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
/* Last buffer position covered by an overlay string with an integer
`cursor' property. */
EMACS_INT bpos_covered = 0;
+ /* Non-zero means the display string on which to display the cursor
+ comes from a text property, not from an overlay. */
+ int string_from_text_prop = 0;
/* Skip over glyphs not having an object at the start and the end of
the row. These are special glyphs like truncation marks on
@@ -13613,9 +13690,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
{
Lisp_Object str;
EMACS_INT tem;
+ /* If the display property covers the newline, we
+ need to search for it one position farther. */
+ EMACS_INT lim = pos_after
+ + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
+ string_from_text_prop = 0;
str = glyph->object;
- tem = string_buffer_position_lim (str, pos, pos_after, 0);
+ tem = string_buffer_position_lim (str, pos, lim, 0);
if (tem == 0 /* from overlay */
|| pos <= tem)
{
@@ -13639,7 +13721,10 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
EMACS_INT strpos = glyph->charpos;
if (tem)
- cursor = glyph;
+ {
+ cursor = glyph;
+ string_from_text_prop = 1;
+ }
for ( ;
(row->reversed_p ? glyph > stop : glyph < stop)
&& EQ (glyph->object, str);
@@ -13714,14 +13799,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
w->cursor.vpos >= 0
/* that candidate is not the row we are processing */
&& MATRIX_ROW (matrix, w->cursor.vpos) != row
- /* the row we are processing is part of a continued line */
- && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
/* Make sure cursor.vpos specifies a row whose start and end
- charpos occlude point. This is because some callers of this
- function leave cursor.vpos at the row where the cursor was
- displayed during the last redisplay cycle. */
+ charpos occlude point, and it is valid candidate for being a
+ cursor-row. This is because some callers of this function
+ leave cursor.vpos at the row where the cursor was displayed
+ during the last redisplay cycle. */
&& MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
- && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
+ && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
+ && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
{
struct glyph *g1 =
MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
@@ -13730,18 +13815,39 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
return 0;
/* Keep the candidate whose buffer position is the closest to
- point. */
+ point or has the `cursor' property. */
if (/* previous candidate is a glyph in TEXT_AREA of that row */
w->cursor.hpos >= 0
&& w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
- && BUFFERP (g1->object)
- && (g1->charpos == pt_old /* an exact match always wins */
- || (BUFFERP (glyph->object)
- && eabs (g1->charpos - pt_old)
- < eabs (glyph->charpos - pt_old))))
+ && ((BUFFERP (g1->object)
+ && (g1->charpos == pt_old /* an exact match always wins */
+ || (BUFFERP (glyph->object)
+ && eabs (g1->charpos - pt_old)
+ < eabs (glyph->charpos - pt_old))))
+ /* previous candidate is a glyph from a string that has
+ a non-nil `cursor' property */
+ || (STRINGP (g1->object)
+ && (!NILP (Fget_char_property (make_number (g1->charpos),
+ Qcursor, g1->object))
+ /* pevious candidate is from the same display
+ string as this one, and the display string
+ came from a text property */
+ || (EQ (g1->object, glyph->object)
+ && string_from_text_prop)
+ /* this candidate is from newline and its
+ position is not an exact match */
+ || (INTEGERP (glyph->object)
+ && glyph->charpos != pt_old)))))
return 0;
/* If this candidate gives an exact match, use that. */
- if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
+ if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
+ /* If this candidate is a glyph created for the
+ terminating newline of a line, and point is on that
+ newline, it wins because it's an exact match. */
+ || (!row->continued_p
+ && INTEGERP (glyph->object)
+ && glyph->charpos == 0
+ && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
/* Otherwise, keep the candidate that comes from a row
spanning less buffer positions. This may win when one or
both candidate positions are on glyphs that came from
@@ -14508,22 +14614,43 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
do
{
+ int at_zv_p = 0, exact_match_p = 0;
+
if (MATRIX_ROW_START_CHARPOS (row) <= PT
&& PT <= MATRIX_ROW_END_CHARPOS (row)
&& cursor_row_p (row))
rv |= set_cursor_from_row (w, row, w->current_matrix,
0, 0, 0, 0);
- /* As soon as we've found the first suitable row
- whose ends_at_zv_p flag is set, we are done. */
- if (rv
- && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
+ /* As soon as we've found the exact match for point,
+ or the first suitable row whose ends_at_zv_p flag
+ is set, we are done. */
+ at_zv_p =
+ MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
+ if (!at_zv_p)
+ {
+ struct glyph_row *candidate =
+ MATRIX_ROW (w->current_matrix, w->cursor.vpos);
+ struct glyph *g =
+ candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
+ EMACS_INT endpos = MATRIX_ROW_END_CHARPOS (candidate);
+
+ exact_match_p =
+ (BUFFERP (g->object) && g->charpos == PT)
+ || (INTEGERP (g->object)
+ && (g->charpos == PT
+ || (g->charpos == 0 && endpos - 1 == PT)));
+ }
+ if (rv && (at_zv_p || exact_match_p))
{
rc = CURSOR_MOVEMENT_SUCCESS;
break;
}
+ if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
+ break;
++row;
}
- while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
+ while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
+ || row->continued_p)
&& MATRIX_ROW_BOTTOM_Y (row) <= last_y)
|| (MATRIX_ROW_START_CHARPOS (row) == PT
&& MATRIX_ROW_BOTTOM_Y (row) < last_y));
@@ -14531,7 +14658,9 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
loop before all the candidates were examined, signal
to the caller that this method failed. */
if (rc != CURSOR_MOVEMENT_SUCCESS
- && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
+ && !(rv
+ && !MATRIX_ROW_CONTINUATION_LINE_P (row)
+ && !row->continued_p))
rc = CURSOR_MOVEMENT_MUST_SCROLL;
else if (rv)
rc = CURSOR_MOVEMENT_SUCCESS;
@@ -14991,6 +15120,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
|| (XFASTINT (w->last_modified) >= MODIFF
&& XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
{
+ int d1, d2, d3, d4, d5, d6;
/* If first window line is a continuation line, and window start
is inside the modified region, but the first change is before
@@ -15012,7 +15142,14 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
compute_window_start_on_continuation_line. (See also
bug#197). */
&& XMARKER (w->start)->buffer == current_buffer
- && compute_window_start_on_continuation_line (w))
+ && compute_window_start_on_continuation_line (w)
+ /* It doesn't make sense to force the window start like we
+ do at label force_start if it is already known that point
+ will not be visible in the resulting window, because
+ doing so will move point from its correct position
+ instead of scrolling the window to bring point into view.
+ See bug#9324. */
+ && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
{
w->force_start = Qt;
SET_TEXT_POS_FROM_MARKER (startp, w->start);
@@ -15189,7 +15326,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
if (pt_offset)
centering_position -= pt_offset;
centering_position -=
- FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
+ FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
+ + WINDOW_HEADER_LINE_HEIGHT (w);
/* Don't let point enter the scroll margin near top of
the window. */
if (centering_position < margin * FRAME_LINE_HEIGHT (f))
@@ -17953,7 +18091,8 @@ cursor_row_p (struct glyph_row *row)
{
int result = 1;
- if (PT == CHARPOS (row->end.pos))
+ if (PT == CHARPOS (row->end.pos)
+ || PT == MATRIX_ROW_END_CHARPOS (row))
{
/* Suppose the row ends on a string.
Unless the row is continued, that means it ends on a newline
@@ -18014,16 +18153,25 @@ cursor_row_p (struct glyph_row *row)
-/* Push the display property PROP so that it will be rendered at the
- current position in IT. Return 1 if PROP was successfully pushed,
- 0 otherwise. */
+/* Push the property PROP so that it will be rendered at the current
+ position in IT. Return 1 if PROP was successfully pushed, 0
+ otherwise. Called from handle_line_prefix to handle the
+ `line-prefix' and `wrap-prefix' properties. */
static int
push_display_prop (struct it *it, Lisp_Object prop)
{
- xassert (it->method == GET_FROM_BUFFER);
+ struct text_pos pos =
+ (it->method == GET_FROM_STRING) ? it->current.string_pos : it->current.pos;
- push_it (it, NULL);
+ xassert (it->method == GET_FROM_BUFFER
+ || it->method == GET_FROM_STRING);
+
+ /* We need to save the current buffer/string position, so it will be
+ restored by pop_it, because iterate_out_of_display_property
+ depends on that being set correctly, but some situations leave
+ it->position not yet set when this function is called. */
+ push_it (it, &pos);
if (STRINGP (prop))
{
@@ -18042,11 +18190,9 @@ push_display_prop (struct it *it, Lisp_Object prop)
it->stop_charpos = 0;
it->prev_stop = 0;
it->base_level_stop = 0;
- it->string_from_display_prop_p = 1;
- it->from_disp_prop_p = 1;
/* Force paragraph direction to be that of the parent
- buffer. */
+ buffer/string. */
if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
it->paragraph_embedding = it->bidi_it.paragraph_dir;
else
@@ -18059,7 +18205,7 @@ push_display_prop (struct it *it, Lisp_Object prop)
it->bidi_it.string.s = NULL;
it->bidi_it.string.schars = it->end_charpos;
it->bidi_it.string.bufpos = IT_CHARPOS (*it);
- it->bidi_it.string.from_disp_str = 1;
+ it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
it->bidi_it.string.unibyte = !it->multibyte_p;
bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
}
@@ -18329,15 +18475,22 @@ display_line (struct it *it)
#define RECORD_MAX_MIN_POS(IT) \
do \
{ \
- if (IT_CHARPOS (*(IT)) < min_pos) \
+ int composition_p = (IT)->what == IT_COMPOSITION; \
+ EMACS_INT current_pos = \
+ composition_p ? (IT)->cmp_it.charpos \
+ : IT_CHARPOS (*(IT)); \
+ EMACS_INT current_bpos = \
+ composition_p ? CHAR_TO_BYTE (current_pos) \
+ : IT_BYTEPOS (*(IT)); \
+ if (current_pos < min_pos) \
{ \
- min_pos = IT_CHARPOS (*(IT)); \
- min_bpos = IT_BYTEPOS (*(IT)); \
+ min_pos = current_pos; \
+ min_bpos = current_bpos; \
} \
- if (IT_CHARPOS (*(IT)) > max_pos) \
+ if (IT_CHARPOS (*it) > max_pos) \
{ \
- max_pos = IT_CHARPOS (*(IT)); \
- max_bpos = IT_BYTEPOS (*(IT)); \
+ max_pos = IT_CHARPOS (*it); \
+ max_bpos = IT_BYTEPOS (*it); \
} \
} \
while (0)
@@ -18784,6 +18937,9 @@ display_line (struct it *it)
}
}
+ if (wrap_data)
+ bidi_unshelve_cache (wrap_data, 1);
+
/* If line is not empty and hscrolled, maybe insert truncation glyphs
at the left window margin. */
if (it->first_visible_x
@@ -18941,7 +19097,8 @@ See also `bidi-paragraph-direction'. */)
buf = XBUFFER (buffer);
}
- if (NILP (BVAR (buf, bidi_display_reordering)))
+ if (NILP (BVAR (buf, bidi_display_reordering))
+ || NILP (BVAR (buf, enable_multibyte_characters)))
return Qleft_to_right;
else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
return BVAR (buf, bidi_paragraph_direction);
@@ -21268,7 +21425,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
if (FRAME_WINDOW_P (it->f)
&& valid_image_p (prop))
{
- int id = lookup_image (it->f, prop);
+ ptrdiff_t id = lookup_image (it->f, prop);
struct image *img = IMAGE_FROM_ID (it->f, id);
return OK_PIXELS (width_p ? img->width : img->height);
@@ -22140,7 +22297,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
do { \
int face_id = (row)->glyphs[area][START].face_id; \
struct face *base_face = FACE_FROM_ID (f, face_id); \
- int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
+ ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
struct composition *cmp = composition_table[cmp_id]; \
XChar2b *char2b; \
struct glyph_string *first_s IF_LINT (= NULL); \
@@ -22929,6 +23086,7 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
IT_EXPAND_MATRIX_WIDTH (it, area);
}
+#endif /* HAVE_WINDOW_SYSTEM */
/* Produce a stretch glyph for iterator IT. IT->object is the value
of the glyph property displayed. The value must be a list
@@ -22961,19 +23119,28 @@ append_stretch_glyph (struct it *it, Lisp_Object object,
of the stretch should be used for the ascent of the stretch.
ASCENT must be in the range 0 <= ASCENT <= 100. */
-static void
+void
produce_stretch_glyph (struct it *it)
{
/* (space :width WIDTH :height HEIGHT ...) */
Lisp_Object prop, plist;
int width = 0, height = 0, align_to = -1;
- int zero_width_ok_p = 0, zero_height_ok_p = 0;
+ int zero_width_ok_p = 0;
int ascent = 0;
double tem;
- struct face *face = FACE_FROM_ID (it->f, it->face_id);
- struct font *font = face->font ? face->font : FRAME_FONT (it->f);
+ struct face *face = NULL;
+ struct font *font = NULL;
- PREPARE_FACE_FOR_DISPLAY (it->f, face);
+#ifdef HAVE_WINDOW_SYSTEM
+ int zero_height_ok_p = 0;
+
+ if (FRAME_WINDOW_P (it->f))
+ {
+ face = FACE_FROM_ID (it->f, it->face_id);
+ font = face->font ? face->font : FRAME_FONT (it->f);
+ PREPARE_FACE_FOR_DISPLAY (it->f, face);
+ }
+#endif
/* List should start with `space'. */
xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
@@ -22987,8 +23154,9 @@ produce_stretch_glyph (struct it *it)
zero_width_ok_p = 1;
width = (int)tem;
}
- else if (prop = Fplist_get (plist, QCrelative_width),
- NUMVAL (prop) > 0)
+#ifdef HAVE_WINDOW_SYSTEM
+ else if (FRAME_WINDOW_P (it->f)
+ && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
{
/* Relative width `:relative-width FACTOR' specified and valid.
Compute the width of the characters having the `glyph'
@@ -23011,6 +23179,7 @@ produce_stretch_glyph (struct it *it)
x_produce_glyphs (&it2);
width = NUMVAL (prop) * it2.pixel_width;
}
+#endif /* HAVE_WINDOW_SYSTEM */
else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
&& calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
{
@@ -23030,33 +23199,40 @@ produce_stretch_glyph (struct it *it)
if (width <= 0 && (width < 0 || !zero_width_ok_p))
width = 1;
+#ifdef HAVE_WINDOW_SYSTEM
/* Compute height. */
- if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
- && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
+ if (FRAME_WINDOW_P (it->f))
{
- height = (int)tem;
- zero_height_ok_p = 1;
- }
- else if (prop = Fplist_get (plist, QCrelative_height),
- NUMVAL (prop) > 0)
- height = FONT_HEIGHT (font) * NUMVAL (prop);
- else
- height = FONT_HEIGHT (font);
+ if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
+ && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
+ {
+ height = (int)tem;
+ zero_height_ok_p = 1;
+ }
+ else if (prop = Fplist_get (plist, QCrelative_height),
+ NUMVAL (prop) > 0)
+ height = FONT_HEIGHT (font) * NUMVAL (prop);
+ else
+ height = FONT_HEIGHT (font);
- if (height <= 0 && (height < 0 || !zero_height_ok_p))
- height = 1;
+ if (height <= 0 && (height < 0 || !zero_height_ok_p))
+ height = 1;
- /* Compute percentage of height used for ascent. If
- `:ascent ASCENT' is present and valid, use that. Otherwise,
- derive the ascent from the font in use. */
- if (prop = Fplist_get (plist, QCascent),
- NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
- ascent = height * NUMVAL (prop) / 100.0;
- else if (!NILP (prop)
- && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
- ascent = min (max (0, (int)tem), height);
+ /* Compute percentage of height used for ascent. If
+ `:ascent ASCENT' is present and valid, use that. Otherwise,
+ derive the ascent from the font in use. */
+ if (prop = Fplist_get (plist, QCascent),
+ NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
+ ascent = height * NUMVAL (prop) / 100.0;
+ else if (!NILP (prop)
+ && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
+ ascent = min (max (0, (int)tem), height);
+ else
+ ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
+ }
else
- ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
+#endif /* HAVE_WINDOW_SYSTEM */
+ height = 1;
if (width > 0 && it->line_wrap != TRUNCATE
&& it->current_x + width > it->last_visible_x)
@@ -23064,20 +23240,37 @@ produce_stretch_glyph (struct it *it)
if (width > 0 && height > 0 && it->glyph_row)
{
+ Lisp_Object o_object = it->object;
Lisp_Object object = it->stack[it->sp - 1].string;
+ int n = width;
+
if (!STRINGP (object))
object = it->w->buffer;
- append_stretch_glyph (it, object, width, height, ascent);
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (it->f))
+ {
+ append_stretch_glyph (it, object, width, height, ascent);
+ it->ascent = it->phys_ascent = ascent;
+ it->descent = it->phys_descent = height - it->ascent;
+ it->nglyphs = width > 0 && height > 0 ? 1 : 0;
+ take_vertical_position_into_account (it);
+ }
+ else
+#endif
+ {
+ it->object = object;
+ it->char_to_display = ' ';
+ it->pixel_width = it->len = 1;
+ while (n--)
+ tty_append_glyph (it);
+ it->object = o_object;
+ it->pixel_width = width;
+ }
}
-
- it->pixel_width = width;
- it->ascent = it->phys_ascent = ascent;
- it->descent = it->phys_descent = height - it->ascent;
- it->nglyphs = width > 0 && height > 0 ? 1 : 0;
-
- take_vertical_position_into_account (it);
}
+#ifdef HAVE_WINDOW_SYSTEM
+
/* Calculate line-height and line-spacing properties.
An integer value specifies explicit pixel value.
A float value specifies relative value to current face height.
@@ -23992,6 +24185,8 @@ x_produce_glyphs (struct it *it)
Lisp_Object gstring;
struct font_metrics metrics;
+ it->nglyphs = 1;
+
gstring = composition_gstring_from_id (it->cmp_it.id);
it->pixel_width
= composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
diff --git a/src/xfaces.c b/src/xfaces.c
index 52b125b42e..431ca07b8d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -293,7 +293,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Non-zero if face attribute ATTR is `ignore-defface'. */
-#define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), Qignore_defface)
+#define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
/* Value is the number of elements of VECTOR. */
@@ -332,14 +332,14 @@ static Lisp_Object Qultra_expanded;
static Lisp_Object Qreleased_button, Qpressed_button;
static Lisp_Object QCstyle, QCcolor, QCline_width;
Lisp_Object Qunspecified; /* used in dosfns.c */
-static Lisp_Object Qignore_defface;
+static Lisp_Object QCignore_defface;
char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
/* The name of the function to call when the background of the frame
has changed, frame_set_background_mode. */
-Lisp_Object Qframe_set_background_mode;
+static Lisp_Object Qframe_set_background_mode;
/* Names of basic faces. */
@@ -403,7 +403,7 @@ static int next_lface_id;
/* A vector mapping Lisp face Id's to face names. */
static Lisp_Object *lface_id_to_name;
-static int lface_id_to_name_size;
+static ptrdiff_t lface_id_to_name_size;
/* TTY color-related functions (defined in tty-colors.el). */
@@ -458,11 +458,11 @@ struct table_entry;
struct named_merge_point;
static void map_tty_color (struct frame *, struct face *,
- enum lface_attribute_index, int *);
+ enum lface_attribute_index, int *);
static Lisp_Object resolve_face_name (Lisp_Object, int);
static void set_font_frame_param (Lisp_Object, Lisp_Object);
static int get_lface_attributes (struct frame *, Lisp_Object, Lisp_Object *,
- int, struct named_merge_point *);
+ int, struct named_merge_point *);
static ptrdiff_t load_pixmap (struct frame *, Lisp_Object,
unsigned *, unsigned *);
static struct frame *frame_or_selected_frame (Lisp_Object, int);
@@ -470,9 +470,9 @@ static void load_face_colors (struct frame *, struct face *, Lisp_Object *);
static void free_face_colors (struct frame *, struct face *);
static int face_color_gray_p (struct frame *, const char *);
static struct face *realize_face (struct face_cache *, Lisp_Object *,
- int);
+ int);
static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
- struct face *);
+ struct face *);
static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
static int realize_basic_faces (struct frame *);
@@ -488,11 +488,11 @@ static void clear_face_gcs (struct face_cache *);
static void free_face_cache (struct face_cache *);
static int face_fontset (Lisp_Object *);
static void merge_face_vectors (struct frame *, Lisp_Object *, Lisp_Object*,
- struct named_merge_point *);
+ struct named_merge_point *);
static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
- int, struct named_merge_point *);
+ int, struct named_merge_point *);
static int set_lface_from_font (struct frame *, Lisp_Object, Lisp_Object,
- int);
+ int);
static Lisp_Object lface_from_face_name (struct frame *, Lisp_Object, int);
static struct face *make_realized_face (Lisp_Object *);
static void cache_face (struct face_cache *, struct face *, unsigned);
@@ -623,7 +623,8 @@ x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
is called. */
void
-x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap, long unsigned int *pixels, int npixels)
+x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
+ long unsigned int *pixels, int npixels)
{
struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
int class = dpyinfo->visual->class;
@@ -698,8 +699,8 @@ x_free_gc (struct frame *f, GC gc)
static inline GC
x_create_gc (struct frame *f,
- unsigned long mask,
- XGCValues *xgcv)
+ unsigned long mask,
+ XGCValues *xgcv)
{
GC gc = xmalloc (sizeof (*gc));
if (gc)
@@ -792,7 +793,7 @@ init_frame_faces (struct frame *f)
if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
#endif
if (!realize_basic_faces (f))
- abort ();
+ abort ();
}
@@ -963,7 +964,8 @@ the pixmap. Bits are stored row by row, each row occupies
if these pointers are not null. */
static ptrdiff_t
-load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr, unsigned int *h_ptr)
+load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr,
+ unsigned int *h_ptr)
{
ptrdiff_t bitmap_id;
@@ -1057,7 +1059,8 @@ parse_rgb_list (Lisp_Object rgb_list, XColor *color)
returned in it. */
static int
-tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color, XColor *std_color)
+tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
+ XColor *std_color)
{
Lisp_Object frame, color_desc;
@@ -1153,7 +1156,8 @@ tty_defined_color (struct frame *f, const char *color_name,
This does the right thing for any type of frame. */
static int
-defined_color (struct frame *f, const char *color_name, XColor *color_def, int alloc)
+defined_color (struct frame *f, const char *color_name, XColor *color_def,
+ int alloc)
{
if (!FRAME_WINDOW_P (f))
return tty_defined_color (f, color_name, color_def, alloc);
@@ -1240,7 +1244,8 @@ face_color_gray_p (struct frame *f, const char *color_name)
color. */
static int
-face_color_supported_p (struct frame *f, const char *color_name, int background_p)
+face_color_supported_p (struct frame *f, const char *color_name,
+ int background_p)
{
Lisp_Object frame;
XColor not_used;
@@ -1313,7 +1318,8 @@ COLOR must be a valid color name. */)
these colors. */
unsigned long
-load_color (struct frame *f, struct face *face, Lisp_Object name, enum lface_attribute_index target_index)
+load_color (struct frame *f, struct face *face, Lisp_Object name,
+ enum lface_attribute_index target_index)
{
XColor color;
@@ -1721,7 +1727,8 @@ fonts to match. The first MAXIMUM fonts are reported.
The optional fifth argument WIDTH, if specified, is a number of columns
occupied by a character of a font. In that case, return only fonts
the WIDTH times as wide as FACE on FRAME. */)
- (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame, Lisp_Object maximum, Lisp_Object width)
+ (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame,
+ Lisp_Object maximum, Lisp_Object width)
{
struct frame *f;
int size, avgwidth IF_LINT (= 0);
@@ -2059,7 +2066,8 @@ resolve_face_name (Lisp_Object face_name, int signal_p)
signal an error if FACE_NAME is not a valid face name. If SIGNAL_P
is zero, value is nil if FACE_NAME is not a valid face name. */
static inline Lisp_Object
-lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name, int signal_p)
+lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name,
+ int signal_p)
{
Lisp_Object lface;
@@ -2101,7 +2109,8 @@ lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
Otherwise, value is zero if FACE_NAME is not a face. */
static inline int
-get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, Lisp_Object *attrs, int signal_p)
+get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
+ Lisp_Object *attrs, int signal_p)
{
Lisp_Object lface;
@@ -2122,7 +2131,9 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, Lisp_Obje
Otherwise, value is zero if FACE_NAME is not a face. */
static inline int
-get_lface_attributes (struct frame *f, Lisp_Object face_name, Lisp_Object *attrs, int signal_p, struct named_merge_point *named_merge_points)
+get_lface_attributes (struct frame *f, Lisp_Object face_name,
+ Lisp_Object *attrs, int signal_p,
+ struct named_merge_point *named_merge_points)
{
Lisp_Object face_remapping;
@@ -2165,7 +2176,7 @@ lface_fully_specified_p (Lisp_Object *attrs)
for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
- break;
+ break;
return i == LFACE_VECTOR_SIZE;
}
@@ -2178,7 +2189,8 @@ lface_fully_specified_p (Lisp_Object *attrs)
of FORCE_P. */
static int
-set_lface_from_font (struct frame *f, Lisp_Object lface, Lisp_Object font_object, int force_p)
+set_lface_from_font (struct frame *f, Lisp_Object lface,
+ Lisp_Object font_object, int force_p)
{
Lisp_Object val;
struct font *font = XFONT_OBJECT (font_object);
@@ -2288,7 +2300,8 @@ merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid)
other places. */
static inline void
-merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, struct named_merge_point *named_merge_points)
+merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to,
+ struct named_merge_point *named_merge_points)
{
int i;
@@ -2355,7 +2368,8 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, struct
merging succeeded. */
static int
-merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, struct named_merge_point *named_merge_points)
+merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
+ struct named_merge_point *named_merge_points)
{
struct named_merge_point named_merge_point;
@@ -2405,7 +2419,8 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, struc
specifications. */
static int
-merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, int err_msgs, struct named_merge_point *named_merge_points)
+merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
+ int err_msgs, struct named_merge_point *named_merge_points)
{
int ok = 1; /* Succeed without an error? */
@@ -2667,12 +2682,10 @@ Value is a vector of face attributes. */)
The mapping from Lisp face to Lisp face id is given by the
property `face' of the Lisp face name. */
if (next_lface_id == lface_id_to_name_size)
- {
- int new_size = max (50, 2 * lface_id_to_name_size);
- int sz = new_size * sizeof *lface_id_to_name;
- lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
- lface_id_to_name_size = new_size;
- }
+ lface_id_to_name =
+ xpalloc (lface_id_to_name, &lface_id_to_name_size, 1,
+ min (INT_MAX, MOST_POSITIVE_FIXNUM),
+ sizeof *lface_id_to_name);
lface_id_to_name[next_lface_id] = face;
Fput (face, Qface, make_number (next_lface_id));
@@ -2838,7 +2851,7 @@ FRAME 0 means change the face on all frames, and change the default
The value of that attribute will be inherited from some other
face during face merging. See internal_merge_in_global_face. */
if (UNSPECIFIEDP (value))
- value = Qignore_defface;
+ value = QCignore_defface;
}
else
{
@@ -2885,7 +2898,8 @@ FRAME 0 means change the face on all frames, and change the default
{
/* The default face must have an absolute size. */
if (!INTEGERP (value) || XINT (value) <= 0)
- signal_error ("Default face height not absolute and positive", value);
+ signal_error ("Default face height not absolute and positive",
+ value);
}
else
{
@@ -2895,7 +2909,8 @@ FRAME 0 means change the face on all frames, and change the default
make_number (10),
Qnil);
if (!INTEGERP (test) || XINT (test) <= 0)
- signal_error ("Face height does not produce a positive integer", value);
+ signal_error ("Face height does not produce a positive integer",
+ value);
}
}
@@ -2974,7 +2989,7 @@ FRAME 0 means change the face on all frames, and change the default
int valid_p;
/* Allow t meaning a simple box of width 1 in foreground color
- of the face. */
+ of the face. */
if (EQ (value, Qt))
value = make_number (1);
@@ -3319,7 +3334,8 @@ FRAME 0 means change the face on all frames, and change the default
has been assigned the value NEW_VALUE. */
void
-update_face_from_frame_parameter (struct frame *f, Lisp_Object param, Lisp_Object new_value)
+update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
+ Lisp_Object new_value)
{
Lisp_Object face = Qnil;
Lisp_Object lface;
@@ -3633,7 +3649,7 @@ the only relative value that users see is `unspecified'.
However, for :height, floating point values are also relative. */)
(Lisp_Object attribute, Lisp_Object value)
{
- if (EQ (value, Qunspecified) || (EQ (value, Qignore_defface)))
+ if (EQ (value, Qunspecified) || (EQ (value, QCignore_defface)))
return Qt;
else if (EQ (attribute, QCheight))
return INTEGERP (value) ? Qnil : Qt;
@@ -3648,7 +3664,7 @@ If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
the result will be absolute, otherwise it will be relative. */)
(Lisp_Object attribute, Lisp_Object value1, Lisp_Object value2)
{
- if (EQ (value1, Qunspecified) || EQ (value1, Qignore_defface))
+ if (EQ (value1, Qunspecified) || EQ (value1, QCignore_defface))
return value2;
else if (EQ (attribute, QCheight))
return merge_face_heights (value1, value2, value1);
@@ -4052,7 +4068,7 @@ lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
xassert (lface_fully_specified_p (lface1)
&& lface_fully_specified_p (lface2));
return (xstrcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]),
- SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
+ SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
&& xstrcasecmp (SSDATA (lface1[LFACE_FOUNDRY_INDEX]),
SSDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
&& EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
@@ -4064,7 +4080,7 @@ lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
|| (STRINGP (lface1[LFACE_FONTSET_INDEX])
&& STRINGP (lface2[LFACE_FONTSET_INDEX])
&& ! xstrcasecmp (SSDATA (lface1[LFACE_FONTSET_INDEX]),
- SSDATA (lface2[LFACE_FONTSET_INDEX]))))
+ SSDATA (lface2[LFACE_FONTSET_INDEX]))))
);
}
@@ -4169,10 +4185,10 @@ color_distance (XColor *x, XColor *y)
/* This formula is from a paper title `Colour metric' by Thiadmer Riemersma.
Quoting from that paper:
- This formula has results that are very close to L*u*v* (with the
- modified lightness curve) and, more importantly, it is a more even
- algorithm: it does not have a range of colours where it suddenly
- gives far from optimal results.
+ This formula has results that are very close to L*u*v* (with the
+ modified lightness curve) and, more importantly, it is a more even
+ algorithm: it does not have a range of colours where it suddenly
+ gives far from optimal results.
See <http://www.compuphase.com/cmetric.htm> for more info. */
@@ -4410,15 +4426,8 @@ cache_face (struct face_cache *c, struct face *face, unsigned int hash)
if (i == c->used)
{
if (c->used == c->size)
- {
- int new_size, sz;
- new_size = min (2 * c->size, MAX_FACE_ID);
- if (new_size == c->size)
- abort (); /* Alternatives? ++kfs */
- sz = new_size * sizeof *c->faces_by_id;
- c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
- c->size = new_size;
- }
+ c->faces_by_id = xpalloc (c->faces_by_id, &c->size, 1, MAX_FACE_ID,
+ sizeof *c->faces_by_id);
c->used++;
}
@@ -4702,7 +4711,8 @@ face_with_height (struct frame *f, int face_id, int height)
default face. FACE_ID is assumed to be already realized. */
int
-lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id, int signal_p)
+lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id,
+ int signal_p)
{
Lisp_Object attrs[LFACE_VECTOR_SIZE];
Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
@@ -4758,7 +4768,8 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
\(2) `close in spirit' to what the attributes specify, if not exact. */
static int
-x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face)
+x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs,
+ struct face *def_face)
{
Lisp_Object *def_attrs = def_face->lface;
@@ -4859,7 +4870,8 @@ x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *
substitution of a `dim' face for italic. */
static int
-tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face)
+tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs,
+ struct face *def_face)
{
int weight;
Lisp_Object val, fg, bg;
@@ -5011,7 +5023,8 @@ tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face
/* See if the capabilities we selected above are supported, with the
given colors. */
if (test_caps != 0 &&
- ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
+ ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel,
+ bg_tty_color.pixel))
return 0;
@@ -5283,8 +5296,8 @@ realize_basic_faces (struct frame *f)
{
FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
#ifdef USE_X_TOOLKIT
- if (FRAME_WINDOW_P (f))
- x_update_menu_appearance (f);
+ if (FRAME_WINDOW_P (f))
+ x_update_menu_appearance (f);
#endif
}
@@ -5404,14 +5417,14 @@ realize_default_face (struct frame *f)
if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
{
/* This can happen when making a frame on a display that does
- not support the default font. */
+ not support the default font. */
if (!face->font)
- return 0;
+ return 0;
/* Otherwise, the font specified for the frame was not
- acceptable as a font for the default face (perhaps because
- auto-scaled fonts are rejected), so we must adjust the frame
- font. */
+ acceptable as a font for the default face (perhaps because
+ auto-scaled fonts are rejected), so we must adjust the frame
+ font. */
x_set_font (f, LFACE_FONT (lface), Qnil);
}
#endif /* HAVE_X_WINDOWS */
@@ -5502,7 +5515,8 @@ realize_face (struct face_cache *cache, Lisp_Object *attrs, int former_face_id)
no-font. */
static struct face *
-realize_non_ascii_face (struct frame *f, Lisp_Object font_object, struct face *base_face)
+realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
+ struct face *base_face)
{
struct face_cache *cache = FRAME_FACE_CACHE (f);
struct face *face;
@@ -5621,7 +5635,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
else if (INTEGERP (box))
{
/* Simple box of specified line width in foreground color of the
- face. */
+ face. */
xassert (XINT (box) != 0);
face->box = FACE_SIMPLE_BOX;
face->box_line_width = XINT (box);
@@ -5743,7 +5757,8 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
default foreground/background colors. */
static void
-map_tty_color (struct frame *f, struct face *face, enum lface_attribute_index idx, int *defaulted)
+map_tty_color (struct frame *f, struct face *face,
+ enum lface_attribute_index idx, int *defaulted)
{
Lisp_Object frame, color, def;
int foreground_p = idx == LFACE_FOREGROUND_INDEX;
@@ -5799,7 +5814,7 @@ map_tty_color (struct frame *f, struct face *face, enum lface_attribute_index id
face->lface[idx] = tty_color_name (f, pixel);
*defaulted = 1;
}
- }
+ }
#endif /* MSDOS */
}
@@ -5984,9 +5999,18 @@ face_at_buffer_position (struct window *w, EMACS_INT pos,
*endptr = endpos;
- default_face = FACE_FROM_ID (f, base_face_id >= 0 ? base_face_id
- : NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
- : lookup_basic_face (f, DEFAULT_FACE_ID));
+ {
+ int face_id;
+
+ if (base_face_id >= 0)
+ face_id = base_face_id;
+ else if (NILP (Vface_remapping_alist))
+ face_id = DEFAULT_FACE_ID;
+ else
+ face_id = lookup_basic_face (f, DEFAULT_FACE_ID);
+
+ default_face = FACE_FROM_ID (f, face_id);
+ }
/* Optimize common cases where we can use the default face. */
if (noverlays == 0
@@ -6460,7 +6484,7 @@ syms_of_xfaces (void)
DEFSYM (Qbackground_color, "background-color");
DEFSYM (Qforeground_color, "foreground-color");
DEFSYM (Qunspecified, "unspecified");
- DEFSYM (Qignore_defface, ":ignore-defface");
+ DEFSYM (QCignore_defface, ":ignore-defface");
DEFSYM (Qface_alias, "face-alias");
DEFSYM (Qdefault, "default");
@@ -6598,7 +6622,7 @@ face definitions. For instance, the mode my-mode could define a face
`my-mode-default', and then in the mode setup function, do:
(set (make-local-variable 'face-remapping-alist)
- '((default my-mode-default)))).
+ '((default my-mode-default)))).
Because Emacs normally only redraws screen areas when the underlying
buffer contents change, you may need to call `redraw-display' after
diff --git a/src/xfns.c b/src/xfns.c
index eec19b9d27..9a3d5fcda8 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -145,7 +145,8 @@ static Lisp_Object Qcompound_text, Qcancel_timer;
Lisp_Object Qfont_param;
#if GLYPH_DEBUG
-static int image_cache_refcount, dpyinfo_refcount;
+static ptrdiff_t image_cache_refcount;
+static int dpyinfo_refcount;
#endif
#if defined (USE_GTK) && defined (HAVE_FREETYPE)
@@ -1470,7 +1471,8 @@ x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object old
the result should be `COMPOUND_TEXT'. */
static unsigned char *
-x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, int *text_bytes, int *stringp, int *freep)
+x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
+ ptrdiff_t *text_bytes, int *stringp, int *freep)
{
int result = string_xstring_p (string);
struct coding_system coding;
@@ -1488,8 +1490,8 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp, in
coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
/* We suppress producing escape sequences for composition. */
coding.common_flags &= ~CODING_ANNOTATION_MASK;
+ coding.destination = xnmalloc (SCHARS (string), 2);
coding.dst_bytes = SCHARS (string) * 2;
- coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
encode_coding_object (&coding, string, 0, 0,
SCHARS (string), SBYTES (string), Qnil);
*text_bytes = coding.produced;
@@ -1511,7 +1513,8 @@ x_set_name_internal (FRAME_PTR f, Lisp_Object name)
BLOCK_INPUT;
{
XTextProperty text, icon;
- int bytes, stringp;
+ ptrdiff_t bytes;
+ int stringp;
int do_free_icon_value = 0, do_free_text_value = 0;
Lisp_Object coding_system;
Lisp_Object encoded_name;
@@ -1550,6 +1553,8 @@ x_set_name_internal (FRAME_PTR f, Lisp_Object name)
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
text.format = 8;
text.nitems = bytes;
+ if (text.nitems != bytes)
+ error ("Window name too large");
if (!STRINGP (f->icon_name))
{
@@ -1565,6 +1570,8 @@ x_set_name_internal (FRAME_PTR f, Lisp_Object name)
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
icon.format = 8;
icon.nitems = bytes;
+ if (icon.nitems != bytes)
+ error ("Icon name too large");
encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
}
@@ -4193,21 +4200,19 @@ FRAME. Default is to change on the edit X window. */)
if (CONSP (value))
{
+ ptrdiff_t elsize;
+
nelements = x_check_property_data (value);
if (nelements == -1)
error ("Bad data in VALUE, must be number, string or cons");
- if (element_format == 8)
- data = (unsigned char *) xmalloc (nelements);
- else if (element_format == 16)
- data = (unsigned char *) xmalloc (nelements*2);
- else /* format == 32 */
- /* The man page for XChangeProperty:
- "If the specified format is 32, the property data must be a
- long array."
- This applies even if long is more than 64 bits. The X library
- converts to 32 bits before sending to the X server. */
- data = (unsigned char *) xmalloc (nelements * sizeof(long));
+ /* The man page for XChangeProperty:
+ "If the specified format is 32, the property data must be a
+ long array."
+ This applies even if long is more than 32 bits. The X library
+ converts to 32 bits before sending to the X server. */
+ elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
+ data = xnmalloc (nelements, elsize);
x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
}
@@ -4215,7 +4220,9 @@ FRAME. Default is to change on the edit X window. */)
{
CHECK_STRING (value);
data = SDATA (value);
- nelements = SCHARS (value);
+ if (INT_MAX < SBYTES (value))
+ error ("VALUE too long");
+ nelements = SBYTES (value);
}
BLOCK_INPUT;
diff --git a/src/xgselect.c b/src/xgselect.c
index 9ccdd37489..339ec47511 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -29,7 +29,7 @@ along with GNU Emacs. If not, see <http§://www.gnu.org/licenses/>. */
#include <setjmp.h>
static GPollFD *gfds;
-static int gfds_size;
+static ptrdiff_t gfds_size;
int
xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
@@ -54,10 +54,9 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
do {
if (n_gfds > gfds_size)
{
- while (n_gfds > gfds_size)
- gfds_size *= 2;
xfree (gfds);
- gfds = xmalloc (sizeof (*gfds) * gfds_size);
+ gfds = xpalloc (0, &gfds_size, n_gfds - gfds_size, INT_MAX,
+ sizeof *gfds);
}
n_gfds = g_main_context_query (context,
diff --git a/src/xml.c b/src/xml.c
index 55352baae3..8b485e7364 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -141,7 +141,6 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
Fcons (Qnil, Fnreverse (Fcons (r, result))));
xmlFreeDoc (doc);
- xmlCleanupParser ();
}
return result;
diff --git a/src/xrdb.c b/src/xrdb.c
index 6a16e3260b..63f06738b9 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -426,24 +426,22 @@ get_environ_db (void)
{
XrmDatabase db;
char *p;
- char *path = 0, *home = 0;
- const char *host;
+ char *path = 0;
if ((p = getenv ("XENVIRONMENT")) == NULL)
{
- home = gethomedir ();
- host = get_system_name ();
- path = (char *) xmalloc (strlen (home)
- + sizeof (".Xdefaults-")
- + strlen (host));
- sprintf (path, "%s%s%s", home, ".Xdefaults-", host);
+ static char const xdefaults[] = ".Xdefaults-";
+ char *home = gethomedir ();
+ char const *host = get_system_name ();
+ ptrdiff_t pathsize = strlen (home) + sizeof xdefaults + strlen (host);
+ path = (char *) xrealloc (home, pathsize);
+ strcat (strcat (path, xdefaults), host);
p = path;
}
db = XrmGetFileDatabase (p);
xfree (path);
- xfree (home);
return db;
}
diff --git a/src/xselect.c b/src/xselect.c
index f63977a73d..77bda79007 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -66,22 +66,15 @@ static Lisp_Object wait_for_property_change_unwind (Lisp_Object);
static void wait_for_property_change (struct prop_location *);
static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object);
-static void x_get_window_property (Display *, Window, Atom,
- unsigned char **, int *,
- Atom *, int *, unsigned long *, int);
-static void receive_incremental_selection (Display *, Window, Atom,
- Lisp_Object, unsigned,
- unsigned char **, int *,
- Atom *, int *, unsigned long *);
static Lisp_Object x_get_window_property_as_lisp_data (Display *,
Window, Atom,
Lisp_Object, Atom);
static Lisp_Object selection_data_to_lisp_data (Display *,
const unsigned char *,
- int, Atom, int);
+ ptrdiff_t, Atom, int);
static void lisp_data_to_selection_data (Display *, Lisp_Object,
unsigned char **, Atom *,
- unsigned *, int *, int *);
+ ptrdiff_t *, int *, int *);
static Lisp_Object clean_local_selection_data (Lisp_Object);
/* Printing traces to stderr. */
@@ -114,15 +107,39 @@ static Lisp_Object Qcompound_text_with_extensions;
static Lisp_Object Qforeign_selection;
static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions;
+/* Bytes needed to represent 'long' data. This is as per libX11; it
+ is not necessarily sizeof (long). */
+#define X_LONG_SIZE 4
+
+/* Extreme 'short' and 'long' values suitable for libX11. */
+#define X_SHRT_MAX 0x7fff
+#define X_SHRT_MIN (-1 - X_SHRT_MAX)
+#define X_LONG_MAX 0x7fffffff
+#define X_LONG_MIN (-1 - X_LONG_MAX)
+
/* If this is a smaller number than the max-request-size of the display,
emacs will use INCR selection transfer when the selection is larger
than this. The max-request-size is usually around 64k, so if you want
emacs to use incremental selection transfers when the selection is
smaller than that, set this. I added this mostly for debugging the
- incremental transfer stuff, but it might improve server performance. */
-#define MAX_SELECTION_QUANTUM 0xFFFFFF
+ incremental transfer stuff, but it might improve server performance.
-#define SELECTION_QUANTUM(dpy) ((XMaxRequestSize(dpy) << 2) - 100)
+ This value cannot exceed INT_MAX / max (X_LONG_SIZE, sizeof (long))
+ because it is multiplied by X_LONG_SIZE and by sizeof (long) in
+ subscript calculations. Similarly for PTRDIFF_MAX - 1 or SIZE_MAX
+ - 1 in place of INT_MAX. */
+#define MAX_SELECTION_QUANTUM \
+ ((int) min (0xFFFFFF, (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) - 1) \
+ / max (X_LONG_SIZE, sizeof (long)))))
+
+static int
+selection_quantum (Display *display)
+{
+ long mrs = XMaxRequestSize (display);
+ return (mrs < MAX_SELECTION_QUANTUM / X_LONG_SIZE + 25
+ ? (mrs - 25) * X_LONG_SIZE
+ : MAX_SELECTION_QUANTUM);
+}
#define LOCAL_SELECTION(selection_symbol,dpyinfo) \
assq_no_quit (selection_symbol, dpyinfo->terminal->Vselection_alist)
@@ -477,7 +494,7 @@ static struct x_display_info *selection_request_dpyinfo;
struct selection_data
{
unsigned char *data;
- unsigned int size;
+ ptrdiff_t size;
int format;
Atom type;
int nofree;
@@ -581,14 +598,11 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
XSelectionEvent *reply = &(reply_base.xselection);
Display *display = SELECTION_EVENT_DISPLAY (event);
Window window = SELECTION_EVENT_REQUESTOR (event);
- int bytes_remaining;
- int max_bytes = SELECTION_QUANTUM (display);
+ ptrdiff_t bytes_remaining;
+ int max_bytes = selection_quantum (display);
int count = SPECPDL_INDEX ();
struct selection_data *cs;
- if (max_bytes > MAX_SELECTION_QUANTUM)
- max_bytes = MAX_SELECTION_QUANTUM;
-
reply->type = SelectionNotify;
reply->display = display;
reply->requestor = window;
@@ -616,11 +630,12 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
if (cs->property == None)
continue;
- bytes_remaining = cs->size * (cs->format / 8);
+ bytes_remaining = cs->size;
+ bytes_remaining *= cs->format >> 3;
if (bytes_remaining <= max_bytes)
{
/* Send all the data at once, with minimal handshaking. */
- TRACE1 ("Sending all %d bytes", bytes_remaining);
+ TRACE1 ("Sending all %"pD"d bytes", bytes_remaining);
XChangeProperty (display, window, cs->property,
cs->type, cs->format, PropModeReplace,
cs->data, cs->size);
@@ -630,7 +645,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
/* Send an INCR tag to initiate incremental transfer. */
long value[1];
- TRACE2 ("Start sending %d bytes incrementally (%s)",
+ TRACE2 ("Start sending %"pD"d bytes incrementally (%s)",
bytes_remaining, XGetAtomName (display, cs->property));
cs->wait_object
= expect_property_change (display, window, cs->property,
@@ -638,7 +653,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
/* XChangeProperty expects an array of long even if long is
more than 32 bits. */
- value[0] = bytes_remaining;
+ value[0] = min (bytes_remaining, X_LONG_MAX);
XChangeProperty (display, window, cs->property,
dpyinfo->Xatom_INCR, 32, PropModeReplace,
(unsigned char *) value, 1);
@@ -672,7 +687,8 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
int had_errors = x_had_errors_p (display);
UNBLOCK_INPUT;
- bytes_remaining = cs->size * format_bytes;
+ bytes_remaining = cs->size;
+ bytes_remaining *= format_bytes;
/* Wait for the requester to ack by deleting the property.
This can run Lisp code (process handlers) or signal. */
@@ -810,7 +826,7 @@ x_handle_selection_request (struct input_event *event)
non-None property. */
Window requestor = SELECTION_EVENT_REQUESTOR (event);
Lisp_Object multprop;
- int j, nselections;
+ ptrdiff_t j, nselections;
if (property == None) goto DONE;
multprop
@@ -1269,19 +1285,28 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
static void
x_get_window_property (Display *display, Window window, Atom property,
- unsigned char **data_ret, int *bytes_ret,
+ unsigned char **data_ret, ptrdiff_t *bytes_ret,
Atom *actual_type_ret, int *actual_format_ret,
unsigned long *actual_size_ret, int delete_p)
{
- int total_size;
+ ptrdiff_t total_size;
unsigned long bytes_remaining;
- int offset = 0;
+ ptrdiff_t offset = 0;
+ unsigned char *data = 0;
unsigned char *tmp_data = 0;
int result;
- int buffer_size = SELECTION_QUANTUM (display);
+ int buffer_size = selection_quantum (display);
+
+ /* Wide enough to avoid overflow in expressions using it. */
+ ptrdiff_t x_long_size = X_LONG_SIZE;
- if (buffer_size > MAX_SELECTION_QUANTUM)
- buffer_size = MAX_SELECTION_QUANTUM;
+ /* Maximum value for TOTAL_SIZE. It cannot exceed PTRDIFF_MAX - 1
+ and SIZE_MAX - 1, for an extra byte at the end. And it cannot
+ exceed LONG_MAX * X_LONG_SIZE, for XGetWindowProperty. */
+ ptrdiff_t total_size_max =
+ ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / x_long_size < LONG_MAX
+ ? min (PTRDIFF_MAX, SIZE_MAX) - 1
+ : LONG_MAX * x_long_size);
BLOCK_INPUT;
@@ -1292,49 +1317,44 @@ x_get_window_property (Display *display, Window window, Atom property,
actual_size_ret,
&bytes_remaining, &tmp_data);
if (result != Success)
- {
- UNBLOCK_INPUT;
- *data_ret = 0;
- *bytes_ret = 0;
- return;
- }
+ goto done;
/* This was allocated by Xlib, so use XFree. */
XFree ((char *) tmp_data);
if (*actual_type_ret == None || *actual_format_ret == 0)
- {
- UNBLOCK_INPUT;
- return;
- }
+ goto done;
- total_size = bytes_remaining + 1;
- *data_ret = (unsigned char *) xmalloc (total_size);
+ if (total_size_max < bytes_remaining)
+ goto size_overflow;
+ total_size = bytes_remaining;
+ data = malloc (total_size + 1);
+ if (! data)
+ goto memory_exhausted;
/* Now read, until we've gotten it all. */
while (bytes_remaining)
{
-#ifdef TRACE_SELECTION
- unsigned long last = bytes_remaining;
-#endif
+ ptrdiff_t bytes_gotten;
+ int bytes_per_item;
result
= XGetWindowProperty (display, window, property,
- (long)offset/4, (long)buffer_size/4,
+ offset / X_LONG_SIZE,
+ buffer_size / X_LONG_SIZE,
False,
AnyPropertyType,
actual_type_ret, actual_format_ret,
actual_size_ret, &bytes_remaining, &tmp_data);
- TRACE2 ("Read %lu bytes from property %s",
- last - bytes_remaining,
- XGetAtomName (display, property));
-
/* If this doesn't return Success at this point, it means that
some clod deleted the selection while we were in the midst of
reading it. Deal with that, I guess.... */
if (result != Success)
break;
+ bytes_per_item = *actual_format_ret >> 3;
+ xassert (*actual_size_ret <= buffer_size / bytes_per_item);
+
/* The man page for XGetWindowProperty says:
"If the returned format is 32, the returned data is represented
as a long array and should be cast to that type to obtain the
@@ -1348,32 +1368,61 @@ x_get_window_property (Display *display, Window window, Atom property,
The bytes and offsets passed to XGetWindowProperty refers to the
property and those are indeed in 32 bit quantities if format is 32. */
+ bytes_gotten = *actual_size_ret;
+ bytes_gotten *= bytes_per_item;
+
+ TRACE2 ("Read %"pD"d bytes from property %s",
+ bytes_gotten, XGetAtomName (display, property));
+
+ if (total_size - offset < bytes_gotten)
+ {
+ unsigned char *data1;
+ ptrdiff_t remaining_lim = total_size_max - offset - bytes_gotten;
+ if (remaining_lim < 0 || remaining_lim < bytes_remaining)
+ goto size_overflow;
+ total_size = offset + bytes_gotten + bytes_remaining;
+ data1 = realloc (data, total_size + 1);
+ if (! data1)
+ goto memory_exhausted;
+ data = data1;
+ }
+
if (32 < BITS_PER_LONG && *actual_format_ret == 32)
{
unsigned long i;
- int *idata = (int *) ((*data_ret) + offset);
+ int *idata = (int *) (data + offset);
long *ldata = (long *) tmp_data;
for (i = 0; i < *actual_size_ret; ++i)
- {
- idata[i]= (int) ldata[i];
- offset += 4;
- }
+ idata[i] = ldata[i];
}
else
- {
- *actual_size_ret *= *actual_format_ret / 8;
- memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret);
- offset += *actual_size_ret;
- }
+ memcpy (data + offset, tmp_data, bytes_gotten);
+
+ offset += bytes_gotten;
/* This was allocated by Xlib, so use XFree. */
XFree ((char *) tmp_data);
}
XFlush (display);
+ data[offset] = '\0';
+
+ done:
UNBLOCK_INPUT;
+ *data_ret = data;
*bytes_ret = offset;
+ return;
+
+ size_overflow:
+ free (data);
+ UNBLOCK_INPUT;
+ memory_full (SIZE_MAX);
+
+ memory_exhausted:
+ free (data);
+ UNBLOCK_INPUT;
+ memory_full (total_size + 1);
}
/* Use xfree, not XFree, to free the data obtained with this function. */
@@ -1382,16 +1431,19 @@ static void
receive_incremental_selection (Display *display, Window window, Atom property,
Lisp_Object target_type,
unsigned int min_size_bytes,
- unsigned char **data_ret, int *size_bytes_ret,
+ unsigned char **data_ret,
+ ptrdiff_t *size_bytes_ret,
Atom *type_ret, int *format_ret,
unsigned long *size_ret)
{
- int offset = 0;
+ ptrdiff_t offset = 0;
struct prop_location *wait_object;
+ if (min (PTRDIFF_MAX, SIZE_MAX) < min_size_bytes)
+ memory_full (SIZE_MAX);
+ *data_ret = (unsigned char *) xmalloc (min_size_bytes);
*size_bytes_ret = min_size_bytes;
- *data_ret = (unsigned char *) xmalloc (*size_bytes_ret);
- TRACE1 ("Read %d bytes incrementally", min_size_bytes);
+ TRACE1 ("Read %u bytes incrementally", min_size_bytes);
/* At this point, we have read an INCR property.
Delete the property to ack it.
@@ -1416,7 +1468,7 @@ receive_incremental_selection (Display *display, Window window, Atom property,
while (1)
{
unsigned char *tmp_data;
- int tmp_size_bytes;
+ ptrdiff_t tmp_size_bytes;
TRACE0 (" Wait for property change");
wait_for_property_change (wait_object);
@@ -1429,7 +1481,7 @@ receive_incremental_selection (Display *display, Window window, Atom property,
&tmp_data, &tmp_size_bytes,
type_ret, format_ret, size_ret, 1);
- TRACE1 (" Read increment of %d bytes", tmp_size_bytes);
+ TRACE1 (" Read increment of %"pD"d bytes", tmp_size_bytes);
if (tmp_size_bytes == 0) /* we're done */
{
@@ -1452,11 +1504,10 @@ receive_incremental_selection (Display *display, Window window, Atom property,
XFlush (display);
UNBLOCK_INPUT;
- if (*size_bytes_ret < offset + tmp_size_bytes)
- {
- *size_bytes_ret = offset + tmp_size_bytes;
- *data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
- }
+ if (*size_bytes_ret - offset < tmp_size_bytes)
+ *data_ret = xpalloc (*data_ret, size_bytes_ret,
+ tmp_size_bytes - (*size_bytes_ret - offset),
+ -1, 1);
memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
offset += tmp_size_bytes;
@@ -1482,7 +1533,7 @@ x_get_window_property_as_lisp_data (Display *display, Window window,
int actual_format;
unsigned long actual_size;
unsigned char *data = 0;
- int bytes = 0;
+ ptrdiff_t bytes = 0;
Lisp_Object val;
struct x_display_info *dpyinfo = x_display_info_for_display (display);
@@ -1574,7 +1625,7 @@ x_get_window_property_as_lisp_data (Display *display, Window window,
static Lisp_Object
selection_data_to_lisp_data (Display *display, const unsigned char *data,
- int size, Atom type, int format)
+ ptrdiff_t size, Atom type, int format)
{
struct x_display_info *dpyinfo = x_display_info_for_display (display);
@@ -1607,7 +1658,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
/* Treat ATOM_PAIR type similar to list of atoms. */
|| type == dpyinfo->Xatom_ATOM_PAIR)
{
- int i;
+ ptrdiff_t i;
/* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8.
But the callers of these function has made sure the data for
format == 32 is an array of int. Thus, use int instead
@@ -1634,28 +1685,29 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
else if (format == 32 && size == sizeof (int))
return INTEGER_TO_CONS (((unsigned int *) data) [0]);
else if (format == 16 && size == sizeof (short))
- return make_number ((int) (((unsigned short *) data) [0]));
+ return make_number (((unsigned short *) data) [0]);
/* Convert any other kind of data to a vector of numbers, represented
as above (as an integer, or a cons of two 16 bit integers.)
*/
else if (format == 16)
{
- int i;
+ ptrdiff_t i;
Lisp_Object v;
v = Fmake_vector (make_number (size / 2), make_number (0));
for (i = 0; i < size / 2; i++)
{
- int j = (int) ((unsigned short *) data) [i];
+ EMACS_INT j = ((unsigned short *) data) [i];
Faset (v, make_number (i), make_number (j));
}
return v;
}
else
{
- int i;
- Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0));
- for (i = 0; i < size / 4; i++)
+ ptrdiff_t i;
+ Lisp_Object v = Fmake_vector (make_number (size / X_LONG_SIZE),
+ make_number (0));
+ for (i = 0; i < size / X_LONG_SIZE; i++)
{
unsigned int j = ((unsigned int *) data) [i];
Faset (v, make_number (i), INTEGER_TO_CONS (j));
@@ -1670,7 +1722,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
static void
lisp_data_to_selection_data (Display *display, Lisp_Object obj,
unsigned char **data_ret, Atom *type_ret,
- unsigned int *size_ret,
+ ptrdiff_t *size_ret,
int *format_ret, int *nofree_ret)
{
Lisp_Object type = Qnil;
@@ -1707,22 +1759,20 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
}
else if (SYMBOLP (obj))
{
+ *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
*format_ret = 32;
*size_ret = 1;
- *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
(*data_ret) [sizeof (Atom)] = 0;
(*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj);
if (NILP (type)) type = QATOM;
}
- else if (INTEGERP (obj)
- && XINT (obj) < 0xFFFF
- && XINT (obj) > -0xFFFF)
+ else if (RANGED_INTEGERP (X_SHRT_MIN, obj, X_SHRT_MAX))
{
+ *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
*format_ret = 16;
*size_ret = 1;
- *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
(*data_ret) [sizeof (short)] = 0;
- (*(short **) data_ret) [0] = (short) XINT (obj);
+ (*(short **) data_ret) [0] = XINT (obj);
if (NILP (type)) type = QINTEGER;
}
else if (INTEGERP (obj)
@@ -1731,11 +1781,11 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
|| (CONSP (XCDR (obj))
&& INTEGERP (XCAR (XCDR (obj)))))))
{
+ *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
*format_ret = 32;
*size_ret = 1;
- *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
(*data_ret) [sizeof (long)] = 0;
- (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX);
+ (*(long **) data_ret) [0] = cons_to_signed (obj, X_LONG_MIN, X_LONG_MAX);
if (NILP (type)) type = QINTEGER;
}
else if (VECTORP (obj))
@@ -1744,50 +1794,55 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
a set of 16 or 32 bit INTEGERs;
or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
*/
- int i;
+ ptrdiff_t i;
+ ptrdiff_t size = ASIZE (obj);
if (SYMBOLP (XVECTOR (obj)->contents [0]))
/* This vector is an ATOM set */
{
if (NILP (type)) type = QATOM;
- *size_ret = ASIZE (obj);
- *format_ret = 32;
- for (i = 0; i < *size_ret; i++)
+ for (i = 0; i < size; i++)
if (!SYMBOLP (XVECTOR (obj)->contents [i]))
signal_error ("All elements of selection vector must have same type", obj);
- *data_ret = (unsigned char *) xmalloc ((*size_ret) * sizeof (Atom));
- for (i = 0; i < *size_ret; i++)
+ *data_ret = xnmalloc (size, sizeof (Atom));
+ *format_ret = 32;
+ *size_ret = size;
+ for (i = 0; i < size; i++)
(*(Atom **) data_ret) [i]
= symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]);
}
else
/* This vector is an INTEGER set, or something like it */
{
- int data_size = 2;
- *size_ret = ASIZE (obj);
+ int format = 16;
+ int data_size = sizeof (short);
if (NILP (type)) type = QINTEGER;
- *format_ret = 16;
- for (i = 0; i < *size_ret; i++)
- if (CONSP (XVECTOR (obj)->contents [i]))
- *format_ret = 32;
- else if (!INTEGERP (XVECTOR (obj)->contents [i]))
- signal_error (/* Qselection_error */
- "Elements of selection vector must be integers or conses of integers",
- obj);
-
- /* Use sizeof(long) even if it is more than 32 bits. See comment
- in x_get_window_property and x_fill_property_data. */
-
- if (*format_ret == 32) data_size = sizeof(long);
- *data_ret = (unsigned char *) xmalloc (*size_ret * data_size);
- for (i = 0; i < *size_ret; i++)
- if (*format_ret == 32)
- (*((unsigned long **) data_ret)) [i] =
- cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX);
- else
- (*((unsigned short **) data_ret)) [i] =
- cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX);
+ for (i = 0; i < size; i++)
+ {
+ intmax_t v = cons_to_signed (XVECTOR (obj)->contents[i],
+ X_LONG_MIN, X_LONG_MAX);
+ if (X_SHRT_MIN <= v && v <= X_SHRT_MAX)
+ {
+ /* Use sizeof (long) even if it is more than 32 bits.
+ See comment in x_get_window_property and
+ x_fill_property_data. */
+ data_size = sizeof (long);
+ format = 32;
+ }
+ }
+ *data_ret = xnmalloc (size, data_size);
+ *format_ret = format;
+ *size_ret = size;
+ for (i = 0; i < size; i++)
+ {
+ long v = cons_to_signed (XVECTOR (obj)->contents[i],
+ X_LONG_MIN, X_LONG_MAX);
+ if (format == 32)
+ (*((long **) data_ret)) [i] = v;
+ else
+ (*((short **) data_ret)) [i] = v;
+ }
}
}
else
@@ -1817,8 +1872,8 @@ clean_local_selection_data (Lisp_Object obj)
}
if (VECTORP (obj))
{
- int i;
- int size = ASIZE (obj);
+ ptrdiff_t i;
+ ptrdiff_t size = ASIZE (obj);
Lisp_Object copy;
if (size == 1)
return clean_local_selection_data (XVECTOR (obj)->contents [0]);
@@ -2213,6 +2268,8 @@ x_check_property_data (Lisp_Object data)
else if (CONSP (o) &&
(! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o))))
return -1;
+ if (size == INT_MAX)
+ return -1;
size++;
}
@@ -2294,8 +2351,11 @@ Lisp_Object
x_property_data_to_lisp (struct frame *f, const unsigned char *data,
Atom type, int format, long unsigned int size)
{
+ ptrdiff_t format_bytes = format >> 3;
+ if (PTRDIFF_MAX / format_bytes < size)
+ memory_full (SIZE_MAX);
return selection_data_to_lisp_data (FRAME_X_DISPLAY (f),
- data, size*format/8, type, format);
+ data, size * format_bytes, type, format);
}
/* Get the mouse position in frame relative coordinates. */
@@ -2401,15 +2461,9 @@ FRAME is on. If FRAME is nil, the selected frame is used. */)
return Qnil;
if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
- {
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *dpyinfo->x_dnd_atoms / 2
- < dpyinfo->x_dnd_atoms_size)
- memory_full (SIZE_MAX);
- dpyinfo->x_dnd_atoms_size *= 2;
- dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms,
- sizeof (*dpyinfo->x_dnd_atoms)
- * dpyinfo->x_dnd_atoms_size);
- }
+ dpyinfo->x_dnd_atoms =
+ xpalloc (dpyinfo->x_dnd_atoms, &dpyinfo->x_dnd_atoms_size,
+ 1, -1, sizeof *dpyinfo->x_dnd_atoms);
dpyinfo->x_dnd_atoms[dpyinfo->x_dnd_atoms_length++] = x_atom;
return Qnil;
@@ -2444,7 +2498,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_disp
if (32 < BITS_PER_LONG && event->format == 32)
{
for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */
- idata[i] = (int) event->data.l[i];
+ idata[i] = event->data.l[i];
data = (unsigned char *) idata;
}
diff --git a/src/xsmfns.c b/src/xsmfns.c
index cb56ae648d..55daec7330 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -223,9 +223,11 @@ smc_save_yourself_CB (SmcConn smcConn,
props[props_idx]->name = xstrdup (SmRestartCommand);
props[props_idx]->type = xstrdup (SmLISTofARRAY8);
/* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */
+ if (INT_MAX - 3 < initial_argc)
+ memory_full (SIZE_MAX);
i = 3 + initial_argc;
props[props_idx]->num_vals = i;
- vp = (SmPropValue *) xmalloc (i * sizeof(*vp));
+ vp = xnmalloc (i, sizeof *vp);
props[props_idx]->vals = vp;
props[props_idx]->vals[vp_idx].length = strlen (emacs_program);
props[props_idx]->vals[vp_idx++].value = emacs_program;
diff --git a/src/xterm.c b/src/xterm.c
index 20516ee9d6..c07caec6c7 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -442,6 +442,27 @@ x_display_info_for_display (Display *dpy)
return 0;
}
+static Window
+x_find_topmost_parent (struct frame *f)
+{
+ struct x_output *x = f->output_data.x;
+ Window win = None, wi = x->parent_desc;
+ Display *dpy = FRAME_X_DISPLAY (f);
+
+ while (wi != FRAME_X_DISPLAY_INFO (f)->root_window)
+ {
+ Window root;
+ Window *children;
+ unsigned int nchildren;
+
+ win = wi;
+ XQueryTree (dpy, win, &root, &wi, &children, &nchildren);
+ XFree (children);
+ }
+
+ return win;
+}
+
#define OPAQUE 0xffffffff
void
@@ -453,6 +474,7 @@ x_set_frame_alpha (struct frame *f)
double alpha = 1.0;
double alpha_min = 1.0;
unsigned long opac;
+ Window parent;
if (dpyinfo->x_highlight_frame == f)
alpha = f->alpha[0];
@@ -473,6 +495,19 @@ x_set_frame_alpha (struct frame *f)
opac = alpha * OPAQUE;
+ x_catch_errors (dpy);
+
+ /* If there is a parent from the window manager, put the property there
+ also, to work around broken window managers that fail to do that.
+ Do this unconditionally as this function is called on reparent when
+ alpha has not changed on the frame. */
+
+ parent = x_find_topmost_parent (f);
+ if (parent != None)
+ XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &opac, 1L);
+
/* return unless necessary */
{
unsigned char *data;
@@ -480,7 +515,6 @@ x_set_frame_alpha (struct frame *f)
int rc, format;
unsigned long n, left;
- x_catch_errors (dpy);
rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
0L, 1L, False, XA_CARDINAL,
&actual, &format, &n, &left,
@@ -1625,19 +1659,18 @@ x_color_cells (Display *dpy, int *ncells)
if (dpyinfo->color_cells == NULL)
{
Screen *screen = dpyinfo->screen;
+ int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
int i;
- dpyinfo->ncolor_cells
- = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
- dpyinfo->color_cells
- = (XColor *) xmalloc (dpyinfo->ncolor_cells
- * sizeof *dpyinfo->color_cells);
+ dpyinfo->color_cells = xnmalloc (ncolor_cells,
+ sizeof *dpyinfo->color_cells);
+ dpyinfo->ncolor_cells = ncolor_cells;
- for (i = 0; i < dpyinfo->ncolor_cells; ++i)
+ for (i = 0; i < ncolor_cells; ++i)
dpyinfo->color_cells[i].pixel = i;
XQueryColors (dpy, dpyinfo->cmap,
- dpyinfo->color_cells, dpyinfo->ncolor_cells);
+ dpyinfo->color_cells, ncolor_cells);
}
*ncells = dpyinfo->ncolor_cells;
@@ -4190,7 +4223,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
static struct window **scroll_bar_windows;
-static size_t scroll_bar_windows_size;
+static ptrdiff_t scroll_bar_windows_size;
/* Send a client message with message type Xatom_Scrollbar for a
@@ -4205,7 +4238,7 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
XClientMessageEvent *ev = (XClientMessageEvent *) &event;
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- size_t i;
+ ptrdiff_t i;
BLOCK_INPUT;
@@ -4226,16 +4259,15 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
if (i == scroll_bar_windows_size)
{
- size_t new_size = max (10, 2 * scroll_bar_windows_size);
- size_t nbytes = new_size * sizeof *scroll_bar_windows;
- size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
-
- if ((size_t) -1 / sizeof *scroll_bar_windows < new_size)
- memory_full (SIZE_MAX);
- scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows,
- nbytes);
+ ptrdiff_t old_nbytes =
+ scroll_bar_windows_size * sizeof *scroll_bar_windows;
+ ptrdiff_t nbytes;
+ enum { XClientMessageEvent_MAX = 0x7fffffff };
+ scroll_bar_windows =
+ xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1,
+ XClientMessageEvent_MAX, sizeof *scroll_bar_windows);
+ nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes);
- scroll_bar_windows_size = new_size;
}
scroll_bar_windows[i] = w;
@@ -5813,11 +5845,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
} inev;
int count = 0;
int do_help = 0;
- int nbytes = 0;
+ ptrdiff_t nbytes = 0;
struct frame *f = NULL;
struct coding_system coding;
XEvent event = *eventptr;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+ USE_SAFE_ALLOCA;
*finish = X_EVENT_NORMAL;
@@ -6088,6 +6121,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
/* Perhaps reparented due to a WM restart. Reset this. */
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0;
+
+ x_set_frame_alpha (f);
}
goto OTHER;
@@ -6511,7 +6546,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
}
{ /* Raw bytes, not keysym. */
- register int i;
+ ptrdiff_t i;
int nchars, len;
for (i = 0, nchars = 0; i < nbytes; i++)
@@ -6524,7 +6559,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
if (nchars < nbytes)
{
/* Decode the input data. */
- int require;
/* The input should be decoded with `coding_system'
which depends on which X*LookupString function
@@ -6537,9 +6571,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
gives us composition information. */
coding.common_flags &= ~CODING_ANNOTATION_MASK;
- require = MAX_MULTIBYTE_LENGTH * nbytes;
- coding.destination = alloca (require);
- coding.dst_bytes = require;
+ SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH,
+ nbytes);
+ coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes;
coding.mode |= CODING_MODE_LAST_BLOCK;
decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil);
nbytes = coding.produced;
@@ -6998,6 +7032,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
count++;
}
+ SAFE_FREE ();
*eventptr = event;
return count;
}
@@ -9822,6 +9857,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
struct x_display_info *dpyinfo;
XrmDatabase xrdb;
Mouse_HLInfo *hlinfo;
+ ptrdiff_t lim;
BLOCK_INPUT;
@@ -10040,12 +10076,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
XSetAfterFunction (x_current_display, x_trace_wire);
#endif /* ! 0 */
+ lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@";
+ if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name))
+ memory_full (SIZE_MAX);
dpyinfo->x_id_name
= (char *) xmalloc (SBYTES (Vinvocation_name)
+ SBYTES (Vsystem_name)
+ 2);
- sprintf (dpyinfo->x_id_name, "%s@%s",
- SSDATA (Vinvocation_name), SSDATA (Vsystem_name));
+ strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"),
+ SSDATA (Vsystem_name));
/* Figure out which modifier bits mean what. */
x_find_modifier_meanings (dpyinfo);