1 /* ABI compatibility for lgamma functions.
2    Copyright (C) 2015-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #ifndef LGAMMA_COMPAT_H
20 #define LGAMMA_COMPAT_H 1
21 
22 #include <math-svid-compat.h>
23 #include <shlib-compat.h>
24 
25 /* XSI POSIX requires lgamma to set signgam, but ISO C does not permit
26    this.  Namespace issues can be avoided if the functions set
27    __signgam and signgam is a weak alias, but this only works if both
28    signgam and __signgam were exported from the glibc version the
29    program was linked against.  Before glibc 2.23, lgamma functions
30    set signgam which was not a weak alias for __signgam, so old
31    binaries have dynamic symbols for signgam only and the versions of
32    lgamma used for old binaries must set both signgam and __signgam.
33    Those versions also do a check of _LIB_VERSION != _ISOC_ to match
34    old glibc.
35 
36    Users of this file define USE_AS_COMPAT to 0 when building the main
37    version of lgamma, 1 when building the compatibility version.  */
38 
39 #define LGAMMA_OLD_VER GLIBC_2_0
40 #define LGAMMA_NEW_VER GLIBC_2_23
41 #define HAVE_LGAMMA_COMPAT SHLIB_COMPAT (libm, LGAMMA_OLD_VER, LGAMMA_NEW_VER)
42 
43 /* Whether to build this version at all.  */
44 #define BUILD_LGAMMA \
45   (LIBM_SVID_COMPAT && (HAVE_LGAMMA_COMPAT || !USE_AS_COMPAT))
46 
47 /* The name to use for this version.  */
48 #if USE_AS_COMPAT
49 # define LGFUNC(FUNC) FUNC ## _compat
50 #else
51 # define LGFUNC(FUNC) FUNC
52 #endif
53 
54 /* If there is a compatibility version, gamma (not an ISO C function,
55    so never a problem for it to set signgam) points directly to it
56    rather than having separate versions.  */
57 #define GAMMA_ALIAS (USE_AS_COMPAT ? HAVE_LGAMMA_COMPAT : !HAVE_LGAMMA_COMPAT)
58 
59 /* How to call the underlying lgamma_r function.  */
60 #define CALL_LGAMMA(TYPE, FUNC, ARG)			\
61   ({							\
62     TYPE lgamma_tmp;					\
63     int local_signgam;					\
64     if (USE_AS_COMPAT)					\
65       {							\
66 	lgamma_tmp = FUNC ((ARG), &local_signgam);	\
67 	if (_LIB_VERSION != _ISOC_)			\
68 	  signgam = __signgam = local_signgam;		\
69       }							\
70     else						\
71       lgamma_tmp = FUNC ((ARG), &__signgam);		\
72     lgamma_tmp;						\
73   })
74 
75 #endif /* lgamma-compat.h.  */
76