Update from Gnulib by running admin/merge-gnulib
This commit is contained in:
parent
9143eba0c6
commit
a900e641fa
51 changed files with 1841 additions and 514 deletions
8
build-aux/config.guess
vendored
8
build-aux/config.guess
vendored
|
@ -1,8 +1,8 @@
|
|||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2020 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2021 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2020-12-22'
|
||||
timestamp='2021-01-01'
|
||||
|
||||
# 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
|
||||
|
@ -50,7 +50,7 @@ version="\
|
|||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2020 Free Software Foundation, Inc.
|
||||
Copyright 1992-2021 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
@ -1087,7 +1087,7 @@ EOF
|
|||
ppcle:Linux:*:*)
|
||||
echo powerpcle-unknown-linux-"$LIBC"
|
||||
exit ;;
|
||||
riscv32:Linux:*:* | riscv64:Linux:*:*)
|
||||
riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
|
||||
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
|
|
10
build-aux/config.sub
vendored
10
build-aux/config.sub
vendored
|
@ -1,8 +1,8 @@
|
|||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2020 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2021 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2020-12-22'
|
||||
timestamp='2021-01-07'
|
||||
|
||||
# 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
|
||||
|
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2020 Free Software Foundation, Inc.
|
||||
Copyright 1992-2021 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
@ -1230,7 +1230,7 @@ case $cpu-$vendor in
|
|||
| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
|
||||
| pru \
|
||||
| pyramid \
|
||||
| riscv | riscv32 | riscv64 \
|
||||
| riscv | riscv32 | riscv32be | riscv64 | riscv64be \
|
||||
| rl78 | romp | rs6000 | rx \
|
||||
| s390 | s390x \
|
||||
| score \
|
||||
|
@ -1687,7 +1687,7 @@ case $os in
|
|||
musl* | newlib* | uclibc*)
|
||||
;;
|
||||
# Likewise for "kernel-libc"
|
||||
eabi | eabihf | gnueabi | gnueabihf)
|
||||
eabi* | gnueabi*)
|
||||
;;
|
||||
# Now accept the basic system types.
|
||||
# The portable systems comes first.
|
||||
|
|
|
@ -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-10-24.12}
|
||||
\def\texinfoversion{2020-11-25.18}
|
||||
%
|
||||
% Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc.
|
||||
%
|
||||
|
@ -572,10 +572,9 @@
|
|||
\fi
|
||||
}
|
||||
|
||||
% @end foo executes the definition of \Efoo.
|
||||
% But first, it executes a specialized version of \checkenv
|
||||
%
|
||||
\parseargdef\end{%
|
||||
|
||||
% @end foo calls \checkenv and executes the definition of \Efoo.
|
||||
\parseargdef\end{
|
||||
\if 1\csname iscond.#1\endcsname
|
||||
\else
|
||||
% The general wording of \badenverr may not be ideal.
|
||||
|
@ -2673,8 +2672,6 @@
|
|||
\definetextfontsizexi
|
||||
|
||||
|
||||
\message{markup,}
|
||||
|
||||
% Check if we are currently using a typewriter font. Since all the
|
||||
% Computer Modern typewriter fonts have zero interword stretch (and
|
||||
% shrink), and it is reasonable to expect all typewriter fonts to have
|
||||
|
@ -2682,68 +2679,14 @@
|
|||
%
|
||||
\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
|
||||
|
||||
% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
|
||||
% define and register \INITMACRO to be called on markup style changes.
|
||||
% \INITMACRO can check \currentmarkupstyle for the innermost
|
||||
% style.
|
||||
|
||||
\let\currentmarkupstyle\empty
|
||||
|
||||
\def\setupmarkupstyle#1{%
|
||||
\def\currentmarkupstyle{#1}%
|
||||
\markupstylesetup
|
||||
}
|
||||
|
||||
\let\markupstylesetup\empty
|
||||
|
||||
\def\defmarkupstylesetup#1{%
|
||||
\expandafter\def\expandafter\markupstylesetup
|
||||
\expandafter{\markupstylesetup #1}%
|
||||
\def#1%
|
||||
}
|
||||
|
||||
% Markup style setup for left and right quotes.
|
||||
\defmarkupstylesetup\markupsetuplq{%
|
||||
\expandafter\let\expandafter \temp
|
||||
\csname markupsetuplq\currentmarkupstyle\endcsname
|
||||
\ifx\temp\relax \markupsetuplqdefault \else \temp \fi
|
||||
}
|
||||
|
||||
\defmarkupstylesetup\markupsetuprq{%
|
||||
\expandafter\let\expandafter \temp
|
||||
\csname markupsetuprq\currentmarkupstyle\endcsname
|
||||
\ifx\temp\relax \markupsetuprqdefault \else \temp \fi
|
||||
}
|
||||
|
||||
{
|
||||
\catcode`\'=\active
|
||||
\catcode`\`=\active
|
||||
|
||||
\gdef\markupsetuplqdefault{\let`\lq}
|
||||
\gdef\markupsetuprqdefault{\let'\rq}
|
||||
|
||||
\gdef\markupsetcodequoteleft{\let`\codequoteleft}
|
||||
\gdef\markupsetcodequoteright{\let'\codequoteright}
|
||||
\gdef\setcodequotes{\let`\codequoteleft \let'\codequoteright}
|
||||
\gdef\setregularquotes{\let`\lq \let'\rq}
|
||||
}
|
||||
|
||||
\let\markupsetuplqcode \markupsetcodequoteleft
|
||||
\let\markupsetuprqcode \markupsetcodequoteright
|
||||
%
|
||||
\let\markupsetuplqexample \markupsetcodequoteleft
|
||||
\let\markupsetuprqexample \markupsetcodequoteright
|
||||
%
|
||||
\let\markupsetuplqkbd \markupsetcodequoteleft
|
||||
\let\markupsetuprqkbd \markupsetcodequoteright
|
||||
%
|
||||
\let\markupsetuplqsamp \markupsetcodequoteleft
|
||||
\let\markupsetuprqsamp \markupsetcodequoteright
|
||||
%
|
||||
\let\markupsetuplqverb \markupsetcodequoteleft
|
||||
\let\markupsetuprqverb \markupsetcodequoteright
|
||||
%
|
||||
\let\markupsetuplqverbatim \markupsetcodequoteleft
|
||||
\let\markupsetuprqverbatim \markupsetcodequoteright
|
||||
|
||||
% Allow an option to not use regular directed right quote/apostrophe
|
||||
% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
|
||||
% The undirected quote is ugly, so don't make it the default, but it
|
||||
|
@ -2906,7 +2849,7 @@
|
|||
}
|
||||
|
||||
% @samp.
|
||||
\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
|
||||
\def\samp#1{{\setcodequotes\lq\tclose{#1}\rq\null}}
|
||||
|
||||
% @indicateurl is \samp, that is, with quotes.
|
||||
\let\indicateurl=\samp
|
||||
|
@ -2949,8 +2892,7 @@
|
|||
\global\let'=\rq \global\let`=\lq % default definitions
|
||||
%
|
||||
\global\def\code{\begingroup
|
||||
\setupmarkupstyle{code}%
|
||||
% The following should really be moved into \setupmarkupstyle handlers.
|
||||
\setcodequotes
|
||||
\catcode\dashChar=\active \catcode\underChar=\active
|
||||
\ifallowcodebreaks
|
||||
\let-\codedash
|
||||
|
@ -3104,7 +3046,7 @@
|
|||
\urefcatcodes
|
||||
%
|
||||
\global\def\urefcode{\begingroup
|
||||
\setupmarkupstyle{code}%
|
||||
\setcodequotes
|
||||
\urefcatcodes
|
||||
\let&\urefcodeamp
|
||||
\let.\urefcodedot
|
||||
|
@ -3225,8 +3167,8 @@
|
|||
\def\kbdsub#1#2#3\par{%
|
||||
\def\one{#1}\def\three{#3}\def\threex{??}%
|
||||
\ifx\one\xkey\ifx\threex\three \key{#2}%
|
||||
\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
|
||||
\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
|
||||
\else{\tclose{\kbdfont\setcodequotes\look}}\fi
|
||||
\else{\tclose{\kbdfont\setcodequotes\look}}\fi
|
||||
}
|
||||
|
||||
% definition of @key that produces a lozenge. Doesn't adjust to text size.
|
||||
|
@ -3243,7 +3185,7 @@
|
|||
% monospace, don't change it; that way, we respect @kbdinputstyle. But
|
||||
% if it isn't monospace, then use \tt.
|
||||
%
|
||||
\def\key#1{{\setupmarkupstyle{key}%
|
||||
\def\key#1{{\setregularquotes
|
||||
\nohyphenation
|
||||
\ifmonospace\else\tt\fi
|
||||
#1}\null}
|
||||
|
@ -3373,16 +3315,20 @@
|
|||
{\obeylines
|
||||
\globaldefs=1
|
||||
\envdef\displaymath{%
|
||||
\tex
|
||||
\tex%
|
||||
\def\thisenv{\displaymath}%
|
||||
\begingroup\let\end\displaymathend%
|
||||
$$%
|
||||
}
|
||||
|
||||
\def\Edisplaymath{$$
|
||||
\def\displaymathend{$$\endgroup\end}%
|
||||
|
||||
\def\Edisplaymath{%
|
||||
\def\thisenv{\tex}%
|
||||
\end tex
|
||||
}}
|
||||
|
||||
|
||||
% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
|
||||
% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
|
||||
% except specified as a normal braced arg, so no newlines to worry about.
|
||||
|
@ -7144,7 +7090,7 @@
|
|||
% But \@ or @@ will get a plain @ character.
|
||||
|
||||
\envdef\tex{%
|
||||
\setupmarkupstyle{tex}%
|
||||
\setregularquotes
|
||||
\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
|
||||
\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
|
||||
\catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
|
||||
|
@ -7370,7 +7316,7 @@
|
|||
% If you want all examples etc. small: @set dispenvsize small.
|
||||
% If you want even small examples the full size: @set dispenvsize nosmall.
|
||||
% This affects the following displayed environments:
|
||||
% @example, @display, @format, @lisp
|
||||
% @example, @display, @format, @lisp, @verbatim
|
||||
%
|
||||
\def\smallword{small}
|
||||
\def\nosmallword{nosmall}
|
||||
|
@ -7416,9 +7362,9 @@
|
|||
%
|
||||
\maketwodispenvdef{lisp}{example}{%
|
||||
\nonfillstart
|
||||
\tt\setupmarkupstyle{example}%
|
||||
\tt\setcodequotes
|
||||
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
|
||||
\gobble % eat return
|
||||
\parsearg\gobble
|
||||
}
|
||||
% @display/@smalldisplay: same as @lisp except keep current font.
|
||||
%
|
||||
|
@ -7576,7 +7522,7 @@
|
|||
\def\setupverb{%
|
||||
\tt % easiest (and conventionally used) font for verbatim
|
||||
\def\par{\leavevmode\endgraf}%
|
||||
\setupmarkupstyle{verb}%
|
||||
\setcodequotes
|
||||
\tabeightspaces
|
||||
% Respect line breaks,
|
||||
% print special symbols as themselves, and
|
||||
|
@ -7617,7 +7563,7 @@
|
|||
\tt % easiest (and conventionally used) font for verbatim
|
||||
\def\par{\egroup\leavevmode\box\verbbox\endgraf\starttabbox}%
|
||||
\tabexpand
|
||||
\setupmarkupstyle{verbatim}%
|
||||
\setcodequotes
|
||||
% Respect line breaks,
|
||||
% print special symbols as themselves, and
|
||||
% make each space count.
|
||||
|
@ -8036,7 +7982,7 @@
|
|||
% leave the code in, but it's strange for @var to lead to typewriter.
|
||||
% Nowadays we recommend @code, since the difference between a ttsl hyphen
|
||||
% and a tt hyphen is pretty tiny. @code also disables ?` !`.
|
||||
\def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
|
||||
\def\var##1{{\setregularquotes\ttslanted{##1}}}%
|
||||
#1%
|
||||
\sl\hyphenchar\font=45
|
||||
}
|
||||
|
@ -8145,11 +8091,18 @@
|
|||
}
|
||||
\fi
|
||||
|
||||
\let\E=\expandafter
|
||||
|
||||
% Used at the time of macro expansion.
|
||||
% Argument is macro body with arguments substituted
|
||||
\def\scanmacro#1{%
|
||||
\newlinechar`\^^M
|
||||
\def\xeatspaces{\eatspaces}%
|
||||
% expand the expansion of \eatleadingcr twice to maybe remove a leading
|
||||
% newline (and \else and \fi tokens), then call \eatspaces on the result.
|
||||
\def\xeatspaces##1{%
|
||||
\E\E\E\E\E\E\E\eatspaces\E\E\E\E\E\E\E{\eatleadingcr##1%
|
||||
}}%
|
||||
\def\xempty##1{}%
|
||||
%
|
||||
% Process the macro body under the current catcode regime.
|
||||
\scantokens{#1@comment}%
|
||||
|
@ -8202,6 +8155,11 @@
|
|||
\unbrace{\gdef\trim@@@ #1 } #2@{#1}
|
||||
}
|
||||
|
||||
{\catcode`\^^M=\other%
|
||||
\gdef\eatleadingcr#1{\if\noexpand#1\noexpand^^M\else\E#1\fi}}%
|
||||
% Warning: this won't work for a delimited argument
|
||||
% or for an empty argument
|
||||
|
||||
% Trim a single trailing ^^M off a string.
|
||||
{\catcode`\^^M=\other \catcode`\Q=3%
|
||||
\gdef\eatcr #1{\eatcra #1Q^^MQ}%
|
||||
|
@ -8368,6 +8326,7 @@
|
|||
\let\hash\relax
|
||||
% \hash is redefined to `#' later to get it into definitions
|
||||
\let\xeatspaces\relax
|
||||
\let\xempty\relax
|
||||
\parsemargdefxxx#1,;,%
|
||||
\ifnum\paramno<10\relax\else
|
||||
\paramno0\relax
|
||||
|
@ -8379,9 +8338,11 @@
|
|||
\else \let\next=\parsemargdefxxx
|
||||
\advance\paramno by 1
|
||||
\expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
|
||||
{\xeatspaces{\hash\the\paramno}}%
|
||||
{\xeatspaces{\hash\the\paramno\noexpand\xempty{}}}%
|
||||
\edef\paramlist{\paramlist\hash\the\paramno,}%
|
||||
\fi\next}
|
||||
% the \xempty{} is to give \eatleadingcr an argument in the case of an
|
||||
% empty macro argument.
|
||||
|
||||
% \parsemacbody, \parsermacbody
|
||||
%
|
||||
|
@ -9107,20 +9068,22 @@
|
|||
% output the `[mynode]' via the macro below so it can be overridden.
|
||||
\xrefprintnodename\printedrefname
|
||||
%
|
||||
% But we always want a comma and a space:
|
||||
,\space
|
||||
%
|
||||
% output the `page 3'.
|
||||
\turnoffactive \putwordpage\tie\refx{#1-pg}{}%
|
||||
% Add a , if xref followed by a space
|
||||
\if\space\noexpand\tokenafterxref ,%
|
||||
\else\ifx\ \tokenafterxref ,% @TAB
|
||||
\else\ifx\*\tokenafterxref ,% @*
|
||||
\else\ifx\ \tokenafterxref ,% @SPACE
|
||||
\else\ifx\
|
||||
\tokenafterxref ,% @NL
|
||||
\else\ifx\tie\tokenafterxref ,% @tie
|
||||
\fi\fi\fi\fi\fi\fi
|
||||
\expandafter\ifx\csname SETtxiomitxrefpg\endcsname\relax
|
||||
% But we always want a comma and a space:
|
||||
,\space
|
||||
%
|
||||
% output the `page 3'.
|
||||
\turnoffactive \putwordpage\tie\refx{#1-pg}{}%
|
||||
% Add a , if xref followed by a space
|
||||
\if\space\noexpand\tokenafterxref ,%
|
||||
\else\ifx\ \tokenafterxref ,% @TAB
|
||||
\else\ifx\*\tokenafterxref ,% @*
|
||||
\else\ifx\ \tokenafterxref ,% @SPACE
|
||||
\else\ifx\
|
||||
\tokenafterxref ,% @NL
|
||||
\else\ifx\tie\tokenafterxref ,% @tie
|
||||
\fi\fi\fi\fi\fi\fi
|
||||
\fi
|
||||
\fi\fi
|
||||
\fi
|
||||
\endlink
|
||||
|
@ -9550,7 +9513,7 @@
|
|||
\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
|
||||
\catcode`\^^M = 5 % in case we're inside an example
|
||||
\normalturnoffactive % allow _ et al. in names
|
||||
\def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro
|
||||
\makevalueexpandable
|
||||
% If the image is by itself, center it.
|
||||
\ifvmode
|
||||
\imagevmodetrue
|
||||
|
@ -11603,7 +11566,7 @@
|
|||
\let> = \activegtr
|
||||
\let~ = \activetilde
|
||||
\let^ = \activehat
|
||||
\markupsetuplqdefault \markupsetuprqdefault
|
||||
\setregularquotes
|
||||
\let\b = \strong
|
||||
\let\i = \smartitalic
|
||||
% in principle, all other definitions in \tex have to be undone too.
|
||||
|
@ -11662,8 +11625,7 @@
|
|||
@let|=@normalverticalbar
|
||||
@let~=@normaltilde
|
||||
@let\=@ttbackslash
|
||||
@markupsetuplqdefault
|
||||
@markupsetuprqdefault
|
||||
@setregularquotes
|
||||
@unsepspaces
|
||||
}
|
||||
}
|
||||
|
@ -11756,8 +11718,7 @@
|
|||
@c Do this last of all since we use ` in the previous @catcode assignments.
|
||||
@catcode`@'=@active
|
||||
@catcode`@`=@active
|
||||
@markupsetuplqdefault
|
||||
@markupsetuprqdefault
|
||||
@setregularquotes
|
||||
|
||||
@c Local variables:
|
||||
@c eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
|
|
|
@ -26,14 +26,16 @@
|
|||
AIX system header files and several gnulib header files use precisely
|
||||
this syntax with 'extern'. */
|
||||
# define _Noreturn [[noreturn]]
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| (!defined __STRICT_ANSI__ \
|
||||
&& (__4 < __GNUC__ + (7 <= __GNUC_MINOR__) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
|
||||
/* _Noreturn works as-is. */
|
||||
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
|
||||
# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \
|
||||
|| 0x5110 <= __SUNPRO_C)
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
|
||||
# define _Noreturn __declspec (noreturn)
|
||||
|
|
|
@ -85,10 +85,6 @@
|
|||
# define IF_LINT(Code) /* empty */
|
||||
#endif
|
||||
|
||||
/* True if adding two valid object sizes might overflow idx_t.
|
||||
As a practical matter, this cannot happen on 64-bit machines. */
|
||||
enum { NARROW_ADDRESSES = IDX_MAX >> 31 >> 31 == 0 };
|
||||
|
||||
#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
# define DOUBLE_SLASH_IS_DISTINCT_ROOT false
|
||||
#endif
|
||||
|
@ -145,11 +141,11 @@ suffix_requires_dir_check (char const *end)
|
|||
macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on
|
||||
platforms like AIX 7.2 that need at least "/.". */
|
||||
|
||||
#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
# if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||
static char const dir_suffix[] = "/";
|
||||
#else
|
||||
# else
|
||||
static char const dir_suffix[] = "/./";
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* Return true if DIR is a searchable dir, false (setting errno) otherwise.
|
||||
DIREND points to the NUL byte at the end of the DIR string.
|
||||
|
@ -191,13 +187,13 @@ get_path_max (void)
|
|||
to pacify GCC is known; even an explicit #pragma does not pacify GCC.
|
||||
When the GCC bug is fixed this workaround should be limited to the
|
||||
broken GCC versions. */
|
||||
#if __GNUC_PREREQ (10, 1)
|
||||
# if defined GCC_LINT || defined lint
|
||||
# if __GNUC_PREREQ (10, 1)
|
||||
# if defined GCC_LINT || defined lint
|
||||
__attribute__ ((__noinline__))
|
||||
# elif __OPTIMIZE__ && !__NO_INLINE__
|
||||
# define GCC_BOGUS_WRETURN_LOCAL_ADDR
|
||||
# elif __OPTIMIZE__ && !__NO_INLINE__
|
||||
# define GCC_BOGUS_WRETURN_LOCAL_ADDR
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
static char *
|
||||
realpath_stk (const char *name, char *resolved,
|
||||
struct scratch_buffer *rname_buf)
|
||||
|
@ -343,7 +339,7 @@ realpath_stk (const char *name, char *resolved,
|
|||
if (end_in_extra_buffer)
|
||||
end_idx = end - extra_buf;
|
||||
size_t len = strlen (end);
|
||||
if (NARROW_ADDRESSES && INT_ADD_OVERFLOW (len, n))
|
||||
if (INT_ADD_OVERFLOW (len, n))
|
||||
{
|
||||
__set_errno (ENOMEM);
|
||||
goto error_nomem;
|
||||
|
@ -443,7 +439,8 @@ __realpath (const char *name, char *resolved)
|
|||
}
|
||||
libc_hidden_def (__realpath)
|
||||
versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
|
||||
#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
|
||||
|
||||
#endif /* defined _LIBC || !FUNC_REALPATH_WORKS */
|
||||
|
||||
|
||||
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
|
||||
|
|
186
lib/cdefs.h
186
lib/cdefs.h
|
@ -25,7 +25,7 @@
|
|||
|
||||
/* The GNU libc does not support any K&R compilers or the traditional mode
|
||||
of ISO C compilers anymore. Check for some of the combinations not
|
||||
anymore supported. */
|
||||
supported anymore. */
|
||||
#if defined __GNUC__ && !defined __STDC__
|
||||
# error "You need a ISO C conforming compiler to use the glibc headers"
|
||||
#endif
|
||||
|
@ -34,31 +34,26 @@
|
|||
#undef __P
|
||||
#undef __PMT
|
||||
|
||||
/* Compilers that are not clang may object to
|
||||
#if defined __clang__ && __has_attribute(...)
|
||||
even though they do not need to evaluate the right-hand side of the &&. */
|
||||
#if defined __clang__ && defined __has_attribute
|
||||
# define __glibc_clang_has_attribute(name) __has_attribute (name)
|
||||
/* Compilers that lack __has_attribute may object to
|
||||
#if defined __has_attribute && __has_attribute (...)
|
||||
even though they do not need to evaluate the right-hand side of the &&.
|
||||
Similarly for __has_builtin, etc. */
|
||||
#if (defined __has_attribute \
|
||||
&& (!defined __clang_minor__ \
|
||||
|| 3 < __clang_major__ + (5 <= __clang_minor__)))
|
||||
# define __glibc_has_attribute(attr) __has_attribute (attr)
|
||||
#else
|
||||
# define __glibc_clang_has_attribute(name) 0
|
||||
# define __glibc_has_attribute(attr) 0
|
||||
#endif
|
||||
|
||||
/* Compilers that are not clang may object to
|
||||
#if defined __clang__ && __has_builtin(...)
|
||||
even though they do not need to evaluate the right-hand side of the &&. */
|
||||
#if defined __clang__ && defined __has_builtin
|
||||
# define __glibc_clang_has_builtin(name) __has_builtin (name)
|
||||
#ifdef __has_builtin
|
||||
# define __glibc_has_builtin(name) __has_builtin (name)
|
||||
#else
|
||||
# define __glibc_clang_has_builtin(name) 0
|
||||
# define __glibc_has_builtin(name) 0
|
||||
#endif
|
||||
|
||||
/* Compilers that are not clang may object to
|
||||
#if defined __clang__ && __has_extension(...)
|
||||
even though they do not need to evaluate the right-hand side of the &&. */
|
||||
#if defined __clang__ && defined __has_extension
|
||||
# define __glibc_clang_has_extension(ext) __has_extension (ext)
|
||||
#ifdef __has_extension
|
||||
# define __glibc_has_extension(ext) __has_extension (ext)
|
||||
#else
|
||||
# define __glibc_clang_has_extension(ext) 0
|
||||
# define __glibc_has_extension(ext) 0
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ || defined __clang__
|
||||
|
@ -74,22 +69,26 @@
|
|||
# endif
|
||||
|
||||
/* GCC can always grok prototypes. For C++ programs we add throw()
|
||||
to help it optimize the function calls. But this works only with
|
||||
to help it optimize the function calls. But this only works with
|
||||
gcc 2.8.x and egcs. For gcc 3.4 and up we even mark C functions
|
||||
as non-throwing using a function attribute since programs can use
|
||||
the -fexceptions options for C code as well. */
|
||||
# if !defined __cplusplus \
|
||||
&& (__GNUC_PREREQ (3, 4) || __glibc_clang_has_attribute (__nothrow__))
|
||||
&& (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__))
|
||||
# define __THROW __attribute__ ((__nothrow__ __LEAF))
|
||||
# define __THROWNL __attribute__ ((__nothrow__))
|
||||
# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
|
||||
# define __NTHNL(fct) __attribute__ ((__nothrow__)) fct
|
||||
# else
|
||||
# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4)
|
||||
# define __THROW throw ()
|
||||
# define __THROWNL throw ()
|
||||
# define __NTH(fct) __LEAF_ATTR fct throw ()
|
||||
# define __NTHNL(fct) fct throw ()
|
||||
# if __cplusplus >= 201103L
|
||||
# define __THROW noexcept (true)
|
||||
# else
|
||||
# define __THROW throw ()
|
||||
# endif
|
||||
# define __THROWNL __THROW
|
||||
# define __NTH(fct) __LEAF_ATTR fct __THROW
|
||||
# define __NTHNL(fct) fct __THROW
|
||||
# else
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
|
@ -142,24 +141,20 @@
|
|||
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
|
||||
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||
|
||||
/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
|
||||
#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
|
||||
# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
|
||||
# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
|
||||
#else
|
||||
# define __glibc_objsize0(__o) __bos0 (__o)
|
||||
# define __glibc_objsize(__o) __bos (__o)
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __warndecl(name, msg) \
|
||||
extern void name (void) __attribute__((__warning__ (msg)))
|
||||
# define __warnattr(msg) __attribute__((__warning__ (msg)))
|
||||
# define __errordecl(name, msg) \
|
||||
extern void name (void) __attribute__((__error__ (msg)))
|
||||
#elif __glibc_clang_has_attribute (__diagnose_if__) && 0
|
||||
/* These definitions are not enabled, because they produce bogus warnings
|
||||
in the glibc Fortify functions. These functions are written in a style
|
||||
that works with GCC. In order to work with clang, these functions would
|
||||
need to be modified. */
|
||||
# define __warndecl(name, msg) \
|
||||
extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning")))
|
||||
# define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning")))
|
||||
# define __errordecl(name, msg) \
|
||||
extern void name (void) __attribute__((__diagnose_if__ (1, msg, "error")))
|
||||
#else
|
||||
# define __warndecl(name, msg) extern void name (void)
|
||||
# define __warnattr(msg)
|
||||
# define __errordecl(name, msg) extern void name (void)
|
||||
#endif
|
||||
|
@ -233,7 +228,7 @@
|
|||
/* At some point during the gcc 2.96 development the `malloc' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__malloc__)
|
||||
#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__)
|
||||
# define __attribute_malloc__ __attribute__ ((__malloc__))
|
||||
#else
|
||||
# define __attribute_malloc__ /* Ignore */
|
||||
|
@ -251,23 +246,31 @@
|
|||
/* At some point during the gcc 2.96 development the `pure' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__pure__)
|
||||
#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__)
|
||||
# define __attribute_pure__ __attribute__ ((__pure__))
|
||||
#else
|
||||
# define __attribute_pure__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* This declaration tells the compiler that the value is constant. */
|
||||
#if __GNUC_PREREQ (2,5) || __glibc_clang_has_attribute (__const__)
|
||||
#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__)
|
||||
# define __attribute_const__ __attribute__ ((__const__))
|
||||
#else
|
||||
# define __attribute_const__ /* Ignore */
|
||||
#endif
|
||||
|
||||
#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
|
||||
# define __attribute_maybe_unused__ [[__maybe_unused__]]
|
||||
#elif __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)
|
||||
# define __attribute_maybe_unused__ __attribute__ ((__unused__))
|
||||
#else
|
||||
# define __attribute_maybe_unused__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 3.1 development the `used' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (3,1) || __glibc_clang_has_attribute (__used__)
|
||||
#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__)
|
||||
# define __attribute_used__ __attribute__ ((__used__))
|
||||
# define __attribute_noinline__ __attribute__ ((__noinline__))
|
||||
#else
|
||||
|
@ -276,7 +279,7 @@
|
|||
#endif
|
||||
|
||||
/* Since version 3.2, gcc allows marking deprecated functions. */
|
||||
#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__deprecated__)
|
||||
#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__)
|
||||
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
|
||||
#else
|
||||
# define __attribute_deprecated__ /* Ignore */
|
||||
|
@ -285,8 +288,8 @@
|
|||
/* Since version 4.5, gcc also allows one to specify the message printed
|
||||
when a deprecated function is used. clang claims to be gcc 4.2, but
|
||||
may also support this feature. */
|
||||
#if __GNUC_PREREQ (4,5) || \
|
||||
__glibc_clang_has_extension (__attribute_deprecated_with_message__)
|
||||
#if __GNUC_PREREQ (4,5) \
|
||||
|| __glibc_has_extension (__attribute_deprecated_with_message__)
|
||||
# define __attribute_deprecated_msg__(msg) \
|
||||
__attribute__ ((__deprecated__ (msg)))
|
||||
#else
|
||||
|
@ -299,7 +302,7 @@
|
|||
If several `format_arg' attributes are given for the same function, in
|
||||
gcc-3.0 and older, all but the last one are ignored. In newer gccs,
|
||||
all designated arguments are considered. */
|
||||
#if __GNUC_PREREQ (2,8) || __glibc_clang_has_attribute (__format_arg__)
|
||||
#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__)
|
||||
# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
|
||||
#else
|
||||
# define __attribute_format_arg__(x) /* Ignore */
|
||||
|
@ -309,7 +312,7 @@
|
|||
attribute for functions was introduced. We don't want to use it
|
||||
unconditionally (although this would be possible) since it
|
||||
generates warnings. */
|
||||
#if __GNUC_PREREQ (2,97) || __glibc_clang_has_attribute (__format__)
|
||||
#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__)
|
||||
# define __attribute_format_strfmon__(a,b) \
|
||||
__attribute__ ((__format__ (__strfmon__, a, b)))
|
||||
#else
|
||||
|
@ -320,7 +323,7 @@
|
|||
must not be NULL. Do not define __nonnull if it is already defined,
|
||||
for portability when this file is used in Gnulib. */
|
||||
#ifndef __nonnull
|
||||
# if __GNUC_PREREQ (3,3) || __glibc_clang_has_attribute (__nonnull__)
|
||||
# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)
|
||||
# define __nonnull(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define __nonnull(params)
|
||||
|
@ -329,7 +332,7 @@
|
|||
|
||||
/* If fortification mode, we warn about unused results of certain
|
||||
function calls which can lead to problems. */
|
||||
#if __GNUC_PREREQ (3,4) || __glibc_clang_has_attribute (__warn_unused_result__)
|
||||
#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__)
|
||||
# define __attribute_warn_unused_result__ \
|
||||
__attribute__ ((__warn_unused_result__))
|
||||
# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
|
||||
|
@ -343,7 +346,7 @@
|
|||
#endif
|
||||
|
||||
/* Forces a function to be always inlined. */
|
||||
#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__always_inline__)
|
||||
#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__)
|
||||
/* The Linux kernel defines __always_inline in stddef.h (283d7573), and
|
||||
it conflicts with this definition. Therefore undefine it first to
|
||||
allow either header to be included first. */
|
||||
|
@ -356,7 +359,7 @@
|
|||
|
||||
/* Associate error messages with the source location of the call site rather
|
||||
than with the source location inside the function. */
|
||||
#if __GNUC_PREREQ (4,3) || __glibc_clang_has_attribute (__artificial__)
|
||||
#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__)
|
||||
# define __attribute_artificial__ __attribute__ ((__artificial__))
|
||||
#else
|
||||
# define __attribute_artificial__ /* Ignore */
|
||||
|
@ -433,7 +436,7 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 3) || __glibc_clang_has_builtin (__builtin_expect)
|
||||
#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect)
|
||||
# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
|
||||
# define __glibc_likely(cond) __builtin_expect ((cond), 1)
|
||||
#else
|
||||
|
@ -441,12 +444,6 @@
|
|||
# define __glibc_likely(cond) (cond)
|
||||
#endif
|
||||
|
||||
#ifdef __has_attribute
|
||||
# define __glibc_has_attribute(attr) __has_attribute (attr)
|
||||
#else
|
||||
# define __glibc_has_attribute(attr) 0
|
||||
#endif
|
||||
|
||||
#if (!defined _Noreturn \
|
||||
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
|
||||
&& !(__GNUC_PREREQ (4,7) \
|
||||
|
@ -467,6 +464,16 @@
|
|||
# define __attribute_nonstring__
|
||||
#endif
|
||||
|
||||
/* Undefine (also defined in libc-symbols.h). */
|
||||
#undef __attribute_copy__
|
||||
#if __GNUC_PREREQ (9, 0)
|
||||
/* Copies attributes from the declaration or type referenced by
|
||||
the argument. */
|
||||
# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg)))
|
||||
#else
|
||||
# define __attribute_copy__(arg)
|
||||
#endif
|
||||
|
||||
#if (!defined _Static_assert && !defined __cplusplus \
|
||||
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
|
||||
&& (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \
|
||||
|
@ -483,7 +490,37 @@
|
|||
# include <bits/long-double.h>
|
||||
#endif
|
||||
|
||||
#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
|
||||
#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
|
||||
# ifdef __REDIRECT
|
||||
|
||||
/* Alias name defined automatically. */
|
||||
# define __LDBL_REDIR(name, proto) ... unused__ldbl_redir
|
||||
# define __LDBL_REDIR_DECL(name) \
|
||||
extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128"));
|
||||
|
||||
/* Alias name defined automatically, with leading underscores. */
|
||||
# define __LDBL_REDIR2_DECL(name) \
|
||||
extern __typeof (__##name) __##name \
|
||||
__asm (__ASMNAME ("__" #name "ieee128"));
|
||||
|
||||
/* Alias name defined manually. */
|
||||
# define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1
|
||||
# define __LDBL_REDIR1_DECL(name, alias) \
|
||||
extern __typeof (name) name __asm (__ASMNAME (#alias));
|
||||
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) \
|
||||
__REDIRECT_NTH (name, proto, alias)
|
||||
# define __REDIRECT_NTH_LDBL(name, proto, alias) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __##alias##ieee128)
|
||||
|
||||
/* Unused. */
|
||||
# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl
|
||||
# define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth
|
||||
|
||||
# else
|
||||
_Static_assert (0, "IEEE 128-bits long double requires redirection on this platform");
|
||||
# endif
|
||||
#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
|
||||
# define __LDBL_COMPAT 1
|
||||
# ifdef __REDIRECT
|
||||
# define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
|
||||
|
@ -492,6 +529,8 @@
|
|||
# define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)
|
||||
# define __LDBL_REDIR_NTH(name, proto) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __nldbl_##name)
|
||||
# define __LDBL_REDIR2_DECL(name) \
|
||||
extern __typeof (__##name) __##name __asm (__ASMNAME ("__nldbl___" #name));
|
||||
# define __LDBL_REDIR1_DECL(name, alias) \
|
||||
extern __typeof (name) name __asm (__ASMNAME (#alias));
|
||||
# define __LDBL_REDIR_DECL(name) \
|
||||
|
@ -502,11 +541,13 @@
|
|||
__LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined __LDBL_COMPAT || !defined __REDIRECT
|
||||
#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \
|
||||
|| !defined __REDIRECT
|
||||
# define __LDBL_REDIR1(name, proto, alias) name proto
|
||||
# define __LDBL_REDIR(name, proto) name proto
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
|
||||
# define __LDBL_REDIR_NTH(name, proto) name proto __THROW
|
||||
# define __LDBL_REDIR2_DECL(name)
|
||||
# define __LDBL_REDIR_DECL(name)
|
||||
# ifdef __REDIRECT
|
||||
# define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
|
||||
|
@ -537,7 +578,7 @@
|
|||
check is required to enable the use of generic selection. */
|
||||
#if !defined __cplusplus \
|
||||
&& (__GNUC_PREREQ (4, 9) \
|
||||
|| __glibc_clang_has_extension (c_generic_selections) \
|
||||
|| __glibc_has_extension (c_generic_selections) \
|
||||
|| (!defined __GNUC__ && defined __STDC_VERSION__ \
|
||||
&& __STDC_VERSION__ >= 201112L))
|
||||
# define __HAVE_GENERIC_SELECTION 1
|
||||
|
@ -545,4 +586,23 @@
|
|||
# define __HAVE_GENERIC_SELECTION 0
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (10, 0)
|
||||
/* Designates a 1-based positional argument ref-index of pointer type
|
||||
that can be used to access size-index elements of the pointed-to
|
||||
array according to access mode, or at least one element when
|
||||
size-index is not provided:
|
||||
access (access-mode, <ref-index> [, <size-index>]) */
|
||||
#define __attr_access(x) __attribute__ ((__access__ x))
|
||||
#else
|
||||
# define __attr_access(x)
|
||||
#endif
|
||||
|
||||
/* Specify that a function such as setjmp or vfork may return
|
||||
twice. */
|
||||
#if __GNUC_PREREQ (4, 1)
|
||||
# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))
|
||||
#else
|
||||
# define __attribute_returns_twice__ /* Ignore. */
|
||||
#endif
|
||||
|
||||
#endif /* sys/cdefs.h */
|
||||
|
|
|
@ -154,7 +154,8 @@ _GL_WARN_ON_USE (closedir, "closedir is not portable - "
|
|||
/* Return the file descriptor associated with the given directory stream,
|
||||
or -1 if none exists. */
|
||||
# if @REPLACE_DIRFD@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
/* On kLIBC, dirfd() is a macro that does not work. Undefine it. */
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE) || defined dirfd
|
||||
# undef dirfd
|
||||
# define dirfd rpl_dirfd
|
||||
# endif
|
||||
|
|
31
lib/dynarray.h
Normal file
31
lib/dynarray.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* Type-safe arrays which grow dynamically.
|
||||
Copyright 2021 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, 2021. */
|
||||
|
||||
#ifndef _GL_DYNARRAY_H
|
||||
#define _GL_DYNARRAY_H
|
||||
|
||||
#include <libc-config.h>
|
||||
|
||||
#define __libc_dynarray_at_failure gl_dynarray_at_failure
|
||||
#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge
|
||||
#define __libc_dynarray_finalize gl_dynarray_finalize
|
||||
#define __libc_dynarray_resize_clear gl_dynarray_resize_clear
|
||||
#define __libc_dynarray_resize gl_dynarray_resize
|
||||
#include <malloc/dynarray.h>
|
||||
|
||||
#endif /* _GL_DYNARRAY_H */
|
|
@ -38,6 +38,7 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags)
|
|||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __osf__
|
||||
|
@ -63,6 +64,22 @@ orig_fchmodat (int dir, char const *file, mode_t mode, int flags)
|
|||
int
|
||||
fchmodat (int dir, char const *file, mode_t mode, int flags)
|
||||
{
|
||||
# if HAVE_NEARLY_WORKING_FCHMODAT
|
||||
/* Correct the trailing slash handling. */
|
||||
size_t len = strlen (file);
|
||||
if (len && file[len - 1] == '/')
|
||||
{
|
||||
struct stat st;
|
||||
if (fstatat (dir, file, &st, flags & AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return -1;
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
# if NEED_FCHMODAT_NONSYMLINK_FIX
|
||||
if (flags == AT_SYMLINK_NOFOLLOW)
|
||||
{
|
||||
|
|
14
lib/free.c
14
lib/free.c
|
@ -27,7 +27,21 @@ void
|
|||
rpl_free (void *p)
|
||||
#undef free
|
||||
{
|
||||
#if defined __GNUC__ && !defined __clang__
|
||||
/* An invalid GCC optimization
|
||||
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98396>
|
||||
would optimize away the assignments in the code below, when link-time
|
||||
optimization (LTO) is enabled. Make the code more complicated, so that
|
||||
GCC does not grok how to optimize it. */
|
||||
int err[2];
|
||||
err[0] = errno;
|
||||
err[1] = errno;
|
||||
errno = 0;
|
||||
free (p);
|
||||
errno = err[errno == 0];
|
||||
#else
|
||||
int err = errno;
|
||||
free (p);
|
||||
errno = err;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -516,6 +516,7 @@ GNULIB_SYMLINK = @GNULIB_SYMLINK@
|
|||
GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
|
||||
GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
|
||||
GNULIB_TIMEGM = @GNULIB_TIMEGM@
|
||||
GNULIB_TIMESPEC_GET = @GNULIB_TIMESPEC_GET@
|
||||
GNULIB_TIME_R = @GNULIB_TIME_R@
|
||||
GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
|
||||
GNULIB_TMPFILE = @GNULIB_TMPFILE@
|
||||
|
@ -746,6 +747,7 @@ HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@
|
|||
HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
|
||||
HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
|
||||
HAVE_TIMEGM = @HAVE_TIMEGM@
|
||||
HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@
|
||||
HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
|
||||
HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
|
||||
HAVE_UNISTD_H = @HAVE_UNISTD_H@
|
||||
|
@ -949,6 +951,7 @@ REPLACE_FCNTL = @REPLACE_FCNTL@
|
|||
REPLACE_FDOPEN = @REPLACE_FDOPEN@
|
||||
REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@
|
||||
REPLACE_FFLUSH = @REPLACE_FFLUSH@
|
||||
REPLACE_FFSLL = @REPLACE_FFSLL@
|
||||
REPLACE_FOPEN = @REPLACE_FOPEN@
|
||||
REPLACE_FPRINTF = @REPLACE_FPRINTF@
|
||||
REPLACE_FPURGE = @REPLACE_FPURGE@
|
||||
|
@ -989,7 +992,9 @@ REPLACE_MEMCHR = @REPLACE_MEMCHR@
|
|||
REPLACE_MEMMEM = @REPLACE_MEMMEM@
|
||||
REPLACE_MKDIR = @REPLACE_MKDIR@
|
||||
REPLACE_MKFIFO = @REPLACE_MKFIFO@
|
||||
REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@
|
||||
REPLACE_MKNOD = @REPLACE_MKNOD@
|
||||
REPLACE_MKNODAT = @REPLACE_MKNODAT@
|
||||
REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
|
||||
REPLACE_MKTIME = @REPLACE_MKTIME@
|
||||
REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
|
||||
|
@ -1087,6 +1092,7 @@ SYSTEM_TYPE = @SYSTEM_TYPE@
|
|||
SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
|
||||
TERMCAP_OBJ = @TERMCAP_OBJ@
|
||||
TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
|
||||
TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@
|
||||
TOOLKIT_LIBW = @TOOLKIT_LIBW@
|
||||
UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
|
||||
UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
|
||||
|
@ -1171,6 +1177,7 @@ gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 = @gl_GNULIB_ENABLED_a9786850
|
|||
gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 = @gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36@
|
||||
gl_GNULIB_ENABLED_cloexec = @gl_GNULIB_ENABLED_cloexec@
|
||||
gl_GNULIB_ENABLED_dirfd = @gl_GNULIB_ENABLED_dirfd@
|
||||
gl_GNULIB_ENABLED_dynarray = @gl_GNULIB_ENABLED_dynarray@
|
||||
gl_GNULIB_ENABLED_euidaccess = @gl_GNULIB_ENABLED_euidaccess@
|
||||
gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@
|
||||
gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@
|
||||
|
@ -1584,6 +1591,20 @@ EXTRA_libgnu_a_SOURCES += dup2.c
|
|||
endif
|
||||
## end gnulib module dup2
|
||||
|
||||
## begin gnulib module dynarray
|
||||
ifeq (,$(OMIT_GNULIB_MODULE_dynarray))
|
||||
|
||||
ifneq (,$(gl_GNULIB_ENABLED_dynarray))
|
||||
libgnu_a_SOURCES += malloc/dynarray_at_failure.c malloc/dynarray_emplace_enlarge.c malloc/dynarray_finalize.c malloc/dynarray_resize.c malloc/dynarray_resize_clear.c
|
||||
|
||||
endif
|
||||
EXTRA_DIST += dynarray.h malloc/dynarray-skeleton.c malloc/dynarray.h
|
||||
|
||||
EXTRA_libgnu_a_SOURCES += malloc/dynarray-skeleton.c
|
||||
|
||||
endif
|
||||
## end gnulib module dynarray
|
||||
|
||||
## begin gnulib module eloop-threshold
|
||||
ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold))
|
||||
|
||||
|
@ -3036,6 +3057,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
|
|||
-e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \
|
||||
-e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
|
||||
-e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
|
||||
-e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \
|
||||
-e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
|
||||
-e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
|
||||
-e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
|
||||
|
@ -3237,7 +3259,9 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
|
|||
-e 's|@''REPLACE_LSTAT''@|$(REPLACE_LSTAT)|g' \
|
||||
-e 's|@''REPLACE_MKDIR''@|$(REPLACE_MKDIR)|g' \
|
||||
-e 's|@''REPLACE_MKFIFO''@|$(REPLACE_MKFIFO)|g' \
|
||||
-e 's|@''REPLACE_MKFIFOAT''@|$(REPLACE_MKFIFOAT)|g' \
|
||||
-e 's|@''REPLACE_MKNOD''@|$(REPLACE_MKNOD)|g' \
|
||||
-e 's|@''REPLACE_MKNODAT''@|$(REPLACE_MKNODAT)|g' \
|
||||
-e 's|@''REPLACE_STAT''@|$(REPLACE_STAT)|g' \
|
||||
-e 's|@''REPLACE_UTIMENSAT''@|$(REPLACE_UTIMENSAT)|g' \
|
||||
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
|
||||
|
@ -3350,6 +3374,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's/@''GNULIB_STRFTIME''@/$(GNULIB_STRFTIME)/g' \
|
||||
-e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \
|
||||
-e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \
|
||||
-e 's/@''GNULIB_TIMESPEC_GET''@/$(GNULIB_TIMESPEC_GET)/g' \
|
||||
-e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \
|
||||
-e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \
|
||||
-e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \
|
||||
|
@ -3358,6 +3383,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's|@''HAVE_NANOSLEEP''@|$(HAVE_NANOSLEEP)|g' \
|
||||
-e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
|
||||
-e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
|
||||
-e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \
|
||||
-e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
|
||||
-e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \
|
||||
-e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
|
||||
|
@ -3372,6 +3398,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
|
|||
-e 's|@''SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e 's|@''TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e 's|@''UNISTD_H_DEFINES_STRUCT_TIMESPEC''@|$(UNISTD_H_DEFINES_STRUCT_TIMESPEC)|g' \
|
||||
-e 's|@''TIME_H_DEFINES_TIME_UTC''@|$(TIME_H_DEFINES_TIME_UTC)|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)' \
|
||||
|
|
|
@ -71,107 +71,112 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Prepare to include <cdefs.h>, which is our copy of glibc
|
||||
<sys/cdefs.h>. */
|
||||
#ifndef __attribute_maybe_unused__
|
||||
/* <sys/cdefs.h> either does not exist, or is too old for Gnulib.
|
||||
Prepare to include <cdefs.h>, which is Gnulib's version of a
|
||||
more-recent glibc <sys/cdefs.h>. */
|
||||
|
||||
/* Define _FEATURES_H so that <cdefs.h> does not include <features.h>. */
|
||||
#ifndef _FEATURES_H
|
||||
# define _FEATURES_H 1
|
||||
#endif
|
||||
# ifndef _FEATURES_H
|
||||
# define _FEATURES_H 1
|
||||
# endif
|
||||
/* Define __WORDSIZE so that <cdefs.h> does not attempt to include
|
||||
nonexistent files. Make it a syntax error, since Gnulib does not
|
||||
use __WORDSIZE now, and if Gnulib uses it later the syntax error
|
||||
will let us know that __WORDSIZE needs configuring. */
|
||||
#ifndef __WORDSIZE
|
||||
# define __WORDSIZE %%%
|
||||
#endif
|
||||
# ifndef __WORDSIZE
|
||||
# define __WORDSIZE %%%
|
||||
# endif
|
||||
/* Undef the macros unconditionally defined by our copy of glibc
|
||||
<sys/cdefs.h>, so that they do not clash with any system-defined
|
||||
versions. */
|
||||
#undef _SYS_CDEFS_H
|
||||
#undef __ASMNAME
|
||||
#undef __ASMNAME2
|
||||
#undef __BEGIN_DECLS
|
||||
#undef __CONCAT
|
||||
#undef __END_DECLS
|
||||
#undef __HAVE_GENERIC_SELECTION
|
||||
#undef __LDBL_COMPAT
|
||||
#undef __LDBL_REDIR
|
||||
#undef __LDBL_REDIR1
|
||||
#undef __LDBL_REDIR1_DECL
|
||||
#undef __LDBL_REDIR1_NTH
|
||||
#undef __LDBL_REDIR_DECL
|
||||
#undef __LDBL_REDIR_NTH
|
||||
#undef __LEAF
|
||||
#undef __LEAF_ATTR
|
||||
#undef __NTH
|
||||
#undef __NTHNL
|
||||
#undef __P
|
||||
#undef __PMT
|
||||
#undef __REDIRECT
|
||||
#undef __REDIRECT_LDBL
|
||||
#undef __REDIRECT_NTH
|
||||
#undef __REDIRECT_NTHNL
|
||||
#undef __REDIRECT_NTH_LDBL
|
||||
#undef __STRING
|
||||
#undef __THROW
|
||||
#undef __THROWNL
|
||||
#undef __always_inline
|
||||
#undef __attribute__
|
||||
#undef __attribute_alloc_size__
|
||||
#undef __attribute_artificial__
|
||||
#undef __attribute_const__
|
||||
#undef __attribute_deprecated__
|
||||
#undef __attribute_deprecated_msg__
|
||||
#undef __attribute_format_arg__
|
||||
#undef __attribute_format_strfmon__
|
||||
#undef __attribute_malloc__
|
||||
#undef __attribute_noinline__
|
||||
#undef __attribute_nonstring__
|
||||
#undef __attribute_pure__
|
||||
#undef __attribute_used__
|
||||
#undef __attribute_warn_unused_result__
|
||||
#undef __bos
|
||||
#undef __bos0
|
||||
#undef __errordecl
|
||||
#undef __extension__
|
||||
#undef __extern_always_inline
|
||||
#undef __extern_inline
|
||||
#undef __flexarr
|
||||
#undef __fortify_function
|
||||
#undef __glibc_c99_flexarr_available
|
||||
#undef __glibc_clang_has_extension
|
||||
#undef __glibc_likely
|
||||
#undef __glibc_macro_warning
|
||||
#undef __glibc_macro_warning1
|
||||
#undef __glibc_unlikely
|
||||
#undef __inline
|
||||
#undef __ptr_t
|
||||
#undef __restrict
|
||||
#undef __restrict_arr
|
||||
#undef __va_arg_pack
|
||||
#undef __va_arg_pack_len
|
||||
#undef __warnattr
|
||||
#undef __warndecl
|
||||
# undef _SYS_CDEFS_H
|
||||
# undef __ASMNAME
|
||||
# undef __ASMNAME2
|
||||
# undef __BEGIN_DECLS
|
||||
# undef __CONCAT
|
||||
# undef __END_DECLS
|
||||
# undef __HAVE_GENERIC_SELECTION
|
||||
# undef __LDBL_COMPAT
|
||||
# undef __LDBL_REDIR
|
||||
# undef __LDBL_REDIR1
|
||||
# undef __LDBL_REDIR1_DECL
|
||||
# undef __LDBL_REDIR1_NTH
|
||||
# undef __LDBL_REDIR2_DECL
|
||||
# undef __LDBL_REDIR_DECL
|
||||
# undef __LDBL_REDIR_NTH
|
||||
# undef __LEAF
|
||||
# undef __LEAF_ATTR
|
||||
# undef __NTH
|
||||
# undef __NTHNL
|
||||
# undef __REDIRECT
|
||||
# undef __REDIRECT_LDBL
|
||||
# undef __REDIRECT_NTH
|
||||
# undef __REDIRECT_NTHNL
|
||||
# undef __REDIRECT_NTH_LDBL
|
||||
# undef __STRING
|
||||
# undef __THROW
|
||||
# undef __THROWNL
|
||||
# undef __attr_access
|
||||
# undef __attribute__
|
||||
# undef __attribute_alloc_size__
|
||||
# undef __attribute_artificial__
|
||||
# undef __attribute_const__
|
||||
# undef __attribute_deprecated__
|
||||
# undef __attribute_deprecated_msg__
|
||||
# undef __attribute_format_arg__
|
||||
# undef __attribute_format_strfmon__
|
||||
# undef __attribute_malloc__
|
||||
# undef __attribute_noinline__
|
||||
# undef __attribute_nonstring__
|
||||
# undef __attribute_pure__
|
||||
# undef __attribute_returns_twice__
|
||||
# undef __attribute_used__
|
||||
# undef __attribute_warn_unused_result__
|
||||
# undef __bos
|
||||
# undef __bos0
|
||||
# undef __errordecl
|
||||
# undef __extension__
|
||||
# undef __extern_always_inline
|
||||
# undef __extern_inline
|
||||
# undef __flexarr
|
||||
# undef __fortify_function
|
||||
# undef __glibc_c99_flexarr_available
|
||||
# undef __glibc_has_attribute
|
||||
# undef __glibc_has_builtin
|
||||
# undef __glibc_has_extension
|
||||
# undef __glibc_macro_warning
|
||||
# undef __glibc_macro_warning1
|
||||
# undef __glibc_objsize
|
||||
# undef __glibc_objsize0
|
||||
# undef __glibc_unlikely
|
||||
# undef __inline
|
||||
# undef __ptr_t
|
||||
# undef __restrict
|
||||
# undef __restrict_arr
|
||||
# undef __va_arg_pack
|
||||
# undef __va_arg_pack_len
|
||||
# undef __warnattr
|
||||
|
||||
/* Include our copy of glibc <sys/cdefs.h>. */
|
||||
#include <cdefs.h>
|
||||
# include <cdefs.h>
|
||||
|
||||
/* <cdefs.h> __inline is too pessimistic for non-GCC. */
|
||||
#undef __inline
|
||||
#ifndef HAVE___INLINE
|
||||
# if 199901 <= __STDC_VERSION__ || defined inline
|
||||
# define __inline inline
|
||||
# else
|
||||
# define __inline
|
||||
# undef __inline
|
||||
# ifndef HAVE___INLINE
|
||||
# if 199901 <= __STDC_VERSION__ || defined inline
|
||||
# define __inline inline
|
||||
# else
|
||||
# define __inline
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* defined __glibc_likely */
|
||||
|
||||
|
||||
/* A substitute for glibc <libc-symbols.h>, good enough for Gnulib. */
|
||||
#define attribute_hidden
|
||||
#define libc_hidden_proto(name, ...)
|
||||
#define libc_hidden_proto(name)
|
||||
#define libc_hidden_def(name)
|
||||
#define libc_hidden_weak(name)
|
||||
#define libc_hidden_ver(local, name)
|
||||
|
|
525
lib/malloc/dynarray-skeleton.c
Normal file
525
lib/malloc/dynarray-skeleton.c
Normal file
|
@ -0,0 +1,525 @@
|
|||
/* Type-safe arrays which grow dynamically.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Pre-processor macros which act as parameters:
|
||||
|
||||
DYNARRAY_STRUCT
|
||||
The struct tag of dynamic array to be defined.
|
||||
DYNARRAY_ELEMENT
|
||||
The type name of the element type. Elements are copied
|
||||
as if by memcpy, and can change address as the dynamic
|
||||
array grows.
|
||||
DYNARRAY_PREFIX
|
||||
The prefix of the functions which are defined.
|
||||
|
||||
The following parameters are optional:
|
||||
|
||||
DYNARRAY_ELEMENT_FREE
|
||||
DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the
|
||||
contents of elements. E is of type DYNARRAY_ELEMENT *.
|
||||
DYNARRAY_ELEMENT_INIT
|
||||
DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new
|
||||
element. E is of type DYNARRAY_ELEMENT *.
|
||||
If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is
|
||||
defined, new elements are automatically zero-initialized.
|
||||
Otherwise, new elements have undefined contents.
|
||||
DYNARRAY_INITIAL_SIZE
|
||||
The size of the statically allocated array (default:
|
||||
at least 2, more elements if they fit into 128 bytes).
|
||||
Must be a preprocessor constant. If DYNARRAY_INITIAL_SIZE is 0,
|
||||
there is no statically allocated array at, and all non-empty
|
||||
arrays are heap-allocated.
|
||||
DYNARRAY_FINAL_TYPE
|
||||
The name of the type which holds the final array. If not
|
||||
defined, is PREFIX##finalize not provided. DYNARRAY_FINAL_TYPE
|
||||
must be a struct type, with members of type DYNARRAY_ELEMENT and
|
||||
size_t at the start (in this order).
|
||||
|
||||
These macros are undefined after this header file has been
|
||||
included.
|
||||
|
||||
The following types are provided (their members are private to the
|
||||
dynarray implementation):
|
||||
|
||||
struct DYNARRAY_STRUCT
|
||||
|
||||
The following functions are provided:
|
||||
|
||||
void DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *);
|
||||
void DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *);
|
||||
bool DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *);
|
||||
void DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *);
|
||||
size_t DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *);
|
||||
DYNARRAY_ELEMENT *DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *);
|
||||
DYNARRAY_ELEMENT *DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *);
|
||||
DYNARRAY_ELEMENT *DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *, size_t);
|
||||
void DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *, DYNARRAY_ELEMENT);
|
||||
DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *);
|
||||
bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t);
|
||||
void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *);
|
||||
void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *);
|
||||
|
||||
The following functions are provided are provided if the
|
||||
prerequisites are met:
|
||||
|
||||
bool DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,
|
||||
DYNARRAY_FINAL_TYPE *);
|
||||
(if DYNARRAY_FINAL_TYPE is defined)
|
||||
DYNARRAY_ELEMENT *DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,
|
||||
size_t *);
|
||||
(if DYNARRAY_FINAL_TYPE is not defined)
|
||||
*/
|
||||
|
||||
#include <malloc/dynarray.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef DYNARRAY_STRUCT
|
||||
# error "DYNARRAY_STRUCT must be defined"
|
||||
#endif
|
||||
|
||||
#ifndef DYNARRAY_ELEMENT
|
||||
# error "DYNARRAY_ELEMENT must be defined"
|
||||
#endif
|
||||
|
||||
#ifndef DYNARRAY_PREFIX
|
||||
# error "DYNARRAY_PREFIX must be defined"
|
||||
#endif
|
||||
|
||||
#ifdef DYNARRAY_INITIAL_SIZE
|
||||
# if DYNARRAY_INITIAL_SIZE < 0
|
||||
# error "DYNARRAY_INITIAL_SIZE must be non-negative"
|
||||
# endif
|
||||
# if DYNARRAY_INITIAL_SIZE > 0
|
||||
# define DYNARRAY_HAVE_SCRATCH 1
|
||||
# else
|
||||
# define DYNARRAY_HAVE_SCRATCH 0
|
||||
# endif
|
||||
#else
|
||||
/* Provide a reasonable default which limits the size of
|
||||
DYNARRAY_STRUCT. */
|
||||
# define DYNARRAY_INITIAL_SIZE \
|
||||
(sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT))
|
||||
# define DYNARRAY_HAVE_SCRATCH 1
|
||||
#endif
|
||||
|
||||
/* Public type definitions. */
|
||||
|
||||
/* All fields of this struct are private to the implementation. */
|
||||
struct DYNARRAY_STRUCT
|
||||
{
|
||||
union
|
||||
{
|
||||
struct dynarray_header dynarray_abstract;
|
||||
struct
|
||||
{
|
||||
/* These fields must match struct dynarray_header. */
|
||||
size_t used;
|
||||
size_t allocated;
|
||||
DYNARRAY_ELEMENT *array;
|
||||
} dynarray_header;
|
||||
} u;
|
||||
|
||||
#if DYNARRAY_HAVE_SCRATCH
|
||||
/* Initial inline allocation. */
|
||||
DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Internal use only: Helper macros. */
|
||||
|
||||
/* Ensure macro-expansion of DYNARRAY_PREFIX. */
|
||||
#define DYNARRAY_CONCAT0(prefix, name) prefix##name
|
||||
#define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)
|
||||
#define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)
|
||||
|
||||
/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free),
|
||||
so that Gnulib does not change 'free' to 'rpl_free'. */
|
||||
#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)
|
||||
|
||||
/* Address of the scratch buffer if any. */
|
||||
#if DYNARRAY_HAVE_SCRATCH
|
||||
# define DYNARRAY_SCRATCH(list) (list)->scratch
|
||||
#else
|
||||
# define DYNARRAY_SCRATCH(list) NULL
|
||||
#endif
|
||||
|
||||
/* Internal use only: Helper functions. */
|
||||
|
||||
/* Internal function. Call DYNARRAY_ELEMENT_FREE with the array
|
||||
elements. Name mangling needed due to the DYNARRAY_ELEMENT_FREE
|
||||
macro expansion. */
|
||||
static inline void
|
||||
DYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array,
|
||||
size_t __dynarray_used)
|
||||
{
|
||||
#ifdef DYNARRAY_ELEMENT_FREE
|
||||
for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i)
|
||||
DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]);
|
||||
#endif /* DYNARRAY_ELEMENT_FREE */
|
||||
}
|
||||
|
||||
/* Internal function. Free the non-scratch array allocation. */
|
||||
static inline void
|
||||
DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
#if DYNARRAY_HAVE_SCRATCH
|
||||
if (list->u.dynarray_header.array != list->scratch)
|
||||
free (list->u.dynarray_header.array);
|
||||
#else
|
||||
free (list->u.dynarray_header.array);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Public functions. */
|
||||
|
||||
/* Initialize a dynamic array object. This must be called before any
|
||||
use of the object. */
|
||||
__nonnull ((1))
|
||||
static void
|
||||
DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
list->u.dynarray_header.used = 0;
|
||||
list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
|
||||
list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
|
||||
}
|
||||
|
||||
/* Deallocate the dynamic array and its elements. */
|
||||
__attribute_maybe_unused__ __nonnull ((1))
|
||||
static void
|
||||
DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
DYNARRAY_NAME (free__elements__)
|
||||
(list->u.dynarray_header.array, list->u.dynarray_header.used);
|
||||
DYNARRAY_NAME (free__array__) (list);
|
||||
DYNARRAY_NAME (init) (list);
|
||||
}
|
||||
|
||||
/* Return true if the dynamic array is in an error state. */
|
||||
__nonnull ((1))
|
||||
static inline bool
|
||||
DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
return list->u.dynarray_header.allocated == __dynarray_error_marker ();
|
||||
}
|
||||
|
||||
/* Mark the dynamic array as failed. All elements are deallocated as
|
||||
a side effect. */
|
||||
__nonnull ((1))
|
||||
static void
|
||||
DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
DYNARRAY_NAME (free__elements__)
|
||||
(list->u.dynarray_header.array, list->u.dynarray_header.used);
|
||||
DYNARRAY_NAME (free__array__) (list);
|
||||
list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
|
||||
list->u.dynarray_header.used = 0;
|
||||
list->u.dynarray_header.allocated = __dynarray_error_marker ();
|
||||
}
|
||||
|
||||
/* Return the number of elements which have been added to the dynamic
|
||||
array. */
|
||||
__nonnull ((1))
|
||||
static inline size_t
|
||||
DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
return list->u.dynarray_header.used;
|
||||
}
|
||||
|
||||
/* Return a pointer to the array element at INDEX. Terminate the
|
||||
process if INDEX is out of bounds. */
|
||||
__nonnull ((1))
|
||||
static inline DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
|
||||
{
|
||||
if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list)))
|
||||
__libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);
|
||||
return list->u.dynarray_header.array + index;
|
||||
}
|
||||
|
||||
/* Return a pointer to the first array element, if any. For a
|
||||
zero-length array, the pointer can be NULL even though the dynamic
|
||||
array has not entered the failure state. */
|
||||
__nonnull ((1))
|
||||
static inline DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
return list->u.dynarray_header.array;
|
||||
}
|
||||
|
||||
/* Return a pointer one element past the last array element. For a
|
||||
zero-length array, the pointer can be NULL even though the dynamic
|
||||
array has not entered the failure state. */
|
||||
__nonnull ((1))
|
||||
static inline DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
return list->u.dynarray_header.array + list->u.dynarray_header.used;
|
||||
}
|
||||
|
||||
/* Internal function. Slow path for the add function below. */
|
||||
static void
|
||||
DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
|
||||
{
|
||||
if (__glibc_unlikely
|
||||
(!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
|
||||
DYNARRAY_SCRATCH (list),
|
||||
sizeof (DYNARRAY_ELEMENT))))
|
||||
{
|
||||
DYNARRAY_NAME (mark_failed) (list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the new element and increase the array length. */
|
||||
list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
|
||||
}
|
||||
|
||||
/* Add ITEM at the end of the array, enlarging it by one element.
|
||||
Mark *LIST as failed if the dynamic array allocation size cannot be
|
||||
increased. */
|
||||
__nonnull ((1))
|
||||
static inline void
|
||||
DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
|
||||
{
|
||||
/* Do nothing in case of previous error. */
|
||||
if (DYNARRAY_NAME (has_failed) (list))
|
||||
return;
|
||||
|
||||
/* Enlarge the array if necessary. */
|
||||
if (__glibc_unlikely (list->u.dynarray_header.used
|
||||
== list->u.dynarray_header.allocated))
|
||||
{
|
||||
DYNARRAY_NAME (add__) (list, item);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the new element and increase the array length. */
|
||||
list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
|
||||
}
|
||||
|
||||
/* Internal function. Building block for the emplace functions below.
|
||||
Assumes space for one more element in *LIST. */
|
||||
static inline DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
DYNARRAY_ELEMENT *result
|
||||
= &list->u.dynarray_header.array[list->u.dynarray_header.used];
|
||||
++list->u.dynarray_header.used;
|
||||
#if defined (DYNARRAY_ELEMENT_INIT)
|
||||
DYNARRAY_ELEMENT_INIT (result);
|
||||
#elif defined (DYNARRAY_ELEMENT_FREE)
|
||||
memset (result, 0, sizeof (*result));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Internal function. Slow path for the emplace function below. */
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
if (__glibc_unlikely
|
||||
(!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
|
||||
DYNARRAY_SCRATCH (list),
|
||||
sizeof (DYNARRAY_ELEMENT))))
|
||||
{
|
||||
DYNARRAY_NAME (mark_failed) (list);
|
||||
return NULL;
|
||||
}
|
||||
return DYNARRAY_NAME (emplace__tail__) (list);
|
||||
}
|
||||
|
||||
/* Allocate a place for a new element in *LIST and return a pointer to
|
||||
it. The pointer can be NULL if the dynamic array cannot be
|
||||
enlarged due to a memory allocation failure. */
|
||||
__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
|
||||
static
|
||||
/* Avoid inlining with the larger initialization code. */
|
||||
#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
|
||||
inline
|
||||
#endif
|
||||
DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
/* Do nothing in case of previous error. */
|
||||
if (DYNARRAY_NAME (has_failed) (list))
|
||||
return NULL;
|
||||
|
||||
/* Enlarge the array if necessary. */
|
||||
if (__glibc_unlikely (list->u.dynarray_header.used
|
||||
== list->u.dynarray_header.allocated))
|
||||
return (DYNARRAY_NAME (emplace__) (list));
|
||||
return DYNARRAY_NAME (emplace__tail__) (list);
|
||||
}
|
||||
|
||||
/* Change the size of *LIST to SIZE. If SIZE is larger than the
|
||||
existing size, new elements are added (which can be initialized).
|
||||
Otherwise, the list is truncated, and elements are freed. Return
|
||||
false on memory allocation failure (and mark *LIST as failed). */
|
||||
__attribute_maybe_unused__ __nonnull ((1))
|
||||
static bool
|
||||
DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
|
||||
{
|
||||
if (size > list->u.dynarray_header.used)
|
||||
{
|
||||
bool ok;
|
||||
#if defined (DYNARRAY_ELEMENT_INIT)
|
||||
/* The new elements have to be initialized. */
|
||||
size_t old_size = list->u.dynarray_header.used;
|
||||
ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
|
||||
size, DYNARRAY_SCRATCH (list),
|
||||
sizeof (DYNARRAY_ELEMENT));
|
||||
if (ok)
|
||||
for (size_t i = old_size; i < size; ++i)
|
||||
{
|
||||
DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);
|
||||
}
|
||||
#elif defined (DYNARRAY_ELEMENT_FREE)
|
||||
/* Zero initialization is needed so that the elements can be
|
||||
safely freed. */
|
||||
ok = __libc_dynarray_resize_clear
|
||||
(&list->u.dynarray_abstract, size,
|
||||
DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));
|
||||
#else
|
||||
ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
|
||||
size, DYNARRAY_SCRATCH (list),
|
||||
sizeof (DYNARRAY_ELEMENT));
|
||||
#endif
|
||||
if (__glibc_unlikely (!ok))
|
||||
DYNARRAY_NAME (mark_failed) (list);
|
||||
return ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The list has shrunk in size. Free the removed elements. */
|
||||
DYNARRAY_NAME (free__elements__)
|
||||
(list->u.dynarray_header.array + size,
|
||||
list->u.dynarray_header.used - size);
|
||||
list->u.dynarray_header.used = size;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the last element of LIST if it is present. */
|
||||
__attribute_maybe_unused__ __nonnull ((1))
|
||||
static void
|
||||
DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
/* used > 0 implies that the array is the non-failed state. */
|
||||
if (list->u.dynarray_header.used > 0)
|
||||
{
|
||||
size_t new_length = list->u.dynarray_header.used - 1;
|
||||
#ifdef DYNARRAY_ELEMENT_FREE
|
||||
DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);
|
||||
#endif
|
||||
list->u.dynarray_header.used = new_length;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all elements from the list. The elements are freed, but the
|
||||
list itself is not. */
|
||||
__attribute_maybe_unused__ __nonnull ((1))
|
||||
static void
|
||||
DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
|
||||
{
|
||||
/* free__elements__ does nothing if the list is in the failed
|
||||
state. */
|
||||
DYNARRAY_NAME (free__elements__)
|
||||
(list->u.dynarray_header.array, list->u.dynarray_header.used);
|
||||
list->u.dynarray_header.used = 0;
|
||||
}
|
||||
|
||||
#ifdef DYNARRAY_FINAL_TYPE
|
||||
/* Transfer the dynamic array to a permanent location at *RESULT.
|
||||
Returns true on success on false on allocation failure. In either
|
||||
case, *LIST is re-initialized and can be reused. A NULL pointer is
|
||||
stored in *RESULT if LIST refers to an empty list. On success, the
|
||||
pointer in *RESULT is heap-allocated and must be deallocated using
|
||||
free. */
|
||||
__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1, 2))
|
||||
static bool
|
||||
DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
|
||||
DYNARRAY_FINAL_TYPE *result)
|
||||
{
|
||||
struct dynarray_finalize_result res;
|
||||
if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
|
||||
DYNARRAY_SCRATCH (list),
|
||||
sizeof (DYNARRAY_ELEMENT), &res))
|
||||
{
|
||||
/* On success, the result owns all the data. */
|
||||
DYNARRAY_NAME (init) (list);
|
||||
*result = (DYNARRAY_FINAL_TYPE) { res.array, res.length };
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* On error, we need to free all data. */
|
||||
DYNARRAY_FREE (list);
|
||||
errno = ENOMEM;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else /* !DYNARRAY_FINAL_TYPE */
|
||||
/* Transfer the dynamic array to a heap-allocated array and return a
|
||||
pointer to it. The pointer is NULL if memory allocation fails, or
|
||||
if the array is empty, so this function should be used only for
|
||||
arrays which are known not be empty (usually because they always
|
||||
have a sentinel at the end). If LENGTHP is not NULL, the array
|
||||
length is written to *LENGTHP. *LIST is re-initialized and can be
|
||||
reused. */
|
||||
__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
|
||||
static DYNARRAY_ELEMENT *
|
||||
DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
|
||||
{
|
||||
struct dynarray_finalize_result res;
|
||||
if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
|
||||
DYNARRAY_SCRATCH (list),
|
||||
sizeof (DYNARRAY_ELEMENT), &res))
|
||||
{
|
||||
/* On success, the result owns all the data. */
|
||||
DYNARRAY_NAME (init) (list);
|
||||
if (lengthp != NULL)
|
||||
*lengthp = res.length;
|
||||
return res.array;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* On error, we need to free all data. */
|
||||
DYNARRAY_FREE (list);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* !DYNARRAY_FINAL_TYPE */
|
||||
|
||||
/* Undo macro definitions. */
|
||||
|
||||
#undef DYNARRAY_CONCAT0
|
||||
#undef DYNARRAY_CONCAT1
|
||||
#undef DYNARRAY_NAME
|
||||
#undef DYNARRAY_SCRATCH
|
||||
#undef DYNARRAY_HAVE_SCRATCH
|
||||
|
||||
#undef DYNARRAY_STRUCT
|
||||
#undef DYNARRAY_ELEMENT
|
||||
#undef DYNARRAY_PREFIX
|
||||
#undef DYNARRAY_ELEMENT_FREE
|
||||
#undef DYNARRAY_ELEMENT_INIT
|
||||
#undef DYNARRAY_INITIAL_SIZE
|
||||
#undef DYNARRAY_FINAL_TYPE
|
178
lib/malloc/dynarray.h
Normal file
178
lib/malloc/dynarray.h
Normal file
|
@ -0,0 +1,178 @@
|
|||
/* Type-safe arrays which grow dynamically. Shared definitions.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* To use the dynarray facility, you need to include
|
||||
<malloc/dynarray-skeleton.c> and define the parameter macros
|
||||
documented in that file.
|
||||
|
||||
A minimal example which provides a growing list of integers can be
|
||||
defined like this:
|
||||
|
||||
struct int_array
|
||||
{
|
||||
// Pointer to result array followed by its length,
|
||||
// as required by DYNARRAY_FINAL_TYPE.
|
||||
int *array;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#define DYNARRAY_STRUCT dynarray_int
|
||||
#define DYNARRAY_ELEMENT int
|
||||
#define DYNARRAY_PREFIX dynarray_int_
|
||||
#define DYNARRAY_FINAL_TYPE struct int_array
|
||||
#include <malloc/dynarray-skeleton.c>
|
||||
|
||||
To create a three-element array with elements 1, 2, 3, use this
|
||||
code:
|
||||
|
||||
struct dynarray_int dyn;
|
||||
dynarray_int_init (&dyn);
|
||||
for (int i = 1; i <= 3; ++i)
|
||||
{
|
||||
int *place = dynarray_int_emplace (&dyn);
|
||||
assert (place != NULL);
|
||||
*place = i;
|
||||
}
|
||||
struct int_array result;
|
||||
bool ok = dynarray_int_finalize (&dyn, &result);
|
||||
assert (ok);
|
||||
assert (result.length == 3);
|
||||
assert (result.array[0] == 1);
|
||||
assert (result.array[1] == 2);
|
||||
assert (result.array[2] == 3);
|
||||
free (result.array);
|
||||
|
||||
If the elements contain resources which must be freed, define
|
||||
DYNARRAY_ELEMENT_FREE appropriately, like this:
|
||||
|
||||
struct str_array
|
||||
{
|
||||
char **array;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#define DYNARRAY_STRUCT dynarray_str
|
||||
#define DYNARRAY_ELEMENT char *
|
||||
#define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)
|
||||
#define DYNARRAY_PREFIX dynarray_str_
|
||||
#define DYNARRAY_FINAL_TYPE struct str_array
|
||||
#include <malloc/dynarray-skeleton.c>
|
||||
|
||||
Compared to scratch buffers, dynamic arrays have the following
|
||||
features:
|
||||
|
||||
- They have an element type, and are not just an untyped buffer of
|
||||
bytes.
|
||||
|
||||
- When growing, previously stored elements are preserved. (It is
|
||||
expected that scratch_buffer_grow_preserve and
|
||||
scratch_buffer_set_array_size eventually go away because all
|
||||
current users are moved to dynamic arrays.)
|
||||
|
||||
- Scratch buffers have a more aggressive growth policy because
|
||||
growing them typically means a retry of an operation (across an
|
||||
NSS service module boundary), which is expensive.
|
||||
|
||||
- For the same reason, scratch buffers have a much larger initial
|
||||
stack allocation. */
|
||||
|
||||
#ifndef _DYNARRAY_H
|
||||
#define _DYNARRAY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
struct dynarray_header
|
||||
{
|
||||
size_t used;
|
||||
size_t allocated;
|
||||
void *array;
|
||||
};
|
||||
|
||||
/* Marker used in the allocated member to indicate that an error was
|
||||
encountered. */
|
||||
static inline size_t
|
||||
__dynarray_error_marker (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Internal function. See the has_failed function in
|
||||
dynarray-skeleton.c. */
|
||||
static inline bool
|
||||
__dynarray_error (struct dynarray_header *list)
|
||||
{
|
||||
return list->allocated == __dynarray_error_marker ();
|
||||
}
|
||||
|
||||
/* Internal function. Enlarge the dynamically allocated area of the
|
||||
array to make room for one more element. SCRATCH is a pointer to
|
||||
the scratch area (which is not heap-allocated and must not be
|
||||
freed). ELEMENT_SIZE is the size, in bytes, of one element.
|
||||
Return false on failure, true on success. */
|
||||
bool __libc_dynarray_emplace_enlarge (struct dynarray_header *,
|
||||
void *scratch, size_t element_size);
|
||||
|
||||
/* Internal function. Enlarge the dynamically allocated area of the
|
||||
array to make room for at least SIZE elements (which must be larger
|
||||
than the existing used part of the dynamic array). SCRATCH is a
|
||||
pointer to the scratch area (which is not heap-allocated and must
|
||||
not be freed). ELEMENT_SIZE is the size, in bytes, of one element.
|
||||
Return false on failure, true on success. */
|
||||
bool __libc_dynarray_resize (struct dynarray_header *, size_t size,
|
||||
void *scratch, size_t element_size);
|
||||
|
||||
/* Internal function. Like __libc_dynarray_resize, but clear the new
|
||||
part of the dynamic array. */
|
||||
bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size,
|
||||
void *scratch, size_t element_size);
|
||||
|
||||
/* Internal type. */
|
||||
struct dynarray_finalize_result
|
||||
{
|
||||
void *array;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
/* Internal function. Copy the dynamically-allocated area to an
|
||||
explicitly-sized heap allocation. SCRATCH is a pointer to the
|
||||
embedded scratch space. ELEMENT_SIZE is the size, in bytes, of the
|
||||
element type. On success, true is returned, and pointer and length
|
||||
are written to *RESULT. On failure, false is returned. The caller
|
||||
has to take care of some of the memory management; this function is
|
||||
expected to be called from dynarray-skeleton.c. */
|
||||
bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,
|
||||
size_t element_size,
|
||||
struct dynarray_finalize_result *result);
|
||||
|
||||
|
||||
/* Internal function. Terminate the process after an index error.
|
||||
SIZE is the number of elements of the dynamic array. INDEX is the
|
||||
lookup index which triggered the failure. */
|
||||
_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);
|
||||
|
||||
#ifndef _ISOMAC
|
||||
libc_hidden_proto (__libc_dynarray_emplace_enlarge)
|
||||
libc_hidden_proto (__libc_dynarray_resize)
|
||||
libc_hidden_proto (__libc_dynarray_resize_clear)
|
||||
libc_hidden_proto (__libc_dynarray_finalize)
|
||||
libc_hidden_proto (__libc_dynarray_at_failure)
|
||||
#endif
|
||||
|
||||
#endif /* _DYNARRAY_H */
|
35
lib/malloc/dynarray_at_failure.c
Normal file
35
lib/malloc/dynarray_at_failure.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Report an dynamic array index out of bounds condition.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <dynarray.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
__libc_dynarray_at_failure (size_t size, size_t index)
|
||||
{
|
||||
#ifdef _LIBC
|
||||
char buf[200];
|
||||
__snprintf (buf, sizeof (buf), "Fatal glibc error: "
|
||||
"array index %zu not less than array length %zu\n",
|
||||
index, size);
|
||||
#else
|
||||
abort ();
|
||||
#endif
|
||||
}
|
||||
libc_hidden_def (__libc_dynarray_at_failure)
|
73
lib/malloc/dynarray_emplace_enlarge.c
Normal file
73
lib/malloc/dynarray_emplace_enlarge.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* Increase the size of a dynamic array in preparation of an emplace operation.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <dynarray.h>
|
||||
#include <errno.h>
|
||||
#include <intprops.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
__libc_dynarray_emplace_enlarge (struct dynarray_header *list,
|
||||
void *scratch, size_t element_size)
|
||||
{
|
||||
size_t new_allocated;
|
||||
if (list->allocated == 0)
|
||||
{
|
||||
/* No scratch buffer provided. Choose a reasonable default
|
||||
size. */
|
||||
if (element_size < 4)
|
||||
new_allocated = 16;
|
||||
else if (element_size < 8)
|
||||
new_allocated = 8;
|
||||
else
|
||||
new_allocated = 4;
|
||||
}
|
||||
else
|
||||
/* Increase the allocated size, using an exponential growth
|
||||
policy. */
|
||||
{
|
||||
new_allocated = list->allocated + list->allocated / 2 + 1;
|
||||
if (new_allocated <= list->allocated)
|
||||
{
|
||||
/* Overflow. */
|
||||
__set_errno (ENOMEM);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
size_t new_size;
|
||||
if (INT_MULTIPLY_WRAPV (new_allocated, element_size, &new_size))
|
||||
return false;
|
||||
void *new_array;
|
||||
if (list->array == scratch)
|
||||
{
|
||||
/* The previous array was not heap-allocated. */
|
||||
new_array = malloc (new_size);
|
||||
if (new_array != NULL && list->array != NULL)
|
||||
memcpy (new_array, list->array, list->used * element_size);
|
||||
}
|
||||
else
|
||||
new_array = realloc (list->array, new_size);
|
||||
if (new_array == NULL)
|
||||
return false;
|
||||
list->array = new_array;
|
||||
list->allocated = new_allocated;
|
||||
return true;
|
||||
}
|
||||
libc_hidden_def (__libc_dynarray_emplace_enlarge)
|
62
lib/malloc/dynarray_finalize.c
Normal file
62
lib/malloc/dynarray_finalize.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* Copy the dynamically-allocated area to an explicitly-sized heap allocation.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <dynarray.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
__libc_dynarray_finalize (struct dynarray_header *list,
|
||||
void *scratch, size_t element_size,
|
||||
struct dynarray_finalize_result *result)
|
||||
{
|
||||
if (__dynarray_error (list))
|
||||
/* The caller will reported the deferred error. */
|
||||
return false;
|
||||
|
||||
size_t used = list->used;
|
||||
|
||||
/* Empty list. */
|
||||
if (used == 0)
|
||||
{
|
||||
/* An empty list could still be backed by a heap-allocated
|
||||
array. Free it if necessary. */
|
||||
if (list->array != scratch)
|
||||
free (list->array);
|
||||
*result = (struct dynarray_finalize_result) { NULL, 0 };
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t allocation_size = used * element_size;
|
||||
void *heap_array = malloc (allocation_size);
|
||||
if (heap_array != NULL)
|
||||
{
|
||||
/* The new array takes ownership of the strings. */
|
||||
if (list->array != NULL)
|
||||
memcpy (heap_array, list->array, allocation_size);
|
||||
if (list->array != scratch)
|
||||
free (list->array);
|
||||
*result = (struct dynarray_finalize_result)
|
||||
{ .array = heap_array, .length = used };
|
||||
return true;
|
||||
}
|
||||
else
|
||||
/* The caller will perform the freeing operation. */
|
||||
return false;
|
||||
}
|
||||
libc_hidden_def (__libc_dynarray_finalize)
|
64
lib/malloc/dynarray_resize.c
Normal file
64
lib/malloc/dynarray_resize.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Increase the size of a dynamic array.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <dynarray.h>
|
||||
#include <errno.h>
|
||||
#include <intprops.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
__libc_dynarray_resize (struct dynarray_header *list, size_t size,
|
||||
void *scratch, size_t element_size)
|
||||
{
|
||||
/* The existing allocation provides sufficient room. */
|
||||
if (size <= list->allocated)
|
||||
{
|
||||
list->used = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Otherwise, use size as the new allocation size. The caller is
|
||||
expected to provide the final size of the array, so there is no
|
||||
over-allocation here. */
|
||||
|
||||
size_t new_size_bytes;
|
||||
if (INT_MULTIPLY_WRAPV (size, element_size, &new_size_bytes))
|
||||
{
|
||||
/* Overflow. */
|
||||
__set_errno (ENOMEM);
|
||||
return false;
|
||||
}
|
||||
void *new_array;
|
||||
if (list->array == scratch)
|
||||
{
|
||||
/* The previous array was not heap-allocated. */
|
||||
new_array = malloc (new_size_bytes);
|
||||
if (new_array != NULL && list->array != NULL)
|
||||
memcpy (new_array, list->array, list->used * element_size);
|
||||
}
|
||||
else
|
||||
new_array = realloc (list->array, new_size_bytes);
|
||||
if (new_array == NULL)
|
||||
return false;
|
||||
list->array = new_array;
|
||||
list->allocated = size;
|
||||
list->used = size;
|
||||
return true;
|
||||
}
|
||||
libc_hidden_def (__libc_dynarray_resize)
|
35
lib/malloc/dynarray_resize_clear.c
Normal file
35
lib/malloc/dynarray_resize_clear.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Increase the size of a dynamic array and clear the new part.
|
||||
Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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 the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <dynarray.h>
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
__libc_dynarray_resize_clear (struct dynarray_header *list, size_t size,
|
||||
void *scratch, size_t element_size)
|
||||
{
|
||||
size_t old_size = list->used;
|
||||
if (!__libc_dynarray_resize (list, size, scratch, element_size))
|
||||
return false;
|
||||
/* __libc_dynarray_resize already checked for overflow. */
|
||||
char *array = list->array;
|
||||
memset (array + (old_size * element_size), 0,
|
||||
(size - old_size) * element_size);
|
||||
return true;
|
||||
}
|
||||
libc_hidden_def (__libc_dynarray_resize_clear)
|
|
@ -1,5 +1,5 @@
|
|||
/* Variable-sized buffer with on-stack default allocation.
|
||||
Copyright (C) 2015-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 2015-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Variable-sized buffer with on-stack default allocation.
|
||||
Copyright (C) 2015-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 2015-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Variable-sized buffer with on-stack default allocation.
|
||||
Copyright (C) 2015-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 2015-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
|
|
|
@ -4521,7 +4521,7 @@ mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
|
|||
mp_size_t un;
|
||||
|
||||
if (nails != 0)
|
||||
gmp_die ("mpz_import: Nails not supported.");
|
||||
gmp_die ("mpz_export: Nails not supported.");
|
||||
|
||||
assert (order == 1 || order == -1);
|
||||
assert (endian >= -1 && endian <= 1);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Internals of mktime and related functions
|
||||
Copyright 2016-2020 Free Software Foundation, Inc.
|
||||
Copyright 2016-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Paul Eggert <eggert@cs.ucla.edu>.
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# define USE_IN_EXTENDED_LOCALE_MODEL 1
|
||||
# define HAVE_STRUCT_ERA_ENTRY 1
|
||||
# define HAVE_TM_GMTOFF 1
|
||||
# define HAVE_TM_ZONE 1
|
||||
# define HAVE_STRUCT_TM_TM_ZONE 1
|
||||
# define HAVE_TZNAME 1
|
||||
# include "../locale/localeinfo.h"
|
||||
#else
|
||||
|
@ -499,7 +499,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
|
|||
#endif
|
||||
|
||||
zone = NULL;
|
||||
#if HAVE_TM_ZONE
|
||||
#if HAVE_STRUCT_TM_TM_ZONE
|
||||
/* The POSIX test suite assumes that setting
|
||||
the environment variable TZ to a new value before calling strftime()
|
||||
will influence the result (the %Z format) even if the information in
|
||||
|
@ -516,7 +516,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
|
|||
}
|
||||
else
|
||||
{
|
||||
# if !HAVE_TM_ZONE
|
||||
# if !HAVE_STRUCT_TM_TM_ZONE
|
||||
/* Infer the zone name from *TZ instead of from TZNAME. */
|
||||
tzname_vec = tz->tzname_copy;
|
||||
# endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Extended regular expression matching and search library.
|
||||
Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <dynarray.h>
|
||||
#include <intprops.h>
|
||||
#include <verify.h>
|
||||
|
||||
|
@ -444,25 +445,6 @@ typedef struct re_dfa_t re_dfa_t;
|
|||
#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
|
||||
#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
|
||||
|
||||
#if defined _LIBC || HAVE_ALLOCA
|
||||
# include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifndef _LIBC
|
||||
# if HAVE_ALLOCA
|
||||
/* The OS usually guarantees only one guard page at the bottom of the stack,
|
||||
and a page size can be as small as 4096 bytes. So we cannot safely
|
||||
allocate anything larger than 4096 bytes. Also care for the possibility
|
||||
of a few compiler-allocated temporary stack slots. */
|
||||
# define __libc_use_alloca(n) ((n) < 4032)
|
||||
# else
|
||||
/* alloca is implemented with malloc, so just use malloc. */
|
||||
# define __libc_use_alloca(n) 0
|
||||
# undef alloca
|
||||
# define alloca(n) malloc (n)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# define MALLOC_0_IS_NONNULL 1
|
||||
#elif !defined MALLOC_0_IS_NONNULL
|
||||
|
@ -848,12 +830,14 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx)
|
|||
}
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
|
||||
#ifndef FALLTHROUGH
|
||||
# if (__GNUC__ >= 7) || (__clang_major__ >= 10)
|
||||
#ifdef _LIBC
|
||||
# if __GNUC__ >= 7
|
||||
# define FALLTHROUGH __attribute__ ((__fallthrough__))
|
||||
# else
|
||||
# define FALLTHROUGH ((void) 0)
|
||||
# endif
|
||||
#else
|
||||
# include "attribute.h"
|
||||
#endif
|
||||
|
||||
#endif /* _REGEX_INTERNAL_H */
|
||||
|
|
117
lib/regexec.c
117
lib/regexec.c
|
@ -1,5 +1,5 @@
|
|||
/* Extended regular expression matching and search library.
|
||||
Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||
|
||||
|
@ -1355,6 +1355,12 @@ pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
|
|||
return fs->stack[num].node;
|
||||
}
|
||||
|
||||
|
||||
#define DYNARRAY_STRUCT regmatch_list
|
||||
#define DYNARRAY_ELEMENT regmatch_t
|
||||
#define DYNARRAY_PREFIX regmatch_list_
|
||||
#include <malloc/dynarray-skeleton.c>
|
||||
|
||||
/* Set the positions where the subexpressions are starts/ends to registers
|
||||
PMATCH.
|
||||
Note: We assume that pmatch[0] is already set, and
|
||||
|
@ -1370,8 +1376,8 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
|||
re_node_set eps_via_nodes;
|
||||
struct re_fail_stack_t *fs;
|
||||
struct re_fail_stack_t fs_body = { 0, 2, NULL };
|
||||
regmatch_t *prev_idx_match;
|
||||
bool prev_idx_match_malloced = false;
|
||||
struct regmatch_list prev_match;
|
||||
regmatch_list_init (&prev_match);
|
||||
|
||||
DEBUG_ASSERT (nmatch > 1);
|
||||
DEBUG_ASSERT (mctx->state_log != NULL);
|
||||
|
@ -1388,18 +1394,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
|||
cur_node = dfa->init_node;
|
||||
re_node_set_init_empty (&eps_via_nodes);
|
||||
|
||||
if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
|
||||
prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
|
||||
else
|
||||
if (!regmatch_list_resize (&prev_match, nmatch))
|
||||
{
|
||||
prev_idx_match = re_malloc (regmatch_t, nmatch);
|
||||
if (prev_idx_match == NULL)
|
||||
{
|
||||
free_fail_stack_return (fs);
|
||||
return REG_ESPACE;
|
||||
}
|
||||
prev_idx_match_malloced = true;
|
||||
regmatch_list_free (&prev_match);
|
||||
free_fail_stack_return (fs);
|
||||
return REG_ESPACE;
|
||||
}
|
||||
regmatch_t *prev_idx_match = regmatch_list_begin (&prev_match);
|
||||
memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
|
||||
|
||||
for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
|
||||
|
@ -1417,8 +1418,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
|||
if (reg_idx == nmatch)
|
||||
{
|
||||
re_node_set_free (&eps_via_nodes);
|
||||
if (prev_idx_match_malloced)
|
||||
re_free (prev_idx_match);
|
||||
regmatch_list_free (&prev_match);
|
||||
return free_fail_stack_return (fs);
|
||||
}
|
||||
cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
|
||||
|
@ -1427,8 +1427,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
|||
else
|
||||
{
|
||||
re_node_set_free (&eps_via_nodes);
|
||||
if (prev_idx_match_malloced)
|
||||
re_free (prev_idx_match);
|
||||
regmatch_list_free (&prev_match);
|
||||
return REG_NOERROR;
|
||||
}
|
||||
}
|
||||
|
@ -1442,8 +1441,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
|||
if (__glibc_unlikely (cur_node == -2))
|
||||
{
|
||||
re_node_set_free (&eps_via_nodes);
|
||||
if (prev_idx_match_malloced)
|
||||
re_free (prev_idx_match);
|
||||
regmatch_list_free (&prev_match);
|
||||
free_fail_stack_return (fs);
|
||||
return REG_ESPACE;
|
||||
}
|
||||
|
@ -1453,15 +1451,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
|||
else
|
||||
{
|
||||
re_node_set_free (&eps_via_nodes);
|
||||
if (prev_idx_match_malloced)
|
||||
re_free (prev_idx_match);
|
||||
regmatch_list_free (&prev_match);
|
||||
return REG_NOMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
re_node_set_free (&eps_via_nodes);
|
||||
if (prev_idx_match_malloced)
|
||||
re_free (prev_idx_match);
|
||||
regmatch_list_free (&prev_match);
|
||||
return free_fail_stack_return (fs);
|
||||
}
|
||||
|
||||
|
@ -3251,7 +3247,7 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
|
|||
/* Build transition table for the state.
|
||||
Return true if successful. */
|
||||
|
||||
static bool
|
||||
static bool __attribute_noinline__
|
||||
build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
||||
{
|
||||
reg_errcode_t err;
|
||||
|
@ -3259,36 +3255,20 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
|||
int ch;
|
||||
bool need_word_trtable = false;
|
||||
bitset_word_t elem, mask;
|
||||
bool dests_node_malloced = false;
|
||||
bool dest_states_malloced = false;
|
||||
Idx ndests; /* Number of the destination states from 'state'. */
|
||||
re_dfastate_t **trtable;
|
||||
re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
|
||||
re_node_set follows, *dests_node;
|
||||
bitset_t *dests_ch;
|
||||
re_dfastate_t *dest_states[SBC_MAX];
|
||||
re_dfastate_t *dest_states_word[SBC_MAX];
|
||||
re_dfastate_t *dest_states_nl[SBC_MAX];
|
||||
re_node_set follows;
|
||||
bitset_t acceptable;
|
||||
|
||||
struct dests_alloc
|
||||
{
|
||||
re_node_set dests_node[SBC_MAX];
|
||||
bitset_t dests_ch[SBC_MAX];
|
||||
} *dests_alloc;
|
||||
|
||||
/* We build DFA states which corresponds to the destination nodes
|
||||
from 'state'. 'dests_node[i]' represents the nodes which i-th
|
||||
destination state contains, and 'dests_ch[i]' represents the
|
||||
characters which i-th destination state accepts. */
|
||||
if (__libc_use_alloca (sizeof (struct dests_alloc)))
|
||||
dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
|
||||
else
|
||||
{
|
||||
dests_alloc = re_malloc (struct dests_alloc, 1);
|
||||
if (__glibc_unlikely (dests_alloc == NULL))
|
||||
return false;
|
||||
dests_node_malloced = true;
|
||||
}
|
||||
dests_node = dests_alloc->dests_node;
|
||||
dests_ch = dests_alloc->dests_ch;
|
||||
re_node_set dests_node[SBC_MAX];
|
||||
bitset_t dests_ch[SBC_MAX];
|
||||
|
||||
/* Initialize transition table. */
|
||||
state->word_trtable = state->trtable = NULL;
|
||||
|
@ -3298,8 +3278,6 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
|||
ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
|
||||
if (__glibc_unlikely (ndests <= 0))
|
||||
{
|
||||
if (dests_node_malloced)
|
||||
re_free (dests_alloc);
|
||||
/* Return false in case of an error, true otherwise. */
|
||||
if (ndests == 0)
|
||||
{
|
||||
|
@ -3314,38 +3292,14 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
|||
|
||||
err = re_node_set_alloc (&follows, ndests + 1);
|
||||
if (__glibc_unlikely (err != REG_NOERROR))
|
||||
goto out_free;
|
||||
|
||||
/* Avoid arithmetic overflow in size calculation. */
|
||||
size_t ndests_max
|
||||
= ((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
|
||||
/ (3 * sizeof (re_dfastate_t *)));
|
||||
if (__glibc_unlikely (ndests_max < ndests))
|
||||
goto out_free;
|
||||
|
||||
if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
|
||||
+ ndests * 3 * sizeof (re_dfastate_t *)))
|
||||
dest_states = (re_dfastate_t **)
|
||||
alloca (ndests * 3 * sizeof (re_dfastate_t *));
|
||||
else
|
||||
{
|
||||
dest_states = re_malloc (re_dfastate_t *, ndests * 3);
|
||||
if (__glibc_unlikely (dest_states == NULL))
|
||||
{
|
||||
out_free:
|
||||
if (dest_states_malloced)
|
||||
re_free (dest_states);
|
||||
re_node_set_free (&follows);
|
||||
for (i = 0; i < ndests; ++i)
|
||||
re_node_set_free (dests_node + i);
|
||||
if (dests_node_malloced)
|
||||
re_free (dests_alloc);
|
||||
return false;
|
||||
}
|
||||
dest_states_malloced = true;
|
||||
out_free:
|
||||
re_node_set_free (&follows);
|
||||
for (i = 0; i < ndests; ++i)
|
||||
re_node_set_free (dests_node + i);
|
||||
return false;
|
||||
}
|
||||
dest_states_word = dest_states + ndests;
|
||||
dest_states_nl = dest_states_word + ndests;
|
||||
|
||||
bitset_empty (acceptable);
|
||||
|
||||
/* Then build the states for all destinations. */
|
||||
|
@ -3470,16 +3424,9 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
|||
}
|
||||
}
|
||||
|
||||
if (dest_states_malloced)
|
||||
re_free (dest_states);
|
||||
|
||||
re_node_set_free (&follows);
|
||||
for (i = 0; i < ndests; ++i)
|
||||
re_node_set_free (dests_node + i);
|
||||
|
||||
if (dests_node_malloced)
|
||||
re_free (dests_alloc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <libc-config.h>
|
||||
|
||||
#define __libc_scratch_buffer_dupfree gl_scratch_buffer_dupfree
|
||||
#define __libc_scratch_buffer_grow gl_scratch_buffer_grow
|
||||
#define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve
|
||||
#define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size
|
||||
|
|
|
@ -49,6 +49,23 @@
|
|||
|
||||
# ifndef _@GUARD_PREFIX@_STDDEF_H
|
||||
|
||||
/* On AIX 7.2, with xlc in 64-bit mode, <stddef.h> defines max_align_t to a
|
||||
type with alignment 4, but 'long' has alignment 8. */
|
||||
# if defined _AIX && defined _ARCH_PPC64
|
||||
# if !GNULIB_defined_max_align_t
|
||||
# ifdef _MAX_ALIGN_T
|
||||
/* /usr/include/stddef.h has already defined max_align_t. Override it. */
|
||||
typedef long rpl_max_align_t;
|
||||
# define max_align_t rpl_max_align_t
|
||||
# else
|
||||
/* Prevent /usr/include/stddef.h from defining max_align_t. */
|
||||
typedef long max_align_t;
|
||||
# define _MAX_ALIGN_T
|
||||
# endif
|
||||
# define GNULIB_defined_max_align_t 1
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
|
||||
# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
|
||||
|
@ -86,8 +103,10 @@
|
|||
we are currently compiling with gcc.
|
||||
On MSVC, max_align_t is defined only in C++ mode, after <cstddef> was
|
||||
included. Its definition is good since it has an alignment of 8 (on x86
|
||||
and x86_64). */
|
||||
#if defined _MSC_VER && defined __cplusplus
|
||||
and x86_64).
|
||||
Similarly on OS/2 kLIBC. */
|
||||
#if (defined _MSC_VER || (defined __KLIBC__ && !defined __LIBCN__)) \
|
||||
&& defined __cplusplus
|
||||
# include <cstddef>
|
||||
#else
|
||||
# if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T)
|
||||
|
|
|
@ -69,6 +69,14 @@
|
|||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* AIX 7.2 declares ffsl and ffsll in <strings.h>, not in <string.h>. */
|
||||
/* But in any case avoid namespace pollution on glibc systems. */
|
||||
#if ((@GNULIB_FFSL@ || @GNULIB_FFSLL@ || defined GNULIB_POSIXCHECK) \
|
||||
&& defined _AIX) \
|
||||
&& ! defined __GLIBC__
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
|
||||
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||
|
@ -110,10 +118,18 @@ _GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module");
|
|||
|
||||
/* Find the index of the least-significant set bit. */
|
||||
#if @GNULIB_FFSLL@
|
||||
# if !@HAVE_FFSLL@
|
||||
# if @REPLACE_FFSLL@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# define ffsll rpl_ffsll
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (ffsll, int, (long long int i));
|
||||
_GL_CXXALIAS_RPL (ffsll, int, (long long int i));
|
||||
# else
|
||||
# if !@HAVE_FFSLL@
|
||||
_GL_FUNCDECL_SYS (ffsll, int, (long long int i));
|
||||
# endif
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (ffsll, int, (long long int i));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (ffsll);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef ffsll
|
||||
|
|
|
@ -713,11 +713,21 @@ _GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - "
|
|||
|
||||
|
||||
#if @GNULIB_MKFIFOAT@
|
||||
# if !@HAVE_MKFIFOAT@
|
||||
# if @REPLACE_MKFIFOAT@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef mkfifoat
|
||||
# define mkfifoat rpl_mkfifoat
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode));
|
||||
# else
|
||||
# if !@HAVE_MKFIFOAT@
|
||||
_GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
# endif
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (mkfifoat);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mkfifoat
|
||||
|
@ -756,13 +766,25 @@ _GL_WARN_ON_USE (mknod, "mknod is not portable - "
|
|||
|
||||
|
||||
#if @GNULIB_MKNODAT@
|
||||
# if !@HAVE_MKNODAT@
|
||||
# if @REPLACE_MKNODAT@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef mknodat
|
||||
# define mknodat rpl_mknodat
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (mknodat, int,
|
||||
(int fd, char const *file, mode_t mode, dev_t dev)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (mknodat, int,
|
||||
(int fd, char const *file, mode_t mode, dev_t dev));
|
||||
# else
|
||||
# if !@HAVE_MKNODAT@
|
||||
_GL_FUNCDECL_SYS (mknodat, int,
|
||||
(int fd, char const *file, mode_t mode, dev_t dev)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
# endif
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (mknodat, int,
|
||||
(int fd, char const *file, mode_t mode, dev_t dev));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (mknodat);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef mknodat
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -61,7 +62,8 @@
|
|||
# define __gen_tempname gen_tempname
|
||||
# define __mkdir mkdir
|
||||
# define __open open
|
||||
# define __lxstat64(version, file, buf) lstat (file, buf)
|
||||
# define __lstat64(file, buf) lstat (file, buf)
|
||||
# define __stat64(file, buf) stat (file, buf)
|
||||
# define __getrandom getrandom
|
||||
# define __clock_gettime64 clock_gettime
|
||||
# define __timespec64 timespec
|
||||
|
@ -76,13 +78,14 @@ typedef uint_fast64_t random_value;
|
|||
#define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62)
|
||||
|
||||
static random_value
|
||||
random_bits (random_value var)
|
||||
random_bits (random_value var, bool use_getrandom)
|
||||
{
|
||||
random_value r;
|
||||
if (__getrandom (&r, sizeof r, 0) == sizeof r)
|
||||
/* Without GRND_NONBLOCK it can be blocked for minutes on some systems. */
|
||||
if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r)
|
||||
return r;
|
||||
#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME)
|
||||
/* Add entropy if getrandom is not supported. */
|
||||
/* Add entropy if getrandom did not work. */
|
||||
struct __timespec64 tv;
|
||||
__clock_gettime64 (CLOCK_MONOTONIC, &tv);
|
||||
var ^= tv.tv_nsec;
|
||||
|
@ -96,7 +99,7 @@ static int
|
|||
direxists (const char *dir)
|
||||
{
|
||||
struct_stat64 buf;
|
||||
return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
|
||||
return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
|
||||
}
|
||||
|
||||
/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
|
||||
|
@ -188,7 +191,7 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
|
|||
{
|
||||
struct_stat64 st;
|
||||
|
||||
if (__lxstat64 (_STAT_VER, tmpl, &st) == 0 || errno == EOVERFLOW)
|
||||
if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW)
|
||||
__set_errno (EEXIST);
|
||||
return errno == ENOENT ? 0 : -1;
|
||||
}
|
||||
|
@ -267,6 +270,13 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
|
|||
/* How many random base-62 digits can currently be extracted from V. */
|
||||
int vdigits = 0;
|
||||
|
||||
/* Whether to consume entropy when acquiring random bits. On the
|
||||
first try it's worth the entropy cost with __GT_NOCREATE, which
|
||||
is inherently insecure and can use the entropy to make it a bit
|
||||
less secure. On the (rare) second and later attempts it might
|
||||
help against DoS attacks. */
|
||||
bool use_getrandom = tryfunc == try_nocreate;
|
||||
|
||||
/* 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
|
||||
|
@ -290,7 +300,10 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
|
|||
if (vdigits == 0)
|
||||
{
|
||||
do
|
||||
v = random_bits (v);
|
||||
{
|
||||
v = random_bits (v, use_getrandom);
|
||||
use_getrandom = true;
|
||||
}
|
||||
while (unfair_min <= v);
|
||||
|
||||
vdigits = BASE_62_DIGITS;
|
||||
|
|
|
@ -24,7 +24,7 @@ struct tm_zone
|
|||
members are zero. */
|
||||
struct tm_zone *next;
|
||||
|
||||
#if HAVE_TZNAME && !HAVE_TM_ZONE
|
||||
#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE
|
||||
/* Copies of recent strings taken from tzname[0] and tzname[1].
|
||||
The copies are in ABBRS, so that they survive tzset. Null if unknown. */
|
||||
char *tzname_copy[2];
|
||||
|
|
|
@ -101,6 +101,25 @@ struct __time_t_must_be_integral {
|
|||
# define GNULIB_defined_struct_time_t_must_be_integral 1
|
||||
# endif
|
||||
|
||||
/* Define TIME_UTC, a positive integer constant used for timespec_get(). */
|
||||
# if ! @TIME_H_DEFINES_TIME_UTC@
|
||||
# if !GNULIB_defined_TIME_UTC
|
||||
# define TIME_UTC 1
|
||||
# define GNULIB_defined_TIME_UTC 1
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Set *TS to the current time, and return BASE.
|
||||
Upon failure, return 0. */
|
||||
# if @GNULIB_TIMESPEC_GET@
|
||||
# if ! @HAVE_TIMESPEC_GET@
|
||||
_GL_FUNCDECL_SYS (timespec_get, int, (struct timespec *ts, int base)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base));
|
||||
_GL_CXXALIASWARN (timespec_get);
|
||||
# endif
|
||||
|
||||
/* Sleep for at least RQTP seconds unless interrupted, If interrupted,
|
||||
return -1 and store the remaining time into RMTP. See
|
||||
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html>. */
|
||||
|
|
|
@ -71,7 +71,7 @@ tzalloc (char const *name)
|
|||
if (tz)
|
||||
{
|
||||
tz->next = NULL;
|
||||
#if HAVE_TZNAME && !HAVE_TM_ZONE
|
||||
#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE
|
||||
tz->tzname_copy[0] = tz->tzname_copy[1] = NULL;
|
||||
#endif
|
||||
tz->tz_is_set = !!name;
|
||||
|
@ -83,13 +83,13 @@ tzalloc (char const *name)
|
|||
}
|
||||
|
||||
/* Save into TZ any nontrivial time zone abbreviation used by TM, and
|
||||
update *TM (if HAVE_TM_ZONE) or *TZ (if !HAVE_TM_ZONE &&
|
||||
HAVE_TZNAME) if they use the abbreviation. Return true if
|
||||
successful, false (setting errno) otherwise. */
|
||||
update *TM (if HAVE_STRUCT_TM_TM_ZONE) or *TZ (if
|
||||
!HAVE_STRUCT_TM_TM_ZONE && HAVE_TZNAME) if they use the abbreviation.
|
||||
Return true if successful, false (setting errno) otherwise. */
|
||||
static bool
|
||||
save_abbr (timezone_t tz, struct tm *tm)
|
||||
{
|
||||
#if HAVE_TM_ZONE || HAVE_TZNAME
|
||||
#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME
|
||||
char const *zone = NULL;
|
||||
char *zone_copy = (char *) "";
|
||||
|
||||
|
@ -97,7 +97,7 @@ save_abbr (timezone_t tz, struct tm *tm)
|
|||
int tzname_index = -1;
|
||||
# endif
|
||||
|
||||
# if HAVE_TM_ZONE
|
||||
# if HAVE_STRUCT_TM_TM_ZONE
|
||||
zone = tm->tm_zone;
|
||||
# endif
|
||||
|
||||
|
@ -145,7 +145,7 @@ save_abbr (timezone_t tz, struct tm *tm)
|
|||
}
|
||||
|
||||
/* Replace the zone name so that its lifetime matches that of TZ. */
|
||||
# if HAVE_TM_ZONE
|
||||
# if HAVE_STRUCT_TM_TM_ZONE
|
||||
tm->tm_zone = zone_copy;
|
||||
# else
|
||||
if (0 <= tzname_index)
|
||||
|
@ -303,7 +303,7 @@ mktime_z (timezone_t tz, struct tm *tm)
|
|||
tm_1.tm_isdst = tm->tm_isdst;
|
||||
time_t t = mktime (&tm_1);
|
||||
bool ok = 0 <= tm_1.tm_yday;
|
||||
#if HAVE_TM_ZONE || HAVE_TZNAME
|
||||
#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME
|
||||
ok = ok && save_abbr (tz, &tm_1);
|
||||
#endif
|
||||
if (revert_tz (old_tz) && ok)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Convert UTC calendar time to simple time. Like mktime but assumes UTC.
|
||||
|
||||
Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
@ -52,7 +53,9 @@
|
|||
|
||||
/* Avoid recursion with rpl_futimens or rpl_utimensat. */
|
||||
#undef futimens
|
||||
#undef utimensat
|
||||
#if !HAVE_NEARLY_WORKING_UTIMENSAT
|
||||
# undef utimensat
|
||||
#endif
|
||||
|
||||
/* Solaris 9 mistakenly succeeds when given a non-directory with a
|
||||
trailing slash. Force the use of rpl_stat for a fix. */
|
||||
|
@ -246,6 +249,20 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
|
|||
# if HAVE_UTIMENSAT
|
||||
if (fd < 0)
|
||||
{
|
||||
# if defined __APPLE__ && defined __MACH__
|
||||
size_t len = strlen (file);
|
||||
if (len > 0 && file[len - 1] == '/')
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (stat (file, &statbuf) < 0)
|
||||
return -1;
|
||||
if (!S_ISDIR (statbuf.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
result = utimensat (AT_FDCWD, file, ts, 0);
|
||||
# ifdef __linux__
|
||||
/* Work around a kernel bug:
|
||||
|
|
101
lib/utimensat.c
101
lib/utimensat.c
|
@ -24,14 +24,40 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "stat-time.h"
|
||||
#include "timespec.h"
|
||||
#include "utimens.h"
|
||||
|
||||
#if HAVE_UTIMENSAT
|
||||
#if HAVE_NEARLY_WORKING_UTIMENSAT
|
||||
|
||||
/* Use the original utimensat(), but correct the trailing slash handling. */
|
||||
int
|
||||
rpl_utimensat (int fd, char const *file, struct timespec const times[2],
|
||||
int flag)
|
||||
# undef utimensat
|
||||
{
|
||||
size_t len = strlen (file);
|
||||
if (len && file[len - 1] == '/')
|
||||
{
|
||||
struct stat st;
|
||||
if (fstatat (fd, file, &st, flag & AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return -1;
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return utimensat (fd, file, times, flag);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# if HAVE_UTIMENSAT
|
||||
|
||||
/* If we have a native utimensat, but are compiling this file, then
|
||||
utimensat was defined to rpl_utimensat by our replacement
|
||||
|
@ -42,24 +68,25 @@
|
|||
local_utimensat provides the fallback manipulation. */
|
||||
|
||||
static int local_utimensat (int, char const *, struct timespec const[2], int);
|
||||
# define AT_FUNC_NAME local_utimensat
|
||||
# define AT_FUNC_NAME local_utimensat
|
||||
|
||||
/* Like utimensat, but work around native bugs. */
|
||||
|
||||
int
|
||||
rpl_utimensat (int fd, char const *file, struct timespec const times[2],
|
||||
int flag)
|
||||
# undef utimensat
|
||||
{
|
||||
# if defined __linux__ || defined __sun
|
||||
# if defined __linux__ || defined __sun
|
||||
struct timespec ts[2];
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* See comments in utimens.c for details. */
|
||||
static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */
|
||||
if (0 <= utimensat_works_really)
|
||||
{
|
||||
int result;
|
||||
# if defined __linux__ || defined __sun
|
||||
# if defined __linux__ || defined __sun
|
||||
struct stat st;
|
||||
/* As recently as Linux kernel 2.6.32 (Dec 2009), several file
|
||||
systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
|
||||
|
@ -90,7 +117,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
|
|||
ts[1] = times[1];
|
||||
times = ts;
|
||||
}
|
||||
# ifdef __hppa__
|
||||
# ifdef __hppa__
|
||||
/* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec
|
||||
values. */
|
||||
else if (times
|
||||
|
@ -104,8 +131,36 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
|
|||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# if defined __APPLE__ && defined __MACH__
|
||||
/* macOS 10.13 does not reject invalid tv_nsec values either. */
|
||||
if (times
|
||||
&& ((times[0].tv_nsec != UTIME_OMIT
|
||||
&& times[0].tv_nsec != UTIME_NOW
|
||||
&& ! (0 <= times[0].tv_nsec
|
||||
&& times[0].tv_nsec < TIMESPEC_HZ))
|
||||
|| (times[1].tv_nsec != UTIME_OMIT
|
||||
&& times[1].tv_nsec != UTIME_NOW
|
||||
&& ! (0 <= times[1].tv_nsec
|
||||
&& times[1].tv_nsec < TIMESPEC_HZ))))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
size_t len = strlen (file);
|
||||
if (len > 0 && file[len - 1] == '/')
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (fstatat (fd, file, &statbuf, 0) < 0)
|
||||
return -1;
|
||||
if (!S_ISDIR (statbuf.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
result = utimensat (fd, file, times, flag);
|
||||
/* Linux kernel 2.6.25 has a bug where it returns EINVAL for
|
||||
UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which
|
||||
|
@ -129,11 +184,11 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
|
|||
return local_utimensat (fd, file, times, flag);
|
||||
}
|
||||
|
||||
#else /* !HAVE_UTIMENSAT */
|
||||
# else /* !HAVE_UTIMENSAT */
|
||||
|
||||
# define AT_FUNC_NAME utimensat
|
||||
# define AT_FUNC_NAME utimensat
|
||||
|
||||
#endif /* !HAVE_UTIMENSAT */
|
||||
# endif /* !HAVE_UTIMENSAT */
|
||||
|
||||
/* Set the access and modification timestamps of FILE to be
|
||||
TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory
|
||||
|
@ -146,15 +201,17 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2],
|
|||
Return 0 on success, -1 (setting errno) on failure. */
|
||||
|
||||
/* AT_FUNC_NAME is now utimensat or local_utimensat. */
|
||||
#define AT_FUNC_F1 lutimens
|
||||
#define AT_FUNC_F2 utimens
|
||||
#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
|
||||
#define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag
|
||||
#define AT_FUNC_POST_FILE_ARGS , ts
|
||||
#include "at-func.c"
|
||||
#undef AT_FUNC_NAME
|
||||
#undef AT_FUNC_F1
|
||||
#undef AT_FUNC_F2
|
||||
#undef AT_FUNC_USE_F1_COND
|
||||
#undef AT_FUNC_POST_FILE_PARAM_DECLS
|
||||
#undef AT_FUNC_POST_FILE_ARGS
|
||||
# define AT_FUNC_F1 lutimens
|
||||
# define AT_FUNC_F2 utimens
|
||||
# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
|
||||
# define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag
|
||||
# define AT_FUNC_POST_FILE_ARGS , ts
|
||||
# include "at-func.c"
|
||||
# undef AT_FUNC_NAME
|
||||
# undef AT_FUNC_F1
|
||||
# undef AT_FUNC_F2
|
||||
# undef AT_FUNC_USE_F1_COND
|
||||
# undef AT_FUNC_POST_FILE_PARAM_DECLS
|
||||
# undef AT_FUNC_POST_FILE_ARGS
|
||||
|
||||
#endif /* !HAVE_NEARLY_WORKING_UTIMENSAT */
|
||||
|
|
28
lib/verify.h
28
lib/verify.h
|
@ -22,16 +22,10 @@
|
|||
|
||||
|
||||
/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)
|
||||
works as per C11. This is supported by GCC 4.6.0 and later, in C
|
||||
mode, and by clang (also in C++ mode).
|
||||
works as per C11. This is supported by GCC 4.6.0+ and by clang 4+.
|
||||
|
||||
Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
|
||||
per C2X. This is supported by GCC 9.1 and later, and by clang in
|
||||
C++1z mode.
|
||||
|
||||
Define _GL_HAVE_STATIC_ASSERT1 if static_assert (R) works as per
|
||||
C++17. This is supported by GCC 9.1 and later, and by clang in
|
||||
C++1z mode.
|
||||
per C2X. This is supported by GCC 9.1+.
|
||||
|
||||
Support compilers claiming conformance to the relevant standard,
|
||||
and also support GCC when not pedantic. If we were willing to slow
|
||||
|
@ -47,18 +41,6 @@
|
|||
|| (!defined __STRICT_ANSI__ && 9 <= __GNUC__))
|
||||
# define _GL_HAVE__STATIC_ASSERT1 1
|
||||
# endif
|
||||
#else
|
||||
# if 4 <= __clang_major__
|
||||
# define _GL_HAVE__STATIC_ASSERT 1
|
||||
# endif
|
||||
# if 4 <= __clang_major__ && 201411 <= __cpp_static_assert
|
||||
# define _GL_HAVE__STATIC_ASSERT1 1
|
||||
# endif
|
||||
# if 201703L <= __cplusplus \
|
||||
|| 9 <= __GNUC__ \
|
||||
|| (4 <= __clang_major__ && 201411 <= __cpp_static_assert)
|
||||
# define _GL_HAVE_STATIC_ASSERT1 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
|
||||
|
@ -225,7 +207,9 @@ template <int w>
|
|||
Unfortunately, unlike C11, this implementation must appear as an
|
||||
ordinary declaration, and cannot appear inside struct { ... }. */
|
||||
|
||||
#if defined _GL_HAVE__STATIC_ASSERT
|
||||
#if 200410 <= __cpp_static_assert
|
||||
# define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC)
|
||||
#elif defined _GL_HAVE__STATIC_ASSERT
|
||||
# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
|
||||
#else
|
||||
# define _GL_VERIFY(R, DIAGNOSTIC, ...) \
|
||||
|
@ -239,7 +223,7 @@ template <int w>
|
|||
# define _Static_assert(...) \
|
||||
_GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
|
||||
# endif
|
||||
# if !defined _GL_HAVE_STATIC_ASSERT1 && !defined static_assert
|
||||
# if __cpp_static_assert < 201411 && !defined static_assert
|
||||
# define static_assert _Static_assert /* C11 requires this #define. */
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# canonicalize.m4 serial 35
|
||||
# canonicalize.m4 serial 37
|
||||
|
||||
dnl Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
|
||||
|
||||
|
@ -78,68 +78,106 @@ AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
|
|||
# so is the latter.
|
||||
AC_DEFUN([gl_FUNC_REALPATH_WORKS],
|
||||
[
|
||||
AC_CHECK_FUNCS_ONCE([realpath])
|
||||
AC_CHECK_FUNCS_ONCE([realpath lstat])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [
|
||||
rm -rf conftest.a conftest.d
|
||||
touch conftest.a
|
||||
# Assume that if we have lstat, we can also check symlinks.
|
||||
if test $ac_cv_func_lstat = yes; then
|
||||
ln -s conftest.a conftest.l
|
||||
fi
|
||||
mkdir conftest.d
|
||||
AC_RUN_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
]GL_NOCRASH[
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
]], [[
|
||||
int result = 0;
|
||||
/* This test fails on Solaris 10. */
|
||||
{
|
||||
char *name = realpath ("conftest.a", NULL);
|
||||
if (!(name && *name == '/'))
|
||||
result |= 1;
|
||||
free (name);
|
||||
}
|
||||
/* This test fails on older versions of Cygwin. */
|
||||
{
|
||||
char *name = realpath ("conftest.b/../conftest.a", NULL);
|
||||
if (name != NULL)
|
||||
result |= 2;
|
||||
free (name);
|
||||
}
|
||||
/* This test fails on Cygwin 2.9. */
|
||||
#if HAVE_LSTAT
|
||||
{
|
||||
char *name = realpath ("conftest.a/", NULL);
|
||||
if (name != NULL)
|
||||
char *name = realpath ("conftest.l/../conftest.a", NULL);
|
||||
if (name != NULL || errno != ENOTDIR)
|
||||
result |= 4;
|
||||
free (name);
|
||||
}
|
||||
#endif
|
||||
/* This test fails on Mac OS X 10.13, OpenBSD 6.0. */
|
||||
{
|
||||
char *name = realpath ("conftest.a/", NULL);
|
||||
if (name != NULL)
|
||||
result |= 8;
|
||||
free (name);
|
||||
}
|
||||
/* This test fails on AIX 7, Solaris 10. */
|
||||
{
|
||||
char *name1 = realpath (".", NULL);
|
||||
char *name2 = realpath ("conftest.d//./..", NULL);
|
||||
if (! name1 || ! name2 || strcmp (name1, name2))
|
||||
result |= 8;
|
||||
result |= 16;
|
||||
free (name1);
|
||||
free (name2);
|
||||
}
|
||||
#ifdef __linux__
|
||||
/* On Linux, // is the same as /. See also double-slash-root.m4.
|
||||
realpath() should respect this.
|
||||
This test fails on musl libc 1.2.2. */
|
||||
{
|
||||
char *name = realpath ("//", NULL);
|
||||
if (! name || strcmp (name, "/"))
|
||||
result |= 32;
|
||||
free (name);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
]])
|
||||
],
|
||||
[gl_cv_func_realpath_works=yes],
|
||||
[gl_cv_func_realpath_works=no],
|
||||
[case $? in
|
||||
32) gl_cv_func_realpath_works=nearly ;;
|
||||
*) gl_cv_func_realpath_works=no ;;
|
||||
esac
|
||||
],
|
||||
[case "$host_os" in
|
||||
# Guess yes on glibc systems.
|
||||
*-gnu* | gnu*) gl_cv_func_realpath_works="guessing yes" ;;
|
||||
# Guess yes on musl systems.
|
||||
*-musl*) gl_cv_func_realpath_works="guessing yes" ;;
|
||||
# Guess 'nearly' on musl systems.
|
||||
*-musl*) gl_cv_func_realpath_works="guessing nearly" ;;
|
||||
# Guess no on Cygwin.
|
||||
cygwin*) gl_cv_func_realpath_works="guessing no" ;;
|
||||
# Guess no on native Windows.
|
||||
mingw*) gl_cv_func_realpath_works="guessing no" ;;
|
||||
# If we don't know, obey --enable-cross-guesses.
|
||||
*) gl_cv_func_realpath_works="$gl_cross_guess_normal" ;;
|
||||
esac
|
||||
])
|
||||
rm -rf conftest.a conftest.d
|
||||
rm -rf conftest.a conftest.l conftest.d
|
||||
])
|
||||
case "$gl_cv_func_realpath_works" in
|
||||
*yes)
|
||||
AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath()
|
||||
can malloc memory, always gives an absolute path, and handles
|
||||
trailing slash correctly.])
|
||||
AC_DEFINE([FUNC_REALPATH_WORKS], [1],
|
||||
[Define to 1 if realpath() can malloc memory, always gives an absolute path, and handles leading slashes and a trailing slash correctly.])
|
||||
;;
|
||||
*nearly)
|
||||
AC_DEFINE([FUNC_REALPATH_NEARLY_WORKS], [1],
|
||||
[Define to 1 if realpath() can malloc memory, always gives an absolute path, and handles a trailing slash correctly.])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# serial 21 -*- Autoconf -*-
|
||||
# serial 22 -*- Autoconf -*-
|
||||
# Enable extensions on systems that normally disable them.
|
||||
|
||||
# Copyright (C) 2003, 2006-2021 Free Software Foundation, Inc.
|
||||
|
@ -212,4 +212,16 @@ dnl it should only be defined when necessary.
|
|||
AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS],
|
||||
[
|
||||
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
|
||||
|
||||
dnl On OpenBSD 6.8 with GCC, the include files contain a couple of
|
||||
dnl definitions that are only activated with an explicit -D_ISOC11_SOURCE.
|
||||
dnl That's because this version of GCC (4.2.1) supports the option
|
||||
dnl '-std=gnu99' but not the option '-std=gnu11'.
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
case "$host_os" in
|
||||
openbsd*)
|
||||
AC_DEFINE([_ISOC11_SOURCE], [1],
|
||||
[Define to enable the declarations of ISO C 11 types and functions.])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# fchmodat.m4 serial 5
|
||||
# fchmodat.m4 serial 6
|
||||
dnl Copyright (C) 2004-2021 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -16,11 +16,9 @@ AC_DEFUN([gl_FUNC_FCHMODAT],
|
|||
HAVE_FCHMODAT=0
|
||||
else
|
||||
AC_CACHE_CHECK(
|
||||
[whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks],
|
||||
[whether fchmodat works],
|
||||
[gl_cv_func_fchmodat_works],
|
||||
[dnl This test fails on GNU/Linux with glibc 2.31 (but not on
|
||||
dnl GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9.
|
||||
AC_RUN_IFELSE(
|
||||
[AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[
|
||||
AC_INCLUDES_DEFAULT[
|
||||
|
@ -44,27 +42,49 @@ AC_DEFUN([gl_FUNC_FCHMODAT],
|
|||
[[
|
||||
int permissive = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
int desired = S_IRUSR | S_IWUSR;
|
||||
static char const f[] = "conftest.fchmodat";
|
||||
int result = 0;
|
||||
#define file "conftest.fchmodat"
|
||||
struct stat st;
|
||||
if (creat (f, permissive) < 0)
|
||||
if (creat (file, permissive) < 0)
|
||||
return 1;
|
||||
if (fchmodat (AT_FDCWD, f, desired, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
/* Test whether fchmodat rejects a trailing slash on a non-directory.
|
||||
This test fails on AIX 7.2. */
|
||||
if (fchmodat (AT_FDCWD, file "/", desired, 0) == 0)
|
||||
result |= 2;
|
||||
/* Test whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks.
|
||||
This test fails on GNU/Linux with glibc 2.31 (but not on
|
||||
GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9. */
|
||||
if (fchmodat (AT_FDCWD, file, desired, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
result |= 4;
|
||||
if (stat (file, &st) != 0)
|
||||
return 1;
|
||||
if (stat (f, &st) != 0)
|
||||
return 1;
|
||||
return ! ((st.st_mode & permissive) == desired);
|
||||
if ((st.st_mode & permissive) != desired)
|
||||
result |= 4;
|
||||
return result;
|
||||
]])],
|
||||
[gl_cv_func_fchmodat_works=yes],
|
||||
[gl_cv_func_fchmodat_works=no],
|
||||
[case $? in
|
||||
2) gl_cv_func_fchmodat_works='nearly' ;;
|
||||
*) gl_cv_func_fchmodat_works=no ;;
|
||||
esac
|
||||
],
|
||||
[case "$host_os" in
|
||||
dnl Guess no on Linux with glibc and Cygwin, yes otherwise.
|
||||
# Guess no on Linux with glibc and Cygwin.
|
||||
linux-gnu* | cygwin*) gl_cv_func_fchmodat_works="guessing no" ;;
|
||||
# Guess 'nearly' on AIX.
|
||||
aix*) gl_cv_func_fchmodat_works="guessing nearly" ;;
|
||||
# If we don't know, obey --enable-cross-guesses.
|
||||
*) gl_cv_func_fchmodat_works="$gl_cross_guess_normal" ;;
|
||||
esac
|
||||
])
|
||||
rm -f conftest.fchmodat])
|
||||
case $gl_cv_func_fchmodat_works in
|
||||
case "$gl_cv_func_fchmodat_works" in
|
||||
*yes) ;;
|
||||
*nearly)
|
||||
AC_DEFINE([HAVE_NEARLY_WORKING_FCHMODAT], [1],
|
||||
[Define to 1 if fchmodat works, except for the trailing slash handling.])
|
||||
REPLACE_FCHMODAT=1
|
||||
;;
|
||||
*)
|
||||
AC_DEFINE([NEED_FCHMODAT_NONSYMLINK_FIX], [1],
|
||||
[Define to 1 if fchmodat+AT_SYMLINK_NOFOLLOW does not work right on non-symlinks.])
|
||||
|
|
|
@ -39,11 +39,12 @@ AC_DEFUN([gl_COMMON_BODY], [
|
|||
this syntax with 'extern'. */
|
||||
# define _Noreturn [[noreturn]]
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| _GL_GNUC_PREREQ (4, 7) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| (!defined __STRICT_ANSI__ \
|
||||
&& (_GL_GNUC_PREREQ (4, 7) \
|
||||
|| (defined __apple_build_version__ \
|
||||
? 6000000 <= __apple_build_version__ \
|
||||
: 3 < __clang_major__ + (5 <= __clang_minor__))))))
|
||||
/* _Noreturn works as-is. */
|
||||
# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
|
@ -66,7 +67,9 @@ AC_DEFUN([gl_COMMON_BODY], [
|
|||
#endif])
|
||||
AH_VERBATIM([attribute],
|
||||
[/* Attributes. */
|
||||
#ifdef __has_attribute
|
||||
#if (defined __has_attribute \
|
||||
&& (!defined __clang_minor__ \
|
||||
|| 3 < __clang_major__ + (5 <= __clang_minor__)))
|
||||
# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)
|
||||
#else
|
||||
# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr
|
||||
|
|
|
@ -75,6 +75,7 @@ AC_DEFUN([gl_EARLY],
|
|||
# Code from module dtoastr:
|
||||
# Code from module dtotimespec:
|
||||
# Code from module dup2:
|
||||
# Code from module dynarray:
|
||||
# Code from module eloop-threshold:
|
||||
# Code from module environ:
|
||||
# Code from module errno:
|
||||
|
@ -517,6 +518,7 @@ AC_DEFUN([gl_INIT],
|
|||
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
|
||||
gl_gnulib_enabled_cloexec=false
|
||||
gl_gnulib_enabled_dirfd=false
|
||||
gl_gnulib_enabled_dynarray=false
|
||||
gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c=false
|
||||
gl_gnulib_enabled_euidaccess=false
|
||||
gl_gnulib_enabled_getdtablesize=false
|
||||
|
@ -564,6 +566,12 @@ AC_DEFUN([gl_INIT],
|
|||
gl_gnulib_enabled_dirfd=true
|
||||
fi
|
||||
}
|
||||
func_gl_gnulib_m4code_dynarray ()
|
||||
{
|
||||
if ! $gl_gnulib_enabled_dynarray; then
|
||||
gl_gnulib_enabled_dynarray=true
|
||||
fi
|
||||
}
|
||||
func_gl_gnulib_m4code_925677f0343de64b89a9f0c790b4104c ()
|
||||
{
|
||||
if ! $gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c; then
|
||||
|
@ -797,6 +805,9 @@ AC_DEFUN([gl_INIT],
|
|||
if test $HAVE_READLINKAT = 0 || test $REPLACE_READLINKAT = 1; then
|
||||
func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
|
||||
fi
|
||||
if test $ac_use_included_regex = yes; then
|
||||
func_gl_gnulib_m4code_dynarray
|
||||
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
|
||||
|
@ -819,6 +830,7 @@ AC_DEFUN([gl_INIT],
|
|||
AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
|
||||
AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec])
|
||||
AM_CONDITIONAL([gl_GNULIB_ENABLED_dirfd], [$gl_gnulib_enabled_dirfd])
|
||||
AM_CONDITIONAL([gl_GNULIB_ENABLED_dynarray], [$gl_gnulib_enabled_dynarray])
|
||||
AM_CONDITIONAL([gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c], [$gl_gnulib_enabled_925677f0343de64b89a9f0c790b4104c])
|
||||
AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess])
|
||||
AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], [$gl_gnulib_enabled_getdtablesize])
|
||||
|
@ -1021,6 +1033,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/dtoastr.c
|
||||
lib/dtotimespec.c
|
||||
lib/dup2.c
|
||||
lib/dynarray.h
|
||||
lib/eloop-threshold.h
|
||||
lib/errno.in.h
|
||||
lib/euidaccess.c
|
||||
|
@ -1076,6 +1089,13 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/libc-config.h
|
||||
lib/limits.in.h
|
||||
lib/lstat.c
|
||||
lib/malloc/dynarray-skeleton.c
|
||||
lib/malloc/dynarray.h
|
||||
lib/malloc/dynarray_at_failure.c
|
||||
lib/malloc/dynarray_emplace_enlarge.c
|
||||
lib/malloc/dynarray_finalize.c
|
||||
lib/malloc/dynarray_resize.c
|
||||
lib/malloc/dynarray_resize_clear.c
|
||||
lib/malloc/scratch_buffer.h
|
||||
lib/malloc/scratch_buffer_dupfree.c
|
||||
lib/malloc/scratch_buffer_grow.c
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# serial 36
|
||||
# serial 37
|
||||
|
||||
# Copyright (C) 1996-1997, 1999-2007, 2009-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
|
@ -12,7 +12,7 @@ AC_DEFUN([gl_FUNC_GNU_STRFTIME],
|
|||
[
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
|
||||
# This defines (or not) HAVE_TZNAME and HAVE_TM_ZONE.
|
||||
# This defines (or not) HAVE_TZNAME and HAVE_STRUCT_TM_TM_ZONE.
|
||||
AC_REQUIRE([AC_STRUCT_TIMEZONE])
|
||||
|
||||
AC_REQUIRE([gl_TM_GMTOFF])
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
dnl A placeholder for <stddef.h>, for platforms that have issues.
|
||||
# stddef_h.m4 serial 7
|
||||
# stddef_h.m4 serial 9
|
||||
dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl A placeholder for <stddef.h>, for platforms that have issues.
|
||||
|
||||
AC_DEFUN([gl_STDDEF_H],
|
||||
[
|
||||
AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
|
||||
AC_REQUIRE([gt_TYPE_WCHAR_T])
|
||||
|
||||
dnl Persuade OpenBSD <stddef.h> to declare max_align_t.
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
|
||||
STDDEF_H=
|
||||
|
||||
dnl Test whether the type max_align_t exists and whether its alignment
|
||||
|
@ -23,6 +28,13 @@ AC_DEFUN([gl_STDDEF_H],
|
|||
int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1];
|
||||
int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1];
|
||||
#endif
|
||||
typedef struct { char a; max_align_t b; } max_helper;
|
||||
typedef struct { char a; long b; } long_helper;
|
||||
typedef struct { char a; double b; } double_helper;
|
||||
typedef struct { char a; long double b; } long_double_helper;
|
||||
int check3[2 * (offsetof (long_helper, b) <= offsetof (max_helper, b)) - 1];
|
||||
int check4[2 * (offsetof (double_helper, b) <= offsetof (max_helper, b)) - 1];
|
||||
int check5[2 * (offsetof (long_double_helper, b) <= offsetof (max_helper, b)) - 1];
|
||||
]])],
|
||||
[gl_cv_type_max_align_t=yes],
|
||||
[gl_cv_type_max_align_t=no])
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 28
|
||||
# serial 29
|
||||
|
||||
# Written by Paul Eggert.
|
||||
|
||||
|
@ -113,6 +113,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
|
|||
HAVE_SIGDESCR_NP=1; AC_SUBST([HAVE_SIGDESCR_NP])
|
||||
HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL])
|
||||
HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP])
|
||||
REPLACE_FFSLL=0; AC_SUBST([REPLACE_FFSLL])
|
||||
REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR])
|
||||
REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM])
|
||||
REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# sys_stat_h.m4 serial 36 -*- Autoconf -*-
|
||||
# sys_stat_h.m4 serial 38 -*- Autoconf -*-
|
||||
dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -104,7 +104,9 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
|
|||
REPLACE_LSTAT=0; AC_SUBST([REPLACE_LSTAT])
|
||||
REPLACE_MKDIR=0; AC_SUBST([REPLACE_MKDIR])
|
||||
REPLACE_MKFIFO=0; AC_SUBST([REPLACE_MKFIFO])
|
||||
REPLACE_MKFIFOAT=0; AC_SUBST([REPLACE_MKFIFOAT])
|
||||
REPLACE_MKNOD=0; AC_SUBST([REPLACE_MKNOD])
|
||||
REPLACE_MKNODAT=0; AC_SUBST([REPLACE_MKNODAT])
|
||||
REPLACE_STAT=0; AC_SUBST([REPLACE_STAT])
|
||||
REPLACE_UTIMENSAT=0; AC_SUBST([REPLACE_UTIMENSAT])
|
||||
])
|
||||
|
|
20
m4/time_h.m4
20
m4/time_h.m4
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc.
|
||||
|
||||
# serial 13
|
||||
# serial 15
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -25,6 +25,22 @@ AC_DEFUN([gl_HEADER_TIME_H_BODY],
|
|||
AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC])
|
||||
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
|
||||
AC_CACHE_CHECK([for TIME_UTC in <time.h>],
|
||||
[gl_cv_time_h_has_TIME_UTC],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <time.h>
|
||||
]],
|
||||
[[static int x = TIME_UTC; x++;]])],
|
||||
[gl_cv_time_h_has_TIME_UTC=yes],
|
||||
[gl_cv_time_h_has_TIME_UTC=no])])
|
||||
if test $gl_cv_time_h_has_TIME_UTC = yes; then
|
||||
TIME_H_DEFINES_TIME_UTC=1
|
||||
else
|
||||
TIME_H_DEFINES_TIME_UTC=0
|
||||
fi
|
||||
AC_SUBST([TIME_H_DEFINES_TIME_UTC])
|
||||
])
|
||||
|
||||
dnl Check whether 'struct timespec' is declared
|
||||
|
@ -113,6 +129,7 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS],
|
|||
GNULIB_STRFTIME=0; AC_SUBST([GNULIB_STRFTIME])
|
||||
GNULIB_STRPTIME=0; AC_SUBST([GNULIB_STRPTIME])
|
||||
GNULIB_TIMEGM=0; AC_SUBST([GNULIB_TIMEGM])
|
||||
GNULIB_TIMESPEC_GET=0; AC_SUBST([GNULIB_TIMESPEC_GET])
|
||||
GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R])
|
||||
GNULIB_TIME_RZ=0; AC_SUBST([GNULIB_TIME_RZ])
|
||||
GNULIB_TZSET=0; AC_SUBST([GNULIB_TZSET])
|
||||
|
@ -123,6 +140,7 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS],
|
|||
HAVE_NANOSLEEP=1; AC_SUBST([HAVE_NANOSLEEP])
|
||||
HAVE_STRPTIME=1; AC_SUBST([HAVE_STRPTIME])
|
||||
HAVE_TIMEGM=1; AC_SUBST([HAVE_TIMEGM])
|
||||
HAVE_TIMESPEC_GET=1; AC_SUBST([HAVE_TIMESPEC_GET])
|
||||
dnl Even GNU libc does not have timezone_t yet.
|
||||
HAVE_TIMEZONE_T=0; AC_SUBST([HAVE_TIMEZONE_T])
|
||||
dnl If another module says to replace or to not replace, do that.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# serial 7
|
||||
# serial 9
|
||||
# See if we need to provide utimensat replacement.
|
||||
|
||||
dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
|
||||
|
@ -12,6 +12,7 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
|
|||
[
|
||||
AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CHECK_FUNCS_ONCE([utimensat])
|
||||
if test $ac_cv_func_utimensat = no; then
|
||||
HAVE_UTIMENSAT=0
|
||||
|
@ -28,10 +29,19 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
|
|||
const char *f = "conftest.file";
|
||||
if (close (creat (f, 0600)))
|
||||
return 1;
|
||||
/* Test whether a trailing slash is handled correctly.
|
||||
This fails on AIX 7.2. */
|
||||
{
|
||||
struct timespec ts[2];
|
||||
ts[0].tv_sec = 345183300; ts[0].tv_nsec = 0;
|
||||
ts[1] = ts[0];
|
||||
if (utimensat (AT_FDCWD, "conftest.file/", ts, 0) == 0)
|
||||
result |= 2;
|
||||
}
|
||||
/* Test whether the AT_SYMLINK_NOFOLLOW flag is supported. */
|
||||
{
|
||||
if (utimensat (AT_FDCWD, f, NULL, AT_SYMLINK_NOFOLLOW))
|
||||
result |= 2;
|
||||
result |= 4;
|
||||
}
|
||||
/* Test whether UTIME_NOW and UTIME_OMIT work. */
|
||||
{
|
||||
|
@ -41,7 +51,7 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
|
|||
ts[1].tv_sec = 1;
|
||||
ts[1].tv_nsec = UTIME_NOW;
|
||||
if (utimensat (AT_FDCWD, f, ts, 0))
|
||||
result |= 4;
|
||||
result |= 8;
|
||||
}
|
||||
sleep (1);
|
||||
{
|
||||
|
@ -52,19 +62,44 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
|
|||
ts[1].tv_sec = 1;
|
||||
ts[1].tv_nsec = UTIME_OMIT;
|
||||
if (utimensat (AT_FDCWD, f, ts, 0))
|
||||
result |= 8;
|
||||
if (stat (f, &st))
|
||||
result |= 16;
|
||||
else if (st.st_ctime < st.st_atime)
|
||||
if (stat (f, &st))
|
||||
result |= 32;
|
||||
else if (st.st_ctime < st.st_atime)
|
||||
result |= 64;
|
||||
}
|
||||
return result;
|
||||
]])],
|
||||
[gl_cv_func_utimensat_works=yes],
|
||||
[gl_cv_func_utimensat_works=no],
|
||||
[gl_cv_func_utimensat_works="guessing yes"])])
|
||||
if test "$gl_cv_func_utimensat_works" = no; then
|
||||
REPLACE_UTIMENSAT=1
|
||||
fi
|
||||
[case $? in
|
||||
2) gl_cv_func_utimensat_works='nearly' ;;
|
||||
*) gl_cv_func_utimensat_works=no ;;
|
||||
esac
|
||||
],
|
||||
[case "$host_os" in
|
||||
# Guess yes on Linux or glibc systems.
|
||||
linux-* | linux | *-gnu* | gnu*)
|
||||
gl_cv_func_utimensat_works="guessing yes" ;;
|
||||
# Guess 'nearly' on AIX.
|
||||
aix*)
|
||||
gl_cv_func_utimensat_works="guessing nearly" ;;
|
||||
# If we don't know, obey --enable-cross-guesses.
|
||||
*)
|
||||
gl_cv_func_utimensat_works="$gl_cross_guess_normal" ;;
|
||||
esac
|
||||
])
|
||||
])
|
||||
case "$gl_cv_func_utimensat_works" in
|
||||
*yes)
|
||||
;;
|
||||
*nearly)
|
||||
AC_DEFINE([HAVE_NEARLY_WORKING_UTIMENSAT], [1],
|
||||
[Define to 1 if utimensat works, except for the trailing slash handling.])
|
||||
REPLACE_UTIMENSAT=1
|
||||
;;
|
||||
*)
|
||||
REPLACE_UTIMENSAT=1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
|
|
Loading…
Add table
Reference in a new issue