diff options
54 files changed, 1520 insertions, 609 deletions
diff --git a/CONTRIBUTE b/CONTRIBUTE index d9502dcac35..26efbd7e5aa 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -53,9 +53,18 @@ archives. To email a patch you can use a shell command like 'git format-patch -1' to create a file, and then attach the file to your email. This nicely -packages the patch's commit message and changes. To send just one -such patch without additional remarks, you can use a command like -'git send-email --to=bug-gnu-emacs@gnu.org 0001-DESCRIPTION.patch'. +packages the patch's commit message and changes, and makes sure the +format and whitespace are not munged in transit by the various mail +agents. To send just one such patch without additional remarks, it is +also possible to use a command like + + git send-email --to=bug-gnu-emacs@gnu.org 0001-DESCRIPTION.patch'. + +However, we prefer the 'git format-patch' method with attachment, as +doing so delivers patches in the correct and easily-recognizable format +more reliably, and makes the job of applying the patches easier and less +error-prone. It also allows to send patches whose author is someone +other than the email sender. Once the cumulative amount of your submissions exceeds about 15 lines of non-trivial changes, we will need you to assign to the FSF the diff --git a/admin/nt/dist-build/build-dep-zips.py b/admin/nt/dist-build/build-dep-zips.py index b0345a42cf3..7047d28346d 100755 --- a/admin/nt/dist-build/build-dep-zips.py +++ b/admin/nt/dist-build/build-dep-zips.py @@ -32,6 +32,7 @@ EMACS_MAJOR_VERSION="28" PKG_REQ='''mingw-w64-x86_64-giflib mingw-w64-x86_64-gnutls mingw-w64-x86_64-harfbuzz +mingw-w64-x86_64-jansson mingw-w64-x86_64-lcms2 mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libpng diff --git a/build-aux/config.guess b/build-aux/config.guess index 11fda528bc7..92bfc33e296 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -1095,7 +1095,17 @@ EOF echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" diff --git a/build-aux/config.sub b/build-aux/config.sub index 973a2980ac3..186616ac7a9 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -2,7 +2,7 @@ # Configuration validation subroutine script. # Copyright 1992-2020 Free Software Foundation, Inc. -timestamp='2020-05-04' +timestamp='2020-06-20' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -477,6 +477,10 @@ case $1 in basic_machine=hppa-unknown os=linux ;; + psp) + basic_machine=mipsallegrexel-sony + os=psp + ;; pw32) basic_machine=i586-unknown os=pw32 @@ -1138,13 +1142,9 @@ case $cpu-$vendor in cpu=nsx vendor=tandem ;; - s390-*) - cpu=s390 - vendor=ibm - ;; - s390x-*) - cpu=s390x - vendor=ibm + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony ;; tile*-*) os=${os:-linux-gnu} @@ -1229,6 +1229,7 @@ case $cpu-$vendor in | pyramid \ | riscv | riscv32 | riscv64 \ | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ | score \ | sh | shl \ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ @@ -1334,41 +1335,6 @@ case $os in psos*) os=psos ;; - # Now accept the basic system types. - # The portable systems comes first. - # Each alternative MUST end in a * to match a version number. - # sysv* is not here because it comes later, after sysvr4. - gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ - | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ - | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ - | sym* | kopensolaris* | plan9* \ - | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ - | aos* | aros* | cloudabi* | sortix* | twizzler* \ - | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ - | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ - | knetbsd* | mirbsd* | netbsd* \ - | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ - | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ - | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ - | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ - | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ - | chorusrdb* | cegcc* | glidix* \ - | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ - | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ - | linux-newlib* | linux-musl* | linux-uclibc* \ - | uxpv* | beos* | mpeix* | udk* | moxiebox* \ - | interix* | uwin* | mks* | rhapsody* | darwin* \ - | openstep* | oskit* | conix* | pw32* | nonstopux* \ - | storm-chaos* | tops10* | tenex* | tops20* | its* \ - | os2* | vos* | palmos* | uclinux* | nucleus* \ - | morphos* | superux* | rtmk* | windiss* \ - | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ - | skyos* | haiku* | rdos* | toppers* | drops* | es* \ - | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ - | nsk* | powerunix* | genode*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; qnx*) case $cpu in x86 | i*86) @@ -1393,18 +1359,21 @@ case $os in linux-dietlibc) os=linux-dietlibc ;; - linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; lynx*178) os=lynxos178 ;; lynx*5) os=lynxos5 ;; + lynxos*) + # don't get caught up in next wildcard + ;; lynx*) os=lynxos ;; + mach) + # don't get caught up in next wildcard + ;; mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; @@ -1507,10 +1476,50 @@ case $os in ;; ios) ;; + psp) + ;; none) ;; *-eabi) ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + # sysv* is not here because it comes later, after sysvr4. + gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | kopensolaris* | plan9* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | knetbsd* | mirbsd* | netbsd* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ + | linux-newlib* | linux-musl* | linux-uclibc* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* \ + | morphos* | superux* | rtmk* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; *) echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 536f4cb5daa..a2ace00cbbc 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1174,19 +1174,20 @@ right-to-left paragraphs. @findex display-fill-column-indicator-mode @findex global-display-fill-column-indicator-mode Emacs can add an indicator to display a fill column position. The -fill column indicator is a useful functionality specially in -prog-mode to indicate the position of an specific column. +fill column indicator is a useful functionality especially in +@code{prog-mode} to indicate the position of a specific column. - You can set the buffer-local variables @code{display-fill-column-indicator} -and @code{display-fill-column-indicator-character} to activate the -indicator and controls how the indicator looks. + You can set the buffer-local variables +@code{display-fill-column-indicator} and +@code{display-fill-column-indicator-character} to activate the +indicator and control how it looks, respectively. Alternatively you can type @w{@kbd{M-x display-fill-column-indicator-mode}} -or @w{@kbd{M-x global-display-fill-column-indicator-mode}} which enables the -indicator locally and globally respectively and also chooses the -character to use if none is set already. It is possible to use the -first one to activate the indicator in a hook or the second one to -enable it globally. +or @w{@kbd{M-x global-display-fill-column-indicator-mode}} which +enables the indicator locally or globally, respectively, and also +chooses the character to use if none is already set. It is possible +to use the first one to activate the indicator in a hook and the +second one to enable it globally. There are 2 buffer local variables and 1 face to customize this mode: @@ -1203,20 +1204,20 @@ Any other value disables the indicator. The default value is @code{t}. @item display-fill-column-indicator-character @vindex display-fill-column-indicator-character Specifies the character used for the indicator. This character can be -any valid char including unicode ones if the actual font supports -them. +any valid character including Unicode ones if the font supports them. When the mode is enabled through the functions @code{display-fill-column-indicator-mode} or @code{global-display-fill-column-indicator-mode}, the initialization -functions check if this variable is @code{non-nil}, otherwise the -initialization tries to set it to U+2502 or @samp{|}. +functions check if this variable is non-@code{nil}, otherwise the +initialization tries to set it to @code{U+2502} or @samp{|}. @item fill-column-indicator @vindex fill-column-indicator Specifies the face used to display the indicator. It inherits its -default values from shadow but without background color. To change -the indicator color you need to set only the foreground color of this face. +default values from the face @code{shadow} but without background +color. To change the indicator color you need only set the foreground +color of this face. @end table @vindex indicate-buffer-boundaries diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 01ae94ea7dd..d2419f415bf 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -959,8 +959,9 @@ For example, the following is invalid: @example @group +(require 'cl-lib) (pcase (read-number "Enter an integer: ") - ((or (and (pred evenp) + ((or (and (pred cl-evenp) e-num) ; @r{bind @code{e-num} to @var{expval}} o-num) ; @r{bind @code{o-num} to @var{expval}} (list e-num o-num))) @@ -984,9 +985,10 @@ Reworking the above example: @example @group +(require 'cl-lib) (pcase (read-number "Enter an integer: ") ((and num ; @r{line 1} - (or (and (pred evenp) ; @r{line 2} + (or (and (pred cl-evenp) ; @r{line 2} (let spin 'even)) ; @r{line 3} (let spin 'odd))) ; @r{line 4} (list spin num))) ; @r{line 5} diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index 8f7ed715b52..82467048a08 100644 --- a/doc/misc/efaq.texi +++ b/doc/misc/efaq.texi @@ -3477,15 +3477,18 @@ You can browse the resulting @file{*Packages*} buffer to see what is available, and then Emacs can automatically download and install the packages that you select. @xref{Packages,,, emacs, The GNU Emacs Manual}. -There are other, non-GNU, Emacs Lisp package servers, including: -@uref{https://melpa.org, MELPA}; and -@uref{https://marmalade-repo.org, Marmalade}. To use additional -package servers, customize the @code{package-archives} variable. Be -aware that installing a package can run arbitrary code, so only add -sources that you trust. Also, packages hosted on non-GNU package -servers may encourage or require you to install and use non-free -software; for example, MELPA is known to host some packages that do -this. +There are other Emacs Lisp package archives. To use additional +archives, you can customize the @code{package-archives} variable. +Those archives have no affiliation with GNU Emacs, and we do not +monitor how they are maintained. They may pay close attention to +correctness and safety of the code, or they may give only cursory +attention. + +Also, packages hosted on these other archives may encourage or require +you to install and use other nonfree programs. Unless you can verify +that a package is free software, and that it functions without +installing any nonfree software, we recommend for your freedom's sake +that you stay away from it. The @uref{https://lists.gnu.org/mailman/listinfo/gnu-emacs-sources, GNU Emacs sources mailing list}, which is gatewayed to the diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 2b7b31b34a9..d3136db38aa 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2020-05-07.17} +\def\texinfoversion{2020-05-22.11} % % Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc. % @@ -33,7 +33,7 @@ % The texinfo.tex in any given distribution could well be out % of date, so if that's what you're using, please check. % -% Send bug reports to bug-texinfo@gnu.org. Please include including a +% Send bug reports to bug-texinfo@gnu.org. Please include a % complete document in each bug report with which we can reproduce the % problem. Patches are, of course, greatly appreciated. % @@ -408,7 +408,8 @@ \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } -% Check if we are on the first page of a chapter. +% Check if we are on the first page of a chapter. Used for printing headings. +\newif\ifchapterpage \def\checkchapterpage{% % Get the chapter that was current at the end of the last page \ifcase1\the\savedtopmark\fi @@ -418,12 +419,9 @@ \let\curchaptername\thischaptername % \ifx\curchaptername\prevchaptername - \let\thischapterheading\thischapter + \chapterpagefalse \else - % \thischapterheading is the same as \thischapter except it is blank - % for the first page of a chapter. This is to prevent the chapter name - % being shown twice. - \def\thischapterheading{}% + \chapterpagetrue \fi } @@ -1013,7 +1011,7 @@ where each line of input produces a line of output.} \let\setfilename=\comment % @bye. -\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} +\outer\def\bye{\chappager\pagelabels\tracingstats=1\ptexend} \message{pdf,} @@ -1140,6 +1138,45 @@ where each line of input produces a line of output.} \fi +% Output page labels information. +% See PDF reference v.1.7 p.594, section 8.3.1. +\ifpdf +\def\pagelabels{% + \def\title{0 << /P (T-) /S /D >>}% + \edef\roman{\the\romancount << /S /r >>}% + \edef\arabic{\the\arabiccount << /S /D >>}% + % + % Page label ranges must be increasing. Remove any duplicates. + % (There is a slight chance of this being wrong if e.g. there is + % a @contents but no @titlepage, etc.) + % + \ifnum\romancount=0 \def\roman{}\fi + \ifnum\arabiccount=0 \def\title{}% + \else + \ifnum\romancount=\arabiccount \def\roman{}\fi + \fi + % + \ifnum\romancount<\arabiccount + \pdfcatalog{/PageLabels << /Nums [\title \roman \arabic ] >> }\relax + \else + \pdfcatalog{/PageLabels << /Nums [\title \arabic \roman ] >> }\relax + \fi +} +\else + \let\pagelabels\relax +\fi + +\newcount\pagecount \pagecount=0 +\newcount\romancount \romancount=0 +\newcount\arabiccount \arabiccount=0 +\ifpdf + \let\ptxadvancepageno\advancepageno + \def\advancepageno{% + \ptxadvancepageno\global\advance\pagecount by 1 + } +\fi + + % PDF uses PostScript string constants for the names of xref targets, % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be @@ -3806,12 +3843,19 @@ end \newtoks\evenheadline % headline on even pages \newtoks\oddheadline % headline on odd pages +\newtoks\evenchapheadline% headline on even pages with a new chapter +\newtoks\oddchapheadline % headline on odd pages with a new chapter \newtoks\evenfootline % footline on even pages \newtoks\oddfootline % footline on odd pages % Now make \makeheadline and \makefootline in Plain TeX use those variables -\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline - \else \the\evenheadline \fi}} +\headline={{\textfonts\rm + \ifchapterpage + \ifodd\pageno\the\oddchapheadline\else\the\evenchapheadline\fi + \else + \ifodd\pageno\the\oddheadline\else\the\evenheadline\fi + \fi}} + \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax @@ -3827,12 +3871,14 @@ end \def\evenheading{\parsearg\evenheadingxxx} \def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} \def\evenheadingyyy #1\|#2\|#3\|#4\finish{% -\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}} + \global\evenchapheadline=\evenheadline} \def\oddheading{\parsearg\oddheadingxxx} \def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} \def\oddheadingyyy #1\|#2\|#3\|#4\finish{% -\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}% + \global\oddchapheadline=\oddheadline} \parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% @@ -3899,37 +3945,34 @@ end \parseargdef\headings{\csname HEADINGS#1\endcsname} \def\headingsoff{% non-global headings elimination - \evenheadline={\hfil}\evenfootline={\hfil}% - \oddheadline={\hfil}\oddfootline={\hfil}% + \evenheadline={\hfil}\evenfootline={\hfil}\evenchapheadline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}\oddchapheadline={\hfil}% } \def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting \HEADINGSoff % it's the default % When we turn headings on, set the page number to 1. +\def\pageone{ + \global\pageno=1 + \global\arabiccount = \pagecount +} + % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{% -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage +\pageone +\HEADINGSdoublex } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{% -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapterheading\hfil\folio}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} -\global\let\contentsalignmacro = \chappager +\pageone +\HEADINGSsinglex } \def\HEADINGSon{\HEADINGSdouble} @@ -3939,7 +3982,9 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenchapheadline={\line{\folio\hfil}} +\global\oddchapheadline={\line{\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } @@ -3947,8 +3992,22 @@ end \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapterheading\hfil\folio}} -\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenchapheadline={\line{\hfil\folio}} +\global\oddchapheadline={\line{\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% for @setchapternewpage off +\def\HEADINGSsinglechapoff{% +\pageone +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenchapheadline=\evenheadline +\global\oddchapheadline=\oddheadline \global\let\contentsalignmacro = \chappager } @@ -5139,64 +5198,66 @@ end \let\lbracechar\{% \let\rbracechar\}% % + % + \let\do\indexnofontsdef + % % Non-English letters. - \def\AA{AA}% - \def\AE{AE}% - \def\DH{DZZ}% - \def\L{L}% - \def\OE{OE}% - \def\O{O}% - \def\TH{TH}% - \def\aa{aa}% - \def\ae{ae}% - \def\dh{dzz}% - \def\exclamdown{!}% - \def\l{l}% - \def\oe{oe}% - \def\ordf{a}% - \def\ordm{o}% - \def\o{o}% - \def\questiondown{?}% - \def\ss{ss}% - \def\th{th}% - % - \def\LaTeX{LaTeX}% - \def\TeX{TeX}% - % - % Assorted special characters. \defglyph gives the control sequence a - % definition that removes the {} that follows its use. - \defglyph\atchar{@}% - \defglyph\arrow{->}% - \defglyph\bullet{bullet}% - \defglyph\comma{,}% - \defglyph\copyright{copyright}% - \defglyph\dots{...}% - \defglyph\enddots{...}% - \defglyph\equiv{==}% - \defglyph\error{error}% - \defglyph\euro{euro}% - \defglyph\expansion{==>}% - \defglyph\geq{>=}% - \defglyph\guillemetleft{<<}% - \defglyph\guillemetright{>>}% - \defglyph\guilsinglleft{<}% - \defglyph\guilsinglright{>}% - \defglyph\leq{<=}% - \defglyph\lbracechar{\{}% - \defglyph\minus{-}% - \defglyph\point{.}% - \defglyph\pounds{pounds}% - \defglyph\print{-|}% - \defglyph\quotedblbase{"}% - \defglyph\quotedblleft{"}% - \defglyph\quotedblright{"}% - \defglyph\quoteleft{`}% - \defglyph\quoteright{'}% - \defglyph\quotesinglbase{,}% - \defglyph\rbracechar{\}}% - \defglyph\registeredsymbol{R}% - \defglyph\result{=>}% - \defglyph\textdegree{o}% + \do\AA{AA}% + \do\AE{AE}% + \do\DH{DZZ}% + \do\L{L}% + \do\OE{OE}% + \do\O{O}% + \do\TH{TH}% + \do\aa{aa}% + \do\ae{ae}% + \do\dh{dzz}% + \do\exclamdown{!}% + \do\l{l}% + \do\oe{oe}% + \do\ordf{a}% + \do\ordm{o}% + \do\o{o}% + \do\questiondown{?}% + \do\ss{ss}% + \do\th{th}% + % + \do\LaTeX{LaTeX}% + \do\TeX{TeX}% + % + % Assorted special characters. + \do\atchar{@}% + \do\arrow{->}% + \do\bullet{bullet}% + \do\comma{,}% + \do\copyright{copyright}% + \do\dots{...}% + \do\enddots{...}% + \do\equiv{==}% + \do\error{error}% + \do\euro{euro}% + \do\expansion{==>}% + \do\geq{>=}% + \do\guillemetleft{<<}% + \do\guillemetright{>>}% + \do\guilsinglleft{<}% + \do\guilsinglright{>}% + \do\leq{<=}% + \do\lbracechar{\{}% + \do\minus{-}% + \do\point{.}% + \do\pounds{pounds}% + \do\print{-|}% + \do\quotedblbase{"}% + \do\quotedblleft{"}% + \do\quotedblright{"}% + \do\quoteleft{`}% + \do\quoteright{'}% + \do\quotesinglbase{,}% + \do\rbracechar{\}}% + \do\registeredsymbol{R}% + \do\result{=>}% + \do\textdegree{o}% % % We need to get rid of all macros, leaving only the arguments (if present). % Of course this is not nearly correct, but it is the best we can do for now. @@ -5211,7 +5272,10 @@ end \macrolist \let\value\indexnofontsvalue } -\def\defglyph#1#2{\def#1##1{#2}} % see above + +% Give the control sequence a definition that removes the {} that follows +% its use, e.g. @AA{} -> AA +\def\indexnofontsdef#1#2{\def#1##1{#2}}% @@ -6423,18 +6487,16 @@ might help (with 'rm \jobname.?? \jobname.??s')% \def\CHAPPAGoff{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak -\global\let\pagealignmacro=\chappager} +\global\def\HEADINGSon{\HEADINGSsinglechapoff}} \def\CHAPPAGon{% \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager -\global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{% \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage -\global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon @@ -6799,9 +6861,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should - % start on an odd page, unlike chapters. Thus, we maintain - % \contentsalignmacro in parallel with \pagealignmacro. - % From: Torbjorn Granlund <tege@matematik.su.se> + % start on an odd page, unlike chapters. \contentsalignmacro \immediate\closeout\tocfile % @@ -6816,6 +6876,9 @@ might help (with 'rm \jobname.?? \jobname.??s')% % % Roman numerals for page numbers. \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi + \def\thistitle{}% no title in double-sided headings + % Record where the Roman numerals started. + \ifnum\romancount=0 \global\romancount=\pagecount \fi } % redefined for the two-volume lispref. We always output on @@ -6838,8 +6901,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \fi \closein 1 \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno + \contentsendroman } % And just the chapters. @@ -6874,10 +6936,20 @@ might help (with 'rm \jobname.?? \jobname.??s')% \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup + \contentsendroman +} +\let\shortcontents = \summarycontents + +% Get ready to use Arabic numerals again +\def\contentsendroman{% \lastnegativepageno = \pageno \global\pageno = \savepageno + % + % If \romancount > \arabiccount, the contents are at the end of the + % document. Otherwise, advance where the Arabic numerals start for + % the page numbers. + \ifnum\romancount>\arabiccount\else\global\arabiccount=\pagecount\fi } -\let\shortcontents = \summarycontents % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g., `A' for an appendix, or `3' for a chapter. @@ -7559,7 +7631,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% \edef\tmp{\noexpand\input #1 } \expandafter - }\tmp + }\expandafter\starttabbox\tmp\egroup \afterenvbreak }% } @@ -10725,6 +10797,8 @@ directory should work if nowhere else does.} \DeclareUnicodeCharacter{0233}{\=y}% \DeclareUnicodeCharacter{0237}{\dotless{j}}% % + \DeclareUnicodeCharacter{02BC}{'}% + % \DeclareUnicodeCharacter{02DB}{\ogonek{ }}% % % Greek letters upper case @@ -64,8 +64,8 @@ It was declared obsolete in Emacs 27.1. ** Emacs can support 24-bit color TTY without terminfo database. If your text-mode terminal supports 24-bit true color, but your system lacks the terminfo database, you can instruct Emacs to support 24-bit -true color by setting COLORTERM=truecolor in the environment. This is -useful on systems such as FreeBSD which ships only with 'etc/termcap'. +true color by setting 'COLORTERM=truecolor' in the environment. This is +useful on systems such as FreeBSD which ships only with "etc/termcap". * Changes in Emacs 28.1 @@ -115,6 +115,14 @@ setting the variable 'auto-save-visited-mode' buffer-locally to nil. * Changes in Specialized Modes and Packages in Emacs 28.1 +** Windows + +*** The key prefix 'C-x 4 4' displays next command buffer in a new window. + +** Frames + +*** The key prefix 'C-x 5 5' displays next command buffer in a new frame. + ** Tab Bars *** The key prefix 'C-x t t' displays next command buffer in a new tab. @@ -165,6 +173,15 @@ directories with the help of new command 'dired-vc-next-action'. ** Change Logs and VC +*** More VC commands can be used from non-file buffers. +The relevant commands are those that don't change the VC state. +The non-file buffers which can use VC commands are those that have +their 'default-directory' under VC. + +*** 'M-n' now works in minibuffer prompts of VC commands. +Typing 'M-n' in the minibuffer that prompts for a VC directory in VC +commands now retrieves directories of previously used VC projects. + *** New command 'vc-dir-root' uses the root directory without asking. *** New commands 'vc-dir-mark-registered-files' (bound to '* r') and @@ -189,6 +206,11 @@ this user option. *** New command 'describe-keymap' describes keybindings in a keymap. --- +*** The command 'view-lossage' can now be invoked from the menu bar. +The menu-bar Help menu now has a "Show Recent Inputs" item under the +"Describe" sub-menu. + +--- ** The old non-SMIE indentation of 'sh-mode' has been removed. --- @@ -382,7 +404,6 @@ To enable, add it to appropriate entries in 'c-offsets-alist', e.g.: ** browse-url *** Added support for custom URL handlers. - There is a new variable 'browse-url-default-handlers' and a user option 'browse-url-handlers' being alists with '(REGEXP-OR-PREDICATE . FUNCTION)' entries allowing to define different browsing FUNCTIONs @@ -396,7 +417,6 @@ Formerly, one could do the same by setting supported but deprecated. *** Categorization of browsing functions in internal vs. external. - All standard browsing functions such as 'browse-url-firefox', 'browse-url-mail', or 'eww' have been categorized into internal (URL is browsed in Emacs) or external (an external application is spawned @@ -482,6 +502,21 @@ the function 'format-spec' documented under node "(elisp) Custom Format Strings". The new syntax includes specifiers for padding and truncation, amongst other things. +** bug-reference.el + +--- +*** Bug reference mode auto-setup. If 'bug-reference-mode' or +'bug-reference-prog-mode' have been activated, their respective hook +has been run and still 'bug-reference-bug-regexp' and +'bug-reference-url-format' aren't both set, it tries to guess +appropriate values for those two variables. There are two guessing +mechanisms so far: based on version control information of the current +buffer's file, and based on newsgroup/mail-folder name and several +news and mail message headers in Gnus buffers. Both mechanisms are +extensible with custom rules, see the variables +'bug-reference-setup-from-vc-alist' and +'bug-reference-setup-from-mail-alist'. + * New Modes and Packages in Emacs 28.1 @@ -616,6 +651,11 @@ In order for the two functions to behave more consistently, length, and also supports format specifications that include a truncating precision field, such as '%.2a'. +--- +** New function 'color-values-from-color-spec'. +This can be used to parse RGB color specs in several formats and +convert them to a list '(R G B)' of primary color values. + * Changes in Emacs 28.1 on Non-Free Operating Systems diff --git a/lib/count-one-bits.h b/lib/count-one-bits.h index eea56d85910..6c5b75708cf 100644 --- a/lib/count-one-bits.h +++ b/lib/count-one-bits.h @@ -34,29 +34,13 @@ _GL_INLINE_HEADER_BEGIN extern "C" { #endif -/* Expand to code that computes the number of 1-bits of the local - variable 'x' of type TYPE (an unsigned integer type) and return it - from the current function. */ -#define COUNT_ONE_BITS_GENERIC(TYPE) \ - do \ - { \ - int count = 0; \ - int bits; \ - for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \ - { \ - count += count_one_bits_32 (x); \ - x = x >> 31 >> 1; \ - } \ - return count; \ - } \ - while (0) - -/* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN, +/* Assuming the GCC builtin is GCC_BUILTIN and the MSC builtin is MSC_BUILTIN, expand to code that computes the number of 1-bits of the local variable 'x' of type TYPE (an unsigned integer type) and return it from the current function. */ #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# define COUNT_ONE_BITS(BUILTIN, MSC_BUILTIN, TYPE) return BUILTIN (x) +# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ + return GCC_BUILTIN (x) #else /* Compute and return the number of 1-bits set in the least @@ -71,14 +55,46 @@ count_one_bits_32 (unsigned int x) return (x >> 8) + (x & 0x00ff); } +/* Expand to code that computes the number of 1-bits of the local + variable 'x' of type TYPE (an unsigned integer type) and return it + from the current function. */ +# define COUNT_ONE_BITS_GENERIC(TYPE) \ + do \ + { \ + int count = 0; \ + int bits; \ + for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \ + { \ + count += count_one_bits_32 (x); \ + x = x >> 31 >> 1; \ + } \ + return count; \ + } \ + while (0) + # if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64) /* While gcc falls back to its own generic code if the machine on which it's running doesn't support popcount, with Microsoft's compiler we need to detect and fallback ourselves. */ -# pragma intrinsic __cpuid -# pragma intrinsic __popcnt -# pragma intrinsic __popcnt64 + +# if 0 +# include <intrin.h> +# else + /* Don't pollute the namespace with too many MSVC intrinsics. */ +# pragma intrinsic (__cpuid) +# pragma intrinsic (__popcnt) +# if defined _M_X64 +# pragma intrinsic (__popcnt64) +# endif +# endif + +# if !defined _M_X64 +static inline __popcnt64 (unsigned long long x) +{ + return __popcnt ((unsigned int) (x >> 32)) + __popcnt ((unsigned int) x); +} +# endif /* Return nonzero if popcount is supported. */ @@ -90,25 +106,30 @@ popcount_supported (void) { if (popcount_support < 0) { + /* Do as described in + <https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64> */ int cpu_info[4]; __cpuid (cpu_info, 1); - popcount_support = (cpu_info[2] >> 23) & 1; /* See MSDN. */ + popcount_support = (cpu_info[2] >> 23) & 1; } return popcount_support; } -# define COUNT_ONE_BITS(BUILTIN, MSC_BUILTIN, TYPE) \ - do \ - { \ - if (popcount_supported ()) \ - return MSC_BUILTIN (x); \ - else \ - COUNT_ONE_BITS_GENERIC (TYPE); \ - } \ +# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ + do \ + { \ + if (popcount_supported ()) \ + return MSC_BUILTIN (x); \ + else \ + COUNT_ONE_BITS_GENERIC (TYPE); \ + } \ while (0) + # else -# define COUNT_ONE_BITS(BUILTIN, MSC_BUILTIN, TYPE) \ + +# define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ COUNT_ONE_BITS_GENERIC (TYPE) + # endif #endif diff --git a/lib/ftoastr.c b/lib/ftoastr.c index 7a7d4113c22..47a83152e3f 100644 --- a/lib/ftoastr.c +++ b/lib/ftoastr.c @@ -33,20 +33,28 @@ #include <stdio.h> #include <stdlib.h> +#ifdef C_LOCALE +# include "c-snprintf.h" +# include "c-strtod.h" +# define PREFIX(name) c_ ## name +#else +# define PREFIX(name) name +#endif + #if LENGTH == 3 # define FLOAT long double # define FLOAT_DIG LDBL_DIG # define FLOAT_MIN LDBL_MIN # define FLOAT_PREC_BOUND _GL_LDBL_PREC_BOUND -# define FTOASTR ldtoastr +# define FTOASTR PREFIX (ldtoastr) # define PROMOTED_FLOAT long double -# define STRTOF strtold +# define STRTOF PREFIX (strtold) #elif LENGTH == 2 # define FLOAT double # define FLOAT_DIG DBL_DIG # define FLOAT_MIN DBL_MIN # define FLOAT_PREC_BOUND _GL_DBL_PREC_BOUND -# define FTOASTR dtoastr +# define FTOASTR PREFIX (dtoastr) # define PROMOTED_FLOAT double #else # define LENGTH 1 @@ -54,7 +62,7 @@ # define FLOAT_DIG FLT_DIG # define FLOAT_MIN FLT_MIN # define FLOAT_PREC_BOUND _GL_FLT_PREC_BOUND -# define FTOASTR ftoastr +# define FTOASTR PREFIX (ftoastr) # define PROMOTED_FLOAT double # if HAVE_STRTOF # define STRTOF strtof @@ -65,13 +73,16 @@ may generate one or two extra digits, but that's better than not working at all. */ #ifndef STRTOF -# define STRTOF strtod +# define STRTOF PREFIX (strtod) #endif /* On hosts where it's not known that snprintf works, use sprintf to implement the subset needed here. Typically BUFSIZE is big enough and there's little or no performance hit. */ -#if ! GNULIB_SNPRINTF +#ifdef C_LOCALE +# undef snprintf +# define snprintf c_snprintf +#elif ! GNULIB_SNPRINTF # undef snprintf # define snprintf ftoastr_snprintf static int diff --git a/lib/ftoastr.h b/lib/ftoastr.h index d945cc064a7..78b569f3d97 100644 --- a/lib/ftoastr.h +++ b/lib/ftoastr.h @@ -18,6 +18,7 @@ /* Written by Paul Eggert. */ #ifndef _GL_FTOASTR_H +#define _GL_FTOASTR_H #include "intprops.h" #include <float.h> @@ -48,6 +49,12 @@ int ftoastr (char *buf, size_t bufsize, int flags, int width, float x); int dtoastr (char *buf, size_t bufsize, int flags, int width, double x); int ldtoastr (char *buf, size_t bufsize, int flags, int width, long double x); +/* The last two functions except that the formatting takes place in + the C locale. */ +int c_dtoastr (char *buf, size_t bufsize, int flags, int width, double x); +int c_ldtoastr (char *buf, size_t bufsize, int flags, int width, long double x); + + /* Flag values for ftoastr etc. These can be ORed together. */ enum { diff --git a/lib/getloadavg.c b/lib/getloadavg.c index ebb6f5d5dba..468e2506709 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c @@ -512,7 +512,7 @@ getloadavg (double loadavg[], int nelem) char const *ptr = ldavgbuf; int fd, count, saved_errno; - fd = open (LINUX_LDAV_FILE, O_RDONLY); + fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC); if (fd == -1) return -1; count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); @@ -550,7 +550,7 @@ getloadavg (double loadavg[], int nelem) for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; - loadavg[elem++] = numerator / denominator; + loadavg[elem] = numerator / denominator; } return elem; @@ -567,15 +567,22 @@ getloadavg (double loadavg[], int nelem) unsigned long int load_ave[3], scale; int count; - FILE *fp; - - fp = fopen (NETBSD_LDAV_FILE, "r"); - if (fp == NULL) - return -1; - count = fscanf (fp, "%lu %lu %lu %lu\n", + char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1]; + int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return fd; + int nread = read (fd, readbuf, sizeof readbuf - 1); + int err = errno; + close (fd); + if (nread < 0) + { + errno = err; + return -1; + } + readbuf[nread] = '\0'; + count = sscanf (readbuf, "%lu %lu %lu %lu\n", &load_ave[0], &load_ave[1], &load_ave[2], &scale); - (void) fclose (fp); if (count != 4) { errno = ENOTSUP; @@ -869,27 +876,11 @@ getloadavg (double loadavg[], int nelem) if (!getloadavg_initialized) { # ifndef SUNOS_5 - /* Set the channel to close on exec, so it does not - litter any child's descriptor table. */ -# ifndef O_CLOEXEC -# define O_CLOEXEC 0 -# endif int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC); if (0 <= fd) { -# if F_DUPFD_CLOEXEC - if (fd <= STDERR_FILENO) - { - int fd1 = fcntl (fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1); - close (fd); - fd = fd1; - } -# endif - if (0 <= fd) - { - channel = fd; - getloadavg_initialized = true; - } + channel = fd; + getloadavg_initialized = true; } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names diff --git a/lib/getrandom.c b/lib/getrandom.c new file mode 100644 index 00000000000..f0b3f535007 --- /dev/null +++ b/lib/getrandom.c @@ -0,0 +1,178 @@ +/* Obtain a series of random bytes. + + Copyright 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 <https://www.gnu.org/licenses/>. */ + +/* Written by Paul Eggert. */ + +#include <config.h> + +#include <sys/random.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <unistd.h> + +#if defined _WIN32 && ! defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include <windows.h> +# include <bcrypt.h> +# if !HAVE_LIB_BCRYPT +# include <wincrypt.h> +# ifndef CRYPT_VERIFY_CONTEXT +# define CRYPT_VERIFY_CONTEXT 0xF0000000 +# endif +# endif +#endif + +#include "minmax.h" + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* Don't assume that UNICODE is not defined. */ +# undef LoadLibrary +# define LoadLibrary LoadLibraryA +# undef CryptAcquireContext +# define CryptAcquireContext CryptAcquireContextA + +# if !HAVE_LIB_BCRYPT + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress + +/* BCryptGenRandom with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag works only + starting with Windows 7. */ +typedef NTSTATUS (WINAPI * BCryptGenRandomFuncType) (BCRYPT_ALG_HANDLE, UCHAR *, ULONG, ULONG); +static BCryptGenRandomFuncType BCryptGenRandomFunc = NULL; +static BOOL initialized = FALSE; + +static void +initialize (void) +{ + HMODULE bcrypt = LoadLibrary ("bcrypt.dll"); + if (bcrypt != NULL) + { + BCryptGenRandomFunc = + (BCryptGenRandomFuncType) GetProcAddress (bcrypt, "BCryptGenRandom"); + } + initialized = TRUE; +} + +# else + +# define BCryptGenRandomFunc BCryptGenRandom + +# endif + +#else +/* These devices exist on all platforms except native Windows. */ + +/* Name of a device through which the kernel returns high quality random + numbers, from an entropy pool. When the pool is empty, the call blocks + until entropy sources have added enough bits of entropy. */ +# ifndef NAME_OF_RANDOM_DEVICE +# define NAME_OF_RANDOM_DEVICE "/dev/random" +# endif + +/* Name of a device through which the kernel returns random or pseudo-random + numbers. It uses an entropy pool, but, in order to avoid blocking, adds + bits generated by a pseudo-random number generator, as needed. */ +# ifndef NAME_OF_NONCE_DEVICE +# define NAME_OF_NONCE_DEVICE "/dev/urandom" +# endif + +#endif + +/* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS. + Return the number of bytes written (> 0). + Upon error, return -1 and set errno. */ +ssize_t +getrandom (void *buffer, size_t length, unsigned int flags) +#undef getrandom +{ +#if defined _WIN32 && ! defined __CYGWIN__ + /* BCryptGenRandom, defined in <bcrypt.h> + <https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom> + with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag + works in Windows 7 and newer. */ + static int bcrypt_not_working /* = 0 */; + if (!bcrypt_not_working) + { +# if !HAVE_LIB_BCRYPT + if (!initialized) + initialize (); +# endif + if (BCryptGenRandomFunc != NULL + && BCryptGenRandomFunc (NULL, buffer, length, + BCRYPT_USE_SYSTEM_PREFERRED_RNG) + == 0 /*STATUS_SUCCESS*/) + return length; + bcrypt_not_working = 1; + } +# if !HAVE_LIB_BCRYPT + /* CryptGenRandom, defined in <wincrypt.h> + <https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom> + works in older releases as well, but is now deprecated. + CryptAcquireContext, defined in <wincrypt.h> + <https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta> */ + { + static int crypt_initialized /* = 0 */; + static HCRYPTPROV provider; + if (!crypt_initialized) + { + if (CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFY_CONTEXT)) + crypt_initialized = 1; + else + crypt_initialized = -1; + } + if (crypt_initialized >= 0) + { + if (!CryptGenRandom (provider, length, buffer)) + { + errno = EIO; + return -1; + } + return length; + } + } +# endif + errno = ENOSYS; + return -1; +#elif HAVE_GETRANDOM + return getrandom (buffer, length, flags); +#else + static int randfd[2] = { -1, -1 }; + bool devrandom = (flags & GRND_RANDOM) != 0; + int fd = randfd[devrandom]; + + if (fd < 0) + { + static char const randdevice[][MAX (sizeof NAME_OF_NONCE_DEVICE, + sizeof NAME_OF_RANDOM_DEVICE)] + = { NAME_OF_NONCE_DEVICE, NAME_OF_RANDOM_DEVICE }; + int oflags = (O_RDONLY + O_CLOEXEC + + (flags & GRND_NONBLOCK ? O_NONBLOCK : 0)); + fd = open (randdevice[devrandom], oflags); + if (fd < 0) + return fd; + randfd[devrandom] = fd; + } + + return read (fd, buffer, length); +#endif +} diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c index b63f8f29292..057cebdb163 100644 --- a/lib/gettimeofday.c +++ b/lib/gettimeofday.c @@ -33,9 +33,15 @@ #ifdef WINDOWS_NATIVE +/* Don't assume that UNICODE is not defined. */ +# undef LoadLibrary +# define LoadLibrary LoadLibraryA + +# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8) + /* Avoid warnings from gcc -Wcast-function-type. */ -# define GetProcAddress \ - (void *) GetProcAddress +# define GetProcAddress \ + (void *) GetProcAddress /* GetSystemTimePreciseAsFileTime was introduced only in Windows 8. */ typedef void (WINAPI * GetSystemTimePreciseAsFileTimeFuncType) (FILETIME *lpTime); @@ -54,6 +60,12 @@ initialize (void) initialized = TRUE; } +# else + +# define GetSystemTimePreciseAsFileTimeFunc GetSystemTimePreciseAsFileTime + +# endif + #endif /* This is a wrapper for gettimeofday. It is used only on systems @@ -84,8 +96,10 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz) <http://www.windowstimestamp.com/description>. */ FILETIME current_time; +# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8) if (!initialized) initialize (); +# endif if (GetSystemTimePreciseAsFileTimeFunc != NULL) GetSystemTimePreciseAsFileTimeFunc (¤t_time); else diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 5c11dfc95ca..8174ea26fa5 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -311,6 +311,7 @@ GNULIB_GETCWD = @GNULIB_GETCWD@ GNULIB_GETDELIM = @GNULIB_GETDELIM@ GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@ GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@ +GNULIB_GETENTROPY = @GNULIB_GETENTROPY@ GNULIB_GETGROUPS = @GNULIB_GETGROUPS@ GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@ GNULIB_GETLINE = @GNULIB_GETLINE@ @@ -320,6 +321,7 @@ GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@ GNULIB_GETOPT_POSIX = @GNULIB_GETOPT_POSIX@ GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@ GNULIB_GETPASS = @GNULIB_GETPASS@ +GNULIB_GETRANDOM = @GNULIB_GETRANDOM@ GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@ @@ -565,12 +567,14 @@ HAVE_FTELLO = @HAVE_FTELLO@ HAVE_FTRUNCATE = @HAVE_FTRUNCATE@ HAVE_FUTIMENS = @HAVE_FUTIMENS@ HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@ +HAVE_GETENTROPY = @HAVE_GETENTROPY@ HAVE_GETGROUPS = @HAVE_GETGROUPS@ HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@ HAVE_GETLOGIN = @HAVE_GETLOGIN@ HAVE_GETOPT_H = @HAVE_GETOPT_H@ HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ HAVE_GETPASS = @HAVE_GETPASS@ +HAVE_GETRANDOM = @HAVE_GETRANDOM@ HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ HAVE_GRANTPT = @HAVE_GRANTPT@ @@ -667,6 +671,7 @@ HAVE_SYS_CDEFS_H = @HAVE_SYS_CDEFS_H@ HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_RANDOM_H = @HAVE_SYS_RANDOM_H@ HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@ HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ @@ -753,6 +758,7 @@ LIB_ACL = @LIB_ACL@ LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ LIB_EACCESS = @LIB_EACCESS@ LIB_EXECINFO = @LIB_EXECINFO@ +LIB_GETRANDOM = @LIB_GETRANDOM@ LIB_MATH = @LIB_MATH@ LIB_PTHREAD = @LIB_PTHREAD@ LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ @@ -782,6 +788,7 @@ NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@ NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@ NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H@ NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@ NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@ NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@ @@ -800,6 +807,7 @@ NEXT_STDINT_H = @NEXT_STDINT_H@ NEXT_STDIO_H = @NEXT_STDIO_H@ NEXT_STDLIB_H = @NEXT_STDLIB_H@ NEXT_STRING_H = @NEXT_STRING_H@ +NEXT_SYS_RANDOM_H = @NEXT_SYS_RANDOM_H@ NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@ NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@ NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ @@ -884,6 +892,7 @@ REPLACE_GETLINE = @REPLACE_GETLINE@ REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ REPLACE_GETPASS = @REPLACE_GETPASS@ +REPLACE_GETRANDOM = @REPLACE_GETRANDOM@ REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ REPLACE_GMTIME = @REPLACE_GMTIME@ REPLACE_INITSTATE = @REPLACE_INITSTATE@ @@ -1003,6 +1012,7 @@ UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@ UNEXEC_OBJ = @UNEXEC_OBJ@ UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@ +UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@ UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ USE_ACL = @USE_ACL@ @@ -1072,7 +1082,6 @@ gamegroup = @gamegroup@ gameuser = @gameuser@ gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7 = @gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7@ gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9 = @gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9@ -gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467 = @gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467@ gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = @gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b@ gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = @gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@ gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c = @gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c@ @@ -1086,7 +1095,6 @@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ gl_GNULIB_ENABLED_lchmod = @gl_GNULIB_ENABLED_lchmod@ gl_GNULIB_ENABLED_malloca = @gl_GNULIB_ENABLED_malloca@ -gl_GNULIB_ENABLED_open = @gl_GNULIB_ENABLED_open@ gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@ gl_GNULIB_ENABLED_utimens = @gl_GNULIB_ENABLED_utimens@ gl_LIBOBJS = @gl_LIBOBJS@ @@ -1831,6 +1839,17 @@ EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c endif ## end gnulib module getopt-posix +## begin gnulib module getrandom +ifeq (,$(OMIT_GNULIB_MODULE_getrandom)) + + +EXTRA_DIST += getrandom.c + +EXTRA_libgnu_a_SOURCES += getrandom.c + +endif +## end gnulib module getrandom + ## begin gnulib module gettext-h ifeq (,$(OMIT_GNULIB_MODULE_gettext-h)) @@ -1988,9 +2007,7 @@ endif ## begin gnulib module libc-config ifeq (,$(OMIT_GNULIB_MODULE_libc-config)) -ifneq (,$(gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467)) -endif EXTRA_DIST += cdefs.h libc-config.h endif @@ -2151,9 +2168,7 @@ endif ## begin gnulib module open ifeq (,$(OMIT_GNULIB_MODULE_open)) -ifneq (,$(gl_GNULIB_ENABLED_open)) -endif EXTRA_DIST += open.c EXTRA_libgnu_a_SOURCES += open.c @@ -2906,6 +2921,40 @@ EXTRA_libgnu_a_SOURCES += symlink.c endif ## end gnulib module symlink +## begin gnulib module sys_random +ifeq (,$(OMIT_GNULIB_MODULE_sys_random)) + +BUILT_SOURCES += sys/random.h + +# We need the following in order to create <sys/random.h> when the system +# doesn't have one. +sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_SYS_RANDOM_H''@|$(NEXT_SYS_RANDOM_H)|g' \ + -e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \ + -e 's/@''GNULIB_GETRANDOM''@/$(GNULIB_GETRANDOM)/g' \ + -e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \ + -e 's/@''REPLACE_GETRANDOM''@/$(REPLACE_GETRANDOM)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/sys_random.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +MOSTLYCLEANFILES += sys/random.h sys/random.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_random.in.h + +endif +## end gnulib module sys_random + ## begin gnulib module sys_select ifeq (,$(OMIT_GNULIB_MODULE_sys_select)) @@ -3246,6 +3295,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ + -e 's/@''GNULIB_GETENTROPY''@/$(GNULIB_GETENTROPY)/g' \ -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ @@ -3294,6 +3344,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ + -e 's|@''HAVE_GETENTROPY''@|$(HAVE_GETENTROPY)|g' \ -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ @@ -3363,6 +3414,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \ -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \ -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \ + -e 's|@''UNISTD_H_HAVE_SYS_RANDOM_H''@|$(UNISTD_H_HAVE_SYS_RANDOM_H)|g' \ -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \ -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ diff --git a/lib/libc-config.h b/lib/libc-config.h index 124f1d77e01..1300c3a2ac8 100644 --- a/lib/libc-config.h +++ b/lib/libc-config.h @@ -180,4 +180,5 @@ /* A substitute for glibc <shlib-compat.h>, good enough for Gnulib. */ #define SHLIB_COMPAT(lib, introduced, obsoleted) 0 -#define versioned_symbol(lib, local, symbol, version) +#define compat_symbol(lib, local, symbol, version) extern int dummy +#define versioned_symbol(lib, local, symbol, version) extern int dummy diff --git a/lib/open.c b/lib/open.c index bb180fde292..751b42d7dcf 100644 --- a/lib/open.c +++ b/lib/open.c @@ -124,7 +124,7 @@ open (const char *filename, int flags, ...) #endif fd = orig_open (filename, - flags & ~(have_cloexec <= 0 ? O_CLOEXEC : 0), mode); + flags & ~(have_cloexec < 0 ? O_CLOEXEC : 0), mode); if (flags & O_CLOEXEC) { diff --git a/lib/openat-proc.c b/lib/openat-proc.c index 9111cd3d7ee..b5aaee8b1d3 100644 --- a/lib/openat-proc.c +++ b/lib/openat-proc.c @@ -73,8 +73,9 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) problem is exhibited on code that built on Solaris 8 and running on Solaris 10. */ - int proc_self_fd = open ("/proc/self/fd", - O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); + int proc_self_fd = + open ("/proc/self/fd", + O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK | O_CLOEXEC); if (proc_self_fd < 0) proc_status = -1; else diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h new file mode 100644 index 00000000000..f14ac1f5723 --- /dev/null +++ b/lib/sys_random.in.h @@ -0,0 +1,92 @@ +/* Substitute for <sys/random.h>. + Copyright (C) 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, 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 <https://www.gnu.org/licenses/>. */ + +# if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +# endif +@PRAGMA_COLUMNS@ + +#ifndef _@GUARD_PREFIX@_SYS_RANDOM_H + +#if @HAVE_SYS_RANDOM_H@ + +/* On Mac OS X 10.5, <sys/random.h> assumes prior inclusion of <sys/types.h>. + On Max OS X 10.13, <sys/random.h> assumes prior inclusion of a file that + includes <Availability.h>, such as <stdlib.h> or <unistd.h>. */ +# if defined __APPLE__ && defined __MACH__ /* Mac OS X */ +# include <sys/types.h> +# include <stdlib.h> +# endif + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYS_RANDOM_H@ + +#endif + +#ifndef _@GUARD_PREFIX@_SYS_RANDOM_H +#define _@GUARD_PREFIX@_SYS_RANDOM_H + +#include <sys/types.h> + +/* Define the GRND_* constants. */ +#ifndef GRND_NONBLOCK +# define GRND_NONBLOCK 1 +# define GRND_RANDOM 2 +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Declare overridden functions. */ + + +#if @GNULIB_GETRANDOM@ +/* Fill a buffer with random bytes. */ +# if @REPLACE_GETRANDOM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getrandom +# define getrandom rpl_getrandom +# endif +_GL_FUNCDECL_RPL (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags)); +# else +# if !@HAVE_GETRANDOM@ +_GL_FUNCDECL_SYS (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags)); +# endif +_GL_CXXALIASWARN (getrandom); +#elif defined GNULIB_POSIXCHECK +# undef getrandom +# if HAVE_RAW_DECL_GETRANDOM +_GL_WARN_ON_USE (getrandom, "getrandom is unportable - " + "use gnulib module getrandom for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_RANDOM_H */ +#endif /* _@GUARD_PREFIX@_SYS_RANDOM_H */ diff --git a/lib/tempname.c b/lib/tempname.c index 0aad0616c85..cfb0fc42eca 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -1,24 +1,22 @@ -/* tempname.c - generate the name of a temporary file. +/* Copyright (C) 1991-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. - Copyright (C) 1991-2003, 2005-2007, 2009-2020 Free Software Foundation, Inc. + The GNU C Library 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 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, + The GNU C Library 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 <https://www.gnu.org/licenses/>. */ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. -/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */ + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ #if !_LIBC -# include <config.h> +# include <libc-config.h> # include "tempname.h" #endif @@ -26,9 +24,6 @@ #include <assert.h> #include <errno.h> -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif #include <stdio.h> #ifndef P_tmpdir @@ -52,51 +47,39 @@ #include <string.h> #include <fcntl.h> -#include <sys/time.h> #include <stdint.h> -#include <unistd.h> - +#include <sys/random.h> #include <sys/stat.h> #if _LIBC # define struct_stat64 struct stat64 +# define __secure_getenv __libc_secure_getenv #else # define struct_stat64 struct stat -# define __try_tempname try_tempname # define __gen_tempname gen_tempname -# define __getpid getpid -# define __gettimeofday gettimeofday # define __mkdir mkdir # define __open open # define __lxstat64(version, file, buf) lstat (file, buf) #endif #ifdef _LIBC -# include <hp-timing.h> -# if HP_TIMING_AVAIL -# define RANDOM_BITS(Var) \ - if (__builtin_expect (value == UINT64_C (0), 0)) \ - { \ - /* If this is the first time this function is used initialize \ - the variable we accumulate the value in to some somewhat \ - random value. If we'd not do this programs at startup time \ - might have a reduced set of possible names, at least on slow \ - machines. */ \ - struct timeval tv; \ - __gettimeofday (&tv, NULL); \ - value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ - } \ - HP_TIMING_NOW (Var) -# endif -#endif - -/* Use the widest available unsigned type if uint64_t is not - available. The algorithm below extracts a number less than 62**6 - (approximately 2**35.725) from uint64_t, so ancient hosts where - uintmax_t is only 32 bits lose about 3.725 bits of randomness, - which is better than not having mkstemp at all. */ -#if !defined UINT64_MAX && !defined uint64_t -# define uint64_t uintmax_t +# include <random-bits.h> +# define RANDOM_BITS(Var) ((Var) = random_bits ()) +typedef uint32_t random_value; +# define RANDOM_VALUE_MAX UINT32_MAX +# define BASE_62_DIGITS 5 /* 62**5 < UINT32_MAX */ +# define BASE_62_POWER (62 * 62 * 62 * 62 * 62) /* 2**BASE_62_DIGITS */ +#else +/* Use getrandom if it works, falling back on a 64-bit linear + congruential generator that starts with whatever Var's value + happens to be. */ +# define RANDOM_BITS(Var) \ + ((void) (getrandom (&(Var), sizeof (Var), 0) == sizeof (Var) \ + || ((Var) = 2862933555777941757 * (Var) + 3037000493))) +typedef uint_fast64_t random_value; +# define RANDOM_VALUE_MAX UINT_FAST64_MAX +# define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */ +# define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) #endif #if _LIBC @@ -172,18 +155,80 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, } #endif /* _LIBC */ +#if _LIBC +static int try_tempname_len (char *, int, void *, int (*) (char *, void *), + size_t); +#endif + +static int +try_file (char *tmpl, void *flags) +{ + int *openflags = flags; + return __open (tmpl, + (*openflags & ~O_ACCMODE) + | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); +} + +static int +try_dir (char *tmpl, void *flags _GL_UNUSED) +{ + return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); +} + +static int +try_nocreate (char *tmpl, void *flags _GL_UNUSED) +{ + struct_stat64 st; + + if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW) + __set_errno (EEXIST); + return errno == ENOENT ? 0 : -1; +} + /* These are the characters used in temporary file names. */ static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; +/* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e., end in at least X_SUFFIX_LEN "X"s, + possibly with a suffix). + The name constructed does not exist at the time of the call to + this function. TMPL is overwritten with the result. + + KIND may be one of: + __GT_NOCREATE: simply verify that the name does not exist + at the time of the call. + __GT_FILE: create the file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. + __GT_DIR: create a directory, which will be mode 0700. + + We use a clever algorithm to get hard-to-predict names. */ +#ifdef _LIBC +static +#endif int -__try_tempname (char *tmpl, int suffixlen, void *args, - int (*tryfunc) (char *, void *)) +gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind, + size_t x_suffix_len) { - int len; + static int (*const tryfunc[]) (char *, void *) = + { + [__GT_FILE] = try_file, + [__GT_DIR] = try_dir, + [__GT_NOCREATE] = try_nocreate + }; + return try_tempname_len (tmpl, suffixlen, &flags, tryfunc[kind], + x_suffix_len); +} + +#ifdef _LIBC +static +#endif +int +try_tempname_len (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *), size_t x_suffix_len) +{ + size_t len; char *XXXXXX; - static uint64_t value; - uint64_t random_time_bits; unsigned int count; int fd = -1; int save_errno = errno; @@ -193,7 +238,8 @@ __try_tempname (char *tmpl, int suffixlen, void *args, can exist for a given template is 62**6. It should never be necessary to try all of these combinations. Instead if a reasonable number of names is tried (we define reasonable as 62**3) fail to - give the system administrator the chance to remove the problems. */ + give the system administrator the chance to remove the problems. + This value requires that X_SUFFIX_LEN be at least 3. */ #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary file. To @@ -204,44 +250,45 @@ __try_tempname (char *tmpl, int suffixlen, void *args, unsigned int attempts = ATTEMPTS_MIN; #endif + /* A random variable. */ + random_value v; + + /* How many random base-62 digits can currently be extracted from V. */ + int vdigits = 0; + + /* Least unfair value for V. If V is less than this, V can generate + BASE_62_DIGITS digits fairly. Otherwise it might be biased. */ + random_value const unfair_min + = RANDOM_VALUE_MAX - RANDOM_VALUE_MAX % BASE_62_POWER; + len = strlen (tmpl); - if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) + if (len < x_suffix_len + suffixlen + || strspn (&tmpl[len - x_suffix_len - suffixlen], "X") < x_suffix_len) { __set_errno (EINVAL); return -1; } /* This is where the Xs start. */ - XXXXXX = &tmpl[len - 6 - suffixlen]; - - /* Get some more or less random data. */ -#ifdef RANDOM_BITS - RANDOM_BITS (random_time_bits); -#else - { - struct timeval tv; - __gettimeofday (&tv, NULL); - random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; - } -#endif - value += random_time_bits ^ __getpid (); + XXXXXX = &tmpl[len - x_suffix_len - suffixlen]; - for (count = 0; count < attempts; value += 7777, ++count) + for (count = 0; count < attempts; ++count) { - uint64_t v = value; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % 62]; - v /= 62; - XXXXXX[1] = letters[v % 62]; - v /= 62; - XXXXXX[2] = letters[v % 62]; - v /= 62; - XXXXXX[3] = letters[v % 62]; - v /= 62; - XXXXXX[4] = letters[v % 62]; - v /= 62; - XXXXXX[5] = letters[v % 62]; + for (size_t i = 0; i < x_suffix_len; i++) + { + if (vdigits == 0) + { + do + RANDOM_BITS (v); + while (unfair_min <= v); + + vdigits = BASE_62_DIGITS; + } + + XXXXXX[i] = letters[v % 62]; + v /= 62; + vdigits--; + } fd = tryfunc (tmpl, args); if (fd >= 0) @@ -258,66 +305,17 @@ __try_tempname (char *tmpl, int suffixlen, void *args, return -1; } -static int -try_file (char *tmpl, void *flags) -{ - int *openflags = flags; - return __open (tmpl, - (*openflags & ~O_ACCMODE) - | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); -} - -static int -try_dir (char *tmpl, void *flags _GL_UNUSED) -{ - return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); -} - -static int -try_nocreate (char *tmpl, void *flags _GL_UNUSED) +int +__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) { - struct_stat64 st; - - if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW) - __set_errno (EEXIST); - return errno == ENOENT ? 0 : -1; + return gen_tempname_len (tmpl, suffixlen, flags, kind, 6); } -/* Generate a temporary file name based on TMPL. TMPL must match the - rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). - The name constructed does not exist at the time of the call to - __gen_tempname. TMPL is overwritten with the result. - - KIND may be one of: - __GT_NOCREATE: simply verify that the name does not exist - at the time of the call. - __GT_FILE: create the file using open(O_CREAT|O_EXCL) - and return a read-write fd. The file is mode 0600. - __GT_DIR: create a directory, which will be mode 0700. - - We use a clever algorithm to get hard-to-predict names. */ +#if !_LIBC int -__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) +try_tempname (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *)) { - int (*tryfunc) (char *, void *); - - switch (kind) - { - case __GT_FILE: - tryfunc = try_file; - break; - - case __GT_DIR: - tryfunc = try_dir; - break; - - case __GT_NOCREATE: - tryfunc = try_nocreate; - break; - - default: - assert (! "invalid KIND in __gen_tempname"); - abort (); - } - return __try_tempname (tmpl, suffixlen, &flags, tryfunc); + return try_tempname_len (tmpl, suffixlen, args, tryfunc, 6); } +#endif diff --git a/lib/tempname.h b/lib/tempname.h index abb92650827..00dcbe4c93b 100644 --- a/lib/tempname.h +++ b/lib/tempname.h @@ -50,6 +50,9 @@ extern "C" { We use a clever algorithm to get hard-to-predict names. */ extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind); +/* Similar, except X_SUFFIX_LEN gives the number of Xs. */ +extern int gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind, + size_t x_suffix_len); /* Similar to gen_tempname, but TRYFUNC is called for each temporary name to try. If TRYFUNC returns a non-negative number, TRY_GEN_TEMPNAME @@ -57,6 +60,10 @@ extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind); name is tried, or else TRY_GEN_TEMPNAME returns -1. */ extern int try_tempname (char *tmpl, int suffixlen, void *args, int (*tryfunc) (char *, void *)); +/* Similar, except X_SUFFIX_LEN gives the number of Xs. */ +extern int try_tempname_len (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *), + size_t x_suffix_len); #ifdef __cplusplus } diff --git a/lib/unistd.in.h b/lib/unistd.in.h index c9b9ac95821..b211e4d61f7 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -118,6 +118,17 @@ # include <netdb.h> #endif +/* Mac OS X 10.13, Solaris 11.4, and Android 9.0 declare getentropy in + <sys/random.h>, not in <unistd.h>. */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_GETENTROPY@ || defined GNULIB_POSIXCHECK) \ + && ((defined __APPLE__ && defined __MACH__) || defined __sun \ + || defined __ANDROID__) \ + && @UNISTD_H_HAVE_SYS_RANDOM_H@ \ + && !defined __GLIBC__ +# include <sys/random.h> +#endif + /* Android 4.3 declares fchownat in <sys/stat.h>, not in <unistd.h>. */ /* But avoid namespace pollution on glibc systems. */ #if (@GNULIB_FCHOWNAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \ @@ -763,6 +774,22 @@ _GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - " #endif +#if @GNULIB_GETENTROPY@ +/* Fill a buffer with random bytes. */ +# if !@HAVE_GETENTROPY@ +_GL_FUNCDECL_SYS (getentropy, int, (void *buffer, size_t length)); +# endif +_GL_CXXALIAS_SYS (getentropy, int, (void *buffer, size_t length)); +_GL_CXXALIASWARN (getentropy); +#elif defined GNULIB_POSIXCHECK +# undef getentropy +# if HAVE_RAW_DECL_GETENTROPY +_GL_WARN_ON_USE (getentropy, "getentropy is unportable - " + "use gnulib module getentropy for portability"); +# endif +#endif + + #if @GNULIB_GETGROUPS@ /* Return the supplemental groups that the current process belongs to. It is unspecified whether the effective group id is in the list. diff --git a/lib/verify.h b/lib/verify.h index d9ab89a570c..f1097612704 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -277,10 +277,22 @@ template <int w> #endif /* Assume that R always holds. Behavior is undefined if R is false, - fails to evaluate, or has side effects. Although assuming R can - help a compiler generate better code or diagnostics, performance - can suffer if R uses hard-to-optimize features such as function - calls not inlined by the compiler. */ + fails to evaluate, or has side effects. + + 'assume (R)' is a directive from the programmer telling the + compiler that R is true so the compiler needn't generate code to + test R. This is why 'assume' is in verify.h: it's related to + static checking (in this case, static checking done by the + programmer), not dynamic checking. + + 'assume (R)' can affect compilation of all the code, not just code + that happens to be executed after the assume (R) is "executed". + For example, if the code mistakenly does 'assert (R); assume (R);' + the compiler is entitled to optimize away the 'assert (R)'. + + Although assuming R can help a compiler generate better code or + diagnostics, performance can suffer if R uses hard-to-optimize + features such as function calls not inlined by the compiler. */ #if _GL_HAS_BUILTIN_UNREACHABLE # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el index 25961d41089..4af3d631a2c 100644 --- a/lisp/autoinsert.el +++ b/lisp/autoinsert.el @@ -396,7 +396,7 @@ Matches the visited file name against the elements of `auto-insert-alist'." ;; which might ask the user for something (switch-to-buffer (current-buffer)) (if (and (consp action) - (not (eq (car action) 'lambda))) + (not (functionp action))) (skeleton-insert action) (funcall action))))) (if (vectorp action) diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index e3037a71901..4c1a1797adc 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -348,6 +348,7 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called." (setq acc (funcall function acc elt))) acc))) +;;;###autoload (cl-defgeneric seq-every-p (pred sequence) "Return non-nil if (PRED element) is non-nil for all elements of SEQUENCE." (catch 'seq--break diff --git a/lisp/frame.el b/lisp/frame.el index 6c2f774709e..77080b76e4f 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1070,6 +1070,22 @@ that variable should be nil." (setq arg (1+ arg))) (select-frame-set-input-focus frame))) +(defun other-frame-prefix () + "Display the buffer of the next command in a new frame. +The next buffer is the buffer displayed by the next command invoked +immediately after this command (ignoring reading from the minibuffer). +Creates a new frame before displaying the buffer. +When `switch-to-buffer-obey-display-actions' is non-nil, +`switch-to-buffer' commands are also supported." + (interactive) + (display-buffer-override-next-command + (lambda (buffer alist) + (cons (display-buffer-pop-up-frame + buffer (append '((inhibit-same-window . t)) + alist)) + 'frame))) + (message "Display next command buffer in a new frame...")) + (defun iconify-or-deiconify-frame () "Iconify the selected frame, or deiconify if it's currently an icon." (interactive) @@ -2697,6 +2713,7 @@ See also `toggle-frame-maximized'." (define-key ctl-x-5-map "1" 'delete-other-frames) (define-key ctl-x-5-map "0" 'delete-frame) (define-key ctl-x-5-map "o" 'other-frame) +(define-key ctl-x-5-map "5" 'other-frame-prefix) (define-key global-map [f11] 'toggle-frame-fullscreen) (define-key global-map [(meta f10)] 'toggle-frame-maximized) (define-key esc-map [f10] 'toggle-frame-maximized) diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index 5028da5e8df..673a4d22988 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el @@ -478,8 +478,7 @@ Otherwise, returns the Gnus Cloud data chunks." (push (gnus-cloud-parse-chunk) chunks) (forward-line 1)))) (if update - (progn - (mapc #'gnus-cloud-update-all chunks) + (prog1 (mapcar #'gnus-cloud-update-all chunks) (setq gnus-cloud-sequence highest-sequence-seen)) chunks))) diff --git a/lisp/info.el b/lisp/info.el index d579ecc5a3b..78f88947c79 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -2265,7 +2265,8 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat." (match-string-no-properties 1))) (defun Info-next () - "Go to the next node of this node." + "Go to the \"next\" node, staying on the same hierarchical level. +This command doesn't descend into sub-nodes, like \\<Info-mode-map>\\[Info-forward-node] does." (interactive) ;; In case another window is currently selected (save-window-excursion @@ -2273,7 +2274,8 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat." (Info-goto-node (Info-extract-pointer "next")))) (defun Info-prev () - "Go to the previous node of this node." + "Go to the \"previous\" node, staying on the same hierarchical level. +This command doesn't go up to the parent node, like \\<Info-mode-map>\\[Info-backward-node] does." (interactive) ;; In case another window is currently selected (save-window-excursion @@ -2887,7 +2889,13 @@ N is the digit argument used to invoke this command." (Info-goto-node (Info-extract-menu-counting nil))))) (defun Info-forward-node (&optional not-down not-up no-error) - "Go forward one node, considering all nodes as forming one sequence." + "Go forward one node, considering all nodes as forming one sequence. +Interactively, if the current node has sub-nodes, descend into the first +sub-node; otherwise go to the \"next\" node, if it exists, else go \"up\" +to the parent node. +When called from Lisp, NOT-DOWN non-nil means don't descend into sub-nodes, +NOT-UP non-nil means don't go to parent nodes, and NO-ERROR non-nil means +don't signal a user-error if there's no node to go to." (interactive) (goto-char (point-min)) (forward-line 1) @@ -2922,7 +2930,9 @@ N is the digit argument used to invoke this command." (t (user-error "No pointer forward from this node"))))) (defun Info-backward-node () - "Go backward one node, considering all nodes as forming one sequence." + "Go backward one node, considering all nodes as forming one sequence. +If the current node has a \"previous\" node, go to it, descending into its +last sub-node, if any; otherwise go \"up\" to the parent node." (interactive) (let ((prevnode (Info-extract-pointer "prev[ious]*" t)) (upnode (Info-extract-pointer "up" t)) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 9bc667acd61..bc094c9050d 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -1815,6 +1815,10 @@ mail status in mode line")) (bindings--define-key menu [list-keybindings] '(menu-item "List Key Bindings" describe-bindings :help "Display all current key bindings (keyboard shortcuts)")) + (bindings--define-key menu [list-recent-keystrokes] + '(menu-item "Show Recent Inputs" view-lossage + :help "Display last few input events and the commands \ +they ran")) (bindings--define-key menu [describe-current-display-table] '(menu-item "Describe Display Table" describe-current-display-table :help "Describe the current display table")) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 357e9a220ce..947e6a767c7 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -704,11 +704,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (delete nil (mapcar (lambda (x) (when (string-match-p match x) x)) result)))) - ;; Append directory. + ;; Prepend directory. (when full (setq result (mapcar - (lambda (x) (format "%s/%s" directory x)) + (lambda (x) (format "%s/%s" (directory-file-name directory) x)) result))) ;; Sort them if necessary. (unless nosort (setq result (sort result #'string-lessp))) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 8c8296fd6da..888184d2b46 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -3137,7 +3137,7 @@ comment at the start of cc-engine.el for more info." (not base) ; FIXME!!! Compare base and far-base?? ; (2019-05-21) (not end) - (> here end)) + (>= here end)) (progn (setq far-base-and-state (c-parse-ps-state-below here) far-base (car far-base-and-state) @@ -3150,7 +3150,7 @@ comment at the start of cc-engine.el for more info." (or (and (> here base) (null end)) (null (nth 8 s)) - (and end (> here end)) + (and end (>= here end)) (not (or (and (nth 3 s) ; string diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 3ac4aad90b8..00babf95332 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -2787,7 +2787,7 @@ Keywords here should also be in `c-block-stmt-1-kwds'." java '("for" "if" "switch" "while" "catch" "synchronized") idl nil pike '("for" "if" "switch" "while" "foreach") - awk '("for" "if" "while")) + awk '("for" "if" "switch" "while")) (c-lang-defconst c-block-stmt-2-key ;; Regexp matching the start of any statement followed by a paren sexp @@ -2867,8 +2867,7 @@ nevertheless contains a list separated with `;' and not `,'." (c-lang-defconst c-case-kwds "The keyword(s) which introduce a \"case\" like construct. This construct is \"<keyword> <expression> :\"." - t '("case") - awk nil) + t '("case")) (c-lang-defconst c-case-kwds-regexp ;; Adorned regexp matching any "case"-like keyword. diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el index 536a16dbb3c..fce059bafc7 100644 --- a/lisp/progmodes/pascal.el +++ b/lisp/progmodes/pascal.el @@ -589,7 +589,7 @@ See also `pascal-comment-area'." (interactive) (catch 'found (if (not (looking-at (concat "\\s \\|\\s)\\|" pascal-defun-re))) - (forward-sexp 1)) + (ignore-errors (forward-sexp 1))) (let ((nest 0) (max -1) (func 0) (reg (concat pascal-beg-block-re "\\|" pascal-end-block-re "\\|" @@ -1170,26 +1170,27 @@ indent of the current line in parameterlist." (defun pascal-type-completion (pascal-str) "Calculate all possible completions for types." - (let ((start (point)) - (pascal-all ()) - goon) - ;; Search for all reachable type declarations - (while (or (pascal-beg-of-defun) - (setq goon (not goon))) - (save-excursion - (if (and (< start (prog1 (save-excursion (pascal-end-of-defun) - (point)) - (forward-char 1))) - (re-search-forward - "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>" - start t) - (not (match-end 1))) - ;; Check current type declaration - (setq pascal-all - (nconc (pascal-get-completion-decl pascal-str) - pascal-all))))) + (save-excursion + (let ((start (point)) + (pascal-all ()) + goon) + ;; Search for all reachable type declarations + (while (or (pascal-beg-of-defun) + (setq goon (not goon))) + (save-excursion + (if (and (< start (prog1 (save-excursion (pascal-end-of-defun) + (point)) + (forward-char 1))) + (re-search-forward + "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>" + start t) + (not (match-end 1))) + ;; Check current type declaration + (setq pascal-all + (nconc (pascal-get-completion-decl pascal-str) + pascal-all))))) - pascal-all)) + pascal-all))) (defun pascal-var-completion (prefix) "Calculate all possible completions for variables (or constants)." @@ -1263,11 +1264,13 @@ indent of the current line in parameterlist." (and (eq state 'defun) (save-excursion (re-search-backward ")[ \t]*:" (point-at-bol) t)))) - (if (or (eq state 'paramlist) (eq state 'defun)) - (pascal-beg-of-defun)) - (nconc - (pascal-type-completion pascal-str) - (pascal-keyword-completion pascal-type-keywords pascal-str))) + (save-excursion + (if (or (eq state 'paramlist) (eq state 'defun)) + (pascal-beg-of-defun)) + (nconc + (pascal-type-completion pascal-str) + (pascal-keyword-completion pascal-type-keywords + pascal-str)))) ( ;--Starting a new statement (and (not (eq state 'contexp)) (save-excursion diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index bfbe2362721..0a15939d243 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -449,7 +449,7 @@ backend implementation of `project-external-roots'.") (cl-defmethod project-ignores ((project (head vc)) dir) (let* ((root (cdr project)) - backend) + backend) (append (when (file-equal-p dir root) (setq backend (vc-responsible-backend root)) @@ -674,8 +674,8 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in (let* ((all-files (project-files project dirs)) (completion-ignore-case read-file-name-completion-ignore-case) (file (funcall project-read-file-name-function - "Find file" all-files nil nil - filename))) + "Find file" all-files nil nil + filename))) (if (string= file "") (user-error "You didn't specify the file") (find-file file)))) @@ -719,7 +719,7 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in If a buffer already exists for running a shell in the project's root, switch to it. Otherwise, create a new shell buffer. With \\[universal-argument] prefix arg, create a new inferior shell buffer even -if one already exist." +if one already exists." (interactive) (let* ((default-directory (project-root (project-current t))) (default-project-shell-name @@ -738,14 +738,15 @@ if one already exist." If a buffer already exists for running Eshell in the project's root, switch to it. Otherwise, create a new Eshell buffer. With \\[universal-argument] prefix arg, create a new Eshell buffer even -if one already exist." +if one already exists." (interactive) + (defvar eshell-buffer-name) (let* ((default-directory (project-root (project-current t))) (eshell-buffer-name - (concat "*" (file-name-nondirectory - (directory-file-name - (file-name-directory default-directory))) - "-eshell*")) + (concat "*" (file-name-nondirectory + (directory-file-name + (file-name-directory default-directory))) + "-eshell*")) (eshell-buffer (get-buffer eshell-buffer-name))) (if (and eshell-buffer (not current-prefix-arg)) (pop-to-buffer eshell-buffer) @@ -809,7 +810,8 @@ is inside the directory hierarchy of the project's root." (predicate (lambda (buffer) ;; BUFFER is an entry (BUF-NAME . BUF-OBJ) of Vbuffer_alist. - (and (not (eq (cdr buffer) current-buffer)) + (and (cdr buffer) + (not (eq (cdr buffer) current-buffer)) (when-let ((file (buffer-local-value 'default-directory (cdr buffer)))) (file-in-directory-p file root)))))) @@ -818,10 +820,10 @@ is inside the directory hierarchy of the project's root." "Switch to buffer: " (when (funcall predicate (cons other-name other-buffer)) other-name) - t + nil predicate)))) -(defcustom project-kill-buffers-skip-conditions +(defcustom project-kill-buffers-ignores '("\\*Help\\*") "Conditions for buffers `project-kill-buffers' should not kill. Each condition is either a regular expression matching a buffer @@ -829,7 +831,8 @@ name, or a predicate function that takes a buffer object as argument and returns non-nil if it matches. Buffers that match any of the conditions will not be killed." :type '(repeat (choice regexp function)) - :version "28.1") + :version "28.1" + :package-version '(project . "0.5.0")) (defun project--buffer-list (pr) "Return the list of all buffers in project PR." @@ -845,7 +848,7 @@ any of the conditions will not be killed." ;;;###autoload (defun project-kill-buffers () "Kill all live buffers belonging to the current project. -Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'." +Certain buffers may be \"spared\", see `project-kill-buffers-ignores'." (interactive) (let ((pr (project-current t)) bufs) (dolist (buf (project--buffer-list pr)) @@ -855,7 +858,7 @@ Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'." (string-match-p c (buffer-name buf))) ((functionp c) (funcall c buf)))) - project-kill-buffers-skip-conditions) + project-kill-buffers-ignores) (push buf bufs))) (when (yes-or-no-p (format "Kill %d buffers in %s? " (length bufs) (project-root pr))) @@ -871,7 +874,8 @@ Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'." :group 'project) (defvar project--list 'unset - "List of known project directories.") + "List structure containing root directories of known projects. +With some possible metadata (to be decided).") (defun project--read-project-list () "Initialize `project--list' using contents of `project-list-file'." @@ -880,7 +884,13 @@ Certain buffers may be \"spared\", see `project-kill-buffers-skip-conditions'." (when (file-exists-p filename) (with-temp-buffer (insert-file-contents filename) - (read (current-buffer))))))) + (read (current-buffer))))) + (unless (seq-every-p + (lambda (elt) (stringp (car-safe elt))) + project--list) + (warn "Contents of %s are in wrong format, resetting" + project-list-file) + (setq project--list nil)))) (defun project--ensure-read-project-list () "Initialize `project--list' if it isn't already initialized." @@ -933,6 +943,12 @@ It's also possible to enter an arbitrary directory not in the list." (read-directory-name "Select directory: " default-directory nil t) pr-dir))) +;;;###autoload +(defun project-known-project-roots () + "Return the list of root directories of all known projects." + (project--ensure-read-project-list) + (mapcar #'car project--list)) + ;;; Project switching diff --git a/lisp/sort.el b/lisp/sort.el index de0e1b9519d..f878db24a3c 100644 --- a/lisp/sort.el +++ b/lisp/sort.el @@ -554,9 +554,6 @@ is the one that ends before END." (if (> beg end) (let (mid) (setq mid end end beg beg mid))) (save-excursion - (when (or (< (line-beginning-position) beg) - (< end (line-end-position))) - (user-error "There are no full lines in the region")) ;; Put beg at the start of a line and end and the end of one -- ;; the largest possible region which fits this criteria. (goto-char beg) @@ -568,6 +565,8 @@ is the one that ends before END." ;; reversal; it isn't difficult to add it afterward. (or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line))) (setq end (point-marker)) + (when (<= end beg) + (user-error "There are no full lines in the region")) ;; The real work. This thing cranks through memory on large regions. (let (ll (do t)) (while do diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index b54258a4e4a..0a336e41658 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1543,8 +1543,7 @@ Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab." (list (read-buffer-to-switch "Switch to buffer in other tab: "))) (display-buffer (window-normalize-buffer-to-switch-to buffer-or-name) '((display-buffer-in-tab) - (inhibit-same-window . nil) - (reusable-frames . t)) + (inhibit-same-window . nil)) norecord)) (defun find-file-other-tab (filename &optional wildcards) @@ -1575,8 +1574,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, (lambda (buffer alist) (cons (progn (display-buffer-in-tab - buffer (append alist '((inhibit-same-window . nil) - (reusable-frames . t)))) + buffer (append alist '((inhibit-same-window . nil)))) (selected-window)) 'tab))) (message "Display next command buffer in a new tab...")) diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el index 73e2431822e..dda7fcc3691 100644 --- a/lisp/term/tty-colors.el +++ b/lisp/term/tty-colors.el @@ -923,7 +923,7 @@ The returned value reflects the standard Emacs definition of COLOR (see the info node `(emacs) Colors'), regardless of whether the terminal can display it, so the return value should be the same regardless of what display is being used." - (or (internal-color-values-from-color-spec color) + (or (color-values-from-color-spec color) (cdr (assoc color color-name-rgb-alist)))) (defun tty-color-translate (color &optional frame) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index a86c37c24ae..46be9b73801 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -1366,7 +1366,7 @@ These are the commands available for use in the file status buffer: ;; Otherwise if you do C-x v d -> C-x C-f -> C-x v d ;; you may get a new *vc-dir* buffer, different from the original (file-truename (read-directory-name "VC status for directory: " - (vc-root-dir) nil t + (vc-root-dir) (vc-known-roots) t nil)) (if current-prefix-arg (intern @@ -1496,8 +1496,9 @@ This implements the `bookmark-make-record-function' type for This implements the `handler' function interface for the record type returned by `vc-dir-bookmark-make-record'." (let* ((file (bookmark-prop-get bmk 'filename)) - (buf (save-window-excursion - (vc-dir file) (current-buffer)))) + (buf (progn ;; Don't use save-window-excursion (bug#39722) + (vc-dir file) + (current-buffer)))) (bookmark-default-handler `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bmk))))) diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index ce72a49b955..46f55358de8 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -299,6 +299,11 @@ non-nil if FILE exists and its contents were successfully inserted." (set-buffer-modified-p nil) t)) +(declare-function project-try-vc "project") +(defun vc-known-roots () + "Return a list of known vc roots." + (seq-filter #'project-try-vc (project-known-project-roots))) + (defun vc-find-root (file witness) "Find the root of a checked out project. The function walks up the directory tree from FILE looking for WITNESS. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 9b12d449785..49323ef47d2 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1074,11 +1074,9 @@ BEWARE: this function may change the current buffer." (progn ;FIXME: Why not `with-current-buffer'? --Stef. (set-buffer vc-parent-buffer) (vc-deduce-fileset not-state-changing allow-unregistered state-model-only-files))) - ((and (derived-mode-p 'log-view-mode) + ((and (not buffer-file-name) (setq backend (vc-responsible-backend default-directory))) (list backend nil)) - ((not buffer-file-name) - (error "Buffer %s is not associated with a file" (buffer-name))) ((and allow-unregistered (not (vc-registered buffer-file-name))) (if state-model-only-files (list (vc-backend-for-registration (buffer-file-name)) @@ -2003,7 +2001,8 @@ saving the buffer." rootdir working-revision) (if backend (setq rootdir (vc-call-backend backend 'root default-directory)) - (setq rootdir (read-directory-name "Directory for VC root-diff: ")) + (setq rootdir (read-directory-name "Directory for VC root-diff: " + nil (vc-known-roots))) (setq backend (vc-responsible-backend rootdir)) (if backend (setq default-directory rootdir) @@ -2547,7 +2546,8 @@ with its diffs (if the underlying VCS supports that)." rootdir) (if backend (setq rootdir (vc-call-backend backend 'root default-directory)) - (setq rootdir (read-directory-name "Directory for VC revision log: ")) + (setq rootdir (read-directory-name "Directory for VC revision log: " + nil (vc-known-roots))) (setq backend (vc-responsible-backend rootdir)) (unless backend (error "Directory is not version controlled"))) diff --git a/lisp/window.el b/lisp/window.el index 998568e7b82..d499f9ab99a 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4005,6 +4005,43 @@ always effectively nil." ;; Always return nil. nil)))) +(defun other-window-prefix () + "Display the buffer of the next command in a new window. +The next buffer is the buffer displayed by the next command invoked +immediately after this command (ignoring reading from the minibuffer). +Creates a new window before displaying the buffer. +When `switch-to-buffer-obey-display-actions' is non-nil, +`switch-to-buffer' commands are also supported." + (interactive) + (display-buffer-override-next-command + (lambda (buffer alist) + (let ((alist (append '((inhibit-same-window . t)) alist)) + window type) + (if (setq window (display-buffer-pop-up-window buffer alist)) + (setq type 'window) + (setq window (display-buffer-use-some-window buffer alist) + type 'reuse)) + (cons window type)))) + (message "Display next command buffer in a new window...")) + +(defun same-window-prefix () + "Display the buffer of the next command in the same window. +The next buffer is the buffer displayed by the next command invoked +immediately after this command (ignoring reading from the minibuffer). +Even when the default rule should display the buffer in a new window, +force its display in the already selected window. +When `switch-to-buffer-obey-display-actions' is non-nil, +`switch-to-buffer' commands are also supported." + (interactive) + (display-buffer-override-next-command + (lambda (buffer alist) + (setq alist (append '((inhibit-same-window . nil)) alist)) + (cons (or + (display-buffer-same-window buffer alist) + (display-buffer-use-some-window buffer alist)) + 'reuse))) + (message "Display next command buffer in the same window...")) + ;; This should probably return non-nil when the selected window is part ;; of an atomic window whose root is the frame's root window. (defun one-window-p (&optional nomini all-frames) @@ -8590,19 +8627,24 @@ window; the function takes two arguments: an old and new window." (let* ((old-window (or (minibuffer-selected-window) (selected-window))) (new-window nil) (minibuffer-depth (minibuffer-depth)) + (clearfun (make-symbol "clear-display-buffer-overriding-action")) (action (lambda (buffer alist) (unless (> (minibuffer-depth) minibuffer-depth) (let* ((ret (funcall pre-function buffer alist)) (window (car ret)) (type (cdr ret))) (setq new-window (window--display-buffer buffer window - type alist)))))) + type alist)) + ;; Reset display-buffer-overriding-action + ;; after the first buffer display action + (funcall clearfun) + (setq post-function nil) + new-window)))) (command this-command) - (clearfun (make-symbol "clear-display-buffer-overriding-action")) (exitfun (lambda () - (setq display-buffer-overriding-action - (delq action display-buffer-overriding-action)) + (setcar display-buffer-overriding-action + (delq action (car display-buffer-overriding-action))) (remove-hook 'post-command-hook clearfun) (when (functionp post-function) (funcall post-function old-window new-window))))) @@ -8616,8 +8658,10 @@ window; the function takes two arguments: an old and new window." ;; adding the hook by the same command below. (eq this-command command)) (funcall exitfun)))) + ;; Reset display-buffer-overriding-action + ;; after the next command finishes (add-hook 'post-command-hook clearfun) - (push action display-buffer-overriding-action))) + (push action (car display-buffer-overriding-action)))) (defun set-window-text-height (window height) @@ -10124,5 +10168,6 @@ displaying that processes's buffer." (define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer) (define-key ctl-x-map "+" 'balance-windows) (define-key ctl-x-4-map "0" 'kill-buffer-and-window) +(define-key ctl-x-4-map "4" 'other-window-prefix) ;;; window.el ends here diff --git a/m4/getrandom.m4 b/m4/getrandom.m4 new file mode 100644 index 00000000000..37fb10023a0 --- /dev/null +++ b/m4/getrandom.m4 @@ -0,0 +1,64 @@ +# getrandom.m4 serial 5 +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. + +dnl Written by Paul Eggert. + +AC_DEFUN([gl_FUNC_GETRANDOM], +[ + AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([getrandom]) + if test "$ac_cv_func_getrandom" != yes; then + HAVE_GETRANDOM=0 + else + dnl On Solaris 11.4 the return type is 'int', not 'ssize_t'. + AC_CACHE_CHECK([whether getrandom is compatible with its GNU+BSD signature], + [gl_cv_func_getrandom_ok], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[/* Additional includes are needed before <sys/random.h> on Mac OS X. */ + #include <sys/types.h> + #include <stdlib.h> + #include <sys/random.h> + ssize_t getrandom (void *, size_t, unsigned int); + ]], + [[]]) + ], + [gl_cv_func_getrandom_ok=yes], + [gl_cv_func_getrandom_ok=no]) + ]) + if test $gl_cv_func_getrandom_ok = no; then + REPLACE_GETRANDOM=1 + fi + fi + + case "$host_os" in + mingw*) + AC_CACHE_CHECK([whether the bcrypt library is guaranteed to be present], + [gl_cv_lib_assume_bcrypt], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <windows.h>]], + [[#if !(_WIN32_WINNT >= _WIN32_WINNT_WIN7) + cannot assume it + #endif + ]]) + ], + [gl_cv_lib_assume_bcrypt=yes], + [gl_cv_lib_assume_bcrypt=no]) + ]) + if test $gl_cv_lib_assume_bcrypt = yes; then + AC_DEFINE([HAVE_LIB_BCRYPT], [1], + [Define to 1 if the bcrypt library is guaranteed to be present.]) + LIB_GETRANDOM='-lbcrypt' + else + LIB_GETRANDOM='-ladvapi32' + fi + ;; + *) + LIB_GETRANDOM= ;; + esac + AC_SUBST([LIB_GETRANDOM]) +]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 37170247884..1dc50a4a95c 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -53,6 +53,7 @@ AC_DEFUN([gl_EARLY], # Code from module byteswap: # Code from module c-ctype: # Code from module c-strcase: + # Code from module c99: # Code from module canonicalize-lgpl: # Code from module careadlinkat: # Code from module clock-time: @@ -102,6 +103,7 @@ AC_DEFUN([gl_EARLY], # Code from module getloadavg: # Code from module getopt-gnu: # Code from module getopt-posix: + # Code from module getrandom: # Code from module gettext-h: # Code from module gettime: # Code from module gettimeofday: @@ -163,6 +165,7 @@ AC_DEFUN([gl_EARLY], # Code from module strtoimax: # Code from module strtoll: # Code from module symlink: + # Code from module sys_random: # Code from module sys_select: # Code from module sys_stat: # Code from module sys_time: @@ -324,6 +327,11 @@ AC_DEFUN([gl_INIT], fi AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) gl_UNISTD_MODULE_INDICATOR([getopt-posix]) + gl_FUNC_GETRANDOM + if test $HAVE_GETRANDOM = 0 || test $REPLACE_GETRANDOM = 1; then + AC_LIBOBJ([getrandom]) + fi + gl_SYS_RANDOM_MODULE_INDICATOR([getrandom]) gl_GETTIME gl_FUNC_GETTIMEOFDAY if test $HAVE_GETTIMEOFDAY = 0 || test $REPLACE_GETTIMEOFDAY = 1; then @@ -334,6 +342,7 @@ AC_DEFUN([gl_INIT], gl_IEEE754_H gl_INTTYPES_INCOMPLETE AC_REQUIRE([gl_LARGEFILE]) + gl___INLINE gl_LIMITS_H gl_FUNC_LSTAT if test $REPLACE_LSTAT = 1; then @@ -374,6 +383,12 @@ AC_DEFUN([gl_INIT], gl_TIME_MODULE_INDICATOR([mktime]) gl_MULTIARCH gl_FUNC_GNU_STRFTIME + gl_FUNC_OPEN + if test $REPLACE_OPEN = 1; then + AC_LIBOBJ([open]) + gl_PREREQ_OPEN + fi + gl_FCNTL_MODULE_INDICATOR([open]) gl_PATHMAX gl_FUNC_PIPE2 gl_UNISTD_MODULE_INDICATOR([pipe2]) @@ -443,6 +458,8 @@ AC_DEFUN([gl_INIT], AC_LIBOBJ([symlink]) fi gl_UNISTD_MODULE_INDICATOR([symlink]) + gl_HEADER_SYS_RANDOM + AC_PROG_MKDIR_P AC_REQUIRE([gl_HEADER_SYS_SELECT]) AC_PROG_MKDIR_P gl_HEADER_SYS_STAT_H @@ -489,11 +506,9 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false gl_gnulib_enabled_lchmod=false - gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467=false gl_gnulib_enabled_2049e887c7e5308faad27b3f894bb8c9=false gl_gnulib_enabled_malloca=false gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false - gl_gnulib_enabled_open=false gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false gl_gnulib_enabled_strtoll=false @@ -503,7 +518,6 @@ AC_DEFUN([gl_INIT], { if ! $gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b; then gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=true - func_gl_gnulib_m4code_open fi } func_gl_gnulib_m4code_cloexec () @@ -603,13 +617,6 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_lchmod=true fi } - func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467 () - { - if ! $gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467; then - gl___INLINE - gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467=true - fi - } func_gl_gnulib_m4code_2049e887c7e5308faad27b3f894bb8c9 () { if ! $gl_gnulib_enabled_2049e887c7e5308faad27b3f894bb8c9; then @@ -637,21 +644,6 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=true fi } - func_gl_gnulib_m4code_open () - { - if ! $gl_gnulib_enabled_open; then - gl_FUNC_OPEN - if test $REPLACE_OPEN = 1; then - AC_LIBOBJ([open]) - gl_PREREQ_OPEN - fi - gl_FCNTL_MODULE_INDICATOR([open]) - gl_gnulib_enabled_open=true - if test $REPLACE_OPEN = 1; then - func_gl_gnulib_m4code_cloexec - fi - fi - } func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 () { if ! $gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7; then @@ -734,8 +726,8 @@ AC_DEFUN([gl_INIT], if test $NEED_LOCALTIME_BUFFER = 1; then func_gl_gnulib_m4code_2049e887c7e5308faad27b3f894bb8c9 fi - if test $REPLACE_MKTIME = 1; then - func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467 + if test $REPLACE_OPEN = 1; then + func_gl_gnulib_m4code_cloexec fi if test $HAVE_READLINKAT = 0; then func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b @@ -743,9 +735,6 @@ AC_DEFUN([gl_INIT], if test $HAVE_READLINKAT = 0; then func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 fi - if test $ac_use_included_regex = yes; then - func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467 - fi if { test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes; then func_gl_gnulib_m4code_strtoll fi @@ -771,11 +760,9 @@ AC_DEFUN([gl_INIT], AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36]) AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1]) AM_CONDITIONAL([gl_GNULIB_ENABLED_lchmod], [$gl_gnulib_enabled_lchmod]) - AM_CONDITIONAL([gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467], [$gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467]) AM_CONDITIONAL([gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9], [$gl_gnulib_enabled_2049e887c7e5308faad27b3f894bb8c9]) AM_CONDITIONAL([gl_GNULIB_ENABLED_malloca], [$gl_gnulib_enabled_malloca]) AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], [$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31]) - AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open]) AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7]) AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) @@ -1004,6 +991,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/getopt.in.h lib/getopt1.c lib/getopt_int.h + lib/getrandom.c lib/gettext.h lib/gettime.c lib/gettimeofday.c @@ -1076,6 +1064,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/strtol.c lib/strtoll.c lib/symlink.c + lib/sys_random.in.h lib/sys_select.in.h lib/sys_stat.in.h lib/sys_time.in.h @@ -1144,6 +1133,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/getgroups.m4 m4/getloadavg.m4 m4/getopt.m4 + m4/getrandom.m4 m4/gettime.m4 m4/gettimeofday.m4 m4/gl-openssl.m4 @@ -1205,6 +1195,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/strtoimax.m4 m4/strtoll.m4 m4/symlink.m4 + m4/sys_random_h.m4 m4/sys_select_h.m4 m4/sys_socket_h.m4 m4/sys_stat_h.m4 diff --git a/m4/memmem.m4 b/m4/memmem.m4 index e034d7bd775..35a5bb19d1a 100644 --- a/m4/memmem.m4 +++ b/m4/memmem.m4 @@ -1,4 +1,4 @@ -# memmem.m4 serial 26 +# memmem.m4 serial 27 dnl Copyright (C) 2002-2004, 2007-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, @@ -37,7 +37,7 @@ AC_DEFUN([gl_FUNC_MEMMEM_SIMPLE], /* Check for empty needle behavior. */ { const char *haystack = "AAA"; - if (memmem (haystack, 3, NULL, 0) != haystack) + if (memmem (haystack, 3, (const char *) 1, 0) != haystack) result |= 2; } return result; diff --git a/m4/regex.m4 b/m4/regex.m4 index 65f518582c1..e723f591216 100644 --- a/m4/regex.m4 +++ b/m4/regex.m4 @@ -1,4 +1,4 @@ -# serial 69 +# serial 70 # Copyright (C) 1996-2001, 2003-2020 Free Software Foundation, Inc. # @@ -90,11 +90,14 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern (pat, sizeof pat - 1, ®ex); if (s) result |= 1; - else if (re_search (®ex, data, sizeof data - 1, - 0, sizeof data - 1, ®s) - != -1) - result |= 1; - regfree (®ex); + else + { + if (re_search (®ex, data, sizeof data - 1, + 0, sizeof data - 1, ®s) + != -1) + result |= 1; + regfree (®ex); + } } { @@ -125,8 +128,8 @@ AC_DEFUN([gl_REGEX], 0, sizeof data - 1, 0); if (i != 0 && i != 21) result |= 1; + regfree (®ex); } - regfree (®ex); } if (! setlocale (LC_ALL, "C")) @@ -139,9 +142,13 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("a[^x]b", 6, ®ex); if (s) result |= 2; - /* This should fail, but succeeds for glibc-2.5. */ - else if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) - result |= 2; + else + { + /* This should fail, but succeeds for glibc-2.5. */ + if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) + result |= 2; + regfree (®ex); + } /* This regular expression is from Spencer ere test number 75 in grep-2.3. */ @@ -153,7 +160,10 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); /* This should fail with _Invalid character class name_ error. */ if (!s) - result |= 4; + { + result |= 4; + regfree (®ex); + } /* Ensure that [b-a] is diagnosed as invalid, when using RE_NO_EMPTY_RANGES. */ @@ -161,13 +171,18 @@ AC_DEFUN([gl_REGEX], memset (®ex, 0, sizeof regex); s = re_compile_pattern ("a[b-a]", 6, ®ex); if (s == 0) - result |= 8; + { + result |= 8; + regfree (®ex); + } /* This should succeed, but does not for glibc-2.1.3. */ memset (®ex, 0, sizeof regex); s = re_compile_pattern ("{1", 2, ®ex); if (s) result |= 8; + else + regfree (®ex); /* The following example is derived from a problem report against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */ @@ -175,17 +190,35 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("[an\371]*n", 7, ®ex); if (s) result |= 8; - /* This should match, but does not for glibc-2.2.1. */ - else if (re_match (®ex, "an", 2, 0, ®s) != 2) - result |= 8; + else + { + /* This should match, but does not for glibc-2.2.1. */ + if (re_match (®ex, "an", 2, 0, ®s) != 2) + result |= 8; + else + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } memset (®ex, 0, sizeof regex); s = re_compile_pattern ("x", 1, ®ex); if (s) result |= 8; - /* glibc-2.2.93 does not work with a negative RANGE argument. */ - else if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) - result |= 8; + else + { + /* glibc-2.2.93 does not work with a negative RANGE argument. */ + if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) + result |= 8; + else + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } /* The version of regex.c in older versions of gnulib ignored RE_ICASE. Detect that problem too. */ @@ -194,8 +227,17 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("x", 1, ®ex); if (s) result |= 16; - else if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) - result |= 16; + else + { + if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) + result |= 16; + else + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } /* Catch a bug reported by Vin Shelton in https://lists.gnu.org/r/bug-coreutils/2007-06/msg00089.html @@ -207,6 +249,8 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); if (s) result |= 32; + else + regfree (®ex); /* REG_STARTEND was added to glibc on 2004-01-15. Reject older versions. */ @@ -221,8 +265,14 @@ AC_DEFUN([gl_REGEX], re_set_syntax (RE_SYNTAX_POSIX_EGREP); memset (®ex, 0, sizeof regex); s = re_compile_pattern ("0|()0|\\1|0", 10, ®ex); - if (!s || strcmp (s, "Invalid back reference")) + if (!s) result |= 64; + else + { + if (strcmp (s, "Invalid back reference")) + result |= 64; + regfree (®ex); + } #if 0 /* It would be nice to reject hosts whose regoff_t values are too diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4 new file mode 100644 index 00000000000..a964b157841 --- /dev/null +++ b/m4/sys_random_h.m4 @@ -0,0 +1,52 @@ +# sys_random_h.m4 serial 4 +dnl Copyright (C) 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_HEADER_SYS_RANDOM], +[ + AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS]) + dnl <sys/random.h> is always overridden, because of GNULIB_POSIXCHECK. + gl_CHECK_NEXT_HEADERS([sys/random.h]) + if test $ac_cv_header_sys_random_h = yes; then + HAVE_SYS_RANDOM_H=1 + else + HAVE_SYS_RANDOM_H=0 + fi + AC_SUBST([HAVE_SYS_RANDOM_H]) + + m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])]) + if test $ac_cv_header_sys_random_h = yes; then + UNISTD_H_HAVE_SYS_RANDOM_H=1 + fi + + 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([[ +#if HAVE_SYS_RANDOM_H +/* Additional includes are needed before <sys/random.h> on Mac OS X. */ +# include <sys/types.h> +# include <stdlib.h> +# include <sys/random.h> +#endif + ]], + [getrandom]) +]) + +AC_DEFUN([gl_SYS_RANDOM_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_SYS_RANDOM_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_SYS_RANDOM_H_DEFAULTS], +[ + GNULIB_GETRANDOM=0; AC_SUBST([GNULIB_GETRANDOM]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_GETRANDOM=1; AC_SUBST([HAVE_GETRANDOM]) + REPLACE_GETRANDOM=0; AC_SUBST([REPLACE_GETRANDOM]) +]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index e776f3bd445..dfa38f85d60 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 78 +# unistd_h.m4 serial 80 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, @@ -43,7 +43,7 @@ AC_DEFUN([gl_UNISTD_H], #endif ]], [access chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize - getgroups gethostname getlogin getlogin_r getpagesize getpass + getentropy getgroups gethostname getlogin getlogin_r getpagesize getpass getusershell setusershell endusershell group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite readlink readlinkat rmdir sethostname sleep symlink symlinkat @@ -82,6 +82,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME]) GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE]) + GNULIB_GETENTROPY=0; AC_SUBST([GNULIB_GETENTROPY]) GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS]) GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME]) GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN]) @@ -129,6 +130,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) + HAVE_GETENTROPY=1; AC_SUBST([HAVE_GETENTROPY]) HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS]) HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN]) @@ -198,6 +200,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP]) REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE]) + UNISTD_H_HAVE_SYS_RANDOM_H=0; AC_SUBST([UNISTD_H_HAVE_SYS_RANDOM_H]) UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H]) UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS]) diff --git a/src/eval.c b/src/eval.c index f2a85691b42..f9a1a28f004 100644 --- a/src/eval.c +++ b/src/eval.c @@ -840,6 +840,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) Lisp_Object sym, tem; sym = XCAR (args); + CHECK_SYMBOL (sym); Lisp_Object docstring = Qnil; if (!NILP (XCDR (XCDR (args)))) { diff --git a/src/xdisp.c b/src/xdisp.c index bd0711471a2..e454fd7b83f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1871,9 +1871,10 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, top_x = it3.current_x - it3.pixel_width; /* Account for line-number display, if IT3 still didn't. This can happen if START - 1 is the - first character on its display line. */ - if (!it3.line_number_produced_p - && it.line_number_produced_p) + first or the last character on its display line. */ + if (it3.lnum_pixel_width > 0) + top_x += it3.lnum_pixel_width; + else if (it.line_number_produced_p) top_x += it.lnum_pixel_width; /* Normally, we would exit the above loop because we found the display element whose character diff --git a/src/xfaces.c b/src/xfaces.c index 308509a0267..c4a4e1c94f3 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -820,10 +820,10 @@ load_pixmap (struct frame *f, Lisp_Object name) Color Handling ***********************************************************************/ -/* Parse hex color component at S ending right before E. - Set *DST to the value normalized so that the maximum for the - number of digits given becomes 65535, and return true on success, - false otherwise. */ +/* Parse hex color component specification that starts at S and ends + right before E. Set *DST to the parsed value normalized so that + the maximum value for the number of hex digits given becomes 65535, + and return true on success, false otherwise. */ static bool parse_hex_color_comp (const char *s, const char *e, unsigned short *dst) { @@ -849,8 +849,9 @@ parse_hex_color_comp (const char *s, const char *e, unsigned short *dst) return true; } -/* Parse floating-point color component at S ending right before E. - Return the number if in the range [0,1]; otherwise -1. */ +/* Parse floating-point color component specification that starts at S + and ends right before E. Return the parsed number if in the range + [0,1]; otherwise return -1. */ static double parse_float_color_comp (const char *s, const char *e) { @@ -859,48 +860,54 @@ parse_float_color_comp (const char *s, const char *e) return (end == e && x >= 0 && x <= 1) ? x : -1; } -/* Parse S as a numeric color specification and set *R, *G and *B. +/* Parse SPEC as a numeric color specification and set *R, *G and *B. Return true on success, false on failure. - Recognized formats: - "#RGB", with R, G and B hex strings of equal length, 1-4 digits each - "rgb:R/G/B", with R, G and B hex strings, 1-4 digits each - "rgbi:R/G/B", with R, G and B numbers in [0,1] + Recognized formats of SPEC: - The result is normalized to a maximum value of 65535 per component. */ + "#RGB", with R, G and B hex strings of equal length, 1-4 digits each. + "rgb:R/G/B", with R, G and B hex strings, 1-4 digits each. + "rgbi:R/G/B", with R, G and B numbers in [0,1]. + + If the function succeeds, it assigns to each of the components *R, + *G, and *B a value normalized to be in the [0, 65535] range. If + the function fails, some or all of the components remain unassigned. */ bool -parse_color_spec (const char *s, +parse_color_spec (const char *spec, unsigned short *r, unsigned short *g, unsigned short *b) { - int len = strlen (s); - if (s[0] == '#') + int len = strlen (spec); + if (spec[0] == '#') { if ((len - 1) % 3 == 0) { int n = (len - 1) / 3; - return ( parse_hex_color_comp (s + 1 + 0 * n, s + 1 + 1 * n, r) - && parse_hex_color_comp (s + 1 + 1 * n, s + 1 + 2 * n, g) - && parse_hex_color_comp (s + 1 + 2 * n, s + 1 + 3 * n, b)); + return ( parse_hex_color_comp (spec + 1 + 0 * n, + spec + 1 + 1 * n, r) + && parse_hex_color_comp (spec + 1 + 1 * n, + spec + 1 + 2 * n, g) + && parse_hex_color_comp (spec + 1 + 2 * n, + spec + 1 + 3 * n, b)); } } - else if (strncmp (s, "rgb:", 4) == 0) + else if (strncmp (spec, "rgb:", 4) == 0) { char *sep1, *sep2; - return ((sep1 = strchr (s + 4, '/')) != NULL + return ((sep1 = strchr (spec + 4, '/')) != NULL && (sep2 = strchr (sep1 + 1, '/')) != NULL - && parse_hex_color_comp (s + 4, sep1, r) + && parse_hex_color_comp (spec + 4, sep1, r) && parse_hex_color_comp (sep1 + 1, sep2, g) - && parse_hex_color_comp (sep2 + 1, s + len, b)); + && parse_hex_color_comp (sep2 + 1, spec + len, b)); } - else if (strncmp (s, "rgbi:", 5) == 0) + else if (strncmp (spec, "rgbi:", 5) == 0) { char *sep1, *sep2; double red, green, blue; - if ((sep1 = strchr (s + 5, '/')) != NULL + if ((sep1 = strchr (spec + 5, '/')) != NULL && (sep2 = strchr (sep1 + 1, '/')) != NULL - && (red = parse_float_color_comp (s + 5, sep1)) >= 0 + && (red = parse_float_color_comp (spec + 5, sep1)) >= 0 && (green = parse_float_color_comp (sep1 + 1, sep2)) >= 0 - && (blue = parse_float_color_comp (sep2 + 1, s + len)) >= 0) + && (blue = parse_float_color_comp (sep2 + 1, spec + len)) >= 0) { *r = lrint (red * 65535); *g = lrint (green * 65535); @@ -911,25 +918,26 @@ parse_color_spec (const char *s, return false; } -DEFUN ("internal-color-values-from-color-spec", - Finternal_color_values_from_color_spec, - Sinternal_color_values_from_color_spec, +DEFUN ("color-values-from-color-spec", + Fcolor_values_from_color_spec, + Scolor_values_from_color_spec, 1, 1, 0, - doc: /* Parse STRING as a numeric color and return (RED GREEN BLUE). -Recognised formats for STRING are: + doc: /* Parse color SPEC as a numeric color and return (RED GREEN BLUE). +This function recognises the following formats for SPEC: + + #RGB, where R, G and B are hex numbers of equal length, 1-4 digits each. + rgb:R/G/B, where R, G, and B are hex numbers, 1-4 digits each. + rgbi:R/G/B, where R, G and B are floating-point numbers in [0,1]. - #RGB, where R, G and B are hex numbers of equal length, 1-4 digits each - rgb:R/G/B, where R, G, and B are hex numbers, 1-4 digits each - rgbi:R/G/B, where R, G and B are floating-point numbers in [0,1] +If SPEC is not in one of the above forms, return nil. -The result is normalized to a maximum value of 65535 per component, -forming a list of three integers in [0,65535]. -If STRING is not in one of the above forms, return nil. */) - (Lisp_Object string) +Each of the 3 integer members of the resulting list, RED, GREEN, and BLUE, +is normalized to have its value in [0,65535]. */) + (Lisp_Object spec) { - CHECK_STRING (string); + CHECK_STRING (spec); unsigned short r, g, b; - return (parse_color_spec (SSDATA (string), &r, &g, &b) + return (parse_color_spec (SSDATA (spec), &r, &g, &b) ? list3i (r, g, b) : Qnil); } @@ -7133,5 +7141,5 @@ clear the face cache, see `clear-face-cache'. */); defsubr (&Sinternal_face_x_get_resource); defsubr (&Sx_family_fonts); #endif - defsubr (&Sinternal_color_values_from_color_spec); + defsubr (&Scolor_values_from_color_spec); } diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 43630c4debd..1f24ba2786f 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -43,6 +43,7 @@ (require 'dired) (require 'ert) (require 'ert-x) +(require 'trace) (require 'tramp) (require 'vc) (require 'vc-bzr) @@ -177,23 +178,36 @@ This shall used dynamically bound only.") (defmacro tramp--test-instrument-test-case (verbose &rest body) "Run BODY with `tramp-verbose' equal VERBOSE. Print the content of the Tramp connection and debug buffers, if -`tramp-verbose' is greater than 3. `should-error' is not handled -properly. BODY shall not contain a timeout." +`tramp-verbose' is greater than 3. Print traces if `tramp-verbose' +is greater than 10. +`should-error' is not handled properly. BODY shall not contain a timeout." (declare (indent 1) (debug (natnump body))) - `(let ((tramp-verbose (max (or ,verbose 0) (or tramp-verbose 0))) - (debug-ignored-errors - (append - '("^make-symbolic-link not supported$" - "^error with add-name-to-file") - debug-ignored-errors)) - inhibit-message) + `(let* ((tramp-verbose (max (or ,verbose 0) (or tramp-verbose 0))) + (trace-buffer + (when (> tramp-verbose 10) (generate-new-buffer " *temp*"))) + (debug-ignored-errors + (append + '("^make-symbolic-link not supported$" + "^error with add-name-to-file") + debug-ignored-errors)) + inhibit-message) + (when trace-buffer + (dolist (elt (all-completions "tramp-" obarray 'functionp)) + (trace-function-background (intern elt)))) (unwind-protect (let ((tramp--test-instrument-test-case-p t)) ,@body) ;; Unwind forms. + (when trace-buffer + (untrace-all)) (when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 3)) - (dolist (buf (tramp-list-tramp-buffers)) + (dolist + (buf (if trace-buffer + (cons (get-buffer trace-buffer) (tramp-list-tramp-buffers)) + (tramp-list-tramp-buffers))) (with-current-buffer buf - (message ";; %s\n%s" buf (buffer-string)))))))) + (message ";; %s\n%s" buf (buffer-string))))) + (when trace-buffer + (kill-buffer trace-buffer))))) (defsubst tramp--test-message (fmt-string &rest arguments) "Emit a message into ERT *Messages*." @@ -1996,7 +2010,7 @@ properly. BODY shall not contain a timeout." ;; Samba does not support file names with periods followed by ;; spaces, and trailing periods or spaces. - (when (tramp-smb-file-name-p tramp-test-temporary-file-directory) + (when (tramp--test-smb-p) (dolist (file '("foo." "foo. bar" "foo ")) (should-error (tramp-smb-get-localname @@ -2150,7 +2164,7 @@ properly. BODY shall not contain a timeout." ;; These are the methods the test doesn't fail. (when (or (tramp--test-adb-p) (tramp--test-ange-ftp-p) (tramp--test-gvfs-p) (tramp--test-rclone-p) - (tramp-smb-file-name-p tramp-test-temporary-file-directory)) + (tramp--test-smb-p)) (setf (ert-test-expected-result-type (ert-get-test 'tramp-test05-expand-file-name-relative)) :passed)) @@ -3716,7 +3730,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (tramp--test-ignore-make-symbolic-link-error (make-symbolic-link tmp-name2 tmp-name1) (should (file-symlink-p tmp-name1)) - (if (tramp-smb-file-name-p tramp-test-temporary-file-directory) + (if (tramp--test-smb-p) ;; The symlink command of `smbclient' detects the ;; cycle already. (should-error @@ -5697,7 +5711,12 @@ This does not support utf8 based file transfer." "Check, whether the locale or remote host runs MS Windows. This requires restrictions of file name syntax." (or (eq system-type 'windows-nt) - (tramp-smb-file-name-p tramp-test-temporary-file-directory))) + (tramp--test-smb-p))) + +(defun tramp--test-smb-p () + "Check, whether the locale or remote host runs MS Windows. +This requires restrictions of file name syntax." + (tramp-smb-file-name-p tramp-test-temporary-file-directory)) (defun tramp--test-check-files (&rest files) "Run a simple but comprehensive test over every file in FILES." @@ -5821,8 +5840,7 @@ This requires restrictions of file name syntax." ;; It does not work in the "smb" case, only relative ;; symlinks to existing files are shown there. (tramp--test-ignore-make-symbolic-link-error - (unless - (tramp-smb-file-name-p tramp-test-temporary-file-directory) + (unless (tramp--test-smb-p) (make-symbolic-link file2 file3) (should (file-symlink-p file3)) (should @@ -6554,6 +6572,8 @@ If INTERACTIVE is non-nil, the tests are run interactively." ;; * file-equal-p (partly done in `tramp-test21-file-links') ;; * file-in-directory-p ;; * file-name-case-insensitive-p +;; * tramp-get-remote-gid +;; * tramp-get-remote-uid ;; * tramp-set-file-uid-gid ;; * Work on skipped tests. Make a comment, when it is impossible. diff --git a/test/lisp/progmodes/pascal-tests.el b/test/lisp/progmodes/pascal-tests.el new file mode 100644 index 00000000000..ed4c6fb03e0 --- /dev/null +++ b/test/lisp/progmodes/pascal-tests.el @@ -0,0 +1,63 @@ +;;; pascal-tests.el --- tests for pascal.el -*- lexical-binding: t -*- + +;; Copyright (C) 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 <https://www.gnu.org/licenses/>. + +(require 'ert) +(require 'pascal) + +(ert-deftest pascal-completion () + ;; Bug#41740: completion functions must preserve point. + (let ((pascal-completion-cache nil)) + (with-temp-buffer + (pascal-mode) + (insert "program test; var") + (let* ((point-before (point)) + (completions (pascal-completion "var" nil 'metadata)) + (point-after (point))) + (should (equal completions nil)) + (should (equal point-before point-after))))) + + (let ((pascal-completion-cache nil)) + (with-temp-buffer + (pascal-mode) + (insert "program test; function f(x : i") + (let* ((point-before (point)) + (completions (pascal-completion "i" nil 'metadata)) + (point-after (point))) + (should (equal completions nil)) + (should (equal point-before point-after))))) + + (let ((pascal-completion-cache nil)) + (with-temp-buffer + (pascal-mode) + (insert "program test; function f(x : integer) : real") + (let* ((point-before (point)) + (completions (pascal-completion "real" nil 'metadata)) + (point-after (point))) + (should (equal completions nil)) + (should (equal point-before point-after)))))) + +(ert-deftest pascal-beg-of-defun () + (with-temp-buffer + (pascal-mode) + (insert "program test; procedure p(") + (forward-char -1) + (pascal-beg-of-defun) + (should (equal (point) 15)))) + +(provide 'pascal-tests) diff --git a/test/src/xfaces-tests.el b/test/src/xfaces-tests.el index 34cda07e5b4..bde3a354229 100644 --- a/test/src/xfaces-tests.el +++ b/test/src/xfaces-tests.el @@ -25,26 +25,26 @@ (color-distance "#ffffff" "#222222")))) (ert-deftest xfaces-internal-color-values-from-color-spec () - (should (equal (internal-color-values-from-color-spec "#f05") + (should (equal (color-values-from-color-spec "#f05") '(#xffff #x0000 #x5555))) - (should (equal (internal-color-values-from-color-spec "#1fb0C5") + (should (equal (color-values-from-color-spec "#1fb0C5") '(#x1f1f #xb0b0 #xc5c5))) - (should (equal (internal-color-values-from-color-spec "#1f8b0AC5e") + (should (equal (color-values-from-color-spec "#1f8b0AC5e") '(#x1f81 #xb0aa #xc5eb))) - (should (equal (internal-color-values-from-color-spec "#1f83b0ADC5e2") + (should (equal (color-values-from-color-spec "#1f83b0ADC5e2") '(#x1f83 #xb0ad #xc5e2))) - (should (equal (internal-color-values-from-color-spec "#1f83b0ADC5e2g") nil)) - (should (equal (internal-color-values-from-color-spec "#1f83b0ADC5e20") nil)) - (should (equal (internal-color-values-from-color-spec "#12345") nil)) - (should (equal (internal-color-values-from-color-spec "rgb:f/23/28a") + (should (equal (color-values-from-color-spec "#1f83b0ADC5e2g") nil)) + (should (equal (color-values-from-color-spec "#1f83b0ADC5e20") nil)) + (should (equal (color-values-from-color-spec "#12345") nil)) + (should (equal (color-values-from-color-spec "rgb:f/23/28a") '(#xffff #x2323 #x28a2))) - (should (equal (internal-color-values-from-color-spec "rgb:1234/5678/09ab") + (should (equal (color-values-from-color-spec "rgb:1234/5678/09ab") '(#x1234 #x5678 #x09ab))) - (should (equal (internal-color-values-from-color-spec "rgb:0//0") nil)) - (should (equal (internal-color-values-from-color-spec "rgbi:0/0.5/0.1") + (should (equal (color-values-from-color-spec "rgb:0//0") nil)) + (should (equal (color-values-from-color-spec "rgbi:0/0.5/0.1") '(0 32768 6554))) - (should (equal (internal-color-values-from-color-spec "rgbi:1e-3/1.0e-2/1e0") + (should (equal (color-values-from-color-spec "rgbi:1e-3/1.0e-2/1e0") '(66 655 65535))) - (should (equal (internal-color-values-from-color-spec "rgbi:0/0.5/10") nil))) + (should (equal (color-values-from-color-spec "rgbi:0/0.5/10") nil))) (provide 'xfaces-tests) |