aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2020-08-29 11:33:37 +0200
committerAndrea Corallo2020-08-29 11:33:37 +0200
commitc3514a6274cd6c6ddf2c133ccc708b7875aab90e (patch)
tree5f76eefdfef645bca9bc8640accb77c53704116a /src
parentaa526c9470d679e9144af55d9e56928a111d2ceb (diff)
parent7d5807277ff614a337c7e4530bb8d0e0188c189b (diff)
downloademacs-c3514a6274cd6c6ddf2c133ccc708b7875aab90e.tar.gz
emacs-c3514a6274cd6c6ddf2c133ccc708b7875aab90e.zip
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
-rw-r--r--src/character.c6
-rw-r--r--src/coding.c10
-rw-r--r--src/dispextern.h6
-rw-r--r--src/editfns.c121
-rw-r--r--src/fileio.c70
-rw-r--r--src/font.c4
-rw-r--r--src/ftfont.c4
-rw-r--r--src/gnutls.c9
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/image.c220
-rw-r--r--src/keymap.c2
-rw-r--r--src/nsmenu.m2
-rw-r--r--src/regex-emacs.c61
-rw-r--r--src/syntax.c10
-rw-r--r--src/sysdep.c161
-rw-r--r--src/window.c6
-rw-r--r--src/xdisp.c48
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);
3475void mark_image_cache (struct image_cache *); 3475void mark_image_cache (struct image_cache *);
3476bool valid_image_p (Lisp_Object); 3476bool valid_image_p (Lisp_Object);
3477void prepare_image_for_display (struct frame *, struct image *); 3477void prepare_image_for_display (struct frame *, struct image *);
3478ptrdiff_t lookup_image (struct frame *, Lisp_Object); 3478ptrdiff_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. */
1881static 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
1909struct context; 1907struct 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. */)
2122static void 2125static void
2123set_bit (unsigned char *a, ptrdiff_t i) 2126set_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
2132static bool 2132static bool
2133bit_is_set (const unsigned char *a, ptrdiff_t i) 2133bit_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
2155buffer_chars_equal (struct context *ctx, 2152buffer_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: /*
5526Non-nil means don't query fontconfig for color fonts, since they often 5526Non-nil means don't query fontconfig for color fonts, since they often
5527cause Xft crashes. Only has an effect in Xft builds. */); 5527cause 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
2301static Lisp_Object cipher_cache;
2302
2301static Lisp_Object 2303static Lisp_Object
2302gnutls_symmetric (bool encrypting, Lisp_Object cipher, 2304gnutls_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. */
1613static struct image * 1608static struct image *
1614search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) 1609search_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)
1646static void 1643static void
1647uncache_image (struct frame *f, Lisp_Object spec) 1644uncache_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
2314ptrdiff_t 2326ptrdiff_t
2315lookup_image (struct frame *f, Lisp_Object spec) 2327lookup_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) \
970while (REMAINING_AVAIL_SLOTS <= space) { \ 970while (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) { \
979do { \ 983do { \
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.
3760In both cases, LIMIT bounds the search. */); 3760In 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
1772static 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. */
1783static void 1765static void
1784handle_fatal_signal (int sig) 1766handle_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. */
2767char const * 2612char const *
2768safe_strsignal (int code) 2613safe_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.
8403This comes into play when scrolling rapidly over previously 8403This comes into play when scrolling rapidly over previously
8404unfontified buffer regions. Only those portions of the buffer which 8404unfontified buffer regions. Only those portions of the buffer which
@@ -8406,7 +8406,7 @@ are actually going to be displayed get fontified.
8406 8406
8407Note that this optimization can cause the portion of the buffer 8407Note that this optimization can cause the portion of the buffer
8408displayed after a scrolling operation to be somewhat inaccurate. */); 8408displayed 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)
538static bool 538static bool
539char_can_wrap_before (struct it *it) 539char_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)
560static bool 560static bool
561char_can_wrap_after (struct it *it) 561char_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)
589static int 589static int
590fill_column_indicator_column (struct it *it, int char_width) 590fill_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'.
34758If `word-wrap' is enabled, you might want to reduce this. */); 34772If `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.
34763Normally when `word-wrap' is on, Emacs only breaks lines after 34777Normally when `word-wrap' is on, Emacs only breaks lines after
34764whitespace characters. When this option is turned on, Emacs also 34778whitespace characters. When this option is turned on, Emacs also
@@ -34773,7 +34787,7 @@ when breaking lines. That means characters with the ">" category
34773don't appear at the beginning of a line (e.g., FULLWIDTH COMMA), and 34787don't appear at the beginning of a line (e.g., FULLWIDTH COMMA), and
34774characters with the "<" category don't appear at the end of a line 34788characters 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.
35175See Info node `Displaying Boundaries' for details. */); 35189See 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