diff --git a/.gitignore b/.gitignore index 52816e8473f..aebd507486e 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ lib/execinfo.h lib/fcntl.h lib/getopt.h lib/getopt-cdefs.h +lib/gmp.h lib/ieee754.h lib/inttypes.h lib/libgnu.a diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 5a78b052b24..3f32536a629 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -36,7 +36,7 @@ GNULIB_MODULES=' fchmodat fcntl fcntl-h fdopendir filemode filename filevercmp flexmember fpieee fstatat fsusage fsync futimens getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog - ieee754-h ignore-value intprops largefile lstat + ieee754-h ignore-value intprops largefile libgmp lstat manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime pathmax pipe2 pselect pthread_sigmask qcopy-acl readlink readlinkat regex diff --git a/configure.ac b/configure.ac index ac9f23e04a6..2277f36e491 100644 --- a/configure.ac +++ b/configure.ac @@ -1031,14 +1031,17 @@ AS_IF([test $gl_gcc_warnings = no], ;; esac AS_IF([test $gl_gcc_warnings = yes], - [WERROR_CFLAGS=-Werror]) + [WERROR_CFLAGS=-Werror], + [# Use -fanalyzer and related options only if --enable-gcc-warnings, + # as they slow GCC considerably. + nw="$nw -fanalyzer -Wno-analyzer-double-free -Wno-analyzer-malloc-leak" + nw="$nw -Wno-analyzer-null-dereference -Wno-analyzer-use-after-free"]) - nw="$nw -Wcast-align -Wcast-align=strict" # Emacs is tricky with pointers. + nw="$nw -Wcast-align=strict" # Emacs is tricky with pointers. nw="$nw -Wduplicated-branches" # Too many false alarms nw="$nw -Wformat-overflow=2" # False alarms due to GCC bug 80776 nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings nw="$nw -Woverlength-strings" # Not a problem these days - nw="$nw -Wformat-nonliteral" # we do this a lot nw="$nw -Wvla" # Emacs uses . nw="$nw -Wunused-const-variable=2" # lisp.h declares const objects. nw="$nw -Winline" # OK to ignore 'inline' @@ -1047,7 +1050,6 @@ AS_IF([test $gl_gcc_warnings = no], nw="$nw -Wsync-nand" # irrelevant here, and provokes ObjC warning nw="$nw -Wunsafe-loop-optimizations" # OK to suppress unsafe optimizations nw="$nw -Wbad-function-cast" # These casts are no worse than others. - nw="$nw -Wabi" # Not useful, perceived as noise # Emacs doesn't care about shadowing; see # . @@ -1067,26 +1069,12 @@ AS_IF([test $gl_gcc_warnings = no], # option problematic. nw="$nw -Wsuggest-attribute=pure" - # This part is merely for shortening the command line, - # since -Wall implies -Wswitch. - nw="$nw -Wswitch" - - # This part is merely for shortening the command line, - # since -Wno-FOO needs to be added below regardless. - nw="$nw -Wmissing-field-initializers" - nw="$nw -Woverride-init" - nw="$nw -Wtype-limits" - nw="$nw -Wunused-parameter" - if test "$emacs_cv_clang" = yes; then - nw="$nw -Wcast-align" nw="$nw -Wdouble-promotion" - nw="$nw -Wmissing-braces" fi - # These cause too much noise in the MinGW build + # This causes too much noise in the MinGW build. if test $opsys = mingw32; then - nw="$nw -Wpointer-sign" nw="$nw -Wsuggest-attribute=format" fi @@ -4607,32 +4595,6 @@ AC_SUBST(KRB5LIB) AC_SUBST(DESLIB) AC_SUBST(KRB4LIB) -AC_ARG_WITH([libgmp], - [AS_HELP_STRING([--without-libgmp], - [don't use the GNU Multiple Precision (GMP) library; - this is the default on systems lacking libgmp.])]) -GMP_LIB= -GMP_OBJ=mini-gmp-emacs.o -HAVE_GMP=no -case $with_libgmp in - no) ;; - yes) HAVE_GMP=yes GMP_LIB=-lgmp;; - *) AC_CHECK_HEADERS([gmp.h], - [OLIBS=$LIBS - AC_SEARCH_LIBS([__gmpz_roinit_n], [gmp]) - LIBS=$OLIBS - case $ac_cv_search___gmpz_roinit_n in - 'none needed') HAVE_GMP=yes;; - -*) HAVE_GMP=yes GMP_LIB=$ac_cv_search___gmpz_roinit_n;; - esac]);; -esac -if test "$HAVE_GMP" = yes; then - GMP_OBJ= - AC_DEFINE([HAVE_GMP], 1, [Define to 1 if you have recent-enough GMP.]) -fi -AC_SUBST([GMP_LIB]) -AC_SUBST([GMP_OBJ]) - AC_CHECK_HEADERS(valgrind/valgrind.h) AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include ]]) @@ -5800,6 +5762,11 @@ done AC_DEFINE_UNQUOTED(EMACS_CONFIG_FEATURES, "${emacs_config_features}", [Summary of some of the main features enabled by configure.]) +if test -z "$GMP_H"; then + HAVE_GMP=yes +else + HAVE_GMP=no +fi AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D} Does Emacs use -lXpm? ${HAVE_XPM} Does Emacs use -ljpeg? ${HAVE_JPEG} @@ -5828,7 +5795,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D Does Emacs use -lxft? ${HAVE_XFT} Does Emacs use -lsystemd? ${HAVE_LIBSYSTEMD} Does Emacs use -ljansson? ${HAVE_JSON} - Does Emacs use -lgmp? ${HAVE_GMP} + Does Emacs use the GMP library? ${HAVE_GMP} Does Emacs directly use zlib? ${HAVE_ZLIB} Does Emacs have dynamic modules support? ${HAVE_MODULES} Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS} diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index d034a78501b..719e09e8616 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1223,7 +1223,7 @@ other context has no special meaning. disable a minor mode in a local variables list, use the @code{eval} keyword with a Lisp expression that runs the mode command (@pxref{Minor Modes}). For example, the following local variables -list enables Eldoc mode (@pxref{Lisp Doc}) by calling +list enables ElDoc mode (@pxref{Lisp Doc}) by calling @code{eldoc-mode} with no argument (calling it with an argument of 1 would do the same), and disables Font Lock mode (@pxref{Font Lock}) by calling @code{font-lock-mode} with an argument of @minus{}1. diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi index c1420ea13ff..c9c175d51e8 100644 --- a/doc/emacs/modes.texi +++ b/doc/emacs/modes.texi @@ -126,7 +126,7 @@ see which mode is actually being entered. Mode hooks are commonly used to enable minor modes (@pxref{Minor Modes}). For example, you can put the following lines in your init file to enable Flyspell minor mode in all text-based major modes -(@pxref{Spelling}), and Eldoc minor mode in Emacs Lisp mode +(@pxref{Spelling}), and ElDoc minor mode in Emacs Lisp mode (@pxref{Lisp Doc}): @example diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi index 373c7b55817..0f07d286cda 100644 --- a/doc/emacs/mule.texi +++ b/doc/emacs/mule.texi @@ -192,13 +192,19 @@ What keys to type to input the character in the current input method @item The character's encodings, both internally in the buffer, and externally -if you were to save the file. +if you were to save the buffer to a file. @item If you are running Emacs on a graphical display, the font name and glyph code for the character. If you are running Emacs on a text terminal, the code(s) sent to the terminal. +@item +If the character was composed on display with any following characters +to form one or more grapheme clusters, the composition information: +the font glyphs if the frame is on a graphical display, else the +characters that were composed. + @item The character's text properties (@pxref{Text Properties,,, elisp, the Emacs Lisp Reference Manual}), including any non-default diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index 2757c84b53a..1c33d7dccc7 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -1260,16 +1260,16 @@ the WoMan Info manual, which is distributed with Emacs. to view the built-in documentation for the Lisp functions and variables that you want to use. @xref{Name Help}. -@cindex Eldoc mode +@cindex ElDoc mode @findex eldoc-mode @findex global-eldoc-mode - Eldoc is a buffer-local minor mode that helps with looking up Lisp + ElDoc is a buffer-local minor mode that helps with looking up Lisp documentation. When it is enabled, the echo area displays some useful information whenever there is a Lisp function or variable at point; for a function, it shows the argument list, and for a variable it shows the first line of the variable's documentation string. To -toggle Eldoc mode, type @kbd{M-x eldoc-mode}. There's also a Global -Eldoc mode, which is turned on by default, and affects buffers whose +toggle ElDoc mode, type @kbd{M-x eldoc-mode}. There's also a Global +ElDoc mode, which is turned on by default, and affects buffers whose major mode sets the variables described below. Use @w{@kbd{M-x global-eldoc-mode}} to turn it off globally. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index d7aab4ae62f..25eabd6c3fc 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -4275,9 +4275,15 @@ a display specification has the form @var{fringe} is either the symbol @code{left-fringe} or @code{right-fringe}. @var{bitmap} is a symbol identifying the bitmap to display. The optional @var{face} names a face whose foreground and -background colors are to be used to display the bitmap; this face is -automatically merged with the @code{fringe} face. If @var{face} is -omitted, that means to use the @code{default} face. +background colors are to be used to display the bitmap, using the +attributes of the @code{fringe} face for colors that @var{face} didn't +specify. If @var{face} is omitted, that means to use the attributes +of the @code{default} face for the colors which the @code{fringe} face +didn't specify. For predictable results that don't depend on the +attributes of the @code{default} and @code{fringe} faces, we recommend +you never omit @var{face}, but always provide a specific face. In +particular, if you want the bitmap to be always displayed in the +@code{fringe} face, use @code{fringe} as @var{face}. For instance, to display an arrow in the left fringe, using the @code{warning} face, you could say something like: diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 4002b36ce50..f018ef4c7c0 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -227,6 +227,9 @@ you are using. On all computers supported by Emacs, this is and is discussed further in David Goldberg's paper ``@url{https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html, What Every Computer Scientist Should Know About Floating-Point Arithmetic}''. +On modern platforms, floating-point operations follow the IEEE-754 +standard closely; however, results are not always rounded correctly on +some obsolescent platforms, notably 32-bit x86. The read syntax for floating-point numbers requires either a decimal point, an exponent, or both. Optional signs (@samp{+} or @samp{-}) diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 2ef88b90254..8de6255478b 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -248,7 +248,7 @@ properties removed. @defun concat &rest sequences @cindex copying strings @cindex concatenating strings -This function returns a new string consisting of the characters in the +This function returns a string consisting of the characters in the arguments passed to it (along with their text properties, if any). The arguments may be strings, lists of numbers, or vectors of numbers; they are not themselves changed. If @code{concat} receives no arguments, it @@ -269,9 +269,14 @@ returns an empty string. @end example @noindent -This function always constructs a new string that is not @code{eq} to -any existing string, except when the result is the empty string (to -save space, Emacs makes only one empty multibyte string). +This function does not always allocate a new string. Callers are +advised not rely on the result being a new string nor on it being +@code{eq} to an existing string. + +In particular, mutating the returned value may inadvertently change +another string, alter a constant string in the program, or even raise +an error. To obtain a string that you can safely mutate, use +@code{copy-sequence} on the result. For information about other concatenation functions, see the description of @code{mapconcat} in @ref{Mapping Functions}, diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index 701340ed6e2..4ead6032b74 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -83,6 +83,8 @@ Currently supported back-ends are: LDAP, Lightweight Directory Access Protocol @item BBDB, Big Brother's Insidious Database +@item +macOS Contacts @end itemize The main features of the EUDC interface are: @@ -107,6 +109,7 @@ Interface to BBDB to let you insert server records into your own BBDB database @menu * LDAP:: What is LDAP ? * BBDB:: What is BBDB ? +* macOS Contacts:: What is macOS Contacts ? @end menu @@ -159,6 +162,21 @@ queries on multiple servers. EUDC also offers a means to insert results from directory queries into your own local BBDB (@pxref{Creating BBDB Records}) + +@node macOS Contacts +@section macOS Contacts + +macOS Contacts is the rolodex-like application that ships with the +macOS operating system@footnote{Apple have changed the names of their +operating system and some applications over time. macOS used to be +called Mac OS X in the past, and the Contacts application was +previously called Address Book.}. + +EUDC considers macOS Contacts as a directory server back end just like +LDAP, though the macOS Contacts application always resides locally on +your machine. + + @node Installation @chapter Installation @@ -185,6 +203,7 @@ email composition buffers (@pxref{Inline Query Expansion}) @menu * LDAP Configuration:: EUDC needs external support for LDAP +* macOS Contacts Configuration:: Enable the macOS Contacts backend @end menu @node LDAP Configuration @@ -379,6 +398,39 @@ The @command{ldapsearch} command is formatted such that it can be copied and pasted into a terminal. Set the @command{ldapsearch} debug level to 5 by appending @code{-d 5} to the command line. + +@node macOS Contacts Configuration +@section macOS Contacts Configuration + +macOS Contacts support is added by means of @file{eudcb-mab.el}, or +@file{eudcb-macos-contacts.el} which are part of Emacs. + +To enable a macOS Contacts backend, first `require' the respective +library to load it, and then set the `eudc-server' to localhost in +your init file: +@lisp +(require 'eudcb-macos-contacts) +(eudc-macos-contacts-set-server "localhost") +@end lisp + +@file{eudcb-macos-contacts.el} uses the public scripting interfaces +offered by the Contacts app via the macOS Open Scripting Architecture +(OSA). To accomplish this, @file{eudcb-macos-contacts.el} uses an +external command line utility named osascript, which is included with +all macOS versions since 10.0 (which was released 2001). +@file{eudcb-macos-contacts.el} is hence recommended for all new +configurations. + +@file{eudcb-mab.el} reverse engineers the format of the database file +used by the macOS Contacts app, and accesses its contents directly. +While this may promise some performance advantages, it comes at the +cost of using an undocumented interface. Hence, users of +@file{eudcb-mab.el} are recommended to double check the compatibility +of @file{eudcb-mab.el} before upgrading to a new version of macOS. +@file{eudcb-mab.el} is retained for backwards compatibility with +existing configurations, and may be removed in a future release. + + @node Usage @chapter Usage diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index 19dcb19de74..89d2265f816 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -684,7 +684,7 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be active. msg) into diags finally (funcall report-fn diags))) - (flymake-log :warning "Canceling obsolete check %s" + (flymake-log :warning "Cancelling obsolete check %s" proc)) ;; Cleanup the temporary buffer used to hold the ;; check's output. diff --git a/etc/NEWS b/etc/NEWS index 07403f2fb63..e55f57e01af 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -279,6 +279,13 @@ This allows users to use (define-key eshell-mode-map ...) as usual. Some modules have their own minor mode now to account for these changes. +** EUDC + ++++ +*** New macOS Contacts backend. +This backend works on newer versions of macOS and is generally +preferred over the eudcb-mab.el backend. + ** Tramp +++ diff --git a/etc/NEWS.22 b/etc/NEWS.22 index 548a73a0be9..4df1792fbc7 100644 --- a/etc/NEWS.22 +++ b/etc/NEWS.22 @@ -5239,7 +5239,7 @@ has no effect on systems with case-insensitive file names. hooks. `run-mode-hooks' does this automatically. *** Major modes can define `eldoc-documentation-function' -locally to provide Eldoc functionality by some method appropriate to +locally to provide ElDoc functionality by some method appropriate to the language. *** Use the new function `run-mode-hooks' to run the major mode's mode hook. diff --git a/etc/NEWS.23 b/etc/NEWS.23 index 9a49a7d4fcc..331ed281a37 100644 --- a/etc/NEWS.23 +++ b/etc/NEWS.23 @@ -1779,7 +1779,7 @@ to update it to the new VC. If `default-directory' is a remote file name, subprocesses are started on the corresponding remote system. -*** Eldoc highlights the function argument under point +*** ElDoc highlights the function argument under point with the face `eldoc-highlight-function-argument'. *** In Etags, the --members option is now the default. diff --git a/lib/alloca.in.h b/lib/alloca.in.h index c7187e66ae3..5686b082bbe 100644 --- a/lib/alloca.in.h +++ b/lib/alloca.in.h @@ -34,14 +34,17 @@ request, the program just crashes. */ +#ifndef alloca + /* Some version of mingw have an that causes trouble when + included after 'alloca' gets defined as a macro. As a workaround, + include this first and define 'alloca' as a macro afterwards + if needed. */ +# if defined __GNUC__ && (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@ +# include_next +# endif +#endif #ifndef alloca # ifdef __GNUC__ - /* Some version of mingw have an that causes trouble when - included after 'alloca' gets defined as a macro. As a workaround, include - this first and define 'alloca' as a macro afterwards. */ -# if (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@ -# include_next -# endif # define alloca __builtin_alloca # elif defined _AIX # define alloca __alloca diff --git a/lib/dup2.c b/lib/dup2.c index 88ef2591313..9bc3951f3d2 100644 --- a/lib/dup2.c +++ b/lib/dup2.c @@ -25,28 +25,26 @@ #include #include -#if HAVE_DUP2 +#undef dup2 -# undef dup2 - -# if defined _WIN32 && ! defined __CYGWIN__ +#if defined _WIN32 && ! defined __CYGWIN__ /* Get declarations of the native Windows API functions. */ -# define WIN32_LEAN_AND_MEAN -# include +# define WIN32_LEAN_AND_MEAN +# include -# if HAVE_MSVC_INVALID_PARAMETER_HANDLER -# include "msvc-inval.h" -# endif +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +# endif /* Get _get_osfhandle. */ -# if GNULIB_MSVC_NOTHROW -# include "msvc-nothrow.h" -# else -# include -# endif +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif -# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER static int dup2_nothrow (int fd, int desired_fd) { @@ -65,9 +63,9 @@ dup2_nothrow (int fd, int desired_fd) return result; } -# else -# define dup2_nothrow dup2 -# endif +# else +# define dup2_nothrow dup2 +# endif static int ms_windows_dup2 (int fd, int desired_fd) @@ -103,11 +101,11 @@ ms_windows_dup2 (int fd, int desired_fd) return result; } -# define dup2 ms_windows_dup2 +# define dup2 ms_windows_dup2 -# elif defined __KLIBC__ +#elif defined __KLIBC__ -# include +# include static int klibc_dup2dirfd (int fd, int desired_fd) @@ -155,81 +153,37 @@ klibc_dup2 (int fd, int desired_fd) return dupfd; } -# define dup2 klibc_dup2 -# endif +# define dup2 klibc_dup2 +#endif int rpl_dup2 (int fd, int desired_fd) { int result; -# ifdef F_GETFL +#ifdef F_GETFL /* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF. On Cygwin 1.5.x, dup2 (1, 1) returns 0. On Cygwin 1.7.17, dup2 (1, -1) dumps core. On Cygwin 1.7.25, dup2 (1, 256) can dump core. On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */ -# if HAVE_SETDTABLESIZE +# if HAVE_SETDTABLESIZE setdtablesize (desired_fd + 1); -# endif +# endif if (desired_fd < 0) fd = desired_fd; if (fd == desired_fd) return fcntl (fd, F_GETFL) == -1 ? -1 : fd; -# endif +#endif result = dup2 (fd, desired_fd); /* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x. */ if (result == -1 && errno == EMFILE) errno = EBADF; -# if REPLACE_FCHDIR +#if REPLACE_FCHDIR if (fd != desired_fd && result != -1) result = _gl_register_dup (fd, result); -# endif +#endif return result; } - -#else /* !HAVE_DUP2 */ - -/* On older platforms, dup2 did not exist. */ - -# ifndef F_DUPFD -static int -dupfd (int fd, int desired_fd) -{ - int duplicated_fd = dup (fd); - if (duplicated_fd < 0 || duplicated_fd == desired_fd) - return duplicated_fd; - else - { - int r = dupfd (fd, desired_fd); - int e = errno; - close (duplicated_fd); - errno = e; - return r; - } -} -# endif - -int -dup2 (int fd, int desired_fd) -{ - int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd; - if (result == -1 || fd == desired_fd) - return result; - close (desired_fd); -# ifdef F_DUPFD - result = fcntl (fd, F_DUPFD, desired_fd); -# if REPLACE_FCHDIR - if (0 <= result) - result = _gl_register_dup (fd, result); -# endif -# else - result = dupfd (fd, desired_fd); -# endif - if (result == -1 && (errno == EMFILE || errno == EINVAL)) - errno = EBADF; - return result; -} -#endif /* !HAVE_DUP2 */ diff --git a/lib/getrandom.c b/lib/getrandom.c index 030a78bb08d..f8695abf30a 100644 --- a/lib/getrandom.c +++ b/lib/getrandom.c @@ -32,7 +32,7 @@ # if HAVE_BCRYPT_H # include # else -# include /* NTSTATUS */ +# define NTSTATUS LONG typedef void * BCRYPT_ALG_HANDLE; # define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 # if HAVE_LIB_BCRYPT diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 35d2db09bd4..68cae8faf74 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -117,6 +117,7 @@ # ignore-value \ # intprops \ # largefile \ +# libgmp \ # lstat \ # manywarnings \ # memmem-simple \ @@ -245,14 +246,14 @@ GL_GENERATE_ALLOCA_H = @GL_GENERATE_ALLOCA_H@ GL_GENERATE_BYTESWAP_H = @GL_GENERATE_BYTESWAP_H@ GL_GENERATE_ERRNO_H = @GL_GENERATE_ERRNO_H@ GL_GENERATE_EXECINFO_H = @GL_GENERATE_EXECINFO_H@ +GL_GENERATE_GMP_H = @GL_GENERATE_GMP_H@ GL_GENERATE_IEEE754_H = @GL_GENERATE_IEEE754_H@ GL_GENERATE_LIMITS_H = @GL_GENERATE_LIMITS_H@ GL_GENERATE_STDALIGN_H = @GL_GENERATE_STDALIGN_H@ GL_GENERATE_STDDEF_H = @GL_GENERATE_STDDEF_H@ GL_GENERATE_STDINT_H = @GL_GENERATE_STDINT_H@ GMALLOC_OBJ = @GMALLOC_OBJ@ -GMP_LIB = @GMP_LIB@ -GMP_OBJ = @GMP_OBJ@ +GMP_H = @GMP_H@ GNULIB_ACCESS = @GNULIB_ACCESS@ GNULIB_ALPHASORT = @GNULIB_ALPHASORT@ GNULIB_ATOLL = @GNULIB_ATOLL@ @@ -325,6 +326,7 @@ GNULIB_GETPASS = @GNULIB_GETPASS@ GNULIB_GETRANDOM = @GNULIB_GETRANDOM@ GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ +GNULIB_GETUMASK = @GNULIB_GETUMASK@ GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@ GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@ GNULIB_GRANTPT = @GNULIB_GRANTPT@ @@ -548,7 +550,6 @@ HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@ HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ HAVE_DIRENT_H = @HAVE_DIRENT_H@ HAVE_DPRINTF = @HAVE_DPRINTF@ -HAVE_DUP2 = @HAVE_DUP2@ HAVE_DUP3 = @HAVE_DUP3@ HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@ @@ -578,6 +579,7 @@ HAVE_GETPASS = @HAVE_GETPASS@ HAVE_GETRANDOM = @HAVE_GETRANDOM@ HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ +HAVE_GETUMASK = @HAVE_GETUMASK@ HAVE_GRANTPT = @HAVE_GRANTPT@ HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@ HAVE_IMAXDIV_T = @HAVE_IMAXDIV_T@ @@ -592,7 +594,6 @@ HAVE_MAKEINFO = @HAVE_MAKEINFO@ HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@ HAVE_MBSLEN = @HAVE_MBSLEN@ HAVE_MBTOWC = @HAVE_MBTOWC@ -HAVE_MEMCHR = @HAVE_MEMCHR@ HAVE_MEMPCPY = @HAVE_MEMPCPY@ HAVE_MKDIRAT = @HAVE_MKDIRAT@ HAVE_MKDTEMP = @HAVE_MKDTEMP@ @@ -760,6 +761,7 @@ LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ LIB_EACCESS = @LIB_EACCESS@ LIB_EXECINFO = @LIB_EXECINFO@ LIB_GETRANDOM = @LIB_GETRANDOM@ +LIB_GMP = @LIB_GMP@ LIB_MATH = @LIB_MATH@ LIB_PTHREAD = @LIB_PTHREAD@ LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ @@ -1132,7 +1134,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -2015,6 +2016,29 @@ EXTRA_DIST += cdefs.h libc-config.h endif ## end gnulib module libc-config +## begin gnulib module libgmp +ifeq (,$(OMIT_GNULIB_MODULE_libgmp)) + +BUILT_SOURCES += $(GMP_H) + +# Build gmp.h as a wrapper for mini-gmp.h when using mini-gmp. +ifneq (,$(GL_GENERATE_GMP_H)) +gmp.h: $(top_builddir)/config.status + echo '#include "mini-gmp.h"' >$@-t + mv $@-t $@ +else +gmp.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += gmp.h gmp.h-t + +EXTRA_DIST += mini-gmp-gnulib.c mini-gmp.c mini-gmp.h + +EXTRA_libgnu_a_SOURCES += mini-gmp-gnulib.c mini-gmp.c + +endif +## end gnulib module libgmp + ## begin gnulib module limits-h ifeq (,$(OMIT_GNULIB_MODULE_limits-h)) @@ -2833,7 +2857,6 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ - -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ @@ -3017,6 +3040,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's/@''GNULIB_FSTAT''@/$(GNULIB_FSTAT)/g' \ -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \ -e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \ + -e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \ -e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \ -e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \ -e 's/@''GNULIB_MKDIRAT''@/$(GNULIB_MKDIRAT)/g' \ @@ -3030,6 +3054,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \ + -e 's|@''HAVE_GETUMASK''@|$(HAVE_GETUMASK)|g' \ -e 's|@''HAVE_LCHMOD''@|$(HAVE_LCHMOD)|g' \ -e 's|@''HAVE_LSTAT''@|$(HAVE_LSTAT)|g' \ -e 's|@''HAVE_MKDIRAT''@|$(HAVE_MKDIRAT)|g' \ @@ -3338,7 +3363,6 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H < $(srcdir)/unistd.in.h | \ sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ -e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \ - -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \ -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ diff --git a/lib/mini-gmp-gnulib.c b/lib/mini-gmp-gnulib.c new file mode 100644 index 00000000000..5019be5d52a --- /dev/null +++ b/lib/mini-gmp-gnulib.c @@ -0,0 +1,37 @@ +/* Tailor mini-gmp.c for Gnulib-using applications. + + Copyright 2018-2020 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include +#include + +#include "mini-gmp.h" + +/* Pacify GCC -Wsuggest-attribute=const, malloc, pure. */ +#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic ignored "-Wsuggest-attribute=const" +# pragma GCC diagnostic ignored "-Wsuggest-attribute=malloc" +# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" +#endif + +/* Pacify GCC -Wunused-variable for variables used only in 'assert' calls. */ +#if defined NDEBUG && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +#include "mini-gmp.c" diff --git a/src/mini-gmp.c b/lib/mini-gmp.c similarity index 97% rename from src/mini-gmp.c rename to lib/mini-gmp.c index 2e789a2dfcc..2e0301b0081 100644 --- a/src/mini-gmp.c +++ b/lib/mini-gmp.c @@ -2,21 +2,21 @@ Contributed to the GNU project by Niels Möller -Copyright 1991-1997, 1999-2019 Free Software Foundation, Inc. +Copyright 1991-1997, 1999-2020 Free Software Foundation, Inc. This file is part of the GNU MP Library. The GNU MP Library is free software; you can redistribute it and/or modify it under the terms of either: - * the GNU Lesser General Public License as published by the Free + * the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any + Foundation; either version 3 of the License, or (at your option) any later version. or both in parallel, as here. @@ -27,7 +27,7 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received copies of the GNU General Public License and the -GNU Lesser General Public License along with the GNU MP Library. If not, +GNU General Public License along with the GNU MP Library. If not, see https://www.gnu.org/licenses/. */ /* NOTE: All functions in this file which are not declared in @@ -351,20 +351,27 @@ mp_set_memory_functions (void *(*alloc_func) (size_t), gmp_free_func = free_func; } -#define gmp_xalloc(size) ((*gmp_allocate_func)((size))) -#define gmp_free(p) ((*gmp_free_func) ((p), 0)) +#define gmp_alloc(size) ((*gmp_allocate_func)((size))) +#define gmp_free(p, size) ((*gmp_free_func) ((p), (size))) +#define gmp_realloc(ptr, old_size, size) ((*gmp_reallocate_func)(ptr, old_size, size)) static mp_ptr -gmp_xalloc_limbs (mp_size_t size) +gmp_alloc_limbs (mp_size_t size) { - return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t)); + return (mp_ptr) gmp_alloc (size * sizeof (mp_limb_t)); } static mp_ptr -gmp_xrealloc_limbs (mp_ptr old, mp_size_t size) +gmp_realloc_limbs (mp_ptr old, mp_size_t old_size, mp_size_t size) { assert (size > 0); - return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t)); + return (mp_ptr) gmp_realloc (old, old_size * sizeof (mp_limb_t), size * sizeof (mp_limb_t)); +} + +static void +gmp_free_limbs (mp_ptr old, mp_size_t size) +{ + gmp_free (old, size * sizeof (mp_limb_t)); } @@ -956,11 +963,17 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d, di; mp_limb_t r; mp_ptr tp = NULL; + mp_size_t tn = 0; if (inv->shift > 0) { /* Shift, reusing qp area if possible. In-place shift if qp == np. */ - tp = qp ? qp : gmp_xalloc_limbs (nn); + tp = qp; + if (!tp) + { + tn = nn; + tp = gmp_alloc_limbs (tn); + } r = mpn_lshift (tp, np, nn, inv->shift); np = tp; } @@ -977,8 +990,8 @@ mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn, if (qp) qp[nn] = q; } - if ((inv->shift > 0) && (tp != qp)) - gmp_free (tp); + if (tn) + gmp_free_limbs (tp, tn); return r >> inv->shift; } @@ -1136,13 +1149,13 @@ mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn) mpn_div_qr_invert (&inv, dp, dn); if (dn > 2 && inv.shift > 0) { - tp = gmp_xalloc_limbs (dn); + tp = gmp_alloc_limbs (dn); gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift)); dp = tp; } mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv); if (tp) - gmp_free (tp); + gmp_free_limbs (tp, dn); } @@ -1428,14 +1441,14 @@ mpz_init2 (mpz_t r, mp_bitcnt_t bits) r->_mp_alloc = rn; r->_mp_size = 0; - r->_mp_d = gmp_xalloc_limbs (rn); + r->_mp_d = gmp_alloc_limbs (rn); } void mpz_clear (mpz_t r) { if (r->_mp_alloc) - gmp_free (r->_mp_d); + gmp_free_limbs (r->_mp_d, r->_mp_alloc); } static mp_ptr @@ -1444,9 +1457,9 @@ mpz_realloc (mpz_t r, mp_size_t size) size = GMP_MAX (size, 1); if (r->_mp_alloc) - r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size); + r->_mp_d = gmp_realloc_limbs (r->_mp_d, r->_mp_alloc, size); else - r->_mp_d = gmp_xalloc_limbs (size); + r->_mp_d = gmp_alloc_limbs (size); r->_mp_alloc = size; if (GMP_ABS (r->_mp_size) > size) @@ -1541,8 +1554,7 @@ mpz_init_set (mpz_t r, const mpz_t x) int mpz_fits_slong_p (const mpz_t u) { - return (LONG_MAX + LONG_MIN == 0 || mpz_cmp_ui (u, LONG_MAX) <= 0) && - mpz_cmpabs_ui (u, GMP_NEG_CAST (unsigned long int, LONG_MIN)) <= 0; + return mpz_cmp_si (u, LONG_MAX) <= 0 && mpz_cmp_si (u, LONG_MIN) >= 0; } static int @@ -1565,6 +1577,30 @@ mpz_fits_ulong_p (const mpz_t u) return us >= 0 && mpn_absfits_ulong_p (u->_mp_d, us); } +int +mpz_fits_sint_p (const mpz_t u) +{ + return mpz_cmp_si (u, INT_MAX) <= 0 && mpz_cmp_si (u, INT_MIN) >= 0; +} + +int +mpz_fits_uint_p (const mpz_t u) +{ + return u->_mp_size >= 0 && mpz_cmpabs_ui (u, UINT_MAX) <= 0; +} + +int +mpz_fits_sshort_p (const mpz_t u) +{ + return mpz_cmp_si (u, SHRT_MAX) <= 0 && mpz_cmp_si (u, SHRT_MIN) >= 0; +} + +int +mpz_fits_ushort_p (const mpz_t u) +{ + return u->_mp_size >= 0 && mpz_cmpabs_ui (u, USHRT_MAX) <= 0; +} + long int mpz_get_si (const mpz_t u) { @@ -3073,7 +3109,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) one, using a *normalized* m. */ minv.shift = 0; - tp = gmp_xalloc_limbs (mn); + tp = gmp_alloc_limbs (mn); gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift)); mp = tp; } @@ -3139,7 +3175,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn); } if (tp) - gmp_free (tp); + gmp_free_limbs (tp, mn); mpz_swap (r, tr); mpz_clear (tr); @@ -3350,13 +3386,15 @@ gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b) gmp_ctz(c, a); a >>= 1; - do + for (;;) { a >>= c; /* (2/b) = -1 if b = 3 or 5 mod 8 */ bit ^= c & (b ^ (b >> 1)); if (a < b) { + if (a == 0) + return bit & 1 ? -1 : 1; bit ^= a & b; a = b - a; b -= a; @@ -3370,9 +3408,6 @@ gmp_jacobi_coprime (mp_limb_t a, mp_limb_t b) gmp_ctz(c, a); ++c; } - while (b > 0); - - return bit & 1 ? -1 : 1; } static void @@ -4144,7 +4179,7 @@ mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit) size_t mpz_sizeinbase (const mpz_t u, int base) { - mp_size_t un; + mp_size_t un, tn; mp_srcptr up; mp_ptr tp; mp_bitcnt_t bits; @@ -4177,20 +4212,21 @@ mpz_sizeinbase (const mpz_t u, int base) 10. */ } - tp = gmp_xalloc_limbs (un); + tp = gmp_alloc_limbs (un); mpn_copyi (tp, up, un); mpn_div_qr_1_invert (&bi, base); + tn = un; ndigits = 0; do { ndigits++; - mpn_div_qr_1_preinv (tp, tp, un, &bi); - un -= (tp[un-1] == 0); + mpn_div_qr_1_preinv (tp, tp, tn, &bi); + tn -= (tp[tn-1] == 0); } - while (un > 0); + while (tn > 0); - gmp_free (tp); + gmp_free_limbs (tp, un); return ndigits; } @@ -4200,7 +4236,7 @@ mpz_get_str (char *sp, int base, const mpz_t u) unsigned bits; const char *digits; mp_size_t un; - size_t i, sn; + size_t i, sn, osn; digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; if (base > 1) @@ -4221,15 +4257,19 @@ mpz_get_str (char *sp, int base, const mpz_t u) sn = 1 + mpz_sizeinbase (u, base); if (!sp) - sp = (char *) gmp_xalloc (1 + sn); - + { + osn = 1 + sn; + sp = (char *) gmp_alloc (osn); + } + else + osn = 0; un = GMP_ABS (u->_mp_size); if (un == 0) { sp[0] = '0'; - sp[1] = '\0'; - return sp; + sn = 1; + goto ret; } i = 0; @@ -4248,17 +4288,20 @@ mpz_get_str (char *sp, int base, const mpz_t u) mp_ptr tp; mpn_get_base_info (&info, base); - tp = gmp_xalloc_limbs (un); + tp = gmp_alloc_limbs (un); mpn_copyi (tp, u->_mp_d, un); sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un); - gmp_free (tp); + gmp_free_limbs (tp, un); } for (; i < sn; i++) sp[i] = digits[(unsigned char) sp[i]]; +ret: sp[sn] = '\0'; + if (osn && osn != sn + 1) + sp = gmp_realloc(sp, osn, sn + 1); return sp; } @@ -4268,7 +4311,7 @@ mpz_set_str (mpz_t r, const char *sp, int base) unsigned bits, value_of_a; mp_size_t rn, alloc; mp_ptr rp; - size_t dn; + size_t dn, sn; int sign; unsigned char *dp; @@ -4306,7 +4349,8 @@ mpz_set_str (mpz_t r, const char *sp, int base) r->_mp_size = 0; return -1; } - dp = (unsigned char *) gmp_xalloc (strlen (sp)); + sn = strlen(sp); + dp = (unsigned char *) gmp_alloc (sn); value_of_a = (base > 36) ? 36 : 10; for (dn = 0; *sp; sp++) @@ -4326,7 +4370,7 @@ mpz_set_str (mpz_t r, const char *sp, int base) if (digit >= (unsigned) base) { - gmp_free (dp); + gmp_free (dp, sn); r->_mp_size = 0; return -1; } @@ -4336,7 +4380,7 @@ mpz_set_str (mpz_t r, const char *sp, int base) if (!dn) { - gmp_free (dp); + gmp_free (dp, sn); r->_mp_size = 0; return -1; } @@ -4360,7 +4404,7 @@ mpz_set_str (mpz_t r, const char *sp, int base) rn -= rp[rn-1] == 0; } assert (rn <= alloc); - gmp_free (dp); + gmp_free (dp, sn); r->_mp_size = sign ? - rn : rn; @@ -4378,13 +4422,13 @@ size_t mpz_out_str (FILE *stream, int base, const mpz_t x) { char *str; - size_t len; + size_t len, n; str = mpz_get_str (NULL, base, x); len = strlen (str); - len = fwrite (str, 1, len, stream); - gmp_free (str); - return len; + n = fwrite (str, 1, len, stream); + gmp_free (str, len + 1); + return n; } @@ -4512,7 +4556,7 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian, count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; if (!r) - r = gmp_xalloc (count * size); + r = gmp_alloc (count * size); if (endian == 0) endian = gmp_detect_endian (); diff --git a/src/mini-gmp.h b/lib/mini-gmp.h similarity index 97% rename from src/mini-gmp.h rename to lib/mini-gmp.h index 7cce3f7a328..c00568c2568 100644 --- a/src/mini-gmp.h +++ b/lib/mini-gmp.h @@ -7,14 +7,14 @@ This file is part of the GNU MP Library. The GNU MP Library is free software; you can redistribute it and/or modify it under the terms of either: - * the GNU Lesser General Public License as published by the Free + * the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any + Foundation; either version 3 of the License, or (at your option) any later version. or both in parallel, as here. @@ -25,7 +25,7 @@ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received copies of the GNU General Public License and the -GNU Lesser General Public License along with the GNU MP Library. If not, +GNU General Public License along with the GNU MP Library. If not, see https://www.gnu.org/licenses/. */ /* About mini-gmp: This is a minimal implementation of a subset of the @@ -244,6 +244,10 @@ mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t); int mpz_fits_slong_p (const mpz_t); int mpz_fits_ulong_p (const mpz_t); +int mpz_fits_sint_p (const mpz_t); +int mpz_fits_uint_p (const mpz_t); +int mpz_fits_sshort_p (const mpz_t); +int mpz_fits_ushort_p (const mpz_t); long int mpz_get_si (const mpz_t); unsigned long int mpz_get_ui (const mpz_t); double mpz_get_d (const mpz_t); diff --git a/lib/string.in.h b/lib/string.in.h index a08e7057fbd..aa9802791ee 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -134,11 +134,6 @@ _GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); # else -# if ! @HAVE_MEMCHR@ -_GL_FUNCDECL_SYS (memchr, void *, (void const *__s, int __c, size_t __n) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif /* On some systems, this function is defined as an overloaded function: extern "C" { const void * std::memchr (const void *, int, size_t); } extern "C++" { void * std::memchr (void *, int, size_t); } */ diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index 44946072795..89e167f6d1c 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -515,6 +515,23 @@ _GL_WARN_ON_USE (futimens, "futimens is not portable - " #endif +#if @GNULIB_GETUMASK@ +# if !@HAVE_GETUMASK@ +_GL_FUNCDECL_SYS (getumask, mode_t, (void)); +# endif +_GL_CXXALIAS_SYS (getumask, mode_t, (void)); +# if @HAVE_GETUMASK@ +_GL_CXXALIASWARN (getumask); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getumask +# if HAVE_RAW_DECL_GETUMASK +_GL_WARN_ON_USE (getumask, "getumask is not portable - " + "use gnulib module getumask for portability"); +# endif +#endif + + #if @GNULIB_LCHMOD@ /* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME denotes a symbolic link. */ diff --git a/lib/unistd.in.h b/lib/unistd.in.h index b211e4d61f7..a81a14fe873 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -408,9 +408,6 @@ _GL_WARN_ON_USE (dup, "dup is unportable - " _GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd)); _GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); # else -# if !@HAVE_DUP2@ -_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd)); -# endif _GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd)); # endif _GL_CXXALIASWARN (dup2); diff --git a/lisp/autorevert.el b/lisp/autorevert.el index e023c8fc7a6..6e08176f5ff 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -545,7 +545,7 @@ specifies in the mode line." ;; we wouldn't know when to revert it otherwise. (not (eq buffer-stale-function #'buffer-stale--default-function)))) - (not (memq 'major-mode global-auto-revert-ignore-modes)) + (not (memq major-mode global-auto-revert-ignore-modes)) (or (null global-auto-revert-ignore-buffer) (if (functionp global-auto-revert-ignore-buffer) (not (funcall global-auto-revert-ignore-buffer diff --git a/lisp/descr-text.el b/lisp/descr-text.el index 776ce7618d5..4de1a7b7005 100644 --- a/lisp/descr-text.el +++ b/lisp/descr-text.el @@ -763,6 +763,8 @@ The character information includes: (to (nth 4 composition)) glyph) (if (fontp font) + ;; GUI frame: show composition in terms of + ;; font glyphs and characters. (progn (insert " using this font:\n " (symbol-name (font-get font :type)) @@ -772,12 +774,22 @@ The character information includes: (while (and (<= from to) (setq glyph (lgstring-glyph gstring from))) (insert (format " %S\n" glyph)) - (setq from (1+ from)))) + (setq from (1+ from))) + (insert "from these character(s):\n") + (dotimes (i (lgstring-char-len gstring)) + (let ((char (lgstring-char gstring i))) + (insert (format " %c (#x%x) %s\n" + char char + (get-char-code-property + char 'name)))))) + ;; TTY frame: show composition in terms of characters. (insert " by these characters:\n") (while (and (<= from to) (setq glyph (lgstring-glyph gstring from))) - (insert (format " %c (#x%x)\n" - (lglyph-char glyph) (lglyph-char glyph))) + (insert (format " %c (#x%x) %s\n" + (lglyph-char glyph) (lglyph-char glyph) + (get-char-code-property + (lglyph-char glyph) 'name))) (setq from (1+ from))))) (insert " by the rule:\n\t(") (let ((first t)) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index 9efd770dca6..1dd0ea2942d 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -5,7 +5,7 @@ ;; Author: Noah Friedman ;; Keywords: extensions ;; Created: 1995-10-06 -;; Version: 1.1.0 +;; Version: 1.5.0 ;; Package-Requires: ((emacs "26.3")) ;; This is a GNU ELPA :core package. Avoid functionality that is not @@ -372,7 +372,7 @@ about the context around point. - If that decision can be taken quickly, the hook function may call CALLBACK immediately following the protocol described - berlow. Alternatively it may ignore CALLBACK entirely and + below. Alternatively it may ignore CALLBACK entirely and return either the doc string, or nil if there's no doc appropriate for the context. @@ -459,42 +459,46 @@ Honor most of `eldoc-echo-area-use-multiline-p'." ;; top-section of the `*eldoc' buffer. I'm pretty sure nicer ;; strategies can be used here, probably by splitting this ;; function into some `eldoc-display-functions' special hook. - (if (and (eq 'truncate-sym-name-if-fit eldoc-echo-area-use-multiline-p) - (null (cdr docs)) - (setq single-sym-name - (format "%s" (plist-get (cdar docs) :thing))) - (> (+ (length (caar docs)) (length single-sym-name) 2) width)) - (eldoc--message (caar docs)) - (with-current-buffer (eldoc-doc-buffer) - (goto-char (point-min)) - (cond - ;; Potentially truncate a long message into less lines, - ;; then display it in the echo area; - ((> available 1) - (cl-loop - initially (goto-char (line-end-position (1+ available))) - for truncated = nil then t - for needed - = (let ((truncate-lines message-truncate-lines)) - (count-screen-lines (point-min) (point) t (minibuffer-window))) - while (> needed (if truncated (1- available) available)) - do (goto-char (line-end-position (if truncated 0 -1))) - (while (bolp) (goto-char (line-end-position 0))) - finally - (unless (and truncated - eldoc-prefer-doc-buffer - (get-buffer-window eldoc--doc-buffer)) - (eldoc--message - (concat (buffer-substring (point-min) (point)) - (and truncated - (format - "\n(Documentation truncated. Use `%s' to see rest)" - (substitute-command-keys "\\[eldoc-doc-buffer]")))))))) - ((= available 1) - ;; Truncate "brutally." ; FIXME: use `eldoc-prefer-doc-buffer' too? - (eldoc--message - (truncate-string-to-width - (buffer-substring (point-min) (line-end-position 1)) width))))))))) + (let ((echo-area-message + (cond + ((and + (eq 'truncate-sym-name-if-fit eldoc-echo-area-use-multiline-p) + (null (cdr docs)) + (setq single-sym-name + (format "%s" (plist-get (cdar docs) :thing))) + (> (+ (length (caar docs)) (length single-sym-name) 2) width)) + (caar docs)) + ((> available 1) + (with-current-buffer (eldoc-doc-buffer) + (cl-loop + initially + (goto-char (point-min)) + (goto-char (line-end-position (1+ available))) + for truncated = nil then t + for needed + = (let ((truncate-lines message-truncate-lines)) + (count-screen-lines (point-min) (point) t + (minibuffer-window))) + while (> needed (if truncated (1- available) available)) + do (goto-char (line-end-position (if truncated 0 -1))) + (while (and (not (bobp)) (bolp)) (goto-char (line-end-position 0))) + finally + (unless (and truncated + eldoc-prefer-doc-buffer + (get-buffer-window eldoc--doc-buffer)) + (cl-return + (concat + (buffer-substring (point-min) (point)) + (and truncated + (format + "\n(Documentation truncated. Use `%s' to see rest)" + (substitute-command-keys "\\[eldoc-doc-buffer]"))))))))) + ((= available 1) + ;; Truncate "brutally." ; FIXME: use `eldoc-prefer-doc-buffer' too? + (truncate-string-to-width + (buffer-substring (point-min) (line-end-position 1)) width))))) + (when echo-area-message + (eldoc--message echo-area-message)))))) (defun eldoc-documentation-default () "Show first doc string for item at point. @@ -535,10 +539,27 @@ Meant as a value for `eldoc-documentation-strategy'." (if (stringp str) (funcall callback str)) nil)))) -(define-obsolete-variable-alias 'eldoc-documentation-function - 'eldoc-documentation-strategy "eldoc-1.1.0") +;; JT@2020-07-10: Eldoc is pre-loaded, so in in Emacs < 28 we can't +;; make the "old" `eldoc-documentation-function' point to the new +;; `eldoc-documentation-strategy', so we do the reverse. This allows +;; for Eldoc to be loaded in those older Emacs versions and work with +;; whomever (major-modes, extensions, ueser) sets one of the other +;; variable. +(defmacro eldoc--documentation-strategy-defcustom + (main secondary value docstring &rest more) + "Defcustom helper macro for sorting `eldoc-documentation-strategy'." + (declare (indent 2)) + `(if (< emacs-major-version 28) + (progn + (defcustom ,secondary ,value ,docstring ,@more) + (define-obsolete-variable-alias ',main ',secondary "eldoc-1.1.0")) + (progn + (defcustom ,main ,value ,docstring ,@more) + (defvaralias ',secondary ',main ,docstring)))) -(defcustom eldoc-documentation-strategy #'eldoc-documentation-default +(eldoc--documentation-strategy-defcustom eldoc-documentation-strategy + eldoc-documentation-function + #'eldoc-documentation-default "How to collect and organize results of `eldoc-documentation-functions'. This variable controls how `eldoc-documentation-functions', which @@ -712,19 +733,22 @@ endeavour to display the docstrings given to them." (;; New protocol: trust callback will be called; t)))))) -(defun eldoc-print-current-symbol-info () +(defun eldoc-print-current-symbol-info (&optional interactive) "Document thing at point." - (interactive) - (if (not (eldoc-display-message-p)) - ;; Erase the last message if we won't display a new one. - (when eldoc-last-message - (eldoc--message nil)) - (let ((non-essential t)) - ;; Only keep looking for the info as long as the user hasn't - ;; requested our attention. This also locally disables - ;; inhibit-quit. - (while-no-input - (eldoc--invoke-strategy))))) + (interactive '(t)) + (cond (interactive + (eldoc--invoke-strategy)) + (t + (if (not (eldoc-display-message-p)) + ;; Erase the last message if we won't display a new one. + (when eldoc-last-message + (eldoc--message nil)) + (let ((non-essential t)) + ;; Only keep looking for the info as long as the user hasn't + ;; requested our attention. This also locally disables + ;; inhibit-quit. + (while-no-input + (eldoc--invoke-strategy))))))) ;; When point is in a sexp, the function args are not reprinted in the echo ;; area after every possible interactive command because some of them print diff --git a/lisp/net/eudcb-macos-contacts.el b/lisp/net/eudcb-macos-contacts.el new file mode 100644 index 00000000000..f258d5cb9fb --- /dev/null +++ b/lisp/net/eudcb-macos-contacts.el @@ -0,0 +1,118 @@ +;;; eudcb-macos-contacts.el --- EUDC - macOS Contacts backend + +;; Copyright (C) 2020 condition-alpha.com + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program 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 General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: +;; This library provides an interface to the macOS Contacts app as +;; an EUDC data source. It uses AppleScript to interface with the +;; Contacts app on localhost, so no 3rd party tools are needed. + +;;; Usage: +;; (require 'eudcb-macos-contacts) +;; (eudc-macos-contacts-set-server "localhost") + +;;; Code: + +(require 'eudc) +(require 'executable) + +;;{{{ Internal cooking + +(defvar eudc-macos-contacts-conversion-alist nil) + +;; hook ourselves into the EUDC framework +(eudc-protocol-set 'eudc-query-function + 'eudc-macos-contacts-query-internal + 'macos-contacts) +(eudc-protocol-set 'eudc-list-attributes-function + nil + 'macos-contacts) +(eudc-protocol-set 'eudc-macos-contacts-conversion-alist + nil + 'macos-contacts) +(eudc-protocol-set 'eudc-protocol-has-default-query-attributes + nil + 'macos-contacts) + +(defun eudc-macos-contacts-search-helper (str) + "Helper function to query the Contacts app via AppleScript. +Searches for all persons with a case-insensitive substring match +of STR in any of their name fields (first, middle, or last)." + (if (executable-find "osascript") + (call-process "osascript" nil t nil + "-e" + (format " +set results to {} +tell application \"Address Book\" + set pList to every person whose (name contains \"%s\") + repeat with pers in pList + repeat with emailAddr in emails of pers + set results to results & {name of pers & \":\" & value ¬ + of emailAddr & \"\n\"} + end repeat + end repeat + get results as text +end tell" str)) + (message (concat "[eudc] Error in macOS Contacts backend: " + "`osascript' executable not found. " + "Is this is a macOS 10.0 or later system?")))) + +(defun eudc-macos-contacts-query-internal (query &optional return-attrs) + "Query macOS Contacts with QUERY. +QUERY is a list of cons cells (ATTR . VALUE) where ATTRs should be valid +macOS Contacts attribute names. +RETURN-ATTRS is a list of attributes to return, defaulting to +`eudc-default-return-attributes'." + (let ((macos-contacts-buffer (get-buffer-create " *macOS Contacts*")) + result) + (with-current-buffer macos-contacts-buffer + (erase-buffer) + (dolist (term query) + (eudc-macos-contacts-search-helper (cdr term))) + (delete-duplicate-lines (point-min) (point-max)) + (goto-char (point-min)) + (while (not (eobp)) + (if (not (equal (line-beginning-position) (line-end-position))) + (let* ((args (split-string (buffer-substring + (point) (line-end-position)) + ":")) + (name (nth 0 args)) + (email (nth 1 args))) + (setq result (cons `((name . ,name) + (email . ,email)) result)))) + (forward-line)) + result))) + +;;}}} + +;;{{{ High-level interfaces (interactive functions) + +(defun eudc-macos-contacts-set-server (dummy) + "Set the EUDC server to macOS Contacts app. +The server in DUMMY is not actually used, since this backend +always and implicitly connetcs to an instance of the Contacts app +running on the local host." + (interactive) + (eudc-set-server dummy 'macos-contacts) + (message "[eudc] macOS Contacts app server selected")) + +;;}}} + +(eudc-register-protocol 'macos-contacts) + +(provide 'eudcb-macos-contacts) + +;;; eudcb-macos-contacts.el ends here diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index a7a5047ed49..25e4097a806 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -55,15 +55,27 @@ It is used for TCP/IP devices." "When this method name is used, forward all calls to Android Debug Bridge.") ;;;###tramp-autoload -(defcustom tramp-adb-prompt - "^[[:digit:]]*|?[[:alnum:]\e;[]*@?[[:alnum:]]*[^#\\$]*[#\\$][[:space:]]" +(defcustom tramp-adb-prompt "^[^#\\$]*[#\\$][[:space:]]" "Regexp used as prompt in almquist shell." :type 'regexp - :version "24.4" + :version "28.1" :group 'tramp) +(eval-and-compile + (defconst tramp-adb-ls-date-year-regexp + "[[:digit:]]\\{4\\}-[[:digit:]]\\{2\\}-[[:digit:]]\\{2\\}" + "Regexp for date year format in ls output.")) + +(eval-and-compile + (defconst tramp-adb-ls-date-time-regexp + "[[:digit:]]\\{2\\}:[[:digit:]]\\{2\\}" + "Regexp for date time format in ls output.")) + (defconst tramp-adb-ls-date-regexp - "[[:space:]][0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9][[:space:]][0-9][0-9]:[0-9][0-9][[:space:]]" + (concat + "[[:space:]]" tramp-adb-ls-date-year-regexp + "[[:space:]]" tramp-adb-ls-date-time-regexp + "[[:space:]]") "Regexp for date format in ls output.") (defconst tramp-adb-ls-toolbox-regexp @@ -73,7 +85,8 @@ It is used for TCP/IP devices." "[[:space:]]*\\([^[:space:]]+\\)" ; \2 username "[[:space:]]+\\([^[:space:]]+\\)" ; \3 group "[[:space:]]+\\([[:digit:]]+\\)" ; \4 size - "[[:space:]]+\\([-[:digit:]]+[[:space:]][:[:digit:]]+\\)" ; \5 date + "[[:space:]]+\\(" tramp-adb-ls-date-year-regexp + "[[:space:]]" tramp-adb-ls-date-time-regexp "\\)" ; \5 date "[[:space:]]\\(.*\\)$") ; \6 filename "Regexp for ls output.") @@ -215,11 +228,10 @@ ARGUMENTS to pass to the OPERATION." (goto-char (point-min)) (forward-line) (when (looking-at - (eval-when-compile - (concat "[[:space:]]*[^[:space:]]+" - "[[:space:]]+\\([[:digit:]]+\\)" - "[[:space:]]+\\([[:digit:]]+\\)" - "[[:space:]]+\\([[:digit:]]+\\)"))) + (concat "[[:space:]]*[^[:space:]]+" + "[[:space:]]+\\([[:digit:]]+\\)" + "[[:space:]]+\\([[:digit:]]+\\)" + "[[:space:]]+\\([[:digit:]]+\\)")) ;; The values are given as 1k numbers, so we must change ;; them to number of bytes. (list (* 1024 (string-to-number (match-string 1))) @@ -272,7 +284,9 @@ ARGUMENTS to pass to the OPERATION." (if (eq id-format 'integer) 0 uid) (if (eq id-format 'integer) 0 gid) tramp-time-dont-know ; atime - (date-to-time date) ; mtime + ;; `date-to-time' checks `iso8601-parse', which might fail. + (let (signal-hook-function) + (date-to-time date)) ; mtime tramp-time-dont-know ; ctime size mod-string @@ -351,21 +365,6 @@ ARGUMENTS to pass to the OPERATION." "ls --color=never") (t "ls")))) -(defun tramp-adb--gnu-switches-to-ash (switches) - "Almquist shell can't handle multiple arguments. -Convert (\"-al\") to (\"-a\" \"-l\"). Remove arguments like \"--dired\"." - (split-string - (apply #'concat - (mapcar (lambda (s) - (replace-regexp-in-string - "\\(.\\)" " -\\1" (replace-regexp-in-string "^-" "" s))) - ;; FIXME: Warning about removed switches (long and non-dash). - (delq nil - (mapcar - (lambda (s) - (and (not (string-match-p "\\(^--\\|^[^-]\\)" s)) s)) - switches)))))) - (defun tramp-adb-sh-fix-ls-output (&optional sort-by-time) "Insert dummy 0 in empty size columns. Android's \"ls\" command doesn't insert size column for directories: @@ -375,10 +374,16 @@ Emacs dired can't find files." (goto-char (point-min)) (while (search-forward-regexp - "[[:space:]]\\([[:space:]][0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9][[:space:]]\\)" nil t) + (eval-when-compile + (concat + "[[:space:]]" + "\\([[:space:]]" tramp-adb-ls-date-year-regexp "[[:space:]]\\)")) + nil t) (replace-match "0\\1" "\\1" nil) ;; Insert missing "/". - (when (looking-at-p "[0-9][0-9]:[0-9][0-9][[:space:]]+$") + (when (looking-at-p + (eval-when-compile + (concat tramp-adb-ls-date-time-regexp "[[:space:]]+$"))) (end-of-line) (insert "/"))) ;; Sort entries. @@ -489,9 +494,10 @@ Emacs dired can't find files." (with-tramp-progress-reporter v 3 (format "Fetching %s to tmp file %s" filename tmpfile) ;; "adb pull ..." does not always return an error code. - (when (or (tramp-adb-execute-adb-command - v "pull" (tramp-compat-file-name-unquote localname) tmpfile) - (not (file-exists-p tmpfile))) + (unless + (and (tramp-adb-execute-adb-command + v "pull" (tramp-compat-file-name-unquote localname) tmpfile) + (file-exists-p tmpfile)) (ignore-errors (delete-file tmpfile)) (tramp-error v 'file-error "Cannot make local copy of file `%s'" filename)) @@ -544,8 +550,8 @@ But handle the case, if the \"test\" command is not available." v 3 (format-message "Moving tmp file `%s' to `%s'" tmpfile filename) (unwind-protect - (when (tramp-adb-execute-adb-command - v "push" tmpfile (tramp-compat-file-name-unquote localname)) + (unless (tramp-adb-execute-adb-command + v "push" tmpfile (tramp-compat-file-name-unquote localname)) (tramp-error v 'file-error "Cannot write: `%s'" filename)) (delete-file tmpfile))) @@ -577,7 +583,7 @@ But handle the case, if the \"test\" command is not available." (unless (and (eq flag 'nofollow) (file-symlink-p filename)) (tramp-flush-file-properties v localname) (tramp-adb-send-command-and-check - v (format "chmod %o %s" mode localname))))) + v (format "chmod %o %s" mode (tramp-shell-quote-argument localname)))))) (defun tramp-adb-handle-set-file-times (filename &optional time flag) "Like `set-file-times' for Tramp files." @@ -595,15 +601,16 @@ But handle the case, if the \"test\" command is not available." ;; fails. Also, fall back on old POSIX 'touch -t' if 'touch -d' ;; (introduced in POSIX.1-2008) fails. (tramp-adb-send-command-and-check - v (format (concat "touch -d %s %s %s 2>/dev/null || " - "touch -d %s %s %s 2>/dev/null || " - "touch -t %s %s %s") - (format-time-string "%Y-%m-%dT%H:%M:%S.%NZ" time t) - nofollow quoted-name - (format-time-string "%Y-%m-%dT%H:%M:%S" time t) - nofollow quoted-name - (format-time-string "%Y%m%d%H%M.%S" time t) - nofollow quoted-name))))) + v (format + (concat "touch -d %s %s %s 2>/dev/null || " + "touch -d %s %s %s 2>/dev/null || " + "touch -t %s %s %s") + (format-time-string "%Y-%m-%dT%H:%M:%S.%NZ" time t) + nofollow quoted-name + (format-time-string "%Y-%m-%dT%H:%M:%S" time t) + nofollow quoted-name + (format-time-string "%Y%m%d%H%M.%S" time t) + nofollow quoted-name))))) (defun tramp-adb-handle-copy-file (filename newname &optional ok-if-already-exists keep-date @@ -670,10 +677,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." ;; because `file-attributes' reads the values from ;; there. (tramp-flush-file-properties v localname) - (when (tramp-adb-execute-adb-command - v "push" - (tramp-compat-file-name-unquote filename) - (tramp-compat-file-name-unquote localname)) + (unless (tramp-adb-execute-adb-command + v "push" + (tramp-compat-file-name-unquote filename) + (tramp-compat-file-name-unquote localname)) (tramp-error v 'file-error "Cannot copy `%s' `%s'" filename newname)))))))) @@ -1039,10 +1046,10 @@ E.g. a host name \"192.168.1.1#5555\" returns \"192.168.1.1:5555\" ;; Try to connect device. ((and tramp-adb-connect-if-not-connected (not (zerop (length host))) - (not (tramp-adb-execute-adb-command - vec "connect" - (replace-regexp-in-string - tramp-prefix-port-format ":" host)))) + (tramp-adb-execute-adb-command + vec "connect" + (replace-regexp-in-string + tramp-prefix-port-format ":" host))) ;; When new device connected, running other adb command (e.g. ;; adb shell) immediately will fail. To get around this ;; problem, add sleep 0.1 second here. @@ -1052,18 +1059,18 @@ E.g. a host name \"192.168.1.1#5555\" returns \"192.168.1.1:5555\" vec 'file-error "Could not find device %s" host))))))) (defun tramp-adb-execute-adb-command (vec &rest args) - "Return nil on success error-output on failure." + "Execute an adb command. +Insert the result into the connection buffer. Return nil on +error and non-nil on success." (when (and (> (length (tramp-file-name-host vec)) 0) ;; The -s switch is only available for ADB device commands. (not (member (car args) '("connect" "disconnect")))) (setq args (append (list "-s" (tramp-adb-get-device vec)) args))) - (with-temp-buffer - (prog1 - (unless - (zerop - (apply #'tramp-call-process vec tramp-adb-program nil t nil args)) - (buffer-string)) - (tramp-message vec 6 "%s" (buffer-string))))) + (with-current-buffer (tramp-get-connection-buffer vec) + ;; Clean up the buffer. We cannot call `erase-buffer' because + ;; narrowing might be in effect. + (let ((inhibit-read-only t)) (delete-region (point-min) (point-max))) + (zerop (apply #'tramp-call-process vec tramp-adb-program nil t nil args)))) (defun tramp-adb-find-test-command (vec) "Check whether the ash has a builtin \"test\" command. @@ -1075,25 +1082,30 @@ This happens for Android >= 4.0." (defun tramp-adb-send-command (vec command &optional neveropen nooutput) "Send the COMMAND to connection VEC." - (unless neveropen (tramp-adb-maybe-open-connection vec)) - (tramp-message vec 6 "%s" command) - (tramp-send-string vec command) - (unless nooutput - ;; FIXME: Race condition. - (tramp-adb-wait-for-output (tramp-get-connection-process vec)) - (with-current-buffer (tramp-get-connection-buffer vec) - (save-excursion - (goto-char (point-min)) - ;; We can't use stty to disable echo of command. stty is said - ;; to be added to toybox 0.7.6. busybox shall have it, but this - ;; isn't used any longer for Android. - (delete-matching-lines (regexp-quote command)) - ;; When the local machine is W32, there are still trailing ^M. - ;; There must be a better solution by setting the correct coding - ;; system, but this requires changes in core Tramp. - (goto-char (point-min)) - (while (re-search-forward "\r+$" nil t) - (replace-match "" nil nil)))))) + (if (string-match-p "[[:multibyte:]]" command) + ;; Multibyte codepoints with four bytes are not supported at + ;; least by toybox. + (tramp-adb-execute-adb-command vec "shell" command) + + (unless neveropen (tramp-adb-maybe-open-connection vec)) + (tramp-message vec 6 "%s" command) + (tramp-send-string vec command) + (unless nooutput + ;; FIXME: Race condition. + (tramp-adb-wait-for-output (tramp-get-connection-process vec)) + (with-current-buffer (tramp-get-connection-buffer vec) + (save-excursion + (goto-char (point-min)) + ;; We can't use stty to disable echo of command. stty is said + ;; to be added to toybox 0.7.6. busybox shall have it, but this + ;; isn't used any longer for Android. + (delete-matching-lines (regexp-quote command)) + ;; When the local machine is W32, there are still trailing ^M. + ;; There must be a better solution by setting the correct coding + ;; system, but this requires changes in core Tramp. + (goto-char (point-min)) + (while (re-search-forward "\r+$" nil t) + (replace-match "" nil nil))))))) (defun tramp-adb-send-command-and-check (vec command &optional exit-status) "Run COMMAND and check its exit status. @@ -1108,7 +1120,7 @@ the exit status." (format "%s; echo tramp_exit_status $?" command) "echo tramp_exit_status $?")) (with-current-buffer (tramp-get-connection-buffer vec) - (unless (tramp-search-regexp "tramp_exit_status [0-9]+") + (unless (tramp-search-regexp "tramp_exit_status [[:digit:]]+") (tramp-error vec 'file-error "Couldn't find exit status of `%s'" command)) (skip-chars-forward "^ ") @@ -1217,7 +1229,11 @@ connection if a previous connection has died for some reason." ;; connection properties. We start again. (tramp-message vec 5 "Checking system information") (tramp-adb-send-command - vec "echo \\\"`getprop ro.product.model` `getprop ro.product.version` `getprop ro.build.version.release`\\\"") + vec + (concat + "echo \\\"`getprop ro.product.model` " + "`getprop ro.product.version` " + "`getprop ro.build.version.release`\\\"")) (let ((old-getprop (tramp-get-connection-property vec "getprop" nil)) (new-getprop @@ -1241,7 +1257,8 @@ connection if a previous connection has died for some reason." (tramp-adb-send-command vec (format "su %s" user)) (unless (tramp-adb-send-command-and-check vec nil) (delete-process p) - (tramp-flush-file-property vec "" "su-command-p") + ;; Do not flush, we need the nil value. + (tramp-set-file-property vec "" "su-command-p" nil) (tramp-error vec 'file-error "Cannot switch to user `%s'" user))) @@ -1275,4 +1292,9 @@ connection if a previous connection has died for some reason." (provide 'tramp-adb) +;;; TODO: +;; +;; * Support file names with multibyte codepoints. Use as fallback +;; "adb shell COMMAND". +;; ;;; tramp-adb.el ends here diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 2805f6648ce..52cc186ecf7 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -359,9 +359,8 @@ The remote connection identified by SOURCE is flushed by (or (setq target (tramp-default-rename-file source)) (tramp-user-error nil - (eval-when-compile - (concat "There is no target specified. " - "Check `tramp-default-rename-alist' for a proper entry."))))) + (concat "There is no target specified. " + "Check `tramp-default-rename-alist' for a proper entry.")))) (when (tramp-equal-remote source target) (tramp-user-error nil "Source and target must have different remote.")) @@ -566,11 +565,10 @@ buffer in your bug report. ;; Remove string quotation. (forward-line -1) (when (looking-at - (eval-when-compile - (concat "\\(^.*\\)" "\"" ;; \1 " - "\\((base64-decode-string \\)" "\\\\" ;; \2 \ - "\\(\".*\\)" "\\\\" ;; \3 \ - "\\(\")\\)" "\"$"))) ;; \4 " + (concat "\\(^.*\\)" "\"" ;; \1 " + "\\((base64-decode-string \\)" "\\\\" ;; \2 \ + "\\(\".*\\)" "\\\\" ;; \3 \ + "\\(\")\\)" "\"$")) ;; \4 " (replace-match "\\1\\2\\3\\4") (beginning-of-line) (insert " ;; Variable encoded due to non-printable characters.\n")) diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el index 95ae1569dc9..996a92454f1 100644 --- a/lisp/net/tramp-ftp.el +++ b/lisp/net/tramp-ftp.el @@ -31,8 +31,7 @@ (require 'tramp) ;; Pacify byte-compiler. -(eval-when-compile - (require 'custom)) +(eval-when-compile (require 'custom)) (defvar ange-ftp-ftp-name-arg) (defvar ange-ftp-ftp-name-res) (defvar ange-ftp-name-format) @@ -79,9 +78,9 @@ present for backward compatibility." ;;; This regexp recognizes absolute filenames with only one component ;;; on Windows, for the sake of hostname completion. (and (memq system-type '(ms-dos windows-nt)) - (or (assoc "^[a-zA-Z]:/[^/:]*\\'" file-name-handler-alist) + (or (assoc "^[[:alpha:]]:/[^/:]*\\'" file-name-handler-alist) (setq file-name-handler-alist - (cons '("^[a-zA-Z]:/[^/:]*\\'" . + (cons '("^[:alpha:]]:/[^/:]*\\'" . ange-ftp-completion-hook-function) file-name-handler-alist))))) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index dce6edd19c4..6467d8f88b4 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -108,8 +108,7 @@ (require 'url-util) ;; Pacify byte-compiler. -(eval-when-compile - (require 'custom)) +(eval-when-compile (require 'custom)) (declare-function zeroconf-init "zeroconf") (declare-function zeroconf-list-service-types "zeroconf") @@ -697,32 +696,34 @@ It has been changed in GVFS 1.14.") "List of cons cells, mapping \"gvfs-\" to \"gio \".") ;; -(defconst tramp-gvfs-file-attributes - '("name" - "type" - "standard::display-name" - "standard::symlink-target" - "standard::is-volatile" - "unix::nlink" - "unix::uid" - "owner::user" - "unix::gid" - "owner::group" - "time::access" - "time::modified" - "time::changed" - "standard::size" - "unix::mode" - "access::can-read" - "access::can-write" - "access::can-execute" - "unix::inode" - "unix::device") - "GVFS file attributes.") +(eval-and-compile + (defconst tramp-gvfs-file-attributes + '("name" + "type" + "standard::display-name" + "standard::symlink-target" + "standard::is-volatile" + "unix::nlink" + "unix::uid" + "owner::user" + "unix::gid" + "owner::group" + "time::access" + "time::modified" + "time::changed" + "standard::size" + "unix::mode" + "access::can-read" + "access::can-write" + "access::can-execute" + "unix::inode" + "unix::device") + "GVFS file attributes.")) -(defconst tramp-gvfs-file-attributes-with-gvfs-ls-regexp - (concat "[[:blank:]]" (regexp-opt tramp-gvfs-file-attributes t) "=\\(.+?\\)") - "Regexp to parse GVFS file attributes with `gvfs-ls'.") +(eval-and-compile + (defconst tramp-gvfs-file-attributes-with-gvfs-ls-regexp + (concat "[[:blank:]]" (regexp-opt tramp-gvfs-file-attributes t) "=\\(.+?\\)") + "Regexp to parse GVFS file attributes with `gvfs-ls'.")) (defconst tramp-gvfs-file-attributes-with-gvfs-info-regexp (concat "^[[:blank:]]*" @@ -864,7 +865,7 @@ pass to the OPERATION." (defun tramp-gvfs-dbus-string-to-byte-array (string) "Like `dbus-string-to-byte-array' but add trailing \\0 if needed." (dbus-string-to-byte-array - (if (string-match "^(aya{sv})" tramp-gvfs-mountlocation-signature) + (if (string-match-p "^(aya{sv})" tramp-gvfs-mountlocation-signature) (concat string (string 0)) string))) (defun tramp-gvfs-dbus-byte-array-to-string (byte-array) @@ -1181,10 +1182,11 @@ file names." (with-current-buffer (tramp-get-connection-buffer v) (goto-char (point-min)) (while (looking-at - (concat "^\\(.+\\)[[:blank:]]" - "\\([[:digit:]]+\\)[[:blank:]]" - "(\\(.+?\\))" - tramp-gvfs-file-attributes-with-gvfs-ls-regexp)) + (eval-when-compile + (concat "^\\(.+\\)[[:blank:]]" + "\\([[:digit:]]+\\)[[:blank:]]" + "(\\(.+?\\))" + tramp-gvfs-file-attributes-with-gvfs-ls-regexp))) (let ((item (list (cons "type" (match-string 3)) (cons "standard::size" (match-string 2)) (cons "name" (match-string 1))))) @@ -1285,8 +1287,7 @@ If FILE-SYSTEM is non-nil, return file system attributes." (if (eq id-format 'integer) (string-to-number (or (cdr (assoc "unix::uid" attributes)) - (eval-when-compile - (format "%s" tramp-unknown-id-integer)))) + (eval-when-compile (format "%s" tramp-unknown-id-integer)))) (or (cdr (assoc "owner::user" attributes)) (cdr (assoc "unix::uid" attributes)) tramp-unknown-id-string))) @@ -1294,8 +1295,7 @@ If FILE-SYSTEM is non-nil, return file system attributes." (if (eq id-format 'integer) (string-to-number (or (cdr (assoc "unix::gid" attributes)) - (eval-when-compile - (format "%s" tramp-unknown-id-integer)))) + (eval-when-compile (format "%s" tramp-unknown-id-integer)))) (or (cdr (assoc "owner::group" attributes)) (cdr (assoc "unix::gid" attributes)) tramp-unknown-id-string))) @@ -1475,11 +1475,11 @@ If FILE-SYSTEM is non-nil, return file system attributes." ;; File names are returned as URL paths. We must convert them. (when (string-match ddu file) (setq file (replace-match dd nil nil file))) - (while (string-match-p "%\\([0-9A-F]\\{2\\}\\)" file) + (while (string-match-p "%\\([[:xdigit:]]\\{2\\}\\)" file) (setq file (url-unhex-string file))) (when (string-match ddu (or file1 "")) (setq file1 (replace-match dd nil nil file1))) - (while (string-match-p "%\\([0-9A-F]\\{2\\}\\)" (or file1 "")) + (while (string-match-p "%\\([[:xdigit:]]\\{2\\}\\)" (or file1 "")) (setq file1 (url-unhex-string file1))) ;; Remove watch when file or directory to be watched is deleted. (when (and (member action '(moved deleted)) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 89e5dc9e658..0e55d603a3b 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -90,10 +90,10 @@ the default storage location, e.g. \"$HOME/.sh_history\"." (string :tag "Redirect to a file"))) ;;;###tramp-autoload -(defconst tramp-display-escape-sequence-regexp "\e[[;0-9]+m" +(defconst tramp-display-escape-sequence-regexp "\e[[:digit:];[]+m" "Terminal control escape sequences for display attributes.") -(defconst tramp-device-escape-sequence-regexp "\e[[0-9]+n" +(defconst tramp-device-escape-sequence-regexp "\e[[:digit:][]+n" "Terminal control escape sequences for device status.") ;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for @@ -1329,13 +1329,12 @@ component is used as the target of the symlink." (tramp-send-command-and-read vec (format - (eval-when-compile - (concat - ;; Apostrophes in the stat output are masked as - ;; `tramp-stat-marker', in order to make a proper shell escape - ;; of them in file names. - "(%s -c '((%s%%N%s) %%h %s %s %%X %%Y %%Z %%s %s%%A%s t %%i -1)' %s |" - " sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g')")) + (concat + ;; Apostrophes in the stat output are masked as + ;; `tramp-stat-marker', in order to make a proper shell escape of + ;; them in file names. + "(%s -c '((%s%%N%s) %%h %s %s %%X %%Y %%Z %%s %s%%A%s t %%i -1)' %s |" + " sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g')") (tramp-get-remote-stat vec) tramp-stat-marker tramp-stat-marker (if (eq id-format 'integer) @@ -1514,9 +1513,8 @@ ID-FORMAT valid values are `string' and `integer'." (with-parsed-tramp-file-name filename nil (with-tramp-file-property v localname "file-selinux-context" (let ((context '(nil nil nil nil)) - (regexp (eval-when-compile - (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):" - "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\)")))) + (regexp (concat "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\):" + "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\)"))) (when (and (tramp-remote-selinux-p v) (tramp-send-command-and-check v (format @@ -1766,21 +1764,19 @@ ID-FORMAT valid values are `string' and `integer'." (tramp-send-command-and-read vec (format - (eval-when-compile - (concat - ;; We must care about file names with spaces, or starting with - ;; "-"; this would confuse xargs. "ls -aQ" might be a - ;; solution, but it does not work on all remote systems. - ;; Therefore, we use \000 as file separator. - ;; `tramp-sh--quoting-style-options' do not work for file names - ;; with spaces piped to "xargs". - ;; Apostrophes in the stat output are masked as - ;; `tramp-stat-marker', in order to make a proper shell escape - ;; of them in file names. - "cd %s && echo \"(\"; (%s %s -a | tr '\\n\\r' '\\000\\000' | " - "xargs -0 %s -c " - "'(%s%%n%s (%s%%N%s) %%h %s %s %%X %%Y %%Z %%s %s%%A%s t %%i -1)' " - "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"")) + (concat + ;; We must care about file names with spaces, or starting with + ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, + ;; but it does not work on all remote systems. Therefore, we use + ;; \000 as file separator. `tramp-sh--quoting-style-options' do + ;; not work for file names with spaces piped to "xargs". + ;; Apostrophes in the stat output are masked as + ;; `tramp-stat-marker', in order to make a proper shell escape of + ;; them in file names. + "cd %s && echo \"(\"; (%s %s -a | tr '\\n\\r' '\\000\\000' | " + "xargs -0 %s -c " + "'(%s%%n%s (%s%%N%s) %%h %s %s %%X %%Y %%Z %%s %s%%A%s t %%i -1)' " + "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) ;; On systems which have no quoting style, file names with special @@ -1821,13 +1817,12 @@ ID-FORMAT valid values are `string' and `integer'." (format "tramp_perl_file_name_all_completions %s" (tramp-shell-quote-argument localname))) - (format (eval-when-compile - (concat - "(cd %s 2>&1 && %s -a 2>/dev/null" - " | while IFS= read f; do" - " if %s -d \"$f\" 2>/dev/null;" - " then \\echo \"$f/\"; else \\echo \"$f\"; fi; done" - " && \\echo ok) || \\echo fail")) + (format (concat + "(cd %s 2>&1 && %s -a 2>/dev/null" + " | while IFS= read f; do" + " if %s -d \"$f\" 2>/dev/null;" + " then \\echo \"$f/\"; else \\echo \"$f\"; fi; done" + " && \\echo ok) || \\echo fail") (tramp-shell-quote-argument localname) (tramp-get-ls-command v) (tramp-get-test-command v)))) @@ -3387,9 +3382,8 @@ STDERR can also be a file name." loc-enc tmpfile t)) (tramp-error v 'file-error - (eval-when-compile - (concat "Cannot write to `%s', " - "local encoding command `%s' failed")) + (concat "Cannot write to `%s', " + "local encoding command `%s' failed") filename loc-enc)))) ;; Send buffer into remote decoding command which @@ -3434,9 +3428,8 @@ STDERR can also be a file name." (buffer-string)))) (tramp-error v 'file-error - (eval-when-compile - (concat "Couldn't write region to `%s'," - " decode using `%s' failed")) + (concat "Couldn't write region to `%s'," + " decode using `%s' failed") filename rem-dec))))) ;; Save exit. @@ -3446,9 +3439,8 @@ STDERR can also be a file name." (t (tramp-error v 'file-error - (eval-when-compile - (concat "Method `%s' should specify both encoding and " - "decoding command or an scp program")) + (concat "Method `%s' should specify both encoding and " + "decoding command or an scp program") method)))) ;; Make `last-coding-system-used' have the right value. @@ -3648,13 +3640,11 @@ Fall back to normal file name handler if no Tramp handler exists." events (cond ((and (memq 'change flags) (memq 'attribute-change flags)) - (eval-when-compile - (concat "create,modify,move,moved_from,moved_to,move_self," - "delete,delete_self,attrib,ignored"))) + (concat "create,modify,move,moved_from,moved_to,move_self," + "delete,delete_self,attrib,ignored")) ((memq 'change flags) - (eval-when-compile - (concat "create,modify,move,moved_from,moved_to,move_self," - "delete,delete_self,ignored"))) + (concat "create,modify,move,moved_from,moved_to,move_self," + "delete,delete_self,ignored")) ((memq 'attribute-change flags) "attrib,ignored")) sequence `(,command "-mq" "-e" ,events ,localname) ;; Make events a list of symbols. @@ -3796,12 +3786,11 @@ Fall back to normal file name handler if no Tramp handler exists." "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string)) (while (string-match - (eval-when-compile - (concat "^[\n\r]*" - "Directory Monitor Event:[\n\r]+" - "Child = \\([^\n\r]+\\)[\n\r]+" - "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?" - "Event = \\([^[:blank:]]+\\)[\n\r]+")) + (concat "^[\n\r]*" + "Directory Monitor Event:[\n\r]+" + "Child = \\([^\n\r]+\\)[\n\r]+" + "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?" + "Event = \\([^[:blank:]]+\\)[\n\r]+") string) (let* ((file (match-string 1 string)) (file1 (match-string 3 string)) @@ -3837,10 +3826,9 @@ Fall back to normal file name handler if no Tramp handler exists." (dolist (line (split-string string "[\n\r]+" 'omit)) ;; Check, whether there is a problem. (unless (string-match - (eval-when-compile - (concat "^[^[:blank:]]+" - "[[:blank:]]+\\([^[:blank:]]+\\)" - "\\([[:blank:]]+\\([^\n\r]+\\)\\)?")) + (concat "^[^[:blank:]]+" + "[[:blank:]]+\\([^[:blank:]]+\\)" + "\\([[:blank:]]+\\([^\n\r]+\\)\\)?") line) (tramp-error proc 'file-notify-error "%s" line)) @@ -3876,11 +3864,10 @@ Fall back to normal file name handler if no Tramp handler exists." (goto-char (point-min)) (forward-line) (when (looking-at - (eval-when-compile - (concat "\\(?:^/[^[:space:]]*[[:space:]]\\)?" - "[[:space:]]*\\([[:digit:]]+\\)" - "[[:space:]]+\\([[:digit:]]+\\)" - "[[:space:]]+\\([[:digit:]]+\\)"))) + (concat "\\(?:^/[^[:space:]]*[[:space:]]\\)?" + "[[:space:]]*\\([[:digit:]]+\\)" + "[[:space:]]+\\([[:digit:]]+\\)" + "[[:space:]]+\\([[:digit:]]+\\)")) (mapcar (lambda (d) (* d (tramp-get-connection-property v "df-blocksize" 0))) @@ -3949,6 +3936,9 @@ hosts, or files, disagree." (tramp-shell-quote-argument v1-localname) (tramp-shell-quote-argument v2-localname)))))) +(defconst tramp-sunos-unames (regexp-opt '("SunOS 5.10" "SunOS 5.11")) + "Regexp to determine remote SunOS.") + (defun tramp-find-executable (vec progname dirlist &optional ignore-tilde ignore-path) "Search for PROGNAME in $PATH and all directories mentioned in DIRLIST. @@ -3970,7 +3960,7 @@ This function expects to be in the right *tramp* buffer." ;; therefore. (unless (or ignore-path (string-match-p - (eval-when-compile (regexp-opt '("SunOS 5.10" "SunOS 5.11"))) + tramp-sunos-unames (tramp-get-connection-property vec "uname" ""))) (tramp-send-command vec (format "which \\%s | wc -w" progname)) (goto-char (point-min)) @@ -3988,12 +3978,11 @@ This function expects to be in the right *tramp* buffer." (setq dirlist (nreverse newdl)))) (tramp-send-command vec - (format (eval-when-compile - (concat "while read d; " - "do if test -x $d/%s && test -f $d/%s; " - "then echo tramp_executable $d/%s; " - "break; fi; done <<'%s'\n" - "%s\n%s")) + (format (concat "while read d; " + "do if test -x $d/%s && test -f $d/%s; " + "then echo tramp_executable $d/%s; " + "break; fi; done <<'%s'\n" + "%s\n%s") progname progname progname tramp-end-of-heredoc (string-join dirlist "\n") @@ -4146,10 +4135,9 @@ file exists and nonzero exit status otherwise." ;; initial probes to ensure the remote shell is usable.) (tramp-send-command vec (format - (eval-when-compile - (concat - "exec env TERM='%s' INSIDE_EMACS='%s,tramp:%s' " - "ENV=%s %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s")) + (concat + "exec env TERM='%s' INSIDE_EMACS='%s,tramp:%s' " + "ENV=%s %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s") tramp-terminal-type (or (getenv "INSIDE_EMACS") emacs-version) tramp-version (or (getenv-internal "ENV" tramp-remote-process-environment) "") @@ -4199,8 +4187,7 @@ file exists and nonzero exit status otherwise." ;; and Solaris is buggy. We've got reports ;; for "SunOS 5.10" and "SunOS 5.11" so far. (string-match-p - (eval-when-compile - (regexp-opt '("SunOS 5.10" "SunOS 5.11"))) + tramp-sunos-unames (tramp-get-connection-property vec "uname" ""))) (or (tramp-find-executable @@ -4212,10 +4199,9 @@ file exists and nonzero exit status otherwise." default-shell (tramp-message vec 2 - (eval-when-compile - (concat - "Couldn't find a remote shell which groks tilde " - "expansion, using `%s'")) + (concat + "Couldn't find a remote shell which groks tilde " + "expansion, using `%s'") default-shell))) default-shell))) @@ -5223,7 +5209,7 @@ the exit status." "echo tramp_exit_status $?" (if subshell " )" ""))) (with-current-buffer (tramp-get-connection-buffer vec) - (unless (tramp-search-regexp "tramp_exit_status [0-9]+") + (unless (tramp-search-regexp "tramp_exit_status [[:digit:]]+") (tramp-error vec 'file-error "Couldn't find exit status of `%s'" command)) (skip-chars-forward "^ ") @@ -5627,8 +5613,7 @@ Nonexistent directories are removed from spec." ;; stat on Solaris is buggy. We've got reports for "SunOS 5.10" ;; and "SunOS 5.11" so far. (unless (string-match-p - (eval-when-compile (regexp-opt '("SunOS 5.10" "SunOS 5.11"))) - (tramp-get-connection-property vec "uname" "")) + tramp-sunos-unames (tramp-get-connection-property vec "uname" "")) (tramp-message vec 5 "Finding a suitable `stat' command") (let ((result (tramp-find-executable vec "stat" (tramp-get-remote-path vec))) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 947e6a767c7..1b6af2a2e33 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -875,23 +875,31 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (while (not (eobp)) (cond ((looking-at - "Size:\\s-+\\([0-9]+\\)\\s-+Blocks:\\s-+[0-9]+\\s-+\\(\\w+\\)") + (concat + "Size:\\s-+\\([[:digit:]]+\\)\\s-+" + "Blocks:\\s-+[[:digit:]]+\\s-+\\(\\w+\\)")) (setq size (string-to-number (match-string 1)) id (if (string-equal "directory" (match-string 2)) t (if (string-equal "symbolic" (match-string 2)) "")))) ((looking-at - "Inode:\\s-+\\([0-9]+\\)\\s-+Links:\\s-+\\([0-9]+\\)") + "Inode:\\s-+\\([[:digit:]]+\\)\\s-+Links:\\s-+\\([[:digit:]]+\\)") (setq inode (string-to-number (match-string 1)) link (string-to-number (match-string 2)))) ((looking-at - "Access:\\s-+([0-9]+/\\(\\S-+\\))\\s-+Uid:\\s-+\\([0-9]+\\)\\s-+Gid:\\s-+\\([0-9]+\\)") + (concat + "Access:\\s-+([[:digit:]]+/\\(\\S-+\\))\\s-+" + "Uid:\\s-+\\([[:digit:]]+\\)\\s-+" + "Gid:\\s-+\\([[:digit:]]+\\)")) (setq mode (match-string 1) uid (if (equal id-format 'string) (match-string 2) (string-to-number (match-string 2))) gid (if (equal id-format 'string) (match-string 3) (string-to-number (match-string 3))))) ((looking-at - "Access:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") + (concat + "Access:\\s-+" + "\\([[:digit:]]+\\)-\\([[:digit:]]+\\)-\\([[:digit:]]+\\)\\s-+" + "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)")) (setq atime (encode-time (string-to-number (match-string 6)) ;; sec @@ -901,7 +909,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (string-to-number (match-string 2)) ;; month (string-to-number (match-string 1))))) ;; year ((looking-at - "Modify:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") + (concat + "Modify:\\s-+" + "\\([[:digit:]]+\\)-\\([[:digit:]]+\\)-\\([[:digit:]]+\\)\\s-+" + "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)")) (setq mtime (encode-time (string-to-number (match-string 6)) ;; sec @@ -911,7 +922,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (string-to-number (match-string 2)) ;; month (string-to-number (match-string 1))))) ;; year ((looking-at - "Change:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") + (concat + "Change:\\s-+" + "\\([[:digit:]]+\\)-\\([[:digit:]]+\\)-\\([[:digit:]]+\\)\\s-+" + "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)")) (setq ctime (encode-time (string-to-number (match-string 6)) ;; sec @@ -987,10 +1001,9 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (goto-char (point-min)) (forward-line) (when (looking-at - (eval-when-compile - (concat "[[:space:]]*\\([[:digit:]]+\\)" - " blocks of size \\([[:digit:]]+\\)" - "\\. \\([[:digit:]]+\\) blocks available"))) + (concat "[[:space:]]*\\([[:digit:]]+\\)" + " blocks of size \\([[:digit:]]+\\)" + "\\. \\([[:digit:]]+\\) blocks available")) (setq blocksize (string-to-number (match-string 2)) total (* blocksize (string-to-number (match-string 1))) avail (* blocksize (string-to-number (match-string 3))))) @@ -1474,7 +1487,7 @@ component is used as the target of the symlink." ;; This is meant for traces, and returning from the ;; function. No error is propagated outside, due to ;; the `ignore-errors' closure. - (unless (tramp-search-regexp "tramp_exit_status [0-9]+") + (unless (tramp-search-regexp "tramp_exit_status [[:digit:]]+") (tramp-error v 'file-error "Couldn't find exit status of `%s'" tramp-smb-acl-program)) @@ -1719,21 +1732,21 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)." ;; Entries provided by smbclient DIR aren't fully regular. ;; They should have the format ;; -;; \s-\{2,2} - leading spaces +;; \s-\{2,2\} - leading spaces ;; \S-\(.*\S-\)\s-* - file name, 30 chars, left bound ;; \s-+[ADHRSV]* - permissions, 7 chars, right bound ;; \s- - space delimiter -;; \s-+[0-9]+ - size, 8 chars, right bound +;; \s-+[[:digit:]]+ - size, 8 chars, right bound ;; \s-\{2,2\} - space delimiter ;; \w\{3,3\} - weekday ;; \s- - space delimiter ;; \w\{3,3\} - month ;; \s- - space delimiter -;; [ 12][0-9] - day +;; [ 12][[:digit:]] - day ;; \s- - space delimiter -;; [0-9]\{2,2\}:[0-9]\{2,2\}:[0-9]\{2,2\} - time +;; [[:digit:]]\{2,2\}:[[:digit:]]\{2,2\}:[[:digit:]]\{2,2\} - time ;; \s- - space delimiter -;; [0-9]\{4,4\} - year +;; [[:digit:]]\{4,4\} - year ;; ;; samba/src/client.c (http://samba.org/doxygen/samba/client_8c-source.html) ;; has function display_finfo: @@ -1781,13 +1794,14 @@ are listed. Result is the list (LOCALNAME MODE SIZE MTIME)." (cl-block nil ;; year. - (if (string-match "\\([0-9]+\\)$" line) + (if (string-match "\\([[:digit:]]+\\)$" line) (setq year (string-to-number (match-string 1 line)) line (substring line 0 -5)) (cl-return)) ;; time. - (if (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)$" line) + (if (string-match + "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)$" line) (setq hour (string-to-number (match-string 1 line)) min (string-to-number (match-string 2 line)) sec (string-to-number (match-string 3 line)) @@ -1795,7 +1809,7 @@ are listed. Result is the list (LOCALNAME MODE SIZE MTIME)." (cl-return)) ;; day. - (if (string-match "\\([0-9]+\\)$" line) + (if (string-match "\\([[:digit:]]+\\)$" line) (setq day (string-to-number (match-string 1 line)) line (substring line 0 -3)) (cl-return)) @@ -1812,7 +1826,7 @@ are listed. Result is the list (LOCALNAME MODE SIZE MTIME)." (cl-return)) ;; size. - (if (string-match "\\([0-9]+\\)$" line) + (if (string-match "\\([[:digit:]]+\\)$" line) (let ((length (- (max 10 (1+ (length (match-string 1 line))))))) (setq size (string-to-number (match-string 1 line))) (when (string-match diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 05242ffd970..98727dc4a87 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -488,9 +488,8 @@ the result will be a local, non-Tramp, file name." (with-parsed-tramp-file-name filename nil (with-tramp-file-property v localname "file-selinux-context" (let ((context '(nil nil nil nil)) - (regexp (eval-when-compile - (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):" - "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\)")))) + (regexp (concat "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\):" + "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\)"))) (when (and (tramp-sudoedit-remote-selinux-p v) (tramp-sudoedit-send-command v "ls" "-d" "-Z" @@ -515,10 +514,9 @@ the result will be a local, non-Tramp, file name." (goto-char (point-min)) (forward-line) (when (looking-at - (eval-when-compile - (concat "[[:space:]]*\\([[:digit:]]+\\)" - "[[:space:]]+\\([[:digit:]]+\\)" - "[[:space:]]+\\([[:digit:]]+\\)"))) + (concat "[[:space:]]*\\([[:digit:]]+\\)" + "[[:space:]]+\\([[:digit:]]+\\)" + "[[:space:]]+\\([[:digit:]]+\\)")) (list (string-to-number (match-string 1)) ;; The second value is the used size. We need the ;; free size. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 1566162feaf..cd35e3f5dc1 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -560,7 +560,7 @@ Sometimes the prompt is reported to look like \"login as:\"." ;; Allow also [] style prompts. They can appear only during ;; connection initialization; Tramp redefines the prompt afterwards. (concat "\\(?:^\\|\r\\)" - "[^]#$%>\n]*#?[]#$%>] *\\(\e\\[[0-9;]*[a-zA-Z] *\\)*") + "[^]#$%>\n]*#?[]#$%>] *\\(\e\\[[[:digit:];]*[[:alpha:]] *\\)*") "Regexp to match prompts from remote shell. Normally, Tramp expects you to configure `shell-prompt-pattern' correctly, but sometimes it happens that you are connecting to a @@ -601,7 +601,7 @@ The `sudo' program appears to insert a `^@' character into the prompt." "\\|" "^.*\\(" ;; Here comes a list of regexes, separated by \\| - "Received signal [0-9]+" + "Received signal [[:digit:]]+" "\\).*") "Regexp matching a `login failed' message. The regexp should match at end of buffer." @@ -797,9 +797,9 @@ Used in `tramp-make-tramp-file-name'.") Should always start with \"^\". Derived from `tramp-prefix-format'.") (defconst tramp-method-regexp-alist - '((default . "[a-zA-Z0-9-]+") + '((default . "[[:alnum:]-]+") (simplified . "") - (separate . "[a-zA-Z0-9-]*")) + (separate . "[[:alnum:]-]*")) "Alist mapping Tramp syntax to regexps matching methods identifiers.") (defun tramp-build-method-regexp () @@ -843,7 +843,7 @@ Derived from `tramp-postfix-method-format'.") "Regexp matching delimiter between user and domain names. Derived from `tramp-prefix-domain-format'.") -(defconst tramp-domain-regexp "[a-zA-Z0-9_.-]+" +(defconst tramp-domain-regexp "[[:alnum:]_.-]+" "Regexp matching domain names.") (defconst tramp-user-with-domain-regexp @@ -860,7 +860,7 @@ Used in `tramp-make-tramp-file-name'.") "Regexp matching delimiter between user and host names. Derived from `tramp-postfix-user-format'.") -(defconst tramp-host-regexp "[a-zA-Z0-9_.%-]+" +(defconst tramp-host-regexp "[[:alnum:]_.%-]+" "Regexp matching host names.") (defconst tramp-prefix-ipv6-format-alist @@ -888,7 +888,7 @@ Derived from `tramp-prefix-ipv6-format'.") ;; The following regexp is a bit sloppy. But it shall serve our ;; purposes. It covers also IPv4 mapped IPv6 addresses, like in ;; "::ffff:192.168.0.1". -(defconst tramp-ipv6-regexp "\\(?:[a-zA-Z0-9]*:\\)+[a-zA-Z0-9.]+" +(defconst tramp-ipv6-regexp "\\(?:[[:alnum:]]*:\\)+[[:alnum:].]+" "Regexp matching IPv6 addresses.") (defconst tramp-postfix-ipv6-format-alist @@ -920,7 +920,7 @@ Derived from `tramp-postfix-ipv6-format'.") "Regexp matching delimiter between host names and port numbers. Derived from `tramp-prefix-port-format'.") -(defconst tramp-port-regexp "[0-9]+" +(defconst tramp-port-regexp "[[:digit:]]+" "Regexp matching port numbers.") (defconst tramp-host-with-port-regexp @@ -1684,11 +1684,10 @@ version, the function does nothing." (format "*debug tramp/%s %s*" method host-port)))) (defconst tramp-debug-outline-regexp - (eval-when-compile - (concat - "[0-9]+:[0-9]+:[0-9]+\\.[0-9]+ " ;; Timestamp. - "\\(?:\\(#\\) \\)?" ;; Thread. - "[a-z0-9-]+ (\\([0-9]+\\)) #")) ;; Function name, verbosity. + (concat + "[[:digit:]]+:[[:digit:]]+:[[:digit:]]+\\.[[:digit:]]+ " ;; Timestamp. + "\\(?:\\(#\\) \\)?" ;; Thread. + "[[:alnum:]-]+ (\\([[:digit:]]+\\)) #") ;; Function name, verbosity. "Used for highlighting Tramp debug buffers in `outline-mode'.") (defconst tramp-debug-font-lock-keywords @@ -2074,7 +2073,7 @@ letter into the file name. This function removes it." (save-match-data (let ((quoted (tramp-compat-file-name-quoted-p name 'top)) (result (tramp-compat-file-name-unquote name 'top))) - (setq result (if (string-match "\\`[a-zA-Z]:/" result) + (setq result (if (string-match "\\`[[:alpha:]]:/" result) (replace-match "/" nil t result) result)) (if quoted (tramp-compat-file-name-quote result 'top) result)))) @@ -2938,7 +2937,7 @@ User is always nil." "Return a list of (user host) tuples allowed to access. User is always nil." (tramp-parse-shostkeys-sknownhosts - dirname (concat "^key_[0-9]+_\\(" tramp-host-regexp "\\)\\.pub$"))) + dirname (concat "^key_[[:digit:]]+_\\(" tramp-host-regexp "\\)\\.pub$"))) (defun tramp-parse-sknownhosts (dirname) "Return a list of (user host) tuples allowed to access. @@ -3255,12 +3254,13 @@ User is always nil." (let ((candidate (tramp-compat-file-name-unquote (directory-file-name filename))) + case-fold-search tmpfile) ;; Check, whether we find an existing file with ;; lower case letters. This avoids us to create a ;; temporary file. (while (and (string-match-p - "[a-z]" (tramp-file-local-name candidate)) + "[[:lower:]]" (tramp-file-local-name candidate)) (not (file-exists-p candidate))) (setq candidate (directory-file-name @@ -3269,8 +3269,8 @@ User is always nil." ;; for comparison. `make-nearby-temp-file' is added ;; to Emacs 26+ like `file-name-case-insensitive-p', ;; so there is no compatibility problem calling it. - (unless - (string-match-p "[a-z]" (tramp-file-local-name candidate)) + (unless (string-match-p + "[[:lower:]]" (tramp-file-local-name candidate)) (setq tmpfile (let ((default-directory (file-name-directory filename))) @@ -4225,10 +4225,9 @@ performed successfully. Any other value means an error." (tramp-get-connection-buffer vec))) ((eq exit 'process-died) (substitute-command-keys - (eval-when-compile - (concat - "Tramp failed to connect. If this happens repeatedly, try\n" - " `\\[tramp-cleanup-this-connection]'")))) + (concat + "Tramp failed to connect. If this happens repeatedly, try\n" + " `\\[tramp-cleanup-this-connection]'"))) ((eq exit 'timeout) (format-message "Timeout reached, see buffer `%s' for details" diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 08798d86f8e..67ce3dc7d95 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -101,30 +101,46 @@ (defvar project-find-functions (list #'project-try-vc) "Special hook to find the project containing a given directory. Each functions on this hook is called in turn with one -argument (the directory) and should return either nil to mean -that it is not applicable, or a project instance.") +argument, the directory in which to look, and should return +either nil to mean that it is not applicable, or a project instance. +The exact form of the project instance is up to each respective +function; the only practical limitation is to use values that +`cl-defmethod' can dispatch on, like a cons cell, or a list, or a +CL struct.") (defvar project-current-inhibit-prompt nil "Non-nil to skip prompting the user in `project-current'.") ;;;###autoload -(defun project-current (&optional maybe-prompt dir) - "Return the project instance in DIR or `default-directory'. -When no project found in DIR, and MAYBE-PROMPT is non-nil, ask -the user for a different project to look in." - (unless dir (setq dir default-directory)) - (let ((pr (project--find-in-directory dir))) +(defun project-current (&optional maybe-prompt directory) + "Return the project instance in DIRECTORY, defaulting to `default-directory'. + +When no project is found in that directory, the result depends on +the value of MAYBE-PROMPT: if it is nil or omitted, return nil, +else ask the user for a directory in which to look for the +project, and if no project is found there, return a \"transient\" +project instance. + +The \"transient\" project instance is a special kind of value +which denotes a project rooted in that directory and includes all +the files under the directory except for those that should be +ignored (per `project-ignores'). + +See the doc string of `project-find-functions' for the general form +of the project instance object." + (unless directory (setq directory default-directory)) + (let ((pr (project--find-in-directory directory))) (cond (pr) ((unless project-current-inhibit-prompt maybe-prompt) - (setq dir (project-prompt-project-dir) - pr (project--find-in-directory dir)))) + (setq directory (project-prompt-project-dir) + pr (project--find-in-directory directory)))) (when maybe-prompt (if pr (project--add-to-project-list-front pr) - (project--remove-from-project-list dir) - (setq pr (cons 'transient dir)))) + (project--remove-from-project-list directory) + (setq pr (cons 'transient directory)))) pr)) (defun project--find-in-directory (dir) @@ -802,9 +818,11 @@ Arguments the same as in `compile'." ;;;###autoload (defun project-switch-to-buffer () - "Switch to another buffer that is related to the current project. -A buffer is related to a project if `project-current' returns the -same (equal) value when called in that buffer." + "Switch to another buffer belonging to the current project. +This function prompts for another buffer, offering as candidates +buffers that belong to the same project as the current buffer. +Two buffers belong to the same project if their project instances, +as reported by `project-current' in each buffer, are identical." (interactive) (let* ((pr (project-current t)) (current-buffer (current-buffer)) @@ -849,6 +867,8 @@ any of the conditions will not be killed." ;;;###autoload (defun project-kill-buffers () "Kill all live buffers belonging to the current project. +Two buffers belong to the same project if their project instances, +as reported by `project-current' in each buffer, are identical. Certain buffers may be \"spared\", see `project-kill-buffers-ignores'." (interactive) (let ((pr (project-current t)) bufs) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 165463aef59..3af55be4a19 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -34,7 +34,7 @@ ;; Implements Syntax highlighting, Indentation, Movement, Shell ;; interaction, Shell completion, Shell virtualenv support, Shell ;; package support, Shell syntax highlighting, Pdb tracking, Symbol -;; completion, Skeletons, FFAP, Code Check, Eldoc, Imenu. +;; completion, Skeletons, FFAP, Code Check, ElDoc, Imenu. ;; Syntax highlighting: Fontification of code is provided and supports ;; python's triple quoted strings properly. @@ -216,7 +216,7 @@ ;; Code check: Check the current file for errors with `python-check' ;; using the program defined in `python-check-command'. -;; Eldoc: returns documentation for object at point by using the +;; ElDoc: returns documentation for object at point by using the ;; inferior python subprocess to inspect its documentation. As you ;; might guessed you should run `python-shell-send-buffer' from time ;; to time to get better results too. @@ -4474,7 +4474,7 @@ See `python-check-command' for the default." (format python-check-buffer-name command))))) -;;; Eldoc +;;; ElDoc (defcustom python-eldoc-setup-code "def __PYDOC_get_help(obj): @@ -4591,7 +4591,7 @@ fetching." (with-timeout (python-eldoc-function-timeout (if python-eldoc-function-timeout-permanent (progn - (message "Eldoc echo-area display muted in this buffer, see `python-eldoc-function'") + (message "ElDoc echo-area display muted in this buffer, see `python-eldoc-function'") (setq python-eldoc-get-doc nil)) (message "`python-eldoc-function' timed out, see `python-eldoc-function-timeout'"))) (python-eldoc--get-doc-at-point)))) diff --git a/m4/dup2.m4 b/m4/dup2.m4 index 21b1ecc26b8..462bfd0e526 100644 --- a/m4/dup2.m4 +++ b/m4/dup2.m4 @@ -1,4 +1,4 @@ -#serial 25 +#serial 26 dnl Copyright (C) 2002, 2005, 2007, 2009-2020 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,107 +8,94 @@ AC_DEFUN([gl_FUNC_DUP2], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) AC_REQUIRE([AC_CANONICAL_HOST]) - m4_ifdef([gl_FUNC_DUP2_OBSOLETE], [ - AC_CHECK_FUNCS_ONCE([dup2]) - if test $ac_cv_func_dup2 = no; then - HAVE_DUP2=0 - fi - ], [ - AC_DEFINE([HAVE_DUP2], [1], [Define to 1 if you have the 'dup2' function.]) - ]) - if test $HAVE_DUP2 = 1; then - AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], - [AC_RUN_IFELSE([ - AC_LANG_PROGRAM( - [[#include - #include - #include - #include - #include - #ifndef RLIM_SAVED_CUR - # define RLIM_SAVED_CUR RLIM_INFINITY - #endif - #ifndef RLIM_SAVED_MAX - # define RLIM_SAVED_MAX RLIM_INFINITY - #endif - ]], - [[int result = 0; - int bad_fd = INT_MAX; - struct rlimit rlim; - if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 - && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX - && rlim.rlim_cur != RLIM_INFINITY - && rlim.rlim_cur != RLIM_SAVED_MAX - && rlim.rlim_cur != RLIM_SAVED_CUR) - bad_fd = rlim.rlim_cur; - #ifdef FD_CLOEXEC - if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1) - result |= 1; - #endif - if (dup2 (1, 1) != 1) - result |= 2; - #ifdef FD_CLOEXEC - if (fcntl (1, F_GETFD) != FD_CLOEXEC) - result |= 4; - #endif - close (0); - if (dup2 (0, 0) != -1) - result |= 8; - /* Many gnulib modules require POSIX conformance of EBADF. */ - if (dup2 (2, bad_fd) == -1 && errno != EBADF) - result |= 16; - /* Flush out some cygwin core dumps. */ - if (dup2 (2, -1) != -1 || errno != EBADF) - result |= 32; - dup2 (2, 255); - dup2 (2, 256); - /* On OS/2 kLIBC, dup2() does not work on a directory fd. */ - { - int fd = open (".", O_RDONLY); - if (fd == -1) - result |= 64; - else if (dup2 (fd, fd + 1) == -1) - result |= 128; - - close (fd); - } - return result;]]) - ], - [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no], - [case "$host_os" in - mingw*) # on this platform, dup2 always returns 0 for success - gl_cv_func_dup2_works="guessing no" ;; - cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0 - gl_cv_func_dup2_works="guessing no" ;; - aix* | freebsd*) - # on AIX 7.1 and FreeBSD 6.1, dup2 (1,toobig) gives EMFILE, - # not EBADF. - gl_cv_func_dup2_works="guessing no" ;; - haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC. - gl_cv_func_dup2_works="guessing no" ;; - *-android*) # implemented using dup3(), which fails if oldfd == newfd - gl_cv_func_dup2_works="guessing no" ;; - os2*) # on OS/2 kLIBC, dup2() does not work on a directory fd. - gl_cv_func_dup2_works="guessing no" ;; - *) gl_cv_func_dup2_works="guessing yes" ;; - esac]) - ]) - case "$gl_cv_func_dup2_works" in - *yes) ;; - *) - REPLACE_DUP2=1 - AC_CHECK_FUNCS([setdtablesize]) - ;; - esac - fi + AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM( + [[#include + #include + #include + #include + #include + #ifndef RLIM_SAVED_CUR + # define RLIM_SAVED_CUR RLIM_INFINITY + #endif + #ifndef RLIM_SAVED_MAX + # define RLIM_SAVED_MAX RLIM_INFINITY + #endif + ]], + [[int result = 0; + int bad_fd = INT_MAX; + struct rlimit rlim; + if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX + && rlim.rlim_cur != RLIM_INFINITY + && rlim.rlim_cur != RLIM_SAVED_MAX + && rlim.rlim_cur != RLIM_SAVED_CUR) + bad_fd = rlim.rlim_cur; + #ifdef FD_CLOEXEC + if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1) + result |= 1; + #endif + if (dup2 (1, 1) != 1) + result |= 2; + #ifdef FD_CLOEXEC + if (fcntl (1, F_GETFD) != FD_CLOEXEC) + result |= 4; + #endif + close (0); + if (dup2 (0, 0) != -1) + result |= 8; + /* Many gnulib modules require POSIX conformance of EBADF. */ + if (dup2 (2, bad_fd) == -1 && errno != EBADF) + result |= 16; + /* Flush out some cygwin core dumps. */ + if (dup2 (2, -1) != -1 || errno != EBADF) + result |= 32; + dup2 (2, 255); + dup2 (2, 256); + /* On OS/2 kLIBC, dup2() does not work on a directory fd. */ + { + int fd = open (".", O_RDONLY); + if (fd == -1) + result |= 64; + else if (dup2 (fd, fd + 1) == -1) + result |= 128; + close (fd); + } + return result;]]) + ], + [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no], + [case "$host_os" in + mingw*) # on this platform, dup2 always returns 0 for success + gl_cv_func_dup2_works="guessing no" ;; + cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0 + gl_cv_func_dup2_works="guessing no" ;; + aix* | freebsd*) + # on AIX 7.1 and FreeBSD 6.1, dup2 (1,toobig) gives EMFILE, + # not EBADF. + gl_cv_func_dup2_works="guessing no" ;; + haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC. + gl_cv_func_dup2_works="guessing no" ;; + *-android*) # implemented using dup3(), which fails if oldfd == newfd + gl_cv_func_dup2_works="guessing no" ;; + os2*) # on OS/2 kLIBC, dup2() does not work on a directory fd. + gl_cv_func_dup2_works="guessing no" ;; + *) gl_cv_func_dup2_works="guessing yes" ;; + esac]) + ]) + case "$gl_cv_func_dup2_works" in + *yes) ;; + *) + REPLACE_DUP2=1 + AC_CHECK_FUNCS([setdtablesize]) + ;; + esac dnl Replace dup2() for supporting the gnulib-defined fchdir() function, dnl to keep fchdir's bookkeeping up-to-date. m4_ifdef([gl_FUNC_FCHDIR], [ gl_TEST_FCHDIR if test $HAVE_FCHDIR = 0; then - if test $HAVE_DUP2 = 1; then - REPLACE_DUP2=1 - fi + REPLACE_DUP2=1 fi ]) ]) diff --git a/m4/getrandom.m4 b/m4/getrandom.m4 index 2a0034bf76c..424c2fad3e3 100644 --- a/m4/getrandom.m4 +++ b/m4/getrandom.m4 @@ -1,4 +1,4 @@ -# getrandom.m4 serial 6 +# getrandom.m4 serial 7 dnl Copyright 2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -36,7 +36,9 @@ AC_DEFUN([gl_FUNC_GETRANDOM], case "$host_os" in mingw*) - AC_CHECK_HEADERS([bcrypt.h]) + AC_CHECK_HEADERS([bcrypt.h], [], [], + [[#include + ]]) AC_CACHE_CHECK([whether the bcrypt library is guaranteed to be present], [gl_cv_lib_assume_bcrypt], [AC_COMPILE_IFELSE( diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 5c92a0768a4..f577a6fa741 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -118,6 +118,7 @@ AC_DEFUN([gl_EARLY], AC_REQUIRE([AC_SYS_LARGEFILE]) # Code from module lchmod: # Code from module libc-config: + # Code from module libgmp: # Code from module limits-h: # Code from module localtime-buffer: # Code from module lstat: @@ -240,7 +241,7 @@ AC_DEFUN([gl_INIT], gl_DIRENT_H gl_DOUBLE_SLASH_ROOT gl_FUNC_DUP2 - if test $HAVE_DUP2 = 0 || test $REPLACE_DUP2 = 1; then + if test $REPLACE_DUP2 = 1; then AC_LIBOBJ([dup2]) gl_PREREQ_DUP2 fi @@ -345,6 +346,10 @@ AC_DEFUN([gl_INIT], gl_INTTYPES_INCOMPLETE AC_REQUIRE([gl_LARGEFILE]) gl___INLINE + gl_LIBGMP + if test -n "$GMP_H"; then + AC_LIBOBJ([mini-gmp-gnulib]) + fi gl_LIMITS_H gl_FUNC_LSTAT if test $REPLACE_LSTAT = 1; then @@ -465,6 +470,7 @@ AC_DEFUN([gl_INIT], gl_SYS_TYPES_H AC_PROG_MKDIR_P gl_FUNC_GEN_TEMPNAME + gl_MODULE_INDICATOR([tempname]) gl_HEADER_TIME_H gl_TIME_R if test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1; then @@ -1034,6 +1040,9 @@ AC_DEFUN([gl_FILE_LIST], [ lib/memmem.c lib/mempcpy.c lib/memrchr.c + lib/mini-gmp-gnulib.c + lib/mini-gmp.c + lib/mini-gmp.h lib/minmax.h lib/mkostemp.c lib/mktime-internal.h @@ -1165,6 +1174,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/inttypes.m4 m4/largefile.m4 m4/lchmod.m4 + m4/libgmp.m4 m4/limits-h.m4 m4/localtime-buffer.m4 m4/lstat.m4 diff --git a/m4/lchmod.m4 b/m4/lchmod.m4 index b9e8a97cb31..a86a304f5f1 100644 --- a/m4/lchmod.m4 +++ b/m4/lchmod.m4 @@ -1,4 +1,4 @@ -#serial 7 +#serial 8 dnl Copyright (C) 2005-2006, 2008-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -26,6 +26,5 @@ AC_DEFUN([gl_FUNC_LCHMOD], # Prerequisites of lib/lchmod.c. AC_DEFUN([gl_PREREQ_LCHMOD], [ - AC_REQUIRE([AC_C_INLINE]) : ]) diff --git a/m4/libgmp.m4 b/m4/libgmp.m4 new file mode 100644 index 00000000000..b569bb73462 --- /dev/null +++ b/m4/libgmp.m4 @@ -0,0 +1,44 @@ +# Configure the GMP library or a replacement. + +dnl Copyright 2020 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. + +AC_DEFUN([gl_LIBGMP], +[ + AC_ARG_WITH([libgmp], + [AS_HELP_STRING([--without-libgmp], + [do not use the GNU Multiple Precision (GMP) library; + this is the default on systems lacking libgmp.])]) + + AC_CHECK_HEADERS_ONCE([gmp.h]) + GMP_H=gmp.h + LIB_GMP= + + case $with_libgmp in + no) ;; + yes) GMP_H= LIB_GMP=-lgmp;; + *) if test "$ac_cv_header_gmp_h" = yes; then + gl_saved_LIBS=$LIBS + AC_SEARCH_LIBS([__gmpz_roinit_n], [gmp]) + LIBS=$gl_saved_LIBS + case $ac_cv_search___gmpz_roinit_n in + 'none needed') + GMP_H=;; + -*) + GMP_H= LIB_GMP=$ac_cv_search___gmpz_roinit_n;; + esac + fi;; + esac + + if test -z "$GMP_H"; then + AC_DEFINE([HAVE_GMP], 1, + [Define to 1 if you have the GMP library instead of just the + mini-gmp replacement.]) + fi + + AC_SUBST([LIB_GMP]) + AC_SUBST([GMP_H]) + AM_CONDITIONAL([GL_GENERATE_GMP_H], [test -n "$GMP_H"]) +]) diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4 index 719bafb2909..d18da048d9e 100644 --- a/m4/manywarnings.m4 +++ b/m4/manywarnings.m4 @@ -1,4 +1,4 @@ -# manywarnings.m4 serial 19 +# manywarnings.m4 serial 20 dnl Copyright (C) 2008-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -21,7 +21,7 @@ AC_DEFUN([gl_MANYWARN_COMPLEMENT], *" $gl_warn_item "*) ;; *) - gl_warn_set="$gl_warn_set $gl_warn_item" + gl_AS_VAR_APPEND([gl_warn_set], [" $gl_warn_item"]) ;; esac done @@ -49,12 +49,12 @@ m4_defun([gl_MANYWARN_ALL_GCC(C)], AC_REQUIRE([AC_PROG_CC]) if test -n "$GCC"; then - dnl Check if -W -Werror -Wno-missing-field-initializers is supported + dnl Check if -Wextra -Werror -Wno-missing-field-initializers is supported dnl with the current $CC $CFLAGS $CPPFLAGS. AC_CACHE_CHECK([whether -Wno-missing-field-initializers is supported], [gl_cv_cc_nomfi_supported], [gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers" + CFLAGS="$CFLAGS -Wextra -Werror -Wno-missing-field-initializers" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]], [[]])], [gl_cv_cc_nomfi_supported=yes], @@ -68,7 +68,7 @@ m4_defun([gl_MANYWARN_ALL_GCC(C)], AC_CACHE_CHECK([whether -Wno-missing-field-initializers is needed], [gl_cv_cc_nomfi_needed], [gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -W -Werror" + CFLAGS="$CFLAGS -Wextra -Werror" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[int f (void) @@ -105,153 +105,41 @@ m4_defun([gl_MANYWARN_ALL_GCC(C)], # To compare this list to your installed GCC's, run this Bash command: # # comm -3 \ - # <((sed -n 's/^ *\(-[^ 0-9][^ ]*\) .*/\1/p' manywarnings.m4; \ + # <((sed -n 's/^ *\(-[^ 0-9][^ ]*\).*/\1/p' manywarnings.m4; \ # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec) | sort) \ # <(LC_ALL=C gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort) - gl_manywarn_set= - for gl_manywarn_item in -fno-common \ - -W \ - -Wabsolute-value \ - -Waddress \ - -Waddress-of-packed-member \ - -Waggressive-loop-optimizations \ + $1= + for gl_manywarn_item in -fanalyzer -fno-common \ -Wall \ - -Wanalyzer-double-fclose \ - -Wanalyzer-double-free \ - -Wanalyzer-exposure-through-output-file \ - -Wanalyzer-file-leak \ - -Wanalyzer-free-of-non-heap \ - -Wanalyzer-malloc-leak \ - -Wanalyzer-null-argument \ - -Wanalyzer-null-dereference \ - -Wanalyzer-possible-null-argument \ - -Wanalyzer-possible-null-dereference \ - -Wanalyzer-stale-setjmp-buffer \ - -Wanalyzer-tainted-array-index \ - -Wanalyzer-too-complex \ - -Wanalyzer-unsafe-call-within-signal-handler \ - -Wanalyzer-use-after-free \ - -Wanalyzer-use-of-pointer-in-stale-stack-frame \ -Warith-conversion \ - -Wattribute-warning \ - -Wattributes \ -Wbad-function-cast \ - -Wbool-compare \ - -Wbool-operation \ - -Wbuiltin-declaration-mismatch \ - -Wbuiltin-macro-redefined \ - -Wcannot-profile \ - -Wcast-align \ -Wcast-align=strict \ - -Wcast-function-type \ - -Wchar-subscripts \ - -Wclobbered \ - -Wcomment \ - -Wcomments \ - -Wcoverage-mismatch \ - -Wcpp \ - -Wdangling-else \ -Wdate-time \ - -Wdeprecated \ - -Wdeprecated-declarations \ - -Wdesignated-init \ -Wdisabled-optimization \ - -Wdiscarded-array-qualifiers \ - -Wdiscarded-qualifiers \ - -Wdiv-by-zero \ -Wdouble-promotion \ -Wduplicated-branches \ -Wduplicated-cond \ - -Wduplicate-decl-specifier \ - -Wempty-body \ - -Wendif-labels \ - -Wenum-compare \ - -Wenum-conversion \ - -Wexpansion-to-defined \ -Wextra \ - -Wformat-contains-nul \ - -Wformat-diag \ - -Wformat-extra-args \ - -Wformat-nonliteral \ - -Wformat-security \ -Wformat-signedness \ - -Wformat-y2k \ - -Wformat-zero-length \ - -Wframe-address \ - -Wfree-nonheap-object \ - -Whsa \ - -Wif-not-aligned \ - -Wignored-attributes \ - -Wignored-qualifiers \ - -Wimplicit \ - -Wimplicit-function-declaration \ - -Wimplicit-int \ - -Wincompatible-pointer-types \ -Winit-self \ -Winline \ - -Wint-conversion \ - -Wint-in-bool-context \ - -Wint-to-pointer-cast \ - -Winvalid-memory-model \ -Winvalid-pch \ - -Wlogical-not-parentheses \ -Wlogical-op \ - -Wmain \ - -Wmaybe-uninitialized \ - -Wmemset-elt-size \ - -Wmemset-transposed-args \ - -Wmisleading-indentation \ - -Wmissing-attributes \ - -Wmissing-braces \ -Wmissing-declarations \ - -Wmissing-field-initializers \ -Wmissing-include-dirs \ - -Wmissing-parameter-type \ - -Wmissing-profile \ -Wmissing-prototypes \ - -Wmultichar \ - -Wmultistatement-macros \ - -Wnarrowing \ -Wnested-externs \ - -Wnonnull \ - -Wnonnull-compare \ -Wnull-dereference \ - -Wodr \ - -Wold-style-declaration \ -Wold-style-definition \ -Wopenmp-simd \ - -Woverflow \ -Woverlength-strings \ - -Woverride-init \ -Wpacked \ - -Wpacked-bitfield-compat \ - -Wpacked-not-aligned \ - -Wparentheses \ -Wpointer-arith \ - -Wpointer-compare \ - -Wpointer-sign \ - -Wpointer-to-int-cast \ - -Wpragmas \ - -Wpsabi \ - -Wrestrict \ - -Wreturn-local-addr \ - -Wreturn-type \ - -Wscalar-storage-order \ - -Wsequence-point \ -Wshadow \ - -Wshift-count-negative \ - -Wshift-count-overflow \ - -Wshift-negative-value \ - -Wsizeof-array-argument \ - -Wsizeof-pointer-div \ - -Wsizeof-pointer-memaccess \ -Wstack-protector \ - -Wstrict-aliasing \ -Wstrict-overflow \ -Wstrict-prototypes \ - -Wstring-compare \ - -Wstringop-truncation \ -Wsuggest-attribute=cold \ -Wsuggest-attribute=const \ -Wsuggest-attribute=format \ @@ -260,95 +148,63 @@ m4_defun([gl_MANYWARN_ALL_GCC(C)], -Wsuggest-attribute=pure \ -Wsuggest-final-methods \ -Wsuggest-final-types \ - -Wswitch \ - -Wswitch-bool \ - -Wswitch-outside-range \ - -Wswitch-unreachable \ -Wsync-nand \ -Wsystem-headers \ - -Wtautological-compare \ -Wtrampolines \ - -Wtrigraphs \ - -Wtype-limits \ -Wuninitialized \ -Wunknown-pragmas \ -Wunsafe-loop-optimizations \ - -Wunused \ - -Wunused-but-set-parameter \ - -Wunused-but-set-variable \ - -Wunused-function \ - -Wunused-label \ - -Wunused-local-typedefs \ -Wunused-macros \ - -Wunused-parameter \ - -Wunused-result \ - -Wunused-value \ - -Wunused-variable \ - -Wvarargs \ -Wvariadic-macros \ -Wvector-operation-performance \ -Wvla \ - -Wvolatile-register-var \ -Wwrite-strings \ - -Wzero-length-bounds \ \ ; do - gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item" + gl_AS_VAR_APPEND([$1], [" $gl_manywarn_item"]) done # gcc --help=warnings outputs an unusual form for these options; list # them here so that the above 'comm' command doesn't report a false match. - # Would prefer "min (PTRDIFF_MAX, SIZE_MAX)", but it must be a literal. - # Also, AC_COMPUTE_INT requires it to fit in a long; it is 2**63 on - # the only platforms where it does not fit in a long, so make that - # a special case. - AC_MSG_CHECKING([max safe object size]) - AC_COMPUTE_INT([gl_alloc_max], - [LONG_MAX < (PTRDIFF_MAX < (size_t) -1 ? PTRDIFF_MAX : (size_t) -1) - ? -1 - : PTRDIFF_MAX < (size_t) -1 ? (long) PTRDIFF_MAX : (long) (size_t) -1], - [[#include - #include - #include - ]], - [gl_alloc_max=2147483647]) - case $gl_alloc_max in - -1) gl_alloc_max=9223372036854775807;; - esac - AC_MSG_RESULT([$gl_alloc_max]) - gl_manywarn_set="$gl_manywarn_set -Walloc-size-larger-than=$gl_alloc_max" - gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2" - gl_manywarn_set="$gl_manywarn_set -Wattribute-alias=2" - gl_manywarn_set="$gl_manywarn_set -Wformat-overflow=2" - gl_manywarn_set="$gl_manywarn_set -Wformat-truncation=2" - gl_manywarn_set="$gl_manywarn_set -Wimplicit-fallthrough=5" - gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc" - gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2" - gl_manywarn_set="$gl_manywarn_set -Wstringop-overflow=2" - gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2" - gl_manywarn_set="$gl_manywarn_set -Wvla-larger-than=4031" + gl_AS_VAR_APPEND([$1], [' -Warray-bounds=2']) + gl_AS_VAR_APPEND([$1], [' -Wattribute-alias=2']) + gl_AS_VAR_APPEND([$1], [' -Wformat-overflow=2']) + gl_AS_VAR_APPEND([$1], [' -Wformat=2']) + gl_AS_VAR_APPEND([$1], [' -Wformat-truncation=2']) + gl_AS_VAR_APPEND([$1], [' -Wimplicit-fallthrough=5']) + gl_AS_VAR_APPEND([$1], [' -Wshift-overflow=2']) + gl_AS_VAR_APPEND([$1], [' -Wunused-const-variable=2']) + gl_AS_VAR_APPEND([$1], [' -Wvla-larger-than=4031']) # These are needed for older GCC versions. if test -n "$GCC"; then case `($CC --version) 2>/dev/null` in 'gcc (GCC) '[[0-3]].* | \ 'gcc (GCC) '4.[[0-7]].*) - gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option" - gl_manywarn_set="$gl_manywarn_set -funit-at-a-time" + gl_AS_VAR_APPEND([$1], [' -fdiagnostics-show-option']) + gl_AS_VAR_APPEND([$1], [' -funit-at-a-time']) ;; esac fi # Disable specific options as needed. if test "$gl_cv_cc_nomfi_needed" = yes; then - gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers" + gl_AS_VAR_APPEND([$1], [' -Wno-missing-field-initializers']) fi if test "$gl_cv_cc_uninitialized_supported" = no; then - gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized" + gl_AS_VAR_APPEND([$1], [' -Wno-uninitialized']) fi - $1=$gl_manywarn_set + # Some warnings have too many false alarms in GCC 10.1. + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93695 + gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-double-free']) + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94458 + gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-malloc-leak']) + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94851 + gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-null-dereference']) + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95758 + gl_AS_VAR_APPEND([$1], [' -Wno-analyzer-use-after-free']) AC_LANG_POP([C]) ]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 index cc51337f0d1..516b346b311 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -5,7 +5,7 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 23 +# serial 24 # Written by Paul Eggert. @@ -87,7 +87,6 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO]) HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL]) - HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR]) HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR]) diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index 3efba5a7b98..929144d155b 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,4 +1,4 @@ -# sys_stat_h.m4 serial 33 -*- Autoconf -*- +# sys_stat_h.m4 serial 34 -*- Autoconf -*- dnl Copyright (C) 2006-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -46,8 +46,8 @@ AC_DEFUN([gl_HEADER_SYS_STAT_H], dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use. gl_WARN_ON_USE_PREPARE([[#include - ]], [fchmodat fstat fstatat futimens lchmod lstat mkdirat mkfifo mkfifoat - mknod mknodat stat utimensat]) + ]], [fchmodat fstat fstatat futimens getumask lchmod lstat + mkdirat mkfifo mkfifoat mknod mknodat stat utimensat]) AC_REQUIRE([AC_C_RESTRICT]) ]) @@ -68,6 +68,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], GNULIB_FSTAT=0; AC_SUBST([GNULIB_FSTAT]) GNULIB_FSTATAT=0; AC_SUBST([GNULIB_FSTATAT]) GNULIB_FUTIMENS=0; AC_SUBST([GNULIB_FUTIMENS]) + GNULIB_GETUMASK=0; AC_SUBST([GNULIB_GETUMASK]) GNULIB_LCHMOD=0; AC_SUBST([GNULIB_LCHMOD]) GNULIB_LSTAT=0; AC_SUBST([GNULIB_LSTAT]) GNULIB_MKDIRAT=0; AC_SUBST([GNULIB_MKDIRAT]) @@ -82,6 +83,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT]) HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT]) HAVE_FUTIMENS=1; AC_SUBST([HAVE_FUTIMENS]) + HAVE_GETUMASK=1; AC_SUBST([HAVE_GETUMASK]) HAVE_LCHMOD=1; AC_SUBST([HAVE_LCHMOD]) HAVE_LSTAT=1; AC_SUBST([HAVE_LSTAT]) HAVE_MKDIRAT=1; AC_SUBST([HAVE_MKDIRAT]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index dfa38f85d60..b4734daf603 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 80 +# unistd_h.m4 serial 81 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -120,7 +120,6 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], dnl Assume proper GNU behavior unless another module says otherwise. HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE]) - HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) HAVE_DUP3=1; AC_SUBST([HAVE_DUP3]) HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS]) HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) diff --git a/src/Makefile.in b/src/Makefile.in index 85709184da1..2f373d3eb7f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -323,8 +323,7 @@ INTERVALS_H = dispextern.h intervals.h composite.h GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ -GMP_LIB = @GMP_LIB@ -GMP_OBJ = @GMP_OBJ@ +LIB_GMP = @LIB_GMP@ LIBGCCJIT = @LIBGCCJIT_LIB@ @@ -536,7 +535,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ - $(JSON_LIBS) $(GMP_LIB) $(LIBGCCJIT) + $(JSON_LIBS) $(LIB_GMP) $(LIBGCCJIT) ## FORCE it so that admin/unidata can decide whether this file is ## up-to-date. Although since charprop depends on bootstrap-emacs, diff --git a/src/bignum.h b/src/bignum.h index 4a906c3c0eb..251a19e338a 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -22,12 +22,7 @@ along with GNU Emacs. If not, see . */ #ifndef BIGNUM_H #define BIGNUM_H -#ifdef HAVE_GMP -# include -#else -# include "mini-gmp.h" -#endif - +#include #include "lisp.h" /* Number of data bits in a limb. */ diff --git a/src/gtkutil.c b/src/gtkutil.c index 5d1ce6de97c..1fe160acca9 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -17,6 +17,13 @@ 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 . */ +/* FIXME: This code is problematic; it misuses GTK, so the GTK + developers don't think they should fix the resulting problems in GTK + itself. The right way to fix this is by rewriting the code in Emacs + to use GTK3 properly. As of 2020, there is a project to do this. + Talk with Yuuki Harano if you are interested + in doing substantial work on this. */ + #include #ifdef USE_GTK diff --git a/src/mini-gmp-emacs.c b/src/mini-gmp-emacs.c deleted file mode 100644 index b8399b075e0..00000000000 --- a/src/mini-gmp-emacs.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Tailor mini-gmp.c for GNU Emacs - -Copyright 2018-2020 Free Software Foundation, Inc. - -This file is part of GNU Emacs. - -GNU Emacs is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or (at -your option) any later version. - -GNU Emacs 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 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 . */ - -#include - -#include - -/* Pacify GCC -Wsuggest-attribute=malloc. */ -static void *gmp_default_alloc (size_t) ATTRIBUTE_MALLOC; - -/* Pacify GCC -Wunused-variable for variables used only in 'assert' calls. */ -#if defined NDEBUG && GNUC_PREREQ (4, 6, 0) -# pragma GCC diagnostic ignored "-Wunused-variable" -#endif - -#include "mini-gmp.c" diff --git a/src/xdisp.c b/src/xdisp.c index 97c55cdf5b8..eb7f3e7baa1 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -26387,7 +26387,7 @@ decode_mode_spec (struct window *w, register int c, int field_width, height = WINDOW_TOTAL_LINES (w); /* We cannot cope with w->start being outside of the accessible portion of the buffer; in particular, - display_count_lines call below will infloop if called with + display_count_lines call below might infloop if called with startpos_byte outside of the [BEGV_BYTE..ZV_BYTE] region. Such w->start means we were called in some "creative" way when the buffer's restriction was changed, but the window diff --git a/test/Makefile.in b/test/Makefile.in index f03c194a7cb..c4840670e61 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -255,12 +255,10 @@ else FPIC_CFLAGS = -fPIC endif -GMP_LIB = @GMP_LIB@ -GMP_OBJ = $(if @GMP_OBJ@, ../src/@GMP_OBJ@) +GMP_H = @GMP_H@ +LIB_GMP = @LIB_GMP@ -# Note: emacs-module.h is generated from emacs-module.h.in, hence we -# look in ../src, not $(srcdir)/../src. -MODULE_CFLAGS = -I../src -I$(srcdir)/../lib \ +MODULE_CFLAGS = -I../src -I$(srcdir)/../src -I../lib -I$(srcdir)/../lib \ $(FPIC_CFLAGS) $(PROFILING_CFLAGS) \ $(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS) @@ -273,7 +271,8 @@ src/emacs-module-tests.log src/emacs-module-tests.elc: $(test_module) $(test_module): $(test_module:${SO}=.c) ../src/emacs-module.h $(AM_V_at)${MKDIR_P} $(dir $@) $(AM_V_CCLD)$(CC) -shared $(CPPFLAGS) $(MODULE_CFLAGS) $(LDFLAGS) \ - -o $@ $< $(GMP_LIB) $(GMP_OBJ:.o=.c) \ + -o $@ $< $(LIB_GMP) \ + $(and $(GMP_H),$(srcdir)/../lib/mini-gmp-gnulib.c) \ $(srcdir)/../lib/timespec.c $(srcdir)/../lib/gettime.c endif diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index 5e3112f4471..1e64bcd65f1 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c @@ -43,12 +43,7 @@ uintptr_t _beginthread (void (__cdecl *)(void *), unsigned, void *); # include #endif -#ifdef HAVE_GMP #include -#else -#include "mini-gmp.h" -#endif - #include #include "timespec.h" diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 1f24ba2786f..34782e7f151 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -6035,18 +6035,22 @@ Use the `ls' command." "银河系漫游指南系列" "Автостопом по гала́ктике" ;; Use codepoints without a name. See Bug#31272. - "™›šbung") + "™›šbung" + ;; Use codepoints from Supplementary Multilingual Plane (U+10000 + ;; to U+1FFFF). + "🌈🍒👋") (when (tramp--test-expensive-test) (delete-dups (mapcar - ;; Use all available language specific snippets. Filter out - ;; strings which use unencodable characters. + ;; Use all available language specific snippets. (lambda (x) (and (stringp (setq x (eval (get-language-info (car x) 'sample-text)))) - (not (unencodable-char-position - 0 (length x) file-name-coding-system nil x)) + ;; Filter out strings which use unencodable characters. + (not (and (or (tramp--test-gvfs-p) (tramp--test-smb-p)) + (unencodable-char-position + 0 (length x) file-name-coding-system nil x))) ;; ?\n and ?/ shouldn't be part of any file name. ?\t, ;; ?. and ?? do not work for "smb" method. (replace-regexp-in-string "[\t\n/.?]" "" x))) diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 60cd6ea996e..6b3e63653be 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -3553,7 +3553,7 @@ def foo(): ;;; Code check -;;; Eldoc +;;; ElDoc (ert-deftest python-eldoc--get-symbol-at-point-1 () "Test paren handling." diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index 6851b890451..411b4505da0 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el @@ -288,6 +288,9 @@ during garbage collection." (with-temp-buffer (let ((standard-output (current-buffer))) (describe-function-1 #'mod-test-sum) + (goto-char (point-min)) + (while (re-search-forward "`[^']*/data/emacs-module/" nil t) + (replace-match "`data/emacs-module/")) (should (equal (buffer-substring-no-properties 1 (point-max)) (format "a module function in `data/emacs-module/mod-test%s'.