commit f69826a63d18782e372753d25d14a35249ef605d (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Tue Jun 4 09:37:02 2024 +0300 * lisp/outline.el (outline-revert-buffer-restore-visibility): New function. (outline-minor-mode): Add 'outline-revert-buffer-restore-visibility' to 'revert-buffer-restore-functions' (bug#69511). diff --git a/lisp/outline.el b/lisp/outline.el index b7afa6b3f45..80621c78b3b 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -580,6 +580,8 @@ See the command `outline-mode' for more information on this mode." (add-hook 'change-major-mode-hook (lambda () (outline-minor-mode -1)) nil t) + (add-hook 'revert-buffer-restore-functions + #'outline-revert-buffer-restore-visibility nil t) (add-hook 'revert-buffer-restore-functions (lambda () (when (and outline-minor-mode outline-minor-mode-highlight @@ -1713,6 +1715,13 @@ for example, after reverting the buffer." (concat "\\`" (regexp-quote heading) "\\'")) (nreverse headings) "\\|")))) +(defun outline-revert-buffer-restore-visibility () + "Preserve visibility of outlines in `outline-minor-mode' for `revert-buffer'." + (let ((regexp (outline-hidden-headings-regexp))) + (when regexp + (lambda () + (outline-hide-by-heading-regexp regexp))))) + ;;; Visibility cycling commit 799f78a92c6c31f4d181390523b83d036020ede1 Author: Paul Eggert Date: Mon Jun 3 21:57:53 2024 -0700 Update from Gnulib by running admin/merge-gnulib * lib/endian.c, lib/endian.in.h, m4/endian_h.m4, m4/sys_cdefs_h.m4: New files, copied from Gnulib. diff --git a/lib/acl-internal.c b/lib/acl-internal.c index 68aead8de65..9ebb6e544b0 100644 --- a/lib/acl-internal.c +++ b/lib/acl-internal.c @@ -23,6 +23,12 @@ #include "acl-internal.h" +#if defined __CYGWIN__ +# include +# include +# include +#endif + #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ @@ -63,8 +69,58 @@ acl_access_nontrivial (acl_t acl) acl_tag_t tag; if (acl_get_tag_type (ace, &tag) < 0) return -1; - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) - return 1; + switch (tag) + { + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_OTHER: + break; +# ifdef __CYGWIN__ + /* On Cygwin, a trivial ACL inside the Cygwin file system consists of + e.g. + user::rwx + group::r-x + other::r-x + but a trivial ACL outside the Cygwin file system has more entries: + e.g. + user::rwx + group::r-x + group:SYSTEM:rwx + group:Administrators:rwx + mask::r-x + other::r-x + */ + case ACL_GROUP: + { + int ignorable = 0; + void *qualifier = acl_get_qualifier (ace); + if (qualifier != NULL) + { + gid_t group_id = *(gid_t const *) qualifier; + acl_free (qualifier); + struct group *group_details = getgrgid (group_id); + if (group_details != NULL) + { + const char *group_sid = group_details->gr_passwd; + /* Ignore the ace if the group_sid is one of + - S-1-5-18 (group "SYSTEM") + - S-1-5-32-544 (group "Administrators") + Cf. */ + ignorable = (strcmp (group_sid, "S-1-5-18") == 0 + || strcmp (group_sid, "S-1-5-32-544") == 0); + } + } + if (!ignorable) + return 1; + } + break; + case ACL_MASK: + /* XXX Is it OK to ignore acl_get_permset (ace, ...) ? */ + break; +# endif + default: + return 1; + } } return got_one; diff --git a/lib/attribute.h b/lib/attribute.h index 710341ba417..604965a6d18 100644 --- a/lib/attribute.h +++ b/lib/attribute.h @@ -49,8 +49,9 @@ _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_MAY_ALIAS, _GL_ATTRIBUTE_MAYBE_UNUSED, _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOINLINE, _GL_ATTRIBUTE_NONNULL, _GL_ATTRIBUTE_NONSTRING, _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PACKED, - _GL_ATTRIBUTE_PURE, _GL_ATTRIBUTE_RETURNS_NONNULL, - _GL_ATTRIBUTE_SENTINEL. */ + _GL_ATTRIBUTE_PURE, _GL_ATTRIBUTE_REPRODUCIBLE, + _GL_ATTRIBUTE_RETURNS_NONNULL, _GL_ATTRIBUTE_SENTINEL, + _GL_ATTRIBUTE_UNSEQUENCED. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif @@ -88,7 +89,7 @@ is the size of the returned memory block. ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments to determine the size of the returned memory block. */ -/* Applies to: function, pointer to function, function types. */ +/* Applies to: functions, pointer to functions, function types. */ #define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args) /* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers @@ -170,7 +171,7 @@ /* Attributes regarding debugging information emitted by the compiler. */ /* Omit the function from stack traces when debugging. */ -/* Applies to: function. */ +/* Applies to: functions. */ #define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL /* Make the entity visible to debuggers etc., even with '-fwhole-program'. */ @@ -192,25 +193,64 @@ /* Always inline the function, and report an error if the compiler cannot inline. */ -/* Applies to: function. */ +/* Applies to: functions. */ #define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE -/* It is OK for a compiler to omit duplicate calls with the same arguments. +/* It is OK for a compiler to move calls to the function and to omit + calls to the function if another call has the same arguments or the + result is not used. This attribute is safe for a function that neither depends on - nor affects observable state, and always returns exactly once - - e.g., does not loop forever, and does not call longjmp. - (This attribute is stricter than ATTRIBUTE_PURE.) */ + nor affects state, and always returns exactly once - + e.g., does not raise an exception, call longjmp, or loop forever. + (This attribute is stricter than ATTRIBUTE_PURE because the + function cannot observe state. It is stricter than UNSEQUENCED + because the function must return exactly once and cannot depend on + state addressed by its arguments.) */ /* Applies to: functions. */ #define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST -/* It is OK for a compiler to omit duplicate calls with the same - arguments if observable state is not changed between calls. - This attribute is safe for a function that does not affect - observable state, and always returns exactly once. - (This attribute is looser than ATTRIBUTE_CONST.) */ +/* It is OK for a compiler to move calls to the function and to omit duplicate + calls to the function with the same arguments, so long as the state + addressed by its arguments is the same. + This attribute is safe for a function that is effectless, idempotent, + stateless, and independent; see ISO C 23 § 6.7.12.7 for a definition of + these terms. + (This attribute is stricter than REPRODUCIBLE because the function + must be stateless and independent. It is looser than ATTRIBUTE_CONST + because the function need not return exactly once and can depend + on state addressed by its arguments.) + See also and + . */ +/* Applies to: functions, pointer to functions, function type. */ +#define UNSEQUENCED _GL_ATTRIBUTE_UNSEQUENCED + +/* It is OK for a compiler to move calls to the function and to omit + calls to the function if another call has the same arguments or the + result is not used, and if observable state is the same. + This attribute is safe for a function that does not affect observable state + and always returns exactly once. + (This attribute is looser than ATTRIBUTE_CONST because the function + can depend on observable state. It is stricter than REPRODUCIBLE + because the function must return exactly once and cannot affect + state addressed by its arguments.) */ /* Applies to: functions. */ #define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE +/* It is OK for a compiler to move calls to the function and to omit duplicate + calls to the function with the same arguments, so long as the state + addressed by its arguments is the same and is updated in time for + the rest of the program. + This attribute is safe for a function that is effectless and idempotent; see + ISO C 23 § 6.7.12.7 for a definition of these terms. + (This attribute is looser than UNSEQUENCED because the function need + not be stateless and idempotent. It is looser than ATTRIBUTE_PURE + because the function need not return exactly once and can affect + state addressed by its arguments.) + See also and + . */ +/* Applies to: functions, pointer to functions, function type. */ +#define REPRODUCIBLE _GL_ATTRIBUTE_REPRODUCIBLE + /* The function is rarely executed. */ /* Applies to: functions. */ #define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h index 7f8c5405e4c..8b98c4e5734 100644 --- a/lib/boot-time-aux.h +++ b/lib/boot-time-aux.h @@ -108,8 +108,16 @@ get_linux_boot_time_fallback (struct timespec *p_boot_time) struct stat statbuf; if (stat (filename, &statbuf) >= 0) { - *p_boot_time = get_stat_mtime (&statbuf); - return 0; + struct timespec boot_time = get_stat_mtime (&statbuf); + /* On Alpine 3.20.0_rc2 /var/run/utmp was observed with bogus + timestamps of ~10 s. Reject timestamps before + 2005-07-25 23:34:15 UTC (1122334455), as neither Alpine + nor Devuan existed then. */ + if (boot_time.tv_sec >= 1122334455) + { + *p_boot_time = boot_time; + return 0; + } } } return -1; @@ -337,4 +345,78 @@ get_windows_boot_time (struct timespec *p_boot_time) return -1; } +# ifndef __CYGWIN__ +# if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA) + +/* Don't assume that UNICODE is not defined. */ +# undef LoadLibrary +# define LoadLibrary LoadLibraryA + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress + +/* GetTickCount64 is only available on Windows Vista and later. */ +typedef ULONGLONG (WINAPI * GetTickCount64FuncType) (void); + +static GetTickCount64FuncType GetTickCount64Func = NULL; +static BOOL initialized = FALSE; + +static void +initialize (void) +{ + HMODULE kernel32 = LoadLibrary ("kernel32.dll"); + if (kernel32 != NULL) + { + GetTickCount64Func = + (GetTickCount64FuncType) GetProcAddress (kernel32, "GetTickCount64"); + } + initialized = TRUE; +} + +# else + +# define GetTickCount64Func GetTickCount64 + +# endif + +/* Fallback for Windows in the form: + boot time = current time - uptime + This uses the GetTickCount64 function which is only available on Windows + Vista and later. See: + . */ +static int +get_windows_boot_time_fallback (struct timespec *p_boot_time) +{ +# if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA) + if (! initialized) + initialize (); +# endif + if (GetTickCount64Func != NULL) + { + ULONGLONG uptime_ms = GetTickCount64Func (); + struct timespec uptime; + struct timespec result; + struct timeval tv; + if (gettimeofday (&tv, NULL) >= 0) + { + uptime.tv_sec = uptime_ms / 1000; + uptime.tv_nsec = (uptime_ms % 1000) * 1000000; + result.tv_sec = tv.tv_sec; + result.tv_nsec = tv.tv_usec * 1000; + if (result.tv_nsec < uptime.tv_nsec) + { + result.tv_nsec += 1000000000; + result.tv_sec -= 1; + } + result.tv_sec -= uptime.tv_sec; + result.tv_nsec -= uptime.tv_nsec; + *p_boot_time = result; + return 0; + } + } + return -1; +} + +# endif #endif diff --git a/lib/boot-time.c b/lib/boot-time.c index c1171e8024d..71562dcf751 100644 --- a/lib/boot-time.c +++ b/lib/boot-time.c @@ -43,6 +43,13 @@ # include #endif +#if defined _WIN32 && ! defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# include +# include +#endif + #include "idx.h" #include "readutmp.h" #include "stat-time.h" @@ -247,6 +254,10 @@ get_boot_time_uncached (struct timespec *p_boot_time) { /* Workaround for Windows: */ get_windows_boot_time (&found_boot_time); +# ifndef __CYGWIN__ + if (found_boot_time.tv_sec == 0) + get_windows_boot_time_fallback (&found_boot_time); +# endif } # endif diff --git a/lib/endian.c b/lib/endian.c new file mode 100644 index 00000000000..3e7e56f523d --- /dev/null +++ b/lib/endian.c @@ -0,0 +1,23 @@ +/* Inline functions for . + + Copyright 2024 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Collin Funk. */ + +#include + +#define _GL_ENDIAN_INLINE _GL_EXTERN_INLINE +#include diff --git a/lib/endian.in.h b/lib/endian.in.h new file mode 100644 index 00000000000..bd65ae8aaba --- /dev/null +++ b/lib/endian.in.h @@ -0,0 +1,236 @@ +/* endian.h - Byte order macros + + Copyright 2024 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Collin Funk. */ + +#ifndef _@GUARD_PREFIX@_ENDIAN_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if @HAVE_ENDIAN_H@ + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_ENDIAN_H@ + +#endif + + +/* glibc defines all macros and functions but is missing types from + stdint.h. */ +#if @ENDIAN_H_JUST_MISSING_STDINT@ +# include +#else + +/* Others platforms. */ +#ifndef _@GUARD_PREFIX@_ENDIAN_H +#define _@GUARD_PREFIX@_ENDIAN_H 1 + +/* This file uses _GL_INLINE, WORDS_BIGENDIAN. */ +#if !_GL_CONFIG_H_INCLUDED + #error "Please include config.h first." +#endif + +/* Define uint16_t and uint32_t. + Define uint64_t if it is available. */ +#include + +/* Byteswap functions. */ +#include + +_GL_INLINE_HEADER_BEGIN +#ifndef _GL_ENDIAN_INLINE +# define _GL_ENDIAN_INLINE _GL_INLINE +#endif + +#define LITTLE_ENDIAN 1234 +#define BIG_ENDIAN 4321 +#define PDP_ENDIAN 3412 + +#ifdef WORDS_BIGENDIAN +# define BYTE_ORDER BIG_ENDIAN +#else +# define BYTE_ORDER LITTLE_ENDIAN +#endif + +/* Make sure function-like macros get undefined. */ +#if @HAVE_ENDIAN_H@ +# undef be16toh +# undef be32toh +# undef be64toh +# undef htobe16 +# undef htobe32 +# undef htobe64 +# undef le16toh +# undef le32toh +# undef le64toh +# undef htole16 +# undef htole32 +# undef htole64 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Big endian to host. */ + +_GL_ENDIAN_INLINE uint16_t +be16toh (uint16_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return bswap_16 (x); +#endif +} + +_GL_ENDIAN_INLINE uint32_t +be32toh (uint32_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return bswap_32 (x); +#endif +} + +#ifdef UINT64_MAX +_GL_ENDIAN_INLINE uint64_t +be64toh (uint64_t x) +{ +# if BYTE_ORDER == BIG_ENDIAN + return x; +# else + return bswap_64 (x); +# endif +} +#endif + +/* Host to big endian. */ + +_GL_ENDIAN_INLINE uint16_t +htobe16 (uint16_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return bswap_16 (x); +#endif +} + +_GL_ENDIAN_INLINE uint32_t +htobe32 (uint32_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return x; +#else + return bswap_32 (x); +#endif +} + +#ifdef UINT64_MAX +_GL_ENDIAN_INLINE uint64_t +htobe64 (uint64_t x) +{ +# if BYTE_ORDER == BIG_ENDIAN + return x; +# else + return bswap_64 (x); +# endif +} +#endif + +/* Little endian to host. */ + +_GL_ENDIAN_INLINE uint16_t +le16toh (uint16_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return bswap_16 (x); +#else + return x; +#endif +} + +_GL_ENDIAN_INLINE uint32_t +le32toh (uint32_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return bswap_32 (x); +#else + return x; +#endif +} + +#ifdef UINT64_MAX +_GL_ENDIAN_INLINE uint64_t +le64toh (uint64_t x) +{ +# if BYTE_ORDER == BIG_ENDIAN + return bswap_64 (x); +# else + return x; +# endif +} +#endif + +/* Host to little endian. */ + +_GL_ENDIAN_INLINE uint16_t +htole16 (uint16_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return bswap_16 (x); +#else + return x; +#endif +} + +_GL_ENDIAN_INLINE uint32_t +htole32 (uint32_t x) +{ +#if BYTE_ORDER == BIG_ENDIAN + return bswap_32 (x); +#else + return x; +#endif +} + +#ifdef UINT64_MAX +_GL_ENDIAN_INLINE uint64_t +htole64 (uint64_t x) +{ +# if BYTE_ORDER == BIG_ENDIAN + return bswap_64 (x); +# else + return x; +# endif +} +#endif + +#ifdef __cplusplus +} +#endif + +_GL_INLINE_HEADER_END + +#endif /* @ENDIAN_H_JUST_MISSING_STDINT@ */ +#endif /* _@GUARD_PREFIX@_ENDIAN_H */ +#endif /* _@GUARD_PREFIX@_ENDIAN_H */ diff --git a/lib/euidaccess.c b/lib/euidaccess.c index ad392dba19c..6229f2c0d06 100644 --- a/lib/euidaccess.c +++ b/lib/euidaccess.c @@ -29,9 +29,7 @@ #include #include #include -#if defined _WIN32 && ! defined __CYGWIN__ -# include -#else +#if !(defined _WIN32 && ! defined __CYGWIN__) # include "root-uid.h" #endif @@ -88,7 +86,7 @@ euidaccess (const char *file, int mode) #elif HAVE_EACCESS /* FreeBSD */ return eaccess (file, mode); #elif defined _WIN32 && ! defined __CYGWIN__ /* mingw */ - return _access (file, mode); + return access (file, mode); #else /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, BeOS */ uid_t uid = getuid (); diff --git a/lib/getopt.c b/lib/getopt.c index f66f119ec50..ea2d1a529c4 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -723,7 +723,7 @@ _getopt_internal (int argc, char **argv, const char *optstring, return result; } -/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt. +/* glibc gets a LSB-compliant getopt and a POSIX-compliant __posix_getopt. Standalone applications just get a POSIX-compliant getopt. POSIX and LSB both require these functions to take 'char *const *argv' even though this is incorrect (because of the permutation). */ diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 358d58d5015..832b245edc2 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -264,6 +264,8 @@ EMACSRES = @EMACSRES@ EMACS_MANIFEST = @EMACS_MANIFEST@ EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENDIAN_H = @ENDIAN_H@ +ENDIAN_H_JUST_MISSING_STDINT = @ENDIAN_H_JUST_MISSING_STDINT@ ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ ENOLINK_VALUE = @ENOLINK_VALUE@ EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ @@ -349,6 +351,7 @@ GL_COND_OBJ_UTIMENSAT_CONDITION = @GL_COND_OBJ_UTIMENSAT_CONDITION@ GL_GENERATE_ALLOCA_H_CONDITION = @GL_GENERATE_ALLOCA_H_CONDITION@ GL_GENERATE_ASSERT_H_CONDITION = @GL_GENERATE_ASSERT_H_CONDITION@ GL_GENERATE_BYTESWAP_H_CONDITION = @GL_GENERATE_BYTESWAP_H_CONDITION@ +GL_GENERATE_ENDIAN_H_CONDITION = @GL_GENERATE_ENDIAN_H_CONDITION@ GL_GENERATE_ERRNO_H_CONDITION = @GL_GENERATE_ERRNO_H_CONDITION@ GL_GENERATE_EXECINFO_H_CONDITION = @GL_GENERATE_EXECINFO_H_CONDITION@ GL_GENERATE_GETOPT_CDEFS_H_CONDITION = @GL_GENERATE_GETOPT_CDEFS_H_CONDITION@ @@ -761,6 +764,7 @@ HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ HAVE_DIRENT_H = @HAVE_DIRENT_H@ HAVE_DPRINTF = @HAVE_DPRINTF@ HAVE_DUP3 = @HAVE_DUP3@ +HAVE_ENDIAN_H = @HAVE_ENDIAN_H@ HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ HAVE_EXECVPE = @HAVE_EXECVPE@ HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@ @@ -1044,6 +1048,7 @@ NDK_BUILD_SDK = @NDK_BUILD_SDK@ NEXT_ASSERT_H = @NEXT_ASSERT_H@ NEXT_AS_FIRST_DIRECTIVE_ASSERT_H = @NEXT_AS_FIRST_DIRECTIVE_ASSERT_H@ NEXT_AS_FIRST_DIRECTIVE_DIRENT_H = @NEXT_AS_FIRST_DIRECTIVE_DIRENT_H@ +NEXT_AS_FIRST_DIRECTIVE_ENDIAN_H = @NEXT_AS_FIRST_DIRECTIVE_ENDIAN_H@ NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@ NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@ NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ @@ -1063,6 +1068,7 @@ NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@ NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@ NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@ NEXT_DIRENT_H = @NEXT_DIRENT_H@ +NEXT_ENDIAN_H = @NEXT_ENDIAN_H@ NEXT_ERRNO_H = @NEXT_ERRNO_H@ NEXT_FCNTL_H = @NEXT_FCNTL_H@ NEXT_GETOPT_H = @NEXT_GETOPT_H@ @@ -1189,6 +1195,7 @@ REPLACE_GETPROGNAME = @REPLACE_GETPROGNAME@ REPLACE_GETRANDOM = @REPLACE_GETRANDOM@ REPLACE_GETSUBOPT = @REPLACE_GETSUBOPT@ REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_GETUSERSHELL = @REPLACE_GETUSERSHELL@ REPLACE_GMTIME = @REPLACE_GMTIME@ REPLACE_IMAXABS = @REPLACE_IMAXABS@ REPLACE_IMAXDIV = @REPLACE_IMAXDIV@ @@ -1450,6 +1457,7 @@ gl_GNULIB_ENABLED_d3b2383720ee0e541357aa2aac598e2b_CONDITION = @gl_GNULIB_ENABLE gl_GNULIB_ENABLED_dirfd_CONDITION = @gl_GNULIB_ENABLED_dirfd_CONDITION@ gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION = @gl_GNULIB_ENABLED_e80bf6f757095d2e5fc94dafb8f8fc8b_CONDITION@ gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION = @gl_GNULIB_ENABLED_ef455225c00f5049c808c2eda3e76866_CONDITION@ +gl_GNULIB_ENABLED_endian_CONDITION = @gl_GNULIB_ENABLED_endian_CONDITION@ gl_GNULIB_ENABLED_euidaccess_CONDITION = @gl_GNULIB_ENABLED_euidaccess_CONDITION@ gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION = @gl_GNULIB_ENABLED_fd38c7e463b54744b77b98aeafb4fa7c_CONDITION@ gl_GNULIB_ENABLED_getdelim_CONDITION = @gl_GNULIB_ENABLED_getdelim_CONDITION@ @@ -1900,6 +1908,39 @@ EXTRA_DIST += eloop-threshold.h endif ## end gnulib module eloop-threshold +## begin gnulib module endian +ifeq (,$(OMIT_GNULIB_MODULE_endian)) + +ifneq (,$(gl_GNULIB_ENABLED_endian_CONDITION)) +BUILT_SOURCES += $(ENDIAN_H) + +# We need the following in order to create when the system +# doesn't have one. +ifneq (,$(GL_GENERATE_ENDIAN_H_CONDITION)) +endian.h: endian.in.h $(top_builddir)/config.status + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''HAVE_ENDIAN_H''@|$(HAVE_ENDIAN_H)|g' \ + -e 's|@''NEXT_ENDIAN_H''@|$(NEXT_ENDIAN_H)|g' \ + -e 's|@''ENDIAN_H_JUST_MISSING_STDINT''@|$(ENDIAN_H_JUST_MISSING_STDINT)|g' \ + $(srcdir)/endian.in.h > $@-t + $(AM_V_at)mv $@-t $@ +libgnu_a_SOURCES += endian.c +else +endian.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += endian.h endian.h-t + +endif +EXTRA_DIST += endian.in.h + +endif +## end gnulib module endian + ## begin gnulib module errno ifeq (,$(OMIT_GNULIB_MODULE_errno)) @@ -4254,6 +4295,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \ -e 's|@''REPLACE_GETPASS_FOR_GETPASS_GNU''@|$(REPLACE_GETPASS_FOR_GETPASS_GNU)|g' \ + -e 's|@''REPLACE_GETUSERSHELL''@|$(REPLACE_GETUSERSHELL)|g' \ -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \ -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ diff --git a/lib/ieee754.in.h b/lib/ieee754.in.h index 805048ca9fc..4dd0ff55d29 100644 --- a/lib/ieee754.in.h +++ b/lib/ieee754.in.h @@ -16,37 +16,28 @@ . */ #ifndef _IEEE754_H - #define _IEEE754_H 1 #ifndef _GL_GNULIB_HEADER /* Ordinary glibc usage. */ # include -# include +# include +# define _IEEE754_BYTE_ORDER __BYTE_ORDER +# define _IEEE754_BIG_ENDIAN __BIG_ENDIAN +# define _IEEE754_LITTLE_ENDIAN __LITTLE_ENDIAN +# define _IEEE754_FLOAT_WORD_ORDER __FLOAT_WORD_ORDER #else /* Gnulib usage. */ -# ifndef __BEGIN_DECLS -# ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -# endif -# ifndef __FLOAT_WORD_ORDER -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# ifdef WORDS_BIGENDIAN -# define __BYTE_ORDER __BIG_ENDIAN -# else -# define __BYTE_ORDER __LITTLE_ENDIAN -# endif -# define __FLOAT_WORD_ORDER __BYTE_ORDER -# endif +# include +# define _IEEE754_BYTE_ORDER BYTE_ORDER +# define _IEEE754_BIG_ENDIAN BIG_ENDIAN +# define _IEEE754_LITTLE_ENDIAN LITTLE_ENDIAN +# define _IEEE754_FLOAT_WORD_ORDER BYTE_ORDER #endif -__BEGIN_DECLS +#ifdef __cplusplus +extern "C" { +#endif union ieee754_float { @@ -55,12 +46,12 @@ union ieee754_float /* This is the IEEE 754 single-precision format. */ struct { -#if __BYTE_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_BIG_ENDIAN unsigned int negative:1; unsigned int exponent:8; unsigned int mantissa:23; #endif /* Big endian. */ -#if __BYTE_ORDER == __LITTLE_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_LITTLE_ENDIAN unsigned int mantissa:23; unsigned int exponent:8; unsigned int negative:1; @@ -70,13 +61,13 @@ union ieee754_float /* This format makes it easier to see if a NaN is a signalling NaN. */ struct { -#if __BYTE_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_BIG_ENDIAN unsigned int negative:1; unsigned int exponent:8; unsigned int quiet_nan:1; unsigned int mantissa:22; #endif /* Big endian. */ -#if __BYTE_ORDER == __LITTLE_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_LITTLE_ENDIAN unsigned int mantissa:22; unsigned int quiet_nan:1; unsigned int exponent:8; @@ -95,15 +86,15 @@ union ieee754_double /* This is the IEEE 754 double-precision format. */ struct { -#if __BYTE_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_BIG_ENDIAN unsigned int negative:1; unsigned int exponent:11; /* Together these comprise the mantissa. */ unsigned int mantissa0:20; unsigned int mantissa1:32; #endif /* Big endian. */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -# if __FLOAT_WORD_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_LITTLE_ENDIAN +# if _IEEE754_FLOAT_WORD_ORDER == _IEEE754_BIG_ENDIAN unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; @@ -121,7 +112,7 @@ union ieee754_double /* This format makes it easier to see if a NaN is a signalling NaN. */ struct { -#if __BYTE_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_BIG_ENDIAN unsigned int negative:1; unsigned int exponent:11; unsigned int quiet_nan:1; @@ -129,7 +120,7 @@ union ieee754_double unsigned int mantissa0:19; unsigned int mantissa1:32; #else -# if __FLOAT_WORD_ORDER == __BIG_ENDIAN +# if _IEEE754_FLOAT_WORD_ORDER == _IEEE754_BIG_ENDIAN unsigned int mantissa0:19; unsigned int quiet_nan:1; unsigned int exponent:11; @@ -157,15 +148,15 @@ union ieee854_long_double /* This is the IEEE 854 double-extended-precision format. */ struct { -#if __BYTE_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_BIG_ENDIAN unsigned int negative:1; unsigned int exponent:15; unsigned int empty:16; unsigned int mantissa0:32; unsigned int mantissa1:32; #endif -#if __BYTE_ORDER == __LITTLE_ENDIAN -# if __FLOAT_WORD_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_LITTLE_ENDIAN +# if _IEEE754_FLOAT_WORD_ORDER == _IEEE754_BIG_ENDIAN unsigned int exponent:15; unsigned int negative:1; unsigned int empty:16; @@ -184,7 +175,7 @@ union ieee854_long_double /* This is for NaNs in the IEEE 854 double-extended-precision format. */ struct { -#if __BYTE_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_BIG_ENDIAN unsigned int negative:1; unsigned int exponent:15; unsigned int empty:16; @@ -193,8 +184,8 @@ union ieee854_long_double unsigned int mantissa0:30; unsigned int mantissa1:32; #endif -#if __BYTE_ORDER == __LITTLE_ENDIAN -# if __FLOAT_WORD_ORDER == __BIG_ENDIAN +#if _IEEE754_BYTE_ORDER == _IEEE754_LITTLE_ENDIAN +# if _IEEE754_FLOAT_WORD_ORDER == _IEEE754_BIG_ENDIAN unsigned int exponent:15; unsigned int negative:1; unsigned int empty:16; @@ -217,6 +208,8 @@ union ieee854_long_double #define IEEE854_LONG_DOUBLE_BIAS 0x3fff -__END_DECLS +#ifdef __cplusplus +} +#endif #endif /* ieee754.h */ diff --git a/lib/readlink.c b/lib/readlink.c index a5369fa977b..f4af30ebc42 100644 --- a/lib/readlink.c +++ b/lib/readlink.c @@ -98,6 +98,16 @@ rpl_readlink (char const *file, char *buf, size_t bufsize) } # endif +# if defined __CYGWIN__ + /* On Cygwin 3.3.6, readlink("/dev/null") returns "\\Device\\Null", which + is unusable. Better fail with EINVAL. */ + if (r > 0 && strncmp (file, "/dev/", 5) == 0 && buf[0] == '\\') + { + errno = EINVAL; + return -1; + } +# endif + return r; } diff --git a/lib/readlinkat.c b/lib/readlinkat.c index faf85401ae6..f4d64c0d135 100644 --- a/lib/readlinkat.c +++ b/lib/readlinkat.c @@ -79,6 +79,16 @@ rpl_readlinkat (int fd, char const *file, char *buf, size_t bufsize) } # endif +# if defined __CYGWIN__ + /* On Cygwin 3.3.6, readlinkat(AT_FDCWD,"/dev/null") returns "\\Device\\Null", + which is unusable. Better fail with EINVAL. */ + if (r > 0 && strncmp (file, "/dev/", 5) == 0 && buf[0] == '\\') + { + errno = EINVAL; + return -1; + } +# endif + return r; } diff --git a/lib/stdint.in.h b/lib/stdint.in.h index fea7483b9cc..cd3fbdd9654 100644 --- a/lib/stdint.in.h +++ b/lib/stdint.in.h @@ -80,7 +80,7 @@ #define _@GUARD_PREFIX@_STDINT_H /* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, - LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH. */ + LONG_MIN, LONG_MAX, ULONG_MAX, CHAR_BIT, _GL_INTEGER_WIDTH. */ #include /* Override WINT_MIN and WINT_MAX if gnulib's or overrides @@ -189,6 +189,10 @@ typedef __int64 gl_int64_t; # define int64_t gl_int64_t # define GL_INT64_T # else +/* Verify that 'long long' has exactly 64 bits. */ +typedef _gl_verify_int64_bits[ + _STDINT_MAX (1, sizeof (long long) * CHAR_BIT, 0ll) >> 31 >> 31 == 1 + ? 1 : -1]; # undef int64_t typedef long long int gl_int64_t; # define int64_t gl_int64_t @@ -210,6 +214,11 @@ typedef unsigned __int64 gl_uint64_t; # define uint64_t gl_uint64_t # define GL_UINT64_T # else +/* Verify that 'unsigned long long' has exactly 64 bits. */ +typedef _gl_verify_uint64_bits[ + _STDINT_MAX (0, sizeof (unsigned long long) * CHAR_BIT, 0ull) + >> 31 >> 31 >> 1 == 1 + ? 1 : -1]; # undef uint64_t typedef unsigned long long int gl_uint64_t; # define uint64_t gl_uint64_t diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index ef9fde30eb2..cfc69d0a506 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -26,6 +26,10 @@ #@INCLUDE_NEXT@ @NEXT_STDLIB_H@ +/* Make sure that the macros that indicate the special invocation convention + get undefined. This is needed at least on CentOS 7. */ +#undef __need_malloc_and_calloc + #else /* Normal invocation convention. */ diff --git a/lib/strftime.c b/lib/strftime.c index 834f3a79f46..5f1e76833f7 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -1252,6 +1252,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) cpy (am_len, a_month); break; #else +# if defined _WIN32 && !defined __CYGWIN__ + format_char = L_('b'); +# endif goto underlying_strftime; #endif @@ -1288,6 +1291,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT)); #elif USE_C_LOCALE && !HAVE_STRFTIME_L subfmt = L_("%a %b %e %H:%M:%S %Y"); +#elif defined _WIN32 && !defined __CYGWIN__ + /* On native Windows, "%c" is "%d/%m/%Y %H:%M:%S" by default. */ + subfmt = L_("%a %b %e %H:%M:%S %Y"); #else goto underlying_strftime; #endif @@ -1709,8 +1715,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) #elif USE_C_LOCALE && !HAVE_STRFTIME_L subfmt = L_("%I:%M:%S %p"); goto subformat; -#elif (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ - /* macOS, FreeBSD strftime() may produce empty output for "%r". */ +#elif (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || (defined _WIN32 && !defined __CYGWIN__) + /* macOS, FreeBSD, native Windows strftime() may produce empty output + for "%r". */ subfmt = L_("%I:%M:%S %p"); goto subformat; #else diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 7dbed38969b..e01629af259 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -1531,12 +1531,21 @@ _GL_CXXALIASWARN (getpid); #if @GNULIB_GETUSERSHELL@ +# if @REPLACE_GETUSERSHELL@ /* Return the next valid login shell on the system, or NULL when the end of the list has been reached. */ -# if !@HAVE_DECL_GETUSERSHELL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getusershell +# define getusershell rpl_getusershell +# endif +_GL_FUNCDECL_RPL (getusershell, char *, (void)); +_GL_CXXALIAS_RPL (getusershell, char *, (void)); +# else +# if !@HAVE_DECL_GETUSERSHELL@ _GL_FUNCDECL_SYS (getusershell, char *, (void)); -# endif +# endif _GL_CXXALIAS_SYS (getusershell, char *, (void)); +# endif _GL_CXXALIASWARN (getusershell); #elif defined GNULIB_POSIXCHECK # undef getusershell @@ -1548,10 +1557,19 @@ _GL_WARN_ON_USE (getusershell, "getusershell is unportable - " #if @GNULIB_GETUSERSHELL@ /* Rewind to pointer that is advanced at each getusershell() call. */ -# if !@HAVE_DECL_GETUSERSHELL@ +# if @REPLACE_GETUSERSHELL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setusershell +# define setusershell rpl_setusershell +# endif +_GL_FUNCDECL_RPL (setusershell, void, (void)); +_GL_CXXALIAS_RPL (setusershell, void, (void)); +# else +# if !@HAVE_DECL_GETUSERSHELL@ _GL_FUNCDECL_SYS (setusershell, void, (void)); -# endif +# endif _GL_CXXALIAS_SYS (setusershell, void, (void)); +# endif _GL_CXXALIASWARN (setusershell); #elif defined GNULIB_POSIXCHECK # undef setusershell @@ -1564,10 +1582,19 @@ _GL_WARN_ON_USE (setusershell, "setusershell is unportable - " #if @GNULIB_GETUSERSHELL@ /* Free the pointer that is advanced at each getusershell() call and associated resources. */ -# if !@HAVE_DECL_GETUSERSHELL@ +# if @REPLACE_GETUSERSHELL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef endusershell +# define endusershell rpl_endusershell +# endif +_GL_FUNCDECL_RPL (endusershell, void, (void)); +_GL_CXXALIAS_RPL (endusershell, void, (void)); +# else +# if !@HAVE_DECL_GETUSERSHELL@ _GL_FUNCDECL_SYS (endusershell, void, (void)); -# endif +# endif _GL_CXXALIAS_SYS (endusershell, void, (void)); +# endif _GL_CXXALIASWARN (endusershell); #elif defined GNULIB_POSIXCHECK # undef endusershell diff --git a/lib/utimens.c b/lib/utimens.c index 4bfb9c91a7b..6b9f62a53c1 100644 --- a/lib/utimens.c +++ b/lib/utimens.c @@ -220,7 +220,7 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) if (0 <= utimensat_works_really) { int result; -# if __linux__ || __sun +# if defined __linux__ || defined __sun || defined __NetBSD__ /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, but work if both times are either explicitly specified or @@ -230,6 +230,7 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) where UTIME_OMIT would have worked. The same bug occurs in Solaris 11.1 (Apr 2013). + The same bug occurs in NetBSD 10.0 (May 2024). FIXME: Simplify this in 2024, when these file system bugs are no longer common on Gnulib target platforms. */ @@ -440,7 +441,7 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) # endif if (futimes (fd, t) == 0) { -# if __linux__ && __GLIBC__ +# if defined __linux__ && defined __GLIBC__ /* Work around a longstanding glibc bug, still present as of 2010-12-27. On older Linux kernels that lack both utimensat and utimes, glibc's futimes rounds instead of @@ -553,7 +554,7 @@ lutimens (char const *file, struct timespec const timespec[2]) if (0 <= lutimensat_works_really) { int result; -# if __linux__ || __sun +# if defined __linux__ || defined __sun || defined __NetBSD__ /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, but work if both times are either explicitly specified or @@ -563,6 +564,7 @@ lutimens (char const *file, struct timespec const timespec[2]) UTIME_OMIT would have worked. The same bug occurs in Solaris 11.1 (Apr 2013). + The same bug occurs in NetBSD 10.0 (May 2024). FIXME: Simplify this for Linux in 2016 and for Solaris in 2024, when file system bugs are no longer common. */ diff --git a/lib/utimensat.c b/lib/utimensat.c index 1321264269e..b44207b4bec 100644 --- a/lib/utimensat.c +++ b/lib/utimensat.c @@ -77,7 +77,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], int flag) # undef utimensat { -# if defined __linux__ || defined __sun +# if defined __linux__ || defined __sun || defined __NetBSD__ struct timespec ts[2]; # endif @@ -86,7 +86,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], if (0 <= utimensat_works_really) { int result; -# if defined __linux__ || defined __sun +# if defined __linux__ || defined __sun || defined __NetBSD__ struct stat st; /* As recently as Linux kernel 2.6.32 (Dec 2009), several file systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, @@ -97,6 +97,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], UTIME_OMIT would have worked. The same bug occurs in Solaris 11.1 (Apr 2013). + The same bug occurs in NetBSD 10.0 (May 2024). FIXME: Simplify this in 2024, when these file system bugs are no longer common on Gnulib target platforms. */ @@ -117,9 +118,11 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], ts[1] = times[1]; times = ts; } -# ifdef __hppa__ +# if defined __hppa__ || defined __NetBSD__ /* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec - values. */ + values. + + The same bug occurs in NetBSD 10.0 (May 2024). */ else if (times && ((times[0].tv_nsec != UTIME_NOW && ! (0 <= times[0].tv_nsec diff --git a/lib/verify.h b/lib/verify.h index 08268c2498f..978926a4918 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -259,11 +259,22 @@ template && (!defined __cplusplus \ || (__cpp_static_assert < 201411 \ && __GNUG__ < 6 && __clang_major__ < 6 && _MSC_VER < 1910))) -# if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ +# if (defined __cplusplus && defined __GNUG__ && __GNUG__ < 6 \ + && __cplusplus == 201103L && !defined __clang__) +/* g++ >= 4.7, < 6 with option -std=c++11 or -std=gnu++11 supports the + two-arguments static_assert but not the one-argument static_assert, and + it does not support _Static_assert. + We have to play preprocessor tricks to distinguish the two cases. */ +# define _GL_SA1(a1) static_assert ((a1), "static assertion failed") +# define _GL_SA2 static_assert +# define _GL_SA3 static_assert +# define _GL_SA_PICK(x1,x2,x3,x4,...) x4 +# define static_assert(...) _GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1) (__VA_ARGS__) +# elif defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ /* MSVC 14 in C++ mode supports the two-arguments static_assert but not the one-argument static_assert, and it does not support _Static_assert. We have to play preprocessor tricks to distinguish the two cases. - Since the MSVC preprocessor is not ISO C compliant (see above),. + Since the MSVC preprocessor is not ISO C compliant (see above), the solution is specific to MSVC. */ # define _GL_EXPAND(x) x # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") diff --git a/m4/endian_h.m4 b/m4/endian_h.m4 new file mode 100644 index 00000000000..3149b492270 --- /dev/null +++ b/m4/endian_h.m4 @@ -0,0 +1,103 @@ +# endian_h.m4 +# serial 4 +dnl Copyright 2024 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl A placeholder for , for platforms that have issues. + +AC_DEFUN_ONCE([gl_ENDIAN_H], +[ + AC_REQUIRE([gl_BIGENDIAN]) + + AC_CHECK_HEADERS_ONCE([endian.h]) + gl_CHECK_NEXT_HEADERS([endian.h]) + if test $ac_cv_header_endian_h = yes; then + HAVE_ENDIAN_H=1 + dnl Check if endian.h defines uint16_t, uint32_t, and uint64_t. + AC_CACHE_CHECK([if endian.h defines stdint types], + [gl_cv_header_endian_h_stdint_types], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[uint16_t t1 = 0; + uint32_t t2 = 0; + uint64_t t3 = 0; + return !(t1 + t2 + t3); + ]])], + [gl_cv_header_endian_h_stdint_types=yes], + [gl_cv_header_endian_h_stdint_types=no]) + ]) + AC_CACHE_CHECK([if endian.h defines functions and macros], + [gl_cv_header_working_endian_h], + [gl_cv_header_working_endian_h=no + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( +[[ +#include +]], +[[ +#if LITTLE_ENDIAN == BIG_ENDIAN +# error "Endian macros not unique." +#endif +#if BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN +# error "Byte order not defined." +#endif + +/* Big endian to host. */ +int value16_1 = be16toh (0.0); +int value32_1 = be32toh (0.0); +int value64_1 = be64toh (0.0); + +/* Host to big endian. */ +int value16_2 = htobe16 (0.0); +int value32_2 = htobe32 (0.0); +int value64_2 = htobe64 (0.0); + +/* Little endian to host. */ +int value16_3 = le16toh (0.0); +int value32_3 = le32toh (0.0); +int value64_3 = le64toh (0.0); + +/* Host to little endian. */ +int value16_4 = htole16 (0.0); +int value32_4 = htole32 (0.0); +int value64_4 = htole64 (0.0); + +/* Make sure the variables get used. */ +return !(value16_1 + value32_1 + value64_1 + + value16_2 + value32_2 + value64_2 + + value16_3 + value32_3 + value64_3 + + value16_4 + value32_4 + value64_4); +]])], + [gl_cv_header_working_endian_h=yes], + [gl_cv_header_working_endian_h=no]) + ]) + else + HAVE_ENDIAN_H=0 + fi + + dnl Check if endian.h should be generated. + if test "$gl_cv_header_endian_h_stdint_types" = yes \ + && test "$gl_cv_header_working_endian_h" = yes; then + GL_GENERATE_ENDIAN_H=false + else + GL_GENERATE_ENDIAN_H=true + fi + + dnl Check if endian.h works but is missing types from stdint.h. + if test $GL_GENERATE_ENDIAN_H; then + if test "$gl_cv_header_working_endian_h" = yes; then + ENDIAN_H_JUST_MISSING_STDINT=1 + else + ENDIAN_H_JUST_MISSING_STDINT=0 + fi + else + ENDIAN_H_JUST_MISSING_STDINT=0 + fi + + AC_SUBST([HAVE_ENDIAN_H]) + AC_SUBST([ENDIAN_H_JUST_MISSING_STDINT]) +]) diff --git a/m4/getopt.m4 b/m4/getopt.m4 index 297722eae44..53cab8bef93 100644 --- a/m4/getopt.m4 +++ b/m4/getopt.m4 @@ -1,5 +1,5 @@ # getopt.m4 -# serial 49 +# serial 50 dnl Copyright (C) 2002-2006, 2008-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -366,14 +366,7 @@ dnl is ambiguous with environment values that contain newlines. AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], [ - AC_CHECK_HEADERS_ONCE([sys/cdefs.h]) - if test $ac_cv_header_sys_cdefs_h = yes; then - HAVE_SYS_CDEFS_H=1 - else - HAVE_SYS_CDEFS_H=0 - fi - AC_SUBST([HAVE_SYS_CDEFS_H]) - + gl_CHECK_HEADER_SYS_CDEFS_H AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], [Define to rpl_ if the getopt replacement functions and variables should be used.]) diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index cb730449507..b34b4534bfe 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,5 +1,5 @@ # gnulib-common.m4 -# serial 93 +# serial 95 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -114,8 +114,10 @@ AC_DEFUN([gl_COMMON_BODY], [ # define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) # define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) # define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96) +# define _GL_ATTR_reproducible 0 /* not yet supported, as of GCC 14 */ # define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9) # define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0) +# define _GL_ATTR_unsequenced 0 /* not yet supported, as of GCC 14 */ # define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7) # define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4) # endif @@ -152,7 +154,7 @@ AC_DEFUN([gl_COMMON_BODY], [ _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied by the Nth argument of the function is the size of the returned memory block. */ -/* Applies to: function, pointer to function, function types. */ +/* Applies to: functions, pointer to functions, function types. */ #ifndef _GL_ATTRIBUTE_ALLOC_SIZE # if _GL_HAS_ATTRIBUTE (alloc_size) # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) @@ -163,7 +165,7 @@ AC_DEFUN([gl_COMMON_BODY], [ /* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the function and report an error if it cannot do so. */ -/* Applies to: function. */ +/* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_ALWAYS_INLINE # if _GL_HAS_ATTRIBUTE (always_inline) # define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) @@ -175,7 +177,7 @@ AC_DEFUN([gl_COMMON_BODY], [ /* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show in stack traces when debugging. The compiler should omit the function from stack traces. */ -/* Applies to: function. */ +/* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_ARTIFICIAL # if _GL_HAS_ATTRIBUTE (artificial) # define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) @@ -201,18 +203,23 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif #endif -/* _GL_ATTRIBUTE_CONST declares that it is OK for a compiler to omit duplicate - calls to the function with the same arguments. - This attribute is safe for a function that neither depends on nor affects - observable state, and always returns exactly once - e.g., does not loop - forever, and does not call longjmp. - (This attribute is stricter than _GL_ATTRIBUTE_PURE.) */ +/* _GL_ATTRIBUTE_CONST declares: + It is OK for a compiler to move calls to the function and to omit + calls to the function if another call has the same arguments or the + result is not used. + This attribute is safe for a function that neither depends on + nor affects state, and always returns exactly once - + e.g., does not raise an exception, call longjmp, or loop forever. + (This attribute is stricter than _GL_ATTRIBUTE_PURE because the + function cannot observe state. It is stricter than + _GL_ATTRIBUTE_UNSEQUENCED because the function must return exactly + once and cannot depend on state addressed by its arguments.) */ /* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_CONST # if _GL_HAS_ATTRIBUTE (const) # define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) # else -# define _GL_ATTRIBUTE_CONST +# define _GL_ATTRIBUTE_CONST _GL_ATTRIBUTE_UNSEQUENCED # endif #endif @@ -505,9 +512,9 @@ AC_DEFUN([gl_COMMON_BODY], [ minimizing the memory required. */ /* Applies to: struct members, struct, union, in C++ also: class. */ +#ifndef _GL_ATTRIBUTE_PACKED /* Oracle Studio 12.6 miscompiles code with __attribute__ ((__packed__)) despite __has_attribute OK. */ -#ifndef _GL_ATTRIBUTE_PACKED # if _GL_HAS_ATTRIBUTE (packed) && !defined __SUNPRO_C # define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) # else @@ -515,18 +522,49 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif #endif -/* _GL_ATTRIBUTE_PURE declares that It is OK for a compiler to omit duplicate - calls to the function with the same arguments if observable state is not - changed between calls. - This attribute is safe for a function that does not affect - observable state, and always returns exactly once. - (This attribute is looser than _GL_ATTRIBUTE_CONST.) */ +/* _GL_ATTRIBUTE_PURE declares: + It is OK for a compiler to move calls to the function and to omit + calls to the function if another call has the same arguments or the + result is not used, and if observable state is the same. + This attribute is safe for a function that does not affect observable state + and always returns exactly once. + (This attribute is looser than _GL_ATTRIBUTE_CONST because the function + can depend on observable state. It is stricter than + _GL_ATTRIBUTE_REPRODUCIBLE because the function must return exactly + once and cannot affect state addressed by its arguments.) */ /* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_PURE # if _GL_HAS_ATTRIBUTE (pure) # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else -# define _GL_ATTRIBUTE_PURE +# define _GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_REPRODUCIBLE +# endif +#endif + +/* _GL_ATTRIBUTE_REPRODUCIBLE declares: + It is OK for a compiler to move calls to the function and to omit duplicate + calls to the function with the same arguments, so long as the state + addressed by its arguments is the same and is updated in time for + the rest of the program. + This attribute is safe for a function that is effectless and idempotent; see + ISO C 23 § 6.7.12.7 for a definition of these terms. + (This attribute is looser than _GL_ATTRIBUTE_UNSEQUENCED because + the function need not be stateless and idempotent. It is looser + than _GL_ATTRIBUTE_PURE because the function need not return + exactly once and can affect state addressed by its arguments.) + See also and + . */ +/* Applies to: functions, pointer to functions, function types. */ +#ifndef _GL_ATTRIBUTE_REPRODUCIBLE +/* This may be revisited when gcc and clang support [[reproducible]] or possibly + __attribute__ ((__reproducible__)). */ +# ifndef _GL_BRACKET_BEFORE_ATTRIBUTE +# if _GL_HAS_ATTRIBUTE (reproducible) +# define _GL_ATTRIBUTE_REPRODUCIBLE [[reproducible]] +# endif +# endif +# ifndef _GL_ATTRIBUTE_REPRODUCIBLE +# define _GL_ATTRIBUTE_REPRODUCIBLE # endif #endif @@ -554,6 +592,33 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif #endif +/* _GL_ATTRIBUTE_UNSEQUENCED declares: + It is OK for a compiler to move calls to the function and to omit duplicate + calls to the function with the same arguments, so long as the state + addressed by its arguments is the same. + This attribute is safe for a function that is effectless, idempotent, + stateless, and independent; see ISO C 23 § 6.7.12.7 for a definition of + these terms. + (This attribute is stricter than _GL_ATTRIBUTE_REPRODUCIBLE because + the function must be stateless and independent. It is looser than + _GL_ATTRIBUTE_CONST because the function need not return exactly + once and can depend on state addressed by its arguments.) + See also and + . */ +/* Applies to: functions, pointer to functions, function types. */ +#ifndef _GL_ATTRIBUTE_UNSEQUENCED +/* This may be revisited when gcc and clang support [[unsequenced]] or possibly + __attribute__ ((__unsequenced__)). */ +# ifndef _GL_BRACKET_BEFORE_ATTRIBUTE +# if _GL_HAS_ATTRIBUTE (unsequenced) +# define _GL_ATTRIBUTE_UNSEQUENCED [[unsequenced]] +# endif +# endif +# ifndef _GL_ATTRIBUTE_UNSEQUENCED +# define _GL_ATTRIBUTE_UNSEQUENCED +# endif +#endif + /* A helper macro. Don't use it directly. */ #ifndef _GL_ATTRIBUTE_UNUSED # if _GL_HAS_ATTRIBUTE (unused) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 4dd1e68d15c..9af4b3a9fc8 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -77,6 +77,7 @@ AC_DEFUN([gl_EARLY], # Code from module dtotimespec: # Code from module dup2: # Code from module eloop-threshold: + # Code from module endian: # Code from module environ: # Code from module errno: # Code from module euidaccess: @@ -666,6 +667,7 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_cloexec=false gl_gnulib_enabled_dirfd=false gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=false + gl_gnulib_enabled_endian=false gl_gnulib_enabled_euidaccess=false gl_gnulib_enabled_getdelim=false gl_gnulib_enabled_getdtablesize=false @@ -724,6 +726,15 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=true fi } + func_gl_gnulib_m4code_endian () + { + if $gl_gnulib_enabled_endian; then :; else + gl_ENDIAN_H + gl_CONDITIONAL_HEADER([endian.h]) + AC_PROG_MKDIR_P + gl_gnulib_enabled_endian=true + fi + } func_gl_gnulib_m4code_euidaccess () { if $gl_gnulib_enabled_euidaccess; then :; else @@ -1036,6 +1047,9 @@ AC_DEFUN([gl_INIT], if case $host_os in mingw* | windows*) false;; *) test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1;; esac; then func_gl_gnulib_m4code_open fi + if $GL_GENERATE_IEEE754_H; then + func_gl_gnulib_m4code_endian + fi if test $REPLACE_MKTIME = 1; then func_gl_gnulib_m4code_verify fi @@ -1071,6 +1085,7 @@ AC_DEFUN([gl_INIT], AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec]) AM_CONDITIONAL([gl_GNULIB_ENABLED_dirfd], [$gl_gnulib_enabled_dirfd]) AM_CONDITIONAL([gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c], [$gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_endian], [$gl_gnulib_enabled_endian]) AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess]) AM_CONDITIONAL([gl_GNULIB_ENABLED_getdelim], [$gl_gnulib_enabled_getdelim]) AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], [$gl_gnulib_enabled_getdtablesize]) @@ -1312,6 +1327,8 @@ AC_DEFUN([gl_FILE_LIST], [ lib/dup2.c lib/dynarray.h lib/eloop-threshold.h + lib/endian.c + lib/endian.in.h lib/errno.in.h lib/euidaccess.c lib/execinfo.c @@ -1506,6 +1523,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/double-slash-root.m4 m4/dup2.m4 m4/eealloc.m4 + m4/endian_h.m4 m4/environ.m4 m4/errno_h.m4 m4/euidaccess.m4 @@ -1605,6 +1623,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/strtoimax.m4 m4/strtoll.m4 m4/symlink.m4 + m4/sys_cdefs_h.m4 m4/sys_random_h.m4 m4/sys_select_h.m4 m4/sys_socket_h.m4 diff --git a/m4/readlink.m4 b/m4/readlink.m4 index bc9a5deb06e..7ebdb6ca14f 100644 --- a/m4/readlink.m4 +++ b/m4/readlink.m4 @@ -1,5 +1,5 @@ # readlink.m4 -# serial 17 +# serial 18 dnl Copyright (C) 2003, 2007, 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,7 +8,7 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_READLINK], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([AC_CANONICAL_HOST]) AC_CHECK_FUNCS_ONCE([readlink]) if test $ac_cv_func_readlink = no; then HAVE_READLINK=0 @@ -18,9 +18,13 @@ AC_DEFUN([gl_FUNC_READLINK], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include - /* Cause compilation failure if original declaration has wrong type. */ - ssize_t readlink (const char *, char *, size_t);]])], + /* Cause compilation failure if original declaration has + wrong type. */ + ssize_t readlink (const char *, char *, size_t); + ]]) + ], [gl_cv_decl_readlink_works=yes], [gl_cv_decl_readlink_works=no])]) + dnl Solaris 9 ignores trailing slash. dnl FreeBSD 7.2 dereferences only one level of links with trailing slash. AC_CACHE_CHECK([whether readlink handles trailing slash correctly], @@ -31,8 +35,11 @@ AC_DEFUN([gl_FUNC_READLINK], AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#include -]], [[char buf[20]; - return readlink ("conftest.lnk2/", buf, sizeof buf) != -1;]])], + ]], + [[char buf[20]; + return readlink ("conftest.lnk2/", buf, sizeof buf) != -1; + ]]) + ], [gl_cv_func_readlink_trailing_slash=yes], [gl_cv_func_readlink_trailing_slash=no], [case "$host_os" in @@ -71,8 +78,11 @@ AC_DEFUN([gl_FUNC_READLINK], AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#include -]], [[char c; - return readlink ("conftest.link", &c, 1) != 1;]])], + ]], + [[char c; + return readlink ("conftest.link", &c, 1) != 1; + ]]) + ], [gl_cv_func_readlink_truncate=yes], [gl_cv_func_readlink_truncate=no], [case "$host_os" in @@ -103,6 +113,14 @@ AC_DEFUN([gl_FUNC_READLINK], REPLACE_READLINK=1 ;; esac + + dnl On Cygwin 3.3.6, readlink("/dev/null") returns "\\Device\\Null", which + dnl is unusable. + case "$host_os" in + cygwin*) + REPLACE_READLINK=1 + ;; + esac fi ]) diff --git a/m4/readlinkat.m4 b/m4/readlinkat.m4 index 8a33c169136..1f091e8b636 100644 --- a/m4/readlinkat.m4 +++ b/m4/readlinkat.m4 @@ -1,5 +1,5 @@ # readlinkat.m4 -# serial 8 +# serial 9 dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -27,9 +27,12 @@ AC_DEFUN([gl_FUNC_READLINKAT], [AC_LANG_PROGRAM( [[#include /* Check whether original declaration has correct type. */ - ssize_t readlinkat (int, char const *, char *, size_t);]])], + ssize_t readlinkat (int, char const *, char *, size_t); + ]]) + ], [gl_cv_decl_readlinkat_works=yes], - [gl_cv_decl_readlinkat_works=no])]) + [gl_cv_decl_readlinkat_works=no]) + ]) # Assume readlinkat has the same bugs as readlink, # as is the case on OS X 10.10 with trailing slashes. case $gl_cv_decl_readlinkat_works,$gl_cv_func_readlink_trailing_slash,$gl_cv_func_readlink_truncate in @@ -39,5 +42,13 @@ AC_DEFUN([gl_FUNC_READLINKAT], REPLACE_READLINKAT=1 ;; esac + + dnl On Cygwin 3.3.6, readlinkat(AT_FDCWD,"/dev/null") returns + dnl "\\Device\\Null", which is unusable. + case "$host_os" in + cygwin*) + REPLACE_READLINKAT=1 + ;; + esac fi ]) diff --git a/m4/sys_cdefs_h.m4 b/m4/sys_cdefs_h.m4 new file mode 100644 index 00000000000..22fa6c3849e --- /dev/null +++ b/m4/sys_cdefs_h.m4 @@ -0,0 +1,25 @@ +# sys_cdefs_h.m4 - Is compatible enough with glibc? +# serial 2 +dnl Copyright 2024 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Paul Eggert. + +AC_DEFUN_ONCE([gl_CHECK_HEADER_SYS_CDEFS_H], + [AC_CACHE_CHECK([for glibc-compatible sys/cdefs.h], + [gl_cv_header_sys_cdefs_h], + [AC_COMPILE_IFELSE( + [AC_LANG_DEFINES_PROVIDED + [#include + enum { foo = __GNUC_PREREQ (14, 1) } bar; + ]], + [gl_cv_header_sys_cdefs_h=yes], + [gl_cv_header_sys_cdefs_h=no])]) + if test "$gl_cv_header_sys_cdefs_h" = yes; then + HAVE_SYS_CDEFS_H=1 + else + HAVE_SYS_CDEFS_H=0 + fi + AC_SUBST([HAVE_SYS_CDEFS_H])]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 81d1b9f6169..04fa79c9ca6 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,5 +1,5 @@ # unistd_h.m4 -# serial 95 +# serial 96 dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -248,6 +248,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) REPLACE_GETPASS=0; AC_SUBST([REPLACE_GETPASS]) REPLACE_GETPASS_FOR_GETPASS_GNU=0; AC_SUBST([REPLACE_GETPASS_FOR_GETPASS_GNU]) + REPLACE_GETUSERSHELL=0; AC_SUBST([REPLACE_GETUSERSHELL]) REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) commit ce660c5c304e7261cae66224ad90c0dd3db363af Author: Paul Eggert Date: Mon Jun 3 14:43:10 2024 -0700 lwlib: pacify gcc -Wmissing-variable-declarations * lwlib/lwlib.c (lwlib_toolkit_type): Remove unused var. * lwlib/xlwmenu.c (submenu_destroyed): Now static. * src/xmenu.c (widget_id_tick): Declare extern, as a FIXME. diff --git a/lwlib/lwlib.c b/lwlib/lwlib.c index 354faeed5b2..de978d569ed 100644 --- a/lwlib/lwlib.c +++ b/lwlib/lwlib.c @@ -61,12 +61,6 @@ along with GNU Emacs. If not, see . */ static widget_info* all_widget_info = NULL; -#ifdef USE_MOTIF -const char *lwlib_toolkit_type = "motif"; -#else -const char *lwlib_toolkit_type = "lucid"; -#endif - static widget_value *merge_widget_value (widget_value *, widget_value *, int, int *); diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 0f8f94b803c..33f3fa27033 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -248,7 +248,7 @@ XlwMenuClassRec xlwMenuClassRec = WidgetClass xlwMenuWidgetClass = (WidgetClass) &xlwMenuClassRec; -int submenu_destroyed; +static int submenu_destroyed; static int next_release_must_exit; diff --git a/src/xmenu.c b/src/xmenu.c index 8682e67dad4..6dd7b3f37a0 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1607,6 +1607,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, For menu bars, we use numbers starting at 0, counted in next_menubar_widget_id. */ +extern LWLIB_ID widget_id_tick; /* FIXME: Move this to a .h file. */ LWLIB_ID widget_id_tick; static void commit cd7dd3e675ef2e3ae6e30ee70523ceb7f1fd1d67 Author: Jim Porter Date: Sun Jun 2 13:07:10 2024 -0700 Check for a real process when trying to find password prompts in Eshell * lisp/eshell/esh-mode.el (eshell-watch-for-password-prompt): Use 'eshell-head-process'. diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index ea2ccb08be1..e6f3cb5f6ad 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -952,7 +952,7 @@ buffer's process if STRING contains a password prompt defined by `eshell-password-prompt-regexp'. This function could be in the list `eshell-output-filter-functions'." - (when eshell-foreground-command + (when (eshell-head-process) (save-excursion (let ((case-fold-search t)) (goto-char eshell-last-output-block-begin) commit 991600a82c7678fa15301e609f259cf3ec184089 Author: Jim Porter Date: Fri May 31 09:36:03 2024 -0700 Add an "Interaction" chapter to the Eshell manual * doc/misc/eshell.texi (Interaction): New chapter. (Completion, History): Move into "Interaction" and add key indexing. (Key rebinding): Add key indexing. (Command Index): Add this index. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 873d14aff32..c8a04bfa33f 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -79,15 +79,14 @@ similar to command shells such as @command{bash}, @command{zsh}, * Commands:: * Expansion:: * Input/Output:: +* Interaction:: * Extension modules:: * Bugs and ideas:: Known problems, and future ideas. * GNU Free Documentation License:: The license for this documentation. * Concept Index:: * Function and Variable Index:: * Command Index:: -@ignore * Key Index:: -@end ignore @end menu @node Introduction @@ -208,8 +207,6 @@ that will be invoked, type this as the Eshell prompt: * Variables:: * Aliases:: * Remote Access:: -* History:: -* Completion:: * Control Flow:: * Scripts:: @end menu @@ -1556,92 +1553,6 @@ The GNU Emacs Manual}). To disable explicity-remote commands entirely, you can set the option @code{eshell-explicit-remote-commands} to @code{nil}. -@node History -@section History -@cmindex history -@vindex eshell-history-size -The @samp{history} command shows all commands kept in the history ring -as numbered list. If the history ring contains -@code{eshell-history-size} commands, those numbers change after every -command invocation, therefore the @samp{history} command shall be -applied before using the expansion mechanism with history numbers. - -The n-th entry of the history ring can be applied with the @samp{!n} -command. If @code{n} is negative, the entry is counted from the end -of the history ring. - -@cindex event designators -@findex eshell-expand-history-references -When history event designators are enabled (by adding -@code{eshell-expand-history-references} to -@code{eshell-expand-input-functions}), @samp{!foo} expands to the last -command beginning with @code{foo}, and @samp{!?foo} to the last -command containing @code{foo}. The n-th argument of the last command -beginning with @code{foo} is accessible by @code{!foo:n}. - -@vindex eshell-history-file-name -@vindex eshell-history-append -The history is loaded to the history ring from the file -@code{eshell-history-file-name} at the start of every session, and -saved to that file at the end of every session. The default history -saving behavior is to overwrite the history file with the whole -history ring of the session. If @code{eshell-history-append} is -non-@code{nil}, the history will instead be saved by appending new -entries from the session to the history file, which could prevent -potential history loss with multiple Eshell sessions. Unlike other -shells, such as Bash, Eshell cannot currently be configured to control -the size of the history file. In particular, when -@code{eshell-history-append} is non-@code{nil}, the size of the file -will keep increasing, and the recommended way to truncate the file is -to run the @samp{history -w} command in an Eshell session. - -Since the default buffer navigation and searching key-bindings are -still present in the Eshell buffer, the commands for history -navigation and searching are bound to different keys: - -@table @kbd -@item M-r -@itemx M-s -History I-search. - -@item M-p -@itemx M-n -Previous and next history line. If there is anything on the input -line when you run these commands, they will instead jump to the -previous or next line that begins with that string. -@end table - -@node Completion -@section Completion -Eshell uses the pcomplete package for programmable completion, similar -to that of other command shells. Argument completion differs depending -on the preceding command: for example, possible completions for -@command{rmdir} are only directories, while @command{rm} completions can -be directories @emph{and} files. Eshell provides predefined completions -for the built-in functions and some common external commands, and you -can define your own for any command. - -Eshell completion also works for Lisp forms and glob patterns. If the -point is on a Lisp form, then @key{TAB} will behave similarly to -completion in @code{elisp-mode} and @code{lisp-interaction-mode}. For -glob patterns, the pattern will be removed from the input line, and -replaced by the completion. - -If you want to see the entire list of possible completions (e.g. when it's -below the @code{completion-cycle-threshold}), press @kbd{M-?}. - -@subsection pcomplete -Pcomplete, short for programmable completion, is the completion -library originally written for Eshell, but usable for command -completion@footnote{Command completion, as opposed to code completion, -which is beyond the scope of pcomplete.} in other modes. - -Completions are defined as functions (with @code{defun}) named -@code{pcomplete/COMMAND}, where @code{COMMAND} is the name of the -command for which this function provides completions; you can also name -the function @code{pcomplete/MAJOR-MODE/COMMAND} to define completions -for a specific major mode. - @node Control Flow @section Control Flow Because Eshell commands can not (easily) be combined with Lisp forms, @@ -2486,6 +2397,135 @@ at the end of the command are excluded. This allows input like this: sh -c "foo | baz" ># @end example +@node Interaction +@chapter Interaction + +As an interactive shell, Eshell contains many features for helping to +interact with your command environment. In addition, since Eshell is a +part of Emacs, all of the usual Emacs commands work within Eshell as +well. + +@menu +* Navigation:: +* Completion:: +* History:: +@end menu + +@node Navigation +@section Navigation + +@table @kbd + +@kindex C-c C-n +@kindex C-c C-p +@item C-c C-n +@itemx C-c C-p +Move point to the beginning of the input for the next or previous +prompt. With a prefix argument, move to the n-th next or previous +prompt. + +@kindex C-c C-r +@kindex C-M-l +@item C-c C-r +@itemx C-M-l +Move point to the start of the previous command's output and display it +at the top of the window. With a prefix argument, this also narrows the +region to the last command's output. + +@end table + +@node Completion +@section Completion +Eshell uses the pcomplete package for programmable completion, similar +to that of other command shells. Argument completion differs depending +on the preceding command: for example, possible completions for +@command{rmdir} are only directories, while @command{rm} completions can +be directories @emph{and} files. Eshell provides predefined completions +for the built-in functions and some common external commands, and you +can define your own for any command. + +@kindex TAB +Eshell completion also works for Lisp forms and glob patterns. If the +point is on a Lisp form, then @key{TAB} will behave similarly to +completion in @code{elisp-mode} and @code{lisp-interaction-mode}. For +glob patterns, the pattern will be removed from the input line, and +replaced by the completion. + +@kindex M-? +If you want to see the entire list of possible completions (e.g. when it's +below the @code{completion-cycle-threshold}), press @kbd{M-?}. + +@subsection pcomplete +Pcomplete, short for programmable completion, is the completion +library originally written for Eshell, but usable for command +completion@footnote{Command completion, as opposed to code completion, +which is beyond the scope of pcomplete.} in other modes. + +Completions are defined as functions (with @code{defun}) named +@code{pcomplete/COMMAND}, where @code{COMMAND} is the name of the +command for which this function provides completions; you can also name +the function @code{pcomplete/MAJOR-MODE/COMMAND} to define completions +for a specific major mode. + +@node History +@section History +@cmindex history +@vindex eshell-history-size +The @samp{history} command shows all commands kept in the history ring +as numbered list. If the history ring contains +@code{eshell-history-size} commands, those numbers change after every +command invocation, therefore the @samp{history} command shall be +applied before using the expansion mechanism with history numbers. + +The n-th entry of the history ring can be applied with the @samp{!n} +command. If @code{n} is negative, the entry is counted from the end +of the history ring. + +@cindex event designators +@findex eshell-expand-history-references +When history event designators are enabled (by adding +@code{eshell-expand-history-references} to +@code{eshell-expand-input-functions}), @samp{!foo} expands to the last +command beginning with @code{foo}, and @samp{!?foo} to the last +command containing @code{foo}. The n-th argument of the last command +beginning with @code{foo} is accessible by @code{!foo:n}. + +@vindex eshell-history-file-name +@vindex eshell-history-append +The history is loaded to the history ring from the file +@code{eshell-history-file-name} at the start of every session, and +saved to that file at the end of every session. The default history +saving behavior is to overwrite the history file with the whole +history ring of the session. If @code{eshell-history-append} is +non-@code{nil}, the history will instead be saved by appending new +entries from the session to the history file, which could prevent +potential history loss with multiple Eshell sessions. Unlike other +shells, such as Bash, Eshell cannot currently be configured to control +the size of the history file. In particular, when +@code{eshell-history-append} is non-@code{nil}, the size of the file +will keep increasing, and the recommended way to truncate the file is +to run the @samp{history -w} command in an Eshell session. + +Since the default buffer navigation and searching key-bindings are +still present in the Eshell buffer, the commands for history +navigation and searching are bound to different keys: + +@table @kbd +@kindex M-r +@kindex M-s +@item M-r +@itemx M-s +History I-search. + +@kindex M-p +@kindex M-n +@item M-p +@itemx M-n +Previous and next history line. If there is anything on the input +line when you run these commands, they will instead jump to the +previous or next line that begins with that string. +@end table + @node Extension modules @chapter Extension modules Eshell provides a facility for defining extension modules so that they @@ -2524,6 +2564,10 @@ mimic the bindings used in other shells when the user is editing new input text. To enable this module, add @code{eshell-rebind} to @code{eshell-modules-list}. +@kindex C-u +@kindex C-w +@kindex C-p +@kindex C-n For example, it binds @kbd{C-u} to kill the current input text and @kbd{C-w} to @code{backward-kill-word}. If the history module is enabled, it also binds @kbd{C-p} and @kbd{C-n} to move through the @@ -3174,13 +3218,9 @@ Since it keeps the cursor up where the command was invoked. @printindex cm -@c There are no @kindex entries in this manual; avoid generating an -@c empty menu. -@ignore @node Key Index @unnumbered Key Index @printindex ky -@end ignore @bye commit 2a699edbe5e1ab39d97b30e8d783763adc0acf9c Author: Po Lu Date: Tue Jun 4 10:23:13 2024 +0800 Provide additional Android metadata * java/AndroidManifest.xml.in: Enable preserving user data beyond uninstallation, restarting activities without persiting state, increase maximum number of simultaneously open activities, and provide a sensible category. diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in index a95b46c3905..ff811ddf3f1 100644 --- a/java/AndroidManifest.xml.in +++ b/java/AndroidManifest.xml.in @@ -29,6 +29,8 @@ along with GNU Emacs. If not, see . --> android:targetSandboxVersion="1" android:installLocation="auto" android:requestLegacyExternalStorage="true" + android:hasFragileUserData="true" + android:appCategory="productivity" @ANDROID_SHARED_USER_ID@ @ANDROID_SHARED_USER_NAME@ android:versionCode="30" @@ -222,6 +224,7 @@ along with GNU Emacs. If not, see . --> android:taskAffinity="emacs.primary_frame" android:windowSoftInputMode="adjustResize" android:exported="true" + android:stateNotNeeded="true" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale"> @@ -278,6 +281,8 @@ along with GNU Emacs. If not, see . --> android:taskAffinity="emacs.secondary_frame" android:windowSoftInputMode="adjustResize" android:exported="true" + android:maxRecents="50" + android:stateNotNeeded="true" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale"/> Date: Tue Jun 4 10:03:01 2024 +0800 Enable downgrading between this and future releases of Emacs * java/AndroidManifest.xml.in: Fix `versionCode' at 30. diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in index f1047ac41d8..a95b46c3905 100644 --- a/java/AndroidManifest.xml.in +++ b/java/AndroidManifest.xml.in @@ -17,8 +17,12 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . --> - + . --> android:requestLegacyExternalStorage="true" @ANDROID_SHARED_USER_ID@ @ANDROID_SHARED_USER_NAME@ - android:versionCode="@emacs_major_version@" + android:versionCode="30" android:versionName="@version@"> - + Date: Mon Jun 3 21:13:38 2024 +0300 Move revert-buffer-restore-functions use from buff-menu.el to outline.el * lisp/buff-menu.el (Buffer-menu-mode): Remove revert-buffer-restore-functions with handling of outline-minor-mode and move it to outline-minor-mode. * lisp/outline.el (outline-minor-mode): Add revert-buffer-restore-functions to call outline-minor-mode-highlight-buffer after reverting the buffer with outline-minor-mode and outline-minor-mode-highlight where font-lock can't be used to update highlighting. diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index b431637414b..d59c5b6cf21 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -232,8 +232,6 @@ then the buffer will be displayed in the buffer list.") ["Quit" quit-window :help "Remove the buffer menu from the display"])) -(declare-function outline-minor-mode-highlight-buffer "outline" ()) - (define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu" "Major mode for Buffer Menu buffers. The Buffer Menu is invoked by the commands \\[list-buffers], @@ -276,13 +274,7 @@ In Buffer Menu mode, the following commands are defined: :interactive nil (setq-local buffer-stale-function (lambda (&optional _noconfirm) 'fast)) - (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t) - (add-hook 'revert-buffer-restore-functions - (lambda () - (when (bound-and-true-p outline-minor-mode) - (lambda () - (outline-minor-mode-highlight-buffer)))) - nil t)) + (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t)) (defun buffer-menu--display-help () (message "%s" diff --git a/lisp/outline.el b/lisp/outline.el index 5f4d4f3dcba..b7afa6b3f45 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -580,6 +580,14 @@ See the command `outline-mode' for more information on this mode." (add-hook 'change-major-mode-hook (lambda () (outline-minor-mode -1)) nil t) + (add-hook 'revert-buffer-restore-functions + (lambda () + (when (and outline-minor-mode outline-minor-mode-highlight + (not (and global-font-lock-mode + (font-lock-specified-p major-mode)))) + (lambda () + (outline-minor-mode-highlight-buffer)))) + nil t) (setq-local line-move-ignore-invisible t) ;; Cause use of ellipses for invisible text. (add-to-invisibility-spec '(outline . t)) commit 642bf58d4fbff4493b629837564b7e5c77c7615c Author: Eli Zaretskii Date: Mon Jun 3 21:13:05 2024 +0300 Avoid assertion violations in 'try_window_id' * src/xdisp.c (try_window_id): Avoid assertions in 'find_first_unchanged_at_end_row' due to 'init_iterator' freeing all the realized faces. (Bug#71274) diff --git a/src/xdisp.c b/src/xdisp.c index 47675fcc80a..3d8651f4086 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -22337,6 +22337,13 @@ try_window_id (struct window *w) start_pos = it.current.pos; } + /* init_to_row_end and start_display above could have caused the + window's window_end_valid flag to be reset (e.g., if init_iterator + decides to free all realized faces). We cannot continue if that + happens. */ + if (!w->window_end_valid) + GIVE_UP (108); + /* Find the first row that is not affected by changes at the end of the buffer. Value will be null if there is no unchanged row, in which case we must redisplay to the end of the window. delta commit 16fc5b6c0c72464a75d9a84b754375662b3acec6 Author: Stefan Monnier Date: Mon Jun 3 13:26:10 2024 -0400 pcase.el (\`): Try and handle large patterns better Large backquote patterns tend to lead to very large and deeply nested expansions, but they also tend to contain a lot of "constant" subpatterns that can be compiled to quote patterns. This patch does just that. See discussion at https://lists.gnu.org/archive/html/emacs-devel/2024-05/msg01140.html * lisp/emacs-lisp/pcase.el (pcase--split-pred): Improve the handling of pred-vs-quote so it also works with quoted objects like cons cells, vectors, and strings. Simplify the `pcase--mutually-exclusive-p` branch accordingly. (pcase--expand-\`): New function, extracted from the \` pcase macro. Make it recurse internally, and optimize backquote patterns to `quote` patterns where possible. (\`): Use it. * test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-vectors): Add tests that were broken by a more naïve version of the optimization. (pcase-tests-quote-optimization): New test. diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 1a58c60734a..69353daf7d0 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -829,16 +829,8 @@ A and B can be one of: (let* ((test (cadr (cadr upat))) (res (pcase--split-pred vars `(pred ,test) pat))) (cons (cdr res) (car res)))) - ((let ((otherpred - (cond ((eq 'pred (car-safe pat)) (cadr pat)) - ((not (eq 'quote (car-safe pat))) nil) - ((consp (cadr pat)) #'consp) - ((stringp (cadr pat)) #'stringp) - ((vectorp (cadr pat)) #'vectorp) - ((compiled-function-p (cadr pat)) - #'compiled-function-p)))) - (and otherpred - (pcase--mutually-exclusive-p (cadr upat) otherpred))) + ((and (eq 'pred (car-safe pat)) + (pcase--mutually-exclusive-p (cadr upat) (cadr pat))) '(:pcase--fail . nil)) ;; Since we turn (or 'a 'b 'c) into (pred (memq _ '(a b c))) ;; try and preserve the info we get from that memq test. @@ -852,7 +844,8 @@ A and B can be one of: '(:pcase--fail . nil)))) ((and (eq 'quote (car-safe pat)) (symbolp (cadr upat)) - (or (symbolp (cadr pat)) (stringp (cadr pat)) (numberp (cadr pat))) + (or (get (cadr upat) 'pure) ;FIXME: Drop this `or'? + (symbolp (cadr pat)) (stringp (cadr pat)) (numberp (cadr pat))) (get (cadr upat) 'side-effect-free) (ignore-errors (setq test (list (funcall (cadr upat) (cadr pat)))))) @@ -1124,21 +1117,36 @@ The predicate is the logical-AND of: - True! (The second element can be anything, and for the sake of the body forms, its value is bound to the symbol `forum'.)" (declare (debug (pcase-QPAT))) + (pcase--expand-\` qpat)) + +(defun pcase--expand-\` (qpat) (cond ((eq (car-safe qpat) '\,) (cadr qpat)) - ((eq (car-safe qpat) '\,@) (error "Unsupported QPAT: %S" qpat)) + ((or (eq (car-safe qpat) '\,@) (eq qpat '...)) + (error "Unsupported QPAT: %S" qpat)) ((vectorp qpat) - `(and (pred vectorp) - (app length ,(length qpat)) - ,@(let ((upats nil)) - (dotimes (i (length qpat)) - (push `(app (aref _ ,i) ,(list '\` (aref qpat i))) - upats)) - (nreverse upats)))) + (let* ((trivial t) + (contents nil) + (upats nil)) + (dotimes (i (length qpat)) + (let* ((upat (pcase--expand-\` (aref qpat i)))) + (if (eq (car-safe upat) 'quote) + (push (cadr upat) contents) + (setq trivial nil)) + (push `(app (aref _ ,i) ,upat) upats))) + (if trivial + `',(apply #'vector (nreverse contents)) + `(and (pred vectorp) + (app length ,(length qpat)) + ,@(nreverse upats))))) ((consp qpat) - `(and (pred consp) - (app car-safe ,(list '\` (car qpat))) - (app cdr-safe ,(list '\` (cdr qpat))))) + (let ((upata (pcase--expand-\` (car qpat))) + (upatd (pcase--expand-\` (cdr qpat)))) + (if (and (eq (car-safe upata) 'quote) (eq (car-safe upatd) 'quote)) + `'(,(cadr upata) . ,(cadr upatd)) + `(and (pred consp) + (app car-safe ,upata) + (app cdr-safe ,upatd))))) ((or (stringp qpat) (numberp qpat) (symbolp qpat)) `',qpat) ;; In all other cases just raise an error so we can't break ;; backward compatibility when adding \` support for other diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el index c79adcdfec5..35cf2f93cdc 100644 --- a/test/lisp/emacs-lisp/pcase-tests.el +++ b/test/lisp/emacs-lisp/pcase-tests.el @@ -73,7 +73,17 @@ (should-not (pcase-tests-grep 'member exp)))) (ert-deftest pcase-tests-vectors () - (should (equal (pcase [1 2] (`[,x] 1) (`[,x ,y] (+ x y))) 3))) + (should (equal (pcase [1 2] (`[,x] 1) (`[,x ,y] (+ x y))) 3)) + (should (pcase [1 2] (`[1 ,'2] t))) + (should (pcase '(1 2) (`(1 ,'2) t)))) + +(ert-deftest pcase-tests-quote-optimization () + ;; FIXME: We could/should also test that we get a corresponding + ;; "shadowed branch" warning. + (should-not (pcase-tests-grep + 'FOO (macroexpand '(pcase EXP + (`(,_ . ,_) (BAR)) + ('(a b) (FOO))))))) (ert-deftest pcase-tests-bug14773 () (let ((f (lambda (x) commit eb9afd558ec506f1d349dbb61668d6231fda136f Author: Eli Zaretskii Date: Mon Jun 3 20:37:31 2024 +0300 Avoid crashes and assertions while handling SIGWINCH * src/dispnew.c (build_frame_matrix_from_leaf_window) (window_to_frame_vpos): Avoid assertion violations when we have an unhandled SIGWINCH. (frame_size_change_delayed): New function. * src/dispextern.h (frame_size_change_delayed): Add prototype. * src/cm.c (cmcheckmagic): Don't check magicwrap if we have an unhandled SIGWINCH. (Bug#71289) diff --git a/src/cm.c b/src/cm.c index d6b54d507c7..85fc3e776c8 100644 --- a/src/cm.c +++ b/src/cm.c @@ -111,6 +111,10 @@ addcol (tty, n) { void cmcheckmagic (struct tty_display_info *tty) { + /* If we have unhandled SIGWINCH, we don't really know what are our + up-to-date frame diumensions. */ + if (frame_size_change_delayed ()) + return; if (curX (tty) == FrameCols (tty)) { if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1) diff --git a/src/dispextern.h b/src/dispextern.h index 28e59700469..8207e74a90c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3812,6 +3812,7 @@ extern void gui_update_window_end (struct window *, bool, bool); #endif void do_pending_window_change (bool); void change_frame_size (struct frame *, int, int, bool, bool, bool); +extern bool frame_size_change_delayed (void); void init_display (void); void syms_of_display (void); extern void spec_glyph_lookup_face (struct window *, GLYPH *); diff --git a/src/dispnew.c b/src/dispnew.c index 8eda8dbb358..dfa36a9f54f 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -2643,7 +2643,8 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w #ifdef GLYPH_DEBUG /* Window row window_y must be a slice of frame row frame_y. */ - eassert (glyph_row_slice_p (window_row, frame_row)); + eassert (delayed_size_change + || glyph_row_slice_p (window_row, frame_row)); /* If rows are in sync, we don't have to copy glyphs because frame and window share glyphs. */ @@ -3149,7 +3150,8 @@ window_to_frame_vpos (struct window *w, int vpos) eassert (!FRAME_WINDOW_P (XFRAME (w->frame))); eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows); vpos += WINDOW_TOP_EDGE_LINE (w); - eassert (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame))); + eassert (delayed_size_change + || (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame)))); return vpos; } @@ -6078,6 +6080,15 @@ change_frame_size (struct frame *f, int new_width, int new_height, else change_frame_size_1 (f, new_width, new_height, pretend, delay, safe); } + +/* Return non-zero if we delayed size-changes and haven't handled them + yet, which means we cannot be sure about the exact dimensions of our + frames. */ +bool +frame_size_change_delayed (void) +{ + return delayed_size_change; +} /*********************************************************************** Terminal Related Lisp Functions commit 4395f4d4530db77156b20209c1a81dce22c6e62d Author: Juri Linkov Date: Mon Jun 3 20:18:46 2024 +0300 New commands to show/hide outlines by regexp (bug#49731) * lisp/outline.el (outline-mode-prefix-map): Bind "/ s" to 'outline-show-by-heading-regexp', and "/ h" to 'outline-hide-by-heading-regexp'. (outline-show-by-heading-regexp) (outline-hide-by-heading-regexp): New commands. (outline-hidden-headings-regexp): New helper function. diff --git a/etc/NEWS b/etc/NEWS index 87f6d8f7e3c..302cd30a135 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -184,6 +184,12 @@ Set 'describe-mode-outline' to nil to get back the old behavior. ** Outline mode +*** New commands to show/hide outlines by regexp. +'/ h' ('outline-hide-by-heading-regexp') asks for a regexp and then +hides the body lines of all outlines whose heading lines match the +regexp. '/ s' ('outline-show-by-heading-regexp') does the same but +shows the matched outlines. + +++ *** 'outline-minor-mode' is supported in tree-sitter major modes. It can be used in all tree-sitter major modes that set either the diff --git a/lisp/outline.el b/lisp/outline.el index 40a75701cbf..5f4d4f3dcba 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -92,6 +92,8 @@ imitate the function `looking-at'.") (define-key map "\C-o" 'outline-hide-other) (define-key map "\C-^" 'outline-move-subtree-up) (define-key map "\C-v" 'outline-move-subtree-down) + (keymap-set map "/ s" #'outline-show-by-heading-regexp) + (keymap-set map "/ h" #'outline-hide-by-heading-regexp) (define-key map [(control ?<)] 'outline-promote) (define-key map [(control ?>)] 'outline-demote) (define-key map "\C-m" 'outline-insert-heading) @@ -1661,6 +1663,48 @@ LEVEL, decides of subtree visibility according to beg end))) (run-hooks 'outline-view-change-hook))) +(defun outline-show-by-heading-regexp (regexp) + "Show outlines whose headings match REGEXP." + (interactive (list (read-regexp "Regexp to show outlines"))) + (let (outline-view-change-hook) + (outline-map-region + (lambda () + (when (string-match-p regexp (buffer-substring (pos-bol) (pos-eol))) + (outline-show-branches) ;; To reveal all parent headings + (outline-show-entry))) + (point-min) (point-max))) + (run-hooks 'outline-view-change-hook)) + +(defun outline-hide-by-heading-regexp (regexp) + "Hide outlines whose headings match REGEXP." + (interactive (list (read-regexp "Regexp to hide outlines"))) + (let (outline-view-change-hook) + (outline-map-region + (lambda () + (when (string-match-p regexp (buffer-substring (pos-bol) (pos-eol))) + (outline-hide-subtree))) + (point-min) (point-max))) + (run-hooks 'outline-view-change-hook)) + +(defun outline-hidden-headings-regexp () + "Return a regexp that matches all currently hidden outlines. +This is useful to save the hidden outlines and restore them later, +for example, after reverting the buffer." + (let ((headings)) + (outline-map-region + (lambda () + (when (save-excursion + (outline-end-of-heading) + (seq-some (lambda (o) (eq (overlay-get o 'invisible) + 'outline)) + (overlays-at (point)))) + (push (buffer-substring (pos-bol) (pos-eol)) headings))) + (point-min) (point-max)) + (when headings + (mapconcat (lambda (heading) + (concat "\\`" (regexp-quote heading) "\\'")) + (nreverse headings) "\\|")))) + ;;; Visibility cycling commit a525cfb3af0c49c5c64e8af548ab23d086348fed Author: Juri Linkov Date: Mon Jun 3 19:55:47 2024 +0300 New variable 'revert-buffer-restore-functions' (bug#69511) * doc/lispref/backups.texi (Reverting): Add documentation for 'revert-buffer-restore-functions'. * lisp/files.el (revert-buffer-restore-functions): New variable. (revert-buffer-restore-read-only): New function. (revert-buffer): Use 'revert-buffer-restore-functions' with the default value 'revert-buffer-restore-read-only' (bug#69511). * lisp/buff-menu.el (Buffer-menu-mode): Add hook 'revert-buffer-restore-functions' to restore outline-minor-mode highlighting. diff --git a/doc/lispref/backups.texi b/doc/lispref/backups.texi index 8d0f3806646..a55b0a6aed2 100644 --- a/doc/lispref/backups.texi +++ b/doc/lispref/backups.texi @@ -777,6 +777,16 @@ after inserting the modified contents. A custom @code{revert-buffer-function} may or may not run this hook. @end defvar +@defvar revert-buffer-restore-functions +The value of this variable specifies a list of functions that preserve +the state of the buffer. Before the revert operation each function from +this list is called without arguments, and it should return a lambda +that preserves some particular state (for example, the read-only state). +After the revert operation each lambda will be called one by one in the +order of the list, and it should restore the saved state in the reverted +buffer. +@end defvar + Emacs can revert buffers automatically. It does that by default for buffers visiting files. The following describes how to add support for auto-reverting new types of buffers. diff --git a/etc/NEWS b/etc/NEWS index 80fadd122c3..87f6d8f7e3c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2773,6 +2773,10 @@ treesitter grammar. ** New buffer-local variable 'tabulated-list-groups'. It controls display and separate sorting of groups of entries. ++++ +** New variable 'revert-buffer-restore-functions'. +It helps to preserve various states after reverting the buffer. + --- ** New text property 'context-menu-functions'. Like the variable with the same name, it adds menus from the list that diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index d59c5b6cf21..b431637414b 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -232,6 +232,8 @@ then the buffer will be displayed in the buffer list.") ["Quit" quit-window :help "Remove the buffer menu from the display"])) +(declare-function outline-minor-mode-highlight-buffer "outline" ()) + (define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu" "Major mode for Buffer Menu buffers. The Buffer Menu is invoked by the commands \\[list-buffers], @@ -274,7 +276,13 @@ In Buffer Menu mode, the following commands are defined: :interactive nil (setq-local buffer-stale-function (lambda (&optional _noconfirm) 'fast)) - (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t)) + (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t) + (add-hook 'revert-buffer-restore-functions + (lambda () + (when (bound-and-true-p outline-minor-mode) + (lambda () + (outline-minor-mode-highlight-buffer)))) + nil t)) (defun buffer-menu--display-help () (message "%s" diff --git a/lisp/files.el b/lisp/files.el index b25cca00bb3..210cd0fa7ad 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6848,6 +6848,24 @@ A customized `revert-buffer-function' need not run this hook.") ;; `preserve-modes' argument of `revert-buffer'. (defvar revert-buffer-preserve-modes) +(defvar revert-buffer-restore-functions '(revert-buffer-restore-read-only) + "Functions to preserve any state during `revert-buffer'. +The value of this variable is a list of functions that are called before +reverting the buffer. Each of these functions are called without +arguments and should return a lambda that can restore a previous state +of the buffer. Then after reverting the buffer each of these lambdas +will be called one by one in the order of the list to restore previous +states of the buffer. An example of the buffer state is keeping the +buffer read-only, or keeping minor modes, etc.") + +(defun revert-buffer-restore-read-only () + "Preserve read-only state for `revert-buffer'." + (when-let ((state (and (boundp 'read-only-mode--state) + (list read-only-mode--state)))) + (lambda () + (setq buffer-read-only (car state)) + (setq-local read-only-mode--state (car state))))) + (defun revert-buffer (&optional ignore-auto noconfirm preserve-modes) "Replace current buffer text with the text of the visited file on disk. This undoes all changes since the file was visited or saved. @@ -6897,14 +6915,13 @@ preserve markers and overlays, at the price of being slower." (interactive (list (not current-prefix-arg))) (let ((revert-buffer-in-progress-p t) (revert-buffer-preserve-modes preserve-modes) - (state (and (boundp 'read-only-mode--state) - (list read-only-mode--state)))) + restore-functions) + (run-hook-wrapped 'revert-buffer-restore-functions + (lambda (f) (push (funcall f) restore-functions) nil)) ;; Return whatever 'revert-buffer-function' returns. (prog1 (funcall (or revert-buffer-function #'revert-buffer--default) ignore-auto noconfirm) - (when state - (setq buffer-read-only (car state)) - (setq-local read-only-mode--state (car state)))))) + (mapc #'funcall (delq nil restore-functions))))) (defun revert-buffer--default (ignore-auto noconfirm) "Default function for `revert-buffer'. commit 58a26db6261b752a34957a6554820a7cf5c05fc2 Author: Troy Brown Date: Sun Jun 2 11:48:54 2024 -0400 Support ada-ts-mode, gpr-mode and gpr-ts-mode in Eglot * lisp/progmodes/eglot.el (eglot-server-programs): Add ada-ts-mode, gpr-mode and gpr-ts-mode. Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index edbe484157b..5ccae5210fe 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -287,7 +287,8 @@ automatically)." '("language_server.bat") (eglot-alternatives '("language_server.sh" "start_lexical.sh")))) - (ada-mode . ("ada_language_server")) + ((ada-mode ada-ts-mode) . ("ada_language_server")) + ((gpr-mode gpr-ts-mode) . ("ada_language_server" "--language-gpr")) (scala-mode . ,(eglot-alternatives '("metals" "metals-emacs"))) (racket-mode . ("racket" "-l" "racket-langserver")) commit 2ae6451ec1216a9341080008d7065d6a75150455 Author: Andrea Corallo Date: Fri May 31 17:14:10 2024 +0200 Add 'message' to 'comp-primitive-type-specifiers' * lisp/emacs-lisp/comp-common.el (comp-primitive-type-specifiers): Add message. diff --git a/lisp/emacs-lisp/comp-common.el b/lisp/emacs-lisp/comp-common.el index ce6296953bf..e9b94681a4b 100644 --- a/lisp/emacs-lisp/comp-common.el +++ b/lisp/emacs-lisp/comp-common.el @@ -272,6 +272,7 @@ Used to modify the compiler environment." (member (function (t list) list)) (memq (function (t list) list)) (memql (function (t list) list)) + (message (function (string &rest t) string)) (min (function ((or number marker) &rest (or number marker)) number)) (minibuffer-selected-window (function () (or window null))) (minibuffer-window (function (&optional frame) window)) commit e39e96c9b93cf99d50f99f3e0593cbfbf0ac758d Author: Andrea Corallo Date: Fri May 31 17:00:50 2024 +0200 * lisp/emacs-lisp/comp.el (native-compile): Type declare. diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 32d4442ca1b..1627294199a 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -3583,6 +3583,8 @@ is a filename, if the compilation was successful return the filename of the compiled object. If FUNCTION-OR-FILE is a function symbol or a form, if the compilation was successful return the compiled function." + (declare (ftype (function ((or string symbol) &optional string) + (or native-comp-function string)))) (comp--native-compile function-or-file nil output)) ;;;###autoload commit 876bd6506d78392d7f6b8d13df678da21ad05af9 Author: Mattias Engdegård Date: Mon Jun 3 16:52:27 2024 +0200 ; compilation-error-regexp-alist-alist order comment diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index b18eb81fee1..e31af774bd0 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -194,6 +194,11 @@ and a string describing how the process finished.") (defvar compilation-error-regexp-alist-alist (eval-when-compile + ;; The order of this list is the default order of items in + ;; `compilation-error-regexp-alist' which is also the matching order, + ;; so don't add things in alphabetic order just out of habit. + ;; FIXME: We should sort it by frequency (less often used ones in the back), + ;; but individual patterns also have their own partial order. `((absoft "^\\(?:[Ee]rror on \\|[Ww]arning on\\( \\)\\)?[Ll]ine[ \t]+\\([0-9]+\\)[ \t]+\ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) commit bf6c3892dedea4c329fc884e6a1d59c463f1adac Author: Mattias Engdegård Date: Mon Jun 3 16:31:02 2024 +0200 Revert "Add support for Rust compilation messages" This reverts commit 2e862f81a355435fb7e837ffebee2f657c26ff23. It had serveral problems; see bug#70794. diff --git a/etc/compilation.txt b/etc/compilation.txt index 44388e1f197..05f0829864c 100644 --- a/etc/compilation.txt +++ b/etc/compilation.txt @@ -523,45 +523,6 @@ NoMethodError: undefined method `not_exists' for nil:NilClass 4 tests, 3 assertions, 3 failures, 1 errors -* Rust - -symbol: cargo - -The [] part is optional, and the file names are always relative to -project's root. - -error[E0425]: cannot find function `ruun` in module `broot::cli` - --> src/main.rs:6:23 - | -6 | match broot::cli::ruun() { - | ^^^^ help: a function with a similar name exists: `run` - | - ::: /tmp/broot/src/cli/mod.rs:49:1 - | -49 | pub fn run() -> Result, ProgramError> { - | -------------------------------------------------------- similarly - named function `run` defined here - -error: cannot find macro `deebug` in this scope - --> src/main.rs:5:5 - | -5 | deebug!("env::args(): {:#?}", std::env::args().collect::>()); - | ^^^^^^ help: a macro with a similar name exists: `debug` - | - ::: /home/ergo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.21/src/macros.rs:154:1 - | -154 | macro_rules! debug { - | ------------------ similarly named macro `debug` defined here - -warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> src/main.rs:3:1 - | -3 | #[feature(proc_macro_diagnostic)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_attributes)]` on by default - - * RXP symbol: rxp diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 2e4eb11811a..b18eb81fee1 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -224,13 +224,6 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) \\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:\\)?\\([ \n]Warning\\(?: [0-9]+\\)?:\\)?\\)" 2 (3 . 4) (5 . 6) (7)) - (cargo - "\\(?:\\(?4:error\\)\\|\\(?5:warning\\)\\):[^\0]+?--> \\(?1:[^:]+\\):\\(?2:[[:digit:]]+\\):\\(?3:[[:digit:]]+\\)" - 1 2 3 (5) - nil - (5 compilation-warning-face) - (4 compilation-error-face)) - (cmake "^CMake \\(?:Error\\|\\(Warning\\)\\) at \\(.*\\):\\([1-9][0-9]*\\) ([^)]+):$" 2 3 nil (1)) commit 4dfb0829ed3e9c0d26523242e8db9907191dc8db Author: Robert Pluim Date: Mon Jun 3 14:52:05 2024 +0200 Improve key binding documentation. * doc/emacs/custom.texi (Init Rebinding): Explain how to bind a key to a string and how to use non-ASCII characters. * lisp/keymap.el (keymap-global-set, keymap-local-set): Mention 'key-description'. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 0d695032d77..deac2c6c0ff 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1970,8 +1970,39 @@ and mouse events: (keymap-global-set "" 'mouse-save-then-kill) @end example - Language and coding systems may cause problems with key bindings for -non-@acronym{ASCII} characters. @xref{Init Non-ASCII}. +@cindex binding key to string + Key sequences can also be bound directly to Lisp strings rather than +commands. Such strings are written using the same syntax as key +sequences. For example, to bind @kbd{C-c h} to the string +@samp{hello}: + +@example +(keymap-global-set "C-c h" "h e l l o") +@end example + + Since this is somewhat cumbersome to write, the convenience function +@code{key-description} can be used instead: + +@example +(keymap-global-set "C-c h" (key-description "hello")) +@end example + + Non-@acronym{ASCII} characters can be specified directly in the +string. To bind to e.g. @samp{ol@U{00E1}}, use: + +@example +(keymap-global-set "C-c h" (key-description "ol@U{00E1}")) +@end example + + However, be aware that language and coding systems may cause problems +with key bindings for non-@acronym{ASCII} characters (@pxref{Init +Non-ASCII}). Writing the binding directly with the Unicode codepoint +avoids these problems (@pxref{International Chars} for how to determine +the codepoint of a character from within Emacs): + +@example +(keymap-global-set "C-c h" (key-description "ol\u00E1")) +@end example @findex global-set-key @findex define-key diff --git a/lisp/keymap.el b/lisp/keymap.el index 737c11dbd83..861d6724c9e 100644 --- a/lisp/keymap.el +++ b/lisp/keymap.el @@ -84,6 +84,10 @@ as its DEFINITION argument. If COMMAND is a string (which can only happen when this function is called from Lisp), it must satisfy `key-valid-p'. +The `key-description' convenience function converts a simple +string of characters to an equivalent form that is acceptable for +COMMAND. + Note that if KEY has a local binding in the current buffer, that local binding will continue to shadow any global binding that you make with this function." @@ -108,6 +112,10 @@ as its DEFINITION argument. If COMMAND is a string (which can only happen when this function is called from Lisp), it must satisfy `key-valid-p'. +The `key-description' convenience function converts a simple +string of characters to an equivalent form that is acceptable for +COMMAND. + The binding goes in the current buffer's local keymap, which in most cases is shared with all other buffers in the same major mode." (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)) commit 62d6ba2ede95805ba309bdc538628eb49b331f03 Author: Robert Pluim Date: Mon Jun 3 14:00:56 2024 +0200 Add common pairs to defcustom for electric-quote-chars * lisp/electric.el (electric--print-list-of-chars): New function to display chars as chars instead of integers in a custom widget. (electric-char-pair): New widget for displaying a pair of characters. (electric-quote-chars-pairs): New widget. Contains presets for common combinations of left/right quotation characters (electric-quote-chars): Update to use 'electric-quote-chars-pairs'. * etc/NEWS: Announce the change. diff --git a/etc/NEWS b/etc/NEWS index 5a1f7f3e443..80fadd122c3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -141,6 +141,12 @@ function to the advice to remove. ** Emacs now supports Unicode Standard version 15.1. +** New pre-defined values for 'electric-quote-chars'. +The available customization options for 'electric-quote-chars' have been +updated with common pairs of quotation characters, including "‘", "’", +"“", "”", "«", "»", "‹", "›", "‚", "„", "「", "」", "『", and "』". +The default is unchanged. + ** Network Security Manager +++ diff --git a/lisp/electric.el b/lisp/electric.el index fee0bf36d7f..d02bcb4735b 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -506,12 +506,64 @@ The variable `electric-layout-rules' says when and how to insert newlines." :version "25.1" :type 'boolean :safe 'booleanp :group 'electricity) +;; The default :value-create produces "list of numbers" when given "list +;; of characters", this prints them as characters. +(defun electric--print-list-of-chars (widget) + (let ((print-integers-as-characters t)) + (princ (widget-get widget :value) (current-buffer)))) + +;; This is just so we can make pairs print as characters. +(define-widget 'electric-char-pair 'const + "Electric quote character pair." + :group 'electricity + :format "%t: %v\n" + :inline t + :value-create #'electric--print-list-of-chars + :type '(list character character)) + +(define-widget 'electric-quote-chars-pairs 'lazy + "Choose pair of electric quote chars." + :group 'electricity + :type '(radio + (electric-char-pair :tag "Single" (?‘ ?’)) + (electric-char-pair :tag "Double" (?“ ?”)) + (electric-char-pair :tag "Guillemets" (?« ?»)) + (electric-char-pair :tag "Single guillemets" (?‹ ?›)) + (electric-char-pair :tag "Corners" (?「 ?」)) + (electric-char-pair :tag "Double corners" (?『 ?』)) + (electric-char-pair :tag "Low/high single left" (?‚ ?‘)) + (electric-char-pair :tag "Low/high double left" (?„ ?“)) + (electric-char-pair :tag "Low/high single right" (?‚ ?’)) + (electric-char-pair :tag "Low/high double right" (?„ ?”)) + (electric-char-pair :tag "Single inverted" (?’ ?‘)) + (electric-char-pair :tag "Right single only" (?’ ?’)) + (electric-char-pair :tag "Right double only" (?” ?”)) + (electric-char-pair :tag "Guillemets inverted" (?» ?«)) + (electric-char-pair :tag "Guillemets right only" (?» ?»)) + (electric-char-pair :tag "Single guillemets inverted" (?› ?‹)) + (electric-char-pair :tag "Mathematical double angle" (?⟪ ?⟫)) + (electric-char-pair :tag "Mathematical single angle" (?⟨ ?⟩)) + (electric-char-pair :tag "Double angle" (?《 ?》)) + (electric-char-pair :tag "Single angle" (?〈 ?〉)))) + (defcustom electric-quote-chars '(?‘ ?’ ?“ ?”) "Curved quote characters for `electric-quote-mode'. This list's members correspond to left single quote, right single -quote, left double quote, and right double quote, respectively." +quote, left double quote, and right double quote, respectively. + +Commonly used pairs are predefined, or you can define your own +completely custom style." :version "26.1" - :type '(list character character character character) + :type '(choice + (const :format "%t: %v\n" :tag "Default" + :value-create electric--print-list-of-chars + (?‘ ?’ ?“ ?”)) + (list :tag "Predefined pairs" + (electric-quote-chars-pairs :tag "Single quotes") + (electric-quote-chars-pairs :tag "Double quotes")) + (list :tag "Custom" + (character ?‘) (character ?’) + (character ?“) (character ?”))) :safe (lambda (x) (pcase x (`(,(pred characterp) ,(pred characterp) commit 68cc4cb6b1ce7ccc66084cb5e431bc9f6713bf04 Author: Po Lu Date: Mon Jun 3 20:37:41 2024 +0800 Small followup change * lisp/image.el (create-image): Remove supererogatory instances of pcase. Recognize new `lambda' values and refrain from specifying a default transform-smoothing when it is returned. (image--default-smoothing): Return lambda if scaling is default. * lisp/tool-bar.el (tool-bar--image-expression): Revert this portion of last change. diff --git a/lisp/image.el b/lisp/image.el index 654a15ef2b4..c155cda125e 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -520,7 +520,7 @@ Images should not be larger than specified by `max-image-size'." (let ((data-format ;; Pass the image format, if any, if this is data. (and data-p (or (plist-get props :format) t)))) - ;; It is x_find_image_file in image.c that sets the search path. + ;; It is `x_find_image_fd' in image.c that sets the search path. (setq type (ignore-error unknown-image-type (image-type file-or-data type data-format))) ;; If we have external image conversion switched on (for exotic, @@ -540,12 +540,13 @@ Images should not be larger than specified by `max-image-size'." props))) ;; Add default smoothing. (unless (plist-member props :transform-smoothing) - (setq image (nconc image - (list :transform-smoothing - (pcase image-transform-smoothing - ('t t) - ('nil nil) - (func (funcall func image))))))) + (let* ((func image-transform-smoothing) + (value (or (eq func t) + (and func (funcall func image))))) + (unless (eq value 'lambda) + (setq image (nconc image + (list :transform-smoothing + value)))))) ;; Add original map from map. (when (and (plist-get props :map) (not (plist-get props :original-map))) @@ -559,13 +560,18 @@ Images should not be larger than specified by `max-image-size'." image))) (defun image--default-smoothing (image) - "Say whether IMAGE should be smoothed when transformed." + "Say whether IMAGE should be smoothed when transformed. +Return `lambda' if the decision should be deferred to the time IMAGE is +loaded." (let* ((props (nthcdr 5 image)) (scaling (plist-get props :scale)) (rotation (plist-get props :rotation))) (cond + ;; The scale of the image won't be available until + ;; `image_set_transform', and as such, defer to its judgement. + ((eq scaling 'default) 'lambda) ;; We always smooth when scaling down and small upwards scaling. - ((and scaling (numberp scaling) (< scaling 2)) + ((and scaling (< scaling 2)) t) ;; Smooth when doing non-90-degree rotation ((and rotation diff --git a/lisp/tool-bar.el b/lisp/tool-bar.el index 1beb6dd819f..01c65c42324 100644 --- a/lisp/tool-bar.el +++ b/lisp/tool-bar.el @@ -220,8 +220,7 @@ To define items in any other map, use `tool-bar-local-item'." (let* ((fg (face-attribute 'tool-bar :foreground)) (bg (face-attribute 'tool-bar :background)) (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) - (if (eq bg 'unspecified) nil (list :background bg)) - '(:transform-smoothing nil))) + (if (eq bg 'unspecified) nil (list :background bg)))) (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) (xpm-lo-spec (list :type 'xpm :file (concat "low-color/" icon ".xpm"))) commit 3a54dfab2463913601a16756102ac1d30653a805 Author: Collin Funk Date: Mon Jun 3 02:35:06 2024 -0700 ; * src/xterm.c (syms_of_xterm): Fix doc string typos. Bug#71333 Copyright-paperwork-exempt: yes diff --git a/src/xterm.c b/src/xterm.c index 2f5e54f63d5..5e200203f64 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -32695,7 +32695,7 @@ Android does not support scroll bars at all. */); DEFSYM (Qfile_name_sans_extension, "file-name-sans-extension"); DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym, - doc: /* Which modifer value Emacs reports when Ctrl is depressed. + doc: /* Which modifier value Emacs reports when Ctrl is depressed. This should be one of the symbols `ctrl', `alt', `hyper', `meta', or `super', representing a modifier to be reported for key events with the Ctrl modifier (i.e. the keysym Ctrl_L or Ctrl_R) depressed, with nil or @@ -32703,7 +32703,7 @@ any other value equivalent to `ctrl'. */); Vx_ctrl_keysym = Qnil; DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym, - doc: /* Which modifer value Emacs reports when Alt is depressed. + doc: /* Which modifier value Emacs reports when Alt is depressed. This should be one of the symbols `ctrl', `alt', `hyper', `meta', or `super', representing a modifier to be reported for key events with the Alt modifier (e.g. the keysym Alt_L or Alt_R, if the keyboard features a @@ -32712,7 +32712,7 @@ equivalent to `alt'. */); Vx_alt_keysym = Qnil; DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym, - doc: /* Which modifer value Emacs reports when Hyper is depressed. + doc: /* Which modifier value Emacs reports when Hyper is depressed. This should be one of the symbols `ctrl', `alt', `hyper', `meta', or `super', representing a modifier to be reported for key events with the Hyper modifier (i.e. the keysym Hyper_L or Hyper_R) depressed, with nil @@ -32720,7 +32720,7 @@ or any other value equivalent to `hyper'. */); Vx_hyper_keysym = Qnil; DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym, - doc: /* Which modifer value Emacs reports when Meta is depressed. + doc: /* Which modifier value Emacs reports when Meta is depressed. This should be one of the symbols `ctrl', `alt', `hyper', `meta', or `super', representing a modifier to be reported for key events with the Meta modifier (e.g. the keysym Alt_L or Alt_R, when the keyboard does @@ -32729,7 +32729,7 @@ value equivalent to `meta'. */); Vx_meta_keysym = Qnil; DEFVAR_LISP ("x-super-keysym", Vx_super_keysym, - doc: /* Which modifer value Emacs reports when Super is depressed. + doc: /* Which modifier value Emacs reports when Super is depressed. This should be one of the symbols `ctrl', `alt', `hyper', `meta', or `super', representing a modifier to be reported for key events with the Super modifier (i.e. the keysym Super_L or Super_R) depressed, with nil commit bca2969373f343a16ba4b43406c08eec5792de83 Merge: 52f802363ad 3ad2dd7f3bf Author: Eli Zaretskii Date: Mon Jun 3 14:36:38 2024 +0300 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 52f802363ad34010cd073629a55831a52377dd43 Author: Eli Zaretskii Date: Mon Jun 3 14:35:51 2024 +0300 ; Fix doc strings in kmacro.el * lisp/kmacro.el (kmacro-reg-add-counter-equal) (kmacro-reg-add-counter-less, kmacro-reg-add-counter-greater): Clarify doc string. (Bug#61549) diff --git a/lisp/kmacro.el b/lisp/kmacro.el index 19a0e06bbd5..fa5572ec963 100644 --- a/lisp/kmacro.el +++ b/lisp/kmacro.el @@ -370,6 +370,7 @@ information." (defun kmacro-reg-add-counter-equal (&optional arg) "Increment counter by one if it is equal to register value. +Prompt for the register to compare. Optional non-nil ARG specifies the increment." (interactive "p") (let @@ -378,6 +379,7 @@ Optional non-nil ARG specifies the increment." (defun kmacro-reg-add-counter-less (&optional arg) "Increment counter by one if it is less than register value. +Prompt for the register to compare. Optional non-nil ARG specifies increment." (interactive "p") (let @@ -387,6 +389,7 @@ Optional non-nil ARG specifies increment." (defun kmacro-reg-add-counter-greater (&optional arg) "Increment counter by one if it is greater than register value. +Prompt for the register to compare. Optional non-nil ARG specifies increment." (interactive "p") (let commit 3ad2dd7f3bf5309aa5a12aa5d16b0d0d9f9364c4 Author: Robert Pluim Date: Mon Jun 3 13:29:54 2024 +0200 Add another iso-transl entry for Euro character * lisp/international/iso-transl.el (iso-transl-char-map): Add 'C-x 8 E' to align with the other currency characters. * etc/NEWS: Announce it. diff --git a/etc/NEWS b/etc/NEWS index d4d8ee87dec..5a1f7f3e443 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -616,6 +616,10 @@ respectively, after activating French language support via 'iso-transl-set-language'. Double guillemets were already supported via 'C-x 8 <' and 'C-x 8 >' +*** Additional 'C-x 8' key translation for Euro "€" currency symbol. +This can now be entered using 'C-x 8 E' in addition to the existing +'C-x 8 * E' translation. + * Changes in Specialized Modes and Packages in Emacs 30.1 diff --git a/lisp/international/iso-transl.el b/lisp/international/iso-transl.el index a3f2dfb9f9e..33a87b51e43 100644 --- a/lisp/international/iso-transl.el +++ b/lisp/international/iso-transl.el @@ -164,6 +164,8 @@ ("?" . [?¿]) ("*C" . [?©]) ("C" . [?©]) + ("*E" . [?€]) + ("E" . [?€]) ("*L" . [?£]) ("L" . [?£]) ("*P" . [?¶]) @@ -290,7 +292,6 @@ ("**" . [?•]) ("*'" . [?′]) ("*\"" . [?″]) - ("*E" . [?€]) ("No" . [?№]) ("a<" . [?←]) ("a>" . [?→]) commit 0e811aba53f5cc3a8d8c13fa8922149f95e83da4 Author: Robert Pluim Date: Thu May 16 16:25:24 2024 +0200 Improve support for entering quotation marks * lisp/international/iso-transl.el (iso-transl-char-map): Add entries for "low" single and double quotation marks. (iso-transl-language-alist): Add convenient support for the official German quoting style to the German language entry. It uses "low" double quotes on the left, and *left* double quotes on the right. Add support for single guillemets to the French language entry. * lisp/leim/quail/latin-post.el ("latin-postfix"): Add entries for single, double and "low" Unicode quotation marks. Add entries for single guillemets. * lisp/leim/quail/latin-pre.el ("latin-prefix"): And here. * etc/NEWS: Announce the changes. (Bug#70984) diff --git a/etc/NEWS b/etc/NEWS index 53abce8a472..d4d8ee87dec 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -586,6 +586,36 @@ These characters can now be input with 'C-x 8 a e' and 'C-x 8 A E', respectively, in addition to the existing translations 'C-x 8 / e' and 'C-x 8 / E'. +*** New 'C-x 8' key translations for "low" quotes "„", and "‚". +These can now be entered with 'C-x , "' and 'C-x , ''. + +*** New German language 'C-x 8' key translations for quotation marks. +The characters "„", "“", and "”" can now be entered with 'C-x 8 v', +'C-x 8 b' and 'C-x 8 n'. The single versions "‚", "‘", and "’" can now +be entered with 'C-x 8 V', 'C-x 8 B' and 'C-x 8 N'. These characters +are used for the official German quoting style. Using them requires +activating German language support via 'iso-transl-set-language'. + +*** "latin-prefix" and "latin-postfix" quotation marks additions. +These input methods can now produce single, double and "low" left and +right quotation marks: + + "‘", "’", "“", "”", "„", and "‚" + +by using "[", "]", and "," for "left", "right", and "low" respectively +to modify "'" and """. + +*** "latin-prefix" and "latin-postfix" guillemets support. +These input methods can now produce single guillemets "‹" and "›". For +"latin-prefix" use "~~<" and "~~>", for "latin-postfix" use "<~" and +">~". Double guillemets ("«" and "»") were already supported. + +*** New French language 'C-x 8' key translations for "‹" and "›". +These characters can now be entered using 'C-x 8 ~ <' and 'C-x 8 ~ >' +respectively, after activating French language support via +'iso-transl-set-language'. Double guillemets were already supported via +'C-x 8 <' and 'C-x 8 >' + * Changes in Specialized Modes and Packages in Emacs 30.1 diff --git a/lisp/international/iso-transl.el b/lisp/international/iso-transl.el index 67659f7c265..a3f2dfb9f9e 100644 --- a/lisp/international/iso-transl.el +++ b/lisp/international/iso-transl.el @@ -111,6 +111,8 @@ ("*+" . [?±]) ("+" . [?±]) (",," . [?¸]) + (",\"" . [?„]) + (",'" . [?‚]) (",A" . [?Ą]) (",C" . [?Ç]) (",N" . [?Ņ]) @@ -327,7 +329,9 @@ sequence VECTOR. (VECTOR is normally one character long.)") ("u" . [?ŭ])) ("French" ("C" . [?Ç]) - ("c" . [?ç])) + ("c" . [?ç]) + ("~<" . [?‹]) + ("~>" . [?›])) ("German" ("A" . [?Ä]) ("O" . [?Ö]) @@ -336,6 +340,12 @@ sequence VECTOR. (VECTOR is normally one character long.)") ("a" . [?ä]) ("o" . [?ö]) ("s" . [?ß]) + ("v" . [?„]) + ("b" . [?“]) + ("n" . [?”]) + ("V" . [?‚]) + ("B" . [?‘]) + ("N" . [?’]) ("u" . [?ü])) ("Portuguese" ("C" . [?Ç]) diff --git a/lisp/leim/quail/latin-post.el b/lisp/leim/quail/latin-post.el index 25e7c4a64a8..00851a94284 100644 --- a/lisp/leim/quail/latin-post.el +++ b/lisp/leim/quail/latin-post.el @@ -2302,6 +2302,9 @@ of characters from a single Latin-N charset. subscript | _ | 0_ -> ₀ 1_ -> ₁ +_ -> ₊ -_ -> ₋ others | / | s/ -> ß ?/ -> ¿ !/ -> ¡ // -> ° o/ -> œ | / | 2/ -> ½ 3/ -> ¾ 4/ -> ?¼ + | [ | \\='[ -> ‘ \"[ -> “ + | ] | \\='] -> ’ \"] -> ” + | , | \\=', -> ‚ \", -> „ | various | << -> « >> -> » o_ -> º a_ -> ª Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\=' @@ -2309,6 +2312,12 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\=' ;; Fixme: ¦ § ¨ © ¬ ± ´ µ ¶ · ¸ × ÷ (quail-define-rules + ("'[" ?‘) + ("']" ?’) + ("\"[" ?“) + ("\"]" ?”) + ("\"," ?„) + ("'," ?‚) ("2/" ?½) ("3/" ?¾) ("4/" ?¼) @@ -2341,6 +2350,8 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\=' ("//" ?°) ("<<" ?\«) (">>" ?\») + ("<~" ?\‹) + (">~" ?\›) ("?/" ?¿) ("$/" ?£) ("$/" ?¤) @@ -2532,6 +2543,12 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\=' ("z~" ?ž) ("--" ?¯) + ("'[[" ["'["]) + ("']]" ["']"]) + ("\"[[" ["\"["]) + ("\"]]" ["\"]"]) + ("\",," ["\","]) + ("',," ["',"]) ("2//" ["2/"]) ("3//" ["3/"]) ("4//" ["4/"]) @@ -2564,6 +2581,8 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\=' ("///" ["//"]) ("<<<" ["<<"]) (">>>" [">>"]) + ("<~~" ["<~"]) + (">~~" [">~"]) ("?//" ["?/"]) ("$//" ["$/"]) ("A''" ["A'"]) diff --git a/lisp/leim/quail/latin-pre.el b/lisp/leim/quail/latin-pre.el index 91164df0c72..b344a6304bb 100644 --- a/lisp/leim/quail/latin-pre.el +++ b/lisp/leim/quail/latin-pre.el @@ -1107,6 +1107,9 @@ of characters from a single Latin-N charset. macron | - | -a -> ā -/e -> ǣ -- -> ¯ dot above | / . | /g -> ġ .g -> ġ misc | \" ~ / | \"s -> ß ~d -> ð ~t -> þ /a -> å /e -> æ /o -> ø + | [ | [\\=' -> ‘ [\" -> “ + | ] | ]\\=' -> ’ ]\" -> ” + | , | ,\\=' -> ‚ ,\" -> „ symbol | ~ | ~> -> » ~< -> « ~! -> ¡ ~? -> ¿ ~~ -> ¸ symbol | _ / | _o -> º _a -> ª // -> ° /\\ -> × _y -> ¥ symbol | ^ | ^r -> ® ^t -> ™ ^c -> © ^1 -> ¹ ^2 -> ² ^3 -> ³ @@ -1132,6 +1135,12 @@ of characters from a single Latin-N charset. ("-y" ?ȳ) ("' " ?') ("''" ?´) + ("['" ?‘) + ("]'" ?’) + ("[\"" ?“) + ("]\"" ?”) + (",\"" ?„) + (",'" ?‚) ("'A" ?Á) ("'E" ?É) ("'I" ?Í) @@ -1295,8 +1304,10 @@ of characters from a single Latin-N charset. ("~-" ?­) ("~." ?·) ("~<" ?\«) + ("~~<" ?\‹) ("~=" ?¯) ("~>" ?\») + ("~~>" ?\›) ("~?" ?¿) ("~A" ?Ã) ("~A" ?Ă) commit 288b0db9682c519a3d7f8fa0c037640997209375 Author: Michael Albinus Date: Mon Jun 3 12:53:04 2024 +0200 Skip unmature file notification tests * test/lisp/filenotify-tests.el (file-notify--deftest-remote): Skip with "gio" library. It is unmature. diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index 28f4d5fa181..3a3dccfc7b1 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -278,6 +278,9 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (ert-test (ert-get-test ',test)) vc-handled-backends) (skip-unless (file-notify--test-remote-enabled)) + ;; These tests do not work for remote gio/GInotifyFileMonitor. + ;; Needs further investigation. + (skip-when (string-equal (file-notify--test-library) "gio")) (tramp-cleanup-connection (tramp-dissect-file-name temporary-file-directory) nil 'keep-password) (funcall (ert-test-body ert-test))))) commit a739cab66378a367cef8fa3a59f7ccb70a56bbb4 Author: Po Lu Date: Mon Jun 3 16:36:20 2024 +0800 ; * doc/lispref/display.texi (Image Descriptors): Insert missing text. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 864f85bdd46..64c2cab4ba6 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5946,12 +5946,12 @@ factor. @vindex image-scaling-factor Alternatively, the symbol @code{default} may be specified, indicating that the image should be scaled according as the value of the -@code{image-scaling-factor} variable, which by default scales the image -in proportion to the average widths (@pxref{Low-Level Font}) of the -default faces of frames on which it happens to be displayed, if such -widths should exceed @code{10} pixels. If no other value is provided, -@code{create-image} will specify this value in image specifications it -creates. +@code{image-scaling-factor} variable is the default @code{auto} or a +number, which by default scales the image in proportion to the average +widths (@pxref{Low-Level Font}) of the default faces of frames on which +it happens to be displayed, if such widths should exceed @code{10} +pixels. If no other value is provided, @code{create-image} will specify +this value in image specifications it creates. @item :rotation @var{angle} Specifies a rotation angle in degrees. Only multiples of 90 degrees commit 56376585134d627f96c71b7b063ec51548d3ad3f Author: Po Lu Date: Mon Jun 3 16:34:51 2024 +0800 Maintain relationship between tool bar image and default font width * doc/lispref/display.texi (Image Descriptors): Document new value of QCscale. * lisp/cus-start.el (standard) : New definition. * lisp/image.el (image-scaling-factor): Move to C. (create-image): Provide `default' as the default scaling factor. (image--default-smoothing): Accept non-integer scaling factors. (image-compute-scaling-factor): Document that this function is no longer invoked by Emacs. * lisp/tool-bar.el (tool-bar--image-expression): Disable transform smoothing for tool-bar icons. * src/dispextern.h (clear_image_cache): New definition. * src/frame.c (gui_set_font): Clear such image cache entries as derive their scales from the default font width. * src/image.c (clear_image_cache): Export function. (compute_image_size): Implement `default' by reading Vimage_scaling_factor and/or computing a scale factor from the frame's column width, as the case may be. New argument F. All callers changed. (syms_of_image) : Move from image.el. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 16b43553bc8..864f85bdd46 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5943,6 +5943,16 @@ values. If both @code{:scale} and @code{:height}/@code{:width} are specified, the height/width will be adjusted by the specified scaling factor. +@vindex image-scaling-factor +Alternatively, the symbol @code{default} may be specified, indicating +that the image should be scaled according as the value of the +@code{image-scaling-factor} variable, which by default scales the image +in proportion to the average widths (@pxref{Low-Level Font}) of the +default faces of frames on which it happens to be displayed, if such +widths should exceed @code{10} pixels. If no other value is provided, +@code{create-image} will specify this value in image specifications it +creates. + @item :rotation @var{angle} Specifies a rotation angle in degrees. Only multiples of 90 degrees are supported, unless the image type is @code{imagemagick}. Positive diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 165296d2242..a3299cde564 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -361,6 +361,10 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of ;; fringe.c (overflow-newline-into-fringe fringe boolean) ;; image.c + (image-scaling-factor image + (choice number + (const :tag "Automatically compute" auto)) + "26.1") (imagemagick-render-type image integer "24.1") ;; indent.c (indent-tabs-mode indent boolean) diff --git a/lisp/image.el b/lisp/image.el index e973dff32c7..654a15ef2b4 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -136,18 +136,6 @@ Subdirectories are not automatically included in the search." :type '(repeat (choice directory variable)) :initialize #'custom-initialize-delay) -(defcustom image-scaling-factor 'auto - "When displaying images, apply this scaling factor before displaying. -This is not supported for all image types, and is mostly useful -when you have a high-resolution monitor. -The value is either a floating point number (where numbers higher -than 1 means to increase the size and lower means to shrink the -size), or the symbol `auto', which will compute a scaling factor -based on the font pixel size." - :type '(choice number - (const :tag "Automatically compute" auto)) - :version "26.1") - (defcustom image-transform-smoothing #'image--default-smoothing "Whether to do smoothing when applying transforms to images. Common transforms are rescaling and rotation. @@ -548,9 +536,7 @@ Images should not be larger than specified by `max-image-size'." file-or-data) (and (not (plist-get props :scale)) ;; Add default scaling. - (list :scale - (image-compute-scaling-factor - image-scaling-factor))) + (list :scale 'default)) props))) ;; Add default smoothing. (unless (plist-member props :transform-smoothing) @@ -579,7 +565,7 @@ Images should not be larger than specified by `max-image-size'." (rotation (plist-get props :rotation))) (cond ;; We always smooth when scaling down and small upwards scaling. - ((and scaling (< scaling 2)) + ((and scaling (numberp scaling) (< scaling 2)) t) ;; Smooth when doing non-90-degree rotation ((and rotation @@ -619,7 +605,11 @@ properties specific to certain image types." (defun image-compute-scaling-factor (&optional scaling) "Compute the scaling factor based on SCALING. If a number, use that. If it's `auto', compute the factor. -If nil, use the `image-scaling-factor' variable." +If nil, use the `image-scaling-factor' variable. + +This function is provided for the benefit of Lisp code that +must compute this factor; it does not affect Emacs's scaling +of images." (unless scaling (setq scaling image-scaling-factor)) (cond diff --git a/lisp/tool-bar.el b/lisp/tool-bar.el index 01c65c42324..1beb6dd819f 100644 --- a/lisp/tool-bar.el +++ b/lisp/tool-bar.el @@ -220,7 +220,8 @@ To define items in any other map, use `tool-bar-local-item'." (let* ((fg (face-attribute 'tool-bar :foreground)) (bg (face-attribute 'tool-bar :background)) (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) - (if (eq bg 'unspecified) nil (list :background bg)))) + (if (eq bg 'unspecified) nil (list :background bg)) + '(:transform-smoothing nil))) (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) (xpm-lo-spec (list :type 'xpm :file (concat "low-color/" icon ".xpm"))) diff --git a/src/dispextern.h b/src/dispextern.h index 93cbde6583d..28e59700469 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3621,6 +3621,7 @@ extern void update_redisplay_ticks (int, struct window *); #ifdef HAVE_WINDOW_SYSTEM +extern void clear_image_cache (struct frame *, Lisp_Object); extern ptrdiff_t image_bitmap_pixmap (struct frame *, ptrdiff_t); extern void image_reference_bitmap (struct frame *, ptrdiff_t); extern ptrdiff_t image_create_bitmap_from_data (struct frame *, char *, diff --git a/src/frame.c b/src/frame.c index 80aa4a4a2e8..25620217680 100644 --- a/src/frame.c +++ b/src/frame.c @@ -4811,6 +4811,10 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) /* Recalculate toolbar height. */ f->n_tool_bar_rows = 0; + /* Clean F's image cache of images whose values derive from the font + width. */ + clear_image_cache (f, Qauto); + /* Ensure we redraw it. */ clear_current_matrices (f); diff --git a/src/image.c b/src/image.c index 321073a4fd9..879531d5264 100644 --- a/src/image.c +++ b/src/image.c @@ -2327,7 +2327,7 @@ free_image_cache (struct frame *f) If image-cache-eviction-delay is non-nil, this frees images in the cache which weren't displayed for at least that many seconds. */ -static void +void clear_image_cache (struct frame *f, Lisp_Object filter) { struct image_cache *c = FRAME_IMAGE_CACHE (f); @@ -2670,17 +2670,49 @@ image_get_dimension (struct image *img, Lisp_Object symbol) return -1; } -/* Compute the desired size of an image with native size WIDTH x HEIGHT. - Use IMG to deduce the size. Store the desired size into - *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */ +/* Compute the desired size of an image with native size WIDTH x HEIGHT, + which is to be displayed on F. Use IMG to deduce the size. Store + the desired size into *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the + native size is OK. */ + static void -compute_image_size (double width, double height, +compute_image_size (struct frame *f, double width, double height, struct image *img, int *d_width, int *d_height) { double scale = 1; Lisp_Object value = image_spec_value (img->spec, QCscale, NULL); - if (NUMBERP (value)) + + if (EQ (value, Qdefault)) + { + Lisp_Object sval = Vimage_scaling_factor; + + /* Compute the scale from factors specified by the value of + Vimage_scaling_factor. */ + + invalid_value: + if (EQ (sval, Qauto)) + { + /* This is a tag with which callers of `clear_image_cache' can + refer to this image and its likenesses. */ + img->dependencies = Fcons (Qauto, img->dependencies); + scale = (FRAME_COLUMN_WIDTH (f) > 10 + ? (FRAME_COLUMN_WIDTH (f) / 10.0f) : 1); + } + else if (NUMBERP (sval)) + scale = XFLOATINT (sval); + else + { + image_error ("Invalid `image-scaling-factor': %s", + Vimage_scaling_factor); + + /* If Vimage_scaling_factor is set to an invalid value, treat + it as though it were the default. */ + sval = Qauto; + goto invalid_value; + } + } + else if (NUMBERP (value)) { double dval = XFLOATINT (value); if (0 <= dval) @@ -3009,7 +3041,8 @@ image_set_transform (struct frame *f, struct image *img) } else #endif - compute_image_size (img->width, img->height, img, &width, &height); + compute_image_size (f, img->width, img->height, img, &width, + &height); /* Determine rotation. */ double rotation = 0.0; @@ -11161,7 +11194,7 @@ imagemagick_load_image (struct frame *f, struct image *img, } #ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE - compute_image_size (MagickGetImageWidth (image_wand), + compute_image_size (f, MagickGetImageWidth (image_wand), MagickGetImageHeight (image_wand), img, &desired_width, &desired_height); #else @@ -12134,7 +12167,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, #endif #ifdef HAVE_NATIVE_TRANSFORMS - compute_image_size (viewbox_width, viewbox_height, img, + compute_image_size (f, viewbox_width, viewbox_height, img, &width, &height); width = scale_image_size (width, 1, FRAME_SCALE_FACTOR (f)); @@ -12877,6 +12910,7 @@ non-numeric, there is no explicit limit on the size of images. */); DEFSYM (Qcount, "count"); DEFSYM (Qextension_data, "extension-data"); DEFSYM (Qdelay, "delay"); + DEFSYM (Qauto, "auto"); /* Keywords. */ DEFSYM (QCascent, ":ascent"); @@ -13089,6 +13123,17 @@ The value can also be nil, meaning the cache is never cleared. The function `clear-image-cache' disregards this variable. */); Vimage_cache_eviction_delay = make_fixnum (300); + + DEFVAR_LISP ("image-scaling-factor", Vimage_scaling_factor, + doc: /* When displaying images, apply this scaling factor before displaying. +This is not supported for all image types, and is mostly useful +when you have a high-resolution monitor. +The value is either a floating point number (where numbers higher +than 1 means to increase the size and lower means to shrink the +size), or the symbol `auto', which will compute a scaling factor +based on the font pixel size. */); + Vimage_scaling_factor = Qauto; + #ifdef HAVE_IMAGEMAGICK DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type, doc: /* Integer indicating which ImageMagick rendering method to use.