diff options
| author | Andrea Corallo | 2020-08-29 11:33:37 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-08-29 11:33:37 +0200 |
| commit | c3514a6274cd6c6ddf2c133ccc708b7875aab90e (patch) | |
| tree | 5f76eefdfef645bca9bc8640accb77c53704116a /src | |
| parent | aa526c9470d679e9144af55d9e56928a111d2ceb (diff) | |
| parent | 7d5807277ff614a337c7e4530bb8d0e0188c189b (diff) | |
| download | emacs-c3514a6274cd6c6ddf2c133ccc708b7875aab90e.tar.gz emacs-c3514a6274cd6c6ddf2c133ccc708b7875aab90e.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
| -rw-r--r-- | src/character.c | 6 | ||||
| -rw-r--r-- | src/coding.c | 10 | ||||
| -rw-r--r-- | src/dispextern.h | 6 | ||||
| -rw-r--r-- | src/editfns.c | 121 | ||||
| -rw-r--r-- | src/fileio.c | 70 | ||||
| -rw-r--r-- | src/font.c | 4 | ||||
| -rw-r--r-- | src/ftfont.c | 4 | ||||
| -rw-r--r-- | src/gnutls.c | 9 | ||||
| -rw-r--r-- | src/gtkutil.c | 2 | ||||
| -rw-r--r-- | src/image.c | 220 | ||||
| -rw-r--r-- | src/keymap.c | 2 | ||||
| -rw-r--r-- | src/nsmenu.m | 2 | ||||
| -rw-r--r-- | src/regex-emacs.c | 61 | ||||
| -rw-r--r-- | src/syntax.c | 10 | ||||
| -rw-r--r-- | src/sysdep.c | 161 | ||||
| -rw-r--r-- | src/window.c | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 48 |
17 files changed, 383 insertions, 359 deletions
diff --git a/src/character.c b/src/character.c index 4902e564b1d..5860f6a0c8c 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -495,9 +495,9 @@ parse_str_as_multibyte (const unsigned char *str, ptrdiff_t len, | |||
| 495 | 495 | ||
| 496 | /* Arrange unibyte text at STR of NBYTES bytes as a multibyte text. | 496 | /* Arrange unibyte text at STR of NBYTES bytes as a multibyte text. |
| 497 | It actually converts only such 8-bit characters that don't construct | 497 | It actually converts only such 8-bit characters that don't construct |
| 498 | a multibyte sequence to multibyte forms of Latin-1 characters. If | 498 | a multibyte sequence to multibyte forms of raw bytes. If NCHARS |
| 499 | NCHARS is nonzero, set *NCHARS to the number of characters in the | 499 | is nonzero, set *NCHARS to the number of characters in the text. |
| 500 | text. It is assured that we can use LEN bytes at STR as a work | 500 | It is assured that we can use LEN bytes at STR as a work |
| 501 | area and that is enough. Return the number of bytes of the | 501 | area and that is enough. Return the number of bytes of the |
| 502 | resulting text. */ | 502 | resulting text. */ |
| 503 | 503 | ||
diff --git a/src/coding.c b/src/coding.c index 51bd441de9d..221a9cad898 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -10895,7 +10895,10 @@ usage: (define-coding-system-internal ...) */) | |||
| 10895 | ASET (attrs, coding_attr_base_name, name); | 10895 | ASET (attrs, coding_attr_base_name, name); |
| 10896 | 10896 | ||
| 10897 | Lisp_Object val = args[coding_arg_mnemonic]; | 10897 | Lisp_Object val = args[coding_arg_mnemonic]; |
| 10898 | if (! STRINGP (val)) | 10898 | /* decode_mode_spec_coding assumes the mnemonic is a single character. */ |
| 10899 | if (STRINGP (val)) | ||
| 10900 | val = make_fixnum (STRING_CHAR (SDATA (val))); | ||
| 10901 | else | ||
| 10899 | CHECK_CHARACTER (val); | 10902 | CHECK_CHARACTER (val); |
| 10900 | ASET (attrs, coding_attr_mnemonic, val); | 10903 | ASET (attrs, coding_attr_mnemonic, val); |
| 10901 | 10904 | ||
| @@ -11408,7 +11411,10 @@ DEFUN ("coding-system-put", Fcoding_system_put, Scoding_system_put, | |||
| 11408 | attrs = AREF (spec, 0); | 11411 | attrs = AREF (spec, 0); |
| 11409 | if (EQ (prop, QCmnemonic)) | 11412 | if (EQ (prop, QCmnemonic)) |
| 11410 | { | 11413 | { |
| 11411 | if (! STRINGP (val)) | 11414 | /* decode_mode_spec_coding assumes the mnemonic is a single character. */ |
| 11415 | if (STRINGP (val)) | ||
| 11416 | val = make_fixnum (STRING_CHAR (SDATA (val))); | ||
| 11417 | else | ||
| 11412 | CHECK_CHARACTER (val); | 11418 | CHECK_CHARACTER (val); |
| 11413 | ASET (attrs, coding_attr_mnemonic, val); | 11419 | ASET (attrs, coding_attr_mnemonic, val); |
| 11414 | } | 11420 | } |
diff --git a/src/dispextern.h b/src/dispextern.h index 311867a0c8c..956ca96eb61 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3056,9 +3056,9 @@ struct image | |||
| 3056 | if necessary. */ | 3056 | if necessary. */ |
| 3057 | unsigned long background; | 3057 | unsigned long background; |
| 3058 | 3058 | ||
| 3059 | /* Foreground and background colors of the frame on which the image | 3059 | /* Foreground and background colors of the face on which the image |
| 3060 | is created. */ | 3060 | is created. */ |
| 3061 | unsigned long frame_foreground, frame_background; | 3061 | unsigned long face_foreground, face_background; |
| 3062 | 3062 | ||
| 3063 | /* True if this image has a `transparent' background -- that is, is | 3063 | /* True if this image has a `transparent' background -- that is, is |
| 3064 | uses an image mask. The accessor macro for this is | 3064 | uses an image mask. The accessor macro for this is |
| @@ -3475,7 +3475,7 @@ void clear_image_caches (Lisp_Object); | |||
| 3475 | void mark_image_cache (struct image_cache *); | 3475 | void mark_image_cache (struct image_cache *); |
| 3476 | bool valid_image_p (Lisp_Object); | 3476 | bool valid_image_p (Lisp_Object); |
| 3477 | void prepare_image_for_display (struct frame *, struct image *); | 3477 | void prepare_image_for_display (struct frame *, struct image *); |
| 3478 | ptrdiff_t lookup_image (struct frame *, Lisp_Object); | 3478 | ptrdiff_t lookup_image (struct frame *, Lisp_Object, int); |
| 3479 | 3479 | ||
| 3480 | #if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS | 3480 | #if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS |
| 3481 | #define RGB_PIXEL_COLOR unsigned long | 3481 | #define RGB_PIXEL_COLOR unsigned long |
diff --git a/src/editfns.c b/src/editfns.c index 949f3825a3c..7e1e24ef16a 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1877,9 +1877,6 @@ determines whether case is significant or ignored. */) | |||
| 1877 | #undef EQUAL | 1877 | #undef EQUAL |
| 1878 | #define USE_HEURISTIC | 1878 | #define USE_HEURISTIC |
| 1879 | 1879 | ||
| 1880 | /* Counter used to rarely_quit in replace-buffer-contents. */ | ||
| 1881 | static unsigned short rbc_quitcounter; | ||
| 1882 | |||
| 1883 | #define XVECREF_YVECREF_EQUAL(ctx, xoff, yoff) \ | 1880 | #define XVECREF_YVECREF_EQUAL(ctx, xoff, yoff) \ |
| 1884 | buffer_chars_equal ((ctx), (xoff), (yoff)) | 1881 | buffer_chars_equal ((ctx), (xoff), (yoff)) |
| 1885 | 1882 | ||
| @@ -1900,10 +1897,11 @@ static unsigned short rbc_quitcounter; | |||
| 1900 | unsigned char *deletions; \ | 1897 | unsigned char *deletions; \ |
| 1901 | unsigned char *insertions; \ | 1898 | unsigned char *insertions; \ |
| 1902 | struct timespec time_limit; \ | 1899 | struct timespec time_limit; \ |
| 1903 | unsigned int early_abort_tests; | 1900 | sys_jmp_buf jmp; \ |
| 1901 | unsigned short quitcounter; | ||
| 1904 | 1902 | ||
| 1905 | #define NOTE_DELETE(ctx, xoff) set_bit ((ctx)->deletions, (xoff)) | 1903 | #define NOTE_DELETE(ctx, xoff) set_bit ((ctx)->deletions, xoff) |
| 1906 | #define NOTE_INSERT(ctx, yoff) set_bit ((ctx)->insertions, (yoff)) | 1904 | #define NOTE_INSERT(ctx, yoff) set_bit ((ctx)->insertions, yoff) |
| 1907 | #define EARLY_ABORT(ctx) compareseq_early_abort (ctx) | 1905 | #define EARLY_ABORT(ctx) compareseq_early_abort (ctx) |
| 1908 | 1906 | ||
| 1909 | struct context; | 1907 | struct context; |
| @@ -1956,6 +1954,28 @@ nil. */) | |||
| 1956 | if (a == b) | 1954 | if (a == b) |
| 1957 | error ("Cannot replace a buffer with itself"); | 1955 | error ("Cannot replace a buffer with itself"); |
| 1958 | 1956 | ||
| 1957 | ptrdiff_t too_expensive; | ||
| 1958 | if (NILP (max_costs)) | ||
| 1959 | too_expensive = 1000000; | ||
| 1960 | else if (FIXNUMP (max_costs)) | ||
| 1961 | too_expensive = clip_to_bounds (0, XFIXNUM (max_costs), PTRDIFF_MAX); | ||
| 1962 | else | ||
| 1963 | { | ||
| 1964 | CHECK_INTEGER (max_costs); | ||
| 1965 | too_expensive = NILP (Fnatnump (max_costs)) ? 0 : PTRDIFF_MAX; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | struct timespec time_limit = make_timespec (0, -1); | ||
| 1969 | if (!NILP (max_secs)) | ||
| 1970 | { | ||
| 1971 | struct timespec | ||
| 1972 | tlim = timespec_add (current_timespec (), | ||
| 1973 | lisp_time_argument (max_secs)), | ||
| 1974 | tmax = make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1); | ||
| 1975 | if (timespec_cmp (tlim, tmax) < 0) | ||
| 1976 | time_limit = tlim; | ||
| 1977 | } | ||
| 1978 | |||
| 1959 | ptrdiff_t min_a = BEGV; | 1979 | ptrdiff_t min_a = BEGV; |
| 1960 | ptrdiff_t min_b = BUF_BEGV (b); | 1980 | ptrdiff_t min_b = BUF_BEGV (b); |
| 1961 | ptrdiff_t size_a = ZV - min_a; | 1981 | ptrdiff_t size_a = ZV - min_a; |
| @@ -1985,36 +2005,24 @@ nil. */) | |||
| 1985 | 2005 | ||
| 1986 | ptrdiff_t count = SPECPDL_INDEX (); | 2006 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1987 | 2007 | ||
| 1988 | /* FIXME: It is not documented how to initialize the contents of the | ||
| 1989 | context structure. This code cargo-cults from the existing | ||
| 1990 | caller in src/analyze.c of GNU Diffutils, which appears to | ||
| 1991 | work. */ | ||
| 1992 | 2008 | ||
| 1993 | ptrdiff_t diags = size_a + size_b + 3; | 2009 | ptrdiff_t diags = size_a + size_b + 3; |
| 2010 | ptrdiff_t del_bytes = size_a / CHAR_BIT + 1; | ||
| 2011 | ptrdiff_t ins_bytes = size_b / CHAR_BIT + 1; | ||
| 1994 | ptrdiff_t *buffer; | 2012 | ptrdiff_t *buffer; |
| 2013 | ptrdiff_t bytes_needed; | ||
| 2014 | if (INT_MULTIPLY_WRAPV (diags, 2 * sizeof *buffer, &bytes_needed) | ||
| 2015 | || INT_ADD_WRAPV (del_bytes + ins_bytes, bytes_needed, &bytes_needed)) | ||
| 2016 | memory_full (SIZE_MAX); | ||
| 1995 | USE_SAFE_ALLOCA; | 2017 | USE_SAFE_ALLOCA; |
| 1996 | SAFE_NALLOCA (buffer, 2, diags); | 2018 | buffer = SAFE_ALLOCA (bytes_needed); |
| 1997 | 2019 | unsigned char *deletions_insertions = memset (buffer + 2 * diags, 0, | |
| 1998 | if (NILP (max_costs)) | 2020 | del_bytes + ins_bytes); |
| 1999 | XSETFASTINT (max_costs, 1000000); | ||
| 2000 | else | ||
| 2001 | CHECK_FIXNUM (max_costs); | ||
| 2002 | |||
| 2003 | struct timespec time_limit = make_timespec (0, -1); | ||
| 2004 | if (!NILP (max_secs)) | ||
| 2005 | { | ||
| 2006 | struct timespec | ||
| 2007 | tlim = timespec_add (current_timespec (), | ||
| 2008 | lisp_time_argument (max_secs)), | ||
| 2009 | tmax = make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1); | ||
| 2010 | if (timespec_cmp (tlim, tmax) < 0) | ||
| 2011 | time_limit = tlim; | ||
| 2012 | } | ||
| 2013 | 2021 | ||
| 2014 | /* Micro-optimization: Casting to size_t generates much better | 2022 | /* FIXME: It is not documented how to initialize the contents of the |
| 2015 | code. */ | 2023 | context structure. This code cargo-cults from the existing |
| 2016 | ptrdiff_t del_bytes = (size_t) size_a / CHAR_BIT + 1; | 2024 | caller in src/analyze.c of GNU Diffutils, which appears to |
| 2017 | ptrdiff_t ins_bytes = (size_t) size_b / CHAR_BIT + 1; | 2025 | work. */ |
| 2018 | struct context ctx = { | 2026 | struct context ctx = { |
| 2019 | .buffer_a = a, | 2027 | .buffer_a = a, |
| 2020 | .buffer_b = b, | 2028 | .buffer_b = b, |
| @@ -2022,21 +2030,22 @@ nil. */) | |||
| 2022 | .beg_b = min_b, | 2030 | .beg_b = min_b, |
| 2023 | .a_unibyte = BUF_ZV (a) == BUF_ZV_BYTE (a), | 2031 | .a_unibyte = BUF_ZV (a) == BUF_ZV_BYTE (a), |
| 2024 | .b_unibyte = BUF_ZV (b) == BUF_ZV_BYTE (b), | 2032 | .b_unibyte = BUF_ZV (b) == BUF_ZV_BYTE (b), |
| 2025 | .deletions = SAFE_ALLOCA (del_bytes), | 2033 | .deletions = deletions_insertions, |
| 2026 | .insertions = SAFE_ALLOCA (ins_bytes), | 2034 | .insertions = deletions_insertions + del_bytes, |
| 2027 | .fdiag = buffer + size_b + 1, | 2035 | .fdiag = buffer + size_b + 1, |
| 2028 | .bdiag = buffer + diags + size_b + 1, | 2036 | .bdiag = buffer + diags + size_b + 1, |
| 2029 | .heuristic = true, | 2037 | .heuristic = true, |
| 2030 | .too_expensive = XFIXNUM (max_costs), | 2038 | .too_expensive = too_expensive, |
| 2031 | .time_limit = time_limit, | 2039 | .time_limit = time_limit, |
| 2032 | .early_abort_tests = 0 | ||
| 2033 | }; | 2040 | }; |
| 2034 | memclear (ctx.deletions, del_bytes); | ||
| 2035 | memclear (ctx.insertions, ins_bytes); | ||
| 2036 | 2041 | ||
| 2037 | /* compareseq requires indices to be zero-based. We add BEGV back | 2042 | /* compareseq requires indices to be zero-based. We add BEGV back |
| 2038 | later. */ | 2043 | later. */ |
| 2039 | bool early_abort = compareseq (0, size_a, 0, size_b, false, &ctx); | 2044 | bool early_abort; |
| 2045 | if (! sys_setjmp (ctx.jmp)) | ||
| 2046 | early_abort = compareseq (0, size_a, 0, size_b, false, &ctx); | ||
| 2047 | else | ||
| 2048 | early_abort = true; | ||
| 2040 | 2049 | ||
| 2041 | if (early_abort) | 2050 | if (early_abort) |
| 2042 | { | 2051 | { |
| @@ -2046,8 +2055,6 @@ nil. */) | |||
| 2046 | return Qnil; | 2055 | return Qnil; |
| 2047 | } | 2056 | } |
| 2048 | 2057 | ||
| 2049 | rbc_quitcounter = 0; | ||
| 2050 | |||
| 2051 | Fundo_boundary (); | 2058 | Fundo_boundary (); |
| 2052 | bool modification_hooks_inhibited = false; | 2059 | bool modification_hooks_inhibited = false; |
| 2053 | record_unwind_protect_excursion (); | 2060 | record_unwind_protect_excursion (); |
| @@ -2071,13 +2078,12 @@ nil. */) | |||
| 2071 | walk backwards, we don’t have to keep the positions in sync. */ | 2078 | walk backwards, we don’t have to keep the positions in sync. */ |
| 2072 | while (i >= 0 || j >= 0) | 2079 | while (i >= 0 || j >= 0) |
| 2073 | { | 2080 | { |
| 2074 | /* Allow the user to quit if this gets too slow. */ | 2081 | rarely_quit (++ctx.quitcounter); |
| 2075 | rarely_quit (++rbc_quitcounter); | ||
| 2076 | 2082 | ||
| 2077 | /* Check whether there is a change (insertion or deletion) | 2083 | /* Check whether there is a change (insertion or deletion) |
| 2078 | before the current position. */ | 2084 | before the current position. */ |
| 2079 | if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) || | 2085 | if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) |
| 2080 | (j > 0 && bit_is_set (ctx.insertions, j - 1))) | 2086 | || (j > 0 && bit_is_set (ctx.insertions, j - 1))) |
| 2081 | { | 2087 | { |
| 2082 | ptrdiff_t end_a = min_a + i; | 2088 | ptrdiff_t end_a = min_a + i; |
| 2083 | ptrdiff_t end_b = min_b + j; | 2089 | ptrdiff_t end_b = min_b + j; |
| @@ -2087,8 +2093,6 @@ nil. */) | |||
| 2087 | while (j > 0 && bit_is_set (ctx.insertions, j - 1)) | 2093 | while (j > 0 && bit_is_set (ctx.insertions, j - 1)) |
| 2088 | --j; | 2094 | --j; |
| 2089 | 2095 | ||
| 2090 | rarely_quit (rbc_quitcounter++); | ||
| 2091 | |||
| 2092 | ptrdiff_t beg_a = min_a + i; | 2096 | ptrdiff_t beg_a = min_a + i; |
| 2093 | ptrdiff_t beg_b = min_b + j; | 2097 | ptrdiff_t beg_b = min_b + j; |
| 2094 | eassert (beg_a <= end_a); | 2098 | eassert (beg_a <= end_a); |
| @@ -2108,7 +2112,6 @@ nil. */) | |||
| 2108 | } | 2112 | } |
| 2109 | 2113 | ||
| 2110 | SAFE_FREE_UNBIND_TO (count, Qnil); | 2114 | SAFE_FREE_UNBIND_TO (count, Qnil); |
| 2111 | rbc_quitcounter = 0; | ||
| 2112 | 2115 | ||
| 2113 | if (modification_hooks_inhibited) | 2116 | if (modification_hooks_inhibited) |
| 2114 | { | 2117 | { |
| @@ -2122,21 +2125,15 @@ nil. */) | |||
| 2122 | static void | 2125 | static void |
| 2123 | set_bit (unsigned char *a, ptrdiff_t i) | 2126 | set_bit (unsigned char *a, ptrdiff_t i) |
| 2124 | { | 2127 | { |
| 2125 | eassert (i >= 0); | 2128 | eassume (0 <= i); |
| 2126 | /* Micro-optimization: Casting to size_t generates much better | 2129 | a[i / CHAR_BIT] |= (1 << (i % CHAR_BIT)); |
| 2127 | code. */ | ||
| 2128 | size_t j = i; | ||
| 2129 | a[j / CHAR_BIT] |= (1 << (j % CHAR_BIT)); | ||
| 2130 | } | 2130 | } |
| 2131 | 2131 | ||
| 2132 | static bool | 2132 | static bool |
| 2133 | bit_is_set (const unsigned char *a, ptrdiff_t i) | 2133 | bit_is_set (const unsigned char *a, ptrdiff_t i) |
| 2134 | { | 2134 | { |
| 2135 | eassert (i >= 0); | 2135 | eassume (0 <= i); |
| 2136 | /* Micro-optimization: Casting to size_t generates much better | 2136 | return a[i / CHAR_BIT] & (1 << (i % CHAR_BIT)); |
| 2137 | code. */ | ||
| 2138 | size_t j = i; | ||
| 2139 | return a[j / CHAR_BIT] & (1 << (j % CHAR_BIT)); | ||
| 2140 | } | 2137 | } |
| 2141 | 2138 | ||
| 2142 | /* Return true if the characters at position POS_A of buffer | 2139 | /* Return true if the characters at position POS_A of buffer |
| @@ -2155,12 +2152,16 @@ static bool | |||
| 2155 | buffer_chars_equal (struct context *ctx, | 2152 | buffer_chars_equal (struct context *ctx, |
| 2156 | ptrdiff_t pos_a, ptrdiff_t pos_b) | 2153 | ptrdiff_t pos_a, ptrdiff_t pos_b) |
| 2157 | { | 2154 | { |
| 2155 | if (!++ctx->quitcounter) | ||
| 2156 | { | ||
| 2157 | maybe_quit (); | ||
| 2158 | if (compareseq_early_abort (ctx)) | ||
| 2159 | sys_longjmp (ctx->jmp, 1); | ||
| 2160 | } | ||
| 2161 | |||
| 2158 | pos_a += ctx->beg_a; | 2162 | pos_a += ctx->beg_a; |
| 2159 | pos_b += ctx->beg_b; | 2163 | pos_b += ctx->beg_b; |
| 2160 | 2164 | ||
| 2161 | /* Allow the user to escape out of a slow compareseq call. */ | ||
| 2162 | rarely_quit (++rbc_quitcounter); | ||
| 2163 | |||
| 2164 | ptrdiff_t bpos_a = | 2165 | ptrdiff_t bpos_a = |
| 2165 | ctx->a_unibyte ? pos_a : buf_charpos_to_bytepos (ctx->buffer_a, pos_a); | 2166 | ctx->a_unibyte ? pos_a : buf_charpos_to_bytepos (ctx->buffer_a, pos_a); |
| 2166 | ptrdiff_t bpos_b = | 2167 | ptrdiff_t bpos_b = |
diff --git a/src/fileio.c b/src/fileio.c index 37072d9b6bd..c91af36fdf6 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -827,9 +827,9 @@ the root directory. */) | |||
| 827 | ptrdiff_t tlen; | 827 | ptrdiff_t tlen; |
| 828 | #ifdef DOS_NT | 828 | #ifdef DOS_NT |
| 829 | int drive = 0; | 829 | int drive = 0; |
| 830 | bool collapse_newdir = true; | ||
| 831 | bool is_escaped = 0; | 830 | bool is_escaped = 0; |
| 832 | #endif /* DOS_NT */ | 831 | #endif /* DOS_NT */ |
| 832 | bool collapse_newdir = true; | ||
| 833 | ptrdiff_t length, nbytes; | 833 | ptrdiff_t length, nbytes; |
| 834 | Lisp_Object handler, result, handled_name; | 834 | Lisp_Object handler, result, handled_name; |
| 835 | bool multibyte; | 835 | bool multibyte; |
| @@ -1065,7 +1065,7 @@ the root directory. */) | |||
| 1065 | #endif /* WINDOWSNT */ | 1065 | #endif /* WINDOWSNT */ |
| 1066 | #endif /* DOS_NT */ | 1066 | #endif /* DOS_NT */ |
| 1067 | 1067 | ||
| 1068 | /* If nm is absolute, look for `/./' or `/../' or `//''sequences; if | 1068 | /* If nm is absolute, look for "/./" or "/../" or "//" sequences; if |
| 1069 | none are found, we can probably return right away. We will avoid | 1069 | none are found, we can probably return right away. We will avoid |
| 1070 | allocating a new string if name is already fully expanded. */ | 1070 | allocating a new string if name is already fully expanded. */ |
| 1071 | if ( | 1071 | if ( |
| @@ -1183,9 +1183,7 @@ the root directory. */) | |||
| 1183 | newdir = SSDATA (hdir); | 1183 | newdir = SSDATA (hdir); |
| 1184 | newdirlim = newdir + SBYTES (hdir); | 1184 | newdirlim = newdir + SBYTES (hdir); |
| 1185 | } | 1185 | } |
| 1186 | #ifdef DOS_NT | ||
| 1187 | collapse_newdir = false; | 1186 | collapse_newdir = false; |
| 1188 | #endif | ||
| 1189 | } | 1187 | } |
| 1190 | else /* ~user/filename */ | 1188 | else /* ~user/filename */ |
| 1191 | { | 1189 | { |
| @@ -1205,9 +1203,7 @@ the root directory. */) | |||
| 1205 | 1203 | ||
| 1206 | while (*++nm && !IS_DIRECTORY_SEP (*nm)) | 1204 | while (*++nm && !IS_DIRECTORY_SEP (*nm)) |
| 1207 | continue; | 1205 | continue; |
| 1208 | #ifdef DOS_NT | ||
| 1209 | collapse_newdir = false; | 1206 | collapse_newdir = false; |
| 1210 | #endif | ||
| 1211 | } | 1207 | } |
| 1212 | 1208 | ||
| 1213 | /* If we don't find a user of that name, leave the name | 1209 | /* If we don't find a user of that name, leave the name |
| @@ -1374,12 +1370,15 @@ the root directory. */) | |||
| 1374 | } | 1370 | } |
| 1375 | #endif /* DOS_NT */ | 1371 | #endif /* DOS_NT */ |
| 1376 | 1372 | ||
| 1373 | length = newdirlim - newdir; | ||
| 1374 | |||
| 1375 | #ifdef DOS_NT | ||
| 1377 | /* Ignore any slash at the end of newdir, unless newdir is | 1376 | /* Ignore any slash at the end of newdir, unless newdir is |
| 1378 | just "/" or "//". */ | 1377 | just "/" or "//". */ |
| 1379 | length = newdirlim - newdir; | ||
| 1380 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1378 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
| 1381 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) | 1379 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) |
| 1382 | length--; | 1380 | length--; |
| 1381 | #endif | ||
| 1383 | 1382 | ||
| 1384 | /* Now concatenate the directory and name to new space in the stack frame. */ | 1383 | /* Now concatenate the directory and name to new space in the stack frame. */ |
| 1385 | tlen = length + file_name_as_directory_slop + (nmlim - nm) + 1; | 1384 | tlen = length + file_name_as_directory_slop + (nmlim - nm) + 1; |
| @@ -1393,12 +1392,16 @@ the root directory. */) | |||
| 1393 | #else /* not DOS_NT */ | 1392 | #else /* not DOS_NT */ |
| 1394 | target = SAFE_ALLOCA (tlen); | 1393 | target = SAFE_ALLOCA (tlen); |
| 1395 | #endif /* not DOS_NT */ | 1394 | #endif /* not DOS_NT */ |
| 1396 | *target = 0; | ||
| 1397 | nbytes = 0; | 1395 | nbytes = 0; |
| 1398 | 1396 | ||
| 1399 | if (newdir) | 1397 | if (newdir) |
| 1400 | { | 1398 | { |
| 1401 | if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) | 1399 | #ifndef DOS_NT |
| 1400 | bool treat_as_absolute = !collapse_newdir; | ||
| 1401 | #else | ||
| 1402 | bool treat_as_absolute = !nm[0] || IS_DIRECTORY_SEP (nm[0]); | ||
| 1403 | #endif | ||
| 1404 | if (treat_as_absolute) | ||
| 1402 | { | 1405 | { |
| 1403 | #ifdef DOS_NT | 1406 | #ifdef DOS_NT |
| 1404 | /* If newdir is effectively "C:/", then the drive letter will have | 1407 | /* If newdir is effectively "C:/", then the drive letter will have |
| @@ -1410,13 +1413,23 @@ the root directory. */) | |||
| 1410 | && newdir[1] == '\0')) | 1413 | && newdir[1] == '\0')) |
| 1411 | #endif | 1414 | #endif |
| 1412 | { | 1415 | { |
| 1416 | /* With ~ or ~user, leave NEWDIR as-is to avoid transforming | ||
| 1417 | it from a symlink (or a regular file!) into a directory. */ | ||
| 1413 | memcpy (target, newdir, length); | 1418 | memcpy (target, newdir, length); |
| 1414 | target[length] = 0; | ||
| 1415 | nbytes = length; | 1419 | nbytes = length; |
| 1416 | } | 1420 | } |
| 1417 | } | 1421 | } |
| 1418 | else | 1422 | else |
| 1419 | nbytes = file_name_as_directory (target, newdir, length, multibyte); | 1423 | nbytes = file_name_as_directory (target, newdir, length, multibyte); |
| 1424 | |||
| 1425 | #ifndef DOS_NT | ||
| 1426 | /* If TARGET ends in a directory separator, omit leading | ||
| 1427 | directory separators from NM so that concatenating a TARGET "/" | ||
| 1428 | to an NM "/foo" does not result in the incorrect "//foo". */ | ||
| 1429 | if (nbytes && IS_DIRECTORY_SEP (target[nbytes - 1])) | ||
| 1430 | while (IS_DIRECTORY_SEP (nm[0])) | ||
| 1431 | nm++; | ||
| 1432 | #endif | ||
| 1420 | } | 1433 | } |
| 1421 | 1434 | ||
| 1422 | memcpy (target + nbytes, nm, nmlim - nm + 1); | 1435 | memcpy (target + nbytes, nm, nmlim - nm + 1); |
| @@ -1433,6 +1446,20 @@ the root directory. */) | |||
| 1433 | { | 1446 | { |
| 1434 | *o++ = *p++; | 1447 | *o++ = *p++; |
| 1435 | } | 1448 | } |
| 1449 | #ifndef DOS_NT | ||
| 1450 | else if (p[1] == '.' && IS_DIRECTORY_SEP (p[2])) | ||
| 1451 | { | ||
| 1452 | /* Replace "/./" with "/". */ | ||
| 1453 | p += 2; | ||
| 1454 | } | ||
| 1455 | else if (p[1] == '.' && !p[2]) | ||
| 1456 | { | ||
| 1457 | /* At the end of the file name, replace "/." with "/". | ||
| 1458 | The trailing "/" is for symlinks. */ | ||
| 1459 | *o++ = *p; | ||
| 1460 | p += 2; | ||
| 1461 | } | ||
| 1462 | #else | ||
| 1436 | else if (p[1] == '.' | 1463 | else if (p[1] == '.' |
| 1437 | && (IS_DIRECTORY_SEP (p[2]) | 1464 | && (IS_DIRECTORY_SEP (p[2]) |
| 1438 | || p[2] == 0)) | 1465 | || p[2] == 0)) |
| @@ -1443,6 +1470,7 @@ the root directory. */) | |||
| 1443 | *o++ = *p; | 1470 | *o++ = *p; |
| 1444 | p += 2; | 1471 | p += 2; |
| 1445 | } | 1472 | } |
| 1473 | #endif | ||
| 1446 | else if (p[1] == '.' && p[2] == '.' | 1474 | else if (p[1] == '.' && p[2] == '.' |
| 1447 | /* `/../' is the "superroot" on certain file systems. | 1475 | /* `/../' is the "superroot" on certain file systems. |
| 1448 | Turned off on DOS_NT systems because they have no | 1476 | Turned off on DOS_NT systems because they have no |
| @@ -1456,21 +1484,35 @@ the root directory. */) | |||
| 1456 | #endif | 1484 | #endif |
| 1457 | && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0)) | 1485 | && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0)) |
| 1458 | { | 1486 | { |
| 1459 | #ifdef WINDOWSNT | 1487 | #ifndef DOS_NT |
| 1488 | while (o != target) | ||
| 1489 | { | ||
| 1490 | o--; | ||
| 1491 | if (IS_DIRECTORY_SEP (*o)) | ||
| 1492 | { | ||
| 1493 | /* Keep "/" at the end of the name, for symlinks. */ | ||
| 1494 | o += p[3] == 0; | ||
| 1495 | |||
| 1496 | break; | ||
| 1497 | } | ||
| 1498 | } | ||
| 1499 | #else | ||
| 1500 | # ifdef WINDOWSNT | ||
| 1460 | char *prev_o = o; | 1501 | char *prev_o = o; |
| 1461 | #endif | 1502 | # endif |
| 1462 | while (o != target && (--o, !IS_DIRECTORY_SEP (*o))) | 1503 | while (o != target && (--o, !IS_DIRECTORY_SEP (*o))) |
| 1463 | continue; | 1504 | continue; |
| 1464 | #ifdef WINDOWSNT | 1505 | # ifdef WINDOWSNT |
| 1465 | /* Don't go below server level in UNC filenames. */ | 1506 | /* Don't go below server level in UNC filenames. */ |
| 1466 | if (o == target + 1 && IS_DIRECTORY_SEP (*o) | 1507 | if (o == target + 1 && IS_DIRECTORY_SEP (*o) |
| 1467 | && IS_DIRECTORY_SEP (*target)) | 1508 | && IS_DIRECTORY_SEP (*target)) |
| 1468 | o = prev_o; | 1509 | o = prev_o; |
| 1469 | else | 1510 | else |
| 1470 | #endif | 1511 | # endif |
| 1471 | /* Keep initial / only if this is the whole name. */ | 1512 | /* Keep initial / only if this is the whole name. */ |
| 1472 | if (o == target && IS_ANY_SEP (*o) && p[3] == 0) | 1513 | if (o == target && IS_ANY_SEP (*o) && p[3] == 0) |
| 1473 | ++o; | 1514 | ++o; |
| 1515 | #endif | ||
| 1474 | p += 3; | 1516 | p += 3; |
| 1475 | } | 1517 | } |
| 1476 | else if (IS_DIRECTORY_SEP (p[1]) | 1518 | else if (IS_DIRECTORY_SEP (p[1]) |
diff --git a/src/font.c b/src/font.c index 5c01c7ff796..2786a772dc3 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -5521,11 +5521,11 @@ footprint in sessions that use lots of different fonts. */); | |||
| 5521 | #endif | 5521 | #endif |
| 5522 | 5522 | ||
| 5523 | DEFVAR_BOOL ("xft-ignore-color-fonts", | 5523 | DEFVAR_BOOL ("xft-ignore-color-fonts", |
| 5524 | Vxft_ignore_color_fonts, | 5524 | xft_ignore_color_fonts, |
| 5525 | doc: /* | 5525 | doc: /* |
| 5526 | Non-nil means don't query fontconfig for color fonts, since they often | 5526 | Non-nil means don't query fontconfig for color fonts, since they often |
| 5527 | cause Xft crashes. Only has an effect in Xft builds. */); | 5527 | cause Xft crashes. Only has an effect in Xft builds. */); |
| 5528 | Vxft_ignore_color_fonts = 1; | 5528 | xft_ignore_color_fonts = true; |
| 5529 | 5529 | ||
| 5530 | #ifdef HAVE_WINDOW_SYSTEM | 5530 | #ifdef HAVE_WINDOW_SYSTEM |
| 5531 | #ifdef HAVE_FREETYPE | 5531 | #ifdef HAVE_FREETYPE |
diff --git a/src/ftfont.c b/src/ftfont.c index a904007a329..6fca9c85093 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -768,7 +768,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots | |||
| 768 | #if defined HAVE_XFT && defined FC_COLOR | 768 | #if defined HAVE_XFT && defined FC_COLOR |
| 769 | /* We really don't like color fonts, they cause Xft crashes. See | 769 | /* We really don't like color fonts, they cause Xft crashes. See |
| 770 | Bug#30874. */ | 770 | Bug#30874. */ |
| 771 | if (Vxft_ignore_color_fonts | 771 | if (xft_ignore_color_fonts |
| 772 | && ! FcPatternAddBool (pattern, FC_COLOR, FcFalse)) | 772 | && ! FcPatternAddBool (pattern, FC_COLOR, FcFalse)) |
| 773 | goto err; | 773 | goto err; |
| 774 | #endif | 774 | #endif |
| @@ -911,7 +911,7 @@ ftfont_list (struct frame *f, Lisp_Object spec) | |||
| 911 | returns them even when it shouldn't really do so, so we | 911 | returns them even when it shouldn't really do so, so we |
| 912 | need to manually skip them here (Bug#37786). */ | 912 | need to manually skip them here (Bug#37786). */ |
| 913 | FcBool b; | 913 | FcBool b; |
| 914 | if (Vxft_ignore_color_fonts | 914 | if (xft_ignore_color_fonts |
| 915 | && FcPatternGetBool (fontset->fonts[i], FC_COLOR, 0, &b) | 915 | && FcPatternGetBool (fontset->fonts[i], FC_COLOR, 0, &b) |
| 916 | == FcResultMatch && b != FcFalse) | 916 | == FcResultMatch && b != FcFalse) |
| 917 | continue; | 917 | continue; |
diff --git a/src/gnutls.c b/src/gnutls.c index 416fb154701..0010553a9d4 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -2298,6 +2298,8 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, | |||
| 2298 | # endif | 2298 | # endif |
| 2299 | } | 2299 | } |
| 2300 | 2300 | ||
| 2301 | static Lisp_Object cipher_cache; | ||
| 2302 | |||
| 2301 | static Lisp_Object | 2303 | static Lisp_Object |
| 2302 | gnutls_symmetric (bool encrypting, Lisp_Object cipher, | 2304 | gnutls_symmetric (bool encrypting, Lisp_Object cipher, |
| 2303 | Lisp_Object key, Lisp_Object iv, | 2305 | Lisp_Object key, Lisp_Object iv, |
| @@ -2329,7 +2331,9 @@ gnutls_symmetric (bool encrypting, Lisp_Object cipher, | |||
| 2329 | 2331 | ||
| 2330 | if (SYMBOLP (cipher)) | 2332 | if (SYMBOLP (cipher)) |
| 2331 | { | 2333 | { |
| 2332 | info = Fassq (cipher, Fgnutls_ciphers ()); | 2334 | if (NILP (cipher_cache)) |
| 2335 | cipher_cache = Fgnutls_ciphers (); | ||
| 2336 | info = Fassq (cipher, cipher_cache); | ||
| 2333 | if (!CONSP (info)) | 2337 | if (!CONSP (info)) |
| 2334 | xsignal2 (Qerror, | 2338 | xsignal2 (Qerror, |
| 2335 | build_string ("GnuTLS cipher is invalid or not found"), | 2339 | build_string ("GnuTLS cipher is invalid or not found"), |
| @@ -2914,6 +2918,9 @@ level in the ones. For builds without libgnutls, the value is -1. */); | |||
| 2914 | defsubr (&Sgnutls_hash_digest); | 2918 | defsubr (&Sgnutls_hash_digest); |
| 2915 | defsubr (&Sgnutls_symmetric_encrypt); | 2919 | defsubr (&Sgnutls_symmetric_encrypt); |
| 2916 | defsubr (&Sgnutls_symmetric_decrypt); | 2920 | defsubr (&Sgnutls_symmetric_decrypt); |
| 2921 | |||
| 2922 | cipher_cache = Qnil; | ||
| 2923 | staticpro (&cipher_cache); | ||
| 2917 | #endif | 2924 | #endif |
| 2918 | 2925 | ||
| 2919 | DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level, | 2926 | DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level, |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 1fe160acca9..fafd94c0f71 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -5113,7 +5113,7 @@ update_frame_tool_bar (struct frame *f) | |||
| 5113 | else | 5113 | else |
| 5114 | idx = -1; | 5114 | idx = -1; |
| 5115 | 5115 | ||
| 5116 | img_id = lookup_image (f, image); | 5116 | img_id = lookup_image (f, image, -1); |
| 5117 | img = IMAGE_FROM_ID (f, img_id); | 5117 | img = IMAGE_FROM_ID (f, img_id); |
| 5118 | prepare_image_for_display (f, img); | 5118 | prepare_image_for_display (f, img); |
| 5119 | 5119 | ||
diff --git a/src/image.c b/src/image.c index 123de54ba27..35c5946c72f 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -758,10 +758,10 @@ struct image_type | |||
| 758 | 758 | ||
| 759 | /* Load IMG which is used on frame F from information contained in | 759 | /* Load IMG which is used on frame F from information contained in |
| 760 | IMG->spec. Value is true if successful. */ | 760 | IMG->spec. Value is true if successful. */ |
| 761 | bool (*load) (struct frame *f, struct image *img); | 761 | bool (*load_img) (struct frame *f, struct image *img); |
| 762 | 762 | ||
| 763 | /* Free resources of image IMG which is used on frame F. */ | 763 | /* Free resources of image IMG which is used on frame F. */ |
| 764 | void (*free) (struct frame *f, struct image *img); | 764 | void (*free_img) (struct frame *f, struct image *img); |
| 765 | 765 | ||
| 766 | #ifdef WINDOWSNT | 766 | #ifdef WINDOWSNT |
| 767 | /* Initialization function (used for dynamic loading of image | 767 | /* Initialization function (used for dynamic loading of image |
| @@ -1081,7 +1081,7 @@ calling this function. */) | |||
| 1081 | if (valid_image_p (spec)) | 1081 | if (valid_image_p (spec)) |
| 1082 | { | 1082 | { |
| 1083 | struct frame *f = decode_window_system_frame (frame); | 1083 | struct frame *f = decode_window_system_frame (frame); |
| 1084 | ptrdiff_t id = lookup_image (f, spec); | 1084 | ptrdiff_t id = lookup_image (f, spec, -1); |
| 1085 | struct image *img = IMAGE_FROM_ID (f, id); | 1085 | struct image *img = IMAGE_FROM_ID (f, id); |
| 1086 | int width = img->width + 2 * img->hmargin; | 1086 | int width = img->width + 2 * img->hmargin; |
| 1087 | int height = img->height + 2 * img->vmargin; | 1087 | int height = img->height + 2 * img->vmargin; |
| @@ -1111,7 +1111,7 @@ or omitted means use the selected frame. */) | |||
| 1111 | if (valid_image_p (spec)) | 1111 | if (valid_image_p (spec)) |
| 1112 | { | 1112 | { |
| 1113 | struct frame *f = decode_window_system_frame (frame); | 1113 | struct frame *f = decode_window_system_frame (frame); |
| 1114 | ptrdiff_t id = lookup_image (f, spec); | 1114 | ptrdiff_t id = lookup_image (f, spec, -1); |
| 1115 | struct image *img = IMAGE_FROM_ID (f, id); | 1115 | struct image *img = IMAGE_FROM_ID (f, id); |
| 1116 | if (img->mask) | 1116 | if (img->mask) |
| 1117 | mask = Qt; | 1117 | mask = Qt; |
| @@ -1134,7 +1134,7 @@ or omitted means use the selected frame. */) | |||
| 1134 | if (valid_image_p (spec)) | 1134 | if (valid_image_p (spec)) |
| 1135 | { | 1135 | { |
| 1136 | struct frame *f = decode_window_system_frame (frame); | 1136 | struct frame *f = decode_window_system_frame (frame); |
| 1137 | ptrdiff_t id = lookup_image (f, spec); | 1137 | ptrdiff_t id = lookup_image (f, spec, -1); |
| 1138 | struct image *img = IMAGE_FROM_ID (f, id); | 1138 | struct image *img = IMAGE_FROM_ID (f, id); |
| 1139 | ext = img->lisp_data; | 1139 | ext = img->lisp_data; |
| 1140 | } | 1140 | } |
| @@ -1197,13 +1197,8 @@ free_image (struct frame *f, struct image *img) | |||
| 1197 | XRenderFreePicture (FRAME_X_DISPLAY (f), img->mask_picture); | 1197 | XRenderFreePicture (FRAME_X_DISPLAY (f), img->mask_picture); |
| 1198 | #endif | 1198 | #endif |
| 1199 | 1199 | ||
| 1200 | /* Windows NT redefines 'free', but in this file, we need to | ||
| 1201 | avoid the redefinition. */ | ||
| 1202 | #ifdef WINDOWSNT | ||
| 1203 | #undef free | ||
| 1204 | #endif | ||
| 1205 | /* Free resources, then free IMG. */ | 1200 | /* Free resources, then free IMG. */ |
| 1206 | img->type->free (f, img); | 1201 | img->type->free_img (f, img); |
| 1207 | xfree (img); | 1202 | xfree (img); |
| 1208 | } | 1203 | } |
| 1209 | } | 1204 | } |
| @@ -1249,7 +1244,7 @@ prepare_image_for_display (struct frame *f, struct image *img) | |||
| 1249 | /* If IMG doesn't have a pixmap yet, load it now, using the image | 1244 | /* If IMG doesn't have a pixmap yet, load it now, using the image |
| 1250 | type dependent loader function. */ | 1245 | type dependent loader function. */ |
| 1251 | if (img->pixmap == NO_PIXMAP && !img->load_failed_p) | 1246 | if (img->pixmap == NO_PIXMAP && !img->load_failed_p) |
| 1252 | img->load_failed_p = ! img->type->load (f, img); | 1247 | img->load_failed_p = ! img->type->load_img (f, img); |
| 1253 | 1248 | ||
| 1254 | #ifdef USE_CAIRO | 1249 | #ifdef USE_CAIRO |
| 1255 | if (!img->load_failed_p) | 1250 | if (!img->load_failed_p) |
| @@ -1266,7 +1261,7 @@ prepare_image_for_display (struct frame *f, struct image *img) | |||
| 1266 | if (img->cr_data == NULL) | 1261 | if (img->cr_data == NULL) |
| 1267 | { | 1262 | { |
| 1268 | img->load_failed_p = 1; | 1263 | img->load_failed_p = 1; |
| 1269 | img->type->free (f, img); | 1264 | img->type->free_img (f, img); |
| 1270 | } | 1265 | } |
| 1271 | } | 1266 | } |
| 1272 | unblock_input (); | 1267 | unblock_input (); |
| @@ -1611,7 +1606,9 @@ equal_lists (Lisp_Object a, Lisp_Object b) | |||
| 1611 | /* Find an image matching SPEC in the cache, and return it. If no | 1606 | /* Find an image matching SPEC in the cache, and return it. If no |
| 1612 | image is found, return NULL. */ | 1607 | image is found, return NULL. */ |
| 1613 | static struct image * | 1608 | static struct image * |
| 1614 | search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) | 1609 | search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash, |
| 1610 | unsigned long foreground, unsigned long background, | ||
| 1611 | bool ignore_colors) | ||
| 1615 | { | 1612 | { |
| 1616 | struct image *img; | 1613 | struct image *img; |
| 1617 | struct image_cache *c = FRAME_IMAGE_CACHE (f); | 1614 | struct image_cache *c = FRAME_IMAGE_CACHE (f); |
| @@ -1634,8 +1631,8 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) | |||
| 1634 | for (img = c->buckets[i]; img; img = img->next) | 1631 | for (img = c->buckets[i]; img; img = img->next) |
| 1635 | if (img->hash == hash | 1632 | if (img->hash == hash |
| 1636 | && equal_lists (img->spec, spec) | 1633 | && equal_lists (img->spec, spec) |
| 1637 | && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f) | 1634 | && (ignore_colors || (img->face_foreground == foreground |
| 1638 | && img->frame_background == FRAME_BACKGROUND_PIXEL (f)) | 1635 | && img->face_background == background))) |
| 1639 | break; | 1636 | break; |
| 1640 | return img; | 1637 | return img; |
| 1641 | } | 1638 | } |
| @@ -1646,8 +1643,13 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) | |||
| 1646 | static void | 1643 | static void |
| 1647 | uncache_image (struct frame *f, Lisp_Object spec) | 1644 | uncache_image (struct frame *f, Lisp_Object spec) |
| 1648 | { | 1645 | { |
| 1649 | struct image *img = search_image_cache (f, spec, sxhash (spec)); | 1646 | struct image *img; |
| 1650 | if (img) | 1647 | |
| 1648 | /* Because the background colors are based on the current face, we | ||
| 1649 | can have multiple copies of an image with the same spec. We want | ||
| 1650 | to remove them all to ensure the user doesn't see an old version | ||
| 1651 | of the image when the face changes. */ | ||
| 1652 | while ((img = search_image_cache (f, spec, sxhash (spec), 0, 0, true))) | ||
| 1651 | { | 1653 | { |
| 1652 | free_image (f, img); | 1654 | free_image (f, img); |
| 1653 | /* As display glyphs may still be referring to the image ID, we | 1655 | /* As display glyphs may still be referring to the image ID, we |
| @@ -2133,7 +2135,17 @@ image_set_transform (struct frame *f, struct image *img) | |||
| 2133 | 2135 | ||
| 2134 | /* Determine size. */ | 2136 | /* Determine size. */ |
| 2135 | int width, height; | 2137 | int width, height; |
| 2136 | compute_image_size (img->width, img->height, img->spec, &width, &height); | 2138 | |
| 2139 | #ifdef HAVE_RSVG | ||
| 2140 | /* SVGs are pre-scaled to the correct size. */ | ||
| 2141 | if (EQ (image_spec_value (img->spec, QCtype, NULL), Qsvg)) | ||
| 2142 | { | ||
| 2143 | width = img->width; | ||
| 2144 | height = img->height; | ||
| 2145 | } | ||
| 2146 | else | ||
| 2147 | #endif | ||
| 2148 | compute_image_size (img->width, img->height, img->spec, &width, &height); | ||
| 2137 | 2149 | ||
| 2138 | /* Determine rotation. */ | 2150 | /* Determine rotation. */ |
| 2139 | double rotation = 0.0; | 2151 | double rotation = 0.0; |
| @@ -2312,11 +2324,16 @@ image_set_transform (struct frame *f, struct image *img) | |||
| 2312 | SPEC must be a valid Lisp image specification (see valid_image_p). */ | 2324 | SPEC must be a valid Lisp image specification (see valid_image_p). */ |
| 2313 | 2325 | ||
| 2314 | ptrdiff_t | 2326 | ptrdiff_t |
| 2315 | lookup_image (struct frame *f, Lisp_Object spec) | 2327 | lookup_image (struct frame *f, Lisp_Object spec, int face_id) |
| 2316 | { | 2328 | { |
| 2317 | struct image *img; | 2329 | struct image *img; |
| 2318 | EMACS_UINT hash; | 2330 | EMACS_UINT hash; |
| 2319 | 2331 | ||
| 2332 | struct face *face = (face_id >= 0) ? FACE_FROM_ID (f, face_id) | ||
| 2333 | : FACE_FROM_ID (f, DEFAULT_FACE_ID); | ||
| 2334 | unsigned long foreground = FACE_COLOR_TO_PIXEL (face->foreground, f); | ||
| 2335 | unsigned long background = FACE_COLOR_TO_PIXEL (face->background, f); | ||
| 2336 | |||
| 2320 | /* F must be a window-system frame, and SPEC must be a valid image | 2337 | /* F must be a window-system frame, and SPEC must be a valid image |
| 2321 | specification. */ | 2338 | specification. */ |
| 2322 | eassert (FRAME_WINDOW_P (f)); | 2339 | eassert (FRAME_WINDOW_P (f)); |
| @@ -2324,7 +2341,7 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 2324 | 2341 | ||
| 2325 | /* Look up SPEC in the hash table of the image cache. */ | 2342 | /* Look up SPEC in the hash table of the image cache. */ |
| 2326 | hash = sxhash (spec); | 2343 | hash = sxhash (spec); |
| 2327 | img = search_image_cache (f, spec, hash); | 2344 | img = search_image_cache (f, spec, hash, foreground, background, true); |
| 2328 | if (img && img->load_failed_p) | 2345 | if (img && img->load_failed_p) |
| 2329 | { | 2346 | { |
| 2330 | free_image (f, img); | 2347 | free_image (f, img); |
| @@ -2337,9 +2354,9 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 2337 | block_input (); | 2354 | block_input (); |
| 2338 | img = make_image (spec, hash); | 2355 | img = make_image (spec, hash); |
| 2339 | cache_image (f, img); | 2356 | cache_image (f, img); |
| 2340 | img->load_failed_p = ! img->type->load (f, img); | 2357 | img->face_foreground = foreground; |
| 2341 | img->frame_foreground = FRAME_FOREGROUND_PIXEL (f); | 2358 | img->face_background = background; |
| 2342 | img->frame_background = FRAME_BACKGROUND_PIXEL (f); | 2359 | img->load_failed_p = ! img->type->load_img (f, img); |
| 2343 | 2360 | ||
| 2344 | /* If we can't load the image, and we don't have a width and | 2361 | /* If we can't load the image, and we don't have a width and |
| 2345 | height, use some arbitrary width and height so that we can | 2362 | height, use some arbitrary width and height so that we can |
| @@ -2393,8 +2410,7 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 2393 | if (!NILP (bg)) | 2410 | if (!NILP (bg)) |
| 2394 | { | 2411 | { |
| 2395 | img->background | 2412 | img->background |
| 2396 | = image_alloc_image_color (f, img, bg, | 2413 | = image_alloc_image_color (f, img, bg, background); |
| 2397 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 2398 | img->background_valid = 1; | 2414 | img->background_valid = 1; |
| 2399 | } | 2415 | } |
| 2400 | } | 2416 | } |
| @@ -3667,8 +3683,8 @@ xbm_load_image (struct frame *f, struct image *img, char *contents, char *end) | |||
| 3667 | &data, 0); | 3683 | &data, 0); |
| 3668 | if (rc) | 3684 | if (rc) |
| 3669 | { | 3685 | { |
| 3670 | unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); | 3686 | unsigned long foreground = img->face_foreground; |
| 3671 | unsigned long background = FRAME_BACKGROUND_PIXEL (f); | 3687 | unsigned long background = img->face_background; |
| 3672 | bool non_default_colors = 0; | 3688 | bool non_default_colors = 0; |
| 3673 | Lisp_Object value; | 3689 | Lisp_Object value; |
| 3674 | 3690 | ||
| @@ -3764,8 +3780,8 @@ xbm_load (struct frame *f, struct image *img) | |||
| 3764 | { | 3780 | { |
| 3765 | struct image_keyword fmt[XBM_LAST]; | 3781 | struct image_keyword fmt[XBM_LAST]; |
| 3766 | Lisp_Object data; | 3782 | Lisp_Object data; |
| 3767 | unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); | 3783 | unsigned long foreground = img->face_foreground; |
| 3768 | unsigned long background = FRAME_BACKGROUND_PIXEL (f); | 3784 | unsigned long background = img->face_background; |
| 3769 | bool non_default_colors = 0; | 3785 | bool non_default_colors = 0; |
| 3770 | char *bits; | 3786 | char *bits; |
| 3771 | bool parsed_p; | 3787 | bool parsed_p; |
| @@ -6125,8 +6141,8 @@ pbm_load (struct frame *f, struct image *img) | |||
| 6125 | unsigned char c = 0; | 6141 | unsigned char c = 0; |
| 6126 | int g; | 6142 | int g; |
| 6127 | struct image_keyword fmt[PBM_LAST]; | 6143 | struct image_keyword fmt[PBM_LAST]; |
| 6128 | unsigned long fg = FRAME_FOREGROUND_PIXEL (f); | 6144 | unsigned long fg = img->face_foreground; |
| 6129 | unsigned long bg = FRAME_BACKGROUND_PIXEL (f); | 6145 | unsigned long bg = img->face_background; |
| 6130 | /* Parse the image specification. */ | 6146 | /* Parse the image specification. */ |
| 6131 | memcpy (fmt, pbm_format, sizeof fmt); | 6147 | memcpy (fmt, pbm_format, sizeof fmt); |
| 6132 | parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); | 6148 | parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); |
| @@ -9433,6 +9449,7 @@ enum svg_keyword_index | |||
| 9433 | SVG_ALGORITHM, | 9449 | SVG_ALGORITHM, |
| 9434 | SVG_HEURISTIC_MASK, | 9450 | SVG_HEURISTIC_MASK, |
| 9435 | SVG_MASK, | 9451 | SVG_MASK, |
| 9452 | SVG_FOREGROUND, | ||
| 9436 | SVG_BACKGROUND, | 9453 | SVG_BACKGROUND, |
| 9437 | SVG_LAST | 9454 | SVG_LAST |
| 9438 | }; | 9455 | }; |
| @@ -9451,6 +9468,7 @@ static const struct image_keyword svg_format[SVG_LAST] = | |||
| 9451 | {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 9468 | {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 9452 | {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 9469 | {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 9453 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 9470 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 9471 | {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, | ||
| 9454 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} | 9472 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
| 9455 | }; | 9473 | }; |
| 9456 | 9474 | ||
| @@ -9715,6 +9733,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9715 | int height; | 9733 | int height; |
| 9716 | const guint8 *pixels; | 9734 | const guint8 *pixels; |
| 9717 | int rowstride; | 9735 | int rowstride; |
| 9736 | char *wrapped_contents = NULL; | ||
| 9737 | ptrdiff_t wrapped_size; | ||
| 9718 | 9738 | ||
| 9719 | #if ! GLIB_CHECK_VERSION (2, 36, 0) | 9739 | #if ! GLIB_CHECK_VERSION (2, 36, 0) |
| 9720 | /* g_type_init is a glib function that must be called prior to | 9740 | /* g_type_init is a glib function that must be called prior to |
| @@ -9722,6 +9742,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9722 | g_type_init (); | 9742 | g_type_init (); |
| 9723 | #endif | 9743 | #endif |
| 9724 | 9744 | ||
| 9745 | /* Parse the unmodified SVG data so we can get its initial size. */ | ||
| 9746 | |||
| 9725 | #if LIBRSVG_CHECK_VERSION (2, 32, 0) | 9747 | #if LIBRSVG_CHECK_VERSION (2, 32, 0) |
| 9726 | GInputStream *input_stream | 9748 | GInputStream *input_stream |
| 9727 | = g_memory_input_stream_new_from_data (contents, size, NULL); | 9749 | = g_memory_input_stream_new_from_data (contents, size, NULL); |
| @@ -9750,6 +9772,105 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9750 | rsvg_handle_write (rsvg_handle, (unsigned char *) contents, size, &err); | 9772 | rsvg_handle_write (rsvg_handle, (unsigned char *) contents, size, &err); |
| 9751 | if (err) goto rsvg_error; | 9773 | if (err) goto rsvg_error; |
| 9752 | 9774 | ||
| 9775 | /* The parsing is complete, rsvg_handle is ready to be used, close | ||
| 9776 | it for further writes. */ | ||
| 9777 | rsvg_handle_close (rsvg_handle, &err); | ||
| 9778 | if (err) goto rsvg_error; | ||
| 9779 | #endif | ||
| 9780 | |||
| 9781 | /* Get the image dimensions. */ | ||
| 9782 | rsvg_handle_get_dimensions (rsvg_handle, &dimension_data); | ||
| 9783 | |||
| 9784 | /* We are now done with the unmodified data. */ | ||
| 9785 | g_object_unref (rsvg_handle); | ||
| 9786 | |||
| 9787 | /* Calculate the final image size. */ | ||
| 9788 | compute_image_size (dimension_data.width, dimension_data.height, | ||
| 9789 | img->spec, &width, &height); | ||
| 9790 | |||
| 9791 | /* Wrap the SVG data in another SVG. This allows us to set the | ||
| 9792 | width and height, as well as modify the foreground and background | ||
| 9793 | colors. */ | ||
| 9794 | { | ||
| 9795 | Lisp_Object value; | ||
| 9796 | unsigned long foreground = img->face_foreground; | ||
| 9797 | unsigned long background = img->face_background; | ||
| 9798 | |||
| 9799 | Lisp_Object encoded_contents | ||
| 9800 | = Fbase64_encode_string (make_unibyte_string (contents, size), Qt); | ||
| 9801 | |||
| 9802 | /* The wrapper sets the foreground color, width and height, and | ||
| 9803 | viewBox must contain the dimensions of the original image. It | ||
| 9804 | also draws a rectangle over the whole space, set to the | ||
| 9805 | background color, before including the original image. This | ||
| 9806 | acts to set the background color, instead of leaving it | ||
| 9807 | transparent. */ | ||
| 9808 | const char *wrapper = | ||
| 9809 | "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" " | ||
| 9810 | "xmlns:xi=\"http://www.w3.org/2001/XInclude\" " | ||
| 9811 | "style=\"color: #%06X; fill: currentColor;\" " | ||
| 9812 | "width=\"%d\" height=\"%d\" preserveAspectRatio=\"none\" " | ||
| 9813 | "viewBox=\"0 0 %d %d\">" | ||
| 9814 | "<rect width=\"100%%\" height=\"100%%\" fill=\"#%06X\"/>" | ||
| 9815 | "<xi:include href=\"data:image/svg+xml;base64,%s\"></xi:include>" | ||
| 9816 | "</svg>"; | ||
| 9817 | |||
| 9818 | /* FIXME: I've added 64 in the hope it will cover the size of the | ||
| 9819 | width and height strings and things. */ | ||
| 9820 | int buffer_size = SBYTES (encoded_contents) + strlen (wrapper) + 64; | ||
| 9821 | |||
| 9822 | value = image_spec_value (img->spec, QCforeground, NULL); | ||
| 9823 | if (!NILP (value)) | ||
| 9824 | foreground = image_alloc_image_color (f, img, value, img->face_foreground); | ||
| 9825 | value = image_spec_value (img->spec, QCbackground, NULL); | ||
| 9826 | if (!NILP (value)) | ||
| 9827 | { | ||
| 9828 | background = image_alloc_image_color (f, img, value, img->face_background); | ||
| 9829 | img->background = background; | ||
| 9830 | img->background_valid = 1; | ||
| 9831 | } | ||
| 9832 | |||
| 9833 | wrapped_contents = malloc (buffer_size); | ||
| 9834 | |||
| 9835 | if (!wrapped_contents | ||
| 9836 | || buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper, | ||
| 9837 | foreground & 0xFFFFFF, width, height, | ||
| 9838 | dimension_data.width, dimension_data.height, | ||
| 9839 | background & 0xFFFFFF, SSDATA (encoded_contents))) | ||
| 9840 | goto rsvg_error; | ||
| 9841 | |||
| 9842 | wrapped_size = strlen (wrapped_contents); | ||
| 9843 | } | ||
| 9844 | |||
| 9845 | /* Now we parse the wrapped version. */ | ||
| 9846 | |||
| 9847 | #if LIBRSVG_CHECK_VERSION (2, 32, 0) | ||
| 9848 | input_stream = g_memory_input_stream_new_from_data (wrapped_contents, wrapped_size, NULL); | ||
| 9849 | base_file = filename ? g_file_new_for_path (filename) : NULL; | ||
| 9850 | rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, | ||
| 9851 | RSVG_HANDLE_FLAGS_NONE, | ||
| 9852 | NULL, &err); | ||
| 9853 | if (base_file) | ||
| 9854 | g_object_unref (base_file); | ||
| 9855 | g_object_unref (input_stream); | ||
| 9856 | |||
| 9857 | /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */ | ||
| 9858 | if (!rsvg_handle || err) goto rsvg_error; | ||
| 9859 | #else | ||
| 9860 | /* Make a handle to a new rsvg object. */ | ||
| 9861 | rsvg_handle = rsvg_handle_new (); | ||
| 9862 | eassume (rsvg_handle); | ||
| 9863 | |||
| 9864 | /* Set base_uri for properly handling referenced images (via 'href'). | ||
| 9865 | See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" | ||
| 9866 | <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */ | ||
| 9867 | if (filename) | ||
| 9868 | rsvg_handle_set_base_uri (rsvg_handle, filename); | ||
| 9869 | |||
| 9870 | /* Parse the contents argument and fill in the rsvg_handle. */ | ||
| 9871 | rsvg_handle_write (rsvg_handle, (unsigned char *) wrapped_contents, wrapped_size, &err); | ||
| 9872 | if (err) goto rsvg_error; | ||
| 9873 | |||
| 9753 | /* The parsing is complete, rsvg_handle is ready to used, close it | 9874 | /* The parsing is complete, rsvg_handle is ready to used, close it |
| 9754 | for further writes. */ | 9875 | for further writes. */ |
| 9755 | rsvg_handle_close (rsvg_handle, &err); | 9876 | rsvg_handle_close (rsvg_handle, &err); |
| @@ -9768,6 +9889,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9768 | pixbuf = rsvg_handle_get_pixbuf (rsvg_handle); | 9889 | pixbuf = rsvg_handle_get_pixbuf (rsvg_handle); |
| 9769 | if (!pixbuf) goto rsvg_error; | 9890 | if (!pixbuf) goto rsvg_error; |
| 9770 | g_object_unref (rsvg_handle); | 9891 | g_object_unref (rsvg_handle); |
| 9892 | free (wrapped_contents); | ||
| 9771 | 9893 | ||
| 9772 | /* Extract some meta data from the svg handle. */ | 9894 | /* Extract some meta data from the svg handle. */ |
| 9773 | width = gdk_pixbuf_get_width (pixbuf); | 9895 | width = gdk_pixbuf_get_width (pixbuf); |
| @@ -9792,25 +9914,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9792 | 9914 | ||
| 9793 | init_color_table (); | 9915 | init_color_table (); |
| 9794 | 9916 | ||
| 9795 | /* Handle alpha channel by combining the image with a background | ||
| 9796 | color. */ | ||
| 9797 | Emacs_Color background; | ||
| 9798 | Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); | ||
| 9799 | if (!STRINGP (specified_bg) | ||
| 9800 | || !FRAME_TERMINAL (f)->defined_color_hook (f, | ||
| 9801 | SSDATA (specified_bg), | ||
| 9802 | &background, | ||
| 9803 | false, | ||
| 9804 | false)) | ||
| 9805 | FRAME_TERMINAL (f)->query_frame_background_color (f, &background); | ||
| 9806 | |||
| 9807 | /* SVG pixmaps specify transparency in the last byte, so right | ||
| 9808 | shift 8 bits to get rid of it, since emacs doesn't support | ||
| 9809 | transparency. */ | ||
| 9810 | background.red >>= 8; | ||
| 9811 | background.green >>= 8; | ||
| 9812 | background.blue >>= 8; | ||
| 9813 | |||
| 9814 | /* This loop handles opacity values, since Emacs assumes | 9917 | /* This loop handles opacity values, since Emacs assumes |
| 9815 | non-transparent images. Each pixel must be "flattened" by | 9918 | non-transparent images. Each pixel must be "flattened" by |
| 9816 | calculating the resulting color, given the transparency of the | 9919 | calculating the resulting color, given the transparency of the |
| @@ -9822,16 +9925,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9822 | int red = *pixels++; | 9925 | int red = *pixels++; |
| 9823 | int green = *pixels++; | 9926 | int green = *pixels++; |
| 9824 | int blue = *pixels++; | 9927 | int blue = *pixels++; |
| 9825 | int opacity = *pixels++; | ||
| 9826 | 9928 | ||
| 9827 | red = ((red * opacity) | 9929 | /* Skip opacity. */ |
| 9828 | + (background.red * ((1 << 8) - opacity))); | 9930 | pixels++; |
| 9829 | green = ((green * opacity) | ||
| 9830 | + (background.green * ((1 << 8) - opacity))); | ||
| 9831 | blue = ((blue * opacity) | ||
| 9832 | + (background.blue * ((1 << 8) - opacity))); | ||
| 9833 | 9931 | ||
| 9834 | PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red, green, blue)); | 9932 | PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red << 8, green << 8, blue << 8)); |
| 9835 | } | 9933 | } |
| 9836 | 9934 | ||
| 9837 | pixels += rowstride - 4 * width; | 9935 | pixels += rowstride - 4 * width; |
| @@ -9861,6 +9959,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | |||
| 9861 | rsvg_error: | 9959 | rsvg_error: |
| 9862 | if (rsvg_handle) | 9960 | if (rsvg_handle) |
| 9863 | g_object_unref (rsvg_handle); | 9961 | g_object_unref (rsvg_handle); |
| 9962 | if (wrapped_contents) | ||
| 9963 | free (wrapped_contents); | ||
| 9864 | /* FIXME: Use error->message so the user knows what is the actual | 9964 | /* FIXME: Use error->message so the user knows what is the actual |
| 9865 | problem with the image. */ | 9965 | problem with the image. */ |
| 9866 | image_error ("Error parsing SVG image `%s'", img->spec); | 9966 | image_error ("Error parsing SVG image `%s'", img->spec); |
| @@ -10159,7 +10259,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, | |||
| 10159 | ptrdiff_t id = -1; | 10259 | ptrdiff_t id = -1; |
| 10160 | 10260 | ||
| 10161 | if (valid_image_p (spec)) | 10261 | if (valid_image_p (spec)) |
| 10162 | id = lookup_image (SELECTED_FRAME (), spec); | 10262 | id = lookup_image (SELECTED_FRAME (), spec, -1); |
| 10163 | 10263 | ||
| 10164 | debug_print (spec); | 10264 | debug_print (spec); |
| 10165 | return make_fixnum (id); | 10265 | return make_fixnum (id); |
diff --git a/src/keymap.c b/src/keymap.c index d98b27b7a1b..0608bdddeea 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -3277,7 +3277,7 @@ describe_map (Lisp_Object map, Lisp_Object prefix, | |||
| 3277 | ptrdiff_t pt = max (PT - 1, BEG); | 3277 | ptrdiff_t pt = max (PT - 1, BEG); |
| 3278 | 3278 | ||
| 3279 | SET_PT (pt); | 3279 | SET_PT (pt); |
| 3280 | insert_string ("\n (that binding is currently shadowed by another mode)"); | 3280 | insert_string ("\n (this binding is currently shadowed)"); |
| 3281 | pt = min (PT + 1, Z); | 3281 | pt = min (PT + 1, Z); |
| 3282 | SET_PT (pt); | 3282 | SET_PT (pt); |
| 3283 | } | 3283 | } |
diff --git a/src/nsmenu.m b/src/nsmenu.m index b7e4cbd5654..e313fc03f40 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -1092,7 +1092,7 @@ update_frame_tool_bar (struct frame *f) | |||
| 1092 | continue; | 1092 | continue; |
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | img_id = lookup_image (f, image); | 1095 | img_id = lookup_image (f, image, -1); |
| 1096 | img = IMAGE_FROM_ID (f, img_id); | 1096 | img = IMAGE_FROM_ID (f, img_id); |
| 1097 | prepare_image_for_display (f, img); | 1097 | prepare_image_for_display (f, img); |
| 1098 | 1098 | ||
diff --git a/src/regex-emacs.c b/src/regex-emacs.c index c44cce9f787..971a5f63749 100644 --- a/src/regex-emacs.c +++ b/src/regex-emacs.c | |||
| @@ -929,7 +929,7 @@ typedef struct | |||
| 929 | ? 0 \ | 929 | ? 0 \ |
| 930 | : ((fail_stack).stack \ | 930 | : ((fail_stack).stack \ |
| 931 | = REGEX_REALLOCATE ((fail_stack).stack, \ | 931 | = REGEX_REALLOCATE ((fail_stack).stack, \ |
| 932 | (fail_stack).size * sizeof (fail_stack_elt_t), \ | 932 | (fail_stack).avail * sizeof (fail_stack_elt_t), \ |
| 933 | min (emacs_re_max_failures * TYPICAL_FAILURE_SIZE, \ | 933 | min (emacs_re_max_failures * TYPICAL_FAILURE_SIZE, \ |
| 934 | ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR)) \ | 934 | ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR)) \ |
| 935 | * sizeof (fail_stack_elt_t)), \ | 935 | * sizeof (fail_stack_elt_t)), \ |
| @@ -969,7 +969,11 @@ typedef struct | |||
| 969 | #define ENSURE_FAIL_STACK(space) \ | 969 | #define ENSURE_FAIL_STACK(space) \ |
| 970 | while (REMAINING_AVAIL_SLOTS <= space) { \ | 970 | while (REMAINING_AVAIL_SLOTS <= space) { \ |
| 971 | if (!GROW_FAIL_STACK (fail_stack)) \ | 971 | if (!GROW_FAIL_STACK (fail_stack)) \ |
| 972 | return -2; \ | 972 | { \ |
| 973 | unbind_to (count, Qnil); \ | ||
| 974 | SAFE_FREE (); \ | ||
| 975 | return -2; \ | ||
| 976 | } \ | ||
| 973 | DEBUG_PRINT ("\n Doubled stack; size now: %td\n", fail_stack.size); \ | 977 | DEBUG_PRINT ("\n Doubled stack; size now: %td\n", fail_stack.size); \ |
| 974 | DEBUG_PRINT (" slots available: %td\n", REMAINING_AVAIL_SLOTS);\ | 978 | DEBUG_PRINT (" slots available: %td\n", REMAINING_AVAIL_SLOTS);\ |
| 975 | } | 979 | } |
| @@ -979,6 +983,8 @@ while (REMAINING_AVAIL_SLOTS <= space) { \ | |||
| 979 | do { \ | 983 | do { \ |
| 980 | char *destination; \ | 984 | char *destination; \ |
| 981 | intptr_t n = num; \ | 985 | intptr_t n = num; \ |
| 986 | eassert (0 < n && n < num_regs); \ | ||
| 987 | eassert (REG_UNSET (regstart[n]) <= REG_UNSET (regend[n])); \ | ||
| 982 | ENSURE_FAIL_STACK(3); \ | 988 | ENSURE_FAIL_STACK(3); \ |
| 983 | DEBUG_PRINT (" Push reg %"PRIdPTR" (spanning %p -> %p)\n", \ | 989 | DEBUG_PRINT (" Push reg %"PRIdPTR" (spanning %p -> %p)\n", \ |
| 984 | n, regstart[n], regend[n]); \ | 990 | n, regstart[n], regend[n]); \ |
| @@ -1017,8 +1023,10 @@ do { \ | |||
| 1017 | } \ | 1023 | } \ |
| 1018 | else \ | 1024 | else \ |
| 1019 | { \ | 1025 | { \ |
| 1026 | eassert (0 < pfreg && pfreg < num_regs); \ | ||
| 1020 | regend[pfreg] = POP_FAILURE_POINTER (); \ | 1027 | regend[pfreg] = POP_FAILURE_POINTER (); \ |
| 1021 | regstart[pfreg] = POP_FAILURE_POINTER (); \ | 1028 | regstart[pfreg] = POP_FAILURE_POINTER (); \ |
| 1029 | eassert (REG_UNSET (regstart[pfreg]) <= REG_UNSET (regend[pfreg])); \ | ||
| 1022 | DEBUG_PRINT (" Pop reg %ld (spanning %p -> %p)\n", \ | 1030 | DEBUG_PRINT (" Pop reg %ld (spanning %p -> %p)\n", \ |
| 1023 | pfreg, regstart[pfreg], regend[pfreg]); \ | 1031 | pfreg, regstart[pfreg], regend[pfreg]); \ |
| 1024 | } \ | 1032 | } \ |
| @@ -3864,6 +3872,10 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 3864 | re_char *string2, ptrdiff_t size2, | 3872 | re_char *string2, ptrdiff_t size2, |
| 3865 | ptrdiff_t pos, struct re_registers *regs, ptrdiff_t stop) | 3873 | ptrdiff_t pos, struct re_registers *regs, ptrdiff_t stop) |
| 3866 | { | 3874 | { |
| 3875 | eassume (0 <= size1); | ||
| 3876 | eassume (0 <= size2); | ||
| 3877 | eassume (0 <= pos && pos <= stop && stop <= size1 + size2); | ||
| 3878 | |||
| 3867 | /* General temporaries. */ | 3879 | /* General temporaries. */ |
| 3868 | int mcnt; | 3880 | int mcnt; |
| 3869 | 3881 | ||
| @@ -3919,8 +3931,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 3919 | attempt) by a subexpression part of the pattern, that is, the | 3931 | attempt) by a subexpression part of the pattern, that is, the |
| 3920 | regnum-th regstart pointer points to where in the pattern we began | 3932 | regnum-th regstart pointer points to where in the pattern we began |
| 3921 | matching and the regnum-th regend points to right after where we | 3933 | matching and the regnum-th regend points to right after where we |
| 3922 | stopped matching the regnum-th subexpression. (The zeroth register | 3934 | stopped matching the regnum-th subexpression. */ |
| 3923 | keeps track of what the whole pattern matches.) */ | ||
| 3924 | re_char **regstart UNINIT, **regend UNINIT; | 3935 | re_char **regstart UNINIT, **regend UNINIT; |
| 3925 | 3936 | ||
| 3926 | /* The following record the register info as found in the above | 3937 | /* The following record the register info as found in the above |
| @@ -3969,29 +3980,22 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 3969 | /* Do not bother to initialize all the register variables if there are | 3980 | /* Do not bother to initialize all the register variables if there are |
| 3970 | no groups in the pattern, as it takes a fair amount of time. If | 3981 | no groups in the pattern, as it takes a fair amount of time. If |
| 3971 | there are groups, we include space for register 0 (the whole | 3982 | there are groups, we include space for register 0 (the whole |
| 3972 | pattern), even though we never use it, since it simplifies the | 3983 | pattern) in REGSTART[0], even though we never use it, to avoid |
| 3973 | array indexing. We should fix this. */ | 3984 | the undefined behavior of subtracting 1 from REGSTART. */ |
| 3974 | if (bufp->re_nsub) | 3985 | ptrdiff_t re_nsub = num_regs - 1; |
| 3986 | if (0 < re_nsub) | ||
| 3975 | { | 3987 | { |
| 3976 | regstart = SAFE_ALLOCA (num_regs * 4 * sizeof *regstart); | 3988 | regstart = SAFE_ALLOCA ((re_nsub * 4 + 1) * sizeof *regstart); |
| 3977 | regend = regstart + num_regs; | 3989 | regend = regstart + num_regs; |
| 3978 | best_regstart = regend + num_regs; | 3990 | best_regstart = regend + re_nsub; |
| 3979 | best_regend = best_regstart + num_regs; | 3991 | best_regend = best_regstart + re_nsub; |
| 3980 | } | ||
| 3981 | 3992 | ||
| 3982 | /* The starting position is bogus. */ | 3993 | /* Initialize subexpression text positions to unset, to mark ones |
| 3983 | if (pos < 0 || pos > size1 + size2) | 3994 | that no start_memory/stop_memory has been seen for. */ |
| 3984 | { | 3995 | for (re_char **apos = regstart + 1; apos < best_regstart + 1; apos++) |
| 3985 | unbind_to (count, Qnil); | 3996 | *apos = NULL; |
| 3986 | SAFE_FREE (); | ||
| 3987 | return -1; | ||
| 3988 | } | 3997 | } |
| 3989 | 3998 | ||
| 3990 | /* Initialize subexpression text positions to -1 to mark ones that no | ||
| 3991 | start_memory/stop_memory has been seen for. */ | ||
| 3992 | for (ptrdiff_t reg = 1; reg < num_regs; reg++) | ||
| 3993 | regstart[reg] = regend[reg] = NULL; | ||
| 3994 | |||
| 3995 | /* We move 'string1' into 'string2' if the latter's empty -- but not if | 3999 | /* We move 'string1' into 'string2' if the latter's empty -- but not if |
| 3996 | 'string1' is null. */ | 4000 | 'string1' is null. */ |
| 3997 | if (size2 == 0 && string1 != NULL) | 4001 | if (size2 == 0 && string1 != NULL) |
| @@ -4126,6 +4130,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 4126 | { | 4130 | { |
| 4127 | regstart[reg] = best_regstart[reg]; | 4131 | regstart[reg] = best_regstart[reg]; |
| 4128 | regend[reg] = best_regend[reg]; | 4132 | regend[reg] = best_regend[reg]; |
| 4133 | eassert (REG_UNSET (regstart[reg]) | ||
| 4134 | <= REG_UNSET (regend[reg])); | ||
| 4129 | } | 4135 | } |
| 4130 | } | 4136 | } |
| 4131 | } /* d != end_match_2 */ | 4137 | } /* d != end_match_2 */ |
| @@ -4173,7 +4179,9 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 4173 | 4179 | ||
| 4174 | for (ptrdiff_t reg = 1; reg < num_regs; reg++) | 4180 | for (ptrdiff_t reg = 1; reg < num_regs; reg++) |
| 4175 | { | 4181 | { |
| 4176 | if (REG_UNSET (regstart[reg]) || REG_UNSET (regend[reg])) | 4182 | eassert (REG_UNSET (regstart[reg]) |
| 4183 | <= REG_UNSET (regend[reg])); | ||
| 4184 | if (REG_UNSET (regend[reg])) | ||
| 4177 | regs->start[reg] = regs->end[reg] = -1; | 4185 | regs->start[reg] = regs->end[reg] = -1; |
| 4178 | else | 4186 | else |
| 4179 | { | 4187 | { |
| @@ -4373,12 +4381,12 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 4373 | registers data structure) under the register number. */ | 4381 | registers data structure) under the register number. */ |
| 4374 | case start_memory: | 4382 | case start_memory: |
| 4375 | DEBUG_PRINT ("EXECUTING start_memory %d:\n", *p); | 4383 | DEBUG_PRINT ("EXECUTING start_memory %d:\n", *p); |
| 4384 | eassert (0 < *p && *p < num_regs); | ||
| 4376 | 4385 | ||
| 4377 | /* In case we need to undo this operation (via backtracking). */ | 4386 | /* In case we need to undo this operation (via backtracking). */ |
| 4378 | PUSH_FAILURE_REG (*p); | 4387 | PUSH_FAILURE_REG (*p); |
| 4379 | 4388 | ||
| 4380 | regstart[*p] = d; | 4389 | regstart[*p] = d; |
| 4381 | regend[*p] = NULL; /* probably unnecessary. -sm */ | ||
| 4382 | DEBUG_PRINT (" regstart: %td\n", POINTER_TO_OFFSET (regstart[*p])); | 4390 | DEBUG_PRINT (" regstart: %td\n", POINTER_TO_OFFSET (regstart[*p])); |
| 4383 | 4391 | ||
| 4384 | /* Move past the register number and inner group count. */ | 4392 | /* Move past the register number and inner group count. */ |
| @@ -4391,6 +4399,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 4391 | case stop_memory: | 4399 | case stop_memory: |
| 4392 | DEBUG_PRINT ("EXECUTING stop_memory %d:\n", *p); | 4400 | DEBUG_PRINT ("EXECUTING stop_memory %d:\n", *p); |
| 4393 | 4401 | ||
| 4402 | eassert (0 < *p && *p < num_regs); | ||
| 4394 | eassert (!REG_UNSET (regstart[*p])); | 4403 | eassert (!REG_UNSET (regstart[*p])); |
| 4395 | /* Strictly speaking, there should be code such as: | 4404 | /* Strictly speaking, there should be code such as: |
| 4396 | 4405 | ||
| @@ -4423,7 +4432,9 @@ re_match_2_internal (struct re_pattern_buffer *bufp, | |||
| 4423 | DEBUG_PRINT ("EXECUTING duplicate %d.\n", regno); | 4432 | DEBUG_PRINT ("EXECUTING duplicate %d.\n", regno); |
| 4424 | 4433 | ||
| 4425 | /* Can't back reference a group which we've never matched. */ | 4434 | /* Can't back reference a group which we've never matched. */ |
| 4426 | if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) | 4435 | eassert (0 < regno && regno < num_regs); |
| 4436 | eassert (REG_UNSET (regstart[regno]) <= REG_UNSET (regend[regno])); | ||
| 4437 | if (REG_UNSET (regend[regno])) | ||
| 4427 | goto fail; | 4438 | goto fail; |
| 4428 | 4439 | ||
| 4429 | /* Where in input to try to start matching. */ | 4440 | /* Where in input to try to start matching. */ |
diff --git a/src/syntax.c b/src/syntax.c index 9f77ea5f9b0..7f0fc341f6e 100644 --- a/src/syntax.c +++ b/src/syntax.c | |||
| @@ -807,7 +807,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, | |||
| 807 | 807 | ||
| 808 | /* Ignore escaped characters, except comment-enders which cannot | 808 | /* Ignore escaped characters, except comment-enders which cannot |
| 809 | be escaped. */ | 809 | be escaped. */ |
| 810 | if ((Vcomment_end_can_be_escaped || code != Sendcomment) | 810 | if ((comment_end_can_be_escaped || code != Sendcomment) |
| 811 | && char_quoted (from, from_byte)) | 811 | && char_quoted (from, from_byte)) |
| 812 | continue; | 812 | continue; |
| 813 | 813 | ||
| @@ -2336,7 +2336,7 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, | |||
| 2336 | && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style | 2336 | && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style |
| 2337 | && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ? | 2337 | && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ? |
| 2338 | (nesting > 0 && --nesting == 0) : nesting < 0) | 2338 | (nesting > 0 && --nesting == 0) : nesting < 0) |
| 2339 | && !(Vcomment_end_can_be_escaped && char_quoted (from, from_byte))) | 2339 | && !(comment_end_can_be_escaped && char_quoted (from, from_byte))) |
| 2340 | /* We have encountered a comment end of the same style | 2340 | /* We have encountered a comment end of the same style |
| 2341 | as the comment sequence which began this comment | 2341 | as the comment sequence which began this comment |
| 2342 | section. */ | 2342 | section. */ |
| @@ -2569,7 +2569,7 @@ between them, return t; otherwise return nil. */) | |||
| 2569 | } | 2569 | } |
| 2570 | else if (code == Sendcomment) | 2570 | else if (code == Sendcomment) |
| 2571 | { | 2571 | { |
| 2572 | found = (!quoted || !Vcomment_end_can_be_escaped) | 2572 | found = (!quoted || !comment_end_can_be_escaped) |
| 2573 | && back_comment (from, from_byte, stop, comnested, comstyle, | 2573 | && back_comment (from, from_byte, stop, comnested, comstyle, |
| 2574 | &out_charpos, &out_bytepos); | 2574 | &out_charpos, &out_bytepos); |
| 2575 | if (!found) | 2575 | if (!found) |
| @@ -3760,9 +3760,9 @@ character of that word. | |||
| 3760 | In both cases, LIMIT bounds the search. */); | 3760 | In both cases, LIMIT bounds the search. */); |
| 3761 | Vfind_word_boundary_function_table = Fmake_char_table (Qnil, Qnil); | 3761 | Vfind_word_boundary_function_table = Fmake_char_table (Qnil, Qnil); |
| 3762 | 3762 | ||
| 3763 | DEFVAR_BOOL ("comment-end-can-be-escaped", Vcomment_end_can_be_escaped, | 3763 | DEFVAR_BOOL ("comment-end-can-be-escaped", comment_end_can_be_escaped, |
| 3764 | doc: /* Non-nil means an escaped ender inside a comment doesn't end the comment. */); | 3764 | doc: /* Non-nil means an escaped ender inside a comment doesn't end the comment. */); |
| 3765 | Vcomment_end_can_be_escaped = 0; | 3765 | comment_end_can_be_escaped = false; |
| 3766 | DEFSYM (Qcomment_end_can_be_escaped, "comment-end-can-be-escaped"); | 3766 | DEFSYM (Qcomment_end_can_be_escaped, "comment-end-can-be-escaped"); |
| 3767 | Fmake_variable_buffer_local (Qcomment_end_can_be_escaped); | 3767 | Fmake_variable_buffer_local (Qcomment_end_can_be_escaped); |
| 3768 | 3768 | ||
diff --git a/src/sysdep.c b/src/sysdep.c index a1050c4309a..e161172a79b 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -1761,24 +1761,6 @@ deliver_thread_signal (int sig, signal_handler_t handler) | |||
| 1761 | errno = old_errno; | 1761 | errno = old_errno; |
| 1762 | } | 1762 | } |
| 1763 | 1763 | ||
| 1764 | #if !HAVE_DECL_SYS_SIGLIST | ||
| 1765 | # undef sys_siglist | ||
| 1766 | # ifdef _sys_siglist | ||
| 1767 | # define sys_siglist _sys_siglist | ||
| 1768 | # elif HAVE_DECL___SYS_SIGLIST | ||
| 1769 | # define sys_siglist __sys_siglist | ||
| 1770 | # else | ||
| 1771 | # define sys_siglist my_sys_siglist | ||
| 1772 | static char const *sys_siglist[NSIG]; | ||
| 1773 | # endif | ||
| 1774 | #endif | ||
| 1775 | |||
| 1776 | #ifdef _sys_nsig | ||
| 1777 | # define sys_siglist_entries _sys_nsig | ||
| 1778 | #else | ||
| 1779 | # define sys_siglist_entries NSIG | ||
| 1780 | #endif | ||
| 1781 | |||
| 1782 | /* Handle bus errors, invalid instruction, etc. */ | 1764 | /* Handle bus errors, invalid instruction, etc. */ |
| 1783 | static void | 1765 | static void |
| 1784 | handle_fatal_signal (int sig) | 1766 | handle_fatal_signal (int sig) |
| @@ -1970,143 +1952,6 @@ init_signals (void) | |||
| 1970 | main_thread_id = pthread_self (); | 1952 | main_thread_id = pthread_self (); |
| 1971 | #endif | 1953 | #endif |
| 1972 | 1954 | ||
| 1973 | #if !HAVE_DECL_SYS_SIGLIST && !defined _sys_siglist | ||
| 1974 | if (! initialized) | ||
| 1975 | { | ||
| 1976 | sys_siglist[SIGABRT] = "Aborted"; | ||
| 1977 | # ifdef SIGAIO | ||
| 1978 | sys_siglist[SIGAIO] = "LAN I/O interrupt"; | ||
| 1979 | # endif | ||
| 1980 | sys_siglist[SIGALRM] = "Alarm clock"; | ||
| 1981 | # ifdef SIGBUS | ||
| 1982 | sys_siglist[SIGBUS] = "Bus error"; | ||
| 1983 | # endif | ||
| 1984 | # ifdef SIGCHLD | ||
| 1985 | sys_siglist[SIGCHLD] = "Child status changed"; | ||
| 1986 | # endif | ||
| 1987 | # ifdef SIGCONT | ||
| 1988 | sys_siglist[SIGCONT] = "Continued"; | ||
| 1989 | # endif | ||
| 1990 | # ifdef SIGDANGER | ||
| 1991 | sys_siglist[SIGDANGER] = "Swap space dangerously low"; | ||
| 1992 | # endif | ||
| 1993 | # ifdef SIGDGNOTIFY | ||
| 1994 | sys_siglist[SIGDGNOTIFY] = "Notification message in queue"; | ||
| 1995 | # endif | ||
| 1996 | # ifdef SIGEMT | ||
| 1997 | sys_siglist[SIGEMT] = "Emulation trap"; | ||
| 1998 | # endif | ||
| 1999 | sys_siglist[SIGFPE] = "Arithmetic exception"; | ||
| 2000 | # ifdef SIGFREEZE | ||
| 2001 | sys_siglist[SIGFREEZE] = "SIGFREEZE"; | ||
| 2002 | # endif | ||
| 2003 | # ifdef SIGGRANT | ||
| 2004 | sys_siglist[SIGGRANT] = "Monitor mode granted"; | ||
| 2005 | # endif | ||
| 2006 | sys_siglist[SIGHUP] = "Hangup"; | ||
| 2007 | sys_siglist[SIGILL] = "Illegal instruction"; | ||
| 2008 | sys_siglist[SIGINT] = "Interrupt"; | ||
| 2009 | # ifdef SIGIO | ||
| 2010 | sys_siglist[SIGIO] = "I/O possible"; | ||
| 2011 | # endif | ||
| 2012 | # ifdef SIGIOINT | ||
| 2013 | sys_siglist[SIGIOINT] = "I/O intervention required"; | ||
| 2014 | # endif | ||
| 2015 | # ifdef SIGIOT | ||
| 2016 | sys_siglist[SIGIOT] = "IOT trap"; | ||
| 2017 | # endif | ||
| 2018 | sys_siglist[SIGKILL] = "Killed"; | ||
| 2019 | # ifdef SIGLOST | ||
| 2020 | sys_siglist[SIGLOST] = "Resource lost"; | ||
| 2021 | # endif | ||
| 2022 | # ifdef SIGLWP | ||
| 2023 | sys_siglist[SIGLWP] = "SIGLWP"; | ||
| 2024 | # endif | ||
| 2025 | # ifdef SIGMSG | ||
| 2026 | sys_siglist[SIGMSG] = "Monitor mode data available"; | ||
| 2027 | # endif | ||
| 2028 | # ifdef SIGPHONE | ||
| 2029 | sys_siglist[SIGWIND] = "SIGPHONE"; | ||
| 2030 | # endif | ||
| 2031 | sys_siglist[SIGPIPE] = "Broken pipe"; | ||
| 2032 | # ifdef SIGPOLL | ||
| 2033 | sys_siglist[SIGPOLL] = "Pollable event occurred"; | ||
| 2034 | # endif | ||
| 2035 | # ifdef SIGPROF | ||
| 2036 | sys_siglist[SIGPROF] = "Profiling timer expired"; | ||
| 2037 | # endif | ||
| 2038 | # ifdef SIGPTY | ||
| 2039 | sys_siglist[SIGPTY] = "PTY I/O interrupt"; | ||
| 2040 | # endif | ||
| 2041 | # ifdef SIGPWR | ||
| 2042 | sys_siglist[SIGPWR] = "Power-fail restart"; | ||
| 2043 | # endif | ||
| 2044 | sys_siglist[SIGQUIT] = "Quit"; | ||
| 2045 | # ifdef SIGRETRACT | ||
| 2046 | sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode"; | ||
| 2047 | # endif | ||
| 2048 | # ifdef SIGSAK | ||
| 2049 | sys_siglist[SIGSAK] = "Secure attention"; | ||
| 2050 | # endif | ||
| 2051 | sys_siglist[SIGSEGV] = "Segmentation violation"; | ||
| 2052 | # ifdef SIGSOUND | ||
| 2053 | sys_siglist[SIGSOUND] = "Sound completed"; | ||
| 2054 | # endif | ||
| 2055 | # ifdef SIGSTOP | ||
| 2056 | sys_siglist[SIGSTOP] = "Stopped (signal)"; | ||
| 2057 | # endif | ||
| 2058 | # ifdef SIGSTP | ||
| 2059 | sys_siglist[SIGSTP] = "Stopped (user)"; | ||
| 2060 | # endif | ||
| 2061 | # ifdef SIGSYS | ||
| 2062 | sys_siglist[SIGSYS] = "Bad argument to system call"; | ||
| 2063 | # endif | ||
| 2064 | sys_siglist[SIGTERM] = "Terminated"; | ||
| 2065 | # ifdef SIGTHAW | ||
| 2066 | sys_siglist[SIGTHAW] = "SIGTHAW"; | ||
| 2067 | # endif | ||
| 2068 | # ifdef SIGTRAP | ||
| 2069 | sys_siglist[SIGTRAP] = "Trace/breakpoint trap"; | ||
| 2070 | # endif | ||
| 2071 | # ifdef SIGTSTP | ||
| 2072 | sys_siglist[SIGTSTP] = "Stopped (user)"; | ||
| 2073 | # endif | ||
| 2074 | # ifdef SIGTTIN | ||
| 2075 | sys_siglist[SIGTTIN] = "Stopped (tty input)"; | ||
| 2076 | # endif | ||
| 2077 | # ifdef SIGTTOU | ||
| 2078 | sys_siglist[SIGTTOU] = "Stopped (tty output)"; | ||
| 2079 | # endif | ||
| 2080 | # ifdef SIGURG | ||
| 2081 | sys_siglist[SIGURG] = "Urgent I/O condition"; | ||
| 2082 | # endif | ||
| 2083 | # ifdef SIGUSR1 | ||
| 2084 | sys_siglist[SIGUSR1] = "User defined signal 1"; | ||
| 2085 | # endif | ||
| 2086 | # ifdef SIGUSR2 | ||
| 2087 | sys_siglist[SIGUSR2] = "User defined signal 2"; | ||
| 2088 | # endif | ||
| 2089 | # ifdef SIGVTALRM | ||
| 2090 | sys_siglist[SIGVTALRM] = "Virtual timer expired"; | ||
| 2091 | # endif | ||
| 2092 | # ifdef SIGWAITING | ||
| 2093 | sys_siglist[SIGWAITING] = "Process's LWPs are blocked"; | ||
| 2094 | # endif | ||
| 2095 | # ifdef SIGWINCH | ||
| 2096 | sys_siglist[SIGWINCH] = "Window size changed"; | ||
| 2097 | # endif | ||
| 2098 | # ifdef SIGWIND | ||
| 2099 | sys_siglist[SIGWIND] = "SIGWIND"; | ||
| 2100 | # endif | ||
| 2101 | # ifdef SIGXCPU | ||
| 2102 | sys_siglist[SIGXCPU] = "CPU time limit exceeded"; | ||
| 2103 | # endif | ||
| 2104 | # ifdef SIGXFSZ | ||
| 2105 | sys_siglist[SIGXFSZ] = "File size limit exceeded"; | ||
| 2106 | # endif | ||
| 2107 | } | ||
| 2108 | #endif /* !HAVE_DECL_SYS_SIGLIST && !_sys_siglist */ | ||
| 2109 | |||
| 2110 | /* Don't alter signal handlers if dumping. On some machines, | 1955 | /* Don't alter signal handlers if dumping. On some machines, |
| 2111 | changing signal handlers sets static data that would make signals | 1956 | changing signal handlers sets static data that would make signals |
| 2112 | fail to work right when the dumped Emacs is run. */ | 1957 | fail to work right when the dumped Emacs is run. */ |
| @@ -2762,15 +2607,13 @@ renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst) | |||
| 2762 | #endif | 2607 | #endif |
| 2763 | } | 2608 | } |
| 2764 | 2609 | ||
| 2765 | /* Like strsignal, except async-signal-safe, and this function typically | 2610 | /* Like strsignal, except async-signal-safe, and this function |
| 2766 | returns a string in the C locale rather than the current locale. */ | 2611 | returns a string in the C locale rather than the current locale. */ |
| 2767 | char const * | 2612 | char const * |
| 2768 | safe_strsignal (int code) | 2613 | safe_strsignal (int code) |
| 2769 | { | 2614 | { |
| 2770 | char const *signame = 0; | 2615 | char const *signame = sigdescr_np (code); |
| 2771 | 2616 | ||
| 2772 | if (0 <= code && code < sys_siglist_entries) | ||
| 2773 | signame = sys_siglist[code]; | ||
| 2774 | if (! signame) | 2617 | if (! signame) |
| 2775 | signame = "Unknown signal"; | 2618 | signame = "Unknown signal"; |
| 2776 | 2619 | ||
diff --git a/src/window.c b/src/window.c index ef58f43a0bd..e7433969d29 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -5462,7 +5462,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror) | |||
| 5462 | 5462 | ||
| 5463 | wset_redisplay (XWINDOW (window)); | 5463 | wset_redisplay (XWINDOW (window)); |
| 5464 | 5464 | ||
| 5465 | if (whole && Vfast_but_imprecise_scrolling) | 5465 | if (whole && fast_but_imprecise_scrolling) |
| 5466 | specbind (Qfontification_functions, Qnil); | 5466 | specbind (Qfontification_functions, Qnil); |
| 5467 | 5467 | ||
| 5468 | /* On GUI frames, use the pixel-based version which is much slower | 5468 | /* On GUI frames, use the pixel-based version which is much slower |
| @@ -8398,7 +8398,7 @@ pixelwise even if this option is nil. */); | |||
| 8398 | window_resize_pixelwise = false; | 8398 | window_resize_pixelwise = false; |
| 8399 | 8399 | ||
| 8400 | DEFVAR_BOOL ("fast-but-imprecise-scrolling", | 8400 | DEFVAR_BOOL ("fast-but-imprecise-scrolling", |
| 8401 | Vfast_but_imprecise_scrolling, | 8401 | fast_but_imprecise_scrolling, |
| 8402 | doc: /* When non-nil, accelerate scrolling operations. | 8402 | doc: /* When non-nil, accelerate scrolling operations. |
| 8403 | This comes into play when scrolling rapidly over previously | 8403 | This comes into play when scrolling rapidly over previously |
| 8404 | unfontified buffer regions. Only those portions of the buffer which | 8404 | unfontified buffer regions. Only those portions of the buffer which |
| @@ -8406,7 +8406,7 @@ are actually going to be displayed get fontified. | |||
| 8406 | 8406 | ||
| 8407 | Note that this optimization can cause the portion of the buffer | 8407 | Note that this optimization can cause the portion of the buffer |
| 8408 | displayed after a scrolling operation to be somewhat inaccurate. */); | 8408 | displayed after a scrolling operation to be somewhat inaccurate. */); |
| 8409 | Vfast_but_imprecise_scrolling = false; | 8409 | fast_but_imprecise_scrolling = false; |
| 8410 | 8410 | ||
| 8411 | defsubr (&Sselected_window); | 8411 | defsubr (&Sselected_window); |
| 8412 | defsubr (&Sold_selected_window); | 8412 | defsubr (&Sold_selected_window); |
diff --git a/src/xdisp.c b/src/xdisp.c index a1f7706ead2..dd737580438 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -538,7 +538,7 @@ it_char_has_category(struct it *it, int cat) | |||
| 538 | static bool | 538 | static bool |
| 539 | char_can_wrap_before (struct it *it) | 539 | char_can_wrap_before (struct it *it) |
| 540 | { | 540 | { |
| 541 | if (!Vword_wrap_by_category) | 541 | if (!word_wrap_by_category) |
| 542 | return !IT_DISPLAYING_WHITESPACE (it); | 542 | return !IT_DISPLAYING_WHITESPACE (it); |
| 543 | 543 | ||
| 544 | /* For CJK (LTR) text in RTL paragraph, EOL and BOL are flipped. | 544 | /* For CJK (LTR) text in RTL paragraph, EOL and BOL are flipped. |
| @@ -560,7 +560,7 @@ char_can_wrap_before (struct it *it) | |||
| 560 | static bool | 560 | static bool |
| 561 | char_can_wrap_after (struct it *it) | 561 | char_can_wrap_after (struct it *it) |
| 562 | { | 562 | { |
| 563 | if (!Vword_wrap_by_category) | 563 | if (!word_wrap_by_category) |
| 564 | return IT_DISPLAYING_WHITESPACE (it); | 564 | return IT_DISPLAYING_WHITESPACE (it); |
| 565 | 565 | ||
| 566 | /* For CJK (LTR) text in RTL paragraph, EOL and BOL are flipped. | 566 | /* For CJK (LTR) text in RTL paragraph, EOL and BOL are flipped. |
| @@ -589,7 +589,7 @@ char_can_wrap_after (struct it *it) | |||
| 589 | static int | 589 | static int |
| 590 | fill_column_indicator_column (struct it *it, int char_width) | 590 | fill_column_indicator_column (struct it *it, int char_width) |
| 591 | { | 591 | { |
| 592 | if (Vdisplay_fill_column_indicator | 592 | if (display_fill_column_indicator |
| 593 | && !it->w->pseudo_window_p | 593 | && !it->w->pseudo_window_p |
| 594 | && it->continuation_lines_width == 0 | 594 | && it->continuation_lines_width == 0 |
| 595 | && CHARACTERP (Vdisplay_fill_column_indicator_character)) | 595 | && CHARACTERP (Vdisplay_fill_column_indicator_character)) |
| @@ -5771,7 +5771,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 5771 | else | 5771 | else |
| 5772 | { | 5772 | { |
| 5773 | it->what = IT_IMAGE; | 5773 | it->what = IT_IMAGE; |
| 5774 | it->image_id = lookup_image (it->f, value); | 5774 | it->image_id = lookup_image (it->f, value, it->face_id); |
| 5775 | it->position = start_pos; | 5775 | it->position = start_pos; |
| 5776 | it->object = NILP (object) ? it->w->contents : object; | 5776 | it->object = NILP (object) ? it->w->contents : object; |
| 5777 | it->method = GET_FROM_IMAGE; | 5777 | it->method = GET_FROM_IMAGE; |
| @@ -12565,6 +12565,11 @@ gui_consider_frame_title (Lisp_Object frame) | |||
| 12565 | display_mode_element (&it, 0, -1, -1, fmt, Qnil, false); | 12565 | display_mode_element (&it, 0, -1, -1, fmt, Qnil, false); |
| 12566 | len = MODE_LINE_NOPROP_LEN (title_start); | 12566 | len = MODE_LINE_NOPROP_LEN (title_start); |
| 12567 | title = mode_line_noprop_buf + title_start; | 12567 | title = mode_line_noprop_buf + title_start; |
| 12568 | /* Make sure that any raw bytes in the title are properly | ||
| 12569 | represented by their multibyte sequences. */ | ||
| 12570 | ptrdiff_t nchars = 0; | ||
| 12571 | len = str_as_multibyte ((unsigned char *)title, | ||
| 12572 | mode_line_noprop_buf_end - title, len, &nchars); | ||
| 12568 | unbind_to (count, Qnil); | 12573 | unbind_to (count, Qnil); |
| 12569 | 12574 | ||
| 12570 | /* Set the title only if it's changed. This avoids consing in | 12575 | /* Set the title only if it's changed. This avoids consing in |
| @@ -12576,9 +12581,10 @@ gui_consider_frame_title (Lisp_Object frame) | |||
| 12576 | || SBYTES (f->name) != len | 12581 | || SBYTES (f->name) != len |
| 12577 | || memcmp (title, SDATA (f->name), len) != 0) | 12582 | || memcmp (title, SDATA (f->name), len) != 0) |
| 12578 | && FRAME_TERMINAL (f)->implicit_set_name_hook) | 12583 | && FRAME_TERMINAL (f)->implicit_set_name_hook) |
| 12579 | FRAME_TERMINAL (f)->implicit_set_name_hook (f, | 12584 | { |
| 12580 | make_string (title, len), | 12585 | Lisp_Object title_string = make_multibyte_string (title, nchars, len); |
| 12581 | Qnil); | 12586 | FRAME_TERMINAL (f)->implicit_set_name_hook (f, title_string, Qnil); |
| 12587 | } | ||
| 12582 | } | 12588 | } |
| 12583 | } | 12589 | } |
| 12584 | 12590 | ||
| @@ -21923,7 +21929,7 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21923 | && !face->stipple | 21929 | && !face->stipple |
| 21924 | #endif | 21930 | #endif |
| 21925 | && !it->glyph_row->reversed_p | 21931 | && !it->glyph_row->reversed_p |
| 21926 | && !Vdisplay_fill_column_indicator) | 21932 | && !display_fill_column_indicator) |
| 21927 | return; | 21933 | return; |
| 21928 | 21934 | ||
| 21929 | /* Set the glyph row flag indicating that the face of the last glyph | 21935 | /* Set the glyph row flag indicating that the face of the last glyph |
| @@ -22517,7 +22523,7 @@ push_prefix_prop (struct it *it, Lisp_Object prop) | |||
| 22517 | else if (IMAGEP (prop)) | 22523 | else if (IMAGEP (prop)) |
| 22518 | { | 22524 | { |
| 22519 | it->what = IT_IMAGE; | 22525 | it->what = IT_IMAGE; |
| 22520 | it->image_id = lookup_image (it->f, prop); | 22526 | it->image_id = lookup_image (it->f, prop, it->face_id); |
| 22521 | it->method = GET_FROM_IMAGE; | 22527 | it->method = GET_FROM_IMAGE; |
| 22522 | } | 22528 | } |
| 22523 | #endif /* HAVE_WINDOW_SYSTEM */ | 22529 | #endif /* HAVE_WINDOW_SYSTEM */ |
| @@ -25631,6 +25637,12 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, | |||
| 25631 | spec = decode_mode_spec (it->w, c, field, &string); | 25637 | spec = decode_mode_spec (it->w, c, field, &string); |
| 25632 | eassert (NILP (string) || STRINGP (string)); | 25638 | eassert (NILP (string) || STRINGP (string)); |
| 25633 | multibyte = !NILP (string) && STRING_MULTIBYTE (string); | 25639 | multibyte = !NILP (string) && STRING_MULTIBYTE (string); |
| 25640 | /* Non-ASCII characters in SPEC should cause mode-line | ||
| 25641 | element be displayed as a multibyte string. */ | ||
| 25642 | ptrdiff_t nbytes = strlen (spec); | ||
| 25643 | if (multibyte_chars_in_text ((const unsigned char *)spec, | ||
| 25644 | nbytes) != nbytes) | ||
| 25645 | multibyte = true; | ||
| 25634 | 25646 | ||
| 25635 | switch (mode_line_target) | 25647 | switch (mode_line_target) |
| 25636 | { | 25648 | { |
| @@ -26249,9 +26261,11 @@ decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag) | |||
| 26249 | attrs = AREF (val, 0); | 26261 | attrs = AREF (val, 0); |
| 26250 | eolvalue = AREF (val, 2); | 26262 | eolvalue = AREF (val, 2); |
| 26251 | 26263 | ||
| 26252 | *buf++ = multibyte | 26264 | if (multibyte) |
| 26253 | ? XFIXNAT (CODING_ATTR_MNEMONIC (attrs)) | 26265 | buf += CHAR_STRING (XFIXNAT (CODING_ATTR_MNEMONIC (attrs)), |
| 26254 | : ' '; | 26266 | (unsigned char *) buf); |
| 26267 | else | ||
| 26268 | *buf++ = ' '; | ||
| 26255 | 26269 | ||
| 26256 | if (eol_flag) | 26270 | if (eol_flag) |
| 26257 | { | 26271 | { |
| @@ -27431,7 +27445,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop, | |||
| 27431 | if (FRAME_WINDOW_P (it->f) | 27445 | if (FRAME_WINDOW_P (it->f) |
| 27432 | && valid_image_p (prop)) | 27446 | && valid_image_p (prop)) |
| 27433 | { | 27447 | { |
| 27434 | ptrdiff_t id = lookup_image (it->f, prop); | 27448 | ptrdiff_t id = lookup_image (it->f, prop, it->face_id); |
| 27435 | struct image *img = IMAGE_FROM_ID (it->f, id); | 27449 | struct image *img = IMAGE_FROM_ID (it->f, id); |
| 27436 | 27450 | ||
| 27437 | return OK_PIXELS (width_p ? img->width : img->height); | 27451 | return OK_PIXELS (width_p ? img->width : img->height); |
| @@ -34758,7 +34772,7 @@ A value of nil means to respect the value of `truncate-lines'. | |||
| 34758 | If `word-wrap' is enabled, you might want to reduce this. */); | 34772 | If `word-wrap' is enabled, you might want to reduce this. */); |
| 34759 | Vtruncate_partial_width_windows = make_fixnum (50); | 34773 | Vtruncate_partial_width_windows = make_fixnum (50); |
| 34760 | 34774 | ||
| 34761 | DEFVAR_BOOL("word-wrap-by-category", Vword_wrap_by_category, doc: /* | 34775 | DEFVAR_BOOL("word-wrap-by-category", word_wrap_by_category, doc: /* |
| 34762 | Non-nil means also wrap after characters of a certain category. | 34776 | Non-nil means also wrap after characters of a certain category. |
| 34763 | Normally when `word-wrap' is on, Emacs only breaks lines after | 34777 | Normally when `word-wrap' is on, Emacs only breaks lines after |
| 34764 | whitespace characters. When this option is turned on, Emacs also | 34778 | whitespace characters. When this option is turned on, Emacs also |
| @@ -34773,7 +34787,7 @@ when breaking lines. That means characters with the ">" category | |||
| 34773 | don't appear at the beginning of a line (e.g., FULLWIDTH COMMA), and | 34787 | don't appear at the beginning of a line (e.g., FULLWIDTH COMMA), and |
| 34774 | characters with the "<" category don't appear at the end of a line | 34788 | characters with the "<" category don't appear at the end of a line |
| 34775 | (e.g., LEFT DOUBLE ANGLE BRACKET). */); | 34789 | (e.g., LEFT DOUBLE ANGLE BRACKET). */); |
| 34776 | Vword_wrap_by_category = false; | 34790 | word_wrap_by_category = false; |
| 34777 | 34791 | ||
| 34778 | DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit, | 34792 | DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit, |
| 34779 | doc: /* Maximum buffer size for which line number should be displayed. | 34793 | doc: /* Maximum buffer size for which line number should be displayed. |
| @@ -35170,10 +35184,10 @@ It has no effect when set to 0, or when line numbers are not absolute. */); | |||
| 35170 | DEFSYM (Qdisplay_line_numbers_offset, "display-line-numbers-offset"); | 35184 | DEFSYM (Qdisplay_line_numbers_offset, "display-line-numbers-offset"); |
| 35171 | Fmake_variable_buffer_local (Qdisplay_line_numbers_offset); | 35185 | Fmake_variable_buffer_local (Qdisplay_line_numbers_offset); |
| 35172 | 35186 | ||
| 35173 | DEFVAR_BOOL ("display-fill-column-indicator", Vdisplay_fill_column_indicator, | 35187 | DEFVAR_BOOL ("display-fill-column-indicator", display_fill_column_indicator, |
| 35174 | doc: /* Non-nil means display the fill column indicator. | 35188 | doc: /* Non-nil means display the fill column indicator. |
| 35175 | See Info node `Displaying Boundaries' for details. */); | 35189 | See Info node `Displaying Boundaries' for details. */); |
| 35176 | Vdisplay_fill_column_indicator = false; | 35190 | display_fill_column_indicator = false; |
| 35177 | DEFSYM (Qdisplay_fill_column_indicator, "display-fill-column-indicator"); | 35191 | DEFSYM (Qdisplay_fill_column_indicator, "display-fill-column-indicator"); |
| 35178 | Fmake_variable_buffer_local (Qdisplay_fill_column_indicator); | 35192 | Fmake_variable_buffer_local (Qdisplay_fill_column_indicator); |
| 35179 | 35193 | ||