mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-03 10:53:23 +00:00
Update from Gnulib
This incorporates: 2020-08-20 sigabbrev_np: New module 2020-08-20 stdalign: Fix 32-bit test failures clang versions < 8 2020-08-17 careadlinkat: speedup for GCC 10 with GCC_LINT 2020-08-17 Assume autoconf >= 2.64 * build-aux/config.guess, build-aux/config.sub, lib/careadlinkat.c: * lib/stdalign.in.h, lib/string.in.h, m4/std-gnu11.m4, m4/string_h.m4: Copy from Gnulib. * lib/gnulib.mk.in: Regenerate.
This commit is contained in:
parent
348686b3f3
commit
3e10174fb6
8 changed files with 105 additions and 66 deletions
28
build-aux/config.guess
vendored
28
build-aux/config.guess
vendored
|
@ -2,7 +2,7 @@
|
|||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2020 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2020-07-12'
|
||||
timestamp='2020-08-17'
|
||||
|
||||
# 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
|
||||
|
@ -404,7 +404,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
|
|||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||
if test "$CC_FOR_BUILD" != no_compiler_found; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
|
@ -544,10 +544,10 @@ EOF
|
|||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
|
||||
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
|
||||
then
|
||||
if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
|
||||
[ "$TARGET_BINARY_INTERFACE"x = x ]
|
||||
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
|
||||
test "$TARGET_BINARY_INTERFACE"x = x
|
||||
then
|
||||
echo m88k-dg-dgux"$UNAME_RELEASE"
|
||||
else
|
||||
|
@ -580,7 +580,7 @@ EOF
|
|||
echo i386-ibm-aix
|
||||
exit ;;
|
||||
ia64:AIX:*:*)
|
||||
if [ -x /usr/bin/oslevel ] ; then
|
||||
if test -x /usr/bin/oslevel ; then
|
||||
IBM_REV=`/usr/bin/oslevel`
|
||||
else
|
||||
IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
|
||||
|
@ -620,7 +620,7 @@ EOF
|
|||
else
|
||||
IBM_ARCH=powerpc
|
||||
fi
|
||||
if [ -x /usr/bin/lslpp ] ; then
|
||||
if test -x /usr/bin/lslpp ; then
|
||||
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
|
||||
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
|
||||
else
|
||||
|
@ -655,7 +655,7 @@ EOF
|
|||
9000/31?) HP_ARCH=m68000 ;;
|
||||
9000/[34]??) HP_ARCH=m68k ;;
|
||||
9000/[678][0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
if test -x /usr/bin/getconf; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "$sc_cpu_version" in
|
||||
|
@ -669,7 +669,7 @@ EOF
|
|||
esac ;;
|
||||
esac
|
||||
fi
|
||||
if [ "$HP_ARCH" = "" ]; then
|
||||
if test "$HP_ARCH" = ""; then
|
||||
set_cc_for_build
|
||||
sed 's/^ //' << EOF > "$dummy.c"
|
||||
|
||||
|
@ -708,7 +708,7 @@ EOF
|
|||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
fi ;;
|
||||
esac
|
||||
if [ "$HP_ARCH" = hppa2.0w ]
|
||||
if test "$HP_ARCH" = hppa2.0w
|
||||
then
|
||||
set_cc_for_build
|
||||
|
||||
|
@ -782,7 +782,7 @@ EOF
|
|||
echo hppa1.0-hp-osf
|
||||
exit ;;
|
||||
i*86:OSF1:*:*)
|
||||
if [ -x /usr/sbin/sysversion ] ; then
|
||||
if test -x /usr/sbin/sysversion ; then
|
||||
echo "$UNAME_MACHINE"-unknown-osf1mk
|
||||
else
|
||||
echo "$UNAME_MACHINE"-unknown-osf1
|
||||
|
@ -1097,7 +1097,7 @@ EOF
|
|||
x86_64:Linux:*:*)
|
||||
set_cc_for_build
|
||||
LIBCABI=$LIBC
|
||||
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||
if test "$CC_FOR_BUILD" != no_compiler_found; then
|
||||
if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
|
||||
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_X32 >/dev/null
|
||||
|
@ -1294,7 +1294,7 @@ EOF
|
|||
echo mips-sony-newsos6
|
||||
exit ;;
|
||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
if test -d /usr/nec; then
|
||||
echo mips-nec-sysv"$UNAME_RELEASE"
|
||||
else
|
||||
echo mips-unknown-sysv"$UNAME_RELEASE"
|
||||
|
@ -1359,7 +1359,7 @@ EOF
|
|||
else
|
||||
set_cc_for_build
|
||||
fi
|
||||
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||
if test "$CC_FOR_BUILD" != no_compiler_found; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
|
|
4
build-aux/config.sub
vendored
4
build-aux/config.sub
vendored
|
@ -2,7 +2,7 @@
|
|||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2020 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2020-07-10'
|
||||
timestamp='2020-08-17'
|
||||
|
||||
# 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
|
||||
|
@ -1278,7 +1278,7 @@ esac
|
|||
|
||||
# Decode manufacturer-specific aliases for certain operating systems.
|
||||
|
||||
if [ x$basic_os != x ]
|
||||
if test x$basic_os != x
|
||||
then
|
||||
|
||||
# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
|
||||
|
|
|
@ -38,66 +38,41 @@
|
|||
|
||||
#include "allocator.h"
|
||||
|
||||
/* Assuming the current directory is FD, get the symbolic link value
|
||||
of FILENAME as a null-terminated string and put it into a buffer.
|
||||
If FD is AT_FDCWD, FILENAME is interpreted relative to the current
|
||||
working directory, as in openat.
|
||||
enum { STACK_BUF_SIZE = 1024 };
|
||||
|
||||
If the link is small enough to fit into BUFFER put it there.
|
||||
BUFFER's size is BUFFER_SIZE, and BUFFER can be null
|
||||
if BUFFER_SIZE is zero.
|
||||
/* Act like careadlinkat (see below), with an additional argument
|
||||
STACK_BUF that can be used as temporary storage.
|
||||
|
||||
If the link is not small, put it into a dynamically allocated
|
||||
buffer managed by ALLOC. It is the caller's responsibility to free
|
||||
the returned value if it is nonnull and is not BUFFER. A null
|
||||
ALLOC stands for the standard allocator.
|
||||
|
||||
The PREADLINKAT function specifies how to read links. It operates
|
||||
like POSIX readlinkat()
|
||||
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
|
||||
but can assume that its first argument is the same as FD.
|
||||
|
||||
If successful, return the buffer address; otherwise return NULL and
|
||||
set errno. */
|
||||
|
||||
char *
|
||||
careadlinkat (int fd, char const *filename,
|
||||
If GCC_LINT is defined, do not inline this function with GCC 10.1
|
||||
and later, to avoid creating a pointer to the stack that GCC
|
||||
-Wreturn-local-addr incorrectly complains about. See:
|
||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644
|
||||
Although the noinline attribute can hurt performance a bit, no better way
|
||||
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 (defined GCC_LINT || defined lint) && _GL_GNUC_PREREQ (10, 1)
|
||||
__attribute__ ((__noinline__))
|
||||
#endif
|
||||
static char *
|
||||
readlink_stk (int fd, char const *filename,
|
||||
char *buffer, size_t buffer_size,
|
||||
struct allocator const *alloc,
|
||||
ssize_t (*preadlinkat) (int, char const *, char *, size_t))
|
||||
ssize_t (*preadlinkat) (int, char const *, char *, size_t),
|
||||
char stack_buf[STACK_BUF_SIZE])
|
||||
{
|
||||
char *buf;
|
||||
size_t buf_size;
|
||||
size_t buf_size_max =
|
||||
SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
|
||||
char stack_buf[1024];
|
||||
|
||||
#if (defined GCC_LINT || defined lint) && _GL_GNUC_PREREQ (10, 1)
|
||||
/* Pacify preadlinkat without creating a pointer to the stack
|
||||
that a broken gcc -Wreturn-local-addr would cry wolf about. See:
|
||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95044
|
||||
This workaround differs from the mainline code, but
|
||||
no other way to pacify GCC 10.1.0 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. */
|
||||
# define WORK_AROUND_GCC_BUG_95044
|
||||
#endif
|
||||
|
||||
if (! alloc)
|
||||
alloc = &stdlib_allocator;
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
#ifdef WORK_AROUND_GCC_BUG_95044
|
||||
buffer = alloc->allocate (sizeof stack_buf);
|
||||
#else
|
||||
/* Allocate the initial buffer on the stack. This way, in the
|
||||
common case of a symlink of small size, we get away with a
|
||||
single small malloc() instead of a big malloc() followed by a
|
||||
shrinking realloc(). */
|
||||
buffer = stack_buf;
|
||||
#endif
|
||||
buffer_size = sizeof stack_buf;
|
||||
buffer_size = STACK_BUF_SIZE;
|
||||
}
|
||||
|
||||
buf = buffer;
|
||||
|
@ -172,3 +147,44 @@ careadlinkat (int fd, char const *filename,
|
|||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Assuming the current directory is FD, get the symbolic link value
|
||||
of FILENAME as a null-terminated string and put it into a buffer.
|
||||
If FD is AT_FDCWD, FILENAME is interpreted relative to the current
|
||||
working directory, as in openat.
|
||||
|
||||
If the link is small enough to fit into BUFFER put it there.
|
||||
BUFFER's size is BUFFER_SIZE, and BUFFER can be null
|
||||
if BUFFER_SIZE is zero.
|
||||
|
||||
If the link is not small, put it into a dynamically allocated
|
||||
buffer managed by ALLOC. It is the caller's responsibility to free
|
||||
the returned value if it is nonnull and is not BUFFER. A null
|
||||
ALLOC stands for the standard allocator.
|
||||
|
||||
The PREADLINKAT function specifies how to read links. It operates
|
||||
like POSIX readlinkat()
|
||||
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
|
||||
but can assume that its first argument is the same as FD.
|
||||
|
||||
If successful, return the buffer address; otherwise return NULL and
|
||||
set errno. */
|
||||
|
||||
char *
|
||||
careadlinkat (int fd, char const *filename,
|
||||
char *buffer, size_t buffer_size,
|
||||
struct allocator const *alloc,
|
||||
ssize_t (*preadlinkat) (int, char const *, char *, size_t))
|
||||
{
|
||||
/* Allocate the initial buffer on the stack. This way, in the
|
||||
common case of a symlink of small size, we get away with a
|
||||
single small malloc instead of a big malloc followed by a
|
||||
shrinking realloc.
|
||||
|
||||
If GCC -Wreturn-local-addr warns about this buffer, the warning
|
||||
is bogus; see readlink_stk. */
|
||||
char stack_buf[STACK_BUF_SIZE];
|
||||
return readlink_stk (fd, filename, buffer, buffer_size, alloc,
|
||||
preadlinkat, stack_buf);
|
||||
}
|
||||
|
|
|
@ -424,6 +424,7 @@ GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
|
|||
GNULIB_SELECT = @GNULIB_SELECT@
|
||||
GNULIB_SETENV = @GNULIB_SETENV@
|
||||
GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
|
||||
GNULIB_SIGABBREV_NP = @GNULIB_SIGABBREV_NP@
|
||||
GNULIB_SIGACTION = @GNULIB_SIGACTION@
|
||||
GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
|
||||
GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
|
||||
|
@ -644,6 +645,7 @@ HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
|
|||
HAVE_SETENV = @HAVE_SETENV@
|
||||
HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
|
||||
HAVE_SETSTATE = @HAVE_SETSTATE@
|
||||
HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@
|
||||
HAVE_SIGACTION = @HAVE_SIGACTION@
|
||||
HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
|
||||
HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
|
||||
|
@ -2843,6 +2845,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
|
|||
-e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
|
||||
-e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
|
||||
-e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
|
||||
-e 's/@''GNULIB_SIGABBREV_NP''@/$(GNULIB_SIGABBREV_NP)/g' \
|
||||
-e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
|
||||
-e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
|
||||
< $(srcdir)/string.in.h | \
|
||||
|
@ -2865,6 +2868,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
|
|||
-e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \
|
||||
-e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
|
||||
-e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \
|
||||
-e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \
|
||||
-e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
|
||||
-e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
|
||||
-e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
|
||||
|
|
|
@ -54,10 +54,12 @@
|
|||
#undef _Alignof
|
||||
|
||||
/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
|
||||
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>. */
|
||||
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
|
||||
clang versions < 8.0.0 have the same bug. */
|
||||
#if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
|
||||
|| (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
|
||||
&& !defined __clang__))
|
||||
&& !defined __clang__) \
|
||||
|| (defined __clang__ && __clang_major__ < 8))
|
||||
# ifdef __cplusplus
|
||||
# if 201103 <= __cplusplus
|
||||
# define _Alignof(type) alignof (type)
|
||||
|
|
|
@ -1045,6 +1045,21 @@ _GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - "
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Return an abbreviation string for the signal number SIG. */
|
||||
#if @GNULIB_SIGABBREV_NP@
|
||||
# if ! @HAVE_SIGABBREV_NP@
|
||||
_GL_FUNCDECL_SYS (sigabbrev_np, const char *, (int sig));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (sigabbrev_np, const char *, (int sig));
|
||||
_GL_CXXALIASWARN (sigabbrev_np);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef sigabbrev_np
|
||||
# if HAVE_RAW_DECL_SIGABBREV_NP
|
||||
_GL_WARN_ON_USE (sigabbrev_np, "sigabbrev_np is unportable - "
|
||||
"use gnulib module sigabbrev_np for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_STRSIGNAL@
|
||||
# if @REPLACE_STRSIGNAL@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
|
|
|
@ -70,7 +70,7 @@ _AS_ECHO_LOG([checking for _AC_LANG compiler version])
|
|||
set X $ac_compile
|
||||
ac_compiler=$[2]
|
||||
for ac_option in --version -v -V -qversion -version; do
|
||||
m4_ifdef([_AC_DO_LIMIT],[_AC_DO_LIMIT],[_AC_DO])([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
|
||||
_AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
|
||||
done
|
||||
|
||||
m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
|
||||
|
@ -135,7 +135,7 @@ _AS_ECHO_LOG([checking for _AC_LANG compiler version])
|
|||
set X $ac_compile
|
||||
ac_compiler=$[2]
|
||||
for ac_option in --version -v -V -qversion; do
|
||||
m4_ifdef([_AC_DO_LIMIT],[_AC_DO_LIMIT],[_AC_DO])([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
|
||||
_AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
|
||||
done
|
||||
|
||||
m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
|
||||
|
|
|
@ -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 24
|
||||
# serial 25
|
||||
|
||||
# Written by Paul Eggert.
|
||||
|
||||
|
@ -28,7 +28,7 @@ AC_DEFUN([gl_HEADER_STRING_H_BODY],
|
|||
]],
|
||||
[ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul
|
||||
strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r
|
||||
strerror_r strsignal strverscmp])
|
||||
strerror_r sigabbrev_np strsignal strverscmp])
|
||||
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
])
|
||||
|
@ -80,6 +80,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
|
|||
GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R])
|
||||
GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR])
|
||||
GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R])
|
||||
GNULIB_SIGABBREV_NP=0;AC_SUBST([GNULIB_SIGABBREV_NP])
|
||||
GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL])
|
||||
GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP])
|
||||
HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN])
|
||||
|
@ -102,6 +103,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
|
|||
HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR])
|
||||
HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R])
|
||||
HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R])
|
||||
HAVE_SIGABBREV_NP=1; AC_SUBST([HAVE_SIGABBREV_NP])
|
||||
HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL])
|
||||
HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP])
|
||||
REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue