From c0f1bce31151ed43120bcda3cf919c81b2873641 Mon Sep 17 00:00:00 2001 From: RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 23 Aug 2022 19:42:51 +0200 Subject: Sync with the latest Gnulib code (d27c820595) --- build-aux/config.rpath | 22 +- build-aux/snippet/_Noreturn.h | 10 - build-aux/snippet/arg-nonnull.h | 26 - build-aux/snippet/c++defs.h | 271 ---- build-aux/snippet/warn-on-use.h | 109 -- gl/Makefile.am | 2337 ++++++++++++++++++++++------------ gl/_Noreturn.h | 45 + gl/af_alg.c | 213 ++++ gl/af_alg.h | 115 ++ gl/alloca.in.h | 35 +- gl/arpa_inet.in.h | 32 +- gl/asnprintf.c | 18 +- gl/asprintf.c | 18 +- gl/attribute.h | 226 ++++ gl/base64.c | 126 +- gl/base64.h | 38 +- gl/basename-lgpl.c | 38 +- gl/basename-lgpl.h | 78 ++ gl/basename.c | 56 +- gl/btowc.c | 18 +- gl/byteswap.in.h | 44 + gl/calloc.c | 55 + gl/cdefs.h | 707 ++++++++++ gl/cloexec.c | 83 ++ gl/cloexec.h | 36 + gl/close.c | 75 ++ gl/config.charset | 684 ---------- gl/dirname-lgpl.c | 18 +- gl/dirname.c | 6 +- gl/dirname.h | 54 +- gl/dosname.h | 53 - gl/dup2.c | 189 +++ gl/dynarray.h | 284 +++++ gl/errno.in.h | 22 +- gl/error.c | 74 +- gl/error.h | 45 +- gl/exitfail.c | 18 +- gl/exitfail.h | 18 +- gl/fcntl.c | 629 +++++++++ gl/fcntl.in.h | 445 +++++++ gl/fd-hook.c | 22 +- gl/fd-hook.h | 22 +- gl/fflush.c | 233 ++++ gl/filename.h | 112 ++ gl/float+.h | 18 +- gl/float.c | 18 +- gl/float.in.h | 30 +- gl/floor.c | 20 +- gl/floorf.c | 18 +- gl/fopen.c | 230 ++++ gl/fpurge.c | 150 +++ gl/freading.c | 76 ++ gl/freading.h | 55 + gl/free.c | 53 + gl/fseek.c | 30 + gl/fseeko.c | 164 +++ gl/fstat.c | 94 ++ gl/fsusage.c | 123 +- gl/fsusage.h | 21 +- gl/ftell.c | 37 + gl/ftello.c | 157 +++ gl/full-read.c | 18 - gl/full-read.h | 24 - gl/full-write.c | 79 -- gl/gai_strerror.c | 18 +- gl/getaddrinfo.c | 178 ++- gl/getdelim.c | 147 +++ gl/getdtablesize.c | 124 ++ gl/gethostname.c | 20 +- gl/getline.c | 27 + gl/getloadavg.c | 178 +-- gl/getopt-cdefs.in.h | 66 + gl/getopt-core.h | 96 ++ gl/getopt-ext.h | 77 ++ gl/getopt-pfx-core.h | 66 + gl/getopt-pfx-ext.h | 70 + gl/getopt.c | 1442 ++++++++------------- gl/getopt.in.h | 242 +--- gl/getopt1.c | 179 ++- gl/getopt_int.h | 91 +- gl/getprogname.c | 302 +++++ gl/getprogname.h | 40 + gl/gettext.h | 50 +- gl/gl_openssl.h | 116 ++ gl/glthread/lock.c | 866 ++++--------- gl/glthread/lock.h | 544 +++----- gl/glthread/threadlib.c | 55 +- gl/hard-locale.c | 35 + gl/hard-locale.h | 28 + gl/ialloc.c | 21 + gl/ialloc.h | 100 ++ gl/idpriv-droptemp.c | 14 +- gl/idpriv.h | 12 +- gl/idx.h | 134 ++ gl/inet_ntop.c | 20 +- gl/intprops-internal.h | 392 ++++++ gl/intprops.h | 250 ++-- gl/inttypes.in.h | 1002 +++++++++++++++ gl/itold.c | 18 +- gl/langinfo.in.h | 66 +- gl/lc-charset-dispatch.c | 82 ++ gl/lc-charset-dispatch.h | 40 + gl/libc-config.h | 202 +++ gl/limits.in.h | 131 ++ gl/localcharset.c | 1309 ++++++++++++++----- gl/localcharset.h | 119 +- gl/locale.in.h | 121 +- gl/localeconv.c | 18 +- gl/lseek.c | 89 ++ gl/m4/00gnulib.m4 | 91 +- gl/m4/__inline.m4 | 22 + gl/m4/absolute-header.m4 | 100 ++ gl/m4/af_alg.m4 | 57 + gl/m4/alloca.m4 | 53 +- gl/m4/arpa_inet_h.m4 | 35 +- gl/m4/base64.m4 | 2 +- gl/m4/btowc.m4 | 33 +- gl/m4/builtin-expect.m4 | 49 + gl/m4/byteswap.m4 | 17 + gl/m4/calloc.m4 | 83 ++ gl/m4/close.m4 | 35 + gl/m4/codeset.m4 | 3 +- gl/m4/configmake.m4 | 50 - gl/m4/dirname.m4 | 19 - gl/m4/double-slash-root.m4 | 2 +- gl/m4/dup2.m4 | 105 ++ gl/m4/eealloc.m4 | 2 +- gl/m4/environ.m4 | 23 +- gl/m4/errno_h.m4 | 20 +- gl/m4/error.m4 | 8 +- gl/m4/exponentd.m4 | 2 +- gl/m4/extensions.m4 | 209 ++- gl/m4/extern-inline.m4 | 96 +- gl/m4/fcntl-o.m4 | 22 +- gl/m4/fcntl.m4 | 151 +++ gl/m4/fcntl_h.m4 | 70 + gl/m4/fflush.m4 | 100 ++ gl/m4/float_h.m4 | 54 +- gl/m4/floorf.m4 | 18 +- gl/m4/fopen.m4 | 149 +++ gl/m4/fpurge.m4 | 73 ++ gl/m4/freading.m4 | 11 + gl/m4/free.m4 | 52 + gl/m4/fseek.m4 | 15 + gl/m4/fseeko.m4 | 77 ++ gl/m4/fstat.m4 | 40 + gl/m4/fstypename.m4 | 2 +- gl/m4/fsusage.m4 | 363 +++--- gl/m4/ftell.m4 | 15 + gl/m4/ftello.m4 | 151 +++ gl/m4/getaddrinfo.m4 | 43 +- gl/m4/getdelim.m4 | 99 ++ gl/m4/getdtablesize.m4 | 63 + gl/m4/gethostname.m4 | 8 +- gl/m4/getline.m4 | 109 ++ gl/m4/getloadavg.m4 | 17 +- gl/m4/getopt.m4 | 39 +- gl/m4/getprogname.m4 | 43 + gl/m4/gettext.m4 | 107 +- gl/m4/gl-openssl.m4 | 76 ++ gl/m4/glibc2.m4 | 31 - gl/m4/glibc21.m4 | 34 - gl/m4/gnulib-cache.m4 | 40 +- gl/m4/gnulib-common.m4 | 940 ++++++++++++-- gl/m4/gnulib-comp.m4 | 861 ++++++++++--- gl/m4/gnulib-tool.m4 | 10 +- gl/m4/host-cpu-c-abi.m4 | 678 ++++++++++ gl/m4/hostent.m4 | 8 +- gl/m4/iconv.m4 | 193 +-- gl/m4/idpriv.m4 | 2 +- gl/m4/include_next.m4 | 90 +- gl/m4/inet_ntop.m4 | 16 +- gl/m4/intdiv0.m4 | 87 -- gl/m4/intl-thread-locale.m4 | 219 ++++ gl/m4/intl.m4 | 271 ---- gl/m4/intldir.m4 | 19 - gl/m4/intlmacosx.m4 | 41 +- gl/m4/intmax.m4 | 36 - gl/m4/intmax_t.m4 | 16 +- gl/m4/inttypes-pri.m4 | 42 - gl/m4/inttypes.m4 | 180 +++ gl/m4/inttypes_h.m4 | 2 +- gl/m4/langinfo_h.m4 | 48 +- gl/m4/largefile.m4 | 87 +- gl/m4/lcmessage.m4 | 35 - gl/m4/lib-ld.m4 | 163 ++- gl/m4/lib-link.m4 | 184 +-- gl/m4/lib-prefix.m4 | 241 ++-- gl/m4/limits-h.m4 | 41 + gl/m4/localcharset.m4 | 10 +- gl/m4/locale-fr.m4 | 43 +- gl/m4/locale-ja.m4 | 45 +- gl/m4/locale-zh.m4 | 45 +- gl/m4/locale_h.m4 | 134 +- gl/m4/localeconv.m4 | 2 +- gl/m4/lock.m4 | 11 +- gl/m4/longlong.m4 | 113 -- gl/m4/ls-mntd-fs.m4 | 357 ------ gl/m4/lseek.m4 | 78 ++ gl/m4/malloc.m4 | 173 ++- gl/m4/malloca.m4 | 5 +- gl/m4/math_h.m4 | 560 ++++---- gl/m4/mbrtowc.m4 | 358 +++++- gl/m4/mbsinit.m4 | 15 +- gl/m4/mbstate_t.m4 | 13 +- gl/m4/mbtowc.m4 | 13 +- gl/m4/memchr.m4 | 74 +- gl/m4/minmax.m4 | 44 + gl/m4/mktime.m4 | 142 ++- gl/m4/mmap-anon.m4 | 8 +- gl/m4/mode_t.m4 | 26 + gl/m4/mountlist.m4 | 331 ++++- gl/m4/msvc-inval.m4 | 2 +- gl/m4/msvc-nothrow.m4 | 2 +- gl/m4/multiarch.m4 | 69 +- gl/m4/netdb_h.m4 | 28 +- gl/m4/netinet_in_h.m4 | 10 +- gl/m4/nl_langinfo.m4 | 37 +- gl/m4/nls.m4 | 14 +- gl/m4/nocrash.m4 | 13 +- gl/m4/off_t.m4 | 2 +- gl/m4/onceonly.m4 | 104 -- gl/m4/open-cloexec.m4 | 21 + gl/m4/open-slash.m4 | 60 + gl/m4/open.m4 | 56 + gl/m4/pathmax.m4 | 42 + gl/m4/pid_t.m4 | 38 + gl/m4/po.m4 | 67 +- gl/m4/printf-posix.m4 | 48 - gl/m4/printf.m4 | 490 ++++--- gl/m4/progtest.m4 | 20 +- gl/m4/pthread_rwlock_rdlock.m4 | 185 +++ gl/m4/read.m4 | 26 - gl/m4/realloc.m4 | 63 + gl/m4/reallocarray.m4 | 23 + gl/m4/regex.m4 | 193 ++- gl/m4/safe-read.m4 | 12 - gl/m4/servent.m4 | 8 +- gl/m4/setenv.m4 | 76 +- gl/m4/setlocale_null.m4 | 98 ++ gl/m4/sha1.m4 | 8 +- gl/m4/size_max.m4 | 16 +- gl/m4/snprintf.m4 | 12 +- gl/m4/socketlib.m4 | 38 +- gl/m4/sockets.m4 | 2 +- gl/m4/socklen.m4 | 17 +- gl/m4/sockpfaf.m4 | 23 +- gl/m4/ssize_t.m4 | 2 +- gl/m4/stat-time.m4 | 83 ++ gl/m4/stat.m4 | 85 ++ gl/m4/std-gnu11.m4 | 829 ++++++++++++ gl/m4/stdalign.m4 | 23 +- gl/m4/stdbool.m4 | 130 +- gl/m4/stddef_h.m4 | 74 +- gl/m4/stdint.m4 | 169 ++- gl/m4/stdint_h.m4 | 2 +- gl/m4/stdio_h.m4 | 229 ++-- gl/m4/stdlib_h.m4 | 173 ++- gl/m4/strcase.m4 | 8 +- gl/m4/strcasestr.m4 | 61 +- gl/m4/strerror.m4 | 30 +- gl/m4/string_h.m4 | 145 ++- gl/m4/strings_h.m4 | 40 +- gl/m4/strndup.m4 | 55 - gl/m4/strnlen.m4 | 30 - gl/m4/strsep.m4 | 6 +- gl/m4/strstr.m4 | 67 +- gl/m4/sys_socket_h.m4 | 88 +- gl/m4/sys_stat_h.m4 | 129 ++ gl/m4/sys_types_h.m4 | 50 +- gl/m4/sys_uio_h.m4 | 25 +- gl/m4/threadlib.m4 | 665 +++++++--- gl/m4/time_h.m4 | 108 +- gl/m4/time_r.m4 | 49 +- gl/m4/timegm.m4 | 10 +- gl/m4/uintmax_t.m4 | 30 - gl/m4/ungetc.m4 | 73 ++ gl/m4/unistd_h.m4 | 348 +++-- gl/m4/unlocked-io.m4 | 36 + gl/m4/vararrays.m4 | 72 ++ gl/m4/vasnprintf.m4 | 17 +- gl/m4/vasprintf.m4 | 2 +- gl/m4/visibility.m4 | 79 +- gl/m4/vsnprintf.m4 | 12 +- gl/m4/warn-on-use.m4 | 48 +- gl/m4/wchar_h.m4 | 222 ++-- gl/m4/wchar_t.m4 | 2 +- gl/m4/wcrtomb.m4 | 90 +- gl/m4/wctype_h.m4 | 99 +- gl/m4/wint_t.m4 | 49 +- gl/m4/xalloc.m4 | 2 +- gl/m4/xsize.m4 | 2 +- gl/m4/xstrndup.m4 | 15 - gl/m4/year2038.m4 | 132 ++ gl/m4/zzgnulib.m4 | 23 + gl/malloc.c | 43 +- gl/malloc/dynarray-skeleton.c | 528 ++++++++ gl/malloc/dynarray.h | 178 +++ gl/malloc/dynarray_at_failure.c | 40 + gl/malloc/dynarray_emplace_enlarge.c | 77 ++ gl/malloc/dynarray_finalize.c | 66 + gl/malloc/dynarray_resize.c | 68 + gl/malloc/dynarray_resize_clear.c | 39 + gl/malloca.c | 164 +-- gl/malloca.h | 69 +- gl/malloca.valgrind | 7 - gl/math.c | 19 + gl/math.in.h | 696 ++++++++-- gl/mbrtowc-impl-utf8.h | 138 ++ gl/mbrtowc-impl.h | 262 ++++ gl/mbrtowc.c | 394 ++---- gl/mbsinit.c | 49 +- gl/mbtowc-impl.h | 18 +- gl/mbtowc-lock.c | 150 +++ gl/mbtowc-lock.h | 125 ++ gl/mbtowc.c | 18 +- gl/memchr.c | 26 +- gl/memchr.valgrind | 16 + gl/minmax.h | 60 + gl/mktime-internal.h | 83 +- gl/mktime.c | 837 +++++------- gl/mountlist.c | 486 ++++--- gl/mountlist.h | 13 +- gl/msvc-inval.c | 18 +- gl/msvc-inval.h | 22 +- gl/msvc-nothrow.c | 22 +- gl/msvc-nothrow.h | 20 +- gl/netdb.in.h | 72 +- gl/netinet_in.in.h | 18 +- gl/nl_langinfo-lock.c | 150 +++ gl/nl_langinfo.c | 579 +++++++-- gl/open.c | 209 +++ gl/pathmax.h | 83 ++ gl/printf-args.c | 22 +- gl/printf-args.h | 30 +- gl/printf-parse.c | 55 +- gl/printf-parse.h | 18 +- gl/read.c | 85 -- gl/realloc.c | 63 + gl/reallocarray.c | 38 + gl/ref-add.sin | 29 - gl/ref-del.sin | 24 - gl/regcomp.c | 1364 +++++++++----------- gl/regex.c | 21 +- gl/regex.h | 142 ++- gl/regex_internal.c | 394 +++--- gl/regex_internal.h | 298 ++--- gl/regexec.c | 1169 +++++++---------- gl/safe-read.c | 77 -- gl/safe-read.h | 47 - gl/setenv.c | 20 +- gl/setlocale-lock.c | 150 +++ gl/setlocale_null.c | 411 ++++++ gl/setlocale_null.h | 82 ++ gl/sha1-stream.c | 129 ++ gl/sha1.c | 125 +- gl/sha1.h | 66 +- gl/size_max.h | 18 +- gl/snprintf.c | 18 +- gl/sockets.c | 33 +- gl/sockets.h | 46 +- gl/stat-time.c | 21 + gl/stat-time.h | 252 ++++ gl/stat-w32.c | 461 +++++++ gl/stat-w32.h | 37 + gl/stat.c | 440 +++++++ gl/stdalign.in.h | 54 +- gl/stdbool.in.h | 49 +- gl/stdckdint.in.h | 37 + gl/stddef.in.h | 111 +- gl/stdint.in.h | 834 ++++++------ gl/stdio-impl.h | 212 +++ gl/stdio-read.c | 168 +++ gl/stdio-write.c | 206 +++ gl/stdio.in.h | 715 ++++++++--- gl/stdlib.in.h | 759 +++++++++-- gl/str-two-way.h | 30 +- gl/strcasecmp.c | 20 +- gl/strcasestr.c | 18 +- gl/streq.h | 22 +- gl/strerror-override.c | 104 +- gl/strerror-override.h | 21 +- gl/strerror.c | 21 +- gl/string.in.h | 441 +++++-- gl/strings.in.h | 18 +- gl/stripslash.c | 18 +- gl/strncasecmp.c | 20 +- gl/strndup.c | 36 - gl/strnlen.c | 30 - gl/strsep.c | 18 +- gl/strstr.c | 22 +- gl/sys-limits.h | 42 + gl/sys_socket.c | 19 + gl/sys_socket.in.h | 137 +- gl/sys_stat.in.h | 954 ++++++++++++++ gl/sys_types.in.h | 77 +- gl/sys_uio.in.h | 18 +- gl/time.in.h | 268 +++- gl/time_r.c | 18 +- gl/timegm.c | 62 +- gl/unistd.c | 19 + gl/unistd.in.h | 995 +++++++++++++-- gl/unlocked-io.h | 136 ++ gl/unsetenv.c | 18 +- gl/vasnprintf.c | 922 ++++++++------ gl/vasnprintf.h | 41 +- gl/vasprintf.c | 18 +- gl/verify.h | 160 ++- gl/vsnprintf.c | 18 +- gl/w32sock.h | 24 +- gl/wchar.in.h | 534 ++++++-- gl/wcrtomb.c | 49 +- gl/wctype-h.c | 19 + gl/wctype.in.h | 457 +++++-- gl/windows-initguard.h | 35 + gl/windows-mutex.c | 95 ++ gl/windows-mutex.h | 51 + gl/windows-once.c | 62 + gl/windows-once.h | 47 + gl/windows-recmutex.c | 127 ++ gl/windows-recmutex.h | 57 + gl/windows-rwlock.c | 377 ++++++ gl/windows-rwlock.h | 68 + gl/xalloc-die.c | 6 +- gl/xalloc-oversized.h | 79 +- gl/xalloc.h | 233 ++-- gl/xmalloc.c | 305 ++++- gl/xsize.c | 18 + gl/xsize.h | 44 +- gl/xstrndup.c | 36 - gl/xstrndup.h | 23 - 431 files changed, 41400 insertions(+), 16609 deletions(-) delete mode 100644 build-aux/snippet/_Noreturn.h delete mode 100644 build-aux/snippet/arg-nonnull.h delete mode 100644 build-aux/snippet/c++defs.h delete mode 100644 build-aux/snippet/warn-on-use.h create mode 100644 gl/_Noreturn.h create mode 100644 gl/af_alg.c create mode 100644 gl/af_alg.h create mode 100644 gl/attribute.h create mode 100644 gl/basename-lgpl.h create mode 100644 gl/byteswap.in.h create mode 100644 gl/calloc.c create mode 100644 gl/cdefs.h create mode 100644 gl/cloexec.c create mode 100644 gl/cloexec.h create mode 100644 gl/close.c delete mode 100644 gl/config.charset delete mode 100644 gl/dosname.h create mode 100644 gl/dup2.c create mode 100644 gl/dynarray.h create mode 100644 gl/fcntl.c create mode 100644 gl/fcntl.in.h create mode 100644 gl/fflush.c create mode 100644 gl/filename.h create mode 100644 gl/fopen.c create mode 100644 gl/fpurge.c create mode 100644 gl/freading.c create mode 100644 gl/freading.h create mode 100644 gl/free.c create mode 100644 gl/fseek.c create mode 100644 gl/fseeko.c create mode 100644 gl/fstat.c create mode 100644 gl/ftell.c create mode 100644 gl/ftello.c delete mode 100644 gl/full-read.c delete mode 100644 gl/full-read.h delete mode 100644 gl/full-write.c create mode 100644 gl/getdelim.c create mode 100644 gl/getdtablesize.c create mode 100644 gl/getline.c create mode 100644 gl/getopt-cdefs.in.h create mode 100644 gl/getopt-core.h create mode 100644 gl/getopt-ext.h create mode 100644 gl/getopt-pfx-core.h create mode 100644 gl/getopt-pfx-ext.h create mode 100644 gl/getprogname.c create mode 100644 gl/getprogname.h create mode 100644 gl/gl_openssl.h create mode 100644 gl/hard-locale.c create mode 100644 gl/hard-locale.h create mode 100644 gl/ialloc.c create mode 100644 gl/ialloc.h create mode 100644 gl/idx.h create mode 100644 gl/intprops-internal.h create mode 100644 gl/inttypes.in.h create mode 100644 gl/lc-charset-dispatch.c create mode 100644 gl/lc-charset-dispatch.h create mode 100644 gl/libc-config.h create mode 100644 gl/limits.in.h create mode 100644 gl/lseek.c create mode 100644 gl/m4/__inline.m4 create mode 100644 gl/m4/absolute-header.m4 create mode 100644 gl/m4/af_alg.m4 create mode 100644 gl/m4/builtin-expect.m4 create mode 100644 gl/m4/byteswap.m4 create mode 100644 gl/m4/calloc.m4 create mode 100644 gl/m4/close.m4 delete mode 100644 gl/m4/configmake.m4 delete mode 100644 gl/m4/dirname.m4 create mode 100644 gl/m4/dup2.m4 create mode 100644 gl/m4/fcntl.m4 create mode 100644 gl/m4/fcntl_h.m4 create mode 100644 gl/m4/fflush.m4 create mode 100644 gl/m4/fopen.m4 create mode 100644 gl/m4/fpurge.m4 create mode 100644 gl/m4/freading.m4 create mode 100644 gl/m4/free.m4 create mode 100644 gl/m4/fseek.m4 create mode 100644 gl/m4/fseeko.m4 create mode 100644 gl/m4/fstat.m4 create mode 100644 gl/m4/ftell.m4 create mode 100644 gl/m4/ftello.m4 create mode 100644 gl/m4/getdelim.m4 create mode 100644 gl/m4/getdtablesize.m4 create mode 100644 gl/m4/getline.m4 create mode 100644 gl/m4/getprogname.m4 create mode 100644 gl/m4/gl-openssl.m4 delete mode 100644 gl/m4/glibc2.m4 delete mode 100644 gl/m4/glibc21.m4 create mode 100644 gl/m4/host-cpu-c-abi.m4 delete mode 100644 gl/m4/intdiv0.m4 create mode 100644 gl/m4/intl-thread-locale.m4 delete mode 100644 gl/m4/intl.m4 delete mode 100644 gl/m4/intldir.m4 delete mode 100644 gl/m4/intmax.m4 delete mode 100644 gl/m4/inttypes-pri.m4 create mode 100644 gl/m4/inttypes.m4 delete mode 100644 gl/m4/lcmessage.m4 create mode 100644 gl/m4/limits-h.m4 delete mode 100644 gl/m4/longlong.m4 delete mode 100644 gl/m4/ls-mntd-fs.m4 create mode 100644 gl/m4/lseek.m4 create mode 100644 gl/m4/minmax.m4 create mode 100644 gl/m4/mode_t.m4 delete mode 100644 gl/m4/onceonly.m4 create mode 100644 gl/m4/open-cloexec.m4 create mode 100644 gl/m4/open-slash.m4 create mode 100644 gl/m4/open.m4 create mode 100644 gl/m4/pathmax.m4 create mode 100644 gl/m4/pid_t.m4 delete mode 100644 gl/m4/printf-posix.m4 create mode 100644 gl/m4/pthread_rwlock_rdlock.m4 delete mode 100644 gl/m4/read.m4 create mode 100644 gl/m4/realloc.m4 create mode 100644 gl/m4/reallocarray.m4 delete mode 100644 gl/m4/safe-read.m4 create mode 100644 gl/m4/setlocale_null.m4 create mode 100644 gl/m4/stat-time.m4 create mode 100644 gl/m4/stat.m4 create mode 100644 gl/m4/std-gnu11.m4 delete mode 100644 gl/m4/strndup.m4 delete mode 100644 gl/m4/strnlen.m4 create mode 100644 gl/m4/sys_stat_h.m4 delete mode 100644 gl/m4/uintmax_t.m4 create mode 100644 gl/m4/ungetc.m4 create mode 100644 gl/m4/unlocked-io.m4 create mode 100644 gl/m4/vararrays.m4 delete mode 100644 gl/m4/xstrndup.m4 create mode 100644 gl/m4/year2038.m4 create mode 100644 gl/m4/zzgnulib.m4 create mode 100644 gl/malloc/dynarray-skeleton.c create mode 100644 gl/malloc/dynarray.h create mode 100644 gl/malloc/dynarray_at_failure.c create mode 100644 gl/malloc/dynarray_emplace_enlarge.c create mode 100644 gl/malloc/dynarray_finalize.c create mode 100644 gl/malloc/dynarray_resize.c create mode 100644 gl/malloc/dynarray_resize_clear.c delete mode 100644 gl/malloca.valgrind create mode 100644 gl/mbrtowc-impl-utf8.h create mode 100644 gl/mbrtowc-impl.h create mode 100644 gl/mbtowc-lock.c create mode 100644 gl/mbtowc-lock.h create mode 100644 gl/minmax.h create mode 100644 gl/nl_langinfo-lock.c create mode 100644 gl/open.c create mode 100644 gl/pathmax.h delete mode 100644 gl/read.c create mode 100644 gl/realloc.c create mode 100644 gl/reallocarray.c delete mode 100644 gl/ref-add.sin delete mode 100644 gl/ref-del.sin delete mode 100644 gl/safe-read.c delete mode 100644 gl/safe-read.h create mode 100644 gl/setlocale-lock.c create mode 100644 gl/setlocale_null.c create mode 100644 gl/setlocale_null.h create mode 100644 gl/sha1-stream.c create mode 100644 gl/stat-time.c create mode 100644 gl/stat-time.h create mode 100644 gl/stat-w32.c create mode 100644 gl/stat-w32.h create mode 100644 gl/stat.c create mode 100644 gl/stdckdint.in.h create mode 100644 gl/stdio-impl.h create mode 100644 gl/stdio-read.c create mode 100644 gl/stdio-write.c delete mode 100644 gl/strndup.c delete mode 100644 gl/strnlen.c create mode 100644 gl/sys-limits.h create mode 100644 gl/sys_stat.in.h create mode 100644 gl/unlocked-io.h create mode 100644 gl/windows-initguard.h create mode 100644 gl/windows-mutex.c create mode 100644 gl/windows-mutex.h create mode 100644 gl/windows-once.c create mode 100644 gl/windows-once.h create mode 100644 gl/windows-recmutex.c create mode 100644 gl/windows-recmutex.h create mode 100644 gl/windows-rwlock.c create mode 100644 gl/windows-rwlock.h delete mode 100644 gl/xstrndup.c delete mode 100644 gl/xstrndup.h diff --git a/build-aux/config.rpath b/build-aux/config.rpath index c38b914d..1e1ab679 100755 --- a/build-aux/config.rpath +++ b/build-aux/config.rpath @@ -2,7 +2,7 @@ # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # -# Copyright 1996-2013 Free Software Foundation, Inc. +# Copyright 1996-2022 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # @@ -367,15 +367,11 @@ else dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) + freebsd2.[01]*) hardcode_direct=yes hardcode_minus_L=yes ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; @@ -548,13 +544,11 @@ case "$host_os" in dgux*) library_names_spec='$libname$shrext' ;; - freebsd* | dragonfly*) - case "$host_os" in - freebsd[123]*) - library_names_spec='$libname$shrext$versuffix' ;; - *) - library_names_spec='$libname$shrext' ;; - esac + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' + ;; + freebsd* | dragonfly* | midnightbsd*) + library_names_spec='$libname$shrext' ;; gnu*) library_names_spec='$libname$shrext' diff --git a/build-aux/snippet/_Noreturn.h b/build-aux/snippet/_Noreturn.h deleted file mode 100644 index c44ad89b..00000000 --- a/build-aux/snippet/_Noreturn.h +++ /dev/null @@ -1,10 +0,0 @@ -#if !defined _Noreturn && __STDC_VERSION__ < 201112 -# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ - || 0x5110 <= __SUNPRO_C) -# define _Noreturn __attribute__ ((__noreturn__)) -# elif 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn -# endif -#endif diff --git a/build-aux/snippet/arg-nonnull.h b/build-aux/snippet/arg-nonnull.h deleted file mode 100644 index 8ea2a474..00000000 --- a/build-aux/snippet/arg-nonnull.h +++ /dev/null @@ -1,26 +0,0 @@ -/* A C macro for declaring that specific arguments must not be NULL. - Copyright (C) 2009-2013 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 . */ - -/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools - that the values passed as arguments n, ..., m must be non-NULL pointers. - n = 1 stands for the first argument, n = 2 for the second argument etc. */ -#ifndef _GL_ARG_NONNULL -# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 -# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) -# else -# define _GL_ARG_NONNULL(params) -# endif -#endif diff --git a/build-aux/snippet/c++defs.h b/build-aux/snippet/c++defs.h deleted file mode 100644 index b35b933c..00000000 --- a/build-aux/snippet/c++defs.h +++ /dev/null @@ -1,271 +0,0 @@ -/* C++ compatible function declaration macros. - Copyright (C) 2010-2013 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 . */ - -#ifndef _GL_CXXDEFS_H -#define _GL_CXXDEFS_H - -/* The three most frequent use cases of these macros are: - - * For providing a substitute for a function that is missing on some - platforms, but is declared and works fine on the platforms on which - it exists: - - #if @GNULIB_FOO@ - # if !@HAVE_FOO@ - _GL_FUNCDECL_SYS (foo, ...); - # endif - _GL_CXXALIAS_SYS (foo, ...); - _GL_CXXALIASWARN (foo); - #elif defined GNULIB_POSIXCHECK - ... - #endif - - * For providing a replacement for a function that exists on all platforms, - but is broken/insufficient and needs to be replaced on some platforms: - - #if @GNULIB_FOO@ - # if @REPLACE_FOO@ - # if !(defined __cplusplus && defined GNULIB_NAMESPACE) - # undef foo - # define foo rpl_foo - # endif - _GL_FUNCDECL_RPL (foo, ...); - _GL_CXXALIAS_RPL (foo, ...); - # else - _GL_CXXALIAS_SYS (foo, ...); - # endif - _GL_CXXALIASWARN (foo); - #elif defined GNULIB_POSIXCHECK - ... - #endif - - * For providing a replacement for a function that exists on some platforms - but is broken/insufficient and needs to be replaced on some of them and - is additionally either missing or undeclared on some other platforms: - - #if @GNULIB_FOO@ - # if @REPLACE_FOO@ - # if !(defined __cplusplus && defined GNULIB_NAMESPACE) - # undef foo - # define foo rpl_foo - # endif - _GL_FUNCDECL_RPL (foo, ...); - _GL_CXXALIAS_RPL (foo, ...); - # else - # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ - _GL_FUNCDECL_SYS (foo, ...); - # endif - _GL_CXXALIAS_SYS (foo, ...); - # endif - _GL_CXXALIASWARN (foo); - #elif defined GNULIB_POSIXCHECK - ... - #endif -*/ - -/* _GL_EXTERN_C declaration; - performs the declaration with C linkage. */ -#if defined __cplusplus -# define _GL_EXTERN_C extern "C" -#else -# define _GL_EXTERN_C extern -#endif - -/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); - declares a replacement function, named rpl_func, with the given prototype, - consisting of return type, parameters, and attributes. - Example: - _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) - _GL_ARG_NONNULL ((1))); - */ -#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ - _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) -#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ - _GL_EXTERN_C rettype rpl_func parameters_and_attributes - -/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); - declares the system function, named func, with the given prototype, - consisting of return type, parameters, and attributes. - Example: - _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) - _GL_ARG_NONNULL ((1))); - */ -#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ - _GL_EXTERN_C rettype func parameters_and_attributes - -/* _GL_CXXALIAS_RPL (func, rettype, parameters); - declares a C++ alias called GNULIB_NAMESPACE::func - that redirects to rpl_func, if GNULIB_NAMESPACE is defined. - Example: - _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); - */ -#define _GL_CXXALIAS_RPL(func,rettype,parameters) \ - _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - rettype (*const func) parameters = ::rpl_func; \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); - is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); - except that the C function rpl_func may have a slightly different - declaration. A cast is used to silence the "invalid conversion" error - that would otherwise occur. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - rettype (*const func) parameters = \ - reinterpret_cast(::rpl_func); \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_SYS (func, rettype, parameters); - declares a C++ alias called GNULIB_NAMESPACE::func - that redirects to the system provided function func, if GNULIB_NAMESPACE - is defined. - Example: - _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); - */ -#if defined __cplusplus && defined GNULIB_NAMESPACE - /* If we were to write - rettype (*const func) parameters = ::func; - like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls - better (remove an indirection through a 'static' pointer variable), - but then the _GL_CXXALIASWARN macro below would cause a warning not only - for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */ -# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - static rettype (*func) parameters = ::func; \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); - is like _GL_CXXALIAS_SYS (func, rettype, parameters); - except that the C function func may have a slightly different declaration. - A cast is used to silence the "invalid conversion" error that would - otherwise occur. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - static rettype (*func) parameters = \ - reinterpret_cast(::func); \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); - is like _GL_CXXALIAS_SYS (func, rettype, parameters); - except that the C function is picked among a set of overloaded functions, - namely the one with rettype2 and parameters2. Two consecutive casts - are used to silence the "cannot find a match" and "invalid conversion" - errors that would otherwise occur. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE - /* The outer cast must be a reinterpret_cast. - The inner cast: When the function is defined as a set of overloaded - functions, it works as a static_cast<>, choosing the designated variant. - When the function is defined as a single variant, it works as a - reinterpret_cast<>. The parenthesized cast syntax works both ways. */ -# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ - namespace GNULIB_NAMESPACE \ - { \ - static rettype (*func) parameters = \ - reinterpret_cast( \ - (rettype2(*)parameters2)(::func)); \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIASWARN (func); - causes a warning to be emitted when ::func is used but not when - GNULIB_NAMESPACE::func is used. func must be defined without overloaded - variants. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIASWARN(func) \ - _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) -# define _GL_CXXALIASWARN_1(func,namespace) \ - _GL_CXXALIASWARN_2 (func, namespace) -/* To work around GCC bug , - we enable the warning only when not optimizing. */ -# if !__OPTIMIZE__ -# define _GL_CXXALIASWARN_2(func,namespace) \ - _GL_WARN_ON_USE (func, \ - "The symbol ::" #func " refers to the system function. " \ - "Use " #namespace "::" #func " instead.") -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -# define _GL_CXXALIASWARN_2(func,namespace) \ - extern __typeof__ (func) func -# else -# define _GL_CXXALIASWARN_2(func,namespace) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -# endif -#else -# define _GL_CXXALIASWARN(func) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); - causes a warning to be emitted when the given overloaded variant of ::func - is used but not when GNULIB_NAMESPACE::func is used. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ - _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ - GNULIB_NAMESPACE) -# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ - _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) -/* To work around GCC bug , - we enable the warning only when not optimizing. */ -# if !__OPTIMIZE__ -# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ - "The symbol ::" #func " refers to the system function. " \ - "Use " #namespace "::" #func " instead.") -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - extern __typeof__ (func) func -# else -# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -# endif -#else -# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -#endif /* _GL_CXXDEFS_H */ diff --git a/build-aux/snippet/warn-on-use.h b/build-aux/snippet/warn-on-use.h deleted file mode 100644 index 1736a1bd..00000000 --- a/build-aux/snippet/warn-on-use.h +++ /dev/null @@ -1,109 +0,0 @@ -/* A C macro for emitting warnings if a function is used. - Copyright (C) 2010-2013 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 . */ - -/* _GL_WARN_ON_USE (function, "literal string") issues a declaration - for FUNCTION which will then trigger a compiler warning containing - the text of "literal string" anywhere that function is called, if - supported by the compiler. If the compiler does not support this - feature, the macro expands to an unused extern declaration. - - This macro is useful for marking a function as a potential - portability trap, with the intent that "literal string" include - instructions on the replacement function that should be used - instead. However, one of the reasons that a function is a - portability trap is if it has the wrong signature. Declaring - FUNCTION with a different signature in C is a compilation error, so - this macro must use the same type as any existing declaration so - that programs that avoid the problematic FUNCTION do not fail to - compile merely because they included a header that poisoned the - function. But this implies that _GL_WARN_ON_USE is only safe to - use if FUNCTION is known to already have a declaration. Use of - this macro implies that there must not be any other macro hiding - the declaration of FUNCTION; but undefining FUNCTION first is part - of the poisoning process anyway (although for symbols that are - provided only via a macro, the result is a compilation error rather - than a warning containing "literal string"). Also note that in - C++, it is only safe to use if FUNCTION has no overloads. - - For an example, it is possible to poison 'getline' by: - - adding a call to gl_WARN_ON_USE_PREPARE([[#include ]], - [getline]) in configure.ac, which potentially defines - HAVE_RAW_DECL_GETLINE - - adding this code to a header that wraps the system : - #undef getline - #if HAVE_RAW_DECL_GETLINE - _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" - "not universally present; use the gnulib module getline"); - #endif - - It is not possible to directly poison global variables. But it is - possible to write a wrapper accessor function, and poison that - (less common usage, like &environ, will cause a compilation error - rather than issue the nice warning, but the end result of informing - the developer about their portability problem is still achieved): - #if HAVE_RAW_DECL_ENVIRON - static char ***rpl_environ (void) { return &environ; } - _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); - # undef environ - # define environ (*rpl_environ ()) - #endif - */ -#ifndef _GL_WARN_ON_USE - -# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) -/* A compiler attribute is available in gcc versions 4.3.0 and later. */ -# define _GL_WARN_ON_USE(function, message) \ -extern __typeof__ (function) function __attribute__ ((__warning__ (message))) -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -/* Verify the existence of the function. */ -# define _GL_WARN_ON_USE(function, message) \ -extern __typeof__ (function) function -# else /* Unsupported. */ -# define _GL_WARN_ON_USE(function, message) \ -_GL_WARN_EXTERN_C int _gl_warn_on_use -# endif -#endif - -/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") - is like _GL_WARN_ON_USE (function, "string"), except that the function is - declared with the given prototype, consisting of return type, parameters, - and attributes. - This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does - not work in this case. */ -#ifndef _GL_WARN_ON_USE_CXX -# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes \ - __attribute__ ((__warning__ (msg))) -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -/* Verify the existence of the function. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes -# else /* Unsupported. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -_GL_WARN_EXTERN_C int _gl_warn_on_use -# endif -#endif - -/* _GL_WARN_EXTERN_C declaration; - performs the declaration with C linkage. */ -#ifndef _GL_WARN_EXTERN_C -# if defined __cplusplus -# define _GL_WARN_EXTERN_C extern "C" -# else -# define _GL_WARN_EXTERN_C extern -# endif -#endif diff --git a/gl/Makefile.am b/gl/Makefile.am index 15135c8b..deb665cf 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am @@ -1,10 +1,10 @@ ## DO NOT EDIT! GENERATED AUTOMATICALLY! ## Process this file with automake to produce Makefile.in. -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2022 Free Software Foundation, Inc. # # 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 -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This file is distributed in the hope that it will be useful, @@ -13,7 +13,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this file. If not, see . +# along with this file. If not, see . # # As a special exception to the GNU General Public License, # this file may be distributed as part of a program that @@ -21,9 +21,42 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext idpriv-droptemp mountlist regex setenv strcase strcasestr strsep timegm unsetenv vasprintf vsnprintf - -AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects +# Reproduce by: +# gnulib-tool --import \ +# --lib=libgnu \ +# --source-base=gl \ +# --m4-base=gl/m4 \ +# --doc-base=doc \ +# --tests-base=tests \ +# --aux-dir=build-aux \ +# --no-conditional-dependencies \ +# --no-libtool \ +# --macro-prefix=gl \ +# --no-vc-files \ +# base64 \ +# crypto/sha1 \ +# dirname \ +# environ \ +# floorf \ +# fsusage \ +# getaddrinfo \ +# gethostname \ +# getloadavg \ +# getopt-gnu \ +# gettext \ +# idpriv-droptemp \ +# mountlist \ +# regex \ +# setenv \ +# strcase \ +# strcasestr \ +# strsep \ +# timegm \ +# unsetenv \ +# vasprintf \ +# vsnprintf + +AUTOMAKE_OPTIONS = 1.14 gnits subdir-objects SUBDIRS = noinst_HEADERS = @@ -37,6 +70,7 @@ MOSTLYCLEANDIRS = CLEANFILES = DISTCLEANFILES = MAINTAINERCLEANFILES = +# No GNU Make output. EXTRA_DIST += m4/gnulib-cache.m4 AM_CPPFLAGS = @@ -45,10 +79,20 @@ AM_CFLAGS = noinst_LIBRARIES += libgnu.a libgnu_a_SOURCES = +libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS) libgnu_a_LIBADD = $(gl_LIBOBJS) libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) EXTRA_libgnu_a_SOURCES = +## begin gnulib module absolute-header + +# Use this preprocessor expression to decide whether #include_next works. +# Do not rely on a 'configure'-time test for this, since the expression +# might appear in an installed header, which is used by some other compiler. +HAVE_INCLUDE_NEXT = (__GNUC__ || __clang__ || 60000000 <= __DECC_VER) + +## end gnulib module absolute-header + ## begin gnulib module alloca-opt BUILT_SOURCES += $(ALLOCA_H) @@ -57,11 +101,10 @@ BUILT_SOURCES += $(ALLOCA_H) # doesn't have one that works with the given compiler. if GL_GENERATE_ALLOCA_H alloca.h: alloca.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/alloca.in.h; \ - } > $@-t && \ - mv -f $@-t $@ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' \ + $(srcdir)/alloca.in.h > $@-t + $(AM_V_at)mv $@-t $@ else alloca.h: $(top_builddir)/config.status rm -f $@ @@ -79,18 +122,18 @@ BUILT_SOURCES += arpa/inet.h # We need the following in order to create when the system # doesn't have one. arpa/inet.h: arpa_inet.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) - $(AM_V_at)$(MKDIR_P) arpa - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(AM_V_GEN)$(MKDIR_P) '%reldir%/arpa' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ -e 's|@''NEXT_ARPA_INET_H''@|$(NEXT_ARPA_INET_H)|g' \ -e 's|@''HAVE_ARPA_INET_H''@|$(HAVE_ARPA_INET_H)|g' \ - -e 's/@''GNULIB_INET_NTOP''@/$(GNULIB_INET_NTOP)/g' \ - -e 's/@''GNULIB_INET_PTON''@/$(GNULIB_INET_PTON)/g' \ + -e 's/@''GNULIB_INET_NTOP''@/$(GL_GNULIB_INET_NTOP)/g' \ + -e 's/@''GNULIB_INET_PTON''@/$(GL_GNULIB_INET_PTON)/g' \ + -e 's|@''HAVE_WS2TCPIP_H''@|$(HAVE_WS2TCPIP_H)|g' \ -e 's|@''HAVE_DECL_INET_NTOP''@|$(HAVE_DECL_INET_NTOP)|g' \ -e 's|@''HAVE_DECL_INET_PTON''@|$(HAVE_DECL_INET_PTON)|g' \ -e 's|@''REPLACE_INET_NTOP''@|$(REPLACE_INET_NTOP)|g' \ @@ -98,9 +141,8 @@ arpa/inet.h: arpa_inet.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/arpa_inet.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/arpa_inet.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += arpa/inet.h arpa/inet.h-t MOSTLYCLEANDIRS += arpa @@ -108,72 +150,110 @@ EXTRA_DIST += arpa_inet.in.h ## end gnulib module arpa_inet +## begin gnulib module attribute + + +EXTRA_DIST += attribute.h + +## end gnulib module attribute + ## begin gnulib module base64 libgnu_a_SOURCES += base64.h base64.c ## end gnulib module base64 -## begin gnulib module btowc +## begin gnulib module basename-lgpl +libgnu_a_SOURCES += basename-lgpl.c -EXTRA_DIST += btowc.c +EXTRA_DIST += basename-lgpl.h -EXTRA_libgnu_a_SOURCES += btowc.c +## end gnulib module basename-lgpl + +## begin gnulib module btowc + +if GL_COND_OBJ_BTOWC +libgnu_a_SOURCES += btowc.c +endif ## end gnulib module btowc -## begin gnulib module configmake - -# Listed in the same order as the GNU makefile conventions, and -# provided by autoconf 2.59c+. -# The Automake-defined pkg* macros are appended, in the order -# listed in the Automake 1.10a+ documentation. -configmake.h: Makefile - $(AM_V_GEN)rm -f $@-t && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - echo '#define PREFIX "$(prefix)"'; \ - echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ - echo '#define BINDIR "$(bindir)"'; \ - echo '#define SBINDIR "$(sbindir)"'; \ - echo '#define LIBEXECDIR "$(libexecdir)"'; \ - echo '#define DATAROOTDIR "$(datarootdir)"'; \ - echo '#define DATADIR "$(datadir)"'; \ - echo '#define SYSCONFDIR "$(sysconfdir)"'; \ - echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ - echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ - echo '#define INCLUDEDIR "$(includedir)"'; \ - echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ - echo '#define DOCDIR "$(docdir)"'; \ - echo '#define INFODIR "$(infodir)"'; \ - echo '#define HTMLDIR "$(htmldir)"'; \ - echo '#define DVIDIR "$(dvidir)"'; \ - echo '#define PDFDIR "$(pdfdir)"'; \ - echo '#define PSDIR "$(psdir)"'; \ - echo '#define LIBDIR "$(libdir)"'; \ - echo '#define LISPDIR "$(lispdir)"'; \ - echo '#define LOCALEDIR "$(localedir)"'; \ - echo '#define MANDIR "$(mandir)"'; \ - echo '#define MANEXT "$(manext)"'; \ - echo '#define PKGDATADIR "$(pkgdatadir)"'; \ - echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ - echo '#define PKGLIBDIR "$(pkglibdir)"'; \ - echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ - } | sed '/""/d' > $@-t && \ - mv -f $@-t $@ - -BUILT_SOURCES += configmake.h -CLEANFILES += configmake.h configmake.h-t - -## end gnulib module configmake +## begin gnulib module byteswap + +BUILT_SOURCES += $(BYTESWAP_H) + +# We need the following in order to create when the system +# doesn't have one. +if GL_GENERATE_BYTESWAP_H +byteswap.h: byteswap.in.h $(top_builddir)/config.status + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/byteswap.in.h + $(AM_V_at)mv $@-t $@ +else +byteswap.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += byteswap.h byteswap.h-t + +EXTRA_DIST += byteswap.in.h + +## end gnulib module byteswap + +## begin gnulib module calloc-gnu + + +EXTRA_DIST += calloc.c + +EXTRA_libgnu_a_SOURCES += calloc.c + +## end gnulib module calloc-gnu + +## begin gnulib module calloc-posix + + +EXTRA_DIST += calloc.c + +EXTRA_libgnu_a_SOURCES += calloc.c + +## end gnulib module calloc-posix + +## begin gnulib module cloexec + +libgnu_a_SOURCES += cloexec.c + +EXTRA_DIST += cloexec.h + +## end gnulib module cloexec + +## begin gnulib module close + +if GL_COND_OBJ_CLOSE +libgnu_a_SOURCES += close.c +endif + +## end gnulib module close + +## begin gnulib module crypto/af_alg + +libgnu_a_SOURCES += af_alg.c + +EXTRA_DIST += af_alg.h sys-limits.h + +## end gnulib module crypto/af_alg ## begin gnulib module crypto/sha1 +libgnu_a_SOURCES += sha1-stream.c + +## end gnulib module crypto/sha1 + +## begin gnulib module crypto/sha1-buffer + libgnu_a_SOURCES += sha1.c -EXTRA_DIST += sha1.h +EXTRA_DIST += gl_openssl.h sha1.h -## end gnulib module crypto/sha1 +## end gnulib module crypto/sha1-buffer ## begin gnulib module dirname @@ -187,18 +267,52 @@ EXTRA_libgnu_a_SOURCES += stripslash.c ## begin gnulib module dirname-lgpl -libgnu_a_SOURCES += dirname-lgpl.c basename-lgpl.c stripslash.c +libgnu_a_SOURCES += dirname-lgpl.c stripslash.c EXTRA_DIST += dirname.h ## end gnulib module dirname-lgpl -## begin gnulib module dosname +## begin gnulib module dup2 +if GL_COND_OBJ_DUP2 +libgnu_a_SOURCES += dup2.c +endif + +## end gnulib module dup2 + +## begin gnulib module dynarray + +BUILT_SOURCES += malloc/dynarray.gl.h malloc/dynarray-skeleton.gl.h + +malloc/dynarray.gl.h: malloc/dynarray.h + $(AM_V_GEN)$(MKDIR_P) '%reldir%/malloc' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e '/libc_hidden_proto/d' \ + $(srcdir)/malloc/dynarray.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += malloc/dynarray.gl.h malloc/dynarray.gl.h-t + +malloc/dynarray-skeleton.gl.h: malloc/dynarray-skeleton.c + $(AM_V_GEN)$(MKDIR_P) '%reldir%/malloc' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|||g' \ + -e 's|__attribute_maybe_unused__|_GL_ATTRIBUTE_MAYBE_UNUSED|g' \ + -e 's|__attribute_nonnull__|_GL_ATTRIBUTE_NONNULL|g' \ + -e 's|__attribute_warn_unused_result__|_GL_ATTRIBUTE_NODISCARD|g' \ + -e 's|__glibc_likely|_GL_LIKELY|g' \ + -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \ + $(srcdir)/malloc/dynarray-skeleton.c > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += malloc/dynarray-skeleton.gl.h malloc/dynarray-skeleton.gl.h-t -EXTRA_DIST += dosname.h +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 -## end gnulib module dosname +EXTRA_DIST += dynarray.h malloc/dynarray-skeleton.c malloc/dynarray.h + +EXTRA_libgnu_a_SOURCES += malloc/dynarray-skeleton.c + +## end gnulib module dynarray ## begin gnulib module errno @@ -208,9 +322,8 @@ BUILT_SOURCES += $(ERRNO_H) # doesn't have one that is POSIX compliant. if GL_GENERATE_ERRNO_H errno.h: errno.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ @@ -221,9 +334,8 @@ errno.h: errno.in.h $(top_builddir)/config.status -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \ -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \ -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \ - < $(srcdir)/errno.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/errno.in.h > $@-t + $(AM_V_at)mv $@-t $@ else errno.h: $(top_builddir)/config.status rm -f $@ @@ -236,10 +348,11 @@ EXTRA_DIST += errno.in.h ## begin gnulib module error +if GL_COND_OBJ_ERROR +libgnu_a_SOURCES += error.c +endif -EXTRA_DIST += error.c error.h - -EXTRA_libgnu_a_SOURCES += error.c +EXTRA_DIST += error.h ## end gnulib module error @@ -251,6 +364,51 @@ EXTRA_DIST += exitfail.h ## end gnulib module exitfail +## begin gnulib module fcntl + +if GL_COND_OBJ_FCNTL +libgnu_a_SOURCES += fcntl.c +endif + +## end gnulib module fcntl + +## begin gnulib module fcntl-h + +BUILT_SOURCES += fcntl.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \ + -e 's/@''GNULIB_CREAT''@/$(GL_GNULIB_CREAT)/g' \ + -e 's/@''GNULIB_FCNTL''@/$(GL_GNULIB_FCNTL)/g' \ + -e 's/@''GNULIB_NONBLOCKING''@/$(GL_GNULIB_NONBLOCKING)/g' \ + -e 's/@''GNULIB_OPEN''@/$(GL_GNULIB_OPEN)/g' \ + -e 's/@''GNULIB_OPENAT''@/$(GL_GNULIB_OPENAT)/g' \ + -e 's/@''GNULIB_MDA_CREAT''@/$(GL_GNULIB_MDA_CREAT)/g' \ + -e 's/@''GNULIB_MDA_OPEN''@/$(GL_GNULIB_MDA_OPEN)/g' \ + -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ + -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \ + -e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \ + -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \ + -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \ + -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/fcntl.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += fcntl.h fcntl.h-t + +EXTRA_DIST += fcntl.in.h + +## end gnulib module fcntl-h + ## begin gnulib module fd-hook libgnu_a_SOURCES += fd-hook.c @@ -259,6 +417,23 @@ EXTRA_DIST += fd-hook.h ## end gnulib module fd-hook +## begin gnulib module fflush + +if GL_COND_OBJ_FFLUSH +libgnu_a_SOURCES += fflush.c +endif + +EXTRA_DIST += stdio-impl.h + +## end gnulib module fflush + +## begin gnulib module filename + + +EXTRA_DIST += filename.h + +## end gnulib module filename + ## begin gnulib module float BUILT_SOURCES += $(FLOAT_H) @@ -267,111 +442,268 @@ BUILT_SOURCES += $(FLOAT_H) # doesn't have one that works with the given compiler. if GL_GENERATE_FLOAT_H float.h: float.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \ - < $(srcdir)/float.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/float.in.h > $@-t + $(AM_V_at)mv $@-t $@ else float.h: $(top_builddir)/config.status rm -f $@ endif MOSTLYCLEANFILES += float.h float.h-t -EXTRA_DIST += float.c float.in.h itold.c +if GL_COND_OBJ_FLOAT +libgnu_a_SOURCES += float.c +endif +if GL_COND_OBJ_ITOLD +libgnu_a_SOURCES += itold.c +endif -EXTRA_libgnu_a_SOURCES += float.c itold.c +EXTRA_DIST += float.in.h ## end gnulib module float ## begin gnulib module floorf +if GL_COND_OBJ_FLOORF +libgnu_a_SOURCES += floorf.c +endif -EXTRA_DIST += floor.c floorf.c +EXTRA_DIST += floor.c -EXTRA_libgnu_a_SOURCES += floor.c floorf.c +EXTRA_libgnu_a_SOURCES += floor.c ## end gnulib module floorf -## begin gnulib module fsusage +## begin gnulib module fopen + + +EXTRA_DIST += fopen.c + +EXTRA_libgnu_a_SOURCES += fopen.c +## end gnulib module fopen -EXTRA_DIST += fsusage.c fsusage.h +## begin gnulib module fopen-gnu -EXTRA_libgnu_a_SOURCES += fsusage.c + +EXTRA_DIST += fopen.c + +EXTRA_libgnu_a_SOURCES += fopen.c + +## end gnulib module fopen-gnu + +## begin gnulib module fpurge + +if GL_COND_OBJ_FPURGE +libgnu_a_SOURCES += fpurge.c +endif + +EXTRA_DIST += stdio-impl.h + +## end gnulib module fpurge + +## begin gnulib module freading + +libgnu_a_SOURCES += freading.c + +EXTRA_DIST += freading.h stdio-impl.h + +## end gnulib module freading + +## begin gnulib module free-posix + +if GL_COND_OBJ_FREE +libgnu_a_SOURCES += free.c +endif + +## end gnulib module free-posix + +## begin gnulib module fseek + +if GL_COND_OBJ_FSEEK +libgnu_a_SOURCES += fseek.c +endif + +## end gnulib module fseek + +## begin gnulib module fseeko + +if GL_COND_OBJ_FSEEKO +libgnu_a_SOURCES += fseeko.c +endif + +EXTRA_DIST += stdio-impl.h + +## end gnulib module fseeko + +## begin gnulib module fstat + +if GL_COND_OBJ_FSTAT +libgnu_a_SOURCES += fstat.c +endif + +EXTRA_DIST += stat-w32.c stat-w32.h + +EXTRA_libgnu_a_SOURCES += stat-w32.c + +## end gnulib module fstat + +## begin gnulib module fsusage + +if GL_COND_OBJ_FSUSAGE +libgnu_a_SOURCES += fsusage.c +endif + +EXTRA_DIST += fsusage.h ## end gnulib module fsusage -## begin gnulib module full-read +## begin gnulib module ftell -libgnu_a_SOURCES += full-read.h full-read.c +if GL_COND_OBJ_FTELL +libgnu_a_SOURCES += ftell.c +endif -EXTRA_DIST += full-write.c +## end gnulib module ftell -EXTRA_libgnu_a_SOURCES += full-write.c +## begin gnulib module ftello -## end gnulib module full-read +if GL_COND_OBJ_FTELLO +libgnu_a_SOURCES += ftello.c +endif -## begin gnulib module getaddrinfo +EXTRA_DIST += stdio-impl.h + +## end gnulib module ftello + +## begin gnulib module gen-header + +# In 'sed', replace the pattern space with a "DO NOT EDIT" comment. +SED_HEADER_NOEDIT = s,.*,/* DO NOT EDIT! GENERATED AUTOMATICALLY! */, +# '$(SED_HEADER_STDOUT) -e "..."' runs 'sed' but first outputs "DO NOT EDIT". +SED_HEADER_STDOUT = sed -e 1h -e '1$(SED_HEADER_NOEDIT)' -e 1G -EXTRA_DIST += gai_strerror.c getaddrinfo.c +# '$(SED_HEADER_TO_AT_t) FILE' copies FILE to $@-t, prepending a leading +# "DO_NOT_EDIT". Although this could be done more simply via: +# SED_HEADER_TO_AT_t = $(SED_HEADER_STDOUT) > $@-t +# the -n and 'w' avoid a fork+exec, at least when GNU Make is used. +SED_HEADER_TO_AT_t = $(SED_HEADER_STDOUT) -n -e 'w $@-t' -EXTRA_libgnu_a_SOURCES += gai_strerror.c getaddrinfo.c +# Use $(gl_V_at) instead of $(AM_V_GEN) or $(AM_V_at) on a line that +gl_V_at = $(AM_V_GEN) + +## end gnulib module gen-header + +## begin gnulib module getaddrinfo + +if GL_COND_OBJ_GETADDRINFO +libgnu_a_SOURCES += getaddrinfo.c +endif +if GL_COND_OBJ_GAI_STRERROR +libgnu_a_SOURCES += gai_strerror.c +endif ## end gnulib module getaddrinfo -## begin gnulib module gethostname +## begin gnulib module getdelim + +if GL_COND_OBJ_GETDELIM +libgnu_a_SOURCES += getdelim.c +endif + +## end gnulib module getdelim + +## begin gnulib module getdtablesize + +if GL_COND_OBJ_GETDTABLESIZE +libgnu_a_SOURCES += getdtablesize.c +endif + +## end gnulib module getdtablesize +## begin gnulib module gethostname -EXTRA_DIST += gethostname.c w32sock.h +if GL_COND_OBJ_GETHOSTNAME +libgnu_a_SOURCES += gethostname.c +endif -EXTRA_libgnu_a_SOURCES += gethostname.c +EXTRA_DIST += w32sock.h ## end gnulib module gethostname -## begin gnulib module getloadavg +## begin gnulib module getline +if GL_COND_OBJ_GETLINE +libgnu_a_SOURCES += getline.c +endif + +## end gnulib module getline -EXTRA_DIST += getloadavg.c +## begin gnulib module getloadavg -EXTRA_libgnu_a_SOURCES += getloadavg.c +if GL_COND_OBJ_GETLOADAVG +libgnu_a_SOURCES += getloadavg.c +endif ## end gnulib module getloadavg ## begin gnulib module getopt-posix -BUILT_SOURCES += $(GETOPT_H) +BUILT_SOURCES += $(GETOPT_H) $(GETOPT_CDEFS_H) # We need the following in order to create when the system # doesn't have one that works with the given compiler. +if GL_GENERATE_GETOPT_H getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - < $(srcdir)/getopt.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -MOSTLYCLEANFILES += getopt.h getopt.h-t + $(srcdir)/getopt.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +getopt.h: $(top_builddir)/config.status + rm -f $@ +endif + +if GL_GENERATE_GETOPT_CDEFS_H +getopt-cdefs.h: getopt-cdefs.in.h $(top_builddir)/config.status + $(AM_V_GEN)$(SED_HEADER_STDOUT) \ + -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \ + $(srcdir)/getopt-cdefs.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +getopt-cdefs.h: $(top_builddir)/config.status + rm -f $@ +endif + +MOSTLYCLEANFILES += getopt.h getopt.h-t getopt-cdefs.h getopt-cdefs.h-t -EXTRA_DIST += getopt.c getopt.in.h getopt1.c getopt_int.h +if GL_COND_OBJ_GETOPT +libgnu_a_SOURCES += getopt.c getopt1.c +endif -EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c +EXTRA_DIST += getopt-cdefs.in.h getopt-core.h getopt-ext.h getopt-pfx-core.h getopt-pfx-ext.h getopt.in.h getopt_int.h ## end gnulib module getopt-posix +## begin gnulib module getprogname + +libgnu_a_SOURCES += getprogname.h getprogname.c + +## end gnulib module getprogname + ## begin gnulib module gettext # If your project uses "gettextize --intl" to put a source-code @@ -395,6 +727,14 @@ libgnu_a_SOURCES += gettext.h ## end gnulib module gettext-h +## begin gnulib module hard-locale + +libgnu_a_SOURCES += hard-locale.c + +EXTRA_DIST += hard-locale.h + +## end gnulib module hard-locale + ## begin gnulib module havelib @@ -402,6 +742,14 @@ EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath ## end gnulib module havelib +## begin gnulib module ialloc + +libgnu_a_SOURCES += ialloc.c + +EXTRA_DIST += ialloc.h + +## end gnulib module ialloc + ## begin gnulib module idpriv-droptemp libgnu_a_SOURCES += idpriv-droptemp.c @@ -410,22 +758,68 @@ EXTRA_DIST += idpriv.h ## end gnulib module idpriv-droptemp -## begin gnulib module inet_ntop +## begin gnulib module idx + +libgnu_a_SOURCES += idx.h +## end gnulib module idx -EXTRA_DIST += inet_ntop.c +## begin gnulib module inet_ntop -EXTRA_libgnu_a_SOURCES += inet_ntop.c +if GL_COND_OBJ_INET_NTOP +libgnu_a_SOURCES += inet_ntop.c +endif ## end gnulib module inet_ntop ## begin gnulib module intprops -EXTRA_DIST += intprops.h +EXTRA_DIST += intprops-internal.h intprops.h ## end gnulib module intprops +## begin gnulib module inttypes-incomplete + +BUILT_SOURCES += inttypes.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +inttypes.h: inttypes.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_INTTYPES_H''@|$(NEXT_INTTYPES_H)|g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \ + -e 's/@''GNULIB_IMAXABS''@/$(GL_GNULIB_IMAXABS)/g' \ + -e 's/@''GNULIB_IMAXDIV''@/$(GL_GNULIB_IMAXDIV)/g' \ + -e 's/@''GNULIB_STRTOIMAX''@/$(GL_GNULIB_STRTOIMAX)/g' \ + -e 's/@''GNULIB_STRTOUMAX''@/$(GL_GNULIB_STRTOUMAX)/g' \ + -e 's/@''HAVE_DECL_IMAXABS''@/$(HAVE_DECL_IMAXABS)/g' \ + -e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \ + -e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \ + -e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \ + -e 's/@''HAVE_IMAXDIV_T''@/$(HAVE_IMAXDIV_T)/g' \ + -e 's/@''REPLACE_STRTOIMAX''@/$(REPLACE_STRTOIMAX)/g' \ + -e 's/@''REPLACE_STRTOUMAX''@/$(REPLACE_STRTOUMAX)/g' \ + -e 's/@''INT32_MAX_LT_INTMAX_MAX''@/$(INT32_MAX_LT_INTMAX_MAX)/g' \ + -e 's/@''INT64_MAX_EQ_LONG_MAX''@/$(INT64_MAX_EQ_LONG_MAX)/g' \ + -e 's/@''UINT32_MAX_LT_UINTMAX_MAX''@/$(UINT32_MAX_LT_UINTMAX_MAX)/g' \ + -e 's/@''UINT64_MAX_EQ_ULONG_MAX''@/$(UINT64_MAX_EQ_ULONG_MAX)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/inttypes.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += inttypes.h inttypes.h-t + +EXTRA_DIST += inttypes.in.h + +## end gnulib module inttypes-incomplete + ## begin gnulib module langinfo BUILT_SOURCES += langinfo.h @@ -433,103 +827,69 @@ BUILT_SOURCES += langinfo.h # We need the following in order to create an empty placeholder for # when the system doesn't have one. langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \ - -e 's/@''GNULIB_NL_LANGINFO''@/$(GNULIB_NL_LANGINFO)/g' \ + -e 's/@''GNULIB_NL_LANGINFO''@/$(GL_GNULIB_NL_LANGINFO)/g' \ -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ + -e 's|@''HAVE_LANGINFO_ALTMON''@|$(HAVE_LANGINFO_ALTMON)|g' \ -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/langinfo.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/langinfo.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += langinfo.h langinfo.h-t EXTRA_DIST += langinfo.in.h ## end gnulib module langinfo -## begin gnulib module localcharset +## begin gnulib module libc-config -libgnu_a_SOURCES += localcharset.h localcharset.c - -# We need the following in order to install a simple file in $(libdir) -# which is shared with other installed packages. We use a list of referencing -# packages so that "make uninstall" will remove the file if and only if it -# is not used by another installed package. -# On systems with glibc-2.1 or newer, the file is redundant, therefore we -# avoid installing it. - -all-local: charset.alias ref-add.sed ref-del.sed - -charset_alias = $(DESTDIR)$(libdir)/charset.alias -charset_tmp = $(DESTDIR)$(libdir)/charset.tmp -install-exec-local: install-exec-localcharset -install-exec-localcharset: all-local - if test $(GLIBC21) = no; then \ - case '$(host_os)' in \ - darwin[56]*) \ - need_charset_alias=true ;; \ - darwin* | cygwin* | mingw* | pw32* | cegcc*) \ - need_charset_alias=false ;; \ - *) \ - need_charset_alias=true ;; \ - esac ; \ - else \ - need_charset_alias=false ; \ - fi ; \ - if $$need_charset_alias; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ - fi ; \ - if test -f $(charset_alias); then \ - sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - else \ - if $$need_charset_alias; then \ - sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - fi ; \ - fi - -uninstall-local: uninstall-localcharset -uninstall-localcharset: all-local - if test -f $(charset_alias); then \ - sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ - if grep '^# Packages using this file: $$' $(charset_tmp) \ - > /dev/null; then \ - rm -f $(charset_alias); \ - else \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ - fi; \ - rm -f $(charset_tmp); \ - fi -charset.alias: config.charset - $(AM_V_GEN)rm -f t-$@ $@ && \ - $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ - mv t-$@ $@ +EXTRA_DIST += cdefs.h libc-config.h + +## end gnulib module libc-config + +## begin gnulib module limits-h + +BUILT_SOURCES += $(LIMITS_H) + +# We need the following in order to create when the system +# doesn't have one that is compatible with GNU. +if GL_GENERATE_LIMITS_H +limits.h: limits.in.h $(top_builddir)/config.status + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \ + $(srcdir)/limits.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +limits.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += limits.h limits.h-t + +EXTRA_DIST += limits.in.h + +## end gnulib module limits-h -SUFFIXES += .sed .sin -.sin.sed: - $(AM_V_GEN)rm -f t-$@ $@ && \ - sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ - mv t-$@ $@ +## begin gnulib module localcharset -CLEANFILES += charset.alias ref-add.sed ref-del.sed +libgnu_a_SOURCES += localcharset.c -EXTRA_DIST += config.charset ref-add.sin ref-del.sin +EXTRA_DIST += localcharset.h ## end gnulib module localcharset @@ -540,28 +900,33 @@ BUILT_SOURCES += locale.h # We need the following in order to create when the system # doesn't have one that provides all definitions. locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \ - -e 's/@''GNULIB_LOCALECONV''@/$(GNULIB_LOCALECONV)/g' \ - -e 's/@''GNULIB_SETLOCALE''@/$(GNULIB_SETLOCALE)/g' \ - -e 's/@''GNULIB_DUPLOCALE''@/$(GNULIB_DUPLOCALE)/g' \ + -e 's/@''GNULIB_LOCALECONV''@/$(GL_GNULIB_LOCALECONV)/g' \ + -e 's/@''GNULIB_SETLOCALE''@/$(GL_GNULIB_SETLOCALE)/g' \ + -e 's/@''GNULIB_SETLOCALE_NULL''@/$(GL_GNULIB_SETLOCALE_NULL)/g' \ + -e 's/@''GNULIB_DUPLOCALE''@/$(GL_GNULIB_DUPLOCALE)/g' \ + -e 's/@''GNULIB_LOCALENAME''@/$(GL_GNULIB_LOCALENAME)/g' \ + -e 's|@''HAVE_NEWLOCALE''@|$(HAVE_NEWLOCALE)|g' \ -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \ + -e 's|@''HAVE_FREELOCALE''@|$(HAVE_FREELOCALE)|g' \ -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \ -e 's|@''REPLACE_LOCALECONV''@|$(REPLACE_LOCALECONV)|g' \ -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \ + -e 's|@''REPLACE_NEWLOCALE''@|$(REPLACE_NEWLOCALE)|g' \ -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \ + -e 's|@''REPLACE_FREELOCALE''@|$(REPLACE_FREELOCALE)|g' \ -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \ + -e 's|@''LOCALENAME_ENHANCE_LOCALE_FUNCS''@|$(LOCALENAME_ENHANCE_LOCALE_FUNCS)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/locale.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/locale.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += locale.h locale.h-t EXTRA_DIST += locale.in.h @@ -570,10 +935,9 @@ EXTRA_DIST += locale.in.h ## begin gnulib module localeconv - -EXTRA_DIST += localeconv.c - -EXTRA_libgnu_a_SOURCES += localeconv.c +if GL_COND_OBJ_LOCALECONV +libgnu_a_SOURCES += localeconv.c +endif ## end gnulib module localeconv @@ -583,6 +947,14 @@ libgnu_a_SOURCES += glthread/lock.h glthread/lock.c ## end gnulib module lock +## begin gnulib module lseek + +if GL_COND_OBJ_LSEEK +libgnu_a_SOURCES += lseek.c +endif + +## end gnulib module lseek + ## begin gnulib module malloc-gnu @@ -605,7 +977,7 @@ EXTRA_libgnu_a_SOURCES += malloc.c libgnu_a_SOURCES += malloca.c -EXTRA_DIST += malloca.h malloca.valgrind +EXTRA_DIST += malloca.h ## end gnulib module malloca @@ -617,109 +989,114 @@ libgnu_a_SOURCES += math.c # We need the following in order to create when the system # doesn't have one that works with the given compiler. math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT_AS_FIRST_DIRECTIVE''@|$(INCLUDE_NEXT_AS_FIRST_DIRECTIVE)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_AS_FIRST_DIRECTIVE_MATH_H''@|$(NEXT_AS_FIRST_DIRECTIVE_MATH_H)|g' \ - -e 's/@''GNULIB_ACOSF''@/$(GNULIB_ACOSF)/g' \ - -e 's/@''GNULIB_ACOSL''@/$(GNULIB_ACOSL)/g' \ - -e 's/@''GNULIB_ASINF''@/$(GNULIB_ASINF)/g' \ - -e 's/@''GNULIB_ASINL''@/$(GNULIB_ASINL)/g' \ - -e 's/@''GNULIB_ATANF''@/$(GNULIB_ATANF)/g' \ - -e 's/@''GNULIB_ATANL''@/$(GNULIB_ATANL)/g' \ - -e 's/@''GNULIB_ATAN2F''@/$(GNULIB_ATAN2F)/g' \ - -e 's/@''GNULIB_CBRT''@/$(GNULIB_CBRT)/g' \ - -e 's/@''GNULIB_CBRTF''@/$(GNULIB_CBRTF)/g' \ - -e 's/@''GNULIB_CBRTL''@/$(GNULIB_CBRTL)/g' \ - -e 's/@''GNULIB_CEIL''@/$(GNULIB_CEIL)/g' \ - -e 's/@''GNULIB_CEILF''@/$(GNULIB_CEILF)/g' \ - -e 's/@''GNULIB_CEILL''@/$(GNULIB_CEILL)/g' \ - -e 's/@''GNULIB_COPYSIGN''@/$(GNULIB_COPYSIGN)/g' \ - -e 's/@''GNULIB_COPYSIGNF''@/$(GNULIB_COPYSIGNF)/g' \ - -e 's/@''GNULIB_COPYSIGNL''@/$(GNULIB_COPYSIGNL)/g' \ - -e 's/@''GNULIB_COSF''@/$(GNULIB_COSF)/g' \ - -e 's/@''GNULIB_COSL''@/$(GNULIB_COSL)/g' \ - -e 's/@''GNULIB_COSHF''@/$(GNULIB_COSHF)/g' \ - -e 's/@''GNULIB_EXPF''@/$(GNULIB_EXPF)/g' \ - -e 's/@''GNULIB_EXPL''@/$(GNULIB_EXPL)/g' \ - -e 's/@''GNULIB_EXP2''@/$(GNULIB_EXP2)/g' \ - -e 's/@''GNULIB_EXP2F''@/$(GNULIB_EXP2F)/g' \ - -e 's/@''GNULIB_EXP2L''@/$(GNULIB_EXP2L)/g' \ - -e 's/@''GNULIB_EXPM1''@/$(GNULIB_EXPM1)/g' \ - -e 's/@''GNULIB_EXPM1F''@/$(GNULIB_EXPM1F)/g' \ - -e 's/@''GNULIB_EXPM1L''@/$(GNULIB_EXPM1L)/g' \ - -e 's/@''GNULIB_FABSF''@/$(GNULIB_FABSF)/g' \ - -e 's/@''GNULIB_FABSL''@/$(GNULIB_FABSL)/g' \ - -e 's/@''GNULIB_FLOOR''@/$(GNULIB_FLOOR)/g' \ - -e 's/@''GNULIB_FLOORF''@/$(GNULIB_FLOORF)/g' \ - -e 's/@''GNULIB_FLOORL''@/$(GNULIB_FLOORL)/g' \ - -e 's/@''GNULIB_FMA''@/$(GNULIB_FMA)/g' \ - -e 's/@''GNULIB_FMAF''@/$(GNULIB_FMAF)/g' \ - -e 's/@''GNULIB_FMAL''@/$(GNULIB_FMAL)/g' \ - -e 's/@''GNULIB_FMOD''@/$(GNULIB_FMOD)/g' \ - -e 's/@''GNULIB_FMODF''@/$(GNULIB_FMODF)/g' \ - -e 's/@''GNULIB_FMODL''@/$(GNULIB_FMODL)/g' \ - -e 's/@''GNULIB_FREXPF''@/$(GNULIB_FREXPF)/g' \ - -e 's/@''GNULIB_FREXP''@/$(GNULIB_FREXP)/g' \ - -e 's/@''GNULIB_FREXPL''@/$(GNULIB_FREXPL)/g' \ - -e 's/@''GNULIB_HYPOT''@/$(GNULIB_HYPOT)/g' \ - -e 's/@''GNULIB_HYPOTF''@/$(GNULIB_HYPOTF)/g' \ - -e 's/@''GNULIB_HYPOTL''@/$(GNULIB_HYPOTL)/g' \ + -e 's/@''GNULIB_ACOSF''@/$(GL_GNULIB_ACOSF)/g' \ + -e 's/@''GNULIB_ACOSL''@/$(GL_GNULIB_ACOSL)/g' \ + -e 's/@''GNULIB_ASINF''@/$(GL_GNULIB_ASINF)/g' \ + -e 's/@''GNULIB_ASINL''@/$(GL_GNULIB_ASINL)/g' \ + -e 's/@''GNULIB_ATANF''@/$(GL_GNULIB_ATANF)/g' \ + -e 's/@''GNULIB_ATANL''@/$(GL_GNULIB_ATANL)/g' \ + -e 's/@''GNULIB_ATAN2F''@/$(GL_GNULIB_ATAN2F)/g' \ + -e 's/@''GNULIB_CBRT''@/$(GL_GNULIB_CBRT)/g' \ + -e 's/@''GNULIB_CBRTF''@/$(GL_GNULIB_CBRTF)/g' \ + -e 's/@''GNULIB_CBRTL''@/$(GL_GNULIB_CBRTL)/g' \ + -e 's/@''GNULIB_CEIL''@/$(GL_GNULIB_CEIL)/g' \ + -e 's/@''GNULIB_CEILF''@/$(GL_GNULIB_CEILF)/g' \ + -e 's/@''GNULIB_CEILL''@/$(GL_GNULIB_CEILL)/g' \ + -e 's/@''GNULIB_COPYSIGN''@/$(GL_GNULIB_COPYSIGN)/g' \ + -e 's/@''GNULIB_COPYSIGNF''@/$(GL_GNULIB_COPYSIGNF)/g' \ + -e 's/@''GNULIB_COPYSIGNL''@/$(GL_GNULIB_COPYSIGNL)/g' \ + -e 's/@''GNULIB_COSF''@/$(GL_GNULIB_COSF)/g' \ + -e 's/@''GNULIB_COSL''@/$(GL_GNULIB_COSL)/g' \ + -e 's/@''GNULIB_COSHF''@/$(GL_GNULIB_COSHF)/g' \ + -e 's/@''GNULIB_EXPF''@/$(GL_GNULIB_EXPF)/g' \ + -e 's/@''GNULIB_EXPL''@/$(GL_GNULIB_EXPL)/g' \ + -e 's/@''GNULIB_EXP2''@/$(GL_GNULIB_EXP2)/g' \ + -e 's/@''GNULIB_EXP2F''@/$(GL_GNULIB_EXP2F)/g' \ + -e 's/@''GNULIB_EXP2L''@/$(GL_GNULIB_EXP2L)/g' \ + -e 's/@''GNULIB_EXPM1''@/$(GL_GNULIB_EXPM1)/g' \ + -e 's/@''GNULIB_EXPM1F''@/$(GL_GNULIB_EXPM1F)/g' \ + -e 's/@''GNULIB_EXPM1L''@/$(GL_GNULIB_EXPM1L)/g' \ + -e 's/@''GNULIB_FABSF''@/$(GL_GNULIB_FABSF)/g' \ + -e 's/@''GNULIB_FABSL''@/$(GL_GNULIB_FABSL)/g' \ + -e 's/@''GNULIB_FLOOR''@/$(GL_GNULIB_FLOOR)/g' \ + -e 's/@''GNULIB_FLOORF''@/$(GL_GNULIB_FLOORF)/g' \ + -e 's/@''GNULIB_FLOORL''@/$(GL_GNULIB_FLOORL)/g' \ + -e 's/@''GNULIB_FMA''@/$(GL_GNULIB_FMA)/g' \ + -e 's/@''GNULIB_FMAF''@/$(GL_GNULIB_FMAF)/g' \ + -e 's/@''GNULIB_FMAL''@/$(GL_GNULIB_FMAL)/g' \ + -e 's/@''GNULIB_FMOD''@/$(GL_GNULIB_FMOD)/g' \ + -e 's/@''GNULIB_FMODF''@/$(GL_GNULIB_FMODF)/g' \ + -e 's/@''GNULIB_FMODL''@/$(GL_GNULIB_FMODL)/g' \ + -e 's/@''GNULIB_FREXPF''@/$(GL_GNULIB_FREXPF)/g' \ + -e 's/@''GNULIB_FREXP''@/$(GL_GNULIB_FREXP)/g' \ + -e 's/@''GNULIB_FREXPL''@/$(GL_GNULIB_FREXPL)/g' \ + -e 's/@''GNULIB_HYPOT''@/$(GL_GNULIB_HYPOT)/g' \ + -e 's/@''GNULIB_HYPOTF''@/$(GL_GNULIB_HYPOTF)/g' \ + -e 's/@''GNULIB_HYPOTL''@/$(GL_GNULIB_HYPOTL)/g' \ < $(srcdir)/math.in.h | \ - sed -e 's/@''GNULIB_ILOGB''@/$(GNULIB_ILOGB)/g' \ - -e 's/@''GNULIB_ILOGBF''@/$(GNULIB_ILOGBF)/g' \ - -e 's/@''GNULIB_ILOGBL''@/$(GNULIB_ILOGBL)/g' \ - -e 's/@''GNULIB_ISFINITE''@/$(GNULIB_ISFINITE)/g' \ - -e 's/@''GNULIB_ISINF''@/$(GNULIB_ISINF)/g' \ - -e 's/@''GNULIB_ISNAN''@/$(GNULIB_ISNAN)/g' \ - -e 's/@''GNULIB_ISNANF''@/$(GNULIB_ISNANF)/g' \ - -e 's/@''GNULIB_ISNAND''@/$(GNULIB_ISNAND)/g' \ - -e 's/@''GNULIB_ISNANL''@/$(GNULIB_ISNANL)/g' \ - -e 's/@''GNULIB_LDEXPF''@/$(GNULIB_LDEXPF)/g' \ - -e 's/@''GNULIB_LDEXPL''@/$(GNULIB_LDEXPL)/g' \ - -e 's/@''GNULIB_LOG''@/$(GNULIB_LOG)/g' \ - -e 's/@''GNULIB_LOGF''@/$(GNULIB_LOGF)/g' \ - -e 's/@''GNULIB_LOGL''@/$(GNULIB_LOGL)/g' \ - -e 's/@''GNULIB_LOG10''@/$(GNULIB_LOG10)/g' \ - -e 's/@''GNULIB_LOG10F''@/$(GNULIB_LOG10F)/g' \ - -e 's/@''GNULIB_LOG10L''@/$(GNULIB_LOG10L)/g' \ - -e 's/@''GNULIB_LOG1P''@/$(GNULIB_LOG1P)/g' \ - -e 's/@''GNULIB_LOG1PF''@/$(GNULIB_LOG1PF)/g' \ - -e 's/@''GNULIB_LOG1PL''@/$(GNULIB_LOG1PL)/g' \ - -e 's/@''GNULIB_LOG2''@/$(GNULIB_LOG2)/g' \ - -e 's/@''GNULIB_LOG2F''@/$(GNULIB_LOG2F)/g' \ - -e 's/@''GNULIB_LOG2L''@/$(GNULIB_LOG2L)/g' \ - -e 's/@''GNULIB_LOGB''@/$(GNULIB_LOGB)/g' \ - -e 's/@''GNULIB_LOGBF''@/$(GNULIB_LOGBF)/g' \ - -e 's/@''GNULIB_LOGBL''@/$(GNULIB_LOGBL)/g' \ - -e 's/@''GNULIB_MODF''@/$(GNULIB_MODF)/g' \ - -e 's/@''GNULIB_MODFF''@/$(GNULIB_MODFF)/g' \ - -e 's/@''GNULIB_MODFL''@/$(GNULIB_MODFL)/g' \ - -e 's/@''GNULIB_POWF''@/$(GNULIB_POWF)/g' \ - -e 's/@''GNULIB_REMAINDER''@/$(GNULIB_REMAINDER)/g' \ - -e 's/@''GNULIB_REMAINDERF''@/$(GNULIB_REMAINDERF)/g' \ - -e 's/@''GNULIB_REMAINDERL''@/$(GNULIB_REMAINDERL)/g' \ - -e 's/@''GNULIB_RINT''@/$(GNULIB_RINT)/g' \ - -e 's/@''GNULIB_RINTF''@/$(GNULIB_RINTF)/g' \ - -e 's/@''GNULIB_RINTL''@/$(GNULIB_RINTL)/g' \ - -e 's/@''GNULIB_ROUND''@/$(GNULIB_ROUND)/g' \ - -e 's/@''GNULIB_ROUNDF''@/$(GNULIB_ROUNDF)/g' \ - -e 's/@''GNULIB_ROUNDL''@/$(GNULIB_ROUNDL)/g' \ - -e 's/@''GNULIB_SIGNBIT''@/$(GNULIB_SIGNBIT)/g' \ - -e 's/@''GNULIB_SINF''@/$(GNULIB_SINF)/g' \ - -e 's/@''GNULIB_SINL''@/$(GNULIB_SINL)/g' \ - -e 's/@''GNULIB_SINHF''@/$(GNULIB_SINHF)/g' \ - -e 's/@''GNULIB_SQRTF''@/$(GNULIB_SQRTF)/g' \ - -e 's/@''GNULIB_SQRTL''@/$(GNULIB_SQRTL)/g' \ - -e 's/@''GNULIB_TANF''@/$(GNULIB_TANF)/g' \ - -e 's/@''GNULIB_TANL''@/$(GNULIB_TANL)/g' \ - -e 's/@''GNULIB_TANHF''@/$(GNULIB_TANHF)/g' \ - -e 's/@''GNULIB_TRUNC''@/$(GNULIB_TRUNC)/g' \ - -e 's/@''GNULIB_TRUNCF''@/$(GNULIB_TRUNCF)/g' \ - -e 's/@''GNULIB_TRUNCL''@/$(GNULIB_TRUNCL)/g' \ + sed -e 's/@''GNULIB_ILOGB''@/$(GL_GNULIB_ILOGB)/g' \ + -e 's/@''GNULIB_ILOGBF''@/$(GL_GNULIB_ILOGBF)/g' \ + -e 's/@''GNULIB_ILOGBL''@/$(GL_GNULIB_ILOGBL)/g' \ + -e 's/@''GNULIB_ISFINITE''@/$(GL_GNULIB_ISFINITE)/g' \ + -e 's/@''GNULIB_ISINF''@/$(GL_GNULIB_ISINF)/g' \ + -e 's/@''GNULIB_ISNAN''@/$(GL_GNULIB_ISNAN)/g' \ + -e 's/@''GNULIB_ISNANF''@/$(GL_GNULIB_ISNANF)/g' \ + -e 's/@''GNULIB_ISNAND''@/$(GL_GNULIB_ISNAND)/g' \ + -e 's/@''GNULIB_ISNANL''@/$(GL_GNULIB_ISNANL)/g' \ + -e 's/@''GNULIB_LDEXPF''@/$(GL_GNULIB_LDEXPF)/g' \ + -e 's/@''GNULIB_LDEXPL''@/$(GL_GNULIB_LDEXPL)/g' \ + -e 's/@''GNULIB_LOG''@/$(GL_GNULIB_LOG)/g' \ + -e 's/@''GNULIB_LOGF''@/$(GL_GNULIB_LOGF)/g' \ + -e 's/@''GNULIB_LOGL''@/$(GL_GNULIB_LOGL)/g' \ + -e 's/@''GNULIB_LOG10''@/$(GL_GNULIB_LOG10)/g' \ + -e 's/@''GNULIB_LOG10F''@/$(GL_GNULIB_LOG10F)/g' \ + -e 's/@''GNULIB_LOG10L''@/$(GL_GNULIB_LOG10L)/g' \ + -e 's/@''GNULIB_LOG1P''@/$(GL_GNULIB_LOG1P)/g' \ + -e 's/@''GNULIB_LOG1PF''@/$(GL_GNULIB_LOG1PF)/g' \ + -e 's/@''GNULIB_LOG1PL''@/$(GL_GNULIB_LOG1PL)/g' \ + -e 's/@''GNULIB_LOG2''@/$(GL_GNULIB_LOG2)/g' \ + -e 's/@''GNULIB_LOG2F''@/$(GL_GNULIB_LOG2F)/g' \ + -e 's/@''GNULIB_LOG2L''@/$(GL_GNULIB_LOG2L)/g' \ + -e 's/@''GNULIB_LOGB''@/$(GL_GNULIB_LOGB)/g' \ + -e 's/@''GNULIB_LOGBF''@/$(GL_GNULIB_LOGBF)/g' \ + -e 's/@''GNULIB_LOGBL''@/$(GL_GNULIB_LOGBL)/g' \ + -e 's/@''GNULIB_MODF''@/$(GL_GNULIB_MODF)/g' \ + -e 's/@''GNULIB_MODFF''@/$(GL_GNULIB_MODFF)/g' \ + -e 's/@''GNULIB_MODFL''@/$(GL_GNULIB_MODFL)/g' \ + -e 's/@''GNULIB_POWF''@/$(GL_GNULIB_POWF)/g' \ + -e 's/@''GNULIB_REMAINDER''@/$(GL_GNULIB_REMAINDER)/g' \ + -e 's/@''GNULIB_REMAINDERF''@/$(GL_GNULIB_REMAINDERF)/g' \ + -e 's/@''GNULIB_REMAINDERL''@/$(GL_GNULIB_REMAINDERL)/g' \ + -e 's/@''GNULIB_RINT''@/$(GL_GNULIB_RINT)/g' \ + -e 's/@''GNULIB_RINTF''@/$(GL_GNULIB_RINTF)/g' \ + -e 's/@''GNULIB_RINTL''@/$(GL_GNULIB_RINTL)/g' \ + -e 's/@''GNULIB_ROUND''@/$(GL_GNULIB_ROUND)/g' \ + -e 's/@''GNULIB_ROUNDF''@/$(GL_GNULIB_ROUNDF)/g' \ + -e 's/@''GNULIB_ROUNDL''@/$(GL_GNULIB_ROUNDL)/g' \ + -e 's/@''GNULIB_SIGNBIT''@/$(GL_GNULIB_SIGNBIT)/g' \ + -e 's/@''GNULIB_SINF''@/$(GL_GNULIB_SINF)/g' \ + -e 's/@''GNULIB_SINL''@/$(GL_GNULIB_SINL)/g' \ + -e 's/@''GNULIB_SINHF''@/$(GL_GNULIB_SINHF)/g' \ + -e 's/@''GNULIB_SQRTF''@/$(GL_GNULIB_SQRTF)/g' \ + -e 's/@''GNULIB_SQRTL''@/$(GL_GNULIB_SQRTL)/g' \ + -e 's/@''GNULIB_TANF''@/$(GL_GNULIB_TANF)/g' \ + -e 's/@''GNULIB_TANL''@/$(GL_GNULIB_TANL)/g' \ + -e 's/@''GNULIB_TANHF''@/$(GL_GNULIB_TANHF)/g' \ + -e 's/@''GNULIB_TRUNC''@/$(GL_GNULIB_TRUNC)/g' \ + -e 's/@''GNULIB_TRUNCF''@/$(GL_GNULIB_TRUNCF)/g' \ + -e 's/@''GNULIB_TRUNCL''@/$(GL_GNULIB_TRUNCL)/g' \ + -e 's/@''GNULIB_MDA_J0''@/$(GL_GNULIB_MDA_J0)/g' \ + -e 's/@''GNULIB_MDA_J1''@/$(GL_GNULIB_MDA_J1)/g' \ + -e 's/@''GNULIB_MDA_JN''@/$(GL_GNULIB_MDA_JN)/g' \ + -e 's/@''GNULIB_MDA_Y0''@/$(GL_GNULIB_MDA_Y0)/g' \ + -e 's/@''GNULIB_MDA_Y1''@/$(GL_GNULIB_MDA_Y1)/g' \ + -e 's/@''GNULIB_MDA_YN''@/$(GL_GNULIB_MDA_YN)/g' \ | \ sed -e 's|@''HAVE_ACOSF''@|$(HAVE_ACOSF)|g' \ -e 's|@''HAVE_ACOSL''@|$(HAVE_ACOSL)|g' \ @@ -818,13 +1195,22 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_DECL_TRUNCF''@|$(HAVE_DECL_TRUNCF)|g' \ -e 's|@''HAVE_DECL_TRUNCL''@|$(HAVE_DECL_TRUNCL)|g' \ | \ - sed -e 's|@''REPLACE_CBRTF''@|$(REPLACE_CBRTF)|g' \ + sed -e 's|@''REPLACE_ACOSF''@|$(REPLACE_ACOSF)|g' \ + -e 's|@''REPLACE_ASINF''@|$(REPLACE_ASINF)|g' \ + -e 's|@''REPLACE_ATANF''@|$(REPLACE_ATANF)|g' \ + -e 's|@''REPLACE_ATAN2F''@|$(REPLACE_ATAN2F)|g' \ + -e 's|@''REPLACE_CBRTF''@|$(REPLACE_CBRTF)|g' \ -e 's|@''REPLACE_CBRTL''@|$(REPLACE_CBRTL)|g' \ -e 's|@''REPLACE_CEIL''@|$(REPLACE_CEIL)|g' \ -e 's|@''REPLACE_CEILF''@|$(REPLACE_CEILF)|g' \ -e 's|@''REPLACE_CEILL''@|$(REPLACE_CEILL)|g' \ + -e 's|@''REPLACE_COSF''@|$(REPLACE_COSF)|g' \ + -e 's|@''REPLACE_COSHF''@|$(REPLACE_COSHF)|g' \ + -e 's|@''REPLACE_EXPF''@|$(REPLACE_EXPF)|g' \ + -e 's|@''REPLACE_EXPL''@|$(REPLACE_EXPL)|g' \ -e 's|@''REPLACE_EXPM1''@|$(REPLACE_EXPM1)|g' \ -e 's|@''REPLACE_EXPM1F''@|$(REPLACE_EXPM1F)|g' \ + -e 's|@''REPLACE_EXPM1L''@|$(REPLACE_EXPM1L)|g' \ -e 's|@''REPLACE_EXP2''@|$(REPLACE_EXP2)|g' \ -e 's|@''REPLACE_EXP2L''@|$(REPLACE_EXP2L)|g' \ -e 's|@''REPLACE_FABSL''@|$(REPLACE_FABSL)|g' \ @@ -846,6 +1232,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''REPLACE_HYPOTL''@|$(REPLACE_HYPOTL)|g' \ -e 's|@''REPLACE_ILOGB''@|$(REPLACE_ILOGB)|g' \ -e 's|@''REPLACE_ILOGBF''@|$(REPLACE_ILOGBF)|g' \ + -e 's|@''REPLACE_ILOGBL''@|$(REPLACE_ILOGBL)|g' \ -e 's|@''REPLACE_ISFINITE''@|$(REPLACE_ISFINITE)|g' \ -e 's|@''REPLACE_ISINF''@|$(REPLACE_ISINF)|g' \ -e 's|@''REPLACE_ISNAN''@|$(REPLACE_ISNAN)|g' \ @@ -873,20 +1260,26 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''REPLACE_REMAINDER''@|$(REPLACE_REMAINDER)|g' \ -e 's|@''REPLACE_REMAINDERF''@|$(REPLACE_REMAINDERF)|g' \ -e 's|@''REPLACE_REMAINDERL''@|$(REPLACE_REMAINDERL)|g' \ + -e 's|@''REPLACE_RINTL''@|$(REPLACE_RINTL)|g' \ -e 's|@''REPLACE_ROUND''@|$(REPLACE_ROUND)|g' \ -e 's|@''REPLACE_ROUNDF''@|$(REPLACE_ROUNDF)|g' \ -e 's|@''REPLACE_ROUNDL''@|$(REPLACE_ROUNDL)|g' \ -e 's|@''REPLACE_SIGNBIT''@|$(REPLACE_SIGNBIT)|g' \ - -e 's|@''REPLACE_SIGNBIT_USING_GCC''@|$(REPLACE_SIGNBIT_USING_GCC)|g' \ + -e 's|@''REPLACE_SIGNBIT_USING_BUILTINS''@|$(REPLACE_SIGNBIT_USING_BUILTINS)|g' \ + -e 's|@''REPLACE_SINF''@|$(REPLACE_SINF)|g' \ + -e 's|@''REPLACE_SINHF''@|$(REPLACE_SINHF)|g' \ + -e 's|@''REPLACE_SQRTF''@|$(REPLACE_SQRTF)|g' \ -e 's|@''REPLACE_SQRTL''@|$(REPLACE_SQRTL)|g' \ + -e 's|@''REPLACE_TANF''@|$(REPLACE_TANF)|g' \ + -e 's|@''REPLACE_TANHF''@|$(REPLACE_TANHF)|g' \ -e 's|@''REPLACE_TRUNC''@|$(REPLACE_TRUNC)|g' \ -e 's|@''REPLACE_TRUNCF''@|$(REPLACE_TRUNCF)|g' \ -e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|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)'; \ - } > $@-t && \ - mv $@-t $@ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += math.h math.h-t EXTRA_DIST += math.in.h @@ -895,40 +1288,50 @@ EXTRA_DIST += math.in.h ## begin gnulib module mbrtowc +if GL_COND_OBJ_MBRTOWC +libgnu_a_SOURCES += mbrtowc.c +endif -EXTRA_DIST += mbrtowc.c +EXTRA_DIST += lc-charset-dispatch.c lc-charset-dispatch.h mbrtowc-impl-utf8.h mbrtowc-impl.h mbtowc-lock.c mbtowc-lock.h windows-initguard.h -EXTRA_libgnu_a_SOURCES += mbrtowc.c +EXTRA_libgnu_a_SOURCES += lc-charset-dispatch.c mbtowc-lock.c ## end gnulib module mbrtowc ## begin gnulib module mbsinit - -EXTRA_DIST += mbsinit.c - -EXTRA_libgnu_a_SOURCES += mbsinit.c +if GL_COND_OBJ_MBSINIT +libgnu_a_SOURCES += mbsinit.c +endif ## end gnulib module mbsinit ## begin gnulib module mbtowc +if GL_COND_OBJ_MBTOWC +libgnu_a_SOURCES += mbtowc.c +endif -EXTRA_DIST += mbtowc-impl.h mbtowc.c - -EXTRA_libgnu_a_SOURCES += mbtowc.c +EXTRA_DIST += mbtowc-impl.h ## end gnulib module mbtowc ## begin gnulib module memchr +if GL_COND_OBJ_MEMCHR +libgnu_a_SOURCES += memchr.c +endif -EXTRA_DIST += memchr.c memchr.valgrind - -EXTRA_libgnu_a_SOURCES += memchr.c +EXTRA_DIST += memchr.valgrind ## end gnulib module memchr +## begin gnulib module minmax + +libgnu_a_SOURCES += minmax.h + +## end gnulib module minmax + ## begin gnulib module mktime @@ -949,28 +1352,31 @@ EXTRA_libgnu_a_SOURCES += mktime.c ## begin gnulib module mountlist +if GL_COND_OBJ_MOUNTLIST +libgnu_a_SOURCES += mountlist.c +endif -EXTRA_DIST += mountlist.c mountlist.h - -EXTRA_libgnu_a_SOURCES += mountlist.c +EXTRA_DIST += mountlist.h ## end gnulib module mountlist ## begin gnulib module msvc-inval +if GL_COND_OBJ_MSVC_INVAL +libgnu_a_SOURCES += msvc-inval.c +endif -EXTRA_DIST += msvc-inval.c msvc-inval.h - -EXTRA_libgnu_a_SOURCES += msvc-inval.c +EXTRA_DIST += msvc-inval.h ## end gnulib module msvc-inval ## begin gnulib module msvc-nothrow +if GL_COND_OBJ_MSVC_NOTHROW +libgnu_a_SOURCES += msvc-nothrow.c +endif -EXTRA_DIST += msvc-nothrow.c msvc-nothrow.h - -EXTRA_libgnu_a_SOURCES += msvc-nothrow.c +EXTRA_DIST += msvc-nothrow.h ## end gnulib module msvc-nothrow @@ -981,27 +1387,26 @@ BUILT_SOURCES += netdb.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. netdb.h: netdb.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_NETDB_H''@|$(NEXT_NETDB_H)|g' \ -e 's|@''HAVE_NETDB_H''@|$(HAVE_NETDB_H)|g' \ - -e 's/@''GNULIB_GETADDRINFO''@/$(GNULIB_GETADDRINFO)/g' \ + -e 's/@''GNULIB_GETADDRINFO''@/$(GL_GNULIB_GETADDRINFO)/g' \ -e 's|@''HAVE_STRUCT_ADDRINFO''@|$(HAVE_STRUCT_ADDRINFO)|g' \ -e 's|@''HAVE_DECL_FREEADDRINFO''@|$(HAVE_DECL_FREEADDRINFO)|g' \ -e 's|@''HAVE_DECL_GAI_STRERROR''@|$(HAVE_DECL_GAI_STRERROR)|g' \ -e 's|@''HAVE_DECL_GETADDRINFO''@|$(HAVE_DECL_GETADDRINFO)|g' \ -e 's|@''HAVE_DECL_GETNAMEINFO''@|$(HAVE_DECL_GETNAMEINFO)|g' \ -e 's|@''REPLACE_GAI_STRERROR''@|$(REPLACE_GAI_STRERROR)|g' \ + -e 's|@''REPLACE_GETADDRINFO''@|$(REPLACE_GETADDRINFO)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/netdb.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/netdb.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += netdb.h netdb.h-t EXTRA_DIST += netdb.in.h @@ -1016,18 +1421,16 @@ BUILT_SOURCES += $(NETINET_IN_H) # doesn't have one. if GL_GENERATE_NETINET_IN_H netinet/in.h: netinet_in.in.h $(top_builddir)/config.status - $(AM_V_at)$(MKDIR_P) netinet - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(AM_V_GEN)$(MKDIR_P) '%reldir%/netinet' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_NETINET_IN_H''@|$(NEXT_NETINET_IN_H)|g' \ -e 's|@''HAVE_NETINET_IN_H''@|$(HAVE_NETINET_IN_H)|g' \ - < $(srcdir)/netinet_in.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/netinet_in.in.h > $@-t + $(AM_V_at)mv $@-t $@ else netinet/in.h: $(top_builddir)/config.status rm -f $@ @@ -1041,48 +1444,89 @@ EXTRA_DIST += netinet_in.in.h ## begin gnulib module nl_langinfo +if GL_COND_OBJ_NL_LANGINFO +libgnu_a_SOURCES += nl_langinfo.c +endif +if GL_COND_OBJ_NL_LANGINFO_LOCK +libgnu_a_SOURCES += nl_langinfo-lock.c +endif -EXTRA_DIST += nl_langinfo.c - -EXTRA_libgnu_a_SOURCES += nl_langinfo.c +EXTRA_DIST += windows-initguard.h ## end gnulib module nl_langinfo -## begin gnulib module read +## begin gnulib module open +if GL_COND_OBJ_OPEN +libgnu_a_SOURCES += open.c +endif -EXTRA_DIST += read.c +## end gnulib module open -EXTRA_libgnu_a_SOURCES += read.c +## begin gnulib module pathmax -## end gnulib module read -## begin gnulib module regex +EXTRA_DIST += pathmax.h +## end gnulib module pathmax -EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c +## begin gnulib module realloc-gnu -EXTRA_libgnu_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c -## end gnulib module regex +EXTRA_DIST += realloc.c -## begin gnulib module safe-read +EXTRA_libgnu_a_SOURCES += realloc.c -libgnu_a_SOURCES += safe-read.c +## end gnulib module realloc-gnu -EXTRA_DIST += safe-read.h +## begin gnulib module realloc-posix -## end gnulib module safe-read -## begin gnulib module setenv +EXTRA_DIST += realloc.c + +EXTRA_libgnu_a_SOURCES += realloc.c +## end gnulib module realloc-posix -EXTRA_DIST += setenv.c +## begin gnulib module reallocarray -EXTRA_libgnu_a_SOURCES += setenv.c +if GL_COND_OBJ_REALLOCARRAY +libgnu_a_SOURCES += reallocarray.c +endif + +## end gnulib module reallocarray + +## begin gnulib module regex + +if GL_COND_OBJ_REGEX +libgnu_a_SOURCES += regex.c +endif + +EXTRA_DIST += regcomp.c regex.h regex_internal.c regex_internal.h regexec.c + +EXTRA_libgnu_a_SOURCES += regcomp.c regex_internal.c regexec.c + +## end gnulib module regex + +## begin gnulib module setenv + +if GL_COND_OBJ_SETENV +libgnu_a_SOURCES += setenv.c +endif ## end gnulib module setenv +## begin gnulib module setlocale-null + +libgnu_a_SOURCES += setlocale_null.c +if GL_COND_OBJ_SETLOCALE_LOCK +libgnu_a_SOURCES += setlocale-lock.c +endif + +EXTRA_DIST += setlocale_null.h windows-initguard.h + +## end gnulib module setlocale-null + ## begin gnulib module size_max libgnu_a_SOURCES += size_max.h @@ -1092,81 +1536,48 @@ libgnu_a_SOURCES += size_max.h ## begin gnulib module snippet/_Noreturn # Because this Makefile snippet defines a variable used by other -# gnulib Makefile snippets, it must be present in all Makefile.am that +# gnulib Makefile snippets, it must be present in all makefiles that # need it. This is ensured by the applicability 'all' defined above. -_NORETURN_H=$(top_srcdir)/build-aux/snippet/_Noreturn.h +_NORETURN_H=$(srcdir)/_Noreturn.h -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/_Noreturn.h +EXTRA_DIST += _Noreturn.h ## end gnulib module snippet/_Noreturn ## begin gnulib module snippet/arg-nonnull -# The BUILT_SOURCES created by this Makefile snippet are not used via #include -# statements but through direct file reference. Therefore this snippet must be -# present in all Makefile.am that need it. This is ensured by the applicability -# 'all' defined above. - -BUILT_SOURCES += arg-nonnull.h -# The arg-nonnull.h that gets inserted into generated .h files is the same as -# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut -# off. -arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h - $(AM_V_GEN)rm -f $@-t $@ && \ - sed -n -e '/GL_ARG_NONNULL/,$$p' \ - < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ - > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. -ARG_NONNULL_H=arg-nonnull.h +ARG_NONNULL_H=$(srcdir)/arg-nonnull.h -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/arg-nonnull.h +EXTRA_DIST += arg-nonnull.h ## end gnulib module snippet/arg-nonnull ## begin gnulib module snippet/c++defs -# The BUILT_SOURCES created by this Makefile snippet are not used via #include -# statements but through direct file reference. Therefore this snippet must be -# present in all Makefile.am that need it. This is ensured by the applicability -# 'all' defined above. - -BUILT_SOURCES += c++defs.h -# The c++defs.h that gets inserted into generated .h files is the same as -# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. -c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h - $(AM_V_GEN)rm -f $@-t $@ && \ - sed -n -e '/_GL_CXXDEFS/,$$p' \ - < $(top_srcdir)/build-aux/snippet/c++defs.h \ - > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += c++defs.h c++defs.h-t +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. -CXXDEFS_H=c++defs.h +CXXDEFS_H=$(srcdir)/c++defs.h -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/c++defs.h +EXTRA_DIST += c++defs.h ## end gnulib module snippet/c++defs ## begin gnulib module snippet/warn-on-use -BUILT_SOURCES += warn-on-use.h -# The warn-on-use.h that gets inserted into generated .h files is the same as -# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut -# off. -warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h - $(AM_V_GEN)rm -f $@-t $@ && \ - sed -n -e '/^.ifndef/,$$p' \ - < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ - > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. -WARN_ON_USE_H=warn-on-use.h +WARN_ON_USE_H=$(srcdir)/warn-on-use.h -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/warn-on-use.h +EXTRA_DIST += warn-on-use.h ## end gnulib module snippet/warn-on-use @@ -1187,6 +1598,26 @@ EXTRA_DIST += w32sock.h ## end gnulib module sockets +## begin gnulib module stat + +if GL_COND_OBJ_STAT +libgnu_a_SOURCES += stat.c +endif + +EXTRA_DIST += stat-w32.c stat-w32.h + +EXTRA_libgnu_a_SOURCES += stat-w32.c + +## end gnulib module stat + +## begin gnulib module stat-time + +libgnu_a_SOURCES += stat-time.c + +EXTRA_DIST += stat-time.h + +## end gnulib module stat-time + ## begin gnulib module stdalign BUILT_SOURCES += $(STDALIGN_H) @@ -1195,11 +1626,8 @@ BUILT_SOURCES += $(STDALIGN_H) # doesn't have one that works. if GL_GENERATE_STDALIGN_H stdalign.h: stdalign.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/stdalign.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/stdalign.in.h + $(AM_V_at)mv $@-t $@ else stdalign.h: $(top_builddir)/config.status rm -f $@ @@ -1218,11 +1646,10 @@ BUILT_SOURCES += $(STDBOOL_H) # doesn't have one that works. if GL_GENERATE_STDBOOL_H stdbool.h: stdbool.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' \ + $(srcdir)/stdbool.in.h > $@-t + $(AM_V_at)mv $@-t $@ else stdbool.h: $(top_builddir)/config.status rm -f $@ @@ -1233,6 +1660,27 @@ EXTRA_DIST += stdbool.in.h ## end gnulib module stdbool +## begin gnulib module stdckdint + +BUILT_SOURCES += $(STDCKDINT_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +if GL_GENERATE_STDCKDINT_H +stdckdint.h: stdckdint.in.h $(top_builddir)/config.status + $(gl_V_at)$(SED_HEADER_STDOUT) \ + $(srcdir)/stdckdint.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +stdckdint.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdckdint.h stdckdint.h-t + +EXTRA_DIST += intprops-internal.h stdckdint.in.h + +## end gnulib module stdckdint + ## begin gnulib module stddef BUILT_SOURCES += $(STDDEF_H) @@ -1241,18 +1689,17 @@ BUILT_SOURCES += $(STDDEF_H) # doesn't have one that works with the given compiler. if GL_GENERATE_STDDEF_H stddef.h: stddef.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ + -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \ -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ - < $(srcdir)/stddef.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/stddef.in.h > $@-t + $(AM_V_at)mv $@-t $@ else stddef.h: $(top_builddir)/config.status rm -f $@ @@ -1271,21 +1718,19 @@ BUILT_SOURCES += $(STDINT_H) # doesn't have one that works with the given compiler. if GL_GENERATE_STDINT_H stdint.h: stdint.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ + -e 's/@''HAVE_C99_STDINT_H''@/$(HAVE_C99_STDINT_H)/g' \ -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ @@ -1300,9 +1745,9 @@ stdint.h: stdint.in.h $(top_builddir)/config.status -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ - < $(srcdir)/stdint.in.h; \ - } > $@-t && \ - mv $@-t $@ + -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \ + $(srcdir)/stdint.in.h > $@-t + $(AM_V_at)mv $@-t $@ else stdint.h: $(top_builddir)/config.status rm -f $@ @@ -1320,68 +1765,75 @@ BUILT_SOURCES += stdio.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ - -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ - -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ - -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \ - -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ - -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ - -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ - -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \ - -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \ - -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \ - -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \ - -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \ - -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \ - -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \ - -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \ - -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \ - -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \ - -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \ - -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \ - -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \ - -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \ - -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ - -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ - -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ - -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ - -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ - -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \ - -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \ - -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \ - -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \ - -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \ - -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \ - -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \ - -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \ - -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \ - -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \ - -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ - -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ - -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ - -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ - -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ - -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ - -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ - -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ - -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ - -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ - -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \ - -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ - -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ - -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_DPRINTF''@/$(GL_GNULIB_DPRINTF)/g' \ + -e 's/@''GNULIB_FCLOSE''@/$(GL_GNULIB_FCLOSE)/g' \ + -e 's/@''GNULIB_FDOPEN''@/$(GL_GNULIB_FDOPEN)/g' \ + -e 's/@''GNULIB_FFLUSH''@/$(GL_GNULIB_FFLUSH)/g' \ + -e 's/@''GNULIB_FGETC''@/$(GL_GNULIB_FGETC)/g' \ + -e 's/@''GNULIB_FGETS''@/$(GL_GNULIB_FGETS)/g' \ + -e 's/@''GNULIB_FOPEN''@/$(GL_GNULIB_FOPEN)/g' \ + -e 's/@''GNULIB_FOPEN_GNU''@/$(GL_GNULIB_FOPEN_GNU)/g' \ + -e 's/@''GNULIB_FPRINTF''@/$(GL_GNULIB_FPRINTF)/g' \ + -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GL_GNULIB_FPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_FPURGE''@/$(GL_GNULIB_FPURGE)/g' \ + -e 's/@''GNULIB_FPUTC''@/$(GL_GNULIB_FPUTC)/g' \ + -e 's/@''GNULIB_FPUTS''@/$(GL_GNULIB_FPUTS)/g' \ + -e 's/@''GNULIB_FREAD''@/$(GL_GNULIB_FREAD)/g' \ + -e 's/@''GNULIB_FREOPEN''@/$(GL_GNULIB_FREOPEN)/g' \ + -e 's/@''GNULIB_FSCANF''@/$(GL_GNULIB_FSCANF)/g' \ + -e 's/@''GNULIB_FSEEK''@/$(GL_GNULIB_FSEEK)/g' \ + -e 's/@''GNULIB_FSEEKO''@/$(GL_GNULIB_FSEEKO)/g' \ + -e 's/@''GNULIB_FTELL''@/$(GL_GNULIB_FTELL)/g' \ + -e 's/@''GNULIB_FTELLO''@/$(GL_GNULIB_FTELLO)/g' \ + -e 's/@''GNULIB_FWRITE''@/$(GL_GNULIB_FWRITE)/g' \ + -e 's/@''GNULIB_GETC''@/$(GL_GNULIB_GETC)/g' \ + -e 's/@''GNULIB_GETCHAR''@/$(GL_GNULIB_GETCHAR)/g' \ + -e 's/@''GNULIB_GETDELIM''@/$(GL_GNULIB_GETDELIM)/g' \ + -e 's/@''GNULIB_GETLINE''@/$(GL_GNULIB_GETLINE)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GL_GNULIB_OBSTACK_PRINTF)/g' \ + -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GL_GNULIB_OBSTACK_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PCLOSE''@/$(GL_GNULIB_PCLOSE)/g' \ + -e 's/@''GNULIB_PERROR''@/$(GL_GNULIB_PERROR)/g' \ + -e 's/@''GNULIB_POPEN''@/$(GL_GNULIB_POPEN)/g' \ + -e 's/@''GNULIB_PRINTF''@/$(GL_GNULIB_PRINTF)/g' \ + -e 's/@''GNULIB_PRINTF_POSIX''@/$(GL_GNULIB_PRINTF_POSIX)/g' \ + -e 's/@''GNULIB_PUTC''@/$(GL_GNULIB_PUTC)/g' \ + -e 's/@''GNULIB_PUTCHAR''@/$(GL_GNULIB_PUTCHAR)/g' \ + -e 's/@''GNULIB_PUTS''@/$(GL_GNULIB_PUTS)/g' \ + -e 's/@''GNULIB_REMOVE''@/$(GL_GNULIB_REMOVE)/g' \ + -e 's/@''GNULIB_RENAME''@/$(GL_GNULIB_RENAME)/g' \ + -e 's/@''GNULIB_RENAMEAT''@/$(GL_GNULIB_RENAMEAT)/g' \ + -e 's/@''GNULIB_SCANF''@/$(GL_GNULIB_SCANF)/g' \ + -e 's/@''GNULIB_SNPRINTF''@/$(GL_GNULIB_SNPRINTF)/g' \ + -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GL_GNULIB_SPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GL_GNULIB_STDIO_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GL_GNULIB_STDIO_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_TMPFILE''@/$(GL_GNULIB_TMPFILE)/g' \ + -e 's/@''GNULIB_VASPRINTF''@/$(GL_GNULIB_VASPRINTF)/g' \ + -e 's/@''GNULIB_VDPRINTF''@/$(GL_GNULIB_VDPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF''@/$(GL_GNULIB_VFPRINTF)/g' \ + -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GL_GNULIB_VFPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VFSCANF''@/$(GL_GNULIB_VFSCANF)/g' \ + -e 's/@''GNULIB_VSCANF''@/$(GL_GNULIB_VSCANF)/g' \ + -e 's/@''GNULIB_VPRINTF''@/$(GL_GNULIB_VPRINTF)/g' \ + -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GL_GNULIB_VPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_VSNPRINTF''@/$(GL_GNULIB_VSNPRINTF)/g' \ + -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GL_GNULIB_VSPRINTF_POSIX)/g' \ + -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GL_GNULIB_MDA_FCLOSEALL)/g' \ + -e 's/@''GNULIB_MDA_FDOPEN''@/$(GL_GNULIB_MDA_FDOPEN)/g' \ + -e 's/@''GNULIB_MDA_FILENO''@/$(GL_GNULIB_MDA_FILENO)/g' \ + -e 's/@''GNULIB_MDA_GETW''@/$(GL_GNULIB_MDA_GETW)/g' \ + -e 's/@''GNULIB_MDA_PUTW''@/$(GL_GNULIB_MDA_PUTW)/g' \ + -e 's/@''GNULIB_MDA_TEMPNAM''@/$(GL_GNULIB_MDA_TEMPNAM)/g' \ < $(srcdir)/stdio.in.h | \ - sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ + sed -e 's|@''HAVE_DECL_FCLOSEALL''@|$(HAVE_DECL_FCLOSEALL)|g' \ + -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ -e 's|@''HAVE_DECL_FSEEKO''@|$(HAVE_DECL_FSEEKO)|g' \ -e 's|@''HAVE_DECL_FTELLO''@|$(HAVE_DECL_FTELLO)|g' \ -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ @@ -1402,6 +1854,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''REPLACE_FDOPEN''@|$(REPLACE_FDOPEN)|g' \ -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \ + -e 's|@''REPLACE_FOPEN_FOR_FOPEN_GNU''@|$(REPLACE_FOPEN_FOR_FOPEN_GNU)|g' \ -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \ -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \ @@ -1432,11 +1885,18 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''ASM_SYMBOL_PREFIX''@|$(ASM_SYMBOL_PREFIX)|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)'; \ - } > $@-t && \ - mv $@-t $@ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += stdio.h stdio.h-t +if GL_COND_OBJ_STDIO_READ +libgnu_a_SOURCES += stdio-read.c +endif +if GL_COND_OBJ_STDIO_WRITE +libgnu_a_SOURCES += stdio-write.c +endif + EXTRA_DIST += stdio.in.h ## end gnulib module stdio @@ -1449,95 +1909,141 @@ BUILT_SOURCES += stdlib.h # doesn't have one that works with the given compiler. stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ - -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ - -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ - -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ - -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ - -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ - -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ - -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ - -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ - -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ - -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ - -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ - -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ - -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ - -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ - -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ - -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ - -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ - -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ - -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ - -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ - -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ - -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ - -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ - -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \ - -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ - -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ - -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ - -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ - -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ - -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ - -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ - -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ + -e 's/@''GNULIB__EXIT''@/$(GL_GNULIB__EXIT)/g' \ + -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GL_GNULIB_ALIGNED_ALLOC)/g' \ + -e 's/@''GNULIB_ATOLL''@/$(GL_GNULIB_ATOLL)/g' \ + -e 's/@''GNULIB_CALLOC_GNU''@/$(GL_GNULIB_CALLOC_GNU)/g' \ + -e 's/@''GNULIB_CALLOC_POSIX''@/$(GL_GNULIB_CALLOC_POSIX)/g' \ + -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GL_GNULIB_CANONICALIZE_FILE_NAME)/g' \ + -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \ + -e 's/@''GNULIB_GETLOADAVG''@/$(GL_GNULIB_GETLOADAVG)/g' \ + -e 's/@''GNULIB_GETSUBOPT''@/$(GL_GNULIB_GETSUBOPT)/g' \ + -e 's/@''GNULIB_GRANTPT''@/$(GL_GNULIB_GRANTPT)/g' \ + -e 's/@''GNULIB_MALLOC_GNU''@/$(GL_GNULIB_MALLOC_GNU)/g' \ + -e 's/@''GNULIB_MALLOC_POSIX''@/$(GL_GNULIB_MALLOC_POSIX)/g' \ + -e 's/@''GNULIB_MBTOWC''@/$(GL_GNULIB_MBTOWC)/g' \ + -e 's/@''GNULIB_MKDTEMP''@/$(GL_GNULIB_MKDTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMP''@/$(GL_GNULIB_MKOSTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMPS''@/$(GL_GNULIB_MKOSTEMPS)/g' \ + -e 's/@''GNULIB_MKSTEMP''@/$(GL_GNULIB_MKSTEMP)/g' \ + -e 's/@''GNULIB_MKSTEMPS''@/$(GL_GNULIB_MKSTEMPS)/g' \ + -e 's/@''GNULIB_POSIX_MEMALIGN''@/$(GL_GNULIB_POSIX_MEMALIGN)/g' \ + -e 's/@''GNULIB_POSIX_OPENPT''@/$(GL_GNULIB_POSIX_OPENPT)/g' \ + -e 's/@''GNULIB_PTSNAME''@/$(GL_GNULIB_PTSNAME)/g' \ + -e 's/@''GNULIB_PTSNAME_R''@/$(GL_GNULIB_PTSNAME_R)/g' \ + -e 's/@''GNULIB_PUTENV''@/$(GL_GNULIB_PUTENV)/g' \ + -e 's/@''GNULIB_QSORT_R''@/$(GL_GNULIB_QSORT_R)/g' \ + -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \ + -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \ + -e 's/@''GNULIB_REALLOC_GNU''@/$(GL_GNULIB_REALLOC_GNU)/g' \ + -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \ + -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \ + -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \ + -e 's/@''GNULIB_RPMATCH''@/$(GL_GNULIB_RPMATCH)/g' \ + -e 's/@''GNULIB_SECURE_GETENV''@/$(GL_GNULIB_SECURE_GETENV)/g' \ + -e 's/@''GNULIB_SETENV''@/$(GL_GNULIB_SETENV)/g' \ + -e 's/@''GNULIB_STRTOD''@/$(GL_GNULIB_STRTOD)/g' \ + -e 's/@''GNULIB_STRTOL''@/$(GL_GNULIB_STRTOL)/g' \ + -e 's/@''GNULIB_STRTOLD''@/$(GL_GNULIB_STRTOLD)/g' \ + -e 's/@''GNULIB_STRTOLL''@/$(GL_GNULIB_STRTOLL)/g' \ + -e 's/@''GNULIB_STRTOUL''@/$(GL_GNULIB_STRTOUL)/g' \ + -e 's/@''GNULIB_STRTOULL''@/$(GL_GNULIB_STRTOULL)/g' \ + -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GL_GNULIB_SYSTEM_POSIX)/g' \ + -e 's/@''GNULIB_UNLOCKPT''@/$(GL_GNULIB_UNLOCKPT)/g' \ + -e 's/@''GNULIB_UNSETENV''@/$(GL_GNULIB_UNSETENV)/g' \ + -e 's/@''GNULIB_WCTOMB''@/$(GL_GNULIB_WCTOMB)/g' \ + -e 's/@''GNULIB_MDA_ECVT''@/$(GL_GNULIB_MDA_ECVT)/g' \ + -e 's/@''GNULIB_MDA_FCVT''@/$(GL_GNULIB_MDA_FCVT)/g' \ + -e 's/@''GNULIB_MDA_GCVT''@/$(GL_GNULIB_MDA_GCVT)/g' \ + -e 's/@''GNULIB_MDA_MKTEMP''@/$(GL_GNULIB_MDA_MKTEMP)/g' \ + -e 's/@''GNULIB_MDA_PUTENV''@/$(GL_GNULIB_MDA_PUTENV)/g' \ < $(srcdir)/stdlib.in.h | \ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \ -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''HAVE_DECL_ECVT''@|$(HAVE_DECL_ECVT)|g' \ + -e 's|@''HAVE_DECL_FCVT''@|$(HAVE_DECL_FCVT)|g' \ + -e 's|@''HAVE_DECL_GCVT''@|$(HAVE_DECL_GCVT)|g' \ -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ + -e 's|@''HAVE_INITSTATE''@|$(HAVE_INITSTATE)|g' \ + -e 's|@''HAVE_DECL_INITSTATE''@|$(HAVE_DECL_INITSTATE)|g' \ + -e 's|@''HAVE_MBTOWC''@|$(HAVE_MBTOWC)|g' \ -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \ -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \ -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \ + -e 's|@''HAVE_POSIX_MEMALIGN''@|$(HAVE_POSIX_MEMALIGN)|g' \ -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \ + -e 's|@''HAVE_QSORT_R''@|$(HAVE_QSORT_R)|g' \ -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \ -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ + -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \ -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \ -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ + -e 's|@''HAVE_SETSTATE''@|$(HAVE_SETSTATE)|g' \ + -e 's|@''HAVE_DECL_SETSTATE''@|$(HAVE_DECL_SETSTATE)|g' \ -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOL''@|$(HAVE_STRTOL)|g' \ + -e 's|@''HAVE_STRTOLD''@|$(HAVE_STRTOLD)|g' \ -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOUL''@|$(HAVE_STRTOUL)|g' \ -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ - -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ + -e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \ + -e 's|@''REPLACE_CALLOC_FOR_CALLOC_GNU''@|$(REPLACE_CALLOC_FOR_CALLOC_GNU)|g' \ + -e 's|@''REPLACE_CALLOC_FOR_CALLOC_POSIX''@|$(REPLACE_CALLOC_FOR_CALLOC_POSIX)|g' \ -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ - -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ + -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \ + -e 's|@''REPLACE_INITSTATE''@|$(REPLACE_INITSTATE)|g' \ + -e 's|@''REPLACE_MALLOC_FOR_MALLOC_GNU''@|$(REPLACE_MALLOC_FOR_MALLOC_GNU)|g' \ + -e 's|@''REPLACE_MALLOC_FOR_MALLOC_POSIX''@|$(REPLACE_MALLOC_FOR_MALLOC_POSIX)|g' \ -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ + -e 's|@''REPLACE_POSIX_MEMALIGN''@|$(REPLACE_POSIX_MEMALIGN)|g' \ -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \ -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ + -e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \ + -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \ -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ - -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ + -e 's|@''REPLACE_REALLOC_FOR_REALLOC_GNU''@|$(REPLACE_REALLOC_FOR_REALLOC_GNU)|g' \ + -e 's|@''REPLACE_REALLOC_FOR_REALLOC_POSIX''@|$(REPLACE_REALLOC_FOR_REALLOC_POSIX)|g' \ + -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \ -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ + -e 's|@''REPLACE_SETSTATE''@|$(REPLACE_SETSTATE)|g' \ -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''REPLACE_STRTOL''@|$(REPLACE_STRTOL)|g' \ + -e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \ + -e 's|@''REPLACE_STRTOLL''@|$(REPLACE_STRTOLL)|g' \ + -e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \ + -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \ -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _Noreturn/r $(_NORETURN_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += stdlib.h stdlib.h-t EXTRA_DIST += stdlib.in.h @@ -1546,12 +2052,23 @@ EXTRA_DIST += stdlib.in.h ## begin gnulib module strcase +if GL_COND_OBJ_STRCASECMP +libgnu_a_SOURCES += strcasecmp.c +endif +if GL_COND_OBJ_STRNCASECMP +libgnu_a_SOURCES += strncasecmp.c +endif + +## end gnulib module strcase -EXTRA_DIST += strcasecmp.c strncasecmp.c +## begin gnulib module strcasestr -EXTRA_libgnu_a_SOURCES += strcasecmp.c strncasecmp.c -## end gnulib module strcase +EXTRA_DIST += strcasestr.c + +EXTRA_libgnu_a_SOURCES += strcasestr.c + +## end gnulib module strcasestr ## begin gnulib module strcasestr-simple @@ -1571,19 +2088,19 @@ EXTRA_DIST += streq.h ## begin gnulib module strerror - -EXTRA_DIST += strerror.c - -EXTRA_libgnu_a_SOURCES += strerror.c +if GL_COND_OBJ_STRERROR +libgnu_a_SOURCES += strerror.c +endif ## end gnulib module strerror ## begin gnulib module strerror-override +if GL_COND_OBJ_STRERROR_OVERRIDE +libgnu_a_SOURCES += strerror-override.c +endif -EXTRA_DIST += strerror-override.c strerror-override.h - -EXTRA_libgnu_a_SOURCES += strerror-override.c +EXTRA_DIST += strerror-override.h ## end gnulib module strerror-override @@ -1594,55 +2111,61 @@ BUILT_SOURCES += string.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ - -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \ - -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \ - -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \ - -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \ - -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \ - -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \ - -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \ - -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \ - -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \ - -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \ - -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \ - -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \ - -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \ - -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \ - -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \ - -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \ - -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \ - -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \ - -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \ - -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \ - -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \ - -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \ - -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \ - -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \ - -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \ - -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \ - -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \ - -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \ - -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \ - -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \ - -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ - -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ - -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_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ - -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ + -e 's/@''GNULIB_EXPLICIT_BZERO''@/$(GL_GNULIB_EXPLICIT_BZERO)/g' \ + -e 's/@''GNULIB_FFSL''@/$(GL_GNULIB_FFSL)/g' \ + -e 's/@''GNULIB_FFSLL''@/$(GL_GNULIB_FFSLL)/g' \ + -e 's/@''GNULIB_MBSLEN''@/$(GL_GNULIB_MBSLEN)/g' \ + -e 's/@''GNULIB_MBSNLEN''@/$(GL_GNULIB_MBSNLEN)/g' \ + -e 's/@''GNULIB_MBSCHR''@/$(GL_GNULIB_MBSCHR)/g' \ + -e 's/@''GNULIB_MBSRCHR''@/$(GL_GNULIB_MBSRCHR)/g' \ + -e 's/@''GNULIB_MBSSTR''@/$(GL_GNULIB_MBSSTR)/g' \ + -e 's/@''GNULIB_MBSCASECMP''@/$(GL_GNULIB_MBSCASECMP)/g' \ + -e 's/@''GNULIB_MBSNCASECMP''@/$(GL_GNULIB_MBSNCASECMP)/g' \ + -e 's/@''GNULIB_MBSPCASECMP''@/$(GL_GNULIB_MBSPCASECMP)/g' \ + -e 's/@''GNULIB_MBSCASESTR''@/$(GL_GNULIB_MBSCASESTR)/g' \ + -e 's/@''GNULIB_MBSCSPN''@/$(GL_GNULIB_MBSCSPN)/g' \ + -e 's/@''GNULIB_MBSPBRK''@/$(GL_GNULIB_MBSPBRK)/g' \ + -e 's/@''GNULIB_MBSSPN''@/$(GL_GNULIB_MBSSPN)/g' \ + -e 's/@''GNULIB_MBSSEP''@/$(GL_GNULIB_MBSSEP)/g' \ + -e 's/@''GNULIB_MBSTOK_R''@/$(GL_GNULIB_MBSTOK_R)/g' \ + -e 's/@''GNULIB_MEMCHR''@/$(GL_GNULIB_MEMCHR)/g' \ + -e 's/@''GNULIB_MEMMEM''@/$(GL_GNULIB_MEMMEM)/g' \ + -e 's/@''GNULIB_MEMPCPY''@/$(GL_GNULIB_MEMPCPY)/g' \ + -e 's/@''GNULIB_MEMRCHR''@/$(GL_GNULIB_MEMRCHR)/g' \ + -e 's/@''GNULIB_RAWMEMCHR''@/$(GL_GNULIB_RAWMEMCHR)/g' \ + -e 's/@''GNULIB_STPCPY''@/$(GL_GNULIB_STPCPY)/g' \ + -e 's/@''GNULIB_STPNCPY''@/$(GL_GNULIB_STPNCPY)/g' \ + -e 's/@''GNULIB_STRCHRNUL''@/$(GL_GNULIB_STRCHRNUL)/g' \ + -e 's/@''GNULIB_STRDUP''@/$(GL_GNULIB_STRDUP)/g' \ + -e 's/@''GNULIB_STRNCAT''@/$(GL_GNULIB_STRNCAT)/g' \ + -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \ + -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \ + -e 's/@''GNULIB_STRPBRK''@/$(GL_GNULIB_STRPBRK)/g' \ + -e 's/@''GNULIB_STRSEP''@/$(GL_GNULIB_STRSEP)/g' \ + -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \ + -e 's/@''GNULIB_STRCASESTR''@/$(GL_GNULIB_STRCASESTR)/g' \ + -e 's/@''GNULIB_STRTOK_R''@/$(GL_GNULIB_STRTOK_R)/g' \ + -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \ + -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \ + -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \ + -e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \ + -e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \ + -e 's/@''GNULIB_STRSIGNAL''@/$(GL_GNULIB_STRSIGNAL)/g' \ + -e 's/@''GNULIB_STRVERSCMP''@/$(GL_GNULIB_STRVERSCMP)/g' \ + -e 's/@''GNULIB_MDA_MEMCCPY''@/$(GL_GNULIB_MDA_MEMCCPY)/g' \ + -e 's/@''GNULIB_MDA_STRDUP''@/$(GL_GNULIB_MDA_STRDUP)/g' \ + -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \ < $(srcdir)/string.in.h | \ - sed -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ + sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \ + -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ - -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ @@ -1658,29 +2181,34 @@ 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_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \ + -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \ + -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_STPNCPY''@|$(REPLACE_STPNCPY)|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_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ + -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \ + -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ - -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ - -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ - -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ - -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ + -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ + -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ + -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ + -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \ + -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - < $(srcdir)/string.in.h; \ - } > $@-t && \ - mv $@-t $@ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += string.h string.h-t EXTRA_DIST += string.in.h @@ -1694,54 +2222,33 @@ BUILT_SOURCES += strings.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_H)|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ - -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \ + -e 's/@''GNULIB_FFS''@/$(GL_GNULIB_FFS)/g' \ -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/strings.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/strings.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += strings.h strings.h-t EXTRA_DIST += strings.in.h ## end gnulib module strings -## begin gnulib module strndup - - -EXTRA_DIST += strndup.c - -EXTRA_libgnu_a_SOURCES += strndup.c - -## end gnulib module strndup - -## begin gnulib module strnlen - - -EXTRA_DIST += strnlen.c - -EXTRA_libgnu_a_SOURCES += strnlen.c - -## end gnulib module strnlen - ## begin gnulib module strsep - -EXTRA_DIST += strsep.c - -EXTRA_libgnu_a_SOURCES += strsep.c +if GL_COND_OBJ_STRSEP +libgnu_a_SOURCES += strsep.c +endif ## end gnulib module strsep @@ -1762,31 +2269,30 @@ libgnu_a_SOURCES += sys_socket.c # We need the following in order to create when the system # doesn't have one that works with the given compiler. sys/socket.h: sys_socket.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) - $(AM_V_at)$(MKDIR_P) sys - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(AM_V_GEN)$(MKDIR_P) '%reldir%/sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_SOCKET_H''@|$(NEXT_SYS_SOCKET_H)|g' \ -e 's|@''HAVE_SYS_SOCKET_H''@|$(HAVE_SYS_SOCKET_H)|g' \ - -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ - -e 's/@''GNULIB_SOCKET''@/$(GNULIB_SOCKET)/g' \ - -e 's/@''GNULIB_CONNECT''@/$(GNULIB_CONNECT)/g' \ - -e 's/@''GNULIB_ACCEPT''@/$(GNULIB_ACCEPT)/g' \ - -e 's/@''GNULIB_BIND''@/$(GNULIB_BIND)/g' \ - -e 's/@''GNULIB_GETPEERNAME''@/$(GNULIB_GETPEERNAME)/g' \ - -e 's/@''GNULIB_GETSOCKNAME''@/$(GNULIB_GETSOCKNAME)/g' \ - -e 's/@''GNULIB_GETSOCKOPT''@/$(GNULIB_GETSOCKOPT)/g' \ - -e 's/@''GNULIB_LISTEN''@/$(GNULIB_LISTEN)/g' \ - -e 's/@''GNULIB_RECV''@/$(GNULIB_RECV)/g' \ - -e 's/@''GNULIB_SEND''@/$(GNULIB_SEND)/g' \ - -e 's/@''GNULIB_RECVFROM''@/$(GNULIB_RECVFROM)/g' \ - -e 's/@''GNULIB_SENDTO''@/$(GNULIB_SENDTO)/g' \ - -e 's/@''GNULIB_SETSOCKOPT''@/$(GNULIB_SETSOCKOPT)/g' \ - -e 's/@''GNULIB_SHUTDOWN''@/$(GNULIB_SHUTDOWN)/g' \ - -e 's/@''GNULIB_ACCEPT4''@/$(GNULIB_ACCEPT4)/g' \ + -e 's/@''GNULIB_CLOSE''@/$(GL_GNULIB_CLOSE)/g' \ + -e 's/@''GNULIB_SOCKET''@/$(GL_GNULIB_SOCKET)/g' \ + -e 's/@''GNULIB_CONNECT''@/$(GL_GNULIB_CONNECT)/g' \ + -e 's/@''GNULIB_ACCEPT''@/$(GL_GNULIB_ACCEPT)/g' \ + -e 's/@''GNULIB_BIND''@/$(GL_GNULIB_BIND)/g' \ + -e 's/@''GNULIB_GETPEERNAME''@/$(GL_GNULIB_GETPEERNAME)/g' \ + -e 's/@''GNULIB_GETSOCKNAME''@/$(GL_GNULIB_GETSOCKNAME)/g' \ + -e 's/@''GNULIB_GETSOCKOPT''@/$(GL_GNULIB_GETSOCKOPT)/g' \ + -e 's/@''GNULIB_LISTEN''@/$(GL_GNULIB_LISTEN)/g' \ + -e 's/@''GNULIB_RECV''@/$(GL_GNULIB_RECV)/g' \ + -e 's/@''GNULIB_SEND''@/$(GL_GNULIB_SEND)/g' \ + -e 's/@''GNULIB_RECVFROM''@/$(GL_GNULIB_RECVFROM)/g' \ + -e 's/@''GNULIB_SENDTO''@/$(GL_GNULIB_SENDTO)/g' \ + -e 's/@''GNULIB_SETSOCKOPT''@/$(GL_GNULIB_SETSOCKOPT)/g' \ + -e 's/@''GNULIB_SHUTDOWN''@/$(GL_GNULIB_SHUTDOWN)/g' \ + -e 's/@''GNULIB_ACCEPT4''@/$(GL_GNULIB_ACCEPT4)/g' \ -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ -e 's|@''HAVE_WS2TCPIP_H''@|$(HAVE_WS2TCPIP_H)|g' \ -e 's|@''HAVE_STRUCT_SOCKADDR_STORAGE''@|$(HAVE_STRUCT_SOCKADDR_STORAGE)|g' \ @@ -1796,9 +2302,8 @@ sys/socket.h: sys_socket.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/sys_socket.in.h; \ - } > $@-t && \ - mv -f $@-t $@ + $(srcdir)/sys_socket.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += sys/socket.h sys/socket.h-t MOSTLYCLEANDIRS += sys @@ -1806,6 +2311,79 @@ EXTRA_DIST += sys_socket.in.h ## end gnulib module sys_socket +## begin gnulib module sys_stat + +BUILT_SOURCES += sys/stat.h + +# We need the following in order to create when the system +# has one that is incomplete. +sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) '%reldir%/sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ + -e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \ + -e 's|@''WINDOWS_STAT_TIMESPEC''@|$(WINDOWS_STAT_TIMESPEC)|g' \ + -e 's/@''GNULIB_CHMOD''@/$(GL_GNULIB_CHMOD)/g' \ + -e 's/@''GNULIB_FCHMODAT''@/$(GL_GNULIB_FCHMODAT)/g' \ + -e 's/@''GNULIB_FSTAT''@/$(GL_GNULIB_FSTAT)/g' \ + -e 's/@''GNULIB_FSTATAT''@/$(GL_GNULIB_FSTATAT)/g' \ + -e 's/@''GNULIB_FUTIMENS''@/$(GL_GNULIB_FUTIMENS)/g' \ + -e 's/@''GNULIB_GETUMASK''@/$(GL_GNULIB_GETUMASK)/g' \ + -e 's/@''GNULIB_LCHMOD''@/$(GL_GNULIB_LCHMOD)/g' \ + -e 's/@''GNULIB_LSTAT''@/$(GL_GNULIB_LSTAT)/g' \ + -e 's/@''GNULIB_MKDIR''@/$(GL_GNULIB_MKDIR)/g' \ + -e 's/@''GNULIB_MKDIRAT''@/$(GL_GNULIB_MKDIRAT)/g' \ + -e 's/@''GNULIB_MKFIFO''@/$(GL_GNULIB_MKFIFO)/g' \ + -e 's/@''GNULIB_MKFIFOAT''@/$(GL_GNULIB_MKFIFOAT)/g' \ + -e 's/@''GNULIB_MKNOD''@/$(GL_GNULIB_MKNOD)/g' \ + -e 's/@''GNULIB_MKNODAT''@/$(GL_GNULIB_MKNODAT)/g' \ + -e 's/@''GNULIB_STAT''@/$(GL_GNULIB_STAT)/g' \ + -e 's/@''GNULIB_UTIMENSAT''@/$(GL_GNULIB_UTIMENSAT)/g' \ + -e 's/@''GNULIB_OVERRIDES_STRUCT_STAT''@/$(GL_GNULIB_OVERRIDES_STRUCT_STAT)/g' \ + -e 's/@''GNULIB_MDA_CHMOD''@/$(GL_GNULIB_MDA_CHMOD)/g' \ + -e 's/@''GNULIB_MDA_MKDIR''@/$(GL_GNULIB_MDA_MKDIR)/g' \ + -e 's/@''GNULIB_MDA_UMASK''@/$(GL_GNULIB_MDA_UMASK)/g' \ + -e 's|@''HAVE_FCHMODAT''@|$(HAVE_FCHMODAT)|g' \ + -e 's|@''HAVE_FSTATAT''@|$(HAVE_FSTATAT)|g' \ + -e 's|@''HAVE_FUTIMENS''@|$(HAVE_FUTIMENS)|g' \ + -e 's|@''HAVE_GETUMASK''@|$(HAVE_GETUMASK)|g' \ + -e 's|@''HAVE_LCHMOD''@|$(HAVE_LCHMOD)|g' \ + -e 's|@''HAVE_LSTAT''@|$(HAVE_LSTAT)|g' \ + -e 's|@''HAVE_MKDIRAT''@|$(HAVE_MKDIRAT)|g' \ + -e 's|@''HAVE_MKFIFO''@|$(HAVE_MKFIFO)|g' \ + -e 's|@''HAVE_MKFIFOAT''@|$(HAVE_MKFIFOAT)|g' \ + -e 's|@''HAVE_MKNOD''@|$(HAVE_MKNOD)|g' \ + -e 's|@''HAVE_MKNODAT''@|$(HAVE_MKNODAT)|g' \ + -e 's|@''HAVE_UTIMENSAT''@|$(HAVE_UTIMENSAT)|g' \ + -e 's|@''REPLACE_CHMOD''@|$(REPLACE_CHMOD)|g' \ + -e 's|@''REPLACE_FCHMODAT''@|$(REPLACE_FCHMODAT)|g' \ + -e 's|@''REPLACE_FSTAT''@|$(REPLACE_FSTAT)|g' \ + -e 's|@''REPLACE_FSTATAT''@|$(REPLACE_FSTATAT)|g' \ + -e 's|@''REPLACE_FUTIMENS''@|$(REPLACE_FUTIMENS)|g' \ + -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)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_stat.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/stat.h sys/stat.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_stat.in.h + +## end gnulib module sys_stat + ## begin gnulib module sys_types BUILT_SOURCES += sys/types.h @@ -1813,18 +2391,17 @@ BUILT_SOURCES += sys/types.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. sys/types.h: sys_types.in.h $(top_builddir)/config.status - $(AM_V_at)$(MKDIR_P) sys - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(AM_V_GEN)$(MKDIR_P) '%reldir%/sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ - < $(srcdir)/sys_types.in.h; \ - } > $@-t && \ - mv $@-t $@ + -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \ + $(srcdir)/sys_types.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += sys/types.h sys/types.h-t EXTRA_DIST += sys_types.in.h @@ -1838,18 +2415,16 @@ BUILT_SOURCES += sys/uio.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. sys/uio.h: sys_uio.in.h $(top_builddir)/config.status - $(AM_V_at)$(MKDIR_P) sys - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(AM_V_GEN)$(MKDIR_P) '%reldir%/sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_UIO_H''@|$(NEXT_SYS_UIO_H)|g' \ -e 's|@''HAVE_SYS_UIO_H''@|$(HAVE_SYS_UIO_H)|g' \ - < $(srcdir)/sys_uio.in.h; \ - } > $@-t && \ - mv -f $@-t $@ + $(srcdir)/sys_uio.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += sys/uio.h sys/uio.h-t MOSTLYCLEANDIRS += sys @@ -1861,8 +2436,6 @@ EXTRA_DIST += sys_uio.in.h libgnu_a_SOURCES += glthread/threadlib.c -EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath - ## end gnulib module threadlib ## begin gnulib module time @@ -1872,35 +2445,51 @@ BUILT_SOURCES += time.h # We need the following in order to create when the system # doesn't have one that works with the given compiler. time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ - -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \ - -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \ - -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ - -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ - -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ + -e 's/@''GNULIB_CTIME''@/$(GL_GNULIB_CTIME)/g' \ + -e 's/@''GNULIB_LOCALTIME''@/$(GL_GNULIB_LOCALTIME)/g' \ + -e 's/@''GNULIB_MKTIME''@/$(GL_GNULIB_MKTIME)/g' \ + -e 's/@''GNULIB_NANOSLEEP''@/$(GL_GNULIB_NANOSLEEP)/g' \ + -e 's/@''GNULIB_STRFTIME''@/$(GL_GNULIB_STRFTIME)/g' \ + -e 's/@''GNULIB_STRPTIME''@/$(GL_GNULIB_STRPTIME)/g' \ + -e 's/@''GNULIB_TIMEGM''@/$(GL_GNULIB_TIMEGM)/g' \ + -e 's/@''GNULIB_TIMESPEC_GET''@/$(GL_GNULIB_TIMESPEC_GET)/g' \ + -e 's/@''GNULIB_TIMESPEC_GETRES''@/$(GL_GNULIB_TIMESPEC_GETRES)/g' \ + -e 's/@''GNULIB_TIME_R''@/$(GL_GNULIB_TIME_R)/g' \ + -e 's/@''GNULIB_TIME_RZ''@/$(GL_GNULIB_TIME_RZ)/g' \ + -e 's/@''GNULIB_TZSET''@/$(GL_GNULIB_TZSET)/g' \ + -e 's/@''GNULIB_MDA_TZSET''@/$(GL_GNULIB_MDA_TZSET)/g' \ -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ -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_TIMESPEC_GETRES''@|$(HAVE_TIMESPEC_GETRES)|g' \ + -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ + -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ + -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ + -e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \ -e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ -e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \ -e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ + -e 's|@''REPLACE_STRFTIME''@|$(REPLACE_STRFTIME)|g' \ -e 's|@''REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \ + -e 's|@''REPLACE_TZSET''@|$(REPLACE_TZSET)|g' \ -e 's|@''PTHREAD_H_DEFINES_STRUCT_TIMESPEC''@|$(PTHREAD_H_DEFINES_STRUCT_TIMESPEC)|g' \ -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)' \ - < $(srcdir)/time.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/time.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += time.h time.h-t EXTRA_DIST += time.in.h @@ -1909,19 +2498,19 @@ EXTRA_DIST += time.in.h ## begin gnulib module time_r - -EXTRA_DIST += time_r.c - -EXTRA_libgnu_a_SOURCES += time_r.c +if GL_COND_OBJ_TIME_R +libgnu_a_SOURCES += time_r.c +endif ## end gnulib module time_r ## begin gnulib module timegm +if GL_COND_OBJ_TIMEGM +libgnu_a_SOURCES += timegm.c +endif -EXTRA_DIST += mktime-internal.h timegm.c - -EXTRA_libgnu_a_SOURCES += timegm.c +EXTRA_DIST += mktime-internal.h ## end gnulib module timegm @@ -1933,69 +2522,104 @@ libgnu_a_SOURCES += unistd.c # We need the following in order to create an empty placeholder for # when the system doesn't have one. unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ - -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ - -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ - -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ - -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \ - -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ - -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ - -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ - -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ - -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ - -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ - -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ - -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \ - -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ - -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ - -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ - -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ - -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ - -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ - -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ - -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ - -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \ - -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \ - -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \ - -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \ - -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \ - -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \ - -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \ - -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \ - -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \ - -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \ - -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \ - -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \ - -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \ - -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \ - -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \ - -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \ - -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \ - -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \ - -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ - -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ - -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ - -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ - -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \ - -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ - -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \ - -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \ - -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ - -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ - -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ + -e 's/@''GNULIB_ACCESS''@/$(GL_GNULIB_ACCESS)/g' \ + -e 's/@''GNULIB_CHDIR''@/$(GL_GNULIB_CHDIR)/g' \ + -e 's/@''GNULIB_CHOWN''@/$(GL_GNULIB_CHOWN)/g' \ + -e 's/@''GNULIB_CLOSE''@/$(GL_GNULIB_CLOSE)/g' \ + -e 's/@''GNULIB_COPY_FILE_RANGE''@/$(GL_GNULIB_COPY_FILE_RANGE)/g' \ + -e 's/@''GNULIB_DUP''@/$(GL_GNULIB_DUP)/g' \ + -e 's/@''GNULIB_DUP2''@/$(GL_GNULIB_DUP2)/g' \ + -e 's/@''GNULIB_DUP3''@/$(GL_GNULIB_DUP3)/g' \ + -e 's/@''GNULIB_ENVIRON''@/$(GL_GNULIB_ENVIRON)/g' \ + -e 's/@''GNULIB_EUIDACCESS''@/$(GL_GNULIB_EUIDACCESS)/g' \ + -e 's/@''GNULIB_EXECL''@/$(GL_GNULIB_EXECL)/g' \ + -e 's/@''GNULIB_EXECLE''@/$(GL_GNULIB_EXECLE)/g' \ + -e 's/@''GNULIB_EXECLP''@/$(GL_GNULIB_EXECLP)/g' \ + -e 's/@''GNULIB_EXECV''@/$(GL_GNULIB_EXECV)/g' \ + -e 's/@''GNULIB_EXECVE''@/$(GL_GNULIB_EXECVE)/g' \ + -e 's/@''GNULIB_EXECVP''@/$(GL_GNULIB_EXECVP)/g' \ + -e 's/@''GNULIB_EXECVPE''@/$(GL_GNULIB_EXECVPE)/g' \ + -e 's/@''GNULIB_FACCESSAT''@/$(GL_GNULIB_FACCESSAT)/g' \ + -e 's/@''GNULIB_FCHDIR''@/$(GL_GNULIB_FCHDIR)/g' \ + -e 's/@''GNULIB_FCHOWNAT''@/$(GL_GNULIB_FCHOWNAT)/g' \ + -e 's/@''GNULIB_FDATASYNC''@/$(GL_GNULIB_FDATASYNC)/g' \ + -e 's/@''GNULIB_FSYNC''@/$(GL_GNULIB_FSYNC)/g' \ + -e 's/@''GNULIB_FTRUNCATE''@/$(GL_GNULIB_FTRUNCATE)/g' \ + -e 's/@''GNULIB_GETCWD''@/$(GL_GNULIB_GETCWD)/g' \ + -e 's/@''GNULIB_GETDOMAINNAME''@/$(GL_GNULIB_GETDOMAINNAME)/g' \ + -e 's/@''GNULIB_GETDTABLESIZE''@/$(GL_GNULIB_GETDTABLESIZE)/g' \ + -e 's/@''GNULIB_GETENTROPY''@/$(GL_GNULIB_GETENTROPY)/g' \ + -e 's/@''GNULIB_GETGROUPS''@/$(GL_GNULIB_GETGROUPS)/g' \ + -e 's/@''GNULIB_GETHOSTNAME''@/$(GL_GNULIB_GETHOSTNAME)/g' \ + -e 's/@''GNULIB_GETLOGIN''@/$(GL_GNULIB_GETLOGIN)/g' \ + -e 's/@''GNULIB_GETLOGIN_R''@/$(GL_GNULIB_GETLOGIN_R)/g' \ + -e 's/@''GNULIB_GETOPT_POSIX''@/$(GL_GNULIB_GETOPT_POSIX)/g' \ + -e 's/@''GNULIB_GETPAGESIZE''@/$(GL_GNULIB_GETPAGESIZE)/g' \ + -e 's/@''GNULIB_GETPASS''@/$(GL_GNULIB_GETPASS)/g' \ + -e 's/@''GNULIB_GETPASS_GNU''@/$(GL_GNULIB_GETPASS_GNU)/g' \ + -e 's/@''GNULIB_GETUSERSHELL''@/$(GL_GNULIB_GETUSERSHELL)/g' \ + -e 's/@''GNULIB_GROUP_MEMBER''@/$(GL_GNULIB_GROUP_MEMBER)/g' \ + -e 's/@''GNULIB_ISATTY''@/$(GL_GNULIB_ISATTY)/g' \ + -e 's/@''GNULIB_LCHOWN''@/$(GL_GNULIB_LCHOWN)/g' \ + -e 's/@''GNULIB_LINK''@/$(GL_GNULIB_LINK)/g' \ + -e 's/@''GNULIB_LINKAT''@/$(GL_GNULIB_LINKAT)/g' \ + -e 's/@''GNULIB_LSEEK''@/$(GL_GNULIB_LSEEK)/g' \ + -e 's/@''GNULIB_PIPE''@/$(GL_GNULIB_PIPE)/g' \ + -e 's/@''GNULIB_PIPE2''@/$(GL_GNULIB_PIPE2)/g' \ + -e 's/@''GNULIB_PREAD''@/$(GL_GNULIB_PREAD)/g' \ + -e 's/@''GNULIB_PWRITE''@/$(GL_GNULIB_PWRITE)/g' \ + -e 's/@''GNULIB_READ''@/$(GL_GNULIB_READ)/g' \ + -e 's/@''GNULIB_READLINK''@/$(GL_GNULIB_READLINK)/g' \ + -e 's/@''GNULIB_READLINKAT''@/$(GL_GNULIB_READLINKAT)/g' \ + -e 's/@''GNULIB_RMDIR''@/$(GL_GNULIB_RMDIR)/g' \ + -e 's/@''GNULIB_SETHOSTNAME''@/$(GL_GNULIB_SETHOSTNAME)/g' \ + -e 's/@''GNULIB_SLEEP''@/$(GL_GNULIB_SLEEP)/g' \ + -e 's/@''GNULIB_SYMLINK''@/$(GL_GNULIB_SYMLINK)/g' \ + -e 's/@''GNULIB_SYMLINKAT''@/$(GL_GNULIB_SYMLINKAT)/g' \ + -e 's/@''GNULIB_TRUNCATE''@/$(GL_GNULIB_TRUNCATE)/g' \ + -e 's/@''GNULIB_TTYNAME_R''@/$(GL_GNULIB_TTYNAME_R)/g' \ + -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GL_GNULIB_UNISTD_H_GETOPT)/g' \ + -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GL_GNULIB_UNISTD_H_NONBLOCKING)/g' \ + -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GL_GNULIB_UNISTD_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_UNLINK''@/$(GL_GNULIB_UNLINK)/g' \ + -e 's/@''GNULIB_UNLINKAT''@/$(GL_GNULIB_UNLINKAT)/g' \ + -e 's/@''GNULIB_USLEEP''@/$(GL_GNULIB_USLEEP)/g' \ + -e 's/@''GNULIB_WRITE''@/$(GL_GNULIB_WRITE)/g' \ + -e 's/@''GNULIB_MDA_ACCESS''@/$(GL_GNULIB_MDA_ACCESS)/g' \ + -e 's/@''GNULIB_MDA_CHDIR''@/$(GL_GNULIB_MDA_CHDIR)/g' \ + -e 's/@''GNULIB_MDA_CLOSE''@/$(GL_GNULIB_MDA_CLOSE)/g' \ + -e 's/@''GNULIB_MDA_DUP''@/$(GL_GNULIB_MDA_DUP)/g' \ + -e 's/@''GNULIB_MDA_DUP2''@/$(GL_GNULIB_MDA_DUP2)/g' \ + -e 's/@''GNULIB_MDA_EXECL''@/$(GL_GNULIB_MDA_EXECL)/g' \ + -e 's/@''GNULIB_MDA_EXECLE''@/$(GL_GNULIB_MDA_EXECLE)/g' \ + -e 's/@''GNULIB_MDA_EXECLP''@/$(GL_GNULIB_MDA_EXECLP)/g' \ + -e 's/@''GNULIB_MDA_EXECV''@/$(GL_GNULIB_MDA_EXECV)/g' \ + -e 's/@''GNULIB_MDA_EXECVE''@/$(GL_GNULIB_MDA_EXECVE)/g' \ + -e 's/@''GNULIB_MDA_EXECVP''@/$(GL_GNULIB_MDA_EXECVP)/g' \ + -e 's/@''GNULIB_MDA_EXECVPE''@/$(GL_GNULIB_MDA_EXECVPE)/g' \ + -e 's/@''GNULIB_MDA_GETCWD''@/$(GL_GNULIB_MDA_GETCWD)/g' \ + -e 's/@''GNULIB_MDA_GETPID''@/$(GL_GNULIB_MDA_GETPID)/g' \ + -e 's/@''GNULIB_MDA_ISATTY''@/$(GL_GNULIB_MDA_ISATTY)/g' \ + -e 's/@''GNULIB_MDA_LSEEK''@/$(GL_GNULIB_MDA_LSEEK)/g' \ + -e 's/@''GNULIB_MDA_READ''@/$(GL_GNULIB_MDA_READ)/g' \ + -e 's/@''GNULIB_MDA_RMDIR''@/$(GL_GNULIB_MDA_RMDIR)/g' \ + -e 's/@''GNULIB_MDA_SWAB''@/$(GL_GNULIB_MDA_SWAB)/g' \ + -e 's/@''GNULIB_MDA_UNLINK''@/$(GL_GNULIB_MDA_UNLINK)/g' \ + -e 's/@''GNULIB_MDA_WRITE''@/$(GL_GNULIB_MDA_WRITE)/g' \ < $(srcdir)/unistd.in.h | \ sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ - -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ + -e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \ -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \ + -e 's|@''HAVE_EXECVPE''@|$(HAVE_EXECVPE)|g' \ -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \ @@ -2003,10 +2627,11 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ + -e 's|@''HAVE_GETENTROPY''@|$(HAVE_GETENTROPY)|g' \ -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ - -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \ -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ + -e 's|@''HAVE_GETPASS''@|$(HAVE_GETPASS)|g' \ -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \ -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \ -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \ @@ -2024,28 +2649,44 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \ -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \ -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \ + -e 's|@''HAVE_DECL_EXECVPE''@|$(HAVE_DECL_EXECVPE)|g' \ -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \ -e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \ -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \ + -e 's|@''HAVE_DECL_GETLOGIN''@|$(HAVE_DECL_GETLOGIN)|g' \ -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \ -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \ -e 's|@''HAVE_DECL_SETHOSTNAME''@|$(HAVE_DECL_SETHOSTNAME)|g' \ + -e 's|@''HAVE_DECL_TRUNCATE''@|$(HAVE_DECL_TRUNCATE)|g' \ -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \ -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \ -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ | \ - sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ + sed -e 's|@''REPLACE_ACCESS''@|$(REPLACE_ACCESS)|g' \ + -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ + -e 's|@''REPLACE_COPY_FILE_RANGE''@|$(REPLACE_COPY_FILE_RANGE)|g' \ -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ + -e 's|@''REPLACE_EXECL''@|$(REPLACE_EXECL)|g' \ + -e 's|@''REPLACE_EXECLE''@|$(REPLACE_EXECLE)|g' \ + -e 's|@''REPLACE_EXECLP''@|$(REPLACE_EXECLP)|g' \ + -e 's|@''REPLACE_EXECV''@|$(REPLACE_EXECV)|g' \ + -e 's|@''REPLACE_EXECVE''@|$(REPLACE_EXECVE)|g' \ + -e 's|@''REPLACE_EXECVP''@|$(REPLACE_EXECVP)|g' \ + -e 's|@''REPLACE_EXECVPE''@|$(REPLACE_EXECVPE)|g' \ + -e 's|@''REPLACE_FACCESSAT''@|$(REPLACE_FACCESSAT)|g' \ -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ + -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ + -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \ + -e 's|@''REPLACE_GETPASS_FOR_GETPASS_GNU''@|$(REPLACE_GETPASS_FOR_GETPASS_GNU)|g' \ -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \ -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ @@ -2055,33 +2696,43 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \ -e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \ -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \ + -e 's|@''REPLACE_READLINKAT''@|$(REPLACE_READLINKAT)|g' \ -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \ + -e 's|@''REPLACE_SYMLINKAT''@|$(REPLACE_SYMLINKAT)|g' \ + -e 's|@''REPLACE_TRUNCATE''@|$(REPLACE_TRUNCATE)|g' \ -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \ -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \ -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \ -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \ -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \ + -e 's|@''UNISTD_H_HAVE_SYS_RANDOM_H''@|$(UNISTD_H_HAVE_SYS_RANDOM_H)|g' \ -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \ -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += unistd.h unistd.h-t EXTRA_DIST += unistd.in.h ## end gnulib module unistd -## begin gnulib module unsetenv +## begin gnulib module unlocked-io-internal -EXTRA_DIST += unsetenv.c +EXTRA_DIST += unlocked-io.h + +## end gnulib module unlocked-io-internal + +## begin gnulib module unsetenv -EXTRA_libgnu_a_SOURCES += unsetenv.c +if GL_COND_OBJ_UNSETENV +libgnu_a_SOURCES += unsetenv.c +endif ## end gnulib module unsetenv @@ -2126,54 +2777,59 @@ BUILT_SOURCES += wchar.h # We need the following in order to create when the system # version does not work standalone. wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ - -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ - -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ - -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ - -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ - -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ - -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ - -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ - -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ - -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ - -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ - -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ - -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ - -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ - -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ - -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ - -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ - -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ - -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ - -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ - -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ - -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ - -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ - -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ - -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ - -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ - -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ - -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ - -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ - -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ - -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ - -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ - -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ - -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ - -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ - -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ - -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ - -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ - -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ - -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ + -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \ + -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \ + -e 's/@''GNULIB_BTOWC''@/$(GL_GNULIB_BTOWC)/g' \ + -e 's/@''GNULIB_WCTOB''@/$(GL_GNULIB_WCTOB)/g' \ + -e 's/@''GNULIB_MBSINIT''@/$(GL_GNULIB_MBSINIT)/g' \ + -e 's/@''GNULIB_MBRTOWC''@/$(GL_GNULIB_MBRTOWC)/g' \ + -e 's/@''GNULIB_MBRLEN''@/$(GL_GNULIB_MBRLEN)/g' \ + -e 's/@''GNULIB_MBSRTOWCS''@/$(GL_GNULIB_MBSRTOWCS)/g' \ + -e 's/@''GNULIB_MBSNRTOWCS''@/$(GL_GNULIB_MBSNRTOWCS)/g' \ + -e 's/@''GNULIB_WCRTOMB''@/$(GL_GNULIB_WCRTOMB)/g' \ + -e 's/@''GNULIB_WCSRTOMBS''@/$(GL_GNULIB_WCSRTOMBS)/g' \ + -e 's/@''GNULIB_WCSNRTOMBS''@/$(GL_GNULIB_WCSNRTOMBS)/g' \ + -e 's/@''GNULIB_WCWIDTH''@/$(GL_GNULIB_WCWIDTH)/g' \ + -e 's/@''GNULIB_WMEMCHR''@/$(GL_GNULIB_WMEMCHR)/g' \ + -e 's/@''GNULIB_WMEMCMP''@/$(GL_GNULIB_WMEMCMP)/g' \ + -e 's/@''GNULIB_WMEMCPY''@/$(GL_GNULIB_WMEMCPY)/g' \ + -e 's/@''GNULIB_WMEMMOVE''@/$(GL_GNULIB_WMEMMOVE)/g' \ + -e 's/@''GNULIB_WMEMPCPY''@/$(GL_GNULIB_WMEMPCPY)/g' \ + -e 's/@''GNULIB_WMEMSET''@/$(GL_GNULIB_WMEMSET)/g' \ + -e 's/@''GNULIB_WCSLEN''@/$(GL_GNULIB_WCSLEN)/g' \ + -e 's/@''GNULIB_WCSNLEN''@/$(GL_GNULIB_WCSNLEN)/g' \ + -e 's/@''GNULIB_WCSCPY''@/$(GL_GNULIB_WCSCPY)/g' \ + -e 's/@''GNULIB_WCPCPY''@/$(GL_GNULIB_WCPCPY)/g' \ + -e 's/@''GNULIB_WCSNCPY''@/$(GL_GNULIB_WCSNCPY)/g' \ + -e 's/@''GNULIB_WCPNCPY''@/$(GL_GNULIB_WCPNCPY)/g' \ + -e 's/@''GNULIB_WCSCAT''@/$(GL_GNULIB_WCSCAT)/g' \ + -e 's/@''GNULIB_WCSNCAT''@/$(GL_GNULIB_WCSNCAT)/g' \ + -e 's/@''GNULIB_WCSCMP''@/$(GL_GNULIB_WCSCMP)/g' \ + -e 's/@''GNULIB_WCSNCMP''@/$(GL_GNULIB_WCSNCMP)/g' \ + -e 's/@''GNULIB_WCSCASECMP''@/$(GL_GNULIB_WCSCASECMP)/g' \ + -e 's/@''GNULIB_WCSNCASECMP''@/$(GL_GNULIB_WCSNCASECMP)/g' \ + -e 's/@''GNULIB_WCSCOLL''@/$(GL_GNULIB_WCSCOLL)/g' \ + -e 's/@''GNULIB_WCSXFRM''@/$(GL_GNULIB_WCSXFRM)/g' \ + -e 's/@''GNULIB_WCSDUP''@/$(GL_GNULIB_WCSDUP)/g' \ + -e 's/@''GNULIB_WCSCHR''@/$(GL_GNULIB_WCSCHR)/g' \ + -e 's/@''GNULIB_WCSRCHR''@/$(GL_GNULIB_WCSRCHR)/g' \ + -e 's/@''GNULIB_WCSCSPN''@/$(GL_GNULIB_WCSCSPN)/g' \ + -e 's/@''GNULIB_WCSSPN''@/$(GL_GNULIB_WCSSPN)/g' \ + -e 's/@''GNULIB_WCSPBRK''@/$(GL_GNULIB_WCSPBRK)/g' \ + -e 's/@''GNULIB_WCSSTR''@/$(GL_GNULIB_WCSSTR)/g' \ + -e 's/@''GNULIB_WCSTOK''@/$(GL_GNULIB_WCSTOK)/g' \ + -e 's/@''GNULIB_WCSWIDTH''@/$(GL_GNULIB_WCSWIDTH)/g' \ + -e 's/@''GNULIB_WCSFTIME''@/$(GL_GNULIB_WCSFTIME)/g' \ + -e 's/@''GNULIB_MDA_WCSDUP''@/$(GL_GNULIB_MDA_WCSDUP)/g' \ + -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \ < $(srcdir)/wchar.in.h | \ sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ @@ -2189,6 +2845,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''HAVE_WMEMCMP''@|$(HAVE_WMEMCMP)|g' \ -e 's|@''HAVE_WMEMCPY''@|$(HAVE_WMEMCPY)|g' \ -e 's|@''HAVE_WMEMMOVE''@|$(HAVE_WMEMMOVE)|g' \ + -e 's|@''HAVE_WMEMPCPY''@|$(HAVE_WMEMPCPY)|g' \ -e 's|@''HAVE_WMEMSET''@|$(HAVE_WMEMSET)|g' \ -e 's|@''HAVE_WCSLEN''@|$(HAVE_WCSLEN)|g' \ -e 's|@''HAVE_WCSNLEN''@|$(HAVE_WCSNLEN)|g' \ @@ -2213,12 +2870,15 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''HAVE_WCSSTR''@|$(HAVE_WCSSTR)|g' \ -e 's|@''HAVE_WCSTOK''@|$(HAVE_WCSTOK)|g' \ -e 's|@''HAVE_WCSWIDTH''@|$(HAVE_WCSWIDTH)|g' \ + -e 's|@''HAVE_WCSFTIME''@|$(HAVE_WCSFTIME)|g' \ -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \ + -e 's|@''HAVE_DECL_WCSDUP''@|$(HAVE_DECL_WCSDUP)|g' \ -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ | \ sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ + -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \ -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \ -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \ @@ -2229,11 +2889,13 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ + -e 's|@''REPLACE_WCSFTIME''@|$(REPLACE_WCSFTIME)|g' \ + -e 's|@''REPLACE_WCSTOK''@|$(REPLACE_WCSTOK)|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)'; \ - } > $@-t && \ - mv $@-t $@ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += wchar.h wchar.h-t EXTRA_DIST += wchar.in.h @@ -2242,10 +2904,9 @@ EXTRA_DIST += wchar.in.h ## begin gnulib module wcrtomb - -EXTRA_DIST += wcrtomb.c - -EXTRA_libgnu_a_SOURCES += wcrtomb.c +if GL_COND_OBJ_WCRTOMB +libgnu_a_SOURCES += wcrtomb.c +endif ## end gnulib module wcrtomb @@ -2257,38 +2918,82 @@ libgnu_a_SOURCES += wctype-h.c # We need the following in order to create when the system # doesn't have one that works with the given compiler. wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ - -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ - -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ - -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ - -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ - -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ + -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \ + -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \ + -e 's/@''GNULIB_ISWBLANK''@/$(GL_GNULIB_ISWBLANK)/g' \ + -e 's/@''GNULIB_ISWDIGIT''@/$(GL_GNULIB_ISWDIGIT)/g' \ + -e 's/@''GNULIB_ISWXDIGIT''@/$(GL_GNULIB_ISWXDIGIT)/g' \ + -e 's/@''GNULIB_WCTYPE''@/$(GL_GNULIB_WCTYPE)/g' \ + -e 's/@''GNULIB_ISWCTYPE''@/$(GL_GNULIB_ISWCTYPE)/g' \ + -e 's/@''GNULIB_WCTRANS''@/$(GL_GNULIB_WCTRANS)/g' \ + -e 's/@''GNULIB_TOWCTRANS''@/$(GL_GNULIB_TOWCTRANS)/g' \ -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \ -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ -e 's/@''HAVE_WCTYPE_T''@/$(HAVE_WCTYPE_T)/g' \ -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \ -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ + -e 's/@''REPLACE_ISWDIGIT''@/$(REPLACE_ISWDIGIT)/g' \ + -e 's/@''REPLACE_ISWXDIGIT''@/$(REPLACE_ISWXDIGIT)/g' \ -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/wctype.in.h; \ - } > $@-t && \ - mv $@-t $@ + $(srcdir)/wctype.in.h > $@-t + $(AM_V_at)mv $@-t $@ MOSTLYCLEANFILES += wctype.h wctype.h-t EXTRA_DIST += wctype.in.h ## end gnulib module wctype-h +## begin gnulib module windows-mutex + +if GL_COND_OBJ_WINDOWS_MUTEX +libgnu_a_SOURCES += windows-mutex.c +endif + +EXTRA_DIST += windows-initguard.h windows-mutex.h + +## end gnulib module windows-mutex + +## begin gnulib module windows-once + +if GL_COND_OBJ_WINDOWS_ONCE +libgnu_a_SOURCES += windows-once.c +endif + +EXTRA_DIST += windows-once.h + +## end gnulib module windows-once + +## begin gnulib module windows-recmutex + +if GL_COND_OBJ_WINDOWS_RECMUTEX +libgnu_a_SOURCES += windows-recmutex.c +endif + +EXTRA_DIST += windows-initguard.h windows-recmutex.h + +## end gnulib module windows-recmutex + +## begin gnulib module windows-rwlock + +if GL_COND_OBJ_WINDOWS_RWLOCK +libgnu_a_SOURCES += windows-rwlock.c +endif + +EXTRA_DIST += windows-initguard.h windows-rwlock.h + +## end gnulib module windows-rwlock + ## begin gnulib module xalloc libgnu_a_SOURCES += xmalloc.c @@ -2301,6 +3006,8 @@ EXTRA_DIST += xalloc.h libgnu_a_SOURCES += xalloc-die.c +EXTRA_DIST += xalloc.h + ## end gnulib module xalloc-die ## begin gnulib module xalloc-oversized @@ -2316,12 +3023,6 @@ libgnu_a_SOURCES += xsize.h xsize.c ## end gnulib module xsize -## begin gnulib module xstrndup - -libgnu_a_SOURCES += xstrndup.h xstrndup.c - -## end gnulib module xstrndup - mostlyclean-local: mostlyclean-generic @for dir in '' $(MOSTLYCLEANDIRS); do \ @@ -2330,3 +3031,7 @@ mostlyclean-local: mostlyclean-generic fi; \ done; \ : +distclean-local: distclean-gnulib-libobjs +distclean-gnulib-libobjs: + -rm -f @gl_LIBOBJDEPS@ +maintainer-clean-local: distclean-gnulib-libobjs diff --git a/gl/_Noreturn.h b/gl/_Noreturn.h new file mode 100644 index 00000000..e914627a --- /dev/null +++ b/gl/_Noreturn.h @@ -0,0 +1,45 @@ +/* A C macro for declaring that a function does not return. + Copyright (C) 2011-2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _Noreturn +# if (defined __cplusplus \ + && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + 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) \ + || (!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__) || defined __clang__ \ + || 0x5110 <= __SUNPRO_C) +# define _Noreturn __attribute__ ((__noreturn__)) +# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn +# endif +#endif diff --git a/gl/af_alg.c b/gl/af_alg.c new file mode 100644 index 00000000..084bff60 --- /dev/null +++ b/gl/af_alg.c @@ -0,0 +1,213 @@ +/* af_alg.c - Compute message digests from file streams and buffers. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Matteo Croce , 2018. */ + +#include + +#include "af_alg.h" + +#if USE_LINUX_CRYPTO_API + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sys-limits.h" + +#define BLOCKSIZE 32768 + +/* Return a newly created socket for ALG. + On error, return a negative error number. */ +static int +alg_socket (char const *alg) +{ + struct sockaddr_alg salg = { + .salg_family = AF_ALG, + .salg_type = "hash", + }; + /* Copy alg into salg.salg_name, without calling strcpy nor strlen. */ + for (size_t i = 0; (salg.salg_name[i] = alg[i]) != '\0'; i++) + if (i == sizeof salg.salg_name - 1) + /* alg is too long. */ + return -EINVAL; + + int cfd = socket (AF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0); + if (cfd < 0) + return -EAFNOSUPPORT; + int ofd = (bind (cfd, (struct sockaddr *) &salg, sizeof salg) == 0 + ? accept4 (cfd, NULL, 0, SOCK_CLOEXEC) + : -1); + close (cfd); + return ofd < 0 ? -EAFNOSUPPORT : ofd; +} + +int +afalg_buffer (const char *buffer, size_t len, const char *alg, + void *resblock, ssize_t hashlen) +{ + /* On Linux < 4.9, the value for an empty stream is wrong (all zeroes). + See . + This was not fixed properly until November 2016, + see . */ + if (len == 0) + return -EAFNOSUPPORT; + + int ofd = alg_socket (alg); + if (ofd < 0) + return ofd; + + int result; + + for (;;) + { + ssize_t size = (len > BLOCKSIZE ? BLOCKSIZE : len); + if (send (ofd, buffer, size, MSG_MORE) != size) + { + result = -EAFNOSUPPORT; + break; + } + buffer += size; + len -= size; + if (len == 0) + { + result = read (ofd, resblock, hashlen) == hashlen ? 0 : -EAFNOSUPPORT; + break; + } + } + + close (ofd); + return result; +} + +int +afalg_stream (FILE *stream, const char *alg, + void *resblock, ssize_t hashlen) +{ + int ofd = alg_socket (alg); + if (ofd < 0) + return ofd; + + /* If STREAM's size is known and nonzero and not too large, attempt + sendfile to pipe the data. The nonzero restriction avoids issues + with /proc files that pretend to be empty, and lets the classic + read-write loop work around an empty-input bug noted below. */ + int fd = fileno (stream); + int result; + struct stat st; + off_t off = ftello (stream); + if (0 <= off && fstat (fd, &st) == 0 + && (S_ISREG (st.st_mode) || S_TYPEISSHM (&st) || S_TYPEISTMO (&st)) + && off < st.st_size && st.st_size - off < SYS_BUFSIZE_MAX) + { + /* Make sure the offset of fileno (stream) reflects how many bytes + have been read from stream before this function got invoked. + Note: fflush on an input stream after ungetc does not work as expected + on some platforms. Therefore this situation is not supported here. */ + if (fflush (stream)) + result = -EIO; + else + { + off_t nbytes = st.st_size - off; + if (sendfile (ofd, fd, &off, nbytes) == nbytes) + { + if (read (ofd, resblock, hashlen) == hashlen) + { + /* The input buffers of stream are no longer valid. */ + if (lseek (fd, off, SEEK_SET) != (off_t)-1) + result = 0; + else + /* The file position of fd has not changed. */ + result = -EAFNOSUPPORT; + } + else + /* The file position of fd has not changed. */ + result = -EAFNOSUPPORT; + } + else + /* The file position of fd has not changed. */ + result = -EAFNOSUPPORT; + } + } + else + { + /* sendfile not possible, do a classic read-write loop. */ + + /* Number of bytes to seek (backwards) in case of error. */ + off_t nseek = 0; + + for (;;) + { + char buf[BLOCKSIZE]; + /* When the stream is not seekable, start with a single-byte block, + so that we can use ungetc() in the case that send() fails. */ + size_t blocksize = (nseek == 0 && off < 0 ? 1 : BLOCKSIZE); + ssize_t size = fread (buf, 1, blocksize, stream); + if (size == 0) + { + /* On Linux < 4.9, the value for an empty stream is wrong (all 0). + See . + This was not fixed properly until November 2016, + see . */ + result = ferror (stream) ? -EIO : nseek == 0 ? -EAFNOSUPPORT : 0; + break; + } + nseek -= size; + if (send (ofd, buf, size, MSG_MORE) != size) + { + if (nseek == -1) + { + /* 1 byte of pushback buffer is guaranteed on stream, even + if stream is not seekable. */ + ungetc ((unsigned char) buf[0], stream); + result = -EAFNOSUPPORT; + } + else if (fseeko (stream, nseek, SEEK_CUR) == 0) + /* The position of stream has been restored. */ + result = -EAFNOSUPPORT; + else + result = -EIO; + break; + } + + /* Don't assume that EOF is sticky. See: + . */ + if (feof (stream)) + { + result = 0; + break; + } + } + + if (result == 0 && read (ofd, resblock, hashlen) != hashlen) + { + if (nseek == 0 || fseeko (stream, nseek, SEEK_CUR) == 0) + /* The position of stream has been restored. */ + result = -EAFNOSUPPORT; + else + result = -EIO; + } + } + close (ofd); + return result; +} + +#endif diff --git a/gl/af_alg.h b/gl/af_alg.h new file mode 100644 index 00000000..ddd6568b --- /dev/null +++ b/gl/af_alg.h @@ -0,0 +1,115 @@ +/* af_alg.h - Compute message digests from file streams and buffers. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Matteo Croce , 2018. + Documentation by Bruno Haible , 2018. */ + +/* Declare specific functions for computing message digests + using the Linux kernel crypto API, if available. This kernel API gives + access to specialized crypto instructions (that would also be available + in user space) or to crypto devices (not directly available in user space). + + For a more complete set of facilities that use the Linux kernel crypto API, + look at libkcapi. */ + +#ifndef AF_ALG_H +# define AF_ALG_H 1 + +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# if USE_LINUX_CRYPTO_API + +/* Compute a message digest of a memory region. + + The memory region starts at BUFFER and is LEN bytes long. + + ALG is the message digest algorithm; see the file /proc/crypto. + + RESBLOCK points to a block of HASHLEN bytes, for the result. + HASHLEN must be the length of the message digest, in bytes, in particular: + + alg | hashlen + -------+-------- + md5 | 16 + sha1 | 20 + sha224 | 28 + sha256 | 32 + sha384 | 48 + sha512 | 64 + + If successful, fill RESBLOCK and return 0. + Upon failure, return a negated error number. */ +int +afalg_buffer (const char *buffer, size_t len, const char *alg, + void *resblock, ssize_t hashlen); + +/* Compute a message digest of data read from STREAM. + + STREAM is an open file stream. The last operation on STREAM should + not be 'ungetc', and if STREAM is also open for writing it should + have been fflushed since its last write. Read from the current + position to the end of STREAM. Handle regular files efficiently. + + ALG is the message digest algorithm; see the file /proc/crypto. + + RESBLOCK points to a block of HASHLEN bytes, for the result. + HASHLEN must be the length of the message digest, in bytes, in particular: + + alg | hashlen + -------+-------- + md5 | 16 + sha1 | 20 + sha224 | 28 + sha256 | 32 + sha384 | 48 + sha512 | 64 + + If successful, fill RESBLOCK and return 0. + Upon failure, return a negated error number. + Unless returning 0 or -EIO, restore STREAM's file position so that + the caller can fall back on some other method. */ +int +afalg_stream (FILE *stream, const char *alg, + void *resblock, ssize_t hashlen); + +# else + +static inline int +afalg_buffer (const char *buffer, size_t len, const char *alg, + void *resblock, ssize_t hashlen) +{ + return -EAFNOSUPPORT; +} + +static inline int +afalg_stream (FILE *stream, const char *alg, + void *resblock, ssize_t hashlen) +{ + return -EAFNOSUPPORT; +} + +# endif + +# ifdef __cplusplus +} +# endif + +#endif /* AF_ALG_H */ diff --git a/gl/alloca.in.h b/gl/alloca.in.h index 72d28ee3..e2b14613 100644 --- a/gl/alloca.in.h +++ b/gl/alloca.in.h @@ -1,22 +1,20 @@ /* Memory allocation on the stack. - Copyright (C) 1995, 1999, 2001-2004, 2006-2013 Free Software Foundation, + Copyright (C) 1995, 1999, 2001-2004, 2006-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser 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 - . - */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H means there is a real alloca function. */ @@ -35,7 +33,16 @@ */ #ifndef alloca -# ifdef __GNUC__ + /* Some version of mingw have an that causes trouble when + included after 'alloca' gets defined as a macro. As a workaround, + include this first and define 'alloca' as a macro afterwards + if needed. */ +# if defined __GNUC__ && (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@ +# include_next +# endif +#endif +#ifndef alloca +# if defined __GNUC__ || (__clang_major__ >= 4) # define alloca __builtin_alloca # elif defined _AIX # define alloca __alloca @@ -51,6 +58,8 @@ extern "C" void *_alloca (unsigned short); # pragma intrinsic (_alloca) # define alloca _alloca +# elif defined __MVS__ +# include # else # include # ifdef __cplusplus diff --git a/gl/arpa_inet.in.h b/gl/arpa_inet.in.h index ba89e977..f5d7db2d 100644 --- a/gl/arpa_inet.in.h +++ b/gl/arpa_inet.in.h @@ -1,19 +1,19 @@ /* A GNU-like . - Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_ARPA_INET_H @@ -49,6 +49,12 @@ #ifndef _@GUARD_PREFIX@_ARPA_INET_H #define _@GUARD_PREFIX@_ARPA_INET_H +/* Get all possible declarations of inet_ntop() and inet_pton(). */ +#if (@GNULIB_INET_NTOP@ || @GNULIB_INET_PTON@ || defined GNULIB_POSIXCHECK) \ + && @HAVE_WS2TCPIP_H@ +# include +#endif + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ /* The definition of _GL_ARG_NONNULL is copied here. */ @@ -70,8 +76,8 @@ the return value is NULL and errno is set to ENOSPC. A good value for CNT is 46. - For more details, see the POSIX:2001 specification - . */ + For more details, see the POSIX:2008 specification + . */ # if @REPLACE_INET_NTOP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef inet_ntop @@ -97,7 +103,9 @@ _GL_CXXALIAS_SYS_CAST (inet_ntop, const char *, (int af, const void *restrict src, char *restrict dst, socklen_t cnt)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (inet_ntop); +# endif #elif defined GNULIB_POSIXCHECK # undef inet_ntop # if HAVE_RAW_DECL_INET_NTOP @@ -126,7 +134,9 @@ _GL_FUNCDECL_SYS (inet_pton, int, _GL_CXXALIAS_SYS (inet_pton, int, (int af, const char *restrict src, void *restrict dst)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (inet_pton); +# endif #elif defined GNULIB_POSIXCHECK # undef inet_pton # if HAVE_RAW_DECL_INET_PTON diff --git a/gl/asnprintf.c b/gl/asnprintf.c index 76e228d8..0c5c76ea 100644 --- a/gl/asnprintf.c +++ b/gl/asnprintf.c @@ -1,18 +1,18 @@ /* Formatted output to strings. - Copyright (C) 1999, 2002, 2006, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/asprintf.c b/gl/asprintf.c index 713dae13..9c163f38 100644 --- a/gl/asprintf.c +++ b/gl/asprintf.c @@ -1,19 +1,19 @@ /* Formatted output to strings. - Copyright (C) 1999, 2002, 2006-2007, 2009-2013 Free Software Foundation, + Copyright (C) 1999, 2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/attribute.h b/gl/attribute.h new file mode 100644 index 00000000..378d4f0a --- /dev/null +++ b/gl/attribute.h @@ -0,0 +1,226 @@ +/* ATTRIBUTE_* macros for using attributes in GCC and similar compilers + + Copyright 2020-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert. */ + +/* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_* + macros used within Gnulib. */ + +/* These attributes can be placed in two ways: + - At the start of a declaration (i.e. even before storage-class + specifiers!); then they apply to all entities that are declared + by the declaration. + - Immediately after the name of an entity being declared by the + declaration; then they apply to that entity only. */ + +#ifndef _GL_ATTRIBUTE_H +#define _GL_ATTRIBUTE_H + + +/* This file defines two types of attributes: + * C2x standard attributes. These have macro names that do not begin with + 'ATTRIBUTE_'. + * Selected GCC attributes; see: + https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html + https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html + These names begin with 'ATTRIBUTE_' to avoid name clashes. */ + + +/* =============== Attributes for specific kinds of functions =============== */ + +/* Attributes for functions that should not be used. */ + +/* Warn if the entity is used. */ +/* Applies to: + - function, variable, + - struct, union, struct/union member, + - enumeration, enumeration item, + - typedef, + in C++ also: namespace, class, template specialization. */ +#define DEPRECATED _GL_ATTRIBUTE_DEPRECATED + +/* If a function call is not optimized way, warn with MSG. */ +/* Applies to: functions. */ +#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING (msg) + +/* If a function call is not optimized way, report an error with MSG. */ +/* Applies to: functions. */ +#define ATTRIBUTE_ERROR(msg) _GL_ATTRIBUTE_ERROR (msg) + + +/* Attributes for memory-allocating functions. */ + +/* The function returns a pointer to freshly allocated memory. */ +/* Applies to: functions. */ +#define ATTRIBUTE_MALLOC _GL_ATTRIBUTE_MALLOC + +/* ATTRIBUTE_ALLOC_SIZE ((N)) - The Nth argument of the function + is the size of the returned memory block. + ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments + to determine the size of the returned memory block. */ +/* Applies to: function, pointer to function, function types. */ +#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args) + +/* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers + that can be freed by passing them as the Ith argument to the + function F. + ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that + can be freed via 'free'; it can be used only after declaring 'free'. */ +/* Applies to: functions. Cannot be used on inline functions. */ +#define ATTRIBUTE_DEALLOC(f, i) _GL_ATTRIBUTE_DEALLOC(f, i) +#define ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC_FREE + +/* Attributes for variadic functions. */ + +/* The variadic function expects a trailing NULL argument. + ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99). + ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL. */ +/* Applies to: functions. */ +#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL (pos) + + +/* ================== Attributes for compiler diagnostics ================== */ + +/* Attributes that help the compiler diagnose programmer mistakes. + Some of them may also help for some compiler optimizations. */ + +/* ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)) - + The STRING-INDEXth function argument is a format string of style + ARCHETYPE, which is one of: + printf, gnu_printf + scanf, gnu_scanf, + strftime, gnu_strftime, + strfmon, + or the same thing prefixed and suffixed with '__'. + If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK + are suitable for the format string. */ +/* Applies to: functions. */ +#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT (spec) + +/* ATTRIBUTE_NONNULL ((N1, N2,...)) - Arguments N1, N2,... must not be NULL. + ATTRIBUTE_NONNULL () - All pointer arguments must not be null. */ +/* Applies to: functions. */ +#define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args) + +/* The function's return value is a non-NULL pointer. */ +/* Applies to: functions. */ +#define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL + +/* Warn if the caller does not use the return value, + unless the caller uses something like ignore_value. */ +/* Applies to: function, enumeration, class. */ +#define NODISCARD _GL_ATTRIBUTE_NODISCARD + + +/* Attributes that disable false alarms when the compiler diagnoses + programmer "mistakes". */ + +/* Do not warn if the entity is not used. */ +/* Applies to: + - function, variable, + - struct, union, struct/union member, + - enumeration, enumeration item, + - typedef, + in C++ also: class. */ +#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED + +/* The contents of a character array is not meant to be NUL-terminated. */ +/* Applies to: struct/union members and variables that are arrays of element + type '[[un]signed] char'. */ +#define ATTRIBUTE_NONSTRING _GL_ATTRIBUTE_NONSTRING + +/* Do not warn if control flow falls through to the immediately + following 'case' or 'default' label. */ +/* Applies to: Empty statement (;), inside a 'switch' statement. */ +#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH + + +/* ================== Attributes for debugging information ================== */ + +/* Attributes regarding debugging information emitted by the compiler. */ + +/* Omit the function from stack traces when debugging. */ +/* Applies to: function. */ +#define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL + +/* Make the entity visible to debuggers etc., even with '-fwhole-program'. */ +/* Applies to: functions, variables. */ +#define ATTRIBUTE_EXTERNALLY_VISIBLE _GL_ATTRIBUTE_EXTERNALLY_VISIBLE + + +/* ========== Attributes that mainly direct compiler optimizations ========== */ + +/* The function does not throw exceptions. */ +/* Applies to: functions. */ +#define ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW + +/* Do not inline the function. */ +/* Applies to: functions. */ +#define ATTRIBUTE_NOINLINE _GL_ATTRIBUTE_NOINLINE + +/* Always inline the function, and report an error if the compiler + cannot inline. */ +/* Applies to: function. */ +#define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE + +/* It is OK for a compiler to omit duplicate calls with the same arguments. + This attribute is safe for a function that neither depends on + nor affects observable state, and always returns exactly once - + e.g., does not loop forever, and does not call longjmp. + (This attribute is stricter than ATTRIBUTE_PURE.) */ +/* Applies to: functions. */ +#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST + +/* It is OK for a compiler to omit duplicate calls with the same + arguments if observable state is not changed between calls. + This attribute is safe for a function that does not affect + observable state, and always returns exactly once. + (This attribute is looser than ATTRIBUTE_CONST.) */ +/* Applies to: functions. */ +#define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE + +/* The function is rarely executed. */ +/* Applies to: functions. */ +#define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD + +/* If called from some other compilation unit, the function executes + code from that unit only by return or by exception handling, + letting the compiler optimize that unit more aggressively. */ +/* Applies to: functions. */ +#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF + +/* For struct members: The member has the smallest possible alignment. + For struct, union, class: All members have the smallest possible alignment, + minimizing the memory required. */ +/* Applies to: struct members, struct, union, + in C++ also: class. */ +#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED + + +/* ================ Attributes that make invalid code valid ================ */ + +/* Attributes that prevent fatal compiler optimizations for code that is not + fully ISO C compliant. */ + +/* Pointers to the type may point to the same storage as pointers to + other types, thus disabling strict aliasing optimization. */ +/* Applies to: types. */ +#define ATTRIBUTE_MAY_ALIAS _GL_ATTRIBUTE_MAY_ALIAS + + +#endif /* _GL_ATTRIBUTE_H */ diff --git a/gl/base64.c b/gl/base64.c index 8da969c0..6b6e5b09 100644 --- a/gl/base64.c +++ b/gl/base64.c @@ -1,24 +1,24 @@ /* base64.c -- Encode binary data using printable characters. - Copyright (C) 1999-2001, 2004-2006, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1999-2001, 2004-2006, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Simon Josefsson. Partially adapted from GNU MailUtils * (mailbox/filter_trans.c, as of 2004-11-28). Improved by review * from Paul Eggert, Bruno Haible, and Stepan Kasal. * - * See also RFC 4648 . + * See also RFC 4648 . * * Be careful with error checking. Here is how you would typically * use these functions: @@ -30,7 +30,7 @@ * FAIL: memory allocation error * OK: data in OUT/OUTLEN * - * size_t outlen = base64_encode_alloc (in, inlen, &out); + * idx_t outlen = base64_encode_alloc (in, inlen, &out); * if (out == NULL && outlen == 0 && inlen != 0) * FAIL: input too long * if (out == NULL) @@ -44,51 +44,84 @@ /* Get prototype. */ #include "base64.h" -/* Get malloc. */ -#include +/* Get imalloc. */ +#include + +#include /* Get UCHAR_MAX. */ #include #include -/* C89 compliant way to cast 'char' to 'unsigned char'. */ +/* Convert 'char' to 'unsigned char' without casting. */ static unsigned char to_uchar (char ch) { return ch; } +static const char b64c[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* Base64 encode IN array of size INLEN into OUT array. OUT needs + to be of length >= BASE64_LENGTH(INLEN), and INLEN needs to be + a multiple of 3. */ +static void +base64_encode_fast (const char *restrict in, idx_t inlen, char *restrict out) +{ + while (inlen) + { + *out++ = b64c[(to_uchar (in[0]) >> 2) & 0x3f]; + *out++ = b64c[((to_uchar (in[0]) << 4) + (to_uchar (in[1]) >> 4)) & 0x3f]; + *out++ = b64c[((to_uchar (in[1]) << 2) + (to_uchar (in[2]) >> 6)) & 0x3f]; + *out++ = b64c[to_uchar (in[2]) & 0x3f]; + + inlen -= 3; + in += 3; + } +} + /* Base64 encode IN array of size INLEN into OUT array of size OUTLEN. If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero terminate the output buffer. */ void -base64_encode (const char *restrict in, size_t inlen, - char *restrict out, size_t outlen) +base64_encode (const char *restrict in, idx_t inlen, + char *restrict out, idx_t outlen) { - static const char b64str[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + /* Note this outlen constraint can be enforced at compile time. + I.E. that the output buffer is exactly large enough to hold + the encoded inlen bytes. The inlen constraints (of corresponding + to outlen, and being a multiple of 3) can change at runtime + at the end of input. However the common case when reading + large inputs is to have both constraints satisfied, so we depend + on both in base_encode_fast(). */ + if (outlen % 4 == 0 && inlen == (outlen >> 2) * 3) + { + base64_encode_fast (in, inlen, out); + return; + } while (inlen && outlen) { - *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f]; + *out++ = b64c[(to_uchar (in[0]) >> 2) & 0x3f]; if (!--outlen) break; - *out++ = b64str[((to_uchar (in[0]) << 4) + *out++ = b64c[((to_uchar (in[0]) << 4) + (--inlen ? to_uchar (in[1]) >> 4 : 0)) & 0x3f]; if (!--outlen) break; *out++ = (inlen - ? b64str[((to_uchar (in[1]) << 2) + ? b64c[((to_uchar (in[1]) << 2) + (--inlen ? to_uchar (in[2]) >> 6 : 0)) & 0x3f] : '='); if (!--outlen) break; - *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '='; + *out++ = inlen ? b64c[to_uchar (in[2]) & 0x3f] : '='; if (!--outlen) break; if (inlen) @@ -110,30 +143,21 @@ base64_encode (const char *restrict in, size_t inlen, memory allocation failed, OUT is set to NULL, and the return value indicates length of the requested memory block, i.e., BASE64_LENGTH(inlen) + 1. */ -size_t -base64_encode_alloc (const char *in, size_t inlen, char **out) +idx_t +base64_encode_alloc (const char *in, idx_t inlen, char **out) { - size_t outlen = 1 + BASE64_LENGTH (inlen); - /* Check for overflow in outlen computation. - * - * If there is no overflow, outlen >= inlen. - * - * If the operation (inlen + 2) overflows then it yields at most +1, so - * outlen is 0. - * - * If the multiplication overflows, we lose at least half of the - * correct value, so the result is < ((inlen + 2) / 3) * 2, which is - * less than (inlen + 2) * 0.66667, which is less than inlen as soon as - * (inlen > 4). - */ - if (inlen > outlen) + Treat negative INLEN as overflow, for better compatibility with + pre-2021-08-27 API, which used size_t. */ + idx_t in_over_3 = inlen / 3 + (inlen % 3 != 0), outlen; + if (! INT_MULTIPLY_OK (in_over_3, 4, &outlen) || inlen < 0) { *out = NULL; return 0; } + outlen++; - *out = malloc (outlen); + *out = imalloc (outlen); if (!*out) return outlen; @@ -317,7 +341,7 @@ base64_decode_ctx_init (struct base64_decode_context *ctx) static char * get_4 (struct base64_decode_context *ctx, char const *restrict *in, char const *restrict in_end, - size_t *n_non_newline) + idx_t *n_non_newline) { if (ctx->i == 4) ctx->i = 0; @@ -369,8 +393,8 @@ get_4 (struct base64_decode_context *ctx, *OUT to point to the byte after the last one written, and decrement *OUTLEN to reflect the number of bytes remaining in *OUT. */ static bool -decode_4 (char const *restrict in, size_t inlen, - char *restrict *outp, size_t *outleft) +decode_4 (char const *restrict in, idx_t inlen, + char *restrict *outp, idx_t *outleft) { char *out = *outp; if (inlen < 2) @@ -455,10 +479,10 @@ decode_4 (char const *restrict in, size_t inlen, bool base64_decode_ctx (struct base64_decode_context *ctx, - const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen) + const char *restrict in, idx_t inlen, + char *restrict out, idx_t *outlen) { - size_t outleft = *outlen; + idx_t outleft = *outlen; bool ignore_newlines = ctx != NULL; bool flush_ctx = false; unsigned int ctx_i = 0; @@ -472,7 +496,7 @@ base64_decode_ctx (struct base64_decode_context *ctx, while (true) { - size_t outleft_save = outleft; + idx_t outleft_save = outleft; if (ctx_i == 0 && !flush_ctx) { while (true) @@ -546,17 +570,17 @@ base64_decode_ctx (struct base64_decode_context *ctx, undefined. */ bool base64_decode_alloc_ctx (struct base64_decode_context *ctx, - const char *in, size_t inlen, char **out, - size_t *outlen) + const char *in, idx_t inlen, char **out, + idx_t *outlen) { /* This may allocate a few bytes too many, depending on input, but it's not worth the extra CPU time to compute the exact size. The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the input ends with "=" and minus another 1 if the input ends with "==". - Dividing before multiplying avoids the possibility of overflow. */ - size_t needlen = 3 * (inlen / 4) + 3; + Shifting before multiplying avoids the possibility of overflow. */ + idx_t needlen = 3 * ((inlen >> 2) + 1); - *out = malloc (needlen); + *out = imalloc (needlen); if (!*out) return true; diff --git a/gl/base64.h b/gl/base64.h index 343150cb..6b8b3dc3 100644 --- a/gl/base64.h +++ b/gl/base64.h @@ -1,25 +1,25 @@ /* base64.h -- Encode binary data using printable characters. - Copyright (C) 2004-2006, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2004-2006, 2009-2022 Free Software Foundation, Inc. Written by Simon Josefsson. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef BASE64_H # define BASE64_H -/* Get size_t. */ -# include +/* Get idx_t. */ +# include /* Get bool. */ # include @@ -34,26 +34,26 @@ extern "C" { struct base64_decode_context { - unsigned int i; + int i; char buf[4]; }; extern bool isbase64 (char ch) _GL_ATTRIBUTE_CONST; -extern void base64_encode (const char *restrict in, size_t inlen, - char *restrict out, size_t outlen); +extern void base64_encode (const char *restrict in, idx_t inlen, + char *restrict out, idx_t outlen); -extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out); +extern idx_t base64_encode_alloc (const char *in, idx_t inlen, char **out); extern void base64_decode_ctx_init (struct base64_decode_context *ctx); extern bool base64_decode_ctx (struct base64_decode_context *ctx, - const char *restrict in, size_t inlen, - char *restrict out, size_t *outlen); + const char *restrict in, idx_t inlen, + char *restrict out, idx_t *outlen); extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx, - const char *in, size_t inlen, - char **out, size_t *outlen); + const char *in, idx_t inlen, + char **out, idx_t *outlen); #define base64_decode(in, inlen, out, outlen) \ base64_decode_ctx (NULL, in, inlen, out, outlen) diff --git a/gl/basename-lgpl.c b/gl/basename-lgpl.c index 9307e831..eb07e254 100644 --- a/gl/basename-lgpl.c +++ b/gl/basename-lgpl.c @@ -1,37 +1,37 @@ /* basename.c -- return the last element in a file name - Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2013 Free Software + Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include -#include "dirname.h" +/* Specification. */ +#include "basename-lgpl.h" +#include #include -/* Return the address of the last file name component of NAME. If - NAME has no relative file name components because it is a file - system root, return the empty string. */ +#include "filename.h" char * last_component (char const *name) { char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); char const *p; - bool saw_slash = false; + bool last_was_slash = false; while (ISSLASH (*base)) base++; @@ -39,21 +39,17 @@ last_component (char const *name) for (p = base; *p; p++) { if (ISSLASH (*p)) - saw_slash = true; - else if (saw_slash) + last_was_slash = true; + else if (last_was_slash) { base = p; - saw_slash = false; + last_was_slash = false; } } return (char *) base; } -/* Return the length of the basename NAME. Typically NAME is the - value returned by base_name or last_component. Act like strlen - (NAME), except omit all trailing slashes. */ - size_t base_len (char const *name) { diff --git a/gl/basename-lgpl.h b/gl/basename-lgpl.h new file mode 100644 index 00000000..5569f219 --- /dev/null +++ b/gl/basename-lgpl.h @@ -0,0 +1,78 @@ +/* Extract the last component (base name) of a file name. + + Copyright (C) 1998, 2001, 2003-2006, 2009-2022 Free Software Foundation, + Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _BASENAME_LGPL_H +#define _BASENAME_LGPL_H + +#include + +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Return the address of the last file name component of FILENAME. + If FILENAME has some trailing slash(es), they are considered to be + part of the last component. + If FILENAME has no relative file name components because it is a file + system root, return the empty string. + Examples: + FILENAME RESULT + "foo.c" "foo.c" + "foo/bar.c" "bar.c" + "/foo/bar.c" "bar.c" + "foo/bar/" "bar/" + "foo/bar//" "bar//" + "/" "" + "//" "" + "" "" + The return value is a tail of the given FILENAME; do NOT free() it! */ + +/* This function was traditionally called 'basename', but we avoid this + function name because + * Various platforms have different functions in their libc. + In particular, the glibc basename(), defined in , does + not consider trailing slashes to be part of the component: + FILENAME RESULT + "foo/bar/" "" + "foo/bar//" "" + * The 'basename' command eliminates trailing slashes and for a root + produces a non-empty result: + FILENAME RESULT + "foo/bar/" "bar" + "foo/bar//" "bar" + "/" "/" + "//" "/" + */ +extern char *last_component (char const *filename) _GL_ATTRIBUTE_PURE; + +/* Return the length of the basename FILENAME. + Typically FILENAME is the value returned by base_name or last_component. + Act like strlen (FILENAME), except omit all trailing slashes. */ +extern size_t base_len (char const *filename) _GL_ATTRIBUTE_PURE; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _BASENAME_LGPL_H */ diff --git a/gl/basename.c b/gl/basename.c index d73fd41a..0e372ca5 100644 --- a/gl/basename.c +++ b/gl/basename.c @@ -1,11 +1,11 @@ /* basename.c -- return the last element in a file name - Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2013 Free Software + Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2022 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 + 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, @@ -14,7 +14,7 @@ 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 . */ + along with this program. If not, see . */ #include @@ -22,37 +22,43 @@ #include #include "xalloc.h" -#include "xstrndup.h" char * base_name (char const *name) { char const *base = last_component (name); - size_t length; - - /* If there is no last component, then name is a file system root or the - empty string. */ - if (! *base) - return xstrndup (name, base_len (name)); - - /* Collapse a sequence of trailing slashes into one. */ - length = base_len (base); - if (ISSLASH (base[length])) - length++; - - /* On systems with drive letters, "a/b:c" must return "./b:c" rather - than "b:c" to avoid confusion with a drive letter. On systems - with pure POSIX semantics, this is not an issue. */ - if (FILE_SYSTEM_PREFIX_LEN (base)) + idx_t length; + int dotslash_len; + if (*base) + { + length = base_len (base); + + /* Collapse a sequence of trailing slashes into one. */ + length += ISSLASH (base[length]); + + /* On systems with drive letters, "a/b:c" must return "./b:c" rather + than "b:c" to avoid confusion with a drive letter. On systems + with pure POSIX semantics, this is not an issue. */ + dotslash_len = FILE_SYSTEM_PREFIX_LEN (base) != 0 ? 2 : 0; + } + else + { + /* There is no last component, so NAME is a file system root or + the empty string. */ + base = name; + length = base_len (base); + dotslash_len = 0; + } + + char *p = ximalloc (dotslash_len + length + 1); + if (dotslash_len) { - char *p = xmalloc (length + 3); p[0] = '.'; p[1] = '/'; - memcpy (p + 2, base, length); - p[length + 2] = '\0'; - return p; } /* Finally, copy the basename. */ - return xstrndup (base, length); + memcpy (p + dotslash_len, base, length); + p[dotslash_len + length] = '\0'; + return p; } diff --git a/gl/btowc.c b/gl/btowc.c index 6c7cbec9..4af58bb0 100644 --- a/gl/btowc.c +++ b/gl/btowc.c @@ -1,19 +1,19 @@ /* Convert unibyte character to wide character. - Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. + Copyright (C) 2008, 2010-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2008. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/byteswap.in.h b/gl/byteswap.in.h new file mode 100644 index 00000000..f4746d39 --- /dev/null +++ b/gl/byteswap.in.h @@ -0,0 +1,44 @@ +/* byteswap.h - Byte swapping + Copyright (C) 2005, 2007, 2009-2022 Free Software Foundation, Inc. + Written by Oskar Liljeblad , 2005. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_BYTESWAP_H +#define _GL_BYTESWAP_H + +/* Given an unsigned 16-bit argument X, return the value corresponding to + X with reversed byte order. */ +#define bswap_16(x) ((((x) & 0x00FF) << 8) | \ + (((x) & 0xFF00) >> 8)) + +/* Given an unsigned 32-bit argument X, return the value corresponding to + X with reversed byte order. */ +#define bswap_32(x) ((((x) & 0x000000FF) << 24) | \ + (((x) & 0x0000FF00) << 8) | \ + (((x) & 0x00FF0000) >> 8) | \ + (((x) & 0xFF000000) >> 24)) + +/* Given an unsigned 64-bit argument X, return the value corresponding to + X with reversed byte order. */ +#define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \ + (((x) & 0x000000000000FF00ULL) << 40) | \ + (((x) & 0x0000000000FF0000ULL) << 24) | \ + (((x) & 0x00000000FF000000ULL) << 8) | \ + (((x) & 0x000000FF00000000ULL) >> 8) | \ + (((x) & 0x0000FF0000000000ULL) >> 24) | \ + (((x) & 0x00FF000000000000ULL) >> 40) | \ + (((x) & 0xFF00000000000000ULL) >> 56)) + +#endif /* _GL_BYTESWAP_H */ diff --git a/gl/calloc.c b/gl/calloc.c new file mode 100644 index 00000000..0a934b30 --- /dev/null +++ b/gl/calloc.c @@ -0,0 +1,55 @@ +/* calloc() function that is glibc compatible. + This wrapper function is required at least on Tru64 UNIX 5.1 and mingw. + Copyright (C) 2004-2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* written by Jim Meyering and Bruno Haible */ + +#include + +/* Specification. */ +#include + +#include + +#include "xalloc-oversized.h" + +/* Call the system's calloc below. */ +#undef calloc + +/* Allocate and zero-fill an NxS-byte block of memory from the heap, + even if N or S is zero. */ + +void * +rpl_calloc (size_t n, size_t s) +{ + if (n == 0 || s == 0) + n = s = 1; + + if (xalloc_oversized (n, s)) + { + errno = ENOMEM; + return NULL; + } + + void *result = calloc (n, s); + +#if !HAVE_MALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/gl/cdefs.h b/gl/cdefs.h new file mode 100644 index 00000000..7b8ed5b3 --- /dev/null +++ b/gl/cdefs.h @@ -0,0 +1,707 @@ +/* Copyright (C) 1992-2022 Free Software Foundation, Inc. + Copyright The GNU Toolchain Authors. + 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _SYS_CDEFS_H +#define _SYS_CDEFS_H 1 + +/* We are almost always included from features.h. */ +#ifndef _FEATURES_H +# include +#endif + +/* 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 + supported anymore. */ +#if defined __GNUC__ && !defined __STDC__ +# error "You need a ISO C conforming compiler to use the glibc headers" +#endif + +/* Some user header file might have defined this before. */ +#undef __P +#undef __PMT + +/* 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__ \ + || (defined __apple_build_version__ \ + ? 6000000 <= __apple_build_version__ \ + : 3 < __clang_major__ + (5 <= __clang_minor__)))) +# define __glibc_has_attribute(attr) __has_attribute (attr) +#else +# define __glibc_has_attribute(attr) 0 +#endif +#ifdef __has_builtin +# define __glibc_has_builtin(name) __has_builtin (name) +#else +# define __glibc_has_builtin(name) 0 +#endif +#ifdef __has_extension +# define __glibc_has_extension(ext) __has_extension (ext) +#else +# define __glibc_has_extension(ext) 0 +#endif + +#if defined __GNUC__ || defined __clang__ + +/* All functions, except those with callbacks or those that + synchronize memory, are leaf functions. */ +# if __GNUC_PREREQ (4, 6) && !defined _LIBC +# define __LEAF , __leaf__ +# define __LEAF_ATTR __attribute__ ((__leaf__)) +# else +# define __LEAF +# define __LEAF_ATTR +# endif + +/* GCC can always grok prototypes. For C++ programs we add throw() + 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_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) +# 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 +# define __NTH(fct) fct +# define __NTHNL(fct) fct +# endif +# endif + +#else /* Not GCC or clang. */ + +# if (defined __cplusplus \ + || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +# define __inline inline +# else +# define __inline /* No inline functions. */ +# endif + +# define __THROW +# define __THROWNL +# define __NTH(fct) fct + +#endif /* GCC || clang. */ + +/* These two macros are not used in glibc anymore. They are kept here + only because some other projects expect the macros to be defined. */ +#define __P(args) args +#define __PMT(args) args + +/* For these things, GCC behaves the ANSI way normally, + and the non-ANSI way under -traditional. */ + +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x + +/* This is not a typedef so `const __ptr_t' does the right thing. */ +#define __ptr_t void * + + +/* C++ needs to know that types and declarations are C, not C++. */ +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS +# define __END_DECLS +#endif + + +/* Fortify support. */ +#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) \ + || __GNUC_PREREQ (12, 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 + +/* Compile time conditions to choose between the regular, _chk and _chk_warn + variants. These conditions should get evaluated to constant and optimized + away. */ + +#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) +#define __glibc_unsigned_or_positive(__l) \ + ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ + || (__builtin_constant_p (__l) && (__l) > 0)) + +/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ + condition can be folded to a constant and if it is true, or unknown (-1) */ +#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ + ((__osz) == (__SIZE_TYPE__) -1 \ + || (__glibc_unsigned_or_positive (__l) \ + && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ + (__s), (__osz))) \ + && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz)))) + +/* Conversely, we know at compile time that the length is unsafe if the + __L * __S <= __OBJSZ condition can be folded to a constant and if it is + false. */ +#define __glibc_unsafe_len(__l, __s, __osz) \ + (__glibc_unsigned_or_positive (__l) \ + && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ + __s, __osz)) \ + && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) + +/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be + declared. */ + +#define __glibc_fortify(f, __l, __s, __osz, ...) \ + (__glibc_safe_or_unknown_len (__l, __s, __osz) \ + ? __ ## f ## _alias (__VA_ARGS__) \ + : (__glibc_unsafe_len (__l, __s, __osz) \ + ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ + : __ ## f ## _chk (__VA_ARGS__, __osz))) \ + +/* Fortify function f, where object size argument passed to f is the number of + elements and not total size. */ + +#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ + (__glibc_safe_or_unknown_len (__l, __s, __osz) \ + ? __ ## f ## _alias (__VA_ARGS__) \ + : (__glibc_unsafe_len (__l, __s, __osz) \ + ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ + : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ + +#if __GNUC_PREREQ (4,3) +# define __warnattr(msg) __attribute__((__warning__ (msg))) +# define __errordecl(name, msg) \ + extern void name (void) __attribute__((__error__ (msg))) +#else +# define __warnattr(msg) +# define __errordecl(name, msg) extern void name (void) +#endif + +/* Support for flexible arrays. + Headers that should use flexible arrays only if they're "real" + (e.g. only if they won't affect sizeof()) should test + #if __glibc_c99_flexarr_available. */ +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc +# define __flexarr [] +# define __glibc_c99_flexarr_available 1 +#elif __GNUC_PREREQ (2,97) || defined __clang__ +/* GCC 2.97 and clang support C99 flexible array members as an extension, + even when in C89 mode or compiling C++ (any version). */ +# define __flexarr [] +# define __glibc_c99_flexarr_available 1 +#elif defined __GNUC__ +/* Pre-2.97 GCC did not support C99 flexible arrays but did have + an equivalent extension with slightly different notation. */ +# define __flexarr [0] +# define __glibc_c99_flexarr_available 1 +#else +/* Some other non-C99 compiler. Approximate with [1]. */ +# define __flexarr [1] +# define __glibc_c99_flexarr_available 0 +#endif + + +/* __asm__ ("xyz") is used throughout the headers to rename functions + at the assembly language level. This is wrapped by the __REDIRECT + macro, in order to support compilers that can do this some other + way. When compilers don't support asm-names at all, we have to do + preprocessor tricks instead (which don't have exactly the right + semantics, but it's the best we can do). + + Example: + int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */ + +#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4) + +# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias)) +# ifdef __cplusplus +# define __REDIRECT_NTH(name, proto, alias) \ + name proto __THROW __asm__ (__ASMNAME (#alias)) +# define __REDIRECT_NTHNL(name, proto, alias) \ + name proto __THROWNL __asm__ (__ASMNAME (#alias)) +# else +# define __REDIRECT_NTH(name, proto, alias) \ + name proto __asm__ (__ASMNAME (#alias)) __THROW +# define __REDIRECT_NTHNL(name, proto, alias) \ + name proto __asm__ (__ASMNAME (#alias)) __THROWNL +# endif +# define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname) +# define __ASMNAME2(prefix, cname) __STRING (prefix) cname + +/* +#elif __SOME_OTHER_COMPILER__ + +# define __REDIRECT(name, proto, alias) name proto; \ + _Pragma("let " #name " = " #alias) +*/ +#endif + +/* GCC and clang have various useful declarations that can be made with + the '__attribute__' syntax. All of the ways we use this do fine if + they are omitted for compilers that don't understand it. */ +#if !(defined __GNUC__ || defined __clang__) +# define __attribute__(xyz) /* Ignore */ +#endif + +/* 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_has_attribute (__malloc__) +# define __attribute_malloc__ __attribute__ ((__malloc__)) +#else +# define __attribute_malloc__ /* Ignore */ +#endif + +/* Tell the compiler which arguments to an allocation function + indicate the size of the allocation. */ +#if __GNUC_PREREQ (4, 3) +# define __attribute_alloc_size__(params) \ + __attribute__ ((__alloc_size__ params)) +#else +# define __attribute_alloc_size__(params) /* Ignore. */ +#endif + +/* Tell the compiler which argument to an allocation function + indicates the alignment of the allocation. */ +#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__) +# define __attribute_alloc_align__(param) \ + __attribute__ ((__alloc_align__ param)) +#else +# define __attribute_alloc_align__(param) /* Ignore. */ +#endif + +/* 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_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_has_attribute (__const__) +# define __attribute_const__ __attribute__ ((__const__)) +#else +# define __attribute_const__ /* Ignore */ +#endif + +#if __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_has_attribute (__used__) +# define __attribute_used__ __attribute__ ((__used__)) +# define __attribute_noinline__ __attribute__ ((__noinline__)) +#else +# define __attribute_used__ __attribute__ ((__unused__)) +# define __attribute_noinline__ /* Ignore */ +#endif + +/* Since version 3.2, gcc allows marking deprecated functions. */ +#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__) +# define __attribute_deprecated__ __attribute__ ((__deprecated__)) +#else +# define __attribute_deprecated__ /* Ignore */ +#endif + +/* 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_has_extension (__attribute_deprecated_with_message__) +# define __attribute_deprecated_msg__(msg) \ + __attribute__ ((__deprecated__ (msg))) +#else +# define __attribute_deprecated_msg__(msg) __attribute_deprecated__ +#endif + +/* At some point during the gcc 2.8 development the `format_arg' attribute + for functions was introduced. We don't want to use it unconditionally + (although this would be possible) since it generates warnings. + 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_has_attribute (__format_arg__) +# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) +#else +# define __attribute_format_arg__(x) /* Ignore */ +#endif + +/* At some point during the gcc 2.97 development the `strfmon' format + 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_has_attribute (__format__) +# define __attribute_format_strfmon__(a,b) \ + __attribute__ ((__format__ (__strfmon__, a, b))) +#else +# define __attribute_format_strfmon__(a,b) /* Ignore */ +#endif + +/* The nonnull function attribute marks pointer parameters that + must not be NULL. This has the name __nonnull in glibc, + and __attribute_nonnull__ in files shared with Gnulib to avoid + collision with a different __nonnull in DragonFlyBSD 5.9. */ +#ifndef __attribute_nonnull__ +# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) +# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params)) +# else +# define __attribute_nonnull__(params) +# endif +#endif +#ifndef __nonnull +# define __nonnull(params) __attribute_nonnull__ (params) +#endif + +/* The returns_nonnull function attribute marks the return type of the function + as always being non-null. */ +#ifndef __returns_nonnull +# if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__returns_nonnull__) +# define __returns_nonnull __attribute__ ((__returns_nonnull__)) +# else +# define __returns_nonnull +# endif +#endif + +/* If fortification mode, we warn about unused results of certain + function calls which can lead to problems. */ +#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 +# define __wur __attribute_warn_unused_result__ +# endif +#else +# define __attribute_warn_unused_result__ /* empty */ +#endif +#ifndef __wur +# define __wur /* Ignore */ +#endif + +/* Forces a function to be always inlined. */ +#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. */ +# undef __always_inline +# define __always_inline __inline __attribute__ ((__always_inline__)) +#else +# undef __always_inline +# define __always_inline __inline +#endif + +/* 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_has_attribute (__artificial__) +# define __attribute_artificial__ __attribute__ ((__artificial__)) +#else +# define __attribute_artificial__ /* Ignore */ +#endif + +/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__ + or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions + older than 4.3 may define these macros and still not guarantee GNU inlining + semantics. + + clang++ identifies itself as gcc-4.2, but has support for GNU inlining + semantics, that can be checked for by using the __GNUC_STDC_INLINE_ and + __GNUC_GNU_INLINE__ macro definitions. */ +#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \ + || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \ + || defined __GNUC_GNU_INLINE__))) +# if defined __GNUC_STDC_INLINE__ || defined __cplusplus +# define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) +# define __extern_always_inline \ + extern __always_inline __attribute__ ((__gnu_inline__)) +# else +# define __extern_inline extern __inline +# define __extern_always_inline extern __always_inline +# endif +#endif + +#ifdef __extern_always_inline +# define __fortify_function __extern_always_inline __attribute_artificial__ +#endif + +/* GCC 4.3 and above allow passing all anonymous arguments of an + __extern_always_inline function to some other vararg function. */ +#if __GNUC_PREREQ (4,3) +# define __va_arg_pack() __builtin_va_arg_pack () +# define __va_arg_pack_len() __builtin_va_arg_pack_len () +#endif + +/* It is possible to compile containing GCC extensions even if GCC is + run in pedantic mode if the uses are carefully marked using the + `__extension__' keyword. But this is not generally available before + version 2.8. */ +#if !(__GNUC_PREREQ (2,8) || defined __clang__) +# define __extension__ /* Ignore */ +#endif + +/* __restrict is known in EGCS 1.2 and above, and in clang. + It works also in C++ mode (outside of arrays), but only when spelled + as '__restrict', not 'restrict'. */ +#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3) +# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +# define __restrict restrict +# else +# define __restrict /* Ignore */ +# endif +#endif + +/* ISO C99 also allows to declare arrays as non-overlapping. The syntax is + array_name[restrict] + GCC 3.1 and clang support this. + This syntax is not usable in C++ mode. */ +#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus +# define __restrict_arr __restrict +#else +# ifdef __GNUC__ +# define __restrict_arr /* Not supported in old GCC. */ +# else +# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +# define __restrict_arr restrict +# else +/* Some other non-C99 compiler. */ +# define __restrict_arr /* Not supported. */ +# endif +# endif +#endif + +#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 +# define __glibc_unlikely(cond) (cond) +# define __glibc_likely(cond) (cond) +#endif + +#if (!defined _Noreturn \ + && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ + && !(__GNUC_PREREQ (4,7) \ + || (3 < __clang_major__ + (5 <= __clang_minor__)))) +# if __GNUC_PREREQ (2,8) +# define _Noreturn __attribute__ ((__noreturn__)) +# else +# define _Noreturn +# endif +#endif + +#if __GNUC_PREREQ (8, 0) +/* Describes a char array whose address can safely be passed as the first + argument to strncpy and strncat, as the char array is not necessarily + a NUL-terminated string. */ +# define __attribute_nonstring__ __attribute__ ((__nonstring__)) +#else +# 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) \ + || defined __STRICT_ANSI__)) +# define _Static_assert(expr, diagnostic) \ + extern int (*__Static_assert_function (void)) \ + [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })] +#endif + +/* Gnulib avoids including these, as they don't work on non-glibc or + older glibc platforms. */ +#ifndef __GNULIB_CDEFS +# include +# include +#endif + +#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) +# define __LDBL_REDIR(name, proto) \ + __LDBL_REDIR1 (name, proto, __nldbl_##name) +# 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) \ + extern __typeof (name) name __asm (__ASMNAME ("__nldbl_" #name)); +# define __REDIRECT_LDBL(name, proto, alias) \ + __LDBL_REDIR1 (name, proto, __nldbl_##alias) +# define __REDIRECT_NTH_LDBL(name, proto, alias) \ + __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias) +# endif +#endif +#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) +# define __REDIRECT_NTH_LDBL(name, proto, alias) \ + __REDIRECT_NTH (name, proto, alias) +# endif +#endif + +/* __glibc_macro_warning (MESSAGE) issues warning MESSAGE. This is + intended for use in preprocessor macros. + + Note: MESSAGE must be a _single_ string; concatenation of string + literals is not supported. */ +#if __GNUC_PREREQ (4,8) || __glibc_clang_prereq (3,5) +# define __glibc_macro_warning1(message) _Pragma (#message) +# define __glibc_macro_warning(message) \ + __glibc_macro_warning1 (GCC warning message) +#else +# define __glibc_macro_warning(msg) +#endif + +/* Generic selection (ISO C11) is a C-only feature, available in GCC + since version 4.9. Previous versions do not provide generic + selection, even though they might set __STDC_VERSION__ to 201112L, + when in -std=c11 mode. Thus, we must check for !defined __GNUC__ + when testing __STDC_VERSION__ for generic selection support. + On the other hand, Clang also defines __GNUC__, so a clang-specific + check is required to enable the use of generic selection. */ +#if !defined __cplusplus \ + && (__GNUC_PREREQ (4, 9) \ + || __glibc_has_extension (c_generic_selections) \ + || (!defined __GNUC__ && defined __STDC_VERSION__ \ + && __STDC_VERSION__ >= 201112L)) +# define __HAVE_GENERIC_SELECTION 1 +#else +# 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, [, ]) */ +# define __attr_access(x) __attribute__ ((__access__ x)) +/* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may + use the access attribute to get object sizes from function definition + arguments, so we can't use them on functions we fortify. Drop the object + size hints for such functions. */ +# if __USE_FORTIFY_LEVEL == 3 +# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o))) +# else +# define __fortified_attr_access(a, o, s) __attr_access ((a, o, s)) +# endif +# if __GNUC_PREREQ (11, 0) +# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno))) +# else +# define __attr_access_none(argno) +# endif +#else +# define __fortified_attr_access(a, o, s) +# define __attr_access(x) +# define __attr_access_none(argno) +#endif + +#if __GNUC_PREREQ (11, 0) +/* Designates dealloc as a function to call to deallocate objects + allocated by the declared function. */ +# define __attr_dealloc(dealloc, argno) \ + __attribute__ ((__malloc__ (dealloc, argno))) +# define __attr_dealloc_free __attr_dealloc (__builtin_free, 1) +#else +# define __attr_dealloc(dealloc, argno) +# define __attr_dealloc_free +#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 */ diff --git a/gl/cloexec.c b/gl/cloexec.c new file mode 100644 index 00000000..812be01a --- /dev/null +++ b/gl/cloexec.c @@ -0,0 +1,83 @@ +/* cloexec.c - set or clear the close-on-exec descriptor flag + + Copyright (C) 1991, 2004-2006, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* The code is taken from glibc/manual/llio.texi */ + +#include + +#include "cloexec.h" + +#include +#include +#include + +/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true, + or clear the flag if VALUE is false. + Return 0 on success, or -1 on error with 'errno' set. + + Note that on MingW, this function does NOT protect DESC from being + inherited into spawned children. Instead, either use dup_cloexec + followed by closing the original DESC, or use interfaces such as + open or pipe2 that accept flags like O_CLOEXEC to create DESC + non-inheritable in the first place. */ + +int +set_cloexec_flag (int desc, bool value) +{ +#ifdef F_SETFD + + int flags = fcntl (desc, F_GETFD, 0); + + if (0 <= flags) + { + int newflags = (value ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC); + + if (flags == newflags + || fcntl (desc, F_SETFD, newflags) != -1) + return 0; + } + + return -1; + +#else /* !F_SETFD */ + + /* Use dup2 to reject invalid file descriptors; the cloexec flag + will be unaffected. */ + if (desc < 0) + { + errno = EBADF; + return -1; + } + if (dup2 (desc, desc) < 0) + /* errno is EBADF here. */ + return -1; + + /* There is nothing we can do on this kind of platform. Punt. */ + return 0; +#endif /* !F_SETFD */ +} + + +/* Duplicates a file handle FD, while marking the copy to be closed + prior to exec or spawn. Returns -1 and sets errno if FD could not + be duplicated. */ + +int +dup_cloexec (int fd) +{ + return fcntl (fd, F_DUPFD_CLOEXEC, 0); +} diff --git a/gl/cloexec.h b/gl/cloexec.h new file mode 100644 index 00000000..7a22d775 --- /dev/null +++ b/gl/cloexec.h @@ -0,0 +1,36 @@ +/* cloexec.c - set or clear the close-on-exec descriptor flag + + Copyright (C) 2004, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true, + or clear the flag if VALUE is false. + Return 0 on success, or -1 on error with 'errno' set. + + Note that on MingW, this function does NOT protect DESC from being + inherited into spawned children. Instead, either use dup_cloexec + followed by closing the original DESC, or use interfaces such as + open or pipe2 that accept flags like O_CLOEXEC to create DESC + non-inheritable in the first place. */ + +int set_cloexec_flag (int desc, bool value); + +/* Duplicates a file handle FD, while marking the copy to be closed + prior to exec or spawn. Returns -1 and sets errno if FD could not + be duplicated. */ + +int dup_cloexec (int fd); diff --git a/gl/close.c b/gl/close.c new file mode 100644 index 00000000..44990ba7 --- /dev/null +++ b/gl/close.c @@ -0,0 +1,75 @@ +/* close replacement. + Copyright (C) 2008-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#include "fd-hook.h" +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +#endif + +#undef close + +#if defined _WIN32 && !defined __CYGWIN__ +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static int +close_nothrow (int fd) +{ + int result; + + TRY_MSVC_INVAL + { + result = _close (fd); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EBADF; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define close_nothrow _close +# endif +#else +# define close_nothrow close +#endif + +/* Override close() to call into other gnulib modules. */ + +int +rpl_close (int fd) +{ +#if WINDOWS_SOCKETS + int retval = execute_all_close_hooks (close_nothrow, fd); +#else + int retval = close_nothrow (fd); +#endif + +#if REPLACE_FCHDIR + if (retval >= 0) + _gl_unregister_fd (fd); +#endif + + return retval; +} diff --git a/gl/config.charset b/gl/config.charset deleted file mode 100644 index a991419c..00000000 --- a/gl/config.charset +++ /dev/null @@ -1,684 +0,0 @@ -#! /bin/sh -# Output a system dependent table of character encoding aliases. -# -# Copyright (C) 2000-2004, 2006-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, see . -# -# The table consists of lines of the form -# ALIAS CANONICAL -# -# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". -# ALIAS is compared in a case sensitive way. -# -# CANONICAL is the GNU canonical name for this character encoding. -# It must be an encoding supported by libiconv. Support by GNU libc is -# also desirable. CANONICAL is case insensitive. Usually an upper case -# MIME charset name is preferred. -# The current list of GNU canonical charset names is as follows. -# -# name MIME? used by which systems -# (darwin = Mac OS X, woe32 = native Windows) -# -# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin -# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin -# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin -# ISO-8859-3 Y glibc solaris cygwin -# ISO-8859-4 Y osf solaris freebsd netbsd openbsd darwin -# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin -# ISO-8859-6 Y glibc aix hpux solaris cygwin -# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin -# ISO-8859-8 Y glibc aix hpux osf solaris cygwin -# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin cygwin -# ISO-8859-13 glibc netbsd openbsd darwin cygwin -# ISO-8859-14 glibc cygwin -# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin -# KOI8-R Y glibc solaris freebsd netbsd openbsd darwin -# KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin -# KOI8-T glibc -# CP437 dos -# CP775 dos -# CP850 aix osf dos -# CP852 dos -# CP855 dos -# CP856 aix -# CP857 dos -# CP861 dos -# CP862 dos -# CP864 dos -# CP865 dos -# CP866 freebsd netbsd openbsd darwin dos -# CP869 dos -# CP874 woe32 dos -# CP922 aix -# CP932 aix cygwin woe32 dos -# CP943 aix -# CP949 osf darwin woe32 dos -# CP950 woe32 dos -# CP1046 aix -# CP1124 aix -# CP1125 dos -# CP1129 aix -# CP1131 darwin -# CP1250 woe32 -# CP1251 glibc solaris netbsd openbsd darwin cygwin woe32 -# CP1252 aix woe32 -# CP1253 woe32 -# CP1254 woe32 -# CP1255 glibc woe32 -# CP1256 woe32 -# CP1257 woe32 -# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin -# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin -# EUC-TW glibc aix hpux irix osf solaris netbsd -# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin -# BIG5-HKSCS glibc solaris darwin -# GBK glibc aix osf solaris darwin cygwin woe32 dos -# GB18030 glibc solaris netbsd darwin -# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin -# JOHAB glibc solaris woe32 -# TIS-620 glibc aix hpux osf solaris cygwin -# VISCII Y glibc -# TCVN5712-1 glibc -# ARMSCII-8 glibc darwin -# GEORGIAN-PS glibc cygwin -# PT154 glibc -# HP-ROMAN8 hpux -# HP-ARABIC8 hpux -# HP-GREEK8 hpux -# HP-HEBREW8 hpux -# HP-TURKISH8 hpux -# HP-KANA8 hpux -# DEC-KANJI osf -# DEC-HANYU osf -# UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin -# -# Note: Names which are not marked as being a MIME name should not be used in -# Internet protocols for information interchange (mail, news, etc.). -# -# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications -# must understand both names and treat them as equivalent. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM - -host="$1" -os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` -echo "# This file contains a table of character encoding aliases," -echo "# suitable for operating system '${os}'." -echo "# It was automatically generated from config.charset." -# List of references, updated during installation: -echo "# Packages using this file: " -case "$os" in - linux-gnulibc1*) - # Linux libc5 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "C ASCII" - echo "POSIX ASCII" - for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ - en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ - en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ - es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ - et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ - fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ - it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ - sv_FI sv_SE; do - echo "$l ISO-8859-1" - echo "$l.iso-8859-1 ISO-8859-1" - echo "$l.iso-8859-15 ISO-8859-15" - echo "$l.iso-8859-15@euro ISO-8859-15" - echo "$l@euro ISO-8859-15" - echo "$l.cp-437 CP437" - echo "$l.cp-850 CP850" - echo "$l.cp-1252 CP1252" - echo "$l.cp-1252@euro CP1252" - #echo "$l.atari-st ATARI-ST" # not a commonly used encoding - echo "$l.utf-8 UTF-8" - echo "$l.utf-8@euro UTF-8" - done - for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ - sl_SI sr sr_CS sr_YU; do - echo "$l ISO-8859-2" - echo "$l.iso-8859-2 ISO-8859-2" - echo "$l.cp-852 CP852" - echo "$l.cp-1250 CP1250" - echo "$l.utf-8 UTF-8" - done - for l in mk mk_MK ru ru_RU; do - echo "$l ISO-8859-5" - echo "$l.iso-8859-5 ISO-8859-5" - echo "$l.koi8-r KOI8-R" - echo "$l.cp-866 CP866" - echo "$l.cp-1251 CP1251" - echo "$l.utf-8 UTF-8" - done - for l in ar ar_SA; do - echo "$l ISO-8859-6" - echo "$l.iso-8859-6 ISO-8859-6" - echo "$l.cp-864 CP864" - #echo "$l.cp-868 CP868" # not a commonly used encoding - echo "$l.cp-1256 CP1256" - echo "$l.utf-8 UTF-8" - done - for l in el el_GR gr gr_GR; do - echo "$l ISO-8859-7" - echo "$l.iso-8859-7 ISO-8859-7" - echo "$l.cp-869 CP869" - echo "$l.cp-1253 CP1253" - echo "$l.cp-1253@euro CP1253" - echo "$l.utf-8 UTF-8" - echo "$l.utf-8@euro UTF-8" - done - for l in he he_IL iw iw_IL; do - echo "$l ISO-8859-8" - echo "$l.iso-8859-8 ISO-8859-8" - echo "$l.cp-862 CP862" - echo "$l.cp-1255 CP1255" - echo "$l.utf-8 UTF-8" - done - for l in tr tr_TR; do - echo "$l ISO-8859-9" - echo "$l.iso-8859-9 ISO-8859-9" - echo "$l.cp-857 CP857" - echo "$l.cp-1254 CP1254" - echo "$l.utf-8 UTF-8" - done - for l in lt lt_LT lv lv_LV; do - #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name - echo "$l ISO-8859-13" - done - for l in ru_UA uk uk_UA; do - echo "$l KOI8-U" - done - for l in zh zh_CN; do - #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name - echo "$l GB2312" - done - for l in ja ja_JP ja_JP.EUC; do - echo "$l EUC-JP" - done - for l in ko ko_KR; do - echo "$l EUC-KR" - done - for l in th th_TH; do - echo "$l TIS-620" - done - for l in fa fa_IR; do - #echo "$l ISIRI-3342" # a broken encoding - echo "$l.utf-8 UTF-8" - done - ;; - linux* | *-gnu*) - # With glibc-2.1 or newer, we don't need any canonicalization, - # because glibc has iconv and both glibc and libiconv support all - # GNU canonical names directly. Therefore, the Makefile does not - # need to install the alias file at all. - # The following applies only to glibc-2.0.x and older libcs. - echo "ISO_646.IRV:1983 ASCII" - ;; - aix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "IBM-850 CP850" - echo "IBM-856 CP856" - echo "IBM-921 ISO-8859-13" - echo "IBM-922 CP922" - echo "IBM-932 CP932" - echo "IBM-943 CP943" - echo "IBM-1046 CP1046" - echo "IBM-1124 CP1124" - echo "IBM-1129 CP1129" - echo "IBM-1252 CP1252" - echo "IBM-eucCN GB2312" - echo "IBM-eucJP EUC-JP" - echo "IBM-eucKR EUC-KR" - echo "IBM-eucTW EUC-TW" - echo "big5 BIG5" - echo "GBK GBK" - echo "TIS-620 TIS-620" - echo "UTF-8 UTF-8" - ;; - hpux*) - echo "iso88591 ISO-8859-1" - echo "iso88592 ISO-8859-2" - echo "iso88595 ISO-8859-5" - echo "iso88596 ISO-8859-6" - echo "iso88597 ISO-8859-7" - echo "iso88598 ISO-8859-8" - echo "iso88599 ISO-8859-9" - echo "iso885915 ISO-8859-15" - echo "roman8 HP-ROMAN8" - echo "arabic8 HP-ARABIC8" - echo "greek8 HP-GREEK8" - echo "hebrew8 HP-HEBREW8" - echo "turkish8 HP-TURKISH8" - echo "kana8 HP-KANA8" - echo "tis620 TIS-620" - echo "big5 BIG5" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "hp15CN GB2312" - #echo "ccdc ?" # what is this? - echo "SJIS SHIFT_JIS" - echo "utf8 UTF-8" - ;; - irix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - ;; - osf*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "cp850 CP850" - echo "big5 BIG5" - echo "dechanyu DEC-HANYU" - echo "dechanzi GB2312" - echo "deckanji DEC-KANJI" - echo "deckorean EUC-KR" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "GBK GBK" - echo "KSC5601 CP949" - echo "sdeckanji EUC-JP" - echo "SJIS SHIFT_JIS" - echo "TACTIS TIS-620" - echo "UTF-8 UTF-8" - ;; - solaris*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-3 ISO-8859-3" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "koi8-r KOI8-R" - echo "ansi-1251 CP1251" - echo "BIG5 BIG5" - echo "Big5-HKSCS BIG5-HKSCS" - echo "gb2312 GB2312" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "cns11643 EUC-TW" - echo "5601 EUC-KR" - echo "ko_KR.johap92 JOHAB" - echo "eucJP EUC-JP" - echo "PCK SHIFT_JIS" - echo "TIS620.2533 TIS-620" - #echo "sun_eu_greek ?" # what is this? - echo "UTF-8 UTF-8" - ;; - freebsd* | os2*) - # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just - # reuse FreeBSD's locale data for OS/2. - echo "C ASCII" - echo "US-ASCII ASCII" - for l in la_LN lt_LN; do - echo "$l.ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ - lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do - echo "$l.ISO_8859-1 ISO-8859-1" - echo "$l.DIS_8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do - echo "$l.ISO_8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO_8859-4 ISO-8859-4" - done - for l in ru_RU ru_SU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO_8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ja_JP.Shift_JIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - netbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "BIG5 BIG5" - echo "SJIS SHIFT_JIS" - ;; - openbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - ;; - darwin[56]*) - # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "C ASCII" - for l in en_AU en_CA en_GB en_US la_LN; do - echo "$l.US-ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ - nl_NL no_NO pt_PT sv_SE; do - echo "$l ISO-8859-1" - echo "$l.ISO8859-1 ISO-8859-1" - echo "$l.ISO8859-15 ISO-8859-15" - done - for l in la_LN; do - echo "$l.ISO8859-1 ISO-8859-1" - echo "$l.ISO8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do - echo "$l.ISO8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO8859-4 ISO-8859-4" - done - for l in ru_RU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - for l in bg_BG; do - echo "$l.CP1251 CP1251" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - darwin*) - # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is - # useless: - # - It returns the empty string when LANG is set to a locale of the - # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 - # LC_CTYPE file. - # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by - # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. - # - The documentation says: - # "... all code that calls BSD system routines should ensure - # that the const *char parameters of these routines are in UTF-8 - # encoding. All BSD system functions expect their string - # parameters to be in UTF-8 encoding and nothing else." - # It also says - # "An additional caveat is that string parameters for files, - # paths, and other file-system entities must be in canonical - # UTF-8. In a canonical UTF-8 Unicode string, all decomposable - # characters are decomposed ..." - # but this is not true: You can pass non-decomposed UTF-8 strings - # to file system functions, and it is the OS which will convert - # them to decomposed UTF-8 before accessing the file system. - # - The Apple Terminal application displays UTF-8 by default. - # - However, other applications are free to use different encodings: - # - xterm uses ISO-8859-1 by default. - # - TextEdit uses MacRoman by default. - # We prefer UTF-8 over decomposed UTF-8-MAC because one should - # minimize the use of decomposed Unicode. Unfortunately, through the - # Darwin file system, decomposed UTF-8 strings are leaked into user - # space nevertheless. - # Then there are also the locales with encodings other than US-ASCII - # and UTF-8. These locales can be occasionally useful to users (e.g. - # when grepping through ISO-8859-1 encoded text files), when all their - # file names are in US-ASCII. - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - echo "KOI8-R KOI8-R" - echo "KOI8-U KOI8-U" - echo "CP866 CP866" - echo "CP949 CP949" - echo "CP1131 CP1131" - echo "CP1251 CP1251" - echo "eucCN GB2312" - echo "GB2312 GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "Big5 BIG5" - echo "Big5HKSCS BIG5-HKSCS" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "SJIS SHIFT_JIS" - echo "ARMSCII-8 ARMSCII-8" - echo "PT154 PT154" - #echo "ISCII-DEV ?" - echo "* UTF-8" - ;; - beos* | haiku*) - # BeOS and Haiku have a single locale, and it has UTF-8 encoding. - echo "* UTF-8" - ;; - msdosdjgpp*) - # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "#" - echo "# The encodings given here may not all be correct." - echo "# If you find that the encoding given for your language and" - echo "# country is not the one your DOS machine actually uses, just" - echo "# correct it in this file, and send a mail to" - echo "# Juan Manuel Guerrero " - echo "# and Bruno Haible ." - echo "#" - echo "C ASCII" - # ISO-8859-1 languages - echo "ca CP850" - echo "ca_ES CP850" - echo "da CP865" # not CP850 ?? - echo "da_DK CP865" # not CP850 ?? - echo "de CP850" - echo "de_AT CP850" - echo "de_CH CP850" - echo "de_DE CP850" - echo "en CP850" - echo "en_AU CP850" # not CP437 ?? - echo "en_CA CP850" - echo "en_GB CP850" - echo "en_NZ CP437" - echo "en_US CP437" - echo "en_ZA CP850" # not CP437 ?? - echo "es CP850" - echo "es_AR CP850" - echo "es_BO CP850" - echo "es_CL CP850" - echo "es_CO CP850" - echo "es_CR CP850" - echo "es_CU CP850" - echo "es_DO CP850" - echo "es_EC CP850" - echo "es_ES CP850" - echo "es_GT CP850" - echo "es_HN CP850" - echo "es_MX CP850" - echo "es_NI CP850" - echo "es_PA CP850" - echo "es_PY CP850" - echo "es_PE CP850" - echo "es_SV CP850" - echo "es_UY CP850" - echo "es_VE CP850" - echo "et CP850" - echo "et_EE CP850" - echo "eu CP850" - echo "eu_ES CP850" - echo "fi CP850" - echo "fi_FI CP850" - echo "fr CP850" - echo "fr_BE CP850" - echo "fr_CA CP850" - echo "fr_CH CP850" - echo "fr_FR CP850" - echo "ga CP850" - echo "ga_IE CP850" - echo "gd CP850" - echo "gd_GB CP850" - echo "gl CP850" - echo "gl_ES CP850" - echo "id CP850" # not CP437 ?? - echo "id_ID CP850" # not CP437 ?? - echo "is CP861" # not CP850 ?? - echo "is_IS CP861" # not CP850 ?? - echo "it CP850" - echo "it_CH CP850" - echo "it_IT CP850" - echo "lt CP775" - echo "lt_LT CP775" - echo "lv CP775" - echo "lv_LV CP775" - echo "nb CP865" # not CP850 ?? - echo "nb_NO CP865" # not CP850 ?? - echo "nl CP850" - echo "nl_BE CP850" - echo "nl_NL CP850" - echo "nn CP865" # not CP850 ?? - echo "nn_NO CP865" # not CP850 ?? - echo "no CP865" # not CP850 ?? - echo "no_NO CP865" # not CP850 ?? - echo "pt CP850" - echo "pt_BR CP850" - echo "pt_PT CP850" - echo "sv CP850" - echo "sv_SE CP850" - # ISO-8859-2 languages - echo "cs CP852" - echo "cs_CZ CP852" - echo "hr CP852" - echo "hr_HR CP852" - echo "hu CP852" - echo "hu_HU CP852" - echo "pl CP852" - echo "pl_PL CP852" - echo "ro CP852" - echo "ro_RO CP852" - echo "sk CP852" - echo "sk_SK CP852" - echo "sl CP852" - echo "sl_SI CP852" - echo "sq CP852" - echo "sq_AL CP852" - echo "sr CP852" # CP852 or CP866 or CP855 ?? - echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? - echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? - # ISO-8859-3 languages - echo "mt CP850" - echo "mt_MT CP850" - # ISO-8859-5 languages - echo "be CP866" - echo "be_BE CP866" - echo "bg CP866" # not CP855 ?? - echo "bg_BG CP866" # not CP855 ?? - echo "mk CP866" # not CP855 ?? - echo "mk_MK CP866" # not CP855 ?? - echo "ru CP866" - echo "ru_RU CP866" - echo "uk CP1125" - echo "uk_UA CP1125" - # ISO-8859-6 languages - echo "ar CP864" - echo "ar_AE CP864" - echo "ar_DZ CP864" - echo "ar_EG CP864" - echo "ar_IQ CP864" - echo "ar_IR CP864" - echo "ar_JO CP864" - echo "ar_KW CP864" - echo "ar_MA CP864" - echo "ar_OM CP864" - echo "ar_QA CP864" - echo "ar_SA CP864" - echo "ar_SY CP864" - # ISO-8859-7 languages - echo "el CP869" - echo "el_GR CP869" - # ISO-8859-8 languages - echo "he CP862" - echo "he_IL CP862" - # ISO-8859-9 languages - echo "tr CP857" - echo "tr_TR CP857" - # Japanese - echo "ja CP932" - echo "ja_JP CP932" - # Chinese - echo "zh_CN GBK" - echo "zh_TW CP950" # not CP938 ?? - # Korean - echo "kr CP949" # not CP934 ?? - echo "kr_KR CP949" # not CP934 ?? - # Thai - echo "th CP874" - echo "th_TH CP874" - # Other - echo "eo CP850" - echo "eo_EO CP850" - ;; -esac diff --git a/gl/dirname-lgpl.c b/gl/dirname-lgpl.c index 82f66301..d54f6a91 100644 --- a/gl/dirname-lgpl.c +++ b/gl/dirname-lgpl.c @@ -1,20 +1,20 @@ /* dirname.c -- return all but the last element in a file name - Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2013 Free Software + Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/dirname.c b/gl/dirname.c index 1fb65888..3d2aaf1e 100644 --- a/gl/dirname.c +++ b/gl/dirname.c @@ -1,11 +1,11 @@ /* dirname.c -- return all but the last element in a file name - Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2013 Free Software + Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2022 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 + 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, @@ -14,7 +14,7 @@ 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 . */ + along with this program. If not, see . */ #include diff --git a/gl/dirname.h b/gl/dirname.h index 4ad03120..e18a97ea 100644 --- a/gl/dirname.h +++ b/gl/dirname.h @@ -1,46 +1,54 @@ -/* Take file names apart into directory and base names. +/* Take file names apart into directory and base names. - Copyright (C) 1998, 2001, 2003-2006, 2009-2013 Free Software Foundation, - Inc. + Copyright (C) 1998, 2001, 2003-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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. + This file 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 Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef DIRNAME_H_ # define DIRNAME_H_ 1 # include -# include -# include "dosname.h" +# include +# include "filename.h" +# include "basename-lgpl.h" # ifndef DIRECTORY_SEPARATOR # define DIRECTORY_SEPARATOR '/' # endif -# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT -# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 -# endif +#ifdef __cplusplus +extern "C" { +#endif # if GNULIB_DIRNAME -char *base_name (char const *file); -char *dir_name (char const *file); +char *base_name (char const *file) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; +char *dir_name (char const *file) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; # endif -char *mdir_name (char const *file); -size_t base_len (char const *file) _GL_ATTRIBUTE_PURE; +char *mdir_name (char const *file) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; size_t dir_len (char const *file) _GL_ATTRIBUTE_PURE; -char *last_component (char const *file) _GL_ATTRIBUTE_PURE; bool strip_trailing_slashes (char *file); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* not DIRNAME_H_ */ diff --git a/gl/dosname.h b/gl/dosname.h deleted file mode 100644 index ba63ce4b..00000000 --- a/gl/dosname.h +++ /dev/null @@ -1,53 +0,0 @@ -/* File names on MS-DOS/Windows systems. - - Copyright (C) 2000-2001, 2004-2006, 2009-2013 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 . - - From Paul Eggert and Jim Meyering. */ - -#ifndef _DOSNAME_H -#define _DOSNAME_H - -#if (defined _WIN32 || defined __WIN32__ || \ - defined __MSDOS__ || defined __CYGWIN__ || \ - defined __EMX__ || defined __DJGPP__) - /* This internal macro assumes ASCII, but all hosts that support drive - letters use ASCII. */ -# define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \ - <= 'z' - 'a') -# define FILE_SYSTEM_PREFIX_LEN(Filename) \ - (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) -# ifndef __CYGWIN__ -# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 -# endif -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#else -# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 -# define ISSLASH(C) ((C) == '/') -#endif - -#ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 -#endif - -#if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) -# else -# define IS_ABSOLUTE_FILE_NAME(F) \ - (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0) -#endif -#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) - -#endif /* DOSNAME_H_ */ diff --git a/gl/dup2.c b/gl/dup2.c new file mode 100644 index 00000000..1c766ab3 --- /dev/null +++ b/gl/dup2.c @@ -0,0 +1,189 @@ +/* Duplicate an open file descriptor to a specified file descriptor. + + Copyright (C) 1999, 2004-2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* written by Paul Eggert */ + +#include + +/* Specification. */ +#include + +#include +#include + +#undef dup2 + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +# endif + +/* Get _get_osfhandle. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static int +dup2_nothrow (int fd, int desired_fd) +{ + int result; + + TRY_MSVC_INVAL + { + result = _dup2 (fd, desired_fd); + } + CATCH_MSVC_INVAL + { + errno = EBADF; + result = -1; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define dup2_nothrow _dup2 +# endif + +static int +ms_windows_dup2 (int fd, int desired_fd) +{ + int result; + + /* If fd is closed, mingw hangs on dup2 (fd, fd). If fd is open, + dup2 (fd, fd) returns 0, but all further attempts to use fd in + future dup2 calls will hang. */ + if (fd == desired_fd) + { + if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + return fd; + } + + /* Wine 1.0.1 return 0 when desired_fd is negative but not -1: + https://bugs.winehq.org/show_bug.cgi?id=21289 */ + if (desired_fd < 0) + { + errno = EBADF; + return -1; + } + + result = dup2_nothrow (fd, desired_fd); + + if (result == 0) + result = desired_fd; + + return result; +} + +# define dup2 ms_windows_dup2 + +#elif defined __KLIBC__ + +# include + +static int +klibc_dup2dirfd (int fd, int desired_fd) +{ + int tempfd; + int dupfd; + + tempfd = open ("NUL", O_RDONLY); + if (tempfd == -1) + return -1; + + if (tempfd == desired_fd) + { + close (tempfd); + + char path[_MAX_PATH]; + if (__libc_Back_ioFHToPath (fd, path, sizeof (path))) + return -1; + + return open(path, O_RDONLY); + } + + dupfd = klibc_dup2dirfd (fd, desired_fd); + + close (tempfd); + + return dupfd; +} + +static int +klibc_dup2 (int fd, int desired_fd) +{ + int dupfd; + struct stat sbuf; + + dupfd = dup2 (fd, desired_fd); + if (dupfd == -1 && errno == ENOTSUP \ + && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) + { + close (desired_fd); + + return klibc_dup2dirfd (fd, desired_fd); + } + + return dupfd; +} + +# define dup2 klibc_dup2 +#endif + +int +rpl_dup2 (int fd, int desired_fd) +{ + int result; + +#ifdef F_GETFL + /* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF. + On Cygwin 1.5.x, dup2 (1, 1) returns 0. + On Cygwin 1.7.17, dup2 (1, -1) dumps core. + On Cygwin 1.7.25, dup2 (1, 256) can dump core. + On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */ +# if HAVE_SETDTABLESIZE + setdtablesize (desired_fd + 1); +# endif + if (desired_fd < 0) + fd = desired_fd; + if (fd == desired_fd) + return fcntl (fd, F_GETFL) == -1 ? -1 : fd; +#endif + + result = dup2 (fd, desired_fd); + + /* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x. */ + if (result == -1 && errno == EMFILE) + errno = EBADF; +#if REPLACE_FCHDIR + if (fd != desired_fd && result != -1) + result = _gl_register_dup (fd, result); +#endif + return result; +} diff --git a/gl/dynarray.h b/gl/dynarray.h new file mode 100644 index 00000000..ca6439d3 --- /dev/null +++ b/gl/dynarray.h @@ -0,0 +1,284 @@ +/* Type-safe arrays which grow dynamically. + Copyright 2021-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert and Bruno Haible, 2021. */ + +#ifndef _GL_DYNARRAY_H +#define _GL_DYNARRAY_H + +/* Before including this file, you need to define: + + 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: + */ + +/* Initialize a dynamic array object. This must be called before any + use of the object. */ +#if 0 +static void + DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *list); +#endif + +/* Deallocate the dynamic array and its elements. */ +#if 0 +static void + DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *list); +#endif + +/* Return true if the dynamic array is in an error state. */ +#if 0 +static bool + DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *list); +#endif + +/* Mark the dynamic array as failed. All elements are deallocated as + a side effect. */ +#if 0 +static void + DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *list); +#endif + +/* Return the number of elements which have been added to the dynamic + array. */ +#if 0 +static size_t + DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *list); +#endif + +/* 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. */ +#if 0 +static DYNARRAY_ELEMENT * + DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *list); +#endif + +/* 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. */ +#if 0 +static DYNARRAY_ELEMENT * + DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *list); +#endif + +/* Return a pointer to the array element at INDEX. Terminate the + process if INDEX is out of bounds. */ +#if 0 +static DYNARRAY_ELEMENT * + DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *list, size_t index); +#endif + +/* 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. */ +#if 0 +static void + DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *list, + DYNARRAY_ELEMENT item); +#endif + +/* 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. */ +#if 0 +static DYNARRAY_ELEMENT * + DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *list); +#endif + +/* 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). */ +#if 0 +static bool + DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *list, size_t size); +#endif + +/* Remove the last element of LIST if it is present. */ +#if 0 +static void + DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *list); +#endif + +/* Remove all elements from the list. The elements are freed, but the + list itself is not. */ +#if 0 +static void + DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *list); +#endif + +#if defined 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. */ +#if 0 +static bool + DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list, + DYNARRAY_FINAL_TYPE *result); +#endif +#else /* !defined 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. */ +#if 0 +static DYNARRAY_ELEMENT * + DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list, + size_t *lengthp); +#endif +#endif + +/* 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 + + 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 + */ + + +/* The implementation is imported from glibc. */ + +/* Avoid possible conflicts with symbols exported by the GNU libc. */ +#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 + +#if defined DYNARRAY_STRUCT || defined DYNARRAY_ELEMENT || defined DYNARRAY_PREFIX + +# ifndef _GL_LIKELY +/* Rely on __builtin_expect, as provided by the module 'builtin-expect'. */ +# define _GL_LIKELY(cond) __builtin_expect ((cond), 1) +# define _GL_UNLIKELY(cond) __builtin_expect ((cond), 0) +# endif + +/* Define auxiliary structs and declare auxiliary functions, common to all + instantiations of dynarray. */ +# include + +/* Define the instantiation, specified through + DYNARRAY_STRUCT + DYNARRAY_ELEMENT + DYNARRAY_PREFIX + etc. */ +# include + +#else + +/* This file is being included from one of the malloc/dynarray_*.c files. */ +# include + +#endif + +#endif /* _GL_DYNARRAY_H */ diff --git a/gl/errno.in.h b/gl/errno.in.h index 49b35464..3ec18456 100644 --- a/gl/errno.in.h +++ b/gl/errno.in.h @@ -1,19 +1,19 @@ /* A POSIX-like . - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_ERRNO_H @@ -30,7 +30,7 @@ /* On native Windows platforms, many macros are not defined. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ /* These are the same values as defined by MSVC 10, for interoperability. */ @@ -248,7 +248,7 @@ interoperability. */ # define EOWNERDEAD 58 # define ENOTRECOVERABLE 59 -# elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# elif defined _WIN32 && ! defined __CYGWIN__ /* We have a conflict here: pthreads-win32 defines these values differently than MSVC 10. It's hairy to decide which one to use. */ # if defined __MINGW32__ && !defined USE_WINDOWS_THREADS diff --git a/gl/error.c b/gl/error.c index 865b2934..272d45e4 100644 --- a/gl/error.c +++ b/gl/error.c @@ -1,19 +1,19 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1990-1998, 2000-2007, 2009-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by David MacKenzie . */ @@ -39,6 +39,11 @@ # include # include # define mbsrtowcs __mbsrtowcs +# define USE_UNLOCKED_IO 0 +# define _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD(a, b) +# define _GL_ARG_NONNULL(a) +#else +# include "getprogname.h" #endif #if USE_UNLOCKED_IO @@ -72,14 +77,14 @@ extern void __error (int status, int errnum, const char *message, ...) extern void __error_at_line (int status, int errnum, const char *file_name, unsigned int line_number, const char *message, ...) - __attribute__ ((__format__ (__printf__, 5, 6)));; + __attribute__ ((__format__ (__printf__, 5, 6))); # define error __error # define error_at_line __error_at_line # include -# define fflush(s) INTUSE(_IO_fflush) (s) +# define fflush(s) _IO_fflush (s) # undef putc -# define putc(c, fp) INTUSE(_IO_putc) (c, fp) +# define putc(c, fp) _IO_putc (c, fp) # include @@ -88,35 +93,37 @@ extern void __error_at_line (int status, int errnum, const char *file_name, # include # include -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ /* Get declarations of the native Windows API functions. */ # define WIN32_LEAN_AND_MEAN # include /* Get _get_osfhandle. */ -# include "msvc-nothrow.h" +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif # endif /* The gnulib override of fcntl is not needed in this file. */ # undef fcntl -# if !HAVE_DECL_STRERROR_R +# if !(GNULIB_STRERROR_R_POSIX || HAVE_DECL_STRERROR_R) # ifndef HAVE_DECL_STRERROR_R "this configure-time declaration test was not run" # endif # if STRERROR_R_CHAR_P -char *strerror_r (); +char *strerror_r (int errnum, char *buf, size_t buflen); # else -int strerror_r (); +int strerror_r (int errnum, char *buf, size_t buflen); # endif # endif -/* The calling program should define program_name and set it to the - name of the executing program. */ -extern char *program_name; +# define program_name getprogname () -# if HAVE_STRERROR_R || defined strerror_r +# if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r # define __strerror_r strerror_r -# endif /* HAVE_STRERROR_R || defined strerror_r */ +# endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */ #endif /* not _LIBC */ #if !_LIBC @@ -124,7 +131,7 @@ extern char *program_name; static int is_open (int fd) { -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ /* On native Windows: The initial state of unassigned standard file descriptors is that they are open but point to an INVALID_HANDLE_VALUE. There is no fcntl, and the gnulib replacement fcntl does not support @@ -169,9 +176,9 @@ print_errno_message (int errnum) { char const *s; -#if defined HAVE_STRERROR_R || _LIBC +#if _LIBC || GNULIB_STRERROR_R_POSIX || defined HAVE_STRERROR_R char errbuf[1024]; -# if STRERROR_R_CHAR_P || _LIBC +# if _LIBC || (!GNULIB_STRERROR_R_POSIX && STRERROR_R_CHAR_P) s = __strerror_r (errnum, errbuf, sizeof errbuf); # else if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) @@ -195,13 +202,12 @@ print_errno_message (int errnum) #endif } -static void +static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3)) error_tail (int status, int errnum, const char *message, va_list args) { #if _LIBC if (_IO_fwide (stderr, 0) > 0) { -# define ALLOCA_LIMIT 2000 size_t len = strlen (message) + 1; wchar_t *wmessage = NULL; mbstate_t st; @@ -237,7 +243,7 @@ error_tail (int status, int errnum, const char *message, va_list args) if (res != len) break; - if (__builtin_expect (len >= SIZE_MAX / 2, 0)) + if (__builtin_expect (len >= SIZE_MAX / sizeof (wchar_t) / 2, 0)) { /* This really should not happen if everything is fine. */ res = (size_t) -1; @@ -266,7 +272,6 @@ error_tail (int status, int errnum, const char *message, va_list args) else #endif vfprintf (stderr, message, args); - va_end (args); ++error_message_count; if (errnum) @@ -316,6 +321,7 @@ error (int status, int errnum, const char *message, ...) va_start (args, message); error_tail (status, errnum, message, args); + va_end (args); #ifdef _LIBC _IO_funlockfile (stderr); @@ -342,7 +348,10 @@ error_at_line (int status, int errnum, const char *file_name, if (old_line_number == line_number && (file_name == old_file_name - || strcmp (old_file_name, file_name) == 0)) + || (old_file_name != NULL + && file_name != NULL + && strcmp (old_file_name, file_name) == 0))) + /* Simply return and print nothing. */ return; @@ -374,15 +383,16 @@ error_at_line (int status, int errnum, const char *file_name, } #if _LIBC - __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", + __fxprintf (NULL, file_name != NULL ? "%s:%u: " : " ", file_name, line_number); #else - fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", + fprintf (stderr, file_name != NULL ? "%s:%u: " : " ", file_name, line_number); #endif va_start (args, message); error_tail (status, errnum, message, args); + va_end (args); #ifdef _LIBC _IO_funlockfile (stderr); diff --git a/gl/error.h b/gl/error.h index afcb0e10..45ec2a5e 100644 --- a/gl/error.h +++ b/gl/error.h @@ -1,35 +1,26 @@ /* Declaration for error-reporting function - Copyright (C) 1995-1997, 2003, 2006, 2008-2013 Free Software Foundation, + Copyright (C) 1995-1997, 2003, 2006, 2008-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _ERROR_H #define _ERROR_H 1 -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif +/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */ +#include #ifdef __cplusplus extern "C" { @@ -40,11 +31,21 @@ extern "C" { If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ extern void error (int __status, int __errnum, const char *__format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); +#if GNULIB_VFPRINTF_POSIX + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)) +#else + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM, 3, 4)) +#endif + ; extern void error_at_line (int __status, int __errnum, const char *__fname, unsigned int __lineno, const char *__format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 5, 6)); +#if GNULIB_VFPRINTF_POSIX + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 5, 6)) +#else + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM, 5, 6)) +#endif + ; /* If NULL, error will flush stdout, then print on stderr the program name, a colon and a space. Otherwise, error will call this diff --git a/gl/exitfail.c b/gl/exitfail.c index b0b4ebe4..84fb0eff 100644 --- a/gl/exitfail.c +++ b/gl/exitfail.c @@ -1,19 +1,19 @@ /* Failure exit status - Copyright (C) 2002-2003, 2005-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2005-2007, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/exitfail.h b/gl/exitfail.h index e54333bd..865f096a 100644 --- a/gl/exitfail.h +++ b/gl/exitfail.h @@ -1,18 +1,18 @@ /* Failure exit status - Copyright (C) 2002, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2002, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ extern int volatile exit_failure; diff --git a/gl/fcntl.c b/gl/fcntl.c new file mode 100644 index 00000000..f9753c40 --- /dev/null +++ b/gl/fcntl.c @@ -0,0 +1,629 @@ +/* Provide file descriptor control. + + Copyright (C) 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Eric Blake . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include +#include +#include + +#ifdef __KLIBC__ +# define INCL_DOS +# include +#endif + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include + +/* Get _get_osfhandle. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +/* Upper bound on getdtablesize(). See lib/getdtablesize.c. */ +# define OPEN_MAX_MAX 0x10000 + +/* Duplicate OLDFD into the first available slot of at least NEWFD, + which must be positive, with FLAGS determining whether the duplicate + will be inheritable. */ +static int +dupfd (int oldfd, int newfd, int flags) +{ + /* Mingw has no way to create an arbitrary fd. Iterate until all + file descriptors less than newfd are filled up. */ + HANDLE curr_process = GetCurrentProcess (); + HANDLE old_handle = (HANDLE) _get_osfhandle (oldfd); + unsigned char fds_to_close[OPEN_MAX_MAX / CHAR_BIT]; + unsigned int fds_to_close_bound = 0; + int result; + BOOL inherit = flags & O_CLOEXEC ? FALSE : TRUE; + int mode; + + if (newfd < 0 || getdtablesize () <= newfd) + { + errno = EINVAL; + return -1; + } + if (old_handle == INVALID_HANDLE_VALUE + || (mode = _setmode (oldfd, O_BINARY)) == -1) + { + /* oldfd is not open, or is an unassigned standard file + descriptor. */ + errno = EBADF; + return -1; + } + _setmode (oldfd, mode); + flags |= mode; + + for (;;) + { + HANDLE new_handle; + int duplicated_fd; + unsigned int index; + + if (!DuplicateHandle (curr_process, /* SourceProcessHandle */ + old_handle, /* SourceHandle */ + curr_process, /* TargetProcessHandle */ + (PHANDLE) &new_handle, /* TargetHandle */ + (DWORD) 0, /* DesiredAccess */ + inherit, /* InheritHandle */ + DUPLICATE_SAME_ACCESS)) /* Options */ + { + switch (GetLastError ()) + { + case ERROR_TOO_MANY_OPEN_FILES: + errno = EMFILE; + break; + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_TARGET_HANDLE: + case ERROR_DIRECT_ACCESS_HANDLE: + errno = EBADF; + break; + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FUNCTION: + case ERROR_INVALID_ACCESS: + errno = EINVAL; + break; + default: + errno = EACCES; + break; + } + result = -1; + break; + } + duplicated_fd = _open_osfhandle ((intptr_t) new_handle, flags); + if (duplicated_fd < 0) + { + CloseHandle (new_handle); + result = -1; + break; + } + if (newfd <= duplicated_fd) + { + result = duplicated_fd; + break; + } + + /* Set the bit duplicated_fd in fds_to_close[]. */ + index = (unsigned int) duplicated_fd / CHAR_BIT; + if (fds_to_close_bound <= index) + { + if (sizeof fds_to_close <= index) + /* Need to increase OPEN_MAX_MAX. */ + abort (); + memset (fds_to_close + fds_to_close_bound, '\0', + index + 1 - fds_to_close_bound); + fds_to_close_bound = index + 1; + } + fds_to_close[index] |= 1 << ((unsigned int) duplicated_fd % CHAR_BIT); + } + + /* Close the previous fds that turned out to be too small. */ + { + int saved_errno = errno; + unsigned int duplicated_fd; + + for (duplicated_fd = 0; + duplicated_fd < fds_to_close_bound * CHAR_BIT; + duplicated_fd++) + if ((fds_to_close[duplicated_fd / CHAR_BIT] + >> (duplicated_fd % CHAR_BIT)) + & 1) + close (duplicated_fd); + + errno = saved_errno; + } + +# if REPLACE_FCHDIR + if (0 <= result) + result = _gl_register_dup (oldfd, result); +# endif + return result; +} +#endif /* W32 */ + +/* Forward declarations, because we '#undef fcntl' in the middle of this + compilation unit. */ +/* Our implementation of fcntl (fd, F_DUPFD, target). */ +static int rpl_fcntl_DUPFD (int fd, int target); +/* Our implementation of fcntl (fd, F_DUPFD_CLOEXEC, target). */ +static int rpl_fcntl_DUPFD_CLOEXEC (int fd, int target); +#ifdef __KLIBC__ +/* Adds support for fcntl on directories. */ +static int klibc_fcntl (int fd, int action, /* arg */...); +#endif + + +/* Perform the specified ACTION on the file descriptor FD, possibly + using the argument ARG further described below. This replacement + handles the following actions, and forwards all others on to the + native fcntl. An unrecognized ACTION returns -1 with errno set to + EINVAL. + + F_DUPFD - duplicate FD, with int ARG being the minimum target fd. + If successful, return the duplicate, which will be inheritable; + otherwise return -1 and set errno. + + F_DUPFD_CLOEXEC - duplicate FD, with int ARG being the minimum + target fd. If successful, return the duplicate, which will not be + inheritable; otherwise return -1 and set errno. + + F_GETFD - ARG need not be present. If successful, return a + non-negative value containing the descriptor flags of FD (only + FD_CLOEXEC is portable, but other flags may be present); otherwise + return -1 and set errno. */ + +int +fcntl (int fd, int action, /* arg */...) +#undef fcntl +#ifdef __KLIBC__ +# define fcntl klibc_fcntl +#endif +{ + va_list arg; + int result = -1; + va_start (arg, action); + switch (action) + { + case F_DUPFD: + { + int target = va_arg (arg, int); + result = rpl_fcntl_DUPFD (fd, target); + break; + } + + case F_DUPFD_CLOEXEC: + { + int target = va_arg (arg, int); + result = rpl_fcntl_DUPFD_CLOEXEC (fd, target); + break; + } + +#if !HAVE_FCNTL + case F_GETFD: + { +# if defined _WIN32 && ! defined __CYGWIN__ + HANDLE handle = (HANDLE) _get_osfhandle (fd); + DWORD flags; + if (handle == INVALID_HANDLE_VALUE + || GetHandleInformation (handle, &flags) == 0) + errno = EBADF; + else + result = (flags & HANDLE_FLAG_INHERIT) ? 0 : FD_CLOEXEC; +# else /* !W32 */ + /* Use dup2 to reject invalid file descriptors. No way to + access this information, so punt. */ + if (0 <= dup2 (fd, fd)) + result = 0; +# endif /* !W32 */ + break; + } /* F_GETFD */ +#endif /* !HAVE_FCNTL */ + + /* Implementing F_SETFD on mingw is not trivial - there is no + API for changing the O_NOINHERIT bit on an fd, and merely + changing the HANDLE_FLAG_INHERIT bit on the underlying handle + can lead to odd state. It may be possible by duplicating the + handle, using _open_osfhandle with the right flags, then + using dup2 to move the duplicate onto the original, but that + is not supported for now. */ + + default: + { +#if HAVE_FCNTL + switch (action) + { + #ifdef F_BARRIERFSYNC /* macOS */ + case F_BARRIERFSYNC: + #endif + #ifdef F_CHKCLEAN /* macOS */ + case F_CHKCLEAN: + #endif + #ifdef F_CLOSEM /* NetBSD, HP-UX */ + case F_CLOSEM: + #endif + #ifdef F_FLUSH_DATA /* macOS */ + case F_FLUSH_DATA: + #endif + #ifdef F_FREEZE_FS /* macOS */ + case F_FREEZE_FS: + #endif + #ifdef F_FULLFSYNC /* macOS */ + case F_FULLFSYNC: + #endif + #ifdef F_GETCONFINED /* macOS */ + case F_GETCONFINED: + #endif + #ifdef F_GETDEFAULTPROTLEVEL /* macOS */ + case F_GETDEFAULTPROTLEVEL: + #endif + #ifdef F_GETFD /* POSIX */ + case F_GETFD: + #endif + #ifdef F_GETFL /* POSIX */ + case F_GETFL: + #endif + #ifdef F_GETLEASE /* Linux */ + case F_GETLEASE: + #endif + #ifdef F_GETNOSIGPIPE /* macOS */ + case F_GETNOSIGPIPE: + #endif + #ifdef F_GETOWN /* POSIX */ + case F_GETOWN: + #endif + #ifdef F_GETPIPE_SZ /* Linux */ + case F_GETPIPE_SZ: + #endif + #ifdef F_GETPROTECTIONCLASS /* macOS */ + case F_GETPROTECTIONCLASS: + #endif + #ifdef F_GETPROTECTIONLEVEL /* macOS */ + case F_GETPROTECTIONLEVEL: + #endif + #ifdef F_GET_SEALS /* Linux */ + case F_GET_SEALS: + #endif + #ifdef F_GETSIG /* Linux */ + case F_GETSIG: + #endif + #ifdef F_MAXFD /* NetBSD */ + case F_MAXFD: + #endif + #ifdef F_RECYCLE /* macOS */ + case F_RECYCLE: + #endif + #ifdef F_SETFIFOENH /* HP-UX */ + case F_SETFIFOENH: + #endif + #ifdef F_THAW_FS /* macOS */ + case F_THAW_FS: + #endif + /* These actions take no argument. */ + result = fcntl (fd, action); + break; + + #ifdef F_ADD_SEALS /* Linux */ + case F_ADD_SEALS: + #endif + #ifdef F_BADFD /* Solaris */ + case F_BADFD: + #endif + #ifdef F_CHECK_OPENEVT /* macOS */ + case F_CHECK_OPENEVT: + #endif + #ifdef F_DUP2FD /* FreeBSD, AIX, Solaris */ + case F_DUP2FD: + #endif + #ifdef F_DUP2FD_CLOEXEC /* FreeBSD, Solaris */ + case F_DUP2FD_CLOEXEC: + #endif + #ifdef F_DUP2FD_CLOFORK /* Solaris */ + case F_DUP2FD_CLOFORK: + #endif + #ifdef F_DUPFD /* POSIX */ + case F_DUPFD: + #endif + #ifdef F_DUPFD_CLOEXEC /* POSIX */ + case F_DUPFD_CLOEXEC: + #endif + #ifdef F_DUPFD_CLOFORK /* Solaris */ + case F_DUPFD_CLOFORK: + #endif + #ifdef F_GETXFL /* Solaris */ + case F_GETXFL: + #endif + #ifdef F_GLOBAL_NOCACHE /* macOS */ + case F_GLOBAL_NOCACHE: + #endif + #ifdef F_MAKECOMPRESSED /* macOS */ + case F_MAKECOMPRESSED: + #endif + #ifdef F_MOVEDATAEXTENTS /* macOS */ + case F_MOVEDATAEXTENTS: + #endif + #ifdef F_NOCACHE /* macOS */ + case F_NOCACHE: + #endif + #ifdef F_NODIRECT /* macOS */ + case F_NODIRECT: + #endif + #ifdef F_NOTIFY /* Linux */ + case F_NOTIFY: + #endif + #ifdef F_OPLKACK /* IRIX */ + case F_OPLKACK: + #endif + #ifdef F_OPLKREG /* IRIX */ + case F_OPLKREG: + #endif + #ifdef F_RDAHEAD /* macOS */ + case F_RDAHEAD: + #endif + #ifdef F_SETBACKINGSTORE /* macOS */ + case F_SETBACKINGSTORE: + #endif + #ifdef F_SETCONFINED /* macOS */ + case F_SETCONFINED: + #endif + #ifdef F_SETFD /* POSIX */ + case F_SETFD: + #endif + #ifdef F_SETFL /* POSIX */ + case F_SETFL: + #endif + #ifdef F_SETLEASE /* Linux */ + case F_SETLEASE: + #endif + #ifdef F_SETNOSIGPIPE /* macOS */ + case F_SETNOSIGPIPE: + #endif + #ifdef F_SETOWN /* POSIX */ + case F_SETOWN: + #endif + #ifdef F_SETPIPE_SZ /* Linux */ + case F_SETPIPE_SZ: + #endif + #ifdef F_SETPROTECTIONCLASS /* macOS */ + case F_SETPROTECTIONCLASS: + #endif + #ifdef F_SETSIG /* Linux */ + case F_SETSIG: + #endif + #ifdef F_SINGLE_WRITER /* macOS */ + case F_SINGLE_WRITER: + #endif + /* These actions take an 'int' argument. */ + { + int x = va_arg (arg, int); + result = fcntl (fd, action, x); + } + break; + + default: + /* Other actions take a pointer argument. */ + { + void *p = va_arg (arg, void *); + result = fcntl (fd, action, p); + } + break; + } +#else + errno = EINVAL; +#endif + break; + } + } + va_end (arg); + return result; +} + +static int +rpl_fcntl_DUPFD (int fd, int target) +{ + int result; +#if !HAVE_FCNTL + result = dupfd (fd, target, 0); +#elif FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR + /* Detect invalid target; needed for cygwin 1.5.x. */ + if (target < 0 || getdtablesize () <= target) + { + result = -1; + errno = EINVAL; + } + else + { + /* Haiku alpha 2 loses fd flags on original. */ + int flags = fcntl (fd, F_GETFD); + if (flags < 0) + result = -1; + else + { + result = fcntl (fd, F_DUPFD, target); + if (0 <= result && fcntl (fd, F_SETFD, flags) == -1) + { + int saved_errno = errno; + close (result); + result = -1; + errno = saved_errno; + } +# if REPLACE_FCHDIR + if (0 <= result) + result = _gl_register_dup (fd, result); +# endif + } + } +#else + result = fcntl (fd, F_DUPFD, target); +#endif + return result; +} + +static int +rpl_fcntl_DUPFD_CLOEXEC (int fd, int target) +{ + int result; +#if !HAVE_FCNTL + result = dupfd (fd, target, O_CLOEXEC); +#else /* HAVE_FCNTL */ +# if defined __NetBSD__ || defined __HAIKU__ + /* On NetBSD 9.0, the system fcntl (fd, F_DUPFD_CLOEXEC, target) + has only the same effect as fcntl (fd, F_DUPFD, target). */ + /* On Haiku, the system fcntl (fd, F_DUPFD_CLOEXEC, target) sets + the FD_CLOEXEC flag on fd, not on target. Therefore avoid the + system fcntl in this case. */ +# define have_dupfd_cloexec -1 +# else + /* Try the system call first, if the headers claim it exists + (that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we + may be running with a glibc that has the macro but with an + older kernel that does not support it. Cache the + information on whether the system call really works, but + avoid caching failure if the corresponding F_DUPFD fails + for any reason. 0 = unknown, 1 = yes, -1 = no. */ + static int have_dupfd_cloexec = GNULIB_defined_F_DUPFD_CLOEXEC ? -1 : 0; + if (0 <= have_dupfd_cloexec) + { + result = fcntl (fd, F_DUPFD_CLOEXEC, target); + if (0 <= result || errno != EINVAL) + { + have_dupfd_cloexec = 1; +# if REPLACE_FCHDIR + if (0 <= result) + result = _gl_register_dup (fd, result); +# endif + } + else + { + result = rpl_fcntl_DUPFD (fd, target); + if (result >= 0) + have_dupfd_cloexec = -1; + } + } + else +# endif + result = rpl_fcntl_DUPFD (fd, target); + if (0 <= result && have_dupfd_cloexec == -1) + { + int flags = fcntl (result, F_GETFD); + if (flags < 0 || fcntl (result, F_SETFD, flags | FD_CLOEXEC) == -1) + { + int saved_errno = errno; + close (result); + errno = saved_errno; + result = -1; + } + } +#endif /* HAVE_FCNTL */ + return result; +} + +#undef fcntl + +#ifdef __KLIBC__ + +static int +klibc_fcntl (int fd, int action, /* arg */...) +{ + va_list arg_ptr; + int arg; + struct stat sbuf; + int result; + + va_start (arg_ptr, action); + arg = va_arg (arg_ptr, int); + result = fcntl (fd, action, arg); + /* EPERM for F_DUPFD, ENOTSUP for others */ + if (result == -1 && (errno == EPERM || errno == ENOTSUP) + && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) + { + ULONG ulMode; + + switch (action) + { + case F_DUPFD: + /* Find available fd */ + while (fcntl (arg, F_GETFL) != -1 || errno != EBADF) + arg++; + + result = dup2 (fd, arg); + break; + + /* Using underlying APIs is right ? */ + case F_GETFD: + if (DosQueryFHState (fd, &ulMode)) + break; + + result = (ulMode & OPEN_FLAGS_NOINHERIT) ? FD_CLOEXEC : 0; + break; + + case F_SETFD: + if (arg & ~FD_CLOEXEC) + break; + + if (DosQueryFHState (fd, &ulMode)) + break; + + if (arg & FD_CLOEXEC) + ulMode |= OPEN_FLAGS_NOINHERIT; + else + ulMode &= ~OPEN_FLAGS_NOINHERIT; + + /* Filter supported flags. */ + ulMode &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR + | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT); + + if (DosSetFHState (fd, ulMode)) + break; + + result = 0; + break; + + case F_GETFL: + result = 0; + break; + + case F_SETFL: + if (arg != 0) + break; + + result = 0; + break; + + default: + errno = EINVAL; + break; + } + } + + va_end (arg_ptr); + + return result; +} + +#endif diff --git a/gl/fcntl.in.h b/gl/fcntl.in.h new file mode 100644 index 00000000..9270ced8 --- /dev/null +++ b/gl/fcntl.in.h @@ -0,0 +1,445 @@ +/* Like , but with non-working flags defined to 0. + + Copyright (C) 2006-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* written by Paul Eggert */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_system_fcntl_h +/* Special invocation convention. */ + +/* Needed before . + May also define off_t to a 64-bit type on native Windows. */ +#include +/* On some systems other than glibc, is a prerequisite of + . On glibc systems, we would like to avoid namespace pollution. + But on glibc systems, includes inside an + extern "C" { ... } block, which leads to errors in C++ mode with the + overridden from gnulib. These errors are known to be gone + with g++ version >= 4.3. */ +#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && (defined __ICC || !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))) +# include +#endif +#@INCLUDE_NEXT@ @NEXT_FCNTL_H@ + +/* Native Windows platforms declare open(), creat() in . */ +#if (@GNULIB_CREAT@ || @GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \ + && (defined _WIN32 && ! defined __CYGWIN__) +# include +#endif + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_FCNTL_H + +/* Needed before . + May also define off_t to a 64-bit type on native Windows. */ +#include +/* On some systems other than glibc, is a prerequisite of + . On glibc systems, we would like to avoid namespace pollution. + But on glibc systems, includes inside an + extern "C" { ... } block, which leads to errors in C++ mode with the + overridden from gnulib. These errors are known to be gone + with g++ version >= 4.3. */ +#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && (defined __ICC || !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))) +# include +#endif +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_FCNTL_H@ + +/* Native Windows platforms declare open(), creat() in . */ +#if (@GNULIB_CREAT@ || @GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \ + && (defined _WIN32 && ! defined __CYGWIN__) +# include +#endif + +#ifndef _@GUARD_PREFIX@_FCNTL_H +#define _@GUARD_PREFIX@_FCNTL_H + +#ifndef __GLIBC__ /* Avoid namespace pollution on glibc systems. */ +# include +#endif + + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Declare overridden functions. */ + +#if @GNULIB_CREAT@ +# if @REPLACE_CREAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef creat +# define creat rpl_creat +# endif +_GL_FUNCDECL_RPL (creat, int, (const char *filename, mode_t mode) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (creat, int, (const char *filename, mode_t mode)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef creat +# define creat _creat +# endif +_GL_CXXALIAS_MDA (creat, int, (const char *filename, mode_t mode)); +# else +_GL_CXXALIAS_SYS (creat, int, (const char *filename, mode_t mode)); +# endif +_GL_CXXALIASWARN (creat); +#elif defined GNULIB_POSIXCHECK +# undef creat +/* Assume creat is always declared. */ +_GL_WARN_ON_USE (creat, "creat is not always POSIX compliant - " + "use gnulib module creat for portability"); +#elif @GNULIB_MDA_CREAT@ +/* On native Windows, map 'creat' to '_creat', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::creat always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef creat +# define creat _creat +# endif +/* Need to cast, because in mingw the last argument is 'int mode'. */ +_GL_CXXALIAS_MDA_CAST (creat, int, (const char *filename, mode_t mode)); +# else +_GL_CXXALIAS_SYS (creat, int, (const char *filename, mode_t mode)); +# endif +_GL_CXXALIASWARN (creat); +#endif + +#if @GNULIB_FCNTL@ +# if @REPLACE_FCNTL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fcntl +# define fcntl rpl_fcntl +# endif +_GL_FUNCDECL_RPL (fcntl, int, (int fd, int action, ...)); +_GL_CXXALIAS_RPL (fcntl, int, (int fd, int action, ...)); +# if !GNULIB_defined_rpl_fcntl +# define GNULIB_defined_rpl_fcntl 1 +# endif +# else +# if !@HAVE_FCNTL@ +_GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...)); +# if !GNULIB_defined_fcntl +# define GNULIB_defined_fcntl 1 +# endif +# endif +_GL_CXXALIAS_SYS (fcntl, int, (int fd, int action, ...)); +# endif +_GL_CXXALIASWARN (fcntl); +#elif defined GNULIB_POSIXCHECK +# undef fcntl +# if HAVE_RAW_DECL_FCNTL +_GL_WARN_ON_USE (fcntl, "fcntl is not always POSIX compliant - " + "use gnulib module fcntl for portability"); +# endif +#endif + +#if @GNULIB_OPEN@ +# if @REPLACE_OPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef open +# define open rpl_open +# endif +_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef open +# define open _open +# endif +_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); +# else +_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); +# endif +/* On HP-UX 11, in C++ mode, open() is defined as an inline function with a + default argument. _GL_CXXALIASWARN does not work in this case. */ +# if !defined __hpux +_GL_CXXALIASWARN (open); +# endif +#elif defined GNULIB_POSIXCHECK +# undef open +/* Assume open is always declared. */ +_GL_WARN_ON_USE (open, "open is not always POSIX compliant - " + "use gnulib module open for portability"); +#elif @GNULIB_MDA_OPEN@ +/* On native Windows, map 'open' to '_open', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::open always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef open +# define open _open +# endif +_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); +# else +_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); +# endif +# if !defined __hpux +_GL_CXXALIASWARN (open); +# endif +#endif + +#if @GNULIB_OPENAT@ +# if @REPLACE_OPENAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef openat +# define openat rpl_openat +# endif +_GL_FUNCDECL_RPL (openat, int, + (int fd, char const *file, int flags, /* mode_t mode */ ...) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (openat, int, + (int fd, char const *file, int flags, /* mode_t mode */ ...)); +# else +# if !@HAVE_OPENAT@ +_GL_FUNCDECL_SYS (openat, int, + (int fd, char const *file, int flags, /* mode_t mode */ ...) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (openat, int, + (int fd, char const *file, int flags, /* mode_t mode */ ...)); +# endif +_GL_CXXALIASWARN (openat); +#elif defined GNULIB_POSIXCHECK +# undef openat +# if HAVE_RAW_DECL_OPENAT +_GL_WARN_ON_USE (openat, "openat is not portable - " + "use gnulib module openat for portability"); +# endif +#endif + + +/* Fix up the FD_* macros, only known to be missing on mingw. */ + +#ifndef FD_CLOEXEC +# define FD_CLOEXEC 1 +#endif + +/* Fix up the supported F_* macros. Intentionally leave other F_* + macros undefined. Only known to be missing on mingw. */ + +#ifndef F_DUPFD_CLOEXEC +# define F_DUPFD_CLOEXEC 0x40000000 +/* Witness variable: 1 if gnulib defined F_DUPFD_CLOEXEC, 0 otherwise. */ +# define GNULIB_defined_F_DUPFD_CLOEXEC 1 +#else +# define GNULIB_defined_F_DUPFD_CLOEXEC 0 +#endif + +#ifndef F_DUPFD +# define F_DUPFD 1 +#endif + +#ifndef F_GETFD +# define F_GETFD 2 +#endif + +/* Fix up the O_* macros. */ + +/* AIX 7.1 with XL C 12.1 defines O_CLOEXEC, O_NOFOLLOW, and O_TTY_INIT + to values outside 'int' range, so omit these misdefinitions. + But avoid namespace pollution on non-AIX systems. */ +#ifdef _AIX +# include +# if defined O_CLOEXEC && ! (INT_MIN <= O_CLOEXEC && O_CLOEXEC <= INT_MAX) +# undef O_CLOEXEC +# endif +# if defined O_NOFOLLOW && ! (INT_MIN <= O_NOFOLLOW && O_NOFOLLOW <= INT_MAX) +# undef O_NOFOLLOW +# endif +# if defined O_TTY_INIT && ! (INT_MIN <= O_TTY_INIT && O_TTY_INIT <= INT_MAX) +# undef O_TTY_INIT +# endif +#endif + +#if !defined O_DIRECT && defined O_DIRECTIO +/* Tru64 spells it 'O_DIRECTIO'. */ +# define O_DIRECT O_DIRECTIO +#endif + +#if !defined O_CLOEXEC && defined O_NOINHERIT +/* Mingw spells it 'O_NOINHERIT'. */ +# define O_CLOEXEC O_NOINHERIT +#endif + +#ifndef O_CLOEXEC +# define O_CLOEXEC 0x40000000 /* Try to not collide with system O_* flags. */ +# define GNULIB_defined_O_CLOEXEC 1 +#else +# define GNULIB_defined_O_CLOEXEC 0 +#endif + +#ifndef O_DIRECT +# define O_DIRECT 0 +#endif + +#ifndef O_DIRECTORY +# define O_DIRECTORY 0 +#endif + +#ifndef O_DSYNC +# define O_DSYNC 0 +#endif + +#ifndef O_EXEC +# define O_EXEC O_RDONLY /* This is often close enough in older systems. */ +#endif + +#ifndef O_IGNORE_CTTY +# define O_IGNORE_CTTY 0 +#endif + +#ifndef O_NDELAY +# define O_NDELAY 0 +#endif + +#ifndef O_NOATIME +# define O_NOATIME 0 +#endif + +#ifndef O_NONBLOCK +# define O_NONBLOCK O_NDELAY +#endif + +/* If the gnulib module 'nonblocking' is in use, guarantee a working non-zero + value of O_NONBLOCK. Otherwise, O_NONBLOCK is defined (above) to O_NDELAY + or to 0 as fallback. */ +#if @GNULIB_NONBLOCKING@ +# if O_NONBLOCK +# define GNULIB_defined_O_NONBLOCK 0 +# else +# define GNULIB_defined_O_NONBLOCK 1 +# undef O_NONBLOCK +# define O_NONBLOCK 0x40000000 +# endif +#endif + +#ifndef O_NOCTTY +# define O_NOCTTY 0 +#endif + +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + +#ifndef O_NOLINK +# define O_NOLINK 0 +#endif + +#ifndef O_NOLINKS +# define O_NOLINKS 0 +#endif + +#ifndef O_NOTRANS +# define O_NOTRANS 0 +#endif + +#ifndef O_RSYNC +# define O_RSYNC 0 +#endif + +#ifndef O_SEARCH +# define O_SEARCH O_RDONLY /* This is often close enough in older systems. */ +#endif + +#ifndef O_SYNC +# define O_SYNC 0 +#endif + +#ifndef O_TTY_INIT +# define O_TTY_INIT 0 +#endif + +#if ~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH) +# undef O_ACCMODE +# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH) +#endif + +/* For systems that distinguish between text and binary I/O. + O_BINARY is usually declared in fcntl.h */ +#if !defined O_BINARY && defined _O_BINARY + /* For MSC-compatible compilers. */ +# define O_BINARY _O_BINARY +# define O_TEXT _O_TEXT +#endif + +#if defined __BEOS__ || defined __HAIKU__ + /* BeOS 5 and Haiku have O_BINARY and O_TEXT, but they have no effect. */ +# undef O_BINARY +# undef O_TEXT +#endif + +#ifndef O_BINARY +# define O_BINARY 0 +# define O_TEXT 0 +#endif + +/* Fix up the AT_* macros. */ + +/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its + value exceeds INT_MAX, so its use as an int doesn't conform to the + C standard, and GCC and Sun C complain in some cases. If the bug + is present, undef AT_FDCWD here, so it can be redefined below. */ +#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553 +# undef AT_FDCWD +#endif + +/* Use the same bit pattern as Solaris 9, but with the proper + signedness. The bit pattern is important, in case this actually is + Solaris with the above workaround. */ +#ifndef AT_FDCWD +# define AT_FDCWD (-3041965) +#endif + +/* Use the same values as Solaris 9. This shouldn't matter, but + there's no real reason to differ. */ +#ifndef AT_SYMLINK_NOFOLLOW +# define AT_SYMLINK_NOFOLLOW 4096 +#endif + +#ifndef AT_REMOVEDIR +# define AT_REMOVEDIR 1 +#endif + +/* Solaris 9 lacks these two, so just pick unique values. */ +#ifndef AT_SYMLINK_FOLLOW +# define AT_SYMLINK_FOLLOW 2 +#endif + +#ifndef AT_EACCESS +# define AT_EACCESS 4 +#endif + +/* Ignore this flag if not supported. */ +#ifndef AT_NO_AUTOMOUNT +# define AT_NO_AUTOMOUNT 0 +#endif + +#endif /* _@GUARD_PREFIX@_FCNTL_H */ +#endif /* _@GUARD_PREFIX@_FCNTL_H */ +#endif diff --git a/gl/fd-hook.c b/gl/fd-hook.c index e158a52a..64a7a80c 100644 --- a/gl/fd-hook.c +++ b/gl/fd-hook.c @@ -1,19 +1,19 @@ -/* Hook for making making file descriptor functions close(), ioctl() extensible. - Copyright (C) 2009-2013 Free Software Foundation, Inc. +/* Hook for making file descriptor functions close(), ioctl() extensible. + Copyright (C) 2009-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2009. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/fd-hook.h b/gl/fd-hook.h index d15b5771..d6c4964d 100644 --- a/gl/fd-hook.h +++ b/gl/fd-hook.h @@ -1,18 +1,18 @@ -/* Hook for making making file descriptor functions close(), ioctl() extensible. - Copyright (C) 2009-2013 Free Software Foundation, Inc. +/* Hook for making file descriptor functions close(), ioctl() extensible. + Copyright (C) 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef FD_HOOK_H diff --git a/gl/fflush.c b/gl/fflush.c new file mode 100644 index 00000000..69511cde --- /dev/null +++ b/gl/fflush.c @@ -0,0 +1,233 @@ +/* fflush.c -- allow flushing input streams + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Eric Blake. */ + +#include + +/* Specification. */ +#include + +#include +#include + +#include "freading.h" + +#include "stdio-impl.h" + +#undef fflush + + +#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 +/* GNU libc, BeOS, Haiku, Linux libc5 */ + +/* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ +static void +clear_ungetc_buffer_preserving_position (FILE *fp) +{ + if (fp->_flags & _IO_IN_BACKUP) + /* _IO_free_backup_area is a bit complicated. Simply call fseek. */ + fseeko (fp, 0, SEEK_CUR); +} + +#else + +/* Clear the stream's ungetc buffer. May modify the value of ftello (fp). */ +static void +clear_ungetc_buffer (FILE *fp) +{ +# if defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + if (HASUB (fp)) + { + fp_->_p += fp_->_r; + fp_->_r = 0; + } +# elif defined __EMX__ /* emx+gcc */ + if (fp->_ungetc_count > 0) + { + fp->_ungetc_count = 0; + fp->_rcount = - fp->_rcount; + } +# elif defined _IOERR /* Minix, AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ + /* Nothing to do. */ +# else /* other implementations */ + fseeko (fp, 0, SEEK_CUR); +# endif +} + +#endif + +#if ! (defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1) +/* GNU libc, BeOS, Haiku, Linux libc5 */ + +# if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT +/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + +static int +disable_seek_optimization (FILE *fp) +{ + int saved_flags = fp_->_flags & (__SOPT | __SNPT); + fp_->_flags = (fp_->_flags & ~__SOPT) | __SNPT; + return saved_flags; +} + +static void +restore_seek_optimization (FILE *fp, int saved_flags) +{ + fp_->_flags = (fp_->_flags & ~(__SOPT | __SNPT)) | saved_flags; +} + +# else + +static void +update_fpos_cache (_GL_ATTRIBUTE_MAYBE_UNUSED FILE *fp, + _GL_ATTRIBUTE_MAYBE_UNUSED off_t pos) +{ +# if defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +# if defined __CYGWIN__ + /* fp_->_offset is typed as an integer. */ + fp_->_offset = pos; +# else + /* fp_->_offset is an fpos_t. */ + /* Use a union, since on NetBSD, the compilation flags determine + whether fpos_t is typedef'd to off_t or a struct containing a + single off_t member. */ + union + { + fpos_t f; + off_t o; + } u; + u.o = pos; + fp_->_offset = u.f; +# endif + fp_->_flags |= __SOFF; +# endif +} +# endif +#endif + +/* Flush all pending data on STREAM according to POSIX rules. Both + output and seekable input streams are supported. */ +int +rpl_fflush (FILE *stream) +{ + /* When stream is NULL, POSIX and C99 only require flushing of "output + streams and update streams in which the most recent operation was not + input", and all implementations do this. + + When stream is "an output stream or an update stream in which the most + recent operation was not input", POSIX and C99 requires that fflush + writes out any buffered data, and all implementations do this. + + When stream is, however, an input stream or an update stream in + which the most recent operation was input, C99 specifies nothing, + and POSIX only specifies behavior if the stream is seekable. + mingw, in particular, drops the input buffer, leaving the file + descriptor positioned at the end of the input buffer. I.e. ftell + (stream) is lost. We don't want to call the implementation's + fflush in this case. + + We test ! freading (stream) here, rather than fwriting (stream), because + what we need to know is whether the stream holds a "read buffer", and on + mingw this is indicated by _IOREAD, regardless of _IOWRT. */ + if (stream == NULL || ! freading (stream)) + return fflush (stream); + +#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 + /* GNU libc, BeOS, Haiku, Linux libc5 */ + + clear_ungetc_buffer_preserving_position (stream); + + return fflush (stream); + +#else + { + /* What POSIX says: + 1) About the file-position indicator (-> fseeko, ftello): + The file position indicator is incremented by fgetc() and decremented + by ungetc(): + + "... the fgetc() function shall ... advance the associated file + position indicator for the stream ..." + + "The file-position indicator is decremented by each successful + call to ungetc()..." + 2) fflush discards bytes pushed back by ungetc: + + "...any characters pushed back onto the stream by ungetc() + or ungetwc() that have not subsequently been read from the + stream shall be discarded..." + This implies implicitly: fflush does not change the file position + indicator. + 3) Effects on the file descriptor, if the file descriptor is capable of + seeking: + + "...the file offset of the underlying open file description shall + be set to the file position of the stream..." */ + + /* POSIX does not specify fflush behavior for non-seekable input + streams. Some implementations purge unread data, some return + EBADF, some do nothing. */ + off_t pos = ftello (stream); + if (pos == -1) + { + errno = EBADF; + return EOF; + } + + /* Clear the ungetc buffer. */ + clear_ungetc_buffer (stream); + + /* To get here, we must be flushing a seekable input stream, so the + semantics of fpurge are now appropriate to clear the buffer. To + avoid losing data, the lseek is also necessary. */ + { + int result = fpurge (stream); + if (result != 0) + return result; + } + +# if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + + { + /* Disable seek optimization for the next fseeko call. This tells the + following fseeko call to seek to the desired position directly, rather + than to seek to a block-aligned boundary. */ + int saved_flags = disable_seek_optimization (stream); + int result = fseeko (stream, pos, SEEK_SET); + + restore_seek_optimization (stream, saved_flags); + return result; + } + +# else + + pos = lseek (fileno (stream), pos, SEEK_SET); + if (pos == -1) + return EOF; + /* After a successful lseek, update the file descriptor's position cache + in the stream. */ + update_fpos_cache (stream, pos); + + return 0; + +# endif + } +#endif +} diff --git a/gl/filename.h b/gl/filename.h new file mode 100644 index 00000000..ab77ca2d --- /dev/null +++ b/gl/filename.h @@ -0,0 +1,112 @@ +/* Basic filename support macros. + Copyright (C) 2001-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* From Paul Eggert and Jim Meyering. */ + +#ifndef _FILENAME_H +#define _FILENAME_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Filename support. + ISSLASH(C) tests whether C is a directory separator + character. + HAS_DEVICE(Filename) tests whether Filename contains a device + specification. + FILE_SYSTEM_PREFIX_LEN(Filename) length of the device specification + at the beginning of Filename, + index of the part consisting of + alternating components and slashes. + FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE + 1 when a non-empty device specification + can be followed by an empty or relative + part, + 0 when a non-empty device specification + must be followed by a slash, + 0 when device specification don't exist. + IS_ABSOLUTE_FILE_NAME(Filename) + tests whether Filename is independent of + any notion of "current directory". + IS_RELATIVE_FILE_NAME(Filename) + tests whether Filename may be concatenated + to a directory filename. + Note: On native Windows, OS/2, DOS, "c:" is neither an absolute nor a + relative file name! + IS_FILE_NAME_WITH_DIR(Filename) tests whether Filename contains a device + or directory specification. + */ +#if defined _WIN32 || defined __CYGWIN__ \ + || defined __EMX__ || defined __MSDOS__ || defined __DJGPP__ + /* Native Windows, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') + /* Internal macro: Tests whether a character is a drive letter. */ +# define _IS_DRIVE_LETTER(C) \ + (((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z')) + /* Help the compiler optimizing it. This assumes ASCII. */ +# undef _IS_DRIVE_LETTER +# define _IS_DRIVE_LETTER(C) \ + (((unsigned int) (C) | ('a' - 'A')) - 'a' <= 'z' - 'a') +# define HAS_DEVICE(Filename) \ + (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':') +# define FILE_SYSTEM_PREFIX_LEN(Filename) (HAS_DEVICE (Filename) ? 2 : 0) +# ifdef __CYGWIN__ +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 +# else + /* On native Windows, OS/2, DOS, the system has the notion of a + "current directory" on each drive. */ +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 +# endif +# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE +# define IS_ABSOLUTE_FILE_NAME(Filename) \ + ISSLASH ((Filename)[FILE_SYSTEM_PREFIX_LEN (Filename)]) +# else +# define IS_ABSOLUTE_FILE_NAME(Filename) \ + (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename)) +# endif +# define IS_RELATIVE_FILE_NAME(Filename) \ + (! (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename))) +# define IS_FILE_NAME_WITH_DIR(Filename) \ + (strchr ((Filename), '/') != NULL || strchr ((Filename), '\\') != NULL \ + || HAS_DEVICE (Filename)) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define HAS_DEVICE(Filename) ((void) (Filename), 0) +# define FILE_SYSTEM_PREFIX_LEN(Filename) ((void) (Filename), 0) +# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 +# define IS_ABSOLUTE_FILE_NAME(Filename) ISSLASH ((Filename)[0]) +# define IS_RELATIVE_FILE_NAME(Filename) (! ISSLASH ((Filename)[0])) +# define IS_FILE_NAME_WITH_DIR(Filename) (strchr ((Filename), '/') != NULL) +#endif + +/* Deprecated macros. For backward compatibility with old users of the + 'filename' module. */ +#define IS_ABSOLUTE_PATH IS_ABSOLUTE_FILE_NAME +#define IS_PATH_WITH_DIR IS_FILE_NAME_WITH_DIR + + +#ifdef __cplusplus +} +#endif + +#endif /* _FILENAME_H */ diff --git a/gl/float+.h b/gl/float+.h index 32fb790b..9ab45208 100644 --- a/gl/float+.h +++ b/gl/float+.h @@ -1,19 +1,19 @@ /* Supplemental information about the floating-point formats. - Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2007. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _FLOATPLUS_H #define _FLOATPLUS_H diff --git a/gl/float.c b/gl/float.c index 366945fa..de850645 100644 --- a/gl/float.c +++ b/gl/float.c @@ -1,19 +1,19 @@ /* Auxiliary definitions for . - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2011. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/float.in.h b/gl/float.in.h index 84e1950f..a4183765 100644 --- a/gl/float.in.h +++ b/gl/float.in.h @@ -1,19 +1,19 @@ /* A correct . - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_FLOAT_H @@ -62,8 +62,8 @@ /* On FreeBSD/x86 6.4, the 'long double' type really has only 53 bits of precision in the compiler but 64 bits of precision at runtime. See - . */ -#if defined __i386__ && defined __FreeBSD__ + . */ +#if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__) /* Number of mantissa units, in base FLT_RADIX. */ # undef LDBL_MANT_DIG # define LDBL_MANT_DIG 64 @@ -81,7 +81,7 @@ # define LDBL_MAX_EXP 16384 /* Minimum positive normalized number. */ # undef LDBL_MIN -# define LDBL_MIN 3.3621031431120935E-4932L /* = 0x1p-16382L */ +# define LDBL_MIN 3.362103143112093506262677817321752E-4932L /* = 0x1p-16382L */ /* Maximum representable finite number. */ # undef LDBL_MAX /* LDBL_MAX is represented as { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }. @@ -93,11 +93,14 @@ extern const long double LDBL_MAX; Unfortunately, this is not a constant expression. */ +# if !GNULIB_defined_long_double_union union gl_long_double_union { struct { unsigned int lo; unsigned int hi; unsigned int exponent; } xd; long double ld; }; +# define GNULIB_defined_long_double_union 1 +# endif extern const union gl_long_double_union gl_LDBL_MAX; # define LDBL_MAX (gl_LDBL_MAX.ld) /* Minimum e such that 10^e is in the range of normalized numbers. */ @@ -146,11 +149,14 @@ extern const union gl_long_double_union gl_LDBL_MAX; Unfortunately, this is not a constant expression, and the latter expression does not work well when GCC is optimizing.. */ +# if !GNULIB_defined_long_double_union union gl_long_double_union { struct { double hi; double lo; } dd; long double ld; }; +# define GNULIB_defined_long_double_union 1 +# endif extern const union gl_long_double_union gl_LDBL_MAX; # define LDBL_MAX (gl_LDBL_MAX.ld) #endif diff --git a/gl/floor.c b/gl/floor.c index cf29b196..3e4f8d05 100644 --- a/gl/floor.c +++ b/gl/floor.c @@ -1,18 +1,18 @@ /* Round towards negative infinity. - Copyright (C) 2007, 2010-2013 Free Software Foundation, Inc. + Copyright (C) 2007, 2010-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2007. */ @@ -44,7 +44,7 @@ /* MSVC with option -fp:strict refuses to compile constant initializers that contain floating-point operations. Pacify this compiler. */ -#ifdef _MSC_VER +#if defined _MSC_VER && !defined __clang__ # pragma fenv_access (off) #endif diff --git a/gl/floorf.c b/gl/floorf.c index bbd3382e..457ec750 100644 --- a/gl/floorf.c +++ b/gl/floorf.c @@ -1,18 +1,18 @@ /* Round towards negative infinity. - Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2007, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2007. */ diff --git a/gl/fopen.c b/gl/fopen.c new file mode 100644 index 00000000..a5b3ae38 --- /dev/null +++ b/gl/fopen.c @@ -0,0 +1,230 @@ +/* Open a stream to a file. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2007. */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_fopen doesn't recurse to + rpl_fopen. */ +#define _GL_ALREADY_INCLUDING_STDIO_H +#include + +/* Get the original definition of fopen. It might be defined as a macro. */ +#include +#undef _GL_ALREADY_INCLUDING_STDIO_H + +static FILE * +orig_fopen (const char *filename, const char *mode) +{ + return fopen (filename, mode); +} + +/* Specification. */ +/* Write "stdio.h" here, not , otherwise OSF/1 5.1 DTK cc eliminates + this include because of the preliminary #include above. */ +#include "stdio.h" + +#include +#include +#include +#include +#include +#include +#include + +FILE * +rpl_fopen (const char *filename, const char *mode) +{ + int open_direction; + int open_flags; +#if GNULIB_FOPEN_GNU + bool open_flags_gnu; +# define BUF_SIZE 80 + char fdopen_mode_buf[BUF_SIZE + 1]; +#endif + +#if defined _WIN32 && ! defined __CYGWIN__ + if (strcmp (filename, "/dev/null") == 0) + filename = "NUL"; +#endif + + /* Parse the mode. */ + open_direction = 0; + open_flags = 0; +#if GNULIB_FOPEN_GNU + open_flags_gnu = false; +#endif + { + const char *p = mode; +#if GNULIB_FOPEN_GNU + char *q = fdopen_mode_buf; +#endif + + for (; *p != '\0'; p++) + { + switch (*p) + { + case 'r': + open_direction = O_RDONLY; +#if GNULIB_FOPEN_GNU + if (q < fdopen_mode_buf + BUF_SIZE) + *q++ = *p; +#endif + continue; + case 'w': + open_direction = O_WRONLY; + open_flags |= O_CREAT | O_TRUNC; +#if GNULIB_FOPEN_GNU + if (q < fdopen_mode_buf + BUF_SIZE) + *q++ = *p; +#endif + continue; + case 'a': + open_direction = O_WRONLY; + open_flags |= O_CREAT | O_APPEND; +#if GNULIB_FOPEN_GNU + if (q < fdopen_mode_buf + BUF_SIZE) + *q++ = *p; +#endif + continue; + case 'b': + /* While it is non-standard, O_BINARY is guaranteed by + gnulib . We can also assume that orig_fopen + supports the 'b' flag. */ + open_flags |= O_BINARY; +#if GNULIB_FOPEN_GNU + if (q < fdopen_mode_buf + BUF_SIZE) + *q++ = *p; +#endif + continue; + case '+': + open_direction = O_RDWR; +#if GNULIB_FOPEN_GNU + if (q < fdopen_mode_buf + BUF_SIZE) + *q++ = *p; +#endif + continue; +#if GNULIB_FOPEN_GNU + case 'x': + open_flags |= O_EXCL; + open_flags_gnu = true; + continue; + case 'e': + open_flags |= O_CLOEXEC; + open_flags_gnu = true; + continue; +#endif + default: + break; + } +#if GNULIB_FOPEN_GNU + /* The rest of the mode string can be a platform-dependent extension. + Copy it unmodified. */ + { + size_t len = strlen (p); + if (len > fdopen_mode_buf + BUF_SIZE - q) + len = fdopen_mode_buf + BUF_SIZE - q; + memcpy (q, p, len); + q += len; + } +#endif + break; + } +#if GNULIB_FOPEN_GNU + *q = '\0'; +#endif + } + +#if FOPEN_TRAILING_SLASH_BUG + /* Fail if the mode requires write access and the filename ends in a slash, + as POSIX says such a filename must name a directory + : + "A pathname that contains at least one non- character and that + ends with one or more trailing characters shall not be resolved + successfully unless the last pathname component before the trailing + characters names an existing directory" + If the named file already exists as a directory, then if a mode that + requires write access is specified, fopen() must fail because POSIX + + says that it fails with errno = EISDIR in this case. + If the named file does not exist or does not name a directory, then + fopen() must fail since the file does not contain a '.' directory. */ + { + size_t len = strlen (filename); + if (len > 0 && filename[len - 1] == '/') + { + int fd; + struct stat statbuf; + FILE *fp; + + if (open_direction != O_RDONLY) + { + errno = EISDIR; + return NULL; + } + + fd = open (filename, open_direction | open_flags, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (fd < 0) + return NULL; + + if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) + { + close (fd); + errno = ENOTDIR; + return NULL; + } + +# if GNULIB_FOPEN_GNU + fp = fdopen (fd, fdopen_mode_buf); +# else + fp = fdopen (fd, mode); +# endif + if (fp == NULL) + { + int saved_errno = errno; + close (fd); + errno = saved_errno; + } + return fp; + } + } +#endif + +#if GNULIB_FOPEN_GNU + if (open_flags_gnu) + { + int fd; + FILE *fp; + + fd = open (filename, open_direction | open_flags, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (fd < 0) + return NULL; + + fp = fdopen (fd, fdopen_mode_buf); + if (fp == NULL) + { + int saved_errno = errno; + close (fd); + errno = saved_errno; + } + return fp; + } +#endif + + return orig_fopen (filename, mode); +} diff --git a/gl/fpurge.c b/gl/fpurge.c new file mode 100644 index 00000000..21e3b862 --- /dev/null +++ b/gl/fpurge.c @@ -0,0 +1,150 @@ +/* Flushing buffers of a FILE stream. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.10, Android API >= 23, musl libc */ +# if HAVE_STDIO_EXT_H +# include +# endif +#endif +#include + +#include "stdio-impl.h" + +int +fpurge (FILE *fp) +{ +#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.10, Android API >= 23, musl libc */ + + __fpurge (fp); + /* The __fpurge function does not have a return value. */ + return 0; + +#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin >= 1.7 */ + + /* Call the system's fpurge function. */ +# undef fpurge +# if !HAVE_DECL_FPURGE + extern int fpurge (FILE *); +# endif + int result = fpurge (fp); +# if defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + if (result == 0) + /* Correct the invariants that fpurge broke. + on BSD systems says: + "The following always hold: if _flags & __SRD, _w is 0." + If this invariant is not fulfilled and the stream is read-write but + currently reading, subsequent putc or fputc calls will write directly + into the buffer, although they shouldn't be allowed to. */ + if ((fp_->_flags & __SRD) != 0) + fp_->_w = 0; +# endif + return result; + +#else + + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 + /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_IO_read_end = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_write_base; + /* Avoid memory leak when there is an active ungetc buffer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_IO_save_base = NULL; + } + return 0; +# elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + fp_->_p = fp_->_bf._base; + fp_->_r = 0; + fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ + ? fp_->_bf._size + : 0); + /* Avoid memory leak when there is an active ungetc buffer. */ + if (fp_ub._base != NULL) + { + if (fp_ub._base != fp_->_ubuf) + free (fp_ub._base); + fp_ub._base = NULL; + } + return 0; +# elif defined __EMX__ /* emx+gcc */ + fp->_ptr = fp->_buffer; + fp->_rcount = 0; + fp->_wcount = 0; + fp->_ungetc_count = 0; + return 0; +# elif defined __minix /* Minix */ + fp->_ptr = fp->_buf; + if (fp->_ptr != NULL) + fp->_count = 0; + return 0; +# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ + fp_->_ptr = fp_->_base; + if (fp_->_ptr != NULL) + fp_->_cnt = 0; + return 0; +# elif defined __UCLIBC__ /* uClibc */ +# ifdef __STDIO_BUFFERS + if (fp->__modeflags & __FLAG_WRITING) + fp->__bufpos = fp->__bufstart; + else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) + fp->__bufpos = fp->__bufread; +# endif + return 0; +# elif defined __QNX__ /* QNX */ + fp->_Rback = fp->_Back + sizeof (fp->_Back); + fp->_Rsave = NULL; + if (fp->_Mode & 0x2000 /* _MWRITE */) + /* fp->_Buf <= fp->_Next <= fp->_Wend */ + fp->_Next = fp->_Buf; + else + /* fp->_Buf <= fp->_Next <= fp->_Rend */ + fp->_Rend = fp->_Next; + return 0; +# elif defined __MINT__ /* Atari FreeMiNT */ + if (fp->__pushed_back) + { + fp->__bufp = fp->__pushback_bufp; + fp->__pushed_back = 0; + } + /* Preserve the current file position. */ + if (fp->__target != -1) + fp->__target += fp->__bufp - fp->__buffer; + fp->__bufp = fp->__buffer; + /* Nothing in the buffer, next getc is nontrivial. */ + fp->__get_limit = fp->__bufp; + /* Nothing in the buffer, next putc is nontrivial. */ + fp->__put_limit = fp->__buffer; + return 0; +# elif defined EPLAN9 /* Plan9 */ + fp->rp = fp->wp = fp->lp = fp->buf; + return 0; +# else +# error "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib." +# endif + +#endif +} diff --git a/gl/freading.c b/gl/freading.c new file mode 100644 index 00000000..93e96e00 --- /dev/null +++ b/gl/freading.c @@ -0,0 +1,76 @@ +/* Retrieve information about a FILE stream. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "freading.h" + +#include "stdio-impl.h" + +/* Don't use glibc's __freading function in glibc < 2.7, see + */ +#if !(HAVE___FREADING && (!defined __GLIBC__ || defined __UCLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))) + +bool +freading (FILE *fp) +{ + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 + /* GNU libc, BeOS, Haiku, Linux libc5 */ + return ((fp->_flags & _IO_NO_WRITES) != 0 + || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 + && fp->_IO_read_base != NULL)); +# elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */ + return (fp_->_flags & __SRD) != 0; +# elif defined __EMX__ /* emx+gcc */ + return (fp->_flags & _IOREAD) != 0; +# elif defined __minix /* Minix */ + return (fp->_flags & _IOREADING) != 0; +# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ +# if defined __sun /* Solaris */ + return (fp_->_flag & _IOREAD) != 0 && (fp_->_flag & _IOWRT) == 0; +# else + return (fp_->_flag & _IOREAD) != 0; +# endif +# elif defined __UCLIBC__ /* uClibc */ + return (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) != 0; +# elif defined __QNX__ /* QNX */ + return ((fp->_Mode & 0x2 /* _MOPENW */) == 0 + || (fp->_Mode & 0x1000 /* _MREAD */) != 0); +# elif defined __MINT__ /* Atari FreeMiNT */ + if (!fp->__mode.__write) + return 1; + if (!fp->__mode.__read) + return 0; +# ifdef _IO_CURRENTLY_GETTING /* Flag added on 2009-02-28 */ + return (fp->__flags & _IO_CURRENTLY_GETTING) != 0; +# else + return (fp->__buffer < fp->__get_limit /*|| fp->__bufp == fp->__put_limit ??*/); +# endif +# elif defined EPLAN9 /* Plan9 */ + if (fp->state == 0 /* CLOSED */ || fp->state == 4 /* WR */) + return 0; + return (fp->state == 3 /* RD */ && (fp->bufl == 0 || fp->rp < fp->wp)); +# else +# error "Please port gnulib freading.c to your platform!" +# endif +} + +#endif diff --git a/gl/freading.h b/gl/freading.h new file mode 100644 index 00000000..74fed227 --- /dev/null +++ b/gl/freading.h @@ -0,0 +1,55 @@ +/* Retrieve information about a FILE stream. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include +#include + +/* Return true if the stream STREAM is opened read-only, or if the + last operation on the stream was a read operation. Return false if + the stream is opened write-only or append-only, or if it supports + writing and there is no current read operation (such as fgetc). + + freading and fwriting will never both be true. If STREAM supports + both reads and writes, then: + - both freading and fwriting might be false when the stream is first + opened, after read encounters EOF, or after fflush, + - freading might be false or true and fwriting might be false + after repositioning (such as fseek, fsetpos, or rewind), + depending on the underlying implementation. + + STREAM must not be wide-character oriented. */ + +#if HAVE___FREADING && (!defined __GLIBC__ || defined __UCLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) +/* Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.34, Android API >= 29, not glibc >= 2.2, but glibc >= 2.7, or musl libc */ + +# if HAVE_STDIO_EXT_H +# include +# endif +# define freading(stream) (__freading (stream) != 0) + +#else + +# ifdef __cplusplus +extern "C" { +# endif + +extern bool freading (FILE *stream) _GL_ATTRIBUTE_PURE; + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/gl/free.c b/gl/free.c new file mode 100644 index 00000000..86ebe6c6 --- /dev/null +++ b/gl/free.c @@ -0,0 +1,53 @@ +/* Make free() preserve errno. + + Copyright (C) 2003, 2006, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* written by Paul Eggert */ + +#include + +/* Specification. */ +#include + +/* A function definition is only needed if HAVE_FREE_POSIX is not defined. */ +#if !HAVE_FREE_POSIX + +# include + +void +rpl_free (void *p) +# undef free +{ +# if defined __GNUC__ && !defined __clang__ + /* An invalid GCC optimization + + 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 +} + +#endif diff --git a/gl/fseek.c b/gl/fseek.c new file mode 100644 index 00000000..e9f93141 --- /dev/null +++ b/gl/fseek.c @@ -0,0 +1,30 @@ +/* An fseek() function that, together with fflush(), is POSIX compliant. + Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Get off_t. */ +#include + +int +fseek (FILE *fp, long offset, int whence) +{ + /* Use the replacement fseeko function with all its workarounds. */ + return fseeko (fp, (off_t)offset, whence); +} diff --git a/gl/fseeko.c b/gl/fseeko.c new file mode 100644 index 00000000..2ca2db88 --- /dev/null +++ b/gl/fseeko.c @@ -0,0 +1,164 @@ +/* An fseeko() function that, together with fflush(), is POSIX compliant. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Get off_t, lseek, _POSIX_VERSION. */ +#include + +#include "stdio-impl.h" + +int +fseeko (FILE *fp, off_t offset, int whence) +#undef fseeko +#if !HAVE_FSEEKO +# undef fseek +# define fseeko fseek +#endif +#if _GL_WINDOWS_64_BIT_OFF_T +# undef fseeko +# if HAVE__FSEEKI64 && HAVE_DECL__FSEEKI64 /* msvc, mingw since msvcrt8.0, mingw64 */ +# define fseeko _fseeki64 +# else /* mingw before msvcrt8.0 */ +# define fseeko fseeko64 +# endif +#endif +{ +#if LSEEK_PIPE_BROKEN + /* mingw gives bogus answers rather than failure on non-seekable files. */ + if (lseek (fileno (fp), 0, SEEK_CUR) == -1) + return EOF; +#endif + + /* These tests are based on fpurge.c. */ +#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 + /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_read_end == fp->_IO_read_ptr + && fp->_IO_write_ptr == fp->_IO_write_base + && fp->_IO_save_base == NULL) +#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +# if defined __SL64 && defined __SCLE /* Cygwin */ + if ((fp->_flags & __SL64) == 0) + { + /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit + mode; but has an fseeko that requires 64-bit mode. */ + FILE *tmp = fopen ("/dev/null", "r"); + if (!tmp) + return -1; + fp->_flags |= __SL64; + fp->_seek64 = tmp->_seek64; + fclose (tmp); + } +# endif + if (fp_->_p == fp_->_bf._base + && fp_->_r == 0 + && fp_->_w == ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ + ? fp_->_bf._size + : 0) + && fp_ub._base == NULL) +#elif defined __EMX__ /* emx+gcc */ + if (fp->_ptr == fp->_buffer + && fp->_rcount == 0 + && fp->_wcount == 0 + && fp->_ungetc_count == 0) +#elif defined __minix /* Minix */ + if (fp_->_ptr == fp_->_buf + && (fp_->_ptr == NULL || fp_->_count == 0)) +#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ + if (fp_->_ptr == fp_->_base + && (fp_->_ptr == NULL || fp_->_cnt == 0)) +#elif defined __UCLIBC__ /* uClibc */ + if (((fp->__modeflags & __FLAG_WRITING) == 0 + || fp->__bufpos == fp->__bufstart) + && ((fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) == 0 + || fp->__bufpos == fp->__bufread)) +#elif defined __QNX__ /* QNX */ + if ((fp->_Mode & 0x2000 /* _MWRITE */ ? fp->_Next == fp->_Buf : fp->_Next == fp->_Rend) + && fp->_Rback == fp->_Back + sizeof (fp->_Back) + && fp->_Rsave == NULL) +#elif defined __MINT__ /* Atari FreeMiNT */ + if (fp->__bufp == fp->__buffer + && fp->__get_limit == fp->__bufp + && fp->__put_limit == fp->__bufp + && !fp->__pushed_back) +#elif defined EPLAN9 /* Plan9 */ + if (fp->rp == fp->buf + && fp->wp == fp->buf) +#elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION + /* Cross-compiling to some other system advertising conformance to + POSIX.1-2008 or later. Assume fseeko and fflush work as advertised. + If this assumption is incorrect, please report the bug to + bug-gnulib. */ + if (0) +#else + #error "Please port gnulib fseeko.c to your platform! Look at the code in fseeko.c, then report this to bug-gnulib." +#endif + { + /* We get here when an fflush() call immediately preceded this one (or + if ftell() has created buffers but no I/O has occurred on a + newly-opened stream). We know there are no buffers. */ + off_t pos = lseek (fileno (fp), offset, whence); + if (pos == -1) + { +#if defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + fp_->_flags &= ~__SOFF; +#endif + return -1; + } + +#if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 + /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_flags &= ~_IO_EOF_SEEN; + fp->_offset = pos; +#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +# if defined __CYGWIN__ || (defined __NetBSD__ && __NetBSD_Version__ >= 600000000) || defined __minix + /* fp_->_offset is typed as an integer. */ + fp_->_offset = pos; +# else + /* fp_->_offset is an fpos_t. */ + { + /* Use a union, since on NetBSD, the compilation flags + determine whether fpos_t is typedef'd to off_t or a struct + containing a single off_t member. */ + union + { + fpos_t f; + off_t o; + } u; + u.o = pos; + fp_->_offset = u.f; + } +# endif + fp_->_flags |= __SOFF; + fp_->_flags &= ~__SEOF; +#elif defined __EMX__ /* emx+gcc */ + fp->_flags &= ~_IOEOF; +#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ + fp_->_flag &= ~_IOEOF; +#elif defined __MINT__ /* Atari FreeMiNT */ + fp->__offset = pos; + fp->__eof = 0; +#endif + return 0; + } + return fseeko (fp, offset, whence); +} diff --git a/gl/fstat.c b/gl/fstat.c new file mode 100644 index 00000000..3928c860 --- /dev/null +++ b/gl/fstat.c @@ -0,0 +1,94 @@ +/* fstat() replacement. + Copyright (C) 2011-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_fstat doesn't recurse to + rpl_fstat. */ +#define __need_system_sys_stat_h +#include + +/* Get the original definition of fstat. It might be defined as a macro. */ +#include +#include +#undef __need_system_sys_stat_h + +#if defined _WIN32 && ! defined __CYGWIN__ +# define WINDOWS_NATIVE +#endif + +#if !defined WINDOWS_NATIVE + +static int +orig_fstat (int fd, struct stat *buf) +{ + return fstat (fd, buf); +} + +#endif + +/* Specification. */ +#ifdef __osf__ +/* Write "sys/stat.h" here, not , otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include + above. */ +# include "sys/stat.h" +#else +# include +#endif + +#include "stat-time.h" + +#include +#include +#ifdef WINDOWS_NATIVE +# define WIN32_LEAN_AND_MEAN +# include +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif +# include "stat-w32.h" +#endif + +int +rpl_fstat (int fd, struct stat *buf) +{ +#if REPLACE_FCHDIR && REPLACE_OPEN_DIRECTORY + /* Handle the case when rpl_open() used a dummy file descriptor to work + around an open() that can't normally visit directories. */ + const char *name = _gl_directory_name (fd); + if (name != NULL) + return stat (name, buf); +#endif + +#ifdef WINDOWS_NATIVE + /* Fill the fields ourselves, because the original fstat function returns + values for st_atime, st_mtime, st_ctime that depend on the current time + zone. See + */ + HANDLE h = (HANDLE) _get_osfhandle (fd); + + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + return _gl_fstat_by_handle (h, NULL, buf); +#else + return stat_time_normalize (orig_fstat (fd, buf), buf); +#endif +} diff --git a/gl/fsusage.c b/gl/fsusage.c index 6103ecf3..18f790f6 100644 --- a/gl/fsusage.c +++ b/gl/fsusage.c @@ -1,20 +1,20 @@ /* fsusage.c -- return space usage of mounted file systems - Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2013 Free Software + Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -43,23 +43,11 @@ # if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */ # include # endif -# if defined HAVE_SYS_FILSYS_H && !defined _CRAY -# include /* SVR2 */ -# endif # if HAVE_SYS_STATFS_H # include # endif -# if HAVE_DUSTAT_H /* AIX PS/2 */ -# include -# endif -# include "full-read.h" #endif -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close - /* Many space usage primitives use all 1 bits to denote a value that is not applicable or unknown. Propagate this information by returning a uintmax_t value that is all 1 bits if X is all 1 bits, even if X @@ -143,7 +131,6 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (vfsd.f_bavail) != 0; fsp->fsu_files = PROPAGATE_ALL_ONES (vfsd.f_files); fsp->fsu_ffree = PROPAGATE_ALL_ONES (vfsd.f_ffree); - fsp->fsu_favail = PROPAGATE_ALL_ONES (vfsd.f_favail); return 0; } @@ -161,58 +148,6 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) ? PROPAGATE_ALL_ONES (fsd.f_frsize) : PROPAGATE_ALL_ONES (fsd.f_bsize)); -#elif defined STAT_STATFS2_FS_DATA /* Ultrix */ - - struct fs_data fsd; - - if (statfs (file, &fsd) != 1) - return -1; - - fsp->fsu_blocksize = 1024; - fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.fd_req.btot); - fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.fd_req.bfree); - fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.fd_req.bfreen); - fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.fd_req.bfreen) != 0; - fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot); - fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree); - fsp->fsu_favail = PROPAGATE_ALL_ONES (fsd.fd_req.gfree); - -#elif defined STAT_READ_FILSYS /* SVR2 */ -# ifndef SUPERBOFF -# define SUPERBOFF (SUPERB * 512) -# endif - - struct filsys fsd; - int fd; - - if (! disk) - { - errno = 0; - return -1; - } - - fd = open (disk, O_RDONLY); - if (fd < 0) - return -1; - lseek (fd, (off_t) SUPERBOFF, 0); - if (full_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd) - { - close (fd); - return -1; - } - close (fd); - - fsp->fsu_blocksize = (fsd.s_type == Fs2b ? 1024 : 512); - fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.s_fsize); - fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.s_tfree); - fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree); - fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0; - fsp->fsu_files = (fsd.s_isize == -1 - ? UINTMAX_MAX - : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1)); - fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode); - fsp->fsu_favail = PROPAGATE_ALL_ONES (fsd.s_tinode); - #elif defined STAT_STATFS3_OSF1 /* OSF/1 */ struct statfs fsd; @@ -266,12 +201,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); -#elif defined STAT_STATFS4 /* SVR3, Dynix, old Irix, old AIX, \ - Dolphin */ - -# if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN -# define f_bavail f_bfree -# endif +#elif defined STAT_STATFS4 /* SVR3, old Irix */ struct statfs fsd; @@ -281,11 +211,7 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) /* Empirically, the block counts on most SVR3 and SVR3-derived systems seem to always be in terms of 512-byte blocks, no matter what value f_bsize has. */ -# if _AIX || defined _CRAY - fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); -# else fsp->fsu_blocksize = 512; -# endif #endif @@ -299,38 +225,9 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0; fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files); fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree); - fsp->fsu_favail = PROPAGATE_ALL_ONES (fsd.f_ffree); #endif (void) disk; /* avoid argument-unused warning */ return 0; } - -#if defined _AIX && defined _I386 -/* AIX PS/2 does not supply statfs. */ - -int -statfs (char *file, struct statfs *fsb) -{ - struct stat stats; - struct dustat fsd; - - if (stat (file, &stats) != 0) - return -1; - if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd))) - return -1; - fsb->f_type = 0; - fsb->f_bsize = fsd.du_bsize; - fsb->f_blocks = fsd.du_fsize - fsd.du_isize; - fsb->f_bfree = fsd.du_tfree; - fsb->f_bavail = fsd.du_tfree; - fsb->f_files = (fsd.du_isize - 2) * fsd.du_inopb; - fsb->f_ffree = fsd.du_tinode; - fsb->f_favail = fsd.du_tinode; - fsb->f_fsid.val[0] = fsd.du_site; - fsb->f_fsid.val[1] = fsd.du_pckno; - return 0; -} - -#endif /* _AIX && _I386 */ diff --git a/gl/fsusage.h b/gl/fsusage.h index e2654fd8..0443d19f 100644 --- a/gl/fsusage.h +++ b/gl/fsusage.h @@ -1,20 +1,20 @@ /* fsusage.h -- declarations for file system space usage info - Copyright (C) 1991-1992, 1997, 2003-2006, 2009-2013 Free Software + Copyright (C) 1991-1992, 1997, 2003-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Space usage statistics for a file system. Blocks are 512-byte. */ @@ -32,8 +32,7 @@ struct fs_usage uintmax_t fsu_bavail; /* Free blocks available to non-superuser. */ bool fsu_bavail_top_bit_set; /* 1 if fsu_bavail represents a value < 0. */ uintmax_t fsu_files; /* Total file nodes. */ - uintmax_t fsu_ffree; /* Free file nodes to superuser. */ - uintmax_t fsu_favail; /* Free file nodes to non-superuser. */ + uintmax_t fsu_ffree; /* Free file nodes. */ }; int get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp); diff --git a/gl/ftell.c b/gl/ftell.c new file mode 100644 index 00000000..3fbd9e95 --- /dev/null +++ b/gl/ftell.c @@ -0,0 +1,37 @@ +/* An ftell() function that works around platform bugs. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include + +long +ftell (FILE *fp) +{ + /* Use the replacement ftello function with all its workarounds. */ + off_t offset = ftello (fp); + if (LONG_MIN <= offset && offset <= LONG_MAX) + return /* (long) */ offset; + else + { + errno = EOVERFLOW; + return -1; + } +} diff --git a/gl/ftello.c b/gl/ftello.c new file mode 100644 index 00000000..989614a0 --- /dev/null +++ b/gl/ftello.c @@ -0,0 +1,157 @@ +/* An ftello() function that works around platform bugs. + Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include "intprops.h" + +/* Get lseek. */ +#include + +#include "stdio-impl.h" + +off_t +ftello (FILE *fp) +#undef ftello +#if !HAVE_FTELLO +# undef ftell +# define ftello ftell +#endif +#if _GL_WINDOWS_64_BIT_OFF_T +# undef ftello +# if HAVE__FTELLI64 /* msvc, mingw64 */ +# define ftello _ftelli64 +# else /* mingw */ +# define ftello ftello64 +# endif +#endif +{ +#if FTELLO_BROKEN_AFTER_UNGETC /* macOS >= 10.15 */ + /* The system's ftello() is completely broken, because it calls __sflush, + which makes side effects on the stream. */ + + /* Handle non-seekable files first. */ + if (fp->_file < 0 || fp->_seek == NULL) + { + errno = ESPIPE; + return -1; + } + + /* Determine the current offset, ignoring buffered and pushed-back bytes. */ + off_t pos; + + if (fp->_flags & __SOFF) + pos = fp->_offset; + else + { + pos = fp->_seek (fp->_cookie, 0, SEEK_CUR); + if (pos < 0) + return -1; + if (fp->_flags & __SOPT) + { + fp->_offset = pos; + fp->_flags |= __SOFF; + } + } + + if (fp->_flags & __SRD) + { + /* Now consider buffered and pushed-back bytes from ungetc. */ + if (fp->_ub._base != NULL) + /* Considering the buffered bytes, we are at position + pos - fp->_ur. + Considering also the pushed-back bytes, we are at position + pos - fp->_ur - fp->_r. */ + pos = pos - fp->_ur - fp->_r; + else + /* Considering the buffered bytes, we are at position + pos - fp->_r. */ + pos = pos - fp->_r; + if (pos < 0) + { + errno = EIO; + return -1; + } + } + else if ((fp->_flags & __SWR) && fp->_p != NULL) + { + /* Consider the buffered bytes. */ + off_t buffered = fp->_p - fp->_bf._base; + + /* Compute pos + buffered, with overflow check. */ + off_t sum; + if (! INT_ADD_OK (pos, buffered, &sum)) + { + errno = EOVERFLOW; + return -1; + } + pos = sum; + } + + return pos; + +#else + +# if LSEEK_PIPE_BROKEN + /* mingw gives bogus answers rather than failure on non-seekable files. */ + if (lseek (fileno (fp), 0, SEEK_CUR) == -1) + return -1; +# endif + +# if FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE /* Solaris */ + /* The Solaris stdio leaves the _IOREAD flag set after reading from a file + reaches EOF and the program then starts writing to the file. ftello + gets confused by this. */ + if (fp_->_flag & _IOWRT) + { + off_t pos; + + /* Call ftello nevertheless, for the side effects that it does on fp. */ + ftello (fp); + + /* Compute the file position ourselves. */ + pos = lseek (fileno (fp), (off_t) 0, SEEK_CUR); + if (pos >= 0) + { + if ((fp_->_flag & _IONBF) == 0 && fp_->_base != NULL) + pos += fp_->_ptr - fp_->_base; + } + return pos; + } +# endif + +# if defined __SL64 && defined __SCLE /* Cygwin */ + if ((fp->_flags & __SL64) == 0) + { + /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit + mode; but has an ftello that requires 64-bit mode. */ + FILE *tmp = fopen ("/dev/null", "r"); + if (!tmp) + return -1; + fp->_flags |= __SL64; + fp->_seek64 = tmp->_seek64; + fclose (tmp); + } +# endif + + return ftello (fp); + +#endif +} diff --git a/gl/full-read.c b/gl/full-read.c deleted file mode 100644 index a0dc82c2..00000000 --- a/gl/full-read.c +++ /dev/null @@ -1,18 +0,0 @@ -/* An interface to read that retries after partial reads and interrupts. - Copyright (C) 2002-2003, 2009-2013 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 . */ - -#define FULL_READ -#include "full-write.c" diff --git a/gl/full-read.h b/gl/full-read.h deleted file mode 100644 index 66c8c5c1..00000000 --- a/gl/full-read.h +++ /dev/null @@ -1,24 +0,0 @@ -/* An interface to read() that reads all it is asked to read. - - Copyright (C) 2002, 2009-2013 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, read to the Free Software Foundation, - along with this program. If not, see . */ - -#include - -/* Read COUNT bytes at BUF to descriptor FD, retrying if interrupted - or if partial reads occur. Return the number of bytes successfully - read, setting errno if that is less than COUNT. errno = 0 means EOF. */ -extern size_t full_read (int fd, void *buf, size_t count); diff --git a/gl/full-write.c b/gl/full-write.c deleted file mode 100644 index beb5bf95..00000000 --- a/gl/full-write.c +++ /dev/null @@ -1,79 +0,0 @@ -/* An interface to read and write that retries (if necessary) until complete. - - Copyright (C) 1993-1994, 1997-2006, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#ifdef FULL_READ -# include "full-read.h" -#else -# include "full-write.h" -#endif - -#include - -#ifdef FULL_READ -# include "safe-read.h" -# define safe_rw safe_read -# define full_rw full_read -# undef const -# define const /* empty */ -#else -# include "safe-write.h" -# define safe_rw safe_write -# define full_rw full_write -#endif - -#ifdef FULL_READ -/* Set errno to zero upon EOF. */ -# define ZERO_BYTE_TRANSFER_ERRNO 0 -#else -/* Some buggy drivers return 0 when one tries to write beyond - a device's end. (Example: Linux 1.2.13 on /dev/fd0.) - Set errno to ENOSPC so they get a sensible diagnostic. */ -# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC -#endif - -/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if - interrupted or if a partial write(read) occurs. Return the number - of bytes transferred. - When writing, set errno if fewer than COUNT bytes are written. - When reading, if fewer than COUNT bytes are read, you must examine - errno to distinguish failure from EOF (errno == 0). */ -size_t -full_rw (int fd, const void *buf, size_t count) -{ - size_t total = 0; - const char *ptr = (const char *) buf; - - while (count > 0) - { - size_t n_rw = safe_rw (fd, ptr, count); - if (n_rw == (size_t) -1) - break; - if (n_rw == 0) - { - errno = ZERO_BYTE_TRANSFER_ERRNO; - break; - } - total += n_rw; - ptr += n_rw; - count -= n_rw; - } - - return total; -} diff --git a/gl/gai_strerror.c b/gl/gai_strerror.c index 1e371d27..c7eedb2f 100644 --- a/gl/gai_strerror.c +++ b/gl/gai_strerror.c @@ -1,20 +1,20 @@ -/* Copyright (C) 1997, 2001-2002, 2004-2006, 2008-2013 Free Software +/* Copyright (C) 1997, 2001-2002, 2004-2006, 2008-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Philip Blundell , 1997. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _LIBC # include diff --git a/gl/getaddrinfo.c b/gl/getaddrinfo.c index 58d28115..39228985 100644 --- a/gl/getaddrinfo.c +++ b/gl/getaddrinfo.c @@ -1,19 +1,19 @@ /* Get address information (partial implementation). - Copyright (C) 1997, 2001-2002, 2004-2013 Free Software Foundation, Inc. + Copyright (C) 1997, 2001-2002, 2004-2022 Free Software Foundation, Inc. Contributed by Simon Josefsson . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc optimizes away the sa == NULL test below. */ @@ -54,14 +54,48 @@ # define PF_UNSPEC 0 #endif -#if defined _WIN32 || defined __WIN32__ -# define WINDOWS_NATIVE -#endif +#if HAVE_GETADDRINFO + +/* Override with cdecl calling convention. */ + +int +getaddrinfo (const char *restrict nodename, + const char *restrict servname, + const struct addrinfo *restrict hints, + struct addrinfo **restrict res) +# undef getaddrinfo +{ + return getaddrinfo (nodename, servname, hints, res); +} + +void +freeaddrinfo (struct addrinfo *ai) +# undef freeaddrinfo +{ + freeaddrinfo (ai); +} + +#else + +# if defined _WIN32 && !defined __CYGWIN__ +# define WINDOWS_NATIVE +# endif /* gl_sockets_startup */ -#include "sockets.h" +# include "sockets.h" + +# ifdef WINDOWS_NATIVE + +/* Don't assume that UNICODE is not defined. */ +# undef GetModuleHandle +# define GetModuleHandle GetModuleHandleA + +# if !(_WIN32_WINNT >= _WIN32_WINNT_WINXP) + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress -#ifdef WINDOWS_NATIVE typedef int (WSAAPI *getaddrinfo_func) (const char*, const char*, const struct addrinfo*, struct addrinfo**); @@ -107,20 +141,43 @@ use_win32_p (void) return 1; } -#endif + +# else + +static int +use_win32_p (void) +{ + static int done = 0; + + if (!done) + { + done = 1; + + gl_sockets_startup (SOCKETS_1_1); + } + + return 1; +} + +# define getaddrinfo_ptr getaddrinfo +# define freeaddrinfo_ptr freeaddrinfo +# define getnameinfo_ptr getnameinfo + +# endif +# endif static bool validate_family (int family) { /* FIXME: Support more families. */ -#if HAVE_IPV4 +# if HAVE_IPV4 if (family == PF_INET) return true; -#endif -#if HAVE_IPV6 +# endif +# if HAVE_IPV6 if (family == PF_INET6) return true; -#endif +# endif if (family == PF_UNSPEC) return true; return false; @@ -133,29 +190,30 @@ getaddrinfo (const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints, struct addrinfo **restrict res) +#undef getaddrinfo { struct addrinfo *tmp; int port = 0; struct hostent *he; void *storage; size_t size; -#if HAVE_IPV6 +# if HAVE_IPV6 struct v6_pair { struct addrinfo addrinfo; struct sockaddr_in6 sockaddr_in6; }; -#endif -#if HAVE_IPV4 +# endif +# if HAVE_IPV4 struct v4_pair { struct addrinfo addrinfo; struct sockaddr_in sockaddr_in; }; -#endif +# endif -#ifdef WINDOWS_NATIVE +# ifdef WINDOWS_NATIVE if (use_win32_p ()) return getaddrinfo_ptr (nodename, servname, hints, res); -#endif +# endif if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE))) /* FIXME: Support more flags. */ @@ -174,11 +232,11 @@ getaddrinfo (const char *restrict nodename, if (!(hints->ai_flags & AI_PASSIVE)) return EAI_NONAME; -#ifdef HAVE_IPV6 +# ifdef HAVE_IPV6 nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; -#else +# else nodename = "0.0.0.0"; -#endif +# endif } if (servname) @@ -212,17 +270,17 @@ getaddrinfo (const char *restrict nodename, switch (he->h_addrtype) { -#if HAVE_IPV6 +# if HAVE_IPV6 case PF_INET6: size = sizeof (struct v6_pair); break; -#endif +# endif -#if HAVE_IPV4 +# if HAVE_IPV4 case PF_INET: size = sizeof (struct v4_pair); break; -#endif +# endif default: return EAI_NODATA; @@ -234,7 +292,7 @@ getaddrinfo (const char *restrict nodename, switch (he->h_addrtype) { -#if HAVE_IPV6 +# if HAVE_IPV6 case PF_INET6: { struct v6_pair *p = storage; @@ -256,9 +314,9 @@ getaddrinfo (const char *restrict nodename, tmp->ai_addrlen = sizeof *sinp; } break; -#endif +# endif -#if HAVE_IPV4 +# if HAVE_IPV4 case PF_INET: { struct v4_pair *p = storage; @@ -280,7 +338,7 @@ getaddrinfo (const char *restrict nodename, tmp->ai_addrlen = sizeof *sinp; } break; -#endif +# endif default: free (storage); @@ -308,21 +366,21 @@ getaddrinfo (const char *restrict nodename, tmp->ai_addr->sa_family = he->h_addrtype; tmp->ai_family = he->h_addrtype; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN +# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN switch (he->h_addrtype) { -#if HAVE_IPV4 +# if HAVE_IPV4 case AF_INET: tmp->ai_addr->sa_len = sizeof (struct sockaddr_in); break; -#endif -#if HAVE_IPV6 +# endif +# if HAVE_IPV6 case AF_INET6: tmp->ai_addr->sa_len = sizeof (struct sockaddr_in6); break; -#endif +# endif } -#endif +# endif /* FIXME: If more than one address, create linked list of addrinfo's. */ @@ -334,14 +392,15 @@ getaddrinfo (const char *restrict nodename, /* Free 'addrinfo' structure AI including associated storage. */ void freeaddrinfo (struct addrinfo *ai) +#undef freeaddrinfo { -#ifdef WINDOWS_NATIVE +# ifdef WINDOWS_NATIVE if (use_win32_p ()) { freeaddrinfo_ptr (ai); return; } -#endif +# endif while (ai) { @@ -360,12 +419,13 @@ getnameinfo (const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, char *restrict service, socklen_t servicelen, int flags) +#undef getnameinfo { -#ifdef WINDOWS_NATIVE +# ifdef WINDOWS_NATIVE if (use_win32_p ()) return getnameinfo_ptr (sa, salen, node, nodelen, service, servicelen, flags); -#endif +# endif /* FIXME: Support other flags. */ if ((node && nodelen > 0 && !(flags & NI_NUMERICHOST)) || @@ -378,18 +438,18 @@ getnameinfo (const struct sockaddr *restrict sa, socklen_t salen, switch (sa->sa_family) { -#if HAVE_IPV4 +# if HAVE_IPV4 case AF_INET: if (salen < sizeof (struct sockaddr_in)) return EAI_FAMILY; break; -#endif -#if HAVE_IPV6 +# endif +# if HAVE_IPV6 case AF_INET6: if (salen < sizeof (struct sockaddr_in6)) return EAI_FAMILY; break; -#endif +# endif default: return EAI_FAMILY; } @@ -398,23 +458,23 @@ getnameinfo (const struct sockaddr *restrict sa, socklen_t salen, { switch (sa->sa_family) { -#if HAVE_IPV4 +# if HAVE_IPV4 case AF_INET: if (!inet_ntop (AF_INET, &(((const struct sockaddr_in *) sa)->sin_addr), node, nodelen)) return EAI_SYSTEM; break; -#endif +# endif -#if HAVE_IPV6 +# if HAVE_IPV6 case AF_INET6: if (!inet_ntop (AF_INET6, &(((const struct sockaddr_in6 *) sa)->sin6_addr), node, nodelen)) return EAI_SYSTEM; break; -#endif +# endif default: return EAI_FAMILY; @@ -424,12 +484,12 @@ getnameinfo (const struct sockaddr *restrict sa, socklen_t salen, if (service && servicelen > 0 && flags & NI_NUMERICSERV) switch (sa->sa_family) { -#if HAVE_IPV4 +# if HAVE_IPV4 case AF_INET: -#endif -#if HAVE_IPV6 +# endif +# if HAVE_IPV6 case AF_INET6: -#endif +# endif { unsigned short int port = ntohs (((const struct sockaddr_in *) sa)->sin_port); @@ -441,3 +501,5 @@ getnameinfo (const struct sockaddr *restrict sa, socklen_t salen, return 0; } + +#endif diff --git a/gl/getdelim.c b/gl/getdelim.c new file mode 100644 index 00000000..9eb0483c --- /dev/null +++ b/gl/getdelim.c @@ -0,0 +1,147 @@ +/* getdelim.c --- Implementation of replacement getdelim function. + Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2022 Free Software + Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Ported from glibc by Simon Josefsson. */ + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below. */ +#define _GL_ARG_NONNULL(params) + +#include + +#include + +#include +#include +#include +#include + +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +# define getc_maybe_unlocked(fp) getc(fp) +#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED +# undef flockfile +# undef funlockfile +# define flockfile(x) ((void) 0) +# define funlockfile(x) ((void) 0) +# define getc_maybe_unlocked(fp) getc(fp) +#else +# define getc_maybe_unlocked(fp) getc_unlocked(fp) +#endif + +static void +alloc_failed (void) +{ +#if defined _WIN32 && ! defined __CYGWIN__ + /* Avoid errno problem without using the realloc module; see: + https://lists.gnu.org/r/bug-gnulib/2016-08/msg00025.html */ + errno = ENOMEM; +#endif +} + +/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and + NUL-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'ed as + necessary. Returns the number of characters read (not including + the null terminator), or -1 on error or EOF. */ + +ssize_t +getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) +{ + ssize_t result; + size_t cur_len = 0; + + if (lineptr == NULL || n == NULL || fp == NULL) + { + errno = EINVAL; + return -1; + } + + flockfile (fp); + + if (*lineptr == NULL || *n == 0) + { + char *new_lineptr; + *n = 120; + new_lineptr = (char *) realloc (*lineptr, *n); + if (new_lineptr == NULL) + { + alloc_failed (); + result = -1; + goto unlock_return; + } + *lineptr = new_lineptr; + } + + for (;;) + { + int i; + + i = getc_maybe_unlocked (fp); + if (i == EOF) + { + result = -1; + break; + } + + /* Make enough space for len+1 (for final NUL) bytes. */ + if (cur_len + 1 >= *n) + { + size_t needed_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + size_t needed = 2 * *n + 1; /* Be generous. */ + char *new_lineptr; + + if (needed_max < needed) + needed = needed_max; + if (cur_len + 1 >= needed) + { + result = -1; + errno = EOVERFLOW; + goto unlock_return; + } + + new_lineptr = (char *) realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + alloc_failed (); + result = -1; + goto unlock_return; + } + + *lineptr = new_lineptr; + *n = needed; + } + + (*lineptr)[cur_len] = i; + cur_len++; + + if (i == delimiter) + break; + } + (*lineptr)[cur_len] = '\0'; + result = cur_len ? cur_len : result; + + unlock_return: + funlockfile (fp); /* doesn't set errno */ + + return result; +} diff --git a/gl/getdtablesize.c b/gl/getdtablesize.c new file mode 100644 index 00000000..793e0f88 --- /dev/null +++ b/gl/getdtablesize.c @@ -0,0 +1,124 @@ +/* getdtablesize() function: Return maximum possible file descriptor value + 1. + Copyright (C) 2008-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ + +# include + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +# endif + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static int +_setmaxstdio_nothrow (int newmax) +{ + int result; + + TRY_MSVC_INVAL + { + result = _setmaxstdio (newmax); + } + CATCH_MSVC_INVAL + { + result = -1; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define _setmaxstdio_nothrow _setmaxstdio +# endif + +/* Cache for the previous getdtablesize () result. Safe to cache because + Windows also lacks setrlimit. */ +static int dtablesize; + +int +getdtablesize (void) +{ + if (dtablesize == 0) + { + /* We are looking for the number N such that the valid file descriptors + are 0..N-1. It can be obtained through a loop as follows: + { + int fd; + for (fd = 3; fd < 65536; fd++) + if (dup2 (0, fd) == -1) + break; + return fd; + } + On Windows XP, the result is 2048. + The drawback of this loop is that it allocates memory for a libc + internal array that is never freed. + + The number N can also be obtained as the upper bound for + _getmaxstdio (). _getmaxstdio () returns the maximum number of open + FILE objects. The sanity check in _setmaxstdio reveals the maximum + number of file descriptors. This too allocates memory, but it is + freed when we call _setmaxstdio with the original value. */ + int orig_max_stdio = _getmaxstdio (); + unsigned int bound; + for (bound = 0x10000; _setmaxstdio_nothrow (bound) < 0; bound = bound / 2) + ; + _setmaxstdio_nothrow (orig_max_stdio); + dtablesize = bound; + } + return dtablesize; +} + +#else + +# include +# include + +# ifndef RLIM_SAVED_CUR +# define RLIM_SAVED_CUR RLIM_INFINITY +# endif +# ifndef RLIM_SAVED_MAX +# define RLIM_SAVED_MAX RLIM_INFINITY +# endif + +# ifdef __CYGWIN__ + /* Cygwin 1.7.25 auto-increases the RLIMIT_NOFILE soft limit until it + hits the compile-time constant hard limit of 3200. We might as + well just report the hard limit. */ +# define rlim_cur rlim_max +# endif + +int +getdtablesize (void) +{ + struct rlimit lim; + + if (getrlimit (RLIMIT_NOFILE, &lim) == 0 + && 0 <= lim.rlim_cur && lim.rlim_cur <= INT_MAX + && lim.rlim_cur != RLIM_INFINITY + && lim.rlim_cur != RLIM_SAVED_CUR + && lim.rlim_cur != RLIM_SAVED_MAX) + return lim.rlim_cur; + + return INT_MAX; +} + +#endif diff --git a/gl/gethostname.c b/gl/gethostname.c index 22015732..ce9bf414 100644 --- a/gl/gethostname.c +++ b/gl/gethostname.c @@ -1,26 +1,26 @@ /* gethostname emulation for SysV and POSIX.1. - Copyright (C) 1992, 2003, 2006, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 1992, 2003, 2006, 2008-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* David MacKenzie Windows port by Simon Josefsson */ #include -#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) +#if !(defined _WIN32 && !defined __CYGWIN__) /* Unix API. */ /* Specification. */ diff --git a/gl/getline.c b/gl/getline.c new file mode 100644 index 00000000..34b91177 --- /dev/null +++ b/gl/getline.c @@ -0,0 +1,27 @@ +/* getline.c --- Implementation of replacement getline function. + Copyright (C) 2005-2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Simon Josefsson. */ + +#include + +#include + +ssize_t +getline (char **lineptr, size_t *n, FILE *stream) +{ + return getdelim (lineptr, n, '\n', stream); +} diff --git a/gl/getloadavg.c b/gl/getloadavg.c index 6e228191..37e82808 100644 --- a/gl/getloadavg.c +++ b/gl/getloadavg.c @@ -1,6 +1,6 @@ /* Get the system load averages. - Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2013 Free Software + Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2022 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with gnulib. @@ -8,7 +8,7 @@ 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 + 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, @@ -17,7 +17,7 @@ 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 . */ + along with this program. If not, see . */ /* Compile-time symbols that this file uses: @@ -47,29 +47,25 @@ N_NAME_POINTER The nlist n_name element is a pointer, not an array. HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'. - LINUX_LDAV_FILE [__linux__, __CYGWIN__]: File containing - load averages. + LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File + containing load averages. Specific system predefines this file uses, aside from setting default values if not emacs: apollo BSD Real BSD, not just BSD-like. - convex DGUX eunice UNIX emulator under VMS. hpux __MSDOS__ No-op for MSDOS. NeXT sgi - sequent Sequent Dynix 3.x.x (BSD) - _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV) - sony_news NEWS-OS (works at least for 4.1C) UMAX UMAX4_3 VMS - WINDOWS32 No-op for Windows95/NT. - __linux__ Linux: assumes /proc file system mounted. + _WIN32 Native Windows (possibly also defined on Cygwin) + __linux__, __ANDROID__ Linux: assumes /proc file system mounted. Support from Michael K. Johnson. __CYGWIN__ Cygwin emulates linux /proc/loadavg. __NetBSD__ NetBSD: assumes /kern file system mounted. @@ -97,9 +93,8 @@ # include "intprops.h" -# if !defined (BSD) && defined (ultrix) -/* Ultrix behaves like BSD on Vaxen. */ -# define BSD +# if defined _WIN32 && ! defined __CYGWIN__ && ! defined WINDOWS32 +# define WINDOWS32 # endif # ifdef NeXT @@ -141,10 +136,6 @@ # define MORE_BSD # endif -# if defined (ultrix) && defined (mips) -# define decstation -# endif - # if defined (__SVR4) && !defined (SVR4) # define SVR4 # endif @@ -168,13 +159,6 @@ # include # endif -/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by - default, but _MACH_IND_SYS_TYPES is defined in . Combine - that with a couple of other things and we'll have a unique match. */ -# if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES) -# define tek4300 /* Define by emacs, but not by other users. */ -# endif - /* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ # ifndef LOAD_AVE_TYPE @@ -187,14 +171,6 @@ # define LOAD_AVE_TYPE long # endif -# ifdef decstation -# define LOAD_AVE_TYPE long -# endif - -# ifdef _SEQUENT_ -# define LOAD_AVE_TYPE long -# endif - # ifdef sgi # define LOAD_AVE_TYPE long # endif @@ -203,41 +179,14 @@ # define LOAD_AVE_TYPE long # endif -# ifdef sony_news -# define LOAD_AVE_TYPE long -# endif - -# ifdef sequent -# define LOAD_AVE_TYPE long -# endif - # ifdef OSF_ALPHA # define LOAD_AVE_TYPE long # endif -# if defined (ardent) && defined (titan) -# define LOAD_AVE_TYPE long -# endif - -# ifdef tek4300 -# define LOAD_AVE_TYPE long -# endif - -# if defined (alliant) && defined (i860) /* Alliant FX/2800 */ -# define LOAD_AVE_TYPE long -# endif - # if defined _AIX && ! defined HAVE_LIBPERFSTAT # define LOAD_AVE_TYPE long # endif -# ifdef convex -# define LOAD_AVE_TYPE double -# ifndef LDAV_CVT -# define LDAV_CVT(n) (n) -# endif -# endif - # endif /* No LOAD_AVE_TYPE. */ # ifdef OSF_ALPHA @@ -247,13 +196,6 @@ # define FSCALE 1024.0 # endif -# if defined (alliant) && defined (i860) /* Alliant FX/2800 */ -/* defines an incorrect value for FSCALE on an - Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */ -# undef FSCALE -# define FSCALE 100.0 -# endif - # ifndef FSCALE @@ -263,25 +205,17 @@ # define FSCALE 2048.0 # endif -# if defined (MIPS) || defined (SVR4) || defined (decstation) +# if defined (MIPS) || defined (SVR4) # define FSCALE 256 # endif -# if defined (sgi) || defined (sequent) +# if defined (sgi) /* Sometimes both MIPS and sgi are defined, so FSCALE was just defined above under #ifdef MIPS. But we want the sgi value. */ # undef FSCALE # define FSCALE 1000.0 # endif -# if defined (ardent) && defined (titan) -# define FSCALE 65536.0 -# endif - -# ifdef tek4300 -# define FSCALE 100.0 -# endif - # if defined _AIX && !defined HAVE_LIBPERFSTAT # define FSCALE 65536.0 # endif @@ -303,28 +237,22 @@ # endif -# if !defined (KERNEL_FILE) && defined (sequent) -# define KERNEL_FILE "/dynix" -# endif - # if !defined (KERNEL_FILE) && defined (hpux) # define KERNEL_FILE "/hp-ux" # endif -# if !defined (KERNEL_FILE) && (defined (_SEQUENT_) || defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan))) +# if !defined (KERNEL_FILE) && (defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi)) # define KERNEL_FILE "/unix" # endif -# if !defined (LDAV_SYMBOL) && defined (alliant) -# define LDAV_SYMBOL "_Loadavg" -# endif - -# if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) || defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT))) +# if !defined (LDAV_SYMBOL) && (defined (hpux) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT))) # define LDAV_SYMBOL "avenrun" # endif -# include +# ifdef HAVE_UNISTD_H +# include +# endif /* LOAD_AVE_TYPE should only get defined if we're going to use the nlist method. */ @@ -335,7 +263,7 @@ # ifdef LOAD_AVE_TYPE # ifndef __VMS -# ifndef __linux__ +# if !(defined __linux__ || defined __ANDROID__) # ifndef NLIST_STRUCT # include # else /* NLIST_STRUCT */ @@ -358,7 +286,7 @@ # ifndef LDAV_SYMBOL # define LDAV_SYMBOL "_avenrun" # endif /* LDAV_SYMBOL */ -# endif /* __linux__ */ +# endif /* __linux__ || __ANDROID__ */ # else /* __VMS */ @@ -431,7 +359,8 @@ # include # endif -# if (defined __linux__ || defined __CYGWIN__ || defined SUNOS_5 \ +# if (defined __linux__ || defined __ANDROID__ \ + || defined __CYGWIN__ || defined SUNOS_5 \ || (defined LOAD_AVE_TYPE && ! defined __VMS)) # include # endif @@ -460,7 +389,7 @@ static bool getloadavg_initialized; /* Offset in kmem to seek to read load average, or 0 means invalid. */ static long offset; -# if ! defined __VMS && ! defined sgi && ! defined __linux__ +# if ! defined __VMS && ! defined sgi && ! (defined __linux__ || defined __ANDROID__) static struct nlist name_list[2]; # endif @@ -495,17 +424,17 @@ getloadavg (double loadavg[], int nelem) int saved_errno; kc = kstat_open (); - if (kc == 0) + if (kc == NULL) return -1; ksp = kstat_lookup (kc, "unix", 0, "system_misc"); - if (ksp == 0) + if (ksp == NULL) return -1; if (kstat_read (kc, ksp, 0) == -1) return -1; kn = kstat_data_lookup (ksp, "avenrun_1min"); - if (kn == 0) + if (kn == NULL) { /* Return -1 if no load average information is available. */ nelem = 0; @@ -518,14 +447,14 @@ getloadavg (double loadavg[], int nelem) if (nelem >= 2) { kn = kstat_data_lookup (ksp, "avenrun_5min"); - if (kn != 0) + if (kn != NULL) { loadavg[elem++] = (double) kn->value.ul / FSCALE; if (nelem >= 3) { kn = kstat_data_lookup (ksp, "avenrun_15min"); - if (kn != 0) + if (kn != NULL) loadavg[elem++] = (double) kn->value.ul / FSCALE; } } @@ -570,8 +499,8 @@ getloadavg (double loadavg[], int nelem) } # endif -# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) - /* Linux without glibc, Cygwin */ +# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__) + /* Linux without glibc, Android, Cygwin */ # define LDAV_DONE # undef LOAD_AVE_TYPE @@ -583,7 +512,7 @@ getloadavg (double loadavg[], int nelem) char const *ptr = ldavgbuf; int fd, count, saved_errno; - fd = open (LINUX_LDAV_FILE, O_RDONLY); + fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC); if (fd == -1) return -1; count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); @@ -621,12 +550,12 @@ getloadavg (double loadavg[], int nelem) for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; - loadavg[elem++] = numerator / denominator; + loadavg[elem] = numerator / denominator; } return elem; -# endif /* __linux__ || __CYGWIN__ */ +# endif /* __linux__ || __ANDROID__ || __CYGWIN__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ # define LDAV_DONE @@ -638,15 +567,22 @@ getloadavg (double loadavg[], int nelem) unsigned long int load_ave[3], scale; int count; - FILE *fp; - - fp = fopen (NETBSD_LDAV_FILE, "r"); - if (fp == NULL) - return -1; - count = fscanf (fp, "%lu %lu %lu %lu\n", + char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1]; + int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return fd; + int nread = read (fd, readbuf, sizeof readbuf - 1); + int err = errno; + close (fd); + if (nread < 0) + { + errno = err; + return -1; + } + readbuf[nread] = '\0'; + count = sscanf (readbuf, "%lu %lu %lu %lu\n", &load_ave[0], &load_ave[1], &load_ave[2], &scale); - (void) fclose (fp); if (count != 4) { errno = ENOTSUP; @@ -915,7 +851,7 @@ getloadavg (double loadavg[], int nelem) # ifndef SUNOS_5 if ( -# if !(defined (_AIX) && !defined (ps2)) +# if !defined (_AIX) nlist (KERNEL_FILE, name_list) # else /* _AIX */ knlist (name_list, 1, sizeof (name_list[0])) @@ -940,33 +876,17 @@ getloadavg (double loadavg[], int nelem) if (!getloadavg_initialized) { # ifndef SUNOS_5 - /* Set the channel to close on exec, so it does not - litter any child's descriptor table. */ -# ifndef O_CLOEXEC -# define O_CLOEXEC 0 -# endif int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC); if (0 <= fd) { -# if F_DUPFD_CLOEXEC - if (fd <= STDERR_FILENO) - { - int fd1 = fcntl (fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1); - close (fd); - fd = fd1; - } -# endif - if (0 <= fd) - { - channel = fd; - getloadavg_initialized = true; - } + channel = fd; + getloadavg_initialized = true; } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names to use the currently running kernel. */ kd = kvm_open (0, 0, 0, O_RDONLY, 0); - if (kd != 0) + if (kd != NULL) { /* nlist the currently running kernel. */ kvm_nlist (kd, name_list); diff --git a/gl/getopt-cdefs.in.h b/gl/getopt-cdefs.in.h new file mode 100644 index 00000000..b6dd913c --- /dev/null +++ b/gl/getopt-cdefs.in.h @@ -0,0 +1,66 @@ +/* getopt-on-non-glibc compatibility macros. + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GETOPT_CDEFS_H +#define _GETOPT_CDEFS_H 1 + +/* This header should not be used directly; include getopt.h or + unistd.h instead. It does not have a protective #error, because + the guard macro for getopt.h in gnulib is not fixed. */ + +/* getopt-core.h and getopt-ext.h are shared with GNU libc, and expect + a number of the internal macros supplied to GNU libc's headers by + sys/cdefs.h. Provide fallback definitions for all of them. */ +#if @HAVE_SYS_CDEFS_H@ +# include +#endif + +#ifndef __BEGIN_DECLS +# ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# else +# define __BEGIN_DECLS /* nothing */ +# endif +#endif +#ifndef __END_DECLS +# ifdef __cplusplus +# define __END_DECLS } +# else +# define __END_DECLS /* nothing */ +# endif +#endif + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_VERSION__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#ifndef __THROW +# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major__ >= 4) +# define __THROW throw () +# else +# define __THROW +# endif +#endif + +#endif /* _GETOPT_CDEFS_H */ diff --git a/gl/getopt-core.h b/gl/getopt-core.h new file mode 100644 index 00000000..1c40ecc8 --- /dev/null +++ b/gl/getopt-core.h @@ -0,0 +1,96 @@ +/* Declarations for getopt (basic, portable features only). + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _GETOPT_CORE_H +#define _GETOPT_CORE_H 1 + +/* This header should not be used directly; include getopt.h or + unistd.h instead. Unlike most bits headers, it does not have + a protective #error, because the guard macro for getopt.h in + gnulib is not fixed. */ + +__BEGIN_DECLS + +/* For communication from 'getopt' to the caller. + When 'getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when 'ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to 'getopt'. + + On entry to 'getopt', zero means this is the first call; initialize. + + When 'getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, 'optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message 'getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, 'optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in 'optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU 'getopt'. + + The argument '--' causes premature termination of argument + scanning, explicitly telling 'getopt' that there are no more + options. + + If OPTS begins with '-', then non-option arguments are treated as + arguments to the option '\1'. This behavior is specific to the GNU + 'getopt'. If OPTS begins with '+', or POSIXLY_CORRECT is set in + the environment, then do not permute arguments. + + For standards compliance, the 'argv' argument has the type + char *const *, but this is inaccurate; if argument permutation is + enabled, the argv array (not the strings it points to) must be + writable. */ + +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + __THROW _GL_ARG_NONNULL ((2, 3)); + +__END_DECLS + +#endif /* _GETOPT_CORE_H */ diff --git a/gl/getopt-ext.h b/gl/getopt-ext.h new file mode 100644 index 00000000..d661fcc5 --- /dev/null +++ b/gl/getopt-ext.h @@ -0,0 +1,77 @@ +/* Declarations for getopt (GNU extensions). + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _GETOPT_EXT_H +#define _GETOPT_EXT_H 1 + +/* This header should not be used directly; include getopt.h instead. + Unlike most bits headers, it does not have a protective #error, + because the guard macro for getopt.h in gnulib is not fixed. */ + +__BEGIN_DECLS + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of 'struct option' terminated by an element containing a name which is + zero. + + The field 'has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field 'flag' is not NULL, it points to a variable that is set + to the value given in the field 'val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an 'int' to + a compiled-in constant, such as set a value from 'optarg', set the + option's 'flag' field to zero and its 'val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero 'flag' field, 'getopt' + returns the contents of the 'val' field. */ + +struct option +{ + const char *name; + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the 'has_arg' field of 'struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); +extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); + +__END_DECLS + +#endif /* _GETOPT_EXT_H */ diff --git a/gl/getopt-pfx-core.h b/gl/getopt-pfx-core.h new file mode 100644 index 00000000..3eead0e0 --- /dev/null +++ b/gl/getopt-pfx-core.h @@ -0,0 +1,66 @@ +/* getopt (basic, portable features) gnulib wrapper header. + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GETOPT_PFX_CORE_H +#define _GETOPT_PFX_CORE_H 1 + +/* This header should not be used directly; include getopt.h or + unistd.h instead. It does not have a protective #error, because + the guard macro for getopt.h in gnulib is not fixed. */ + +/* Standalone applications should #define __GETOPT_PREFIX to an + identifier that prefixes the external functions and variables + defined in getopt-core.h and getopt-ext.h. Systematically + rename identifiers so that they do not collide with the system + functions and variables. Renaming avoids problems with some + compilers and linkers. */ +#ifdef __GETOPT_PREFIX +# ifndef __GETOPT_ID +# define __GETOPT_CONCAT(x, y) x ## y +# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) +# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) +# endif +# undef getopt +# undef optarg +# undef opterr +# undef optind +# undef optopt +# define getopt __GETOPT_ID (getopt) +# define optarg __GETOPT_ID (optarg) +# define opterr __GETOPT_ID (opterr) +# define optind __GETOPT_ID (optind) +# define optopt __GETOPT_ID (optopt) + +/* Work around a a problem on macOS, which declares getopt with a + trailing __DARWIN_ALIAS(getopt) that would expand to something like + __asm("_" "rpl_getopt" "$UNIX2003") were it not for the following + hack to suppress the macOS declaration . */ +# ifdef __APPLE__ +# define _GETOPT +# endif + +/* The system's getopt.h may have already included getopt-core.h to + declare the unprefixed identifiers. Undef _GETOPT_CORE_H so that + getopt-core.h declares them with prefixes. */ +# undef _GETOPT_CORE_H +#endif + +#include + +#endif /* _GETOPT_PFX_CORE_H */ diff --git a/gl/getopt-pfx-ext.h b/gl/getopt-pfx-ext.h new file mode 100644 index 00000000..85a6cb5d --- /dev/null +++ b/gl/getopt-pfx-ext.h @@ -0,0 +1,70 @@ +/* getopt (GNU extensions) gnulib wrapper header. + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GETOPT_PFX_EXT_H +#define _GETOPT_PFX_EXT_H 1 + +/* This header should not be used directly; include getopt.h instead. + It does not have a protective #error, because the guard macro for + getopt.h in gnulib is not fixed. */ + +/* Standalone applications should #define __GETOPT_PREFIX to an + identifier that prefixes the external functions and variables + defined in getopt-core.h and getopt-ext.h. Systematically + rename identifiers so that they do not collide with the system + functions and variables. Renaming avoids problems with some + compilers and linkers. */ +#ifdef __GETOPT_PREFIX +# ifndef __GETOPT_ID +# define __GETOPT_CONCAT(x, y) x ## y +# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) +# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) +# endif +# undef getopt_long +# undef getopt_long_only +# undef option +# undef _getopt_internal +# define getopt_long __GETOPT_ID (getopt_long) +# define getopt_long_only __GETOPT_ID (getopt_long_only) +# define option __GETOPT_ID (option) +# define _getopt_internal __GETOPT_ID (getopt_internal) + +/* The system's getopt.h may have already included getopt-ext.h to + declare the unprefixed identifiers. Undef _GETOPT_EXT_H so that + getopt-ext.h declares them with prefixes. */ +# undef _GETOPT_EXT_H +#endif + +/* Standalone applications get correct prototypes for getopt_long and + getopt_long_only; they declare "char **argv". For backward + compatibility with old applications, if __GETOPT_PREFIX is not + defined, we supply GNU-libc-compatible, but incorrect, prototypes + using "char *const *argv". (GNU libc is stuck with the incorrect + prototypes, as they are baked into older versions of LSB.) */ +#ifndef __getopt_argv_const +# if defined __GETOPT_PREFIX +# define __getopt_argv_const /* empty */ +# else +# define __getopt_argv_const const +# endif +#endif + +#include + +#endif /* _GETOPT_PFX_EXT_H */ diff --git a/gl/getopt.c b/gl/getopt.c index ef0f4cee..128dc7fc 100644 --- a/gl/getopt.c +++ b/gl/getopt.c @@ -1,23 +1,21 @@ /* Getopt for GNU. - NOTE: getopt is part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - 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, + Copyright (C) 1987-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ #ifndef _LIBC # include @@ -31,30 +29,54 @@ #include #ifdef _LIBC +/* When used as part of glibc, error printing must be done differently + for standards compliance. getopt is not a cancellation point, so + it must not call functions that are, and it is specified by an + older standard than stdio locking, so it must not refer to + functions in the "user namespace" related to stdio locking. + Finally, it must use glibc's internal message translation so that + the messages are looked up in the proper text domain. */ # include +# define fprintf __fxprintf_nocancel +# define flockfile(fp) _IO_flockfile (fp) +# define funlockfile(fp) _IO_funlockfile (fp) #else # include "gettext.h" # define _(msgid) gettext (msgid) +/* When used standalone, flockfile and funlockfile might not be + available. */ +# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ + || (defined _WIN32 && ! defined __CYGWIN__)) +# define flockfile(fp) /* nop */ +# define funlockfile(fp) /* nop */ +# endif +/* When used standalone, do not attempt to use alloca. */ +# define __libc_use_alloca(size) 0 +# undef alloca +# define alloca(size) (abort (), (void *)0) #endif -#if defined _LIBC && defined USE_IN_LIBIO -# include -#endif - -/* This version of 'getopt' appears to the caller like standard Unix 'getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As 'getopt_long' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Using 'getopt' or setting the environment variable POSIXLY_CORRECT +/* This implementation of 'getopt' has three modes for handling + options interspersed with non-option arguments. It can stop + scanning for options at the first non-option argument encountered, + as POSIX specifies. It can continue scanning for options after the + first non-option argument, but permute 'argv' as it goes so that, + after 'getopt' is done, all the options precede all the non-option + arguments and 'optind' points to the first non-option argument. + Or, it can report non-option arguments as if they were arguments to + the option character '\x01'. + + The default behavior of 'getopt_long' is to permute the argument list. + When this implementation is used standalone, the default behavior of + 'getopt' is to stop at the first non-option argument, but when it is + used as part of GNU libc it also permutes the argument list. In both + cases, setting the environment variable POSIXLY_CORRECT to any value disables permutation. - Then the behavior is completely standard. - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ + If the first character of the OPTSTRING argument to 'getopt' or + 'getopt_long' is '+', both functions will stop at the first + non-option argument. If it is '-', both functions will report + non-option arguments as arguments to the option character '\x01'. */ #include "getopt_int.h" @@ -95,42 +117,7 @@ int optopt = '?'; /* Keep a global copy of all internal members of getopt_data. */ static struct _getopt_data getopt_data; - - -#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV -extern char *getenv (); -#endif -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (d->__nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. @@ -153,64 +140,40 @@ exchange (char **argv, struct _getopt_data *d) It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the '__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - d->__nonoption_flags_max_len), - '\0', top + 1 - d->__nonoption_flags_max_len); - d->__nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - while (top > middle && middle > bottom) { if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } + { + /* Top segment is the short one. */ + int len = top - middle; + int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } } /* Update records for the slots the non-options now occupy. */ @@ -219,25 +182,216 @@ exchange (char **argv, struct _getopt_data *d) d->__last_nonopt = d->optind; } -/* Initialize the internal data when the first call is made. */ +/* Process the argument starting with d->__nextchar as a long option. + d->optind should *not* have been advanced over this argument. + + If the value returned is -1, it was not actually a long option, the + state is unchanged, and the argument should be processed as a set + of short options (this can only happen when long_only is true). + Otherwise, the option (and its argument, if any) have been consumed + and the return value is the value to return from _getopt_internal_r. */ +static int +process_long_option (int argc, char **argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d, + int print_errors, const char *prefix) +{ + char *nameend; + size_t namelen; + const struct option *p; + const struct option *pfound = NULL; + int n_options; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + namelen = nameend - d->__nextchar; + + /* First look for an exact match, counting the options as a side + effect. */ + for (p = longopts, n_options = 0; p->name; p++, n_options++) + if (!strncmp (p->name, d->__nextchar, namelen) + && namelen == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + option_index = n_options; + break; + } + + if (pfound == NULL) + { + /* Didn't find an exact match, so look for abbreviations. */ + unsigned char *ambig_set = NULL; + int ambig_malloced = 0; + int ambig_fallback = 0; + int indfound = -1; + + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, namelen)) + { + if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + { + /* Second or later nonexact match found. */ + if (!ambig_fallback) + { + if (!print_errors) + /* Don't waste effort tracking the ambig set if + we're not going to print it anyway. */ + ambig_fallback = 1; + else if (!ambig_set) + { + if (__libc_use_alloca (n_options)) + ambig_set = alloca (n_options); + else if ((ambig_set = malloc (n_options)) == NULL) + /* Fall back to simpler error message. */ + ambig_fallback = 1; + else + ambig_malloced = 1; + + if (ambig_set) + { + memset (ambig_set, 0, n_options); + ambig_set[indfound] = 1; + } + } + if (ambig_set) + ambig_set[option_index] = 1; + } + } + } + + if (ambig_set || ambig_fallback) + { + if (print_errors) + { + if (ambig_fallback) + fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"), + argv[0], prefix, d->__nextchar); + else + { + flockfile (stderr); + fprintf (stderr, + _("%s: option '%s%s' is ambiguous; possibilities:"), + argv[0], prefix, d->__nextchar); + + for (option_index = 0; option_index < n_options; option_index++) + if (ambig_set[option_index]) + fprintf (stderr, " '%s%s'", + prefix, longopts[option_index].name); + + /* This must use 'fprintf' even though it's only + printing a single character, so that it goes through + __fxprintf_nocancel when compiled as part of glibc. */ + fprintf (stderr, "\n"); + funlockfile (stderr); + } + } + if (ambig_malloced) + free (ambig_set); + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; + } + + option_index = indfound; + } + + if (pfound == NULL) + { + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short option, + then it's an error. */ + if (!long_only || argv[d->optind][1] == '-' + || strchr (optstring, *d->__nextchar) == NULL) + { + if (print_errors) + fprintf (stderr, _("%s: unrecognized option '%s%s'\n"), + argv[0], prefix, d->__nextchar); + + d->__nextchar = NULL; + d->optind++; + d->optopt = 0; + return '?'; + } + + /* Otherwise interpret it as a short option. */ + return -1; + } + + /* We have found a matching long option. Consume it. */ + d->optind++; + d->__nextchar = NULL; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option '%s%s' doesn't allow an argument\n"), + argv[0], prefix, pfound->name); + + d->optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option '%s%s' requires an argument\n"), + argv[0], prefix, pfound->name); + + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; +} + +/* Initialize internal data upon the first call to getopt. */ static const char * -_getopt_initialize (int argc _GL_UNUSED, - char **argv _GL_UNUSED, const char *optstring, - struct _getopt_data *d, int posixly_correct) +_getopt_initialize (_GL_UNUSED int argc, + _GL_UNUSED char **argv, const char *optstring, + struct _getopt_data *d, int posixly_correct) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ + if (d->optind == 0) + d->optind = 1; d->__first_nonopt = d->__last_nonopt = d->optind; - d->__nextchar = NULL; - d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); - /* Determine how to handle the ordering of options and nonoptions. */ - if (optstring[0] == '-') { d->__ordering = RETURN_IN_ORDER; @@ -248,41 +402,12 @@ _getopt_initialize (int argc _GL_UNUSED, d->__ordering = REQUIRE_ORDER; ++optstring; } - else if (d->__posixly_correct) + else if (posixly_correct || !!getenv ("POSIXLY_CORRECT")) d->__ordering = REQUIRE_ORDER; else d->__ordering = PERMUTE; -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (!d->__posixly_correct - && argc == __libc_argc && argv == __libc_argv) - { - if (d->__nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - d->__nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = d->__nonoption_flags_max_len = strlen (orig_str); - if (d->__nonoption_flags_max_len < argc) - d->__nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (d->__nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - d->__nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', d->__nonoption_flags_max_len - len); - } - } - d->__nonoption_flags_len = d->__nonoption_flags_max_len; - } - else - d->__nonoption_flags_len = 0; -#endif - + d->__initialized = 1; return optstring; } @@ -344,8 +469,8 @@ _getopt_initialize (int argc _GL_UNUSED, int _getopt_internal_r (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, struct _getopt_data *d, int posixly_correct) + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d, int posixly_correct) { int print_errors = d->opterr; @@ -355,431 +480,129 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, d->optarg = NULL; if (d->optind == 0 || !d->__initialized) - { - if (d->optind == 0) - d->optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring, d, - posixly_correct); - d->__initialized = 1; - } + optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct); else if (optstring[0] == '-' || optstring[0] == '+') optstring++; + if (optstring[0] == ':') print_errors = 0; - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ - || (d->optind < d->__nonoption_flags_len \ - && __getopt_nonoption_flags[d->optind] == '1')) -#else -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') -#endif + /* Test whether ARGV[optind] points to a non-option argument. */ +#define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') if (d->__nextchar == NULL || *d->__nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ + moved back by the user (who may also have changed the arguments). */ if (d->__last_nonopt > d->optind) - d->__last_nonopt = d->optind; + d->__last_nonopt = d->optind; if (d->__first_nonopt > d->optind) - d->__first_nonopt = d->optind; + d->__first_nonopt = d->optind; if (d->__ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__last_nonopt != d->optind) - d->__first_nonopt = d->optind; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange (argv, d); + else if (d->__last_nonopt != d->optind) + d->__first_nonopt = d->optind; - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ - while (d->optind < argc && NONOPTION_P) - d->optind++; - d->__last_nonopt = d->optind; - } + while (d->optind < argc && NONOPTION_P) + d->optind++; + d->__last_nonopt = d->optind; + } /* The special ARGV-element '--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ if (d->optind != argc && !strcmp (argv[d->optind], "--")) - { - d->optind++; + { + d->optind++; - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__first_nonopt == d->__last_nonopt) - d->__first_nonopt = d->optind; - d->__last_nonopt = argc; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange (argv, d); + else if (d->__first_nonopt == d->__last_nonopt) + d->__first_nonopt = d->optind; + d->__last_nonopt = argc; - d->optind = argc; - } + d->optind = argc; + } /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ + and back over any non-options that we skipped and permuted. */ if (d->optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (d->__first_nonopt != d->__last_nonopt) - d->optind = d->__first_nonopt; - return -1; - } + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (d->__first_nonopt != d->__last_nonopt) + d->optind = d->__first_nonopt; + return -1; + } /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ + either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) - { - if (d->__ordering == REQUIRE_ORDER) - return -1; - d->optarg = argv[d->optind++]; - return 1; - } + { + if (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; + } /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - d->__nextchar = (argv[d->optind] + 1 - + (longopts != NULL && argv[d->optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[d->optind][1] == '-' - || (long_only && (argv[d->optind][2] - || !strchr (optstring, argv[d->optind][1]))))) - { - char *nameend; - unsigned int namelen; - const struct option *p; - const struct option *pfound = NULL; - struct option_list - { - const struct option *p; - struct option_list *next; - } *ambig_list = NULL; - int exact = 0; - int indfound = -1; - int option_index; - - for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - namelen = nameend - d->__nextchar; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, namelen)) - { - if (namelen == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - { - /* Second or later nonexact match found. */ - struct option_list *newp = malloc (sizeof (*newp)); - newp->p = p; - newp->next = ambig_list; - ambig_list = newp; - } - } - - if (ambig_list != NULL && !exact) - { - if (print_errors) - { - struct option_list first; - first.p = pfound; - first.next = ambig_list; - ambig_list = &first; - -#if defined _LIBC && defined USE_IN_LIBIO - char *buf = NULL; - size_t buflen = 0; - - FILE *fp = open_memstream (&buf, &buflen); - if (fp != NULL) - { - fprintf (fp, - _("%s: option '%s' is ambiguous; possibilities:"), - argv[0], argv[d->optind]); - - do - { - fprintf (fp, " '--%s'", ambig_list->p->name); - ambig_list = ambig_list->next; - } - while (ambig_list != NULL); - - fputc_unlocked ('\n', fp); - - if (__builtin_expect (fclose (fp) != EOF, 1)) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } - } -#else - fprintf (stderr, - _("%s: option '%s' is ambiguous; possibilities:"), - argv[0], argv[d->optind]); - do - { - fprintf (stderr, " '--%s'", ambig_list->p->name); - ambig_list = ambig_list->next; - } - while (ambig_list != NULL); - - fputc ('\n', stderr); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - d->optopt = 0; - return '?'; - } - - while (ambig_list != NULL) - { - struct option_list *pn = ambig_list->next; - free (ambig_list); - ambig_list = pn; - } - - if (pfound != NULL) - { - option_index = indfound; - d->optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind - 1][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option '--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#else - fprintf (stderr, _("\ -%s: option '--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option '%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#else - fprintf (stderr, _("\ -%s: option '%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - - d->__nextchar += strlen (d->__nextchar); - - d->optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '--%s' requires an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option '--%s' requires an argument\n"), - argv[0], pfound->name); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[d->optind][1] == '-' - || strchr (optstring, *d->__nextchar) == NULL) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), - argv[0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option '--%s'\n"), - argv[0], d->__nextchar); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->__nextchar = (char *) ""; - d->optind++; - d->optopt = 0; - return '?'; - } + Check whether it might be a long option. */ + if (longopts) + { + if (argv[d->optind][1] == '-') + { + /* "--foo" is always a long option. The special option + "--" was handled above. */ + d->__nextchar = argv[d->optind] + 2; + return process_long_option (argc, argv, optstring, longopts, + longind, long_only, d, + print_errors, "--"); + } + + /* If long_only and the ARGV-element has the form "-f", + where f is a valid short option, don't consider it an + abbreviated form of a long option that starts with f. + Otherwise there would be no way to give the -f short + option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an + abbreviation of the long option, just like "--fu", and + not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + if (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))) + { + int code; + d->__nextchar = argv[d->optind] + 1; + code = process_long_option (argc, argv, optstring, longopts, + longind, long_only, d, + print_errors, "-"); + if (code != -1) + return code; + } + } + + /* It is not a long option. Skip the initial punctuation. */ + d->__nextchar = argv[d->optind] + 1; } /* Look at and handle the next short option-character. */ @@ -794,331 +617,83 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, if (temp == NULL || c == ':' || c == ';') { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); -#endif - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->optopt = c; - return '?'; + if (print_errors) + fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); + d->optopt = c; + return '?'; } + /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') + if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL) { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - if (longopts == NULL) - goto no_longs; - - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented 'd->optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; - nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), - argv[0], d->optarg) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), - argv[0], d->optarg); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '-W %s' doesn't allow an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option '-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - - d->__nextchar += strlen (d->__nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '-W %s' requires an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option '-W %s' requires an argument\n"), - argv[0], pfound->name); -#endif - } - d->__nextchar += strlen (d->__nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - else - d->optarg = NULL; - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - no_longs: - d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + d->optarg = d->__nextchar; + else if (d->optind == argc) + { + if (print_errors) + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); + + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + d->optarg = argv[d->optind]; + + d->__nextchar = d->optarg; + d->optarg = NULL; + return process_long_option (argc, argv, optstring, longopts, longind, + 0 /* long_only */, d, print_errors, "-W "); } if (temp[1] == ':') { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - d->optind++; - } - else - d->optarg = NULL; - d->__nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option requires an argument -- '%c'\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented 'optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - d->__nextchar = NULL; - } + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); + + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented 'optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } } return c; } @@ -1126,8 +701,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, int _getopt_internal (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, int long_only, - int posixly_correct) + const struct option *longopts, int *longind, int long_only, + int posixly_correct) { int result; @@ -1135,8 +710,8 @@ _getopt_internal (int argc, char **argv, const char *optstring, getopt_data.opterr = opterr; result = _getopt_internal_r (argc, argv, optstring, longopts, - longind, long_only, &getopt_data, - posixly_correct); + longind, long_only, &getopt_data, + posixly_correct); optind = getopt_data.optind; optarg = getopt_data.optarg; @@ -1145,32 +720,23 @@ _getopt_internal (int argc, char **argv, const char *optstring, return result; } -/* glibc gets a LSB-compliant getopt. - Standalone applications get a POSIX-compliant getopt. */ -#if _LIBC -enum { POSIXLY_CORRECT = 0 }; -#else -enum { POSIXLY_CORRECT = 1 }; -#endif - -int -getopt (int argc, char *const *argv, const char *optstring) -{ - return _getopt_internal (argc, (char **) argv, optstring, - (const struct option *) 0, - (int *) 0, - 0, POSIXLY_CORRECT); -} +/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt. + Standalone applications just get a POSIX-compliant getopt. + POSIX and LSB both require these functions to take 'char *const *argv' + even though this is incorrect (because of the permutation). */ +#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \ + int \ + NAME (int argc, char *const *argv, const char *optstring) \ + { \ + return _getopt_internal (argc, (char **)argv, optstring, \ + 0, 0, 0, POSIXLY_CORRECT); \ + } #ifdef _LIBC -int -__posix_getopt (int argc, char *const *argv, const char *optstring) -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0, 1); -} +GETOPT_ENTRY(getopt, 0) +GETOPT_ENTRY(__posix_getopt, 1) +#else +GETOPT_ENTRY(getopt, 1) #endif @@ -1191,51 +757,51 @@ main (int argc, char **argv) c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) - break; + break; switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value '%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value '%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) - printf ("%s ", argv[optind++]); + printf ("%s ", argv[optind++]); printf ("\n"); } diff --git a/gl/getopt.in.h b/gl/getopt.in.h index d9c7d814..9bc50ee2 100644 --- a/gl/getopt.in.h +++ b/gl/getopt.in.h @@ -1,20 +1,22 @@ /* Declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - 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, + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of gnulib. + Unlike most of the getopt implementation, it is NOT shared + with the GNU C Library, which supplies a different version of + this file. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_GETOPT_H @@ -32,22 +34,15 @@ # undef _GL_SYSTEM_GETOPT #endif -#ifndef _@GUARD_PREFIX@_GETOPT_H - -#ifndef __need_getopt -# define _@GUARD_PREFIX@_GETOPT_H 1 -#endif +#define _@GUARD_PREFIX@_GETOPT_H 1 /* Standalone applications should #define __GETOPT_PREFIX to an identifier that prefixes the external functions and variables - defined in this header. When this happens, include the - headers that might declare getopt so that they will not cause - confusion if included after this file (if the system had , - we have already included it). Then systematically rename - identifiers so that they do not collide with the system functions - and variables. Renaming avoids problems with some compilers and - linkers. */ -#if defined __GETOPT_PREFIX && !defined __need_getopt + defined in getopt-core.h and getopt-ext.h. When this happens, + include the headers that might declare getopt so that they will not + cause confusion if included after this file (if the system had + , we have already included it). */ +#if defined __GETOPT_PREFIX # if !@HAVE_GETOPT_H@ # define __need_system_stdlib_h # include @@ -55,201 +50,12 @@ # include # include # endif -# undef __need_getopt -# undef getopt -# undef getopt_long -# undef getopt_long_only -# undef optarg -# undef opterr -# undef optind -# undef optopt -# undef option -# define __GETOPT_CONCAT(x, y) x ## y -# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) -# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) -# define getopt __GETOPT_ID (getopt) -# define getopt_long __GETOPT_ID (getopt_long) -# define getopt_long_only __GETOPT_ID (getopt_long_only) -# define optarg __GETOPT_ID (optarg) -# define opterr __GETOPT_ID (opterr) -# define optind __GETOPT_ID (optind) -# define optopt __GETOPT_ID (optopt) -# define option __GETOPT_ID (option) -# define _getopt_internal __GETOPT_ID (getopt_internal) -#endif - -/* Standalone applications get correct prototypes for getopt_long and - getopt_long_only; they declare "char **argv". libc uses prototypes - with "char *const *argv" that are incorrect because getopt_long and - getopt_long_only can permute argv; this is required for backward - compatibility (e.g., for LSB 2.0.1). - - This used to be '#if defined __GETOPT_PREFIX && !defined __need_getopt', - but it caused redefinition warnings if both unistd.h and getopt.h were - included, since unistd.h includes getopt.h having previously defined - __need_getopt. - - The only place where __getopt_argv_const is used is in definitions - of getopt_long and getopt_long_only below, but these are visible - only if __need_getopt is not defined, so it is quite safe to rewrite - the conditional as follows: -*/ -#if !defined __need_getopt -# if defined __GETOPT_PREFIX -# define __getopt_argv_const /* empty */ -# else -# define __getopt_argv_const const -# endif -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifndef __THROW -# ifndef __GNUC_PREREQ -# define __GNUC_PREREQ(maj, min) (0) -# endif -# if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () -# else -# define __THROW -# endif #endif /* The definition of _GL_ARG_NONNULL is copied here. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from 'getopt' to the caller. - When 'getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when 'ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to 'getopt'. - - On entry to 'getopt', zero means this is the first call; initialize. - - When 'getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, 'optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message 'getopt' prints - for unrecognized options. */ - -extern int opterr; +#include +#include +#include -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of 'struct option' terminated by an element containing a name which is - zero. - - The field 'has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field 'flag' is not NULL, it points to a variable that is set - to the value given in the field 'val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an 'int' to - a compiled-in constant, such as set a value from 'optarg', set the - option's 'flag' field to zero and its 'val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero 'flag' field, 'getopt' - returns the contents of the 'val' field. */ - -# if !GNULIB_defined_struct_option -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; -# define GNULIB_defined_struct_option 1 -# endif - -/* Names for the values of the 'has_arg' field of 'struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, 'optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in 'optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU 'getopt'. - - The argument '--' causes premature termination of argument - scanning, explicitly telling 'getopt' that there are no more - options. - - If OPTS begins with '-', then non-option arguments are treated as - arguments to the option '\1'. This behavior is specific to the GNU - 'getopt'. If OPTS begins with '+', or POSIXLY_CORRECT is set in - the environment, then do not permute arguments. */ - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __THROW _GL_ARG_NONNULL ((2, 3)); - -#ifndef __need_getopt -extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW _GL_ARG_NONNULL ((2, 3)); -extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW _GL_ARG_NONNULL ((2, 3)); - -#endif - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* _@GUARD_PREFIX@_GETOPT_H */ #endif /* _@GUARD_PREFIX@_GETOPT_H */ diff --git a/gl/getopt1.c b/gl/getopt1.c index 55a6b4ea..990eee1b 100644 --- a/gl/getopt1.c +++ b/gl/getopt1.c @@ -1,56 +1,44 @@ /* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987-1994, 1996-1998, 2004, 2006, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1987-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. - 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. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ -#ifdef _LIBC -# include -#else +#ifndef _LIBC # include -# include "getopt.h" #endif -#include "getopt_int.h" - -#include -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif +#include "getopt.h" +#include "getopt_int.h" int getopt_long (int argc, char *__getopt_argv_const *argv, const char *options, - const struct option *long_options, int *opt_index) + const struct option *long_options, int *opt_index) { return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 0, 0); + opt_index, 0, 0); } int _getopt_long_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) + const struct option *long_options, int *opt_index, + struct _getopt_data *d) { return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 0, d, 0); + 0, d, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -60,26 +48,27 @@ _getopt_long_r (int argc, char **argv, const char *options, int getopt_long_only (int argc, char *__getopt_argv_const *argv, - const char *options, - const struct option *long_options, int *opt_index) + const char *options, + const struct option *long_options, int *opt_index) { return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 1, 0); + opt_index, 1, 0); } int _getopt_long_only_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) + const struct option *long_options, int *opt_index, + struct _getopt_data *d) { return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 1, d, 0); + 1, d, 0); } #ifdef TEST #include +#include int main (int argc, char **argv) @@ -93,74 +82,74 @@ main (int argc, char **argv) int option_index = 0; static const struct option long_options[] = { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); + long_options, &option_index); if (c == -1) - break; + break; switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value '%s'\n", optarg); - break; - - case 'd': - printf ("option d with value '%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value '%s'\n", optarg); + break; + + case 'd': + printf ("option d with value '%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) - printf ("%s ", argv[optind++]); + printf ("%s ", argv[optind++]); printf ("\n"); } diff --git a/gl/getopt_int.h b/gl/getopt_int.h index a6e4b9ea..ccdbb973 100644 --- a/gl/getopt_int.h +++ b/gl/getopt_int.h @@ -1,30 +1,31 @@ /* Internal declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1989-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. - 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. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ #ifndef _GETOPT_INT_H -#define _GETOPT_INT_H 1 +#define _GETOPT_INT_H 1 #include extern int _getopt_internal (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct); + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, int __posixly_correct); /* Reentrant versions which can handle parsing multiple argument @@ -32,28 +33,20 @@ extern int _getopt_internal (int ___argc, char **___argv, /* Describe how to deal with options that follow non-option ARGV-elements. - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. + REQUIRE_ORDER means don't recognize them as options; stop option + processing when the first non-option is seen. This is what POSIX + specifies should happen. - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using '+' as the first character - of the list of option characters, or by calling getopt. - - PERMUTE is the default. We permute the contents of ARGV as we - scan, so that eventually all the non-options are at the end. - This allows options to be given in any order, even with programs - that were not written to expect this. + PERMUTE means permute the contents of ARGV as we scan, so that + eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written + to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option - with character code 1. Using '-' as the first character of the - list of option characters selects this mode of operation. + with character code 1. The special argument '--' forces an end of option-scanning regardless of the value of 'ordering'. In the case of RETURN_IN_ORDER, only @@ -91,11 +84,6 @@ struct _getopt_data /* See __ord above. */ enum __ord __ordering; - /* If the POSIXLY_CORRECT environment variable is set - or getopt was called. */ - int __posixly_correct; - - /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have @@ -104,32 +92,27 @@ struct _getopt_data int __first_nonopt; int __last_nonopt; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - int __nonoption_flags_max_len; - int __nonoption_flags_len; -#endif }; /* The initializer is necessary to set OPTIND and OPTERR to their default values and to clear the initialization flag. */ -#define _GETOPT_DATA_INITIALIZER { 1, 1 } +#define _GETOPT_DATA_INITIALIZER { 1, 1 } extern int _getopt_internal_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, struct _getopt_data *__data, - int __posixly_correct); + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, struct _getopt_data *__data, + int __posixly_correct); extern int _getopt_long_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - struct _getopt_data *__data); + const char *__shortopts, + const struct option *__longopts, int *__longind, + struct _getopt_data *__data); extern int _getopt_long_only_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, - int *__longind, - struct _getopt_data *__data); + const char *__shortopts, + const struct option *__longopts, + int *__longind, + struct _getopt_data *__data); #endif /* getopt_int.h */ diff --git a/gl/getprogname.c b/gl/getprogname.c new file mode 100644 index 00000000..62a48004 --- /dev/null +++ b/gl/getprogname.c @@ -0,0 +1,302 @@ +/* Program name management. + Copyright (C) 2016-2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "getprogname.h" + +#include /* get program_invocation_name declaration */ +#include /* get __argv declaration */ + +#ifdef _AIX +# include +# include +# include +#endif + +#ifdef __MVS__ +# ifndef _OPEN_SYS +# define _OPEN_SYS +# endif +# include +# include +#endif + +#ifdef __hpux +# include +# include +# include +# include +#endif + +#if defined __sgi || defined __osf__ +# include +# include +# include +# include +# include +#endif + +#if defined __SCO_VERSION__ || defined __sysv5__ +# include +# include +# include +#endif + +#include "basename-lgpl.h" + +#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */ +char const * +getprogname (void) +{ +# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */ + /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */ + return program_invocation_short_name; +# elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */ + /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */ + return last_component (program_invocation_name); +# elif HAVE_GETEXECNAME /* Solaris */ + /* https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */ + const char *p = getexecname (); + if (!p) + p = "?"; + return last_component (p); +# elif HAVE_DECL___ARGV /* mingw, MSVC */ + /* https://docs.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv */ + const char *p = __argv && __argv[0] ? __argv[0] : "?"; + return last_component (p); +# elif HAVE_VAR___PROGNAME /* OpenBSD, Android, QNX */ + /* https://man.openbsd.org/style.9 */ + /* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */ + /* Be careful to declare this only when we absolutely need it + (OpenBSD 5.1), rather than when it's available. Otherwise, + its mere declaration makes program_invocation_short_name + malfunction (have zero length) with Fedora 25's glibc. */ + extern char *__progname; + const char *p = __progname; +# if defined __ANDROID__ + return last_component (p); +# else + return p && p[0] ? p : "?"; +# endif +# elif _AIX /* AIX */ + /* Idea by Bastien ROUCARIÈS, + https://lists.gnu.org/r/bug-gnulib/2010-12/msg00095.html + Reference: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/getprocs.htm + */ + static char *p; + static int first = 1; + if (first) + { + first = 0; + pid_t pid = getpid (); + struct procentry64 procs; + p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1) + ? strdup (procs.pi_comm) + : NULL); + if (!p) + p = "?"; + } + return p; +# elif defined __hpux + static char *p; + static int first = 1; + if (first) + { + first = 0; + pid_t pid = getpid (); + struct pst_status status; + if (pstat_getproc (&status, sizeof status, 0, pid) > 0) + { + char *ucomm = status.pst_ucomm; + char *cmd = status.pst_cmd; + if (strlen (ucomm) < PST_UCOMMLEN - 1) + p = ucomm; + else + { + /* ucomm is truncated to length PST_UCOMMLEN - 1. + Look at cmd instead. */ + char *space = strchr (cmd, ' '); + if (space != NULL) + *space = '\0'; + p = strrchr (cmd, '/'); + if (p != NULL) + p++; + else + p = cmd; + if (strlen (p) > PST_UCOMMLEN - 1 + && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0) + /* p is less truncated than ucomm. */ + ; + else + p = ucomm; + } + p = strdup (p); + } + else + { +# if !defined __LP64__ + /* Support for 32-bit programs running in 64-bit HP-UX. + The documented way to do this is to use the same source code + as above, but in a compilation unit where '#define _PSTAT64 1' + is in effect. I prefer a single compilation unit; the struct + size and the offsets are not going to change. */ + char status64[1216]; + if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0) + { + char *ucomm = status64 + 288; + char *cmd = status64 + 168; + if (strlen (ucomm) < PST_UCOMMLEN - 1) + p = ucomm; + else + { + /* ucomm is truncated to length PST_UCOMMLEN - 1. + Look at cmd instead. */ + char *space = strchr (cmd, ' '); + if (space != NULL) + *space = '\0'; + p = strrchr (cmd, '/'); + if (p != NULL) + p++; + else + p = cmd; + if (strlen (p) > PST_UCOMMLEN - 1 + && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0) + /* p is less truncated than ucomm. */ + ; + else + p = ucomm; + } + p = strdup (p); + } + else +# endif + p = NULL; + } + if (!p) + p = "?"; + } + return p; +# elif __MVS__ /* z/OS */ + /* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */ + static char *p = "?"; + static int first = 1; + if (first) + { + pid_t pid = getpid (); + int token; + W_PSPROC buf; + first = 0; + memset (&buf, 0, sizeof(buf)); + buf.ps_cmdptr = (char *) malloc (buf.ps_cmdlen = PS_CMDBLEN_LONG); + buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN); + buf.ps_pathptr = (char *) malloc (buf.ps_pathlen = PS_PATHBLEN); + if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr) + { + for (token = 0; token >= 0; + token = w_getpsent (token, &buf, sizeof(buf))) + { + if (token > 0 && buf.ps_pid == pid) + { + char *s = strdup (last_component (buf.ps_pathptr)); + if (s) + p = s; + break; + } + } + } + free (buf.ps_cmdptr); + free (buf.ps_conttyptr); + free (buf.ps_pathptr); + } + return p; +# elif defined __sgi || defined __osf__ /* IRIX or Tru64 */ + char filename[50]; + int fd; + + # if defined __sgi + sprintf (filename, "/proc/pinfo/%d", (int) getpid ()); + # else + sprintf (filename, "/proc/%d", (int) getpid ()); + # endif + fd = open (filename, O_RDONLY | O_CLOEXEC); + if (0 <= fd) + { + prpsinfo_t buf; + int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf); + close (fd); + if (ioctl_ok) + { + char *name = buf.pr_fname; + size_t namesize = sizeof buf.pr_fname; + /* It may not be NUL-terminated. */ + char *namenul = memchr (name, '\0', namesize); + size_t namelen = namenul ? namenul - name : namesize; + char *namecopy = malloc (namelen + 1); + if (namecopy) + { + namecopy[namelen] = '\0'; + return memcpy (namecopy, name, namelen); + } + } + } + return NULL; +# elif defined __SCO_VERSION__ || defined __sysv5__ /* SCO OpenServer6/UnixWare */ + char buf[80]; + int fd; + sprintf (buf, "/proc/%d/cmdline", getpid()); + fd = open (buf, O_RDONLY); + if (0 <= fd) + { + size_t n = read (fd, buf, 79); + if (n > 0) + { + buf[n] = '\0'; /* Guarantee null-termination */ + char *progname; + progname = strrchr (buf, '/'); + if (progname) + { + progname = progname + 1; /* Skip the '/' */ + } + else + { + progname = buf; + } + char *ret; + ret = malloc (strlen (progname) + 1); + if (ret) + { + strcpy (ret, progname); + return ret; + } + } + close (fd); + } + return "?"; +# else +# error "getprogname module not ported to this OS" +# endif +} + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/gl/getprogname.h b/gl/getprogname.h new file mode 100644 index 00000000..9a35e584 --- /dev/null +++ b/gl/getprogname.h @@ -0,0 +1,40 @@ +/* Program name management. + Copyright (C) 2016-2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_GETPROGNAME_H +#define _GL_GETPROGNAME_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return the base name of the executing program. + On native Windows this will usually end in ".exe" or ".EXE". */ +#ifndef HAVE_GETPROGNAME +extern char const *getprogname (void) +# ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME + _GL_ATTRIBUTE_PURE +# endif + ; +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gl/gettext.h b/gl/gettext.h index d0215715..b3577a04 100644 --- a/gl/gettext.h +++ b/gl/gettext.h @@ -1,25 +1,26 @@ /* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2013 Free Software + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS +/* NLS can be disabled through the configure --disable-nls option + or through "#define ENABLE NLS 0" before including this file. */ +#if defined ENABLE_NLS && ENABLE_NLS /* Get declarations of GNU message catalog functions. */ # include @@ -137,7 +138,7 @@ #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) -#ifdef __GNUC__ +#if defined __GNUC__ || defined __clang__ __inline #else #ifdef __cplusplus @@ -156,7 +157,7 @@ pgettext_aux (const char *domain, return translation; } -#ifdef __GNUC__ +#if defined __GNUC__ || defined __clang__ __inline #else #ifdef __cplusplus @@ -183,8 +184,15 @@ npgettext_aux (const char *domain, #include -#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) +/* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported. + This relates to the -Wvla and -Wvla-larger-than warnings, enabled in + the default GCC many warnings set. This allows programs to disable use + of VLAs, which may be unintended, or may be awkward to support portably, + or may have security implications due to non-deterministic stack usage. */ + +#if (!defined GNULIB_NO_VLA \ + && defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \ + && !defined __STDC_NO_VLA__) # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 #else # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 @@ -199,7 +207,7 @@ npgettext_aux (const char *domain, #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) -#ifdef __GNUC__ +#if defined __GNUC__ || defined __clang__ __inline #else #ifdef __cplusplus @@ -225,15 +233,17 @@ dcpgettext_expr (const char *domain, if (msg_ctxt_id != NULL) #endif { + int found_translation; memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcgettext (domain, msg_ctxt_id, category); + found_translation = (translation != msg_ctxt_id); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif - if (translation != msg_ctxt_id) + if (found_translation) return translation; } return msgid; @@ -244,7 +254,7 @@ dcpgettext_expr (const char *domain, #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#ifdef __GNUC__ +#if defined __GNUC__ || defined __clang__ __inline #else #ifdef __cplusplus @@ -271,15 +281,17 @@ dcnpgettext_expr (const char *domain, if (msg_ctxt_id != NULL) #endif { + int found_translation; memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) + if (found_translation) return translation; } return (n == 1 ? msgid : msgid_plural); diff --git a/gl/gl_openssl.h b/gl/gl_openssl.h new file mode 100644 index 00000000..4c42ac86 --- /dev/null +++ b/gl/gl_openssl.h @@ -0,0 +1,116 @@ +/* Wrap openssl crypto hash routines in gnulib interface. -*- coding: utf-8 -*- + + Copyright (C) 2013-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Pádraig Brady */ + +#ifndef GL_OPENSSL_NAME +# error "Please define GL_OPENSSL_NAME to 1,5,256 etc." +#endif + +#ifndef _GL_INLINE_HEADER_BEGIN +# error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef GL_OPENSSL_INLINE +# define GL_OPENSSL_INLINE _GL_INLINE +#endif + +/* Concatenate two preprocessor tokens. */ +#define _GLCRYPTO_CONCAT_(prefix, suffix) prefix##suffix +#define _GLCRYPTO_CONCAT(prefix, suffix) _GLCRYPTO_CONCAT_ (prefix, suffix) + +#if GL_OPENSSL_NAME == 5 +# define OPENSSL_ALG md5 +#else +# define OPENSSL_ALG _GLCRYPTO_CONCAT (sha, GL_OPENSSL_NAME) +#endif + +/* Context type mappings. */ +#if BASE_OPENSSL_TYPE != GL_OPENSSL_NAME +# undef BASE_OPENSSL_TYPE +# if GL_OPENSSL_NAME == 224 +# define BASE_OPENSSL_TYPE 256 +# elif GL_OPENSSL_NAME == 384 +# define BASE_OPENSSL_TYPE 512 +# endif +# define md5_CTX MD5_CTX +# define sha1_CTX SHA_CTX +# define sha224_CTX SHA256_CTX +# define sha224_ctx sha256_ctx +# define sha256_CTX SHA256_CTX +# define sha384_CTX SHA512_CTX +# define sha384_ctx sha512_ctx +# define sha512_CTX SHA512_CTX +# undef _gl_CTX +# undef _gl_ctx +# define _gl_CTX _GLCRYPTO_CONCAT (OPENSSL_ALG, _CTX) /* openssl type. */ +# define _gl_ctx _GLCRYPTO_CONCAT (OPENSSL_ALG, _ctx) /* gnulib type. */ + +struct _gl_ctx { _gl_CTX CTX; }; +#endif + +/* Function name mappings. */ +#define md5_prefix MD5 +#define sha1_prefix SHA1 +#define sha224_prefix SHA224 +#define sha256_prefix SHA256 +#define sha384_prefix SHA384 +#define sha512_prefix SHA512 +#define _GLCRYPTO_PREFIX _GLCRYPTO_CONCAT (OPENSSL_ALG, _prefix) +#define OPENSSL_FN(suffix) _GLCRYPTO_CONCAT (_GLCRYPTO_PREFIX, suffix) +#define GL_CRYPTO_FN(suffix) _GLCRYPTO_CONCAT (OPENSSL_ALG, suffix) + +GL_OPENSSL_INLINE void +GL_CRYPTO_FN (_init_ctx) (struct _gl_ctx *ctx) +{ (void) OPENSSL_FN (_Init) ((_gl_CTX *) ctx); } + +/* These were never exposed by gnulib. */ +#if ! (GL_OPENSSL_NAME == 224 || GL_OPENSSL_NAME == 384) +GL_OPENSSL_INLINE void +GL_CRYPTO_FN (_process_bytes) (const void *buf, size_t len, struct _gl_ctx *ctx) +{ OPENSSL_FN (_Update) ((_gl_CTX *) ctx, buf, len); } + +GL_OPENSSL_INLINE void +GL_CRYPTO_FN (_process_block) (const void *buf, size_t len, struct _gl_ctx *ctx) +{ GL_CRYPTO_FN (_process_bytes) (buf, len, ctx); } +#endif + +GL_OPENSSL_INLINE void * +GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void *restrict res) +{ OPENSSL_FN (_Final) ((unsigned char *) res, (_gl_CTX *) ctx); return res; } + +GL_OPENSSL_INLINE void * +GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void *restrict res) +{ return OPENSSL_FN () ((const unsigned char *) buf, len, (unsigned char *) res); } + +GL_OPENSSL_INLINE void * +GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void *restrict res) +{ + /* Assume any unprocessed bytes in ctx are not to be ignored. */ + _gl_CTX tmp_ctx = *(_gl_CTX *) ctx; + OPENSSL_FN (_Final) ((unsigned char *) res, &tmp_ctx); + return res; +} + +/* Undef so we can include multiple times. */ +#undef GL_CRYPTO_FN +#undef OPENSSL_FN +#undef _GLCRYPTO_PREFIX +#undef OPENSSL_ALG +#undef GL_OPENSSL_NAME + +_GL_INLINE_HEADER_END diff --git a/gl/glthread/lock.c b/gl/glthread/lock.c index f62aa301..b650c219 100644 --- a/gl/glthread/lock.c +++ b/gl/glthread/lock.c @@ -1,22 +1,21 @@ /* Locking in multithreaded situations. - Copyright (C) 2005-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ + Based on GCC's gthr-posix.h, gthr-posix95.h. */ #include @@ -24,15 +23,267 @@ /* ========================================================================= */ +#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS + +/* -------------------------- gl_lock_t datatype -------------------------- */ + +int +glthread_lock_init (gl_lock_t *lock) +{ + if (mtx_init (&lock->mutex, mtx_plain) != thrd_success) + return ENOMEM; + lock->init_needed = 0; + return 0; +} + +int +glthread_lock_lock (gl_lock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_lock (&lock->mutex) != thrd_success) + return EAGAIN; + return 0; +} + +int +glthread_lock_unlock (gl_lock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_unlock (&lock->mutex) != thrd_success) + return EINVAL; + return 0; +} + +int +glthread_lock_destroy (gl_lock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + mtx_destroy (&lock->mutex); + return 0; +} + +/* ------------------------- gl_rwlock_t datatype ------------------------- */ + +int +glthread_rwlock_init (gl_rwlock_t *lock) +{ + if (mtx_init (&lock->lock, mtx_plain) != thrd_success + || cnd_init (&lock->waiting_readers) != thrd_success + || cnd_init (&lock->waiting_writers) != thrd_success) + return ENOMEM; + lock->waiting_writers_count = 0; + lock->runcount = 0; + lock->init_needed = 0; + return 0; +} + +int +glthread_rwlock_rdlock (gl_rwlock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_lock (&lock->lock) != thrd_success) + return EAGAIN; + /* Test whether only readers are currently running, and whether the runcount + field will not overflow, and whether no writer is waiting. The latter + condition is because POSIX recommends that "write locks shall take + precedence over read locks", to avoid "writer starvation". */ + while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0)) + { + /* This thread has to wait for a while. Enqueue it among the + waiting_readers. */ + if (cnd_wait (&lock->waiting_readers, &lock->lock) != thrd_success) + { + mtx_unlock (&lock->lock); + return EINVAL; + } + } + lock->runcount++; + if (mtx_unlock (&lock->lock) != thrd_success) + return EINVAL; + return 0; +} + +int +glthread_rwlock_wrlock (gl_rwlock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_lock (&lock->lock) != thrd_success) + return EAGAIN; + /* Test whether no readers or writers are currently running. */ + while (!(lock->runcount == 0)) + { + /* This thread has to wait for a while. Enqueue it among the + waiting_writers. */ + lock->waiting_writers_count++; + if (cnd_wait (&lock->waiting_writers, &lock->lock) != thrd_success) + { + lock->waiting_writers_count--; + mtx_unlock (&lock->lock); + return EINVAL; + } + lock->waiting_writers_count--; + } + lock->runcount--; /* runcount becomes -1 */ + if (mtx_unlock (&lock->lock) != thrd_success) + return EINVAL; + return 0; +} + +int +glthread_rwlock_unlock (gl_rwlock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_lock (&lock->lock) != thrd_success) + return EAGAIN; + if (lock->runcount < 0) + { + /* Drop a writer lock. */ + if (!(lock->runcount == -1)) + { + mtx_unlock (&lock->lock); + return EINVAL; + } + lock->runcount = 0; + } + else + { + /* Drop a reader lock. */ + if (!(lock->runcount > 0)) + { + mtx_unlock (&lock->lock); + return EINVAL; + } + lock->runcount--; + } + if (lock->runcount == 0) + { + /* POSIX recommends that "write locks shall take precedence over read + locks", to avoid "writer starvation". */ + if (lock->waiting_writers_count > 0) + { + /* Wake up one of the waiting writers. */ + if (cnd_signal (&lock->waiting_writers) != thrd_success) + { + mtx_unlock (&lock->lock); + return EINVAL; + } + } + else + { + /* Wake up all waiting readers. */ + if (cnd_broadcast (&lock->waiting_readers) != thrd_success) + { + mtx_unlock (&lock->lock); + return EINVAL; + } + } + } + if (mtx_unlock (&lock->lock) != thrd_success) + return EINVAL; + return 0; +} + +int +glthread_rwlock_destroy (gl_rwlock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + mtx_destroy (&lock->lock); + cnd_destroy (&lock->waiting_readers); + cnd_destroy (&lock->waiting_writers); + return 0; +} + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +int +glthread_recursive_lock_init (gl_recursive_lock_t *lock) +{ + if (mtx_init (&lock->mutex, mtx_plain | mtx_recursive) != thrd_success) + return ENOMEM; + lock->init_needed = 0; + return 0; +} + +int +glthread_recursive_lock_lock (gl_recursive_lock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_lock (&lock->mutex) != thrd_success) + return EAGAIN; + return 0; +} + +int +glthread_recursive_lock_unlock (gl_recursive_lock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + if (mtx_unlock (&lock->mutex) != thrd_success) + return EINVAL; + return 0; +} + +int +glthread_recursive_lock_destroy (gl_recursive_lock_t *lock) +{ + if (lock->init_needed) + call_once (&lock->init_once, lock->init_func); + mtx_destroy (&lock->mutex); + return 0; +} + +/* -------------------------- gl_once_t datatype -------------------------- */ + +#endif + +/* ========================================================================= */ + #if USE_POSIX_THREADS /* -------------------------- gl_lock_t datatype -------------------------- */ /* ------------------------- gl_rwlock_t datatype ------------------------- */ -# if HAVE_PTHREAD_RWLOCK +# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1))) + +# if defined PTHREAD_RWLOCK_INITIALIZER || defined PTHREAD_RWLOCK_INITIALIZER_NP + +# if !HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER + /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */ + +int +glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock) +{ + pthread_rwlockattr_t attributes; + int err; -# if !defined PTHREAD_RWLOCK_INITIALIZER + err = pthread_rwlockattr_init (&attributes); + if (err != 0) + return err; + /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that + causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not + do this; see + http://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */ + err = pthread_rwlockattr_setkind_np (&attributes, + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); + if (err == 0) + err = pthread_rwlock_init(lock, &attributes); + /* pthread_rwlockattr_destroy always returns 0. It cannot influence the + return value. */ + pthread_rwlockattr_destroy (&attributes); + return err; +} + +# endif +# else int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) @@ -152,11 +403,9 @@ glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) if (err != 0) return err; /* Test whether only readers are currently running, and whether the runcount - field will not overflow. */ - /* POSIX says: "It is implementation-defined whether the calling thread - acquires the lock when a writer does not hold the lock and there are - writers blocked on the lock." Let's say, no: give the writers a higher - priority. */ + field will not overflow, and whether no writer is waiting. The latter + condition is because POSIX recommends that "write locks shall take + precedence over read locks", to avoid "writer starvation". */ while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0)) { /* This thread has to wait for a while. Enqueue it among the @@ -469,161 +718,25 @@ glthread_once_singlethreaded (pthread_once_t *once_control) return 0; } -#endif - -/* ========================================================================= */ - -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -/* -------------------------- gl_lock_t datatype -------------------------- */ - -/* ------------------------- gl_rwlock_t datatype ------------------------- */ - -/* --------------------- gl_recursive_lock_t datatype --------------------- */ - -/* -------------------------- gl_once_t datatype -------------------------- */ - -static void -glthread_once_call (void *arg) -{ - void (**gl_once_temp_addr) (void) = (void (**) (void)) arg; - void (*initfunction) (void) = *gl_once_temp_addr; - initfunction (); -} - -int -glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void)) -{ - void (*temp) (void) = initfunction; - return (!pth_once (once_control, glthread_once_call, &temp) ? errno : 0); -} - -int -glthread_once_singlethreaded (pth_once_t *once_control) -{ - /* We know that pth_once_t is an integer type. */ - if (*once_control == PTH_ONCE_INIT) - { - /* First time use of once_control. Invert the marker. */ - *once_control = ~ PTH_ONCE_INIT; - return 1; - } - else - return 0; -} - -#endif - -/* ========================================================================= */ - -#if USE_SOLARIS_THREADS - -/* Use the old Solaris threads library. */ - -/* -------------------------- gl_lock_t datatype -------------------------- */ - -/* ------------------------- gl_rwlock_t datatype ------------------------- */ - -/* --------------------- gl_recursive_lock_t datatype --------------------- */ +# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) int -glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) +glthread_once_multithreaded (pthread_once_t *once_control, + void (*init_function) (void)) { - int err; - - err = mutex_init (&lock->mutex, USYNC_THREAD, NULL); - if (err != 0) - return err; - lock->owner = (thread_t) 0; - lock->depth = 0; - return 0; -} - -int -glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock) -{ - thread_t self = thr_self (); - if (lock->owner != self) + int err = pthread_once (once_control, init_function); + if (err == ENOSYS) { - int err; - - err = mutex_lock (&lock->mutex); - if (err != 0) - return err; - lock->owner = self; + /* This happens on FreeBSD 11: The pthread_once function in libc returns + ENOSYS. */ + if (glthread_once_singlethreaded (once_control)) + init_function (); + return 0; } - if (++(lock->depth) == 0) /* wraparound? */ - { - lock->depth--; - return EAGAIN; - } - return 0; + return err; } -int -glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock) -{ - if (lock->owner != thr_self ()) - return EPERM; - if (lock->depth == 0) - return EINVAL; - if (--(lock->depth) == 0) - { - lock->owner = (thread_t) 0; - return mutex_unlock (&lock->mutex); - } - else - return 0; -} - -int -glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) -{ - if (lock->owner != (thread_t) 0) - return EBUSY; - return mutex_destroy (&lock->mutex); -} - -/* -------------------------- gl_once_t datatype -------------------------- */ - -int -glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void)) -{ - if (!once_control->inited) - { - int err; - - /* Use the mutex to guarantee that if another thread is already calling - the initfunction, this thread waits until it's finished. */ - err = mutex_lock (&once_control->mutex); - if (err != 0) - return err; - if (!once_control->inited) - { - once_control->inited = 1; - initfunction (); - } - return mutex_unlock (&once_control->mutex); - } - else - return 0; -} - -int -glthread_once_singlethreaded (gl_once_t *once_control) -{ - /* We know that gl_once_t contains an integer type. */ - if (!once_control->inited) - { - /* First time use of once_control. Invert the marker. */ - once_control->inited = ~ 0; - return 1; - } - else - return 0; -} +# endif #endif @@ -631,427 +744,6 @@ glthread_once_singlethreaded (gl_once_t *once_control) #if USE_WINDOWS_THREADS -/* -------------------------- gl_lock_t datatype -------------------------- */ - -void -glthread_lock_init_func (gl_lock_t *lock) -{ - InitializeCriticalSection (&lock->lock); - lock->guard.done = 1; -} - -int -glthread_lock_lock_func (gl_lock_t *lock) -{ - if (!lock->guard.done) - { - if (InterlockedIncrement (&lock->guard.started) == 0) - /* This thread is the first one to need this lock. Initialize it. */ - glthread_lock_init (lock); - else - /* Yield the CPU while waiting for another thread to finish - initializing this lock. */ - while (!lock->guard.done) - Sleep (0); - } - EnterCriticalSection (&lock->lock); - return 0; -} - -int -glthread_lock_unlock_func (gl_lock_t *lock) -{ - if (!lock->guard.done) - return EINVAL; - LeaveCriticalSection (&lock->lock); - return 0; -} - -int -glthread_lock_destroy_func (gl_lock_t *lock) -{ - if (!lock->guard.done) - return EINVAL; - DeleteCriticalSection (&lock->lock); - lock->guard.done = 0; - return 0; -} - -/* ------------------------- gl_rwlock_t datatype ------------------------- */ - -/* In this file, the waitqueues are implemented as circular arrays. */ -#define gl_waitqueue_t gl_carray_waitqueue_t - -static void -gl_waitqueue_init (gl_waitqueue_t *wq) -{ - wq->array = NULL; - wq->count = 0; - wq->alloc = 0; - wq->offset = 0; -} - -/* Enqueues the current thread, represented by an event, in a wait queue. - Returns INVALID_HANDLE_VALUE if an allocation failure occurs. */ -static HANDLE -gl_waitqueue_add (gl_waitqueue_t *wq) -{ - HANDLE event; - unsigned int index; - - if (wq->count == wq->alloc) - { - unsigned int new_alloc = 2 * wq->alloc + 1; - HANDLE *new_array = - (HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE)); - if (new_array == NULL) - /* No more memory. */ - return INVALID_HANDLE_VALUE; - /* Now is a good opportunity to rotate the array so that its contents - starts at offset 0. */ - if (wq->offset > 0) - { - unsigned int old_count = wq->count; - unsigned int old_alloc = wq->alloc; - unsigned int old_offset = wq->offset; - unsigned int i; - if (old_offset + old_count > old_alloc) - { - unsigned int limit = old_offset + old_count - old_alloc; - for (i = 0; i < limit; i++) - new_array[old_alloc + i] = new_array[i]; - } - for (i = 0; i < old_count; i++) - new_array[i] = new_array[old_offset + i]; - wq->offset = 0; - } - wq->array = new_array; - wq->alloc = new_alloc; - } - /* Whether the created event is a manual-reset one or an auto-reset one, - does not matter, since we will wait on it only once. */ - event = CreateEvent (NULL, TRUE, FALSE, NULL); - if (event == INVALID_HANDLE_VALUE) - /* No way to allocate an event. */ - return INVALID_HANDLE_VALUE; - index = wq->offset + wq->count; - if (index >= wq->alloc) - index -= wq->alloc; - wq->array[index] = event; - wq->count++; - return event; -} - -/* Notifies the first thread from a wait queue and dequeues it. */ -static void -gl_waitqueue_notify_first (gl_waitqueue_t *wq) -{ - SetEvent (wq->array[wq->offset + 0]); - wq->offset++; - wq->count--; - if (wq->count == 0 || wq->offset == wq->alloc) - wq->offset = 0; -} - -/* Notifies all threads from a wait queue and dequeues them all. */ -static void -gl_waitqueue_notify_all (gl_waitqueue_t *wq) -{ - unsigned int i; - - for (i = 0; i < wq->count; i++) - { - unsigned int index = wq->offset + i; - if (index >= wq->alloc) - index -= wq->alloc; - SetEvent (wq->array[index]); - } - wq->count = 0; - wq->offset = 0; -} - -void -glthread_rwlock_init_func (gl_rwlock_t *lock) -{ - InitializeCriticalSection (&lock->lock); - gl_waitqueue_init (&lock->waiting_readers); - gl_waitqueue_init (&lock->waiting_writers); - lock->runcount = 0; - lock->guard.done = 1; -} - -int -glthread_rwlock_rdlock_func (gl_rwlock_t *lock) -{ - if (!lock->guard.done) - { - if (InterlockedIncrement (&lock->guard.started) == 0) - /* This thread is the first one to need this lock. Initialize it. */ - glthread_rwlock_init (lock); - else - /* Yield the CPU while waiting for another thread to finish - initializing this lock. */ - while (!lock->guard.done) - Sleep (0); - } - EnterCriticalSection (&lock->lock); - /* Test whether only readers are currently running, and whether the runcount - field will not overflow. */ - if (!(lock->runcount + 1 > 0)) - { - /* This thread has to wait for a while. Enqueue it among the - waiting_readers. */ - HANDLE event = gl_waitqueue_add (&lock->waiting_readers); - if (event != INVALID_HANDLE_VALUE) - { - DWORD result; - LeaveCriticalSection (&lock->lock); - /* Wait until another thread signals this event. */ - result = WaitForSingleObject (event, INFINITE); - if (result == WAIT_FAILED || result == WAIT_TIMEOUT) - abort (); - CloseHandle (event); - /* The thread which signalled the event already did the bookkeeping: - removed us from the waiting_readers, incremented lock->runcount. */ - if (!(lock->runcount > 0)) - abort (); - return 0; - } - else - { - /* Allocation failure. Weird. */ - do - { - LeaveCriticalSection (&lock->lock); - Sleep (1); - EnterCriticalSection (&lock->lock); - } - while (!(lock->runcount + 1 > 0)); - } - } - lock->runcount++; - LeaveCriticalSection (&lock->lock); - return 0; -} - -int -glthread_rwlock_wrlock_func (gl_rwlock_t *lock) -{ - if (!lock->guard.done) - { - if (InterlockedIncrement (&lock->guard.started) == 0) - /* This thread is the first one to need this lock. Initialize it. */ - glthread_rwlock_init (lock); - else - /* Yield the CPU while waiting for another thread to finish - initializing this lock. */ - while (!lock->guard.done) - Sleep (0); - } - EnterCriticalSection (&lock->lock); - /* Test whether no readers or writers are currently running. */ - if (!(lock->runcount == 0)) - { - /* This thread has to wait for a while. Enqueue it among the - waiting_writers. */ - HANDLE event = gl_waitqueue_add (&lock->waiting_writers); - if (event != INVALID_HANDLE_VALUE) - { - DWORD result; - LeaveCriticalSection (&lock->lock); - /* Wait until another thread signals this event. */ - result = WaitForSingleObject (event, INFINITE); - if (result == WAIT_FAILED || result == WAIT_TIMEOUT) - abort (); - CloseHandle (event); - /* The thread which signalled the event already did the bookkeeping: - removed us from the waiting_writers, set lock->runcount = -1. */ - if (!(lock->runcount == -1)) - abort (); - return 0; - } - else - { - /* Allocation failure. Weird. */ - do - { - LeaveCriticalSection (&lock->lock); - Sleep (1); - EnterCriticalSection (&lock->lock); - } - while (!(lock->runcount == 0)); - } - } - lock->runcount--; /* runcount becomes -1 */ - LeaveCriticalSection (&lock->lock); - return 0; -} - -int -glthread_rwlock_unlock_func (gl_rwlock_t *lock) -{ - if (!lock->guard.done) - return EINVAL; - EnterCriticalSection (&lock->lock); - if (lock->runcount < 0) - { - /* Drop a writer lock. */ - if (!(lock->runcount == -1)) - abort (); - lock->runcount = 0; - } - else - { - /* Drop a reader lock. */ - if (!(lock->runcount > 0)) - { - LeaveCriticalSection (&lock->lock); - return EPERM; - } - lock->runcount--; - } - if (lock->runcount == 0) - { - /* POSIX recommends that "write locks shall take precedence over read - locks", to avoid "writer starvation". */ - if (lock->waiting_writers.count > 0) - { - /* Wake up one of the waiting writers. */ - lock->runcount--; - gl_waitqueue_notify_first (&lock->waiting_writers); - } - else - { - /* Wake up all waiting readers. */ - lock->runcount += lock->waiting_readers.count; - gl_waitqueue_notify_all (&lock->waiting_readers); - } - } - LeaveCriticalSection (&lock->lock); - return 0; -} - -int -glthread_rwlock_destroy_func (gl_rwlock_t *lock) -{ - if (!lock->guard.done) - return EINVAL; - if (lock->runcount != 0) - return EBUSY; - DeleteCriticalSection (&lock->lock); - if (lock->waiting_readers.array != NULL) - free (lock->waiting_readers.array); - if (lock->waiting_writers.array != NULL) - free (lock->waiting_writers.array); - lock->guard.done = 0; - return 0; -} - -/* --------------------- gl_recursive_lock_t datatype --------------------- */ - -void -glthread_recursive_lock_init_func (gl_recursive_lock_t *lock) -{ - lock->owner = 0; - lock->depth = 0; - InitializeCriticalSection (&lock->lock); - lock->guard.done = 1; -} - -int -glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock) -{ - if (!lock->guard.done) - { - if (InterlockedIncrement (&lock->guard.started) == 0) - /* This thread is the first one to need this lock. Initialize it. */ - glthread_recursive_lock_init (lock); - else - /* Yield the CPU while waiting for another thread to finish - initializing this lock. */ - while (!lock->guard.done) - Sleep (0); - } - { - DWORD self = GetCurrentThreadId (); - if (lock->owner != self) - { - EnterCriticalSection (&lock->lock); - lock->owner = self; - } - if (++(lock->depth) == 0) /* wraparound? */ - { - lock->depth--; - return EAGAIN; - } - } - return 0; -} - -int -glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock) -{ - if (lock->owner != GetCurrentThreadId ()) - return EPERM; - if (lock->depth == 0) - return EINVAL; - if (--(lock->depth) == 0) - { - lock->owner = 0; - LeaveCriticalSection (&lock->lock); - } - return 0; -} - -int -glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock) -{ - if (lock->owner != 0) - return EBUSY; - DeleteCriticalSection (&lock->lock); - lock->guard.done = 0; - return 0; -} - -/* -------------------------- gl_once_t datatype -------------------------- */ - -void -glthread_once_func (gl_once_t *once_control, void (*initfunction) (void)) -{ - if (once_control->inited <= 0) - { - if (InterlockedIncrement (&once_control->started) == 0) - { - /* This thread is the first one to come to this once_control. */ - InitializeCriticalSection (&once_control->lock); - EnterCriticalSection (&once_control->lock); - once_control->inited = 0; - initfunction (); - once_control->inited = 1; - LeaveCriticalSection (&once_control->lock); - } - else - { - /* Undo last operation. */ - InterlockedDecrement (&once_control->started); - /* Some other thread has already started the initialization. - Yield the CPU while waiting for the other thread to finish - initializing and taking the lock. */ - while (once_control->inited < 0) - Sleep (0); - if (once_control->inited <= 0) - { - /* Take the lock. This blocks until the other thread has - finished calling the initfunction. */ - EnterCriticalSection (&once_control->lock); - LeaveCriticalSection (&once_control->lock); - if (!(once_control->inited > 0)) - abort (); - } - } - } -} - #endif /* ========================================================================= */ diff --git a/gl/glthread/lock.h b/gl/glthread/lock.h index d20bbdef..47eed8fe 100644 --- a/gl/glthread/lock.h +++ b/gl/glthread/lock.h @@ -1,22 +1,21 @@ /* Locking in multithreaded situations. - Copyright (C) 2005-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2005. - Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, - gthr-win32.h. */ + Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */ /* This file contains locking primitives for use with a given thread library. It does not contain primitives for creating threads or for other @@ -81,6 +80,127 @@ #include #include +#if !defined c11_threads_in_use +# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC +# define c11_threads_in_use() 1 +# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK +# include +# pragma weak thrd_exit +# define c11_threads_in_use() (thrd_exit != NULL) +# else +# define c11_threads_in_use() 0 +# endif +#endif + +/* ========================================================================= */ + +#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS + +/* Use the ISO C threads library. */ + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/* -------------------------- gl_lock_t datatype -------------------------- */ + +typedef struct + { + int volatile init_needed; + once_flag init_once; + void (*init_func) (void); + mtx_t mutex; + } + gl_lock_t; +# define gl_lock_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_lock_t NAME; +# define gl_lock_define_initialized(STORAGECLASS, NAME) \ + static void _atomic_init_##NAME (void); \ + STORAGECLASS gl_lock_t NAME = \ + { 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \ + static void _atomic_init_##NAME (void) \ + { \ + if (glthread_lock_init (&(NAME))) \ + abort (); \ + } +extern int glthread_lock_init (gl_lock_t *lock); +extern int glthread_lock_lock (gl_lock_t *lock); +extern int glthread_lock_unlock (gl_lock_t *lock); +extern int glthread_lock_destroy (gl_lock_t *lock); + +/* ------------------------- gl_rwlock_t datatype ------------------------- */ + +typedef struct + { + int volatile init_needed; + once_flag init_once; + void (*init_func) (void); + mtx_t lock; /* protects the remaining fields */ + cnd_t waiting_readers; /* waiting readers */ + cnd_t waiting_writers; /* waiting writers */ + unsigned int waiting_writers_count; /* number of waiting writers */ + int runcount; /* number of readers running, or -1 when a writer runs */ + } + gl_rwlock_t; +# define gl_rwlock_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_rwlock_t NAME; +# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ + static void _atomic_init_##NAME (void); \ + STORAGECLASS gl_rwlock_t NAME = \ + { 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \ + static void _atomic_init_##NAME (void) \ + { \ + if (glthread_rwlock_init (&(NAME))) \ + abort (); \ + } +extern int glthread_rwlock_init (gl_rwlock_t *lock); +extern int glthread_rwlock_rdlock (gl_rwlock_t *lock); +extern int glthread_rwlock_wrlock (gl_rwlock_t *lock); +extern int glthread_rwlock_unlock (gl_rwlock_t *lock); +extern int glthread_rwlock_destroy (gl_rwlock_t *lock); + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +typedef struct + { + int volatile init_needed; + once_flag init_once; + void (*init_func) (void); + mtx_t mutex; + } + gl_recursive_lock_t; +# define gl_recursive_lock_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_recursive_lock_t NAME; +# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ + static void _atomic_init_##NAME (void); \ + STORAGECLASS gl_recursive_lock_t NAME = \ + { 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \ + static void _atomic_init_##NAME (void) \ + { \ + if (glthread_recursive_lock_init (&(NAME))) \ + abort (); \ + } +extern int glthread_recursive_lock_init (gl_recursive_lock_t *lock); +extern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock); +extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); +extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef once_flag gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (call_once (ONCE_CONTROL, INITFUNCTION), 0) + +# ifdef __cplusplus +} +# endif + +#endif + /* ========================================================================= */ #if USE_POSIX_THREADS @@ -139,13 +259,25 @@ extern int glthread_in_use (void); # pragma weak pthread_mutexattr_init # pragma weak pthread_mutexattr_settype # pragma weak pthread_mutexattr_destroy +# pragma weak pthread_rwlockattr_init +# if __GNU_LIBRARY__ > 1 +# pragma weak pthread_rwlockattr_setkind_np +# endif +# pragma weak pthread_rwlockattr_destroy # ifndef pthread_self # pragma weak pthread_self # endif # if !PTHREAD_IN_USE_DETECTION_HARD -# pragma weak pthread_cancel -# define pthread_in_use() (pthread_cancel != NULL) + /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols + can be used to determine whether libpthread is in use. These are: + pthread_mutexattr_gettype + pthread_rwlockattr_destroy + pthread_rwlockattr_init + */ +# pragma weak pthread_mutexattr_gettype +# define pthread_in_use() \ + (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) # endif # else @@ -176,19 +308,32 @@ typedef pthread_mutex_t gl_lock_t; /* ------------------------- gl_rwlock_t datatype ------------------------- */ -# if HAVE_PTHREAD_RWLOCK +# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1))) -# ifdef PTHREAD_RWLOCK_INITIALIZER +# if defined PTHREAD_RWLOCK_INITIALIZER || defined PTHREAD_RWLOCK_INITIALIZER_NP typedef pthread_rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS pthread_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer; -# define gl_rwlock_initializer \ - PTHREAD_RWLOCK_INITIALIZER -# define glthread_rwlock_init(LOCK) \ - (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) +# if HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER +# if defined PTHREAD_RWLOCK_INITIALIZER +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_INITIALIZER +# else +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_INITIALIZER_NP +# endif +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) +# else /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */ +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? glthread_rwlock_init_for_glibc (LOCK) : 0) +extern int glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock); +# endif # define glthread_rwlock_rdlock(LOCK) \ (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0) # define glthread_rwlock_wrlock(LOCK) \ @@ -362,248 +507,20 @@ extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *l typedef pthread_once_t gl_once_t; # define gl_once_define(STORAGECLASS, NAME) \ STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ - (pthread_in_use () \ - ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ - : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) -extern int glthread_once_singlethreaded (pthread_once_t *once_control); - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_PTH_THREADS - -/* Use the GNU Pth threads library. */ - -# include - -# ifdef __cplusplus -extern "C" { -# endif - -# if USE_PTH_THREADS_WEAK - -/* Use weak references to the GNU Pth threads library. */ - -# pragma weak pth_mutex_init -# pragma weak pth_mutex_acquire -# pragma weak pth_mutex_release -# pragma weak pth_rwlock_init -# pragma weak pth_rwlock_acquire -# pragma weak pth_rwlock_release -# pragma weak pth_once - -# pragma weak pth_cancel -# define pth_in_use() (pth_cancel != NULL) - +# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (pthread_in_use () \ + ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ + : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) # else - -# define pth_in_use() 1 - +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (pthread_in_use () \ + ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ + : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) +extern int glthread_once_multithreaded (pthread_once_t *once_control, + void (*init_function) (void)); # endif - -/* -------------------------- gl_lock_t datatype -------------------------- */ - -typedef pth_mutex_t gl_lock_t; -# define gl_lock_define(STORAGECLASS, NAME) \ - STORAGECLASS pth_mutex_t NAME; -# define gl_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pth_mutex_t NAME = gl_lock_initializer; -# define gl_lock_initializer \ - PTH_MUTEX_INIT -# define glthread_lock_init(LOCK) \ - (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0) -# define glthread_lock_lock(LOCK) \ - (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0) -# define glthread_lock_unlock(LOCK) \ - (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0) -# define glthread_lock_destroy(LOCK) \ - ((void)(LOCK), 0) - -/* ------------------------- gl_rwlock_t datatype ------------------------- */ - -typedef pth_rwlock_t gl_rwlock_t; -# define gl_rwlock_define(STORAGECLASS, NAME) \ - STORAGECLASS pth_rwlock_t NAME; -# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer; -# define gl_rwlock_initializer \ - PTH_RWLOCK_INIT -# define glthread_rwlock_init(LOCK) \ - (pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0) -# define glthread_rwlock_rdlock(LOCK) \ - (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0) -# define glthread_rwlock_wrlock(LOCK) \ - (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0) -# define glthread_rwlock_unlock(LOCK) \ - (pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0) -# define glthread_rwlock_destroy(LOCK) \ - ((void)(LOCK), 0) - -/* --------------------- gl_recursive_lock_t datatype --------------------- */ - -/* In Pth, mutexes are recursive by default. */ -typedef pth_mutex_t gl_recursive_lock_t; -# define gl_recursive_lock_define(STORAGECLASS, NAME) \ - STORAGECLASS pth_mutex_t NAME; -# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer; -# define gl_recursive_lock_initializer \ - PTH_MUTEX_INIT -# define glthread_recursive_lock_init(LOCK) \ - (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0) -# define glthread_recursive_lock_lock(LOCK) \ - (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0) -# define glthread_recursive_lock_unlock(LOCK) \ - (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0) -# define glthread_recursive_lock_destroy(LOCK) \ - ((void)(LOCK), 0) - -/* -------------------------- gl_once_t datatype -------------------------- */ - -typedef pth_once_t gl_once_t; -# define gl_once_define(STORAGECLASS, NAME) \ - STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ - (pth_in_use () \ - ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ - : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) -extern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void)); -extern int glthread_once_singlethreaded (pth_once_t *once_control); - -# ifdef __cplusplus -} -# endif - -#endif - -/* ========================================================================= */ - -#if USE_SOLARIS_THREADS - -/* Use the old Solaris threads library. */ - -# include -# include - -# ifdef __cplusplus -extern "C" { -# endif - -# if USE_SOLARIS_THREADS_WEAK - -/* Use weak references to the old Solaris threads library. */ - -# pragma weak mutex_init -# pragma weak mutex_lock -# pragma weak mutex_unlock -# pragma weak mutex_destroy -# pragma weak rwlock_init -# pragma weak rw_rdlock -# pragma weak rw_wrlock -# pragma weak rw_unlock -# pragma weak rwlock_destroy -# pragma weak thr_self - -# pragma weak thr_suspend -# define thread_in_use() (thr_suspend != NULL) - -# else - -# define thread_in_use() 1 - -# endif - -/* -------------------------- gl_lock_t datatype -------------------------- */ - -typedef mutex_t gl_lock_t; -# define gl_lock_define(STORAGECLASS, NAME) \ - STORAGECLASS mutex_t NAME; -# define gl_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS mutex_t NAME = gl_lock_initializer; -# define gl_lock_initializer \ - DEFAULTMUTEX -# define glthread_lock_init(LOCK) \ - (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0) -# define glthread_lock_lock(LOCK) \ - (thread_in_use () ? mutex_lock (LOCK) : 0) -# define glthread_lock_unlock(LOCK) \ - (thread_in_use () ? mutex_unlock (LOCK) : 0) -# define glthread_lock_destroy(LOCK) \ - (thread_in_use () ? mutex_destroy (LOCK) : 0) - -/* ------------------------- gl_rwlock_t datatype ------------------------- */ - -typedef rwlock_t gl_rwlock_t; -# define gl_rwlock_define(STORAGECLASS, NAME) \ - STORAGECLASS rwlock_t NAME; -# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS rwlock_t NAME = gl_rwlock_initializer; -# define gl_rwlock_initializer \ - DEFAULTRWLOCK -# define glthread_rwlock_init(LOCK) \ - (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0) -# define glthread_rwlock_rdlock(LOCK) \ - (thread_in_use () ? rw_rdlock (LOCK) : 0) -# define glthread_rwlock_wrlock(LOCK) \ - (thread_in_use () ? rw_wrlock (LOCK) : 0) -# define glthread_rwlock_unlock(LOCK) \ - (thread_in_use () ? rw_unlock (LOCK) : 0) -# define glthread_rwlock_destroy(LOCK) \ - (thread_in_use () ? rwlock_destroy (LOCK) : 0) - -/* --------------------- gl_recursive_lock_t datatype --------------------- */ - -/* Old Solaris threads did not have recursive locks. - We have to implement them ourselves. */ - -typedef struct - { - mutex_t mutex; - thread_t owner; - unsigned long depth; - } - gl_recursive_lock_t; -# define gl_recursive_lock_define(STORAGECLASS, NAME) \ - STORAGECLASS gl_recursive_lock_t NAME; -# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; -# define gl_recursive_lock_initializer \ - { DEFAULTMUTEX, (thread_t) 0, 0 } -# define glthread_recursive_lock_init(LOCK) \ - (thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) -# define glthread_recursive_lock_lock(LOCK) \ - (thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0) -# define glthread_recursive_lock_unlock(LOCK) \ - (thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0) -# define glthread_recursive_lock_destroy(LOCK) \ - (thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0) -extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock); - -/* -------------------------- gl_once_t datatype -------------------------- */ - -typedef struct - { - volatile int inited; - mutex_t mutex; - } - gl_once_t; -# define gl_once_define(STORAGECLASS, NAME) \ - STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX }; -# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ - (thread_in_use () \ - ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ - : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) -extern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void)); -extern int glthread_once_singlethreaded (gl_once_t *once_control); +extern int glthread_once_singlethreaded (pthread_once_t *once_control); # ifdef __cplusplus } @@ -618,6 +535,11 @@ extern int glthread_once_singlethreaded (gl_once_t *once_control); # define WIN32_LEAN_AND_MEAN /* avoid including junk */ # include +# include "windows-mutex.h" +# include "windows-rwlock.h" +# include "windows-recmutex.h" +# include "windows-once.h" + # ifdef __cplusplus extern "C" { # endif @@ -633,127 +555,69 @@ extern "C" { /* There is no way to statically initialize a CRITICAL_SECTION. It needs to be done lazily, once only. For this we need spinlocks. */ -typedef struct { volatile int done; volatile long started; } gl_spinlock_t; - /* -------------------------- gl_lock_t datatype -------------------------- */ -typedef struct - { - gl_spinlock_t guard; /* protects the initialization */ - CRITICAL_SECTION lock; - } - gl_lock_t; +typedef glwthread_mutex_t gl_lock_t; # define gl_lock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_lock_t NAME; # define gl_lock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS gl_lock_t NAME = gl_lock_initializer; # define gl_lock_initializer \ - { { 0, -1 } } + GLWTHREAD_MUTEX_INIT # define glthread_lock_init(LOCK) \ - (glthread_lock_init_func (LOCK), 0) + (glwthread_mutex_init (LOCK), 0) # define glthread_lock_lock(LOCK) \ - glthread_lock_lock_func (LOCK) + glwthread_mutex_lock (LOCK) # define glthread_lock_unlock(LOCK) \ - glthread_lock_unlock_func (LOCK) + glwthread_mutex_unlock (LOCK) # define glthread_lock_destroy(LOCK) \ - glthread_lock_destroy_func (LOCK) -extern void glthread_lock_init_func (gl_lock_t *lock); -extern int glthread_lock_lock_func (gl_lock_t *lock); -extern int glthread_lock_unlock_func (gl_lock_t *lock); -extern int glthread_lock_destroy_func (gl_lock_t *lock); + glwthread_mutex_destroy (LOCK) /* ------------------------- gl_rwlock_t datatype ------------------------- */ -/* It is impossible to implement read-write locks using plain locks, without - introducing an extra thread dedicated to managing read-write locks. - Therefore here we need to use the low-level Event type. */ - -typedef struct - { - HANDLE *array; /* array of waiting threads, each represented by an event */ - unsigned int count; /* number of waiting threads */ - unsigned int alloc; /* length of allocated array */ - unsigned int offset; /* index of first waiting thread in array */ - } - gl_carray_waitqueue_t; -typedef struct - { - gl_spinlock_t guard; /* protects the initialization */ - CRITICAL_SECTION lock; /* protects the remaining fields */ - gl_carray_waitqueue_t waiting_readers; /* waiting readers */ - gl_carray_waitqueue_t waiting_writers; /* waiting writers */ - int runcount; /* number of readers running, or -1 when a writer runs */ - } - gl_rwlock_t; +typedef glwthread_rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; # define gl_rwlock_initializer \ - { { 0, -1 } } + GLWTHREAD_RWLOCK_INIT # define glthread_rwlock_init(LOCK) \ - (glthread_rwlock_init_func (LOCK), 0) + (glwthread_rwlock_init (LOCK), 0) # define glthread_rwlock_rdlock(LOCK) \ - glthread_rwlock_rdlock_func (LOCK) + glwthread_rwlock_rdlock (LOCK) # define glthread_rwlock_wrlock(LOCK) \ - glthread_rwlock_wrlock_func (LOCK) + glwthread_rwlock_wrlock (LOCK) # define glthread_rwlock_unlock(LOCK) \ - glthread_rwlock_unlock_func (LOCK) + glwthread_rwlock_unlock (LOCK) # define glthread_rwlock_destroy(LOCK) \ - glthread_rwlock_destroy_func (LOCK) -extern void glthread_rwlock_init_func (gl_rwlock_t *lock); -extern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock); -extern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock); -extern int glthread_rwlock_unlock_func (gl_rwlock_t *lock); -extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock); + glwthread_rwlock_destroy (LOCK) /* --------------------- gl_recursive_lock_t datatype --------------------- */ -/* The native Windows documentation says that CRITICAL_SECTION already - implements a recursive lock. But we need not rely on it: It's easy to - implement a recursive lock without this assumption. */ - -typedef struct - { - gl_spinlock_t guard; /* protects the initialization */ - DWORD owner; - unsigned long depth; - CRITICAL_SECTION lock; - } - gl_recursive_lock_t; +typedef glwthread_recmutex_t gl_recursive_lock_t; # define gl_recursive_lock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_recursive_lock_t NAME; # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; # define gl_recursive_lock_initializer \ - { { 0, -1 }, 0, 0 } + GLWTHREAD_RECMUTEX_INIT # define glthread_recursive_lock_init(LOCK) \ - (glthread_recursive_lock_init_func (LOCK), 0) + (glwthread_recmutex_init (LOCK), 0) # define glthread_recursive_lock_lock(LOCK) \ - glthread_recursive_lock_lock_func (LOCK) + glwthread_recmutex_lock (LOCK) # define glthread_recursive_lock_unlock(LOCK) \ - glthread_recursive_lock_unlock_func (LOCK) + glwthread_recmutex_unlock (LOCK) # define glthread_recursive_lock_destroy(LOCK) \ - glthread_recursive_lock_destroy_func (LOCK) -extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock); + glwthread_recmutex_destroy (LOCK) /* -------------------------- gl_once_t datatype -------------------------- */ -typedef struct - { - volatile int inited; - volatile long started; - CRITICAL_SECTION lock; - } - gl_once_t; +typedef glwthread_once_t gl_once_t; # define gl_once_define(STORAGECLASS, NAME) \ - STORAGECLASS gl_once_t NAME = { -1, -1 }; + STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ - (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0) -extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void)); + (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) # ifdef __cplusplus } @@ -763,7 +627,7 @@ extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (v /* ========================================================================= */ -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS) +#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) /* Provide dummy implementation if threads are not supported. */ diff --git a/gl/glthread/threadlib.c b/gl/glthread/threadlib.c index b4476573..88a76bad 100644 --- a/gl/glthread/threadlib.c +++ b/gl/glthread/threadlib.c @@ -1,18 +1,18 @@ /* Multithreading primitives. - Copyright (C) 2005-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2005. */ @@ -20,15 +20,48 @@ /* ========================================================================= */ -#if USE_POSIX_THREADS +#if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS /* Use the POSIX threads library. */ +# include # include # include # if PTHREAD_IN_USE_DETECTION_HARD +# if defined __FreeBSD__ || defined __DragonFly__ /* FreeBSD */ + +/* Test using pthread_key_create. */ + +int +glthread_in_use (void) +{ + static int tested; + static int result; /* 1: linked with -lpthread, 0: only with libc */ + + if (!tested) + { + pthread_key_t key; + int err = pthread_key_create (&key, NULL); + + if (err == ENOSYS) + result = 0; + else + { + result = 1; + if (err == 0) + pthread_key_delete (key); + } + tested = 1; + } + return result; +} + +# else /* Solaris, HP-UX */ + +/* Test using pthread_create. */ + /* The function to be executed by a dummy thread. */ static void * dummy_thread_func (void *arg) @@ -62,6 +95,8 @@ glthread_in_use (void) return result; } +# endif + # endif #endif diff --git a/gl/hard-locale.c b/gl/hard-locale.c new file mode 100644 index 00000000..f7fbc470 --- /dev/null +++ b/gl/hard-locale.c @@ -0,0 +1,35 @@ +/* hard-locale.c -- Determine whether a locale is hard. + + Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2022 Free Software + Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#include "hard-locale.h" + +#include +#include + +bool +hard_locale (int category) +{ + char locale[SETLOCALE_NULL_MAX]; + + if (setlocale_null_r (category, locale, sizeof (locale))) + return false; + + return !(strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0); +} diff --git a/gl/hard-locale.h b/gl/hard-locale.h new file mode 100644 index 00000000..6066f4ed --- /dev/null +++ b/gl/hard-locale.h @@ -0,0 +1,28 @@ +/* Determine whether a locale is hard. + + Copyright (C) 1999, 2003-2004, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef HARD_LOCALE_H_ +# define HARD_LOCALE_H_ 1 + +# include + +/* Return true if the specified CATEGORY of the current locale is hard, i.e. + different from the C or POSIX locale that has a fixed behavior. + CATEGORY must be one of the LC_* values, but not LC_ALL. */ +extern bool hard_locale (int category); + +#endif /* HARD_LOCALE_H_ */ diff --git a/gl/ialloc.c b/gl/ialloc.c new file mode 100644 index 00000000..43c10433 --- /dev/null +++ b/gl/ialloc.c @@ -0,0 +1,21 @@ +/* malloc with idx_t rather than size_t + + Copyright 2021-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#define IALLOC_INLINE _GL_EXTERN_INLINE +#include "ialloc.h" diff --git a/gl/ialloc.h b/gl/ialloc.h new file mode 100644 index 00000000..37cf4bfb --- /dev/null +++ b/gl/ialloc.h @@ -0,0 +1,100 @@ +/* ialloc.h -- malloc with idx_t rather than size_t + + Copyright 2021-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef IALLOC_H_ +#define IALLOC_H_ + +#include "idx.h" + +#include +#include +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef IALLOC_INLINE +# define IALLOC_INLINE _GL_INLINE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +IALLOC_INLINE void * _GL_ATTRIBUTE_COLD +_gl_alloc_nomem (void) +{ + errno = ENOMEM; + return NULL; +} + +IALLOC_INLINE +_GL_ATTRIBUTE_MALLOC /*_GL_ATTRIBUTE_DEALLOC_FREE*/ +void * +imalloc (idx_t s) +{ + return s <= SIZE_MAX ? malloc (s) : _gl_alloc_nomem (); +} + +IALLOC_INLINE +/*_GL_ATTRIBUTE_DEALLOC_FREE*/ +void * +irealloc (void *p, idx_t s) +{ + /* Work around GNU realloc glitch by treating a zero size as if it + were 1, so that returning NULL is equivalent to failing. */ + return s <= SIZE_MAX ? realloc (p, s | !s) : _gl_alloc_nomem (); +} + +IALLOC_INLINE +_GL_ATTRIBUTE_MALLOC /*_GL_ATTRIBUTE_DEALLOC_FREE*/ +void * +icalloc (idx_t n, idx_t s) +{ + if (SIZE_MAX < n) + { + if (s != 0) + return _gl_alloc_nomem (); + n = 0; + } + if (SIZE_MAX < s) + { + if (n != 0) + return _gl_alloc_nomem (); + s = 0; + } + return calloc (n, s); +} + +IALLOC_INLINE void * +ireallocarray (void *p, idx_t n, idx_t s) +{ + /* Work around GNU reallocarray glitch by treating a zero size as if + it were 1, so that returning NULL is equivalent to failing. */ + if (n == 0 || s == 0) + n = s = 1; + return (n <= SIZE_MAX && s <= SIZE_MAX + ? reallocarray (p, n, s) + : _gl_alloc_nomem ()); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gl/idpriv-droptemp.c b/gl/idpriv-droptemp.c index 13d1064e..f3272365 100644 --- a/gl/idpriv-droptemp.c +++ b/gl/idpriv-droptemp.c @@ -1,9 +1,9 @@ /* Dropping uid/gid privileges of the current process temporarily. - Copyright (C) 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2009-2022 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 + 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, @@ -12,7 +12,7 @@ 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 . */ + along with this program. If not, see . */ #include @@ -58,7 +58,9 @@ idpriv_temp_drop (void) /* This is for executables that have the setuid bit set. */ # if HAVE_SETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */ - /* See + /* See + Hao Chen, David Wagner, Drew Dean: Setuid Demystified + figure 14. */ if (setresuid (-1, uid, saved_uid) < 0) return -1; @@ -134,7 +136,9 @@ idpriv_temp_restore (void) /* This is for executables that have the setuid bit set. */ # if HAVE_SETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */ - /* See + /* See + Hao Chen, David Wagner, Drew Dean: Setuid Demystified + figure 14. */ if (setresuid (-1, saved_uid, -1) < 0) return -1; diff --git a/gl/idpriv.h b/gl/idpriv.h index f454a2cc..b97d1922 100644 --- a/gl/idpriv.h +++ b/gl/idpriv.h @@ -1,9 +1,9 @@ /* Dropping uid/gid privileges of the current process. - Copyright (C) 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2009-2022 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 + 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, @@ -12,7 +12,7 @@ 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 . */ + along with this program. If not, see . */ #ifndef _IDPRIV_H #define _IDPRIV_H @@ -74,11 +74,11 @@ extern "C" { /* For more in-depth discussion of these topics, see the papers/articles * Hao Chen, David Wagner, Drew Dean: Setuid Demystified - + * Dan Tsafrir, Dilma da Silva, David Wagner: The Murky Issue of Changing Process Identity: Revising "Setuid Demystified" - - + + * Dhruv Mohindra: Observe correct revocation order while relinquishing privileges diff --git a/gl/idx.h b/gl/idx.h new file mode 100644 index 00000000..c3669dda --- /dev/null +++ b/gl/idx.h @@ -0,0 +1,134 @@ +/* A type for indices and sizes. + Copyright (C) 2020-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _IDX_H +#define _IDX_H + +/* Get ptrdiff_t. */ +#include + +/* Get PTRDIFF_MAX. */ +#include + +/* The type 'idx_t' holds an (array) index or an (object) size. + Its implementation promotes to a signed integer type, + which can hold the values + 0..2^63-1 (on 64-bit platforms) or + 0..2^31-1 (on 32-bit platforms). + + Why a signed integer type? + + * Security: Signed types can be checked for overflow via + '-fsanitize=undefined', but unsigned types cannot. + + * Comparisons without surprises: ISO C99 § 6.3.1.8 specifies a few + surprising results for comparisons, such as + + (int) -3 < (unsigned long) 7 => false + (int) -3 < (unsigned int) 7 => false + and on 32-bit machines: + (long) -3 < (unsigned int) 7 => false + + This is surprising because the natural comparison order is by + value in the realm of infinite-precision signed integers (ℤ). + + The best way to get rid of such surprises is to use signed types + for numerical integer values, and use unsigned types only for + bit masks and enums. + + Why not use 'size_t' directly? + + * Because 'size_t' is an unsigned type, and a signed type is better. + See above. + + Why not use 'ssize_t'? + + * 'ptrdiff_t' is more portable; it is standardized by ISO C + whereas 'ssize_t' is standardized only by POSIX. + + * 'ssize_t' is not required to be as wide as 'size_t', and some + now-obsolete POSIX platforms had 'size_t' wider than 'ssize_t'. + + * Conversely, some now-obsolete platforms had 'ptrdiff_t' wider + than 'size_t', which can be a win and conforms to POSIX. + + Won't this cause a problem with objects larger than PTRDIFF_MAX? + + * Typical modern or large platforms do not allocate such objects, + so this is not much of a problem in practice; for example, you + can safely write 'idx_t len = strlen (s);'. To port to older + small platforms where allocations larger than PTRDIFF_MAX could + in theory be a problem, you can use Gnulib's ialloc module, or + functions like ximalloc in Gnulib's xalloc module. + + Why not use 'ptrdiff_t' directly? + + * Maintainability: When reading and modifying code, it helps to know that + a certain variable cannot have negative values. For example, when you + have a loop + + int n = ...; + for (int i = 0; i < n; i++) ... + + or + + ptrdiff_t n = ...; + for (ptrdiff_t i = 0; i < n; i++) ... + + you have to ask yourself "what if n < 0?". Whereas in + + idx_t n = ...; + for (idx_t i = 0; i < n; i++) ... + + you know that this case cannot happen. + + Similarly, when a programmer writes + + idx_t = ptr2 - ptr1; + + there is an implied assertion that ptr1 and ptr2 point into the same + object and that ptr1 <= ptr2. + + * Being future-proof: In the future, range types (integers which are + constrained to a certain range of values) may be added to C compilers + or to the C standard. Several programming languages (Ada, Haskell, + Common Lisp, Pascal) already have range types. Such range types may + help producing good code and good warnings. The type 'idx_t' could + then be typedef'ed to a range type that is signed after promotion. */ + +/* In the future, idx_t could be typedef'ed to a signed range type. + The clang "extended integer types", supported in Clang 11 or newer + , + are a special case of range types. However, these types don't support binary + operators with plain integer types (e.g. expressions such as x > 1). + Therefore, they don't behave like signed types (and not like unsigned types + either). So, we cannot use them here. */ + +/* Use the signed type 'ptrdiff_t'. */ +/* Note: ISO C does not mandate that 'size_t' and 'ptrdiff_t' have the same + size, but it is so on all platforms we have seen since 1990. */ +typedef ptrdiff_t idx_t; + +/* IDX_MAX is the maximum value of an idx_t. */ +#define IDX_MAX PTRDIFF_MAX + +/* So far no need has been found for an IDX_WIDTH macro. + Perhaps there should be another macro IDX_VALUE_BITS that does not + count the sign bit and is therefore one less than PTRDIFF_WIDTH. */ + +#endif /* _IDX_H */ diff --git a/gl/inet_ntop.c b/gl/inet_ntop.c index fdfd21dc..2d401d22 100644 --- a/gl/inet_ntop.c +++ b/gl/inet_ntop.c @@ -1,19 +1,19 @@ /* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form - Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* * Copyright (c) 1996-1999 by Internet Software Consortium. @@ -40,7 +40,7 @@ /* Use this to suppress gcc's "...may be used before initialized" warnings. Beware: The Code argument must not contain commas. */ #ifndef IF_LINT -# ifdef lint +# if defined GCC_LINT || defined lint # define IF_LINT(Code) Code # else # define IF_LINT(Code) /* empty */ diff --git a/gl/intprops-internal.h b/gl/intprops-internal.h new file mode 100644 index 00000000..f6455f78 --- /dev/null +++ b/gl/intprops-internal.h @@ -0,0 +1,392 @@ +/* intprops-internal.h -- properties of integer types not visible to users + + Copyright (C) 2001-2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_INTPROPS_INTERNAL_H +#define _GL_INTPROPS_INTERNAL_H + +#include + +/* Return a value with the common real type of E and V and the value of V. + Do not evaluate E. */ +#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) + +/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see + . */ +#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v)) + +/* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + +/* True if the real type T is signed. */ +#define _GL_TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Return 1 if the real expression E, after promotion, has a + signed or floating type. Do not evaluate E. */ +#define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) + + +/* Minimum and maximum values for integer types and expressions. */ + +/* The width in bits of the integer type or expression T. + Do not evaluate T. T must not be a bit-field expression. + Padding bits are not supported; this is checked at compile-time below. */ +#define _GL_TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) + +/* The maximum and minimum values for the type of the expression E, + after integer promotion. E is not evaluated. */ +#define _GL_INT_MINIMUM(e) \ + (_GL_EXPR_SIGNED (e) \ + ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_CONVERT (e, 0)) +#define _GL_INT_MAXIMUM(e) \ + (_GL_EXPR_SIGNED (e) \ + ? _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_NEGATE_CONVERT (e, 1)) +#define _GL_SIGNED_INT_MAXIMUM(e) \ + (((_GL_INT_CONVERT (e, 1) << (_GL_TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) + +/* Work around OpenVMS incompatibility with C99. */ +#if !defined LLONG_MAX && defined __INT64_MAX +# define LLONG_MAX __INT64_MAX +# define LLONG_MIN __INT64_MIN +#endif + +/* This include file assumes that signed types are two's complement without + padding bits; the above macros have undefined behavior otherwise. + If this is a problem for you, please let us know how to fix it for your host. + This assumption is tested by the intprops-tests module. */ + +/* Does the __typeof__ keyword work? This could be done by + 'configure', but for now it's easier to do it by hand. */ +#if (2 <= __GNUC__ \ + || (4 <= __clang_major__) \ + || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ + || (0x5110 <= __SUNPRO_C && !__STDC__)) +# define _GL_HAVE___TYPEOF__ 1 +#else +# define _GL_HAVE___TYPEOF__ 0 +#endif + +/* Return 1 if the integer type or expression T might be signed. Return 0 + if it is definitely unsigned. T must not be a bit-field expression. + This macro does not evaluate its argument, and expands to an + integer constant expression. */ +#if _GL_HAVE___TYPEOF__ +# define _GL_SIGNED_TYPE_OR_EXPR(t) _GL_TYPE_SIGNED (__typeof__ (t)) +#else +# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 +#endif + +/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. + A should not have side effects, and A's type should be an + integer with minimum value MIN and maximum MAX. */ +#define _GL_INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ + ((min) < 0 ? (a) < - (max) : 0 < (a)) + +/* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow + (A, B, P) work when P is non-null. */ +#ifdef __EDG__ +/* EDG-based compilers like nvc 22.1 cannot add 64-bit signed to unsigned + . */ +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0 +#elif defined __has_builtin +# define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow) +/* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x, + see . */ +#elif 7 <= __GNUC__ +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 1 +#else +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0 +#endif + +/* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */ +#if defined __clang_major__ && __clang_major__ < 14 +/* Work around Clang bug . */ +# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0 +#else +# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW +#endif + +/* True if __builtin_add_overflow_p (A, B, C) works, and similarly for + __builtin_sub_overflow_p and __builtin_mul_overflow_p. */ +#ifdef __EDG__ +/* In EDG-based compilers like ICC 2021.3 and earlier, + __builtin_add_overflow_p etc. are not treated as integral constant + expressions even when all arguments are. */ +# define _GL_HAS_BUILTIN_OVERFLOW_P 0 +#elif defined __has_builtin +# define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p) +#else +# define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) +#endif + +#if (!defined _GL_STDCKDINT_H && 202311 <= __STDC_VERSION__ \ + && ! (_GL_HAS_BUILTIN_ADD_OVERFLOW && _GL_HAS_BUILTIN_MUL_OVERFLOW)) +# include +#endif + +/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. + Return 1 if the result overflows. Arguments should not have side + effects and A, B and *R can be of any integer type other than char, + bool, a bit-precise integer type, or an enumeration type. */ +#if _GL_HAS_BUILTIN_ADD_OVERFLOW +# define _GL_INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r) +# define _GL_INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r) +#elif defined ckd_add && defined ckd_sub && !defined _GL_STDCKDINT_H +# define _GL_INT_ADD_WRAPV(a, b, r) ckd_add (r, + (a), + (b)) +# define _GL_INT_SUBTRACT_WRAPV(a, b, r) ckd_sub (r, + (a), + (b)) +#else +# define _GL_INT_ADD_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW) +# define _GL_INT_SUBTRACT_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW) +#endif +#if _GL_HAS_BUILTIN_MUL_OVERFLOW +# if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \ + || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \ + && !defined __EDG__) +# define _GL_INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r) +# else + /* Work around GCC bug 91450. */ +# define _GL_INT_MULTIPLY_WRAPV(a, b, r) \ + ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && _GL_EXPR_SIGNED (a) && _GL_EXPR_SIGNED (b) \ + && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \ + ? ((void) __builtin_mul_overflow (a, b, r), 1) \ + : __builtin_mul_overflow (a, b, r)) +# endif +#elif defined ckd_mul && !defined _GL_STDCKDINT_H +# define _GL_INT_MULTIPLY_WRAPV(a, b, r) ckd_mul (r, + (a), + (b)) +#else +# define _GL_INT_MULTIPLY_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW) +#endif + +/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 + https://llvm.org/bugs/show_bug.cgi?id=25390 + For now, assume all versions of GCC-like compilers generate bogus + warnings for _Generic. This matters only for compilers that + lack relevant builtins. */ +#if __GNUC__ || defined __clang__ +# define _GL__GENERIC_BOGUS 1 +#else +# define _GL__GENERIC_BOGUS 0 +#endif + +/* Store the low-order bits of A B into *R, where OP specifies + the operation and OVERFLOW the overflow predicate. Return 1 if the + result overflows. Arguments should not have side effects, + and A, B and *R can be of any integer type other than char, bool, a + bit-precise integer type, or an enumeration type. */ +#if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS +# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \ + (_Generic \ + (*(r), \ + signed char: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + signed char, SCHAR_MIN, SCHAR_MAX), \ + unsigned char: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + unsigned char, 0, UCHAR_MAX), \ + short int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + short int, SHRT_MIN, SHRT_MAX), \ + unsigned short int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + unsigned short int, 0, USHRT_MAX), \ + int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + int, INT_MIN, INT_MAX), \ + unsigned int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + unsigned int, 0, UINT_MAX), \ + long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX), \ + unsigned long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + unsigned long int, 0, ULONG_MAX), \ + long long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + long long int, LLONG_MIN, LLONG_MAX), \ + unsigned long long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + unsigned long long int, 0, ULLONG_MAX))) +#else +/* Store the low-order bits of A B into *R, where OP specifies + the operation and OVERFLOW the overflow predicate. If *R is + signed, its type is ST with bounds SMIN..SMAX; otherwise its type + is UT with bounds U..UMAX. ST and UT are narrower than int. + Return 1 if the result overflows. Arguments should not have side + effects, and A, B and *R can be of any integer type other than + char, bool, a bit-precise integer type, or an enumeration type. */ +# if _GL_HAVE___TYPEOF__ +# define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \ + (_GL_TYPE_SIGNED (__typeof__ (*(r))) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, st, smin, smax) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, ut, 0, umax)) +# else +# define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \ + (overflow (a, b, smin, smax) \ + ? (overflow (a, b, 0, umax) \ + ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 1) \ + : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) < 0) \ + : (overflow (a, b, 0, umax) \ + ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) >= 0 \ + : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0))) +# endif + +# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \ + (sizeof *(r) == sizeof (signed char) \ + ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \ + signed char, SCHAR_MIN, SCHAR_MAX, \ + unsigned char, UCHAR_MAX) \ + : sizeof *(r) == sizeof (short int) \ + ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \ + short int, SHRT_MIN, SHRT_MAX, \ + unsigned short int, USHRT_MAX) \ + : sizeof *(r) == sizeof (int) \ + ? (_GL_EXPR_SIGNED (*(r)) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + int, INT_MIN, INT_MAX) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + unsigned int, 0, UINT_MAX)) \ + : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow)) +# ifdef LLONG_MAX +# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ + (sizeof *(r) == sizeof (long int) \ + ? (_GL_EXPR_SIGNED (*(r)) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + unsigned long int, 0, ULONG_MAX)) \ + : (_GL_EXPR_SIGNED (*(r)) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + long long int, LLONG_MIN, LLONG_MAX) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + unsigned long long int, 0, ULLONG_MAX))) +# else +# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ + (_GL_EXPR_SIGNED (*(r)) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + unsigned long int, 0, ULONG_MAX)) +# endif +#endif + +/* Store the low-order bits of A B into *R, where the operation + is given by OP. Use the unsigned type UT for calculation to avoid + overflow problems. *R's type is T, with extrema TMIN and TMAX. + T can be any signed integer type other than char, bool, a + bit-precise integer type, or an enumeration type. + Return 1 if the result overflows. */ +#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \ + (overflow (a, b, tmin, tmax) \ + ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \ + : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0)) + +/* Return 1 if the integer expressions A - B and -A would overflow, + respectively. Arguments should not have side effects, + and can be any signed integer type other than char, bool, a + bit-precise integer type, or an enumeration type. + These macros are tuned for their last input argument being a constant. */ + +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define _GL_INT_NEGATE_OVERFLOW(a) \ + __builtin_sub_overflow_p (0, a, (__typeof__ (- (a))) 0) +#else +# define _GL_INT_NEGATE_OVERFLOW(a) \ + _GL_INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +#endif + +/* Return the low-order bits of A B, where the operation is given + by OP. Use the unsigned type UT for calculation to avoid undefined + behavior on signed integer overflow, and convert the result to type T. + UT is at least as wide as T and is no narrower than unsigned int, + T is two's complement, and there is no padding or trap representations. + Assume that converting UT to T yields the low-order bits, as is + done in all known two's-complement C compilers. E.g., see: + https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html + + According to the C standard, converting UT to T yields an + implementation-defined result or signal for values outside T's + range. However, code that works around this theoretical problem + runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: + https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html + As the compiler bug is real, don't try to work around the + theoretical problem. */ + +#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \ + ((t) ((ut) (a) op (ut) (b))) + +/* Return true if the numeric values A + B, A - B, A * B fall outside + the range TMIN..TMAX. Arguments should not have side effects + and can be any integer type other than char, bool, + a bit-precise integer type, or an enumeration type. + TMIN should be signed and nonpositive. + TMAX should be positive, and should be signed unless TMIN is zero. */ +#define _GL_INT_ADD_RANGE_OVERFLOW(a, b, tmin, tmax) \ + ((b) < 0 \ + ? (((tmin) \ + ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \ + && (a) < (tmin) - (b)) \ + : (a) <= -1 - (b)) \ + || ((_GL_EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \ + : (a) < 0 \ + ? (((tmin) \ + ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \ + && (b) < (tmin) - (a)) \ + : (b) <= -1 - (a)) \ + || ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, b)) || (tmax) < (b)) \ + && (tmax) < (a) + (b))) \ + : (tmax) < (b) || (tmax) - (b) < (a)) +#define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \ + (((a) < 0) == ((b) < 0) \ + ? ((a) < (b) \ + ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \ + : (tmax) < (a) - (b)) \ + : (a) < 0 \ + ? ((!_GL_EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \ + || (a) - (tmin) < (b)) \ + : ((! (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \ + && _GL_EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \ + && (tmax) <= -1 - (b)) \ + || (tmax) + (b) < (a))) +#define _GL_INT_MULTIPLY_RANGE_OVERFLOW(a, b, tmin, tmax) \ + ((b) < 0 \ + ? ((a) < 0 \ + ? (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \ + ? (a) < (tmax) / (b) \ + : ((_GL_INT_NEGATE_OVERFLOW (b) \ + ? _GL_INT_CONVERT (b, tmax) >> (_GL_TYPE_WIDTH (+ (b)) - 1) \ + : (tmax) / -(b)) \ + <= -1 - (a))) \ + : _GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \ + ? (_GL_EXPR_SIGNED (a) \ + ? 0 < (a) + (tmin) \ + : 0 < (a) && -1 - (tmin) < (a) - 1) \ + : (tmin) / (b) < (a)) \ + : (b) == 0 \ + ? 0 \ + : ((a) < 0 \ + ? (_GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \ + ? (_GL_EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \ + : (tmin) / (a) < (b)) \ + : (tmax) / (b) < (a))) + +#endif /* _GL_INTPROPS_INTERNAL_H */ diff --git a/gl/intprops.h b/gl/intprops.h index f57f9b4d..f182ddc1 100644 --- a/gl/intprops.h +++ b/gl/intprops.h @@ -1,34 +1,24 @@ /* intprops.h -- properties of integer types - Copyright (C) 2001-2005, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2001-2022 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 + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 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. + GNU Lesser 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 . */ - -/* Written by Paul Eggert. */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _GL_INTPROPS_H #define _GL_INTPROPS_H -#include - -/* Return an integer value, converted to the same type as the integer - expression E after integer type promotion. V is the unconverted value. */ -#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) - -/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see - . */ -#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) +#include "intprops-internal.h" /* The extra casts in the following macros work around compiler bugs, e.g., in Cray C 5.0.3.0. */ @@ -37,72 +27,27 @@ an integer. */ #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) -/* True if negative values of the signed integer type T use two's - complement, ones' complement, or signed magnitude representation, - respectively. Much GNU code assumes two's complement, but some - people like to be portable to all possible C hosts. */ -#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) -#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) -#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) +/* True if the real type T is signed. */ +#define TYPE_SIGNED(t) _GL_TYPE_SIGNED (t) -/* True if the signed integer expression E uses two's complement. */ -#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1) +/* Return 1 if the real expression E, after promotion, has a + signed or floating type. Do not evaluate E. */ +#define EXPR_SIGNED(e) _GL_EXPR_SIGNED (e) -/* True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) -/* Return 1 if the integer expression E, after integer promotion, has - a signed type. */ -#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) +/* Minimum and maximum values for integer types and expressions. */ - -/* Minimum and maximum values for integer types and expressions. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ +/* The width in bits of the integer type or expression T. + Do not evaluate T. T must not be a bit-field expression. + Padding bits are not supported; this is checked at compile-time below. */ +#define TYPE_WIDTH(t) _GL_TYPE_WIDTH (t) /* The maximum and minimum values for the integer type T. */ -#define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : TYPE_SIGNED_MAGNITUDE (t) \ - ? ~ (t) 0 \ - : ~ TYPE_MAXIMUM (t))) +#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) #define TYPE_MAXIMUM(t) \ ((t) (! TYPE_SIGNED (t) \ ? (t) -1 \ - : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) - -/* The maximum and minimum values for the type of the expression E, - after integer promotion. E should not have side effects. */ -#define _GL_INT_MINIMUM(e) \ - (_GL_INT_SIGNED (e) \ - ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_CONVERT (e, 0)) -#define _GL_INT_MAXIMUM(e) \ - (_GL_INT_SIGNED (e) \ - ? _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_NEGATE_CONVERT (e, 1)) -#define _GL_SIGNED_INT_MAXIMUM(e) \ - (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1) - - -/* Return 1 if the __typeof__ keyword works. This could be done by - 'configure', but for now it's easier to do it by hand. */ -#if 2 <= __GNUC__ || defined __IBM__TYPEOF__ || 0x5110 <= __SUNPRO_C -# define _GL_HAVE___TYPEOF__ 1 -#else -# define _GL_HAVE___TYPEOF__ 0 -#endif - -/* Return 1 if the integer type or expression T might be signed. Return 0 - if it is definitely unsigned. This macro does not evaluate its argument, - and expands to an integer constant expression. */ -#if _GL_HAVE___TYPEOF__ -# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) -#else -# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 -#endif + : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) /* Bound on length of the string representing an unsigned integer value representable in B bits. log10 (2.0) < 146/485. The @@ -110,30 +55,31 @@ #define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) /* Bound on length of the string representing an integer type or expression T. + T must not be a bit-field expression. + Subtract 1 for the sign bit if T is signed, and then add 1 more for a minus sign if needed. - Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is - signed, this macro may overestimate the true bound by one byte when + Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 1 when its argument is + unsigned, this macro may overestimate the true bound by one byte when applied to unsigned types of size 2, 4, 16, ... bytes. */ #define INT_STRLEN_BOUND(t) \ - (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT \ - - _GL_SIGNED_TYPE_OR_EXPR (t)) \ + (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \ + _GL_SIGNED_TYPE_OR_EXPR (t)) /* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ + including the terminating null. T must not be a bit-field expression. */ #define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) /* Range overflow checks. The INT__RANGE_OVERFLOW macros return 1 if the corresponding C - operators might not yield numerically correct answers due to - arithmetic overflow. They do not rely on undefined or - implementation-defined behavior. Their implementations are simple - and straightforward, but they are a bit harder to use than the - INT__OVERFLOW macros described below. + operators overflow arithmetically when given the same arguments. + These macros do not rely on undefined or implementation-defined behavior. + Although their implementations are simple and straightforward, + they are harder to use and may be less efficient than the + INT__WRAPV, INT__OK, and INT__OVERFLOW macros described below. Example usage: @@ -157,6 +103,9 @@ must have minimum value MIN and maximum MAX. Unsigned types should use a zero MIN of the proper type. + Because all arguments are subject to integer promotions, these + macros typically do not work on types narrower than 'int'. + These macros are tuned for constant MIN and MAX. For commutative operations such as A + B, they are also tuned for constant B. */ @@ -177,14 +126,12 @@ /* Return 1 if - A would overflow in [MIN,MAX] arithmetic. See above for restrictions. */ #define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ - ((min) < 0 \ - ? (a) < - (max) \ - : 0 < (a)) + _GL_INT_NEGATE_RANGE_OVERFLOW (a, min, max) /* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. See above for restrictions. Avoid && and || as they tickle bugs in Sun C 5.11 2010/08/13 and other compilers; see - . */ + . */ #define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ ((b) < 0 \ ? ((a) < 0 \ @@ -223,24 +170,32 @@ ? (a) < (min) >> (b) \ : (max) >> (b) < (a)) - /* The _GL*_OVERFLOW macros have the same restrictions as the *_RANGE_OVERFLOW macros, except that they do not assume that operands (e.g., A and B) have the same type as MIN and MAX. Instead, they assume that the result (e.g., A + B) has that type. */ -#define _GL_ADD_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ - : (a) < 0 ? (b) <= (a) + (b) \ - : (b) < 0 ? (a) <= (a) + (b) \ - : (a) + (b) < (b)) -#define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ - : (a) < 0 ? 1 \ - : (b) < 0 ? (a) - (b) <= (a) \ - : (a) < (b)) -#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ - (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ - || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define _GL_ADD_OVERFLOW(a, b, min, max) \ + __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0) +# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0) +# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0) +#else +# define _GL_ADD_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? (b) <= (a) + (b) \ + : (b) < 0 ? (a) <= (a) + (b) \ + : (a) + (b) < (b)) +# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? 1 \ + : (b) < 0 ? (a) - (b) <= (a) \ + : (a) < (b)) +# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ + || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) +#endif #define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ : (a) < 0 ? (b) <= (a) + (b) - 1 \ @@ -262,22 +217,31 @@ : (a) % - (b)) \ == 0) - -/* Integer overflow checks. +/* Check for integer overflow, and report low order bits of answer. The INT__OVERFLOW macros return 1 if the corresponding C operators might not yield numerically correct answers due to arithmetic overflow. - They work correctly on all known practical hosts, and do not rely + The INT__WRAPV macros compute the low-order bits of the sum, + difference, and product of two C integers, and return 1 if these + low-order bits are not numerically correct. + These macros work correctly on all known practical hosts, and do not rely on undefined behavior due to signed arithmetic overflow. - Example usage: + Example usage, assuming A and B are long int: - long int i = ...; - long int j = ...; - if (INT_MULTIPLY_OVERFLOW (i, j)) - printf ("multiply would overflow"); + if (INT_MULTIPLY_OVERFLOW (a, b)) + printf ("result would overflow\n"); else - printf ("product is %ld", i * j); + printf ("result is %ld (no overflow)\n", a * b); + + Example usage with WRAPV flavor: + + long int result; + bool overflow = INT_MULTIPLY_WRAPV (a, b, &result); + printf ("result is %ld (%s)\n", result, + overflow ? "after overflow" : "no overflow"); + + Restrictions on these macros: These macros do not check for all possible numerical problems or undefined or unspecified behavior: they do not check for division @@ -286,7 +250,23 @@ These macros may evaluate their arguments zero or multiple times, so the arguments should not have side effects. - These macros are tuned for their last argument being a constant. + The WRAPV macros are not constant expressions. They support only + +, binary -, and *. + + Because the WRAPV macros convert the result, they report overflow + in different circumstances than the OVERFLOW macros do. For + example, in the typical case with 16-bit 'short' and 32-bit 'int', + if A, B and *R are all of type 'short' then INT_ADD_OVERFLOW (A, B) + returns false because the addition cannot overflow after A and B + are converted to 'int', whereas INT_ADD_WRAPV (A, B, R) returns + true or false depending on whether the sum fits into 'short'. + + These macros are tuned for their last input argument being a constant. + + A, B, and *R should be integers; they need not be the same type, + and they need not be all signed or all unsigned. + However, none of the integer types should be bit-precise, + and *R's type should not be char, bool, or an enumeration type. Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, A % B, and A << B would overflow, respectively. */ @@ -295,8 +275,7 @@ _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) #define INT_SUBTRACT_OVERFLOW(a, b) \ _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) -#define INT_NEGATE_OVERFLOW(a) \ - INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +#define INT_NEGATE_OVERFLOW(a) _GL_INT_NEGATE_OVERFLOW (a) #define INT_MULTIPLY_OVERFLOW(a, b) \ _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) #define INT_DIVIDE_OVERFLOW(a, b) \ @@ -313,7 +292,44 @@ Arguments should be free of side effects. */ #define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ op_result_overflow (a, b, \ - _GL_INT_MINIMUM (0 * (b) + (a)), \ - _GL_INT_MAXIMUM (0 * (b) + (a))) + _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \ + _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b))) + +/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. + Return 1 if the result overflows. See above for restrictions. */ +#define INT_ADD_WRAPV(a, b, r) _GL_INT_ADD_WRAPV (a, b, r) +#define INT_SUBTRACT_WRAPV(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r) +#define INT_MULTIPLY_WRAPV(a, b, r) _GL_INT_MULTIPLY_WRAPV (a, b, r) + +/* The following macros compute A + B, A - B, and A * B, respectively. + If no overflow occurs, they set *R to the result and return 1; + otherwise, they return 0 and may modify *R. + + Example usage: + + long int result; + if (INT_ADD_OK (a, b, &result)) + printf ("result is %ld\n", result); + else + printf ("overflow\n"); + + A, B, and *R should be integers; they need not be the same type, + and they need not be all signed or all unsigned. + However, none of the integer types should be bit-precise, + and *R's type should not be char, bool, or an enumeration type. + + These macros work correctly on all known practical hosts, and do not rely + on undefined behavior due to signed arithmetic overflow. + + These macros are not constant expressions. + + These macros may evaluate their arguments zero or multiple times, so the + arguments should not have side effects. + + These macros are tuned for B being a constant. */ + +#define INT_ADD_OK(a, b, r) (! INT_ADD_WRAPV (a, b, r)) +#define INT_SUBTRACT_OK(a, b, r) (! INT_SUBTRACT_WRAPV (a, b, r)) +#define INT_MULTIPLY_OK(a, b, r) (! INT_MULTIPLY_WRAPV (a, b, r)) #endif /* _GL_INTPROPS_H */ diff --git a/gl/inttypes.in.h b/gl/inttypes.in.h new file mode 100644 index 00000000..853eca08 --- /dev/null +++ b/gl/inttypes.in.h @@ -0,0 +1,1002 @@ +/* Copyright (C) 2006-2022 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Derek Price. + This file is part of gnulib. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* + * ISO C 99 for platforms that lack it. + * + */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* Include the original if it exists, and if this file + has not been included yet or if this file includes gnulib stdint.h + which in turn includes this file. + The include_next requires a split double-inclusion guard. */ +#if ! defined INTTYPES_H || defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +# if @HAVE_INTTYPES_H@ + + /* Some pre-C++11 implementations need this. */ +# if defined __cplusplus && ! defined __STDC_FORMAT_MACROS +# define __STDC_FORMAT_MACROS 1 +# endif + +# @INCLUDE_NEXT@ @NEXT_INTTYPES_H@ + +# define _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H +# endif +#endif + +#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +#define INTTYPES_H + +/* Include or the gnulib replacement. + But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include +#endif +/* Get CHAR_BIT, INT_MAX, LONG_MAX, etc. */ +#include +/* On mingw, __USE_MINGW_ANSI_STDIO only works if is also included */ +#if defined _WIN32 && ! defined __CYGWIN__ +# include +#endif + +#if !(INT_MAX == 0x7fffffff && INT_MIN + INT_MAX == -1) +# error "This file assumes that 'int' is 32-bit two's complement. Please report your platform and compiler to ." +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* 7.8.1 Macros for format specifiers */ + +#if defined _TNS_R_TARGET + /* Tandem NonStop R series and compatible platforms released before + July 2005 support %Ld but not %lld. */ +# define _LONG_LONG_FORMAT_PREFIX "L" +#else +# define _LONG_LONG_FORMAT_PREFIX "ll" +#endif + +#if !defined PRId8 +# ifdef INT8_MAX +# define PRId8 "d" +# endif +#endif +#if !defined PRIi8 +# ifdef INT8_MAX +# define PRIi8 "i" +# endif +#endif +#if !defined PRIo8 +# ifdef UINT8_MAX +# define PRIo8 "o" +# endif +#endif +#if !defined PRIu8 +# ifdef UINT8_MAX +# define PRIu8 "u" +# endif +#endif +#if !defined PRIx8 +# ifdef UINT8_MAX +# define PRIx8 "x" +# endif +#endif +#if !defined PRIX8 +# ifdef UINT8_MAX +# define PRIX8 "X" +# endif +#endif +#if !defined PRId16 +# ifdef INT16_MAX +# define PRId16 "d" +# endif +#endif +#if !defined PRIi16 +# ifdef INT16_MAX +# define PRIi16 "i" +# endif +#endif +#if !defined PRIo16 +# ifdef UINT16_MAX +# define PRIo16 "o" +# endif +#endif +#if !defined PRIu16 +# ifdef UINT16_MAX +# define PRIu16 "u" +# endif +#endif +#if !defined PRIx16 +# ifdef UINT16_MAX +# define PRIx16 "x" +# endif +#endif +#if !defined PRIX16 +# ifdef UINT16_MAX +# define PRIX16 "X" +# endif +#endif +#if !defined PRId32 +# ifdef INT32_MAX +# define PRId32 "d" +# endif +#endif +#if !defined PRIi32 +# ifdef INT32_MAX +# define PRIi32 "i" +# endif +#endif +#if !defined PRIo32 +# ifdef UINT32_MAX +# define PRIo32 "o" +# endif +#endif +#if !defined PRIu32 +# ifdef UINT32_MAX +# define PRIu32 "u" +# endif +#endif +#if !defined PRIx32 +# ifdef UINT32_MAX +# define PRIx32 "x" +# endif +#endif +#if !defined PRIX32 +# ifdef UINT32_MAX +# define PRIX32 "X" +# endif +#endif +#ifdef INT64_MAX +# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@) +# define _PRI64_PREFIX "l" +# elif defined _MSC_VER || defined __MINGW32__ +# define _PRI64_PREFIX "I64" +# elif LONG_MAX >> 30 == 1 +# define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined PRId64 +# define PRId64 _PRI64_PREFIX "d" +# endif +# if !defined PRIi64 +# define PRIi64 _PRI64_PREFIX "i" +# endif +#endif +#ifdef UINT64_MAX +# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@) +# define _PRIu64_PREFIX "l" +# elif defined _MSC_VER || defined __MINGW32__ +# define _PRIu64_PREFIX "I64" +# elif ULONG_MAX >> 31 == 1 +# define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined PRIo64 +# define PRIo64 _PRIu64_PREFIX "o" +# endif +# if !defined PRIu64 +# define PRIu64 _PRIu64_PREFIX "u" +# endif +# if !defined PRIx64 +# define PRIx64 _PRIu64_PREFIX "x" +# endif +# if !defined PRIX64 +# define PRIX64 _PRIu64_PREFIX "X" +# endif +#endif + +#if !defined PRIdLEAST8 +# define PRIdLEAST8 "d" +#endif +#if !defined PRIiLEAST8 +# define PRIiLEAST8 "i" +#endif +#if !defined PRIoLEAST8 +# define PRIoLEAST8 "o" +#endif +#if !defined PRIuLEAST8 +# define PRIuLEAST8 "u" +#endif +#if !defined PRIxLEAST8 +# define PRIxLEAST8 "x" +#endif +#if !defined PRIXLEAST8 +# define PRIXLEAST8 "X" +#endif +#if !defined PRIdLEAST16 +# define PRIdLEAST16 "d" +#endif +#if !defined PRIiLEAST16 +# define PRIiLEAST16 "i" +#endif +#if !defined PRIoLEAST16 +# define PRIoLEAST16 "o" +#endif +#if !defined PRIuLEAST16 +# define PRIuLEAST16 "u" +#endif +#if !defined PRIxLEAST16 +# define PRIxLEAST16 "x" +#endif +#if !defined PRIXLEAST16 +# define PRIXLEAST16 "X" +#endif +#if !defined PRIdLEAST32 +# define PRIdLEAST32 "d" +#endif +#if !defined PRIiLEAST32 +# define PRIiLEAST32 "i" +#endif +#if !defined PRIoLEAST32 +# define PRIoLEAST32 "o" +#endif +#if !defined PRIuLEAST32 +# define PRIuLEAST32 "u" +#endif +#if !defined PRIxLEAST32 +# define PRIxLEAST32 "x" +#endif +#if !defined PRIXLEAST32 +# define PRIXLEAST32 "X" +#endif +#ifdef INT64_MAX +# if !defined PRIdLEAST64 +# define PRIdLEAST64 PRId64 +# endif +# if !defined PRIiLEAST64 +# define PRIiLEAST64 PRIi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined PRIoLEAST64 +# define PRIoLEAST64 PRIo64 +# endif +# if !defined PRIuLEAST64 +# define PRIuLEAST64 PRIu64 +# endif +# if !defined PRIxLEAST64 +# define PRIxLEAST64 PRIx64 +# endif +# if !defined PRIXLEAST64 +# define PRIXLEAST64 PRIX64 +# endif +#endif + +#if !defined PRIdFAST8 +# if INT_FAST8_MAX > INT32_MAX +# define PRIdFAST8 PRId64 +# else +# define PRIdFAST8 "d" +# endif +#endif +#if !defined PRIiFAST8 +# if INT_FAST8_MAX > INT32_MAX +# define PRIiFAST8 PRIi64 +# else +# define PRIiFAST8 "i" +# endif +#endif +#if !defined PRIoFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIoFAST8 PRIo64 +# else +# define PRIoFAST8 "o" +# endif +#endif +#if !defined PRIuFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIuFAST8 PRIu64 +# else +# define PRIuFAST8 "u" +# endif +#endif +#if !defined PRIxFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIxFAST8 PRIx64 +# else +# define PRIxFAST8 "x" +# endif +#endif +#if !defined PRIXFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define PRIXFAST8 PRIX64 +# else +# define PRIXFAST8 "X" +# endif +#endif +#if !defined PRIdFAST16 +# if INT_FAST16_MAX > INT32_MAX +# define PRIdFAST16 PRId64 +# else +# define PRIdFAST16 "d" +# endif +#endif +#if !defined PRIiFAST16 +# if INT_FAST16_MAX > INT32_MAX +# define PRIiFAST16 PRIi64 +# else +# define PRIiFAST16 "i" +# endif +#endif +#if !defined PRIoFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIoFAST16 PRIo64 +# else +# define PRIoFAST16 "o" +# endif +#endif +#if !defined PRIuFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIuFAST16 PRIu64 +# else +# define PRIuFAST16 "u" +# endif +#endif +#if !defined PRIxFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIxFAST16 PRIx64 +# else +# define PRIxFAST16 "x" +# endif +#endif +#if !defined PRIXFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define PRIXFAST16 PRIX64 +# else +# define PRIXFAST16 "X" +# endif +#endif +#if !defined PRIdFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define PRIdFAST32 PRId64 +# else +# define PRIdFAST32 "d" +# endif +#endif +#if !defined PRIiFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define PRIiFAST32 PRIi64 +# else +# define PRIiFAST32 "i" +# endif +#endif +#if !defined PRIoFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIoFAST32 PRIo64 +# else +# define PRIoFAST32 "o" +# endif +#endif +#if !defined PRIuFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIuFAST32 PRIu64 +# else +# define PRIuFAST32 "u" +# endif +#endif +#if !defined PRIxFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIxFAST32 PRIx64 +# else +# define PRIxFAST32 "x" +# endif +#endif +#if !defined PRIXFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define PRIXFAST32 PRIX64 +# else +# define PRIXFAST32 "X" +# endif +#endif +#ifdef INT64_MAX +# if !defined PRIdFAST64 +# define PRIdFAST64 PRId64 +# endif +# if !defined PRIiFAST64 +# define PRIiFAST64 PRIi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined PRIoFAST64 +# define PRIoFAST64 PRIo64 +# endif +# if !defined PRIuFAST64 +# define PRIuFAST64 PRIu64 +# endif +# if !defined PRIxFAST64 +# define PRIxFAST64 PRIx64 +# endif +# if !defined PRIXFAST64 +# define PRIXFAST64 PRIX64 +# endif +#endif + +#if !defined PRIdMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define PRIdMAX PRId64 +# else +# define PRIdMAX "ld" +# endif +#endif +#if !defined PRIiMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define PRIiMAX PRIi64 +# else +# define PRIiMAX "li" +# endif +#endif +#if !defined PRIoMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIoMAX PRIo64 +# else +# define PRIoMAX "lo" +# endif +#endif +#if !defined PRIuMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIuMAX PRIu64 +# else +# define PRIuMAX "lu" +# endif +#endif +#if !defined PRIxMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIxMAX PRIx64 +# else +# define PRIxMAX "lx" +# endif +#endif +#if !defined PRIXMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define PRIXMAX PRIX64 +# else +# define PRIXMAX "lX" +# endif +#endif + +#if !defined PRIdPTR +# ifdef INTPTR_MAX +# define PRIdPTR @PRIPTR_PREFIX@ "d" +# endif +#endif +#if !defined PRIiPTR +# ifdef INTPTR_MAX +# define PRIiPTR @PRIPTR_PREFIX@ "i" +# endif +#endif +#if !defined PRIoPTR +# ifdef UINTPTR_MAX +# define PRIoPTR @PRIPTR_PREFIX@ "o" +# endif +#endif +#if !defined PRIuPTR +# ifdef UINTPTR_MAX +# define PRIuPTR @PRIPTR_PREFIX@ "u" +# endif +#endif +#if !defined PRIxPTR +# ifdef UINTPTR_MAX +# define PRIxPTR @PRIPTR_PREFIX@ "x" +# endif +#endif +#if !defined PRIXPTR +# ifdef UINTPTR_MAX +# define PRIXPTR @PRIPTR_PREFIX@ "X" +# endif +#endif + +#if !defined SCNd8 +# ifdef INT8_MAX +# define SCNd8 "hhd" +# endif +#endif +#if !defined SCNi8 +# ifdef INT8_MAX +# define SCNi8 "hhi" +# endif +#endif +#if !defined SCNo8 +# ifdef UINT8_MAX +# define SCNo8 "hho" +# endif +#endif +#if !defined SCNu8 +# ifdef UINT8_MAX +# define SCNu8 "hhu" +# endif +#endif +#if !defined SCNx8 +# ifdef UINT8_MAX +# define SCNx8 "hhx" +# endif +#endif +#if !defined SCNd16 +# ifdef INT16_MAX +# define SCNd16 "hd" +# endif +#endif +#if !defined SCNi16 +# ifdef INT16_MAX +# define SCNi16 "hi" +# endif +#endif +#if !defined SCNo16 +# ifdef UINT16_MAX +# define SCNo16 "ho" +# endif +#endif +#if !defined SCNu16 +# ifdef UINT16_MAX +# define SCNu16 "hu" +# endif +#endif +#if !defined SCNx16 +# ifdef UINT16_MAX +# define SCNx16 "hx" +# endif +#endif +#if !defined SCNd32 +# ifdef INT32_MAX +# define SCNd32 "d" +# endif +#endif +#if !defined SCNi32 +# ifdef INT32_MAX +# define SCNi32 "i" +# endif +#endif +#if !defined SCNo32 +# ifdef UINT32_MAX +# define SCNo32 "o" +# endif +#endif +#if !defined SCNu32 +# ifdef UINT32_MAX +# define SCNu32 "u" +# endif +#endif +#if !defined SCNx32 +# ifdef UINT32_MAX +# define SCNx32 "x" +# endif +#endif +#ifdef INT64_MAX +# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@) +# define _SCN64_PREFIX "l" +# elif defined _MSC_VER || defined __MINGW32__ +# define _SCN64_PREFIX "I64" +# elif LONG_MAX >> 30 == 1 +# define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined SCNd64 +# define SCNd64 _SCN64_PREFIX "d" +# endif +# if !defined SCNi64 +# define SCNi64 _SCN64_PREFIX "i" +# endif +#endif +#ifdef UINT64_MAX +# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@) +# define _SCNu64_PREFIX "l" +# elif defined _MSC_VER || defined __MINGW32__ +# define _SCNu64_PREFIX "I64" +# elif ULONG_MAX >> 31 == 1 +# define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX +# endif +# if !defined SCNo64 +# define SCNo64 _SCNu64_PREFIX "o" +# endif +# if !defined SCNu64 +# define SCNu64 _SCNu64_PREFIX "u" +# endif +# if !defined SCNx64 +# define SCNx64 _SCNu64_PREFIX "x" +# endif +#endif + +#if !defined SCNdLEAST8 +# define SCNdLEAST8 "hhd" +#endif +#if !defined SCNiLEAST8 +# define SCNiLEAST8 "hhi" +#endif +#if !defined SCNoLEAST8 +# define SCNoLEAST8 "hho" +#endif +#if !defined SCNuLEAST8 +# define SCNuLEAST8 "hhu" +#endif +#if !defined SCNxLEAST8 +# define SCNxLEAST8 "hhx" +#endif +#if !defined SCNdLEAST16 +# define SCNdLEAST16 "hd" +#endif +#if !defined SCNiLEAST16 +# define SCNiLEAST16 "hi" +#endif +#if !defined SCNoLEAST16 +# define SCNoLEAST16 "ho" +#endif +#if !defined SCNuLEAST16 +# define SCNuLEAST16 "hu" +#endif +#if !defined SCNxLEAST16 +# define SCNxLEAST16 "hx" +#endif +#if !defined SCNdLEAST32 +# define SCNdLEAST32 "d" +#endif +#if !defined SCNiLEAST32 +# define SCNiLEAST32 "i" +#endif +#if !defined SCNoLEAST32 +# define SCNoLEAST32 "o" +#endif +#if !defined SCNuLEAST32 +# define SCNuLEAST32 "u" +#endif +#if !defined SCNxLEAST32 +# define SCNxLEAST32 "x" +#endif +#ifdef INT64_MAX +# if !defined SCNdLEAST64 +# define SCNdLEAST64 SCNd64 +# endif +# if !defined SCNiLEAST64 +# define SCNiLEAST64 SCNi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined SCNoLEAST64 +# define SCNoLEAST64 SCNo64 +# endif +# if !defined SCNuLEAST64 +# define SCNuLEAST64 SCNu64 +# endif +# if !defined SCNxLEAST64 +# define SCNxLEAST64 SCNx64 +# endif +#endif + +#if !defined SCNdFAST8 +# if INT_FAST8_MAX > INT32_MAX +# define SCNdFAST8 SCNd64 +# elif INT_FAST8_MAX == 0x7fff +# define SCNdFAST8 "hd" +# elif INT_FAST8_MAX == 0x7f +# define SCNdFAST8 "hhd" +# else +# define SCNdFAST8 "d" +# endif +#endif +#if !defined SCNiFAST8 +# if INT_FAST8_MAX > INT32_MAX +# define SCNiFAST8 SCNi64 +# elif INT_FAST8_MAX == 0x7fff +# define SCNiFAST8 "hi" +# elif INT_FAST8_MAX == 0x7f +# define SCNiFAST8 "hhi" +# else +# define SCNiFAST8 "i" +# endif +#endif +#if !defined SCNoFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define SCNoFAST8 SCNo64 +# elif UINT_FAST8_MAX == 0xffff +# define SCNoFAST8 "ho" +# elif UINT_FAST8_MAX == 0xff +# define SCNoFAST8 "hho" +# else +# define SCNoFAST8 "o" +# endif +#endif +#if !defined SCNuFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define SCNuFAST8 SCNu64 +# elif UINT_FAST8_MAX == 0xffff +# define SCNuFAST8 "hu" +# elif UINT_FAST8_MAX == 0xff +# define SCNuFAST8 "hhu" +# else +# define SCNuFAST8 "u" +# endif +#endif +#if !defined SCNxFAST8 +# if UINT_FAST8_MAX > UINT32_MAX +# define SCNxFAST8 SCNx64 +# elif UINT_FAST8_MAX == 0xffff +# define SCNxFAST8 "hx" +# elif UINT_FAST8_MAX == 0xff +# define SCNxFAST8 "hhx" +# else +# define SCNxFAST8 "x" +# endif +#endif +#if !defined SCNdFAST16 +# if INT_FAST16_MAX > INT32_MAX +# define SCNdFAST16 SCNd64 +# elif INT_FAST16_MAX == 0x7fff +# define SCNdFAST16 "hd" +# else +# define SCNdFAST16 "d" +# endif +#endif +#if !defined SCNiFAST16 +# if INT_FAST16_MAX > INT32_MAX +# define SCNiFAST16 SCNi64 +# elif INT_FAST16_MAX == 0x7fff +# define SCNiFAST16 "hi" +# else +# define SCNiFAST16 "i" +# endif +#endif +#if !defined SCNoFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define SCNoFAST16 SCNo64 +# elif UINT_FAST16_MAX == 0xffff +# define SCNoFAST16 "ho" +# else +# define SCNoFAST16 "o" +# endif +#endif +#if !defined SCNuFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define SCNuFAST16 SCNu64 +# elif UINT_FAST16_MAX == 0xffff +# define SCNuFAST16 "hu" +# else +# define SCNuFAST16 "u" +# endif +#endif +#if !defined SCNxFAST16 +# if UINT_FAST16_MAX > UINT32_MAX +# define SCNxFAST16 SCNx64 +# elif UINT_FAST16_MAX == 0xffff +# define SCNxFAST16 "hx" +# else +# define SCNxFAST16 "x" +# endif +#endif +#if !defined SCNdFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define SCNdFAST32 SCNd64 +# else +# define SCNdFAST32 "d" +# endif +#endif +#if !defined SCNiFAST32 +# if INT_FAST32_MAX > INT32_MAX +# define SCNiFAST32 SCNi64 +# else +# define SCNiFAST32 "i" +# endif +#endif +#if !defined SCNoFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define SCNoFAST32 SCNo64 +# else +# define SCNoFAST32 "o" +# endif +#endif +#if !defined SCNuFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define SCNuFAST32 SCNu64 +# else +# define SCNuFAST32 "u" +# endif +#endif +#if !defined SCNxFAST32 +# if UINT_FAST32_MAX > UINT32_MAX +# define SCNxFAST32 SCNx64 +# else +# define SCNxFAST32 "x" +# endif +#endif +#ifdef INT64_MAX +# if !defined SCNdFAST64 +# define SCNdFAST64 SCNd64 +# endif +# if !defined SCNiFAST64 +# define SCNiFAST64 SCNi64 +# endif +#endif +#ifdef UINT64_MAX +# if !defined SCNoFAST64 +# define SCNoFAST64 SCNo64 +# endif +# if !defined SCNuFAST64 +# define SCNuFAST64 SCNu64 +# endif +# if !defined SCNxFAST64 +# define SCNxFAST64 SCNx64 +# endif +#endif + +#if !defined SCNdMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define SCNdMAX SCNd64 +# else +# define SCNdMAX "ld" +# endif +#endif +#if !defined SCNiMAX +# if @INT32_MAX_LT_INTMAX_MAX@ +# define SCNiMAX SCNi64 +# else +# define SCNiMAX "li" +# endif +#endif +#if !defined SCNoMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define SCNoMAX SCNo64 +# else +# define SCNoMAX "lo" +# endif +#endif +#if !defined SCNuMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define SCNuMAX SCNu64 +# else +# define SCNuMAX "lu" +# endif +#endif +#if !defined SCNxMAX +# if @UINT32_MAX_LT_UINTMAX_MAX@ +# define SCNxMAX SCNx64 +# else +# define SCNxMAX "lx" +# endif +#endif + +#if !defined SCNdPTR +# ifdef INTPTR_MAX +# define SCNdPTR @PRIPTR_PREFIX@ "d" +# endif +#endif +#if !defined SCNiPTR +# ifdef INTPTR_MAX +# define SCNiPTR @PRIPTR_PREFIX@ "i" +# endif +#endif +#if !defined SCNoPTR +# ifdef UINTPTR_MAX +# define SCNoPTR @PRIPTR_PREFIX@ "o" +# endif +#endif +#if !defined SCNuPTR +# ifdef UINTPTR_MAX +# define SCNuPTR @PRIPTR_PREFIX@ "u" +# endif +#endif +#if !defined SCNxPTR +# ifdef UINTPTR_MAX +# define SCNxPTR @PRIPTR_PREFIX@ "x" +# endif +#endif + +/* 7.8.2 Functions for greatest-width integer types */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if @GNULIB_IMAXABS@ +# if !@HAVE_DECL_IMAXABS@ +extern intmax_t imaxabs (intmax_t); +# endif +#elif defined GNULIB_POSIXCHECK +# undef imaxabs +# if HAVE_RAW_DECL_IMAXABS +_GL_WARN_ON_USE (imaxabs, "imaxabs is unportable - " + "use gnulib module imaxabs for portability"); +# endif +#endif + +#if @GNULIB_IMAXDIV@ +# if !@HAVE_IMAXDIV_T@ +# if !GNULIB_defined_imaxdiv_t +typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; +# define GNULIB_defined_imaxdiv_t 1 +# endif +# endif +# if !@HAVE_DECL_IMAXDIV@ +extern imaxdiv_t imaxdiv (intmax_t, intmax_t); +# endif +#elif defined GNULIB_POSIXCHECK +# undef imaxdiv +# if HAVE_RAW_DECL_IMAXDIV +_GL_WARN_ON_USE (imaxdiv, "imaxdiv is unportable - " + "use gnulib module imaxdiv for portability"); +# endif +#endif + +#if @GNULIB_STRTOIMAX@ +# if @REPLACE_STRTOIMAX@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strtoimax +# define strtoimax rpl_strtoimax +# endif +_GL_FUNCDECL_RPL (strtoimax, intmax_t, + (const char *restrict, char **restrict, int) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoimax, intmax_t, + (const char *restrict, char **restrict, int)); +# else +# if !@HAVE_DECL_STRTOIMAX@ +# undef strtoimax +_GL_FUNCDECL_SYS (strtoimax, intmax_t, + (const char *restrict, char **restrict, int) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoimax, intmax_t, + (const char *restrict, char **restrict, int)); +# endif +_GL_CXXALIASWARN (strtoimax); +#elif defined GNULIB_POSIXCHECK +# undef strtoimax +# if HAVE_RAW_DECL_STRTOIMAX +_GL_WARN_ON_USE (strtoimax, "strtoimax is unportable - " + "use gnulib module strtoimax for portability"); +# endif +#endif + +#if @GNULIB_STRTOUMAX@ +# if @REPLACE_STRTOUMAX@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strtoumax +# define strtoumax rpl_strtoumax +# endif +_GL_FUNCDECL_RPL (strtoumax, uintmax_t, + (const char *restrict, char **restrict, int) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoumax, uintmax_t, + (const char *restrict, char **restrict, int)); +# else +# if !@HAVE_DECL_STRTOUMAX@ +# undef strtoumax +_GL_FUNCDECL_SYS (strtoumax, uintmax_t, + (const char *restrict, char **restrict, int) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoumax, uintmax_t, + (const char *restrict, char **restrict, int)); +# endif +_GL_CXXALIASWARN (strtoumax); +#elif defined GNULIB_POSIXCHECK +# undef strtoumax +# if HAVE_RAW_DECL_STRTOUMAX +_GL_WARN_ON_USE (strtoumax, "strtoumax is unportable - " + "use gnulib module strtoumax for portability"); +# endif +#endif + +/* Don't bother defining or declaring wcstoimax and wcstoumax, since + wide-character functions like this are hardly ever useful. */ + +#ifdef __cplusplus +} +#endif + +#endif /* !defined INTTYPES_H && !defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H */ diff --git a/gl/itold.c b/gl/itold.c index 9aabc7e4..fe4a3842 100644 --- a/gl/itold.c +++ b/gl/itold.c @@ -1,19 +1,19 @@ /* Replacement for 'int' to 'long double' conversion routine. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2011. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/langinfo.in.h b/gl/langinfo.in.h index 5388ce62..98aea6a8 100644 --- a/gl/langinfo.in.h +++ b/gl/langinfo.in.h @@ -1,22 +1,22 @@ /* Substitute for and wrapper around . - Copyright (C) 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* * POSIX for platforms that lack it or have an incomplete one. - * + * */ #ifndef _@GUARD_PREFIX@_LANGINFO_H @@ -49,7 +49,10 @@ typedef int nl_item; # define CODESET 10000 /* nl_langinfo items of the LC_NUMERIC category */ # define RADIXCHAR 10001 +# define DECIMAL_POINT RADIXCHAR # define THOUSEP 10002 +# define THOUSANDS_SEP THOUSEP +# define GROUPING 10114 /* nl_langinfo items of the LC_TIME category */ # define D_T_FMT 10003 # define D_FMT 10004 @@ -83,6 +86,18 @@ typedef int nl_item; # define MON_10 (MON_1 + 9) # define MON_11 (MON_1 + 10) # define MON_12 (MON_1 + 11) +# define ALTMON_1 10200 +# define ALTMON_2 (ALTMON_1 + 1) +# define ALTMON_3 (ALTMON_1 + 2) +# define ALTMON_4 (ALTMON_1 + 3) +# define ALTMON_5 (ALTMON_1 + 4) +# define ALTMON_6 (ALTMON_1 + 5) +# define ALTMON_7 (ALTMON_1 + 6) +# define ALTMON_8 (ALTMON_1 + 7) +# define ALTMON_9 (ALTMON_1 + 8) +# define ALTMON_10 (ALTMON_1 + 9) +# define ALTMON_11 (ALTMON_1 + 10) +# define ALTMON_12 (ALTMON_1 + 11) # define ABMON_1 10035 # define ABMON_2 (ABMON_1 + 1) # define ABMON_3 (ABMON_1 + 2) @@ -102,6 +117,21 @@ typedef int nl_item; # define ALT_DIGITS 10051 /* nl_langinfo items of the LC_MONETARY category */ # define CRNCYSTR 10052 +# define CURRENCY_SYMBOL CRNCYSTR +# define INT_CURR_SYMBOL 10100 +# define MON_DECIMAL_POINT 10101 +# define MON_THOUSANDS_SEP 10102 +# define MON_GROUPING 10103 +# define POSITIVE_SIGN 10104 +# define NEGATIVE_SIGN 10105 +# define FRAC_DIGITS 10106 +# define INT_FRAC_DIGITS 10107 +# define P_CS_PRECEDES 10108 +# define N_CS_PRECEDES 10109 +# define P_SEP_BY_SPACE 10110 +# define N_SEP_BY_SPACE 10111 +# define P_SIGN_POSN 10112 +# define N_SIGN_POSN 10113 /* nl_langinfo items of the LC_MESSAGES category */ # define YESEXPR 10053 # define NOEXPR 10054 @@ -120,6 +150,22 @@ typedef int nl_item; # define GNULIB_defined_T_FMT_AMPM 1 # endif +# if !@HAVE_LANGINFO_ALTMON@ +# define ALTMON_1 10200 +# define ALTMON_2 (ALTMON_1 + 1) +# define ALTMON_3 (ALTMON_1 + 2) +# define ALTMON_4 (ALTMON_1 + 3) +# define ALTMON_5 (ALTMON_1 + 4) +# define ALTMON_6 (ALTMON_1 + 5) +# define ALTMON_7 (ALTMON_1 + 6) +# define ALTMON_8 (ALTMON_1 + 7) +# define ALTMON_9 (ALTMON_1 + 8) +# define ALTMON_10 (ALTMON_1 + 9) +# define ALTMON_11 (ALTMON_1 + 10) +# define ALTMON_12 (ALTMON_1 + 11) +# define GNULIB_defined_ALTMON 1 +# endif + # if !@HAVE_LANGINFO_ERA@ # define ERA 10047 # define ERA_D_FMT 10048 diff --git a/gl/lc-charset-dispatch.c b/gl/lc-charset-dispatch.c new file mode 100644 index 00000000..66d78fd3 --- /dev/null +++ b/gl/lc-charset-dispatch.c @@ -0,0 +1,82 @@ +/* Dispatching based on the current locale's character encoding. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2018. */ + +#include + +/* Specification. */ +#include "lc-charset-dispatch.h" + +#if GNULIB_defined_mbstate_t + +# include "localcharset.h" +# include "streq.h" + +# if GNULIB_WCHAR_SINGLE_LOCALE +/* When we know that the locale does not change, provide a speedup by + caching the value of locale_encoding_classification. */ +# define locale_encoding_classification_cached locale_encoding_classification +# else +/* By default, don't make assumptions, hence no caching. */ +# define locale_encoding_classification_uncached locale_encoding_classification +# endif + +# if GNULIB_WCHAR_SINGLE_LOCALE +static inline +# endif +enc_t +locale_encoding_classification_uncached (void) +{ + const char *encoding = locale_charset (); + if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) + return enc_utf8; + if (STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) + return enc_eucjp; + if (STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) + || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) + return enc_94; + if (STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) + return enc_euctw; + if (STREQ_OPT (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) + return enc_gb18030; + if (STREQ_OPT (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) + return enc_sjis; + return enc_other; +} + +# if GNULIB_WCHAR_SINGLE_LOCALE + +static int cached_locale_enc = -1; + +enc_t +locale_encoding_classification_cached (void) +{ + if (cached_locale_enc < 0) + cached_locale_enc = locale_encoding_classification_uncached (); + return cached_locale_enc; +} + +# endif + +#else + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#endif diff --git a/gl/lc-charset-dispatch.h b/gl/lc-charset-dispatch.h new file mode 100644 index 00000000..3867c323 --- /dev/null +++ b/gl/lc-charset-dispatch.h @@ -0,0 +1,40 @@ +/* Dispatching based on the current locale's character encoding. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2018. */ + +#include + +#if GNULIB_defined_mbstate_t + +/* A classification of special values of the encoding of the current locale. */ +typedef enum + { + enc_other, /* other */ + enc_utf8, /* UTF-8 */ + enc_eucjp, /* EUC-JP */ + enc_94, /* EUC-KR, GB2312, BIG5 */ + enc_euctw, /* EUC-TW */ + enc_gb18030, /* GB18030 */ + enc_sjis /* SJIS */ + } + enc_t; + +/* Returns a classification of special values of the encoding of the current + locale. */ +extern enc_t locale_encoding_classification (void); + +#endif diff --git a/gl/libc-config.h b/gl/libc-config.h new file mode 100644 index 00000000..a56665b1 --- /dev/null +++ b/gl/libc-config.h @@ -0,0 +1,202 @@ +/* System definitions for code taken from the GNU C Library + + Copyright 2017-2022 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see + . */ + +/* Written by Paul Eggert. */ + +/* This is intended to be a good-enough substitute for glibc system + macros like those defined in , so that Gnulib code + shared with glibc can do this as the first #include: + + #ifndef _LIBC + # include + #endif + + When compiled as part of glibc this is a no-op; when compiled as + part of Gnulib this includes Gnulib's and defines macros + that glibc library code would normally assume. + + Note: This header file MUST NOT be included by public header files + of Gnulib. */ + +#include + +/* On glibc this includes and and #defines + _FEATURES_H, __WORDSIZE, and __set_errno. On FreeBSD 11 and + DragonFlyBSD 5.9 it includes which defines __nonnull. + Elsewhere it is harmless. */ +#include + +/* From glibc . */ +#ifndef __set_errno +# define __set_errno(val) (errno = (val)) +#endif + +/* From glibc . */ + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#ifndef __glibc_clang_prereq +# if defined __clang_major__ && defined __clang_minor__ +# ifdef __apple_build_version__ +/* Apple for some reason renumbers __clang_major__ and __clang_minor__. + Gnulib code uses only __glibc_clang_prereq (3, 5); map it to + 6000000 <= __apple_build_version__. Support for other calls to + __glibc_clang_prereq can be added here as needed. */ +# define __glibc_clang_prereq(maj, min) \ + ((maj) == 3 && (min) == 5 ? 6000000 <= __apple_build_version__ : 0) +# else +# define __glibc_clang_prereq(maj, min) \ + ((maj) < __clang_major__ + ((min) <= __clang_minor__)) +# endif +# else +# define __glibc_clang_prereq(maj, min) 0 +# endif +#endif + +#ifndef __attribute_nonnull__ +/* either does not exist, or is too old for Gnulib. + Prepare to include , which is Gnulib's version of a + more-recent glibc . */ + +/* Define _FEATURES_H so that does not include . */ +# ifndef _FEATURES_H +# define _FEATURES_H 1 +# endif +/* Define __GNULIB_CDEFS so that does not attempt to include + nonexistent files. */ +# define __GNULIB_CDEFS +/* Undef the macros unconditionally defined by our copy of glibc + , 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_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 __attr_access_none +# undef __attr_dealloc +# undef __attr_dealloc_free +# undef __attribute__ +# undef __attribute_alloc_align__ +# 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_maybe_unused__ +# 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 __fortified_attr_access +# undef __fortify_function +# undef __glibc_c99_flexarr_available +# undef __glibc_fortify +# undef __glibc_fortify_n +# undef __glibc_has_attribute +# undef __glibc_has_builtin +# undef __glibc_has_extension +# undef __glibc_likely +# undef __glibc_macro_warning +# undef __glibc_macro_warning1 +# undef __glibc_objsize +# undef __glibc_objsize0 +# undef __glibc_safe_len_cond +# undef __glibc_safe_or_unknown_len +# undef __glibc_unlikely +# undef __glibc_unsafe_len +# undef __glibc_unsigned_or_positive +# undef __inline +# undef __ptr_t +# undef __restrict +# undef __restrict_arr +# undef __va_arg_pack +# undef __va_arg_pack_len +# undef __warnattr +# undef __wur + +/* Include our copy of glibc . */ +# include + +/* __inline is too pessimistic for non-GCC. */ +# undef __inline +# ifndef HAVE___INLINE +# if 199901 <= __STDC_VERSION__ || defined inline +# define __inline inline +# else +# define __inline +# endif +# endif + +#endif /* defined __glibc_likely */ + + +/* A substitute for glibc , good enough for Gnulib. */ +#define attribute_hidden +#define libc_hidden_proto(name) +#define libc_hidden_def(name) +#define libc_hidden_weak(name) +#define libc_hidden_ver(local, name) +#define strong_alias(name, aliasname) +#define weak_alias(name, aliasname) + +/* A substitute for glibc , good enough for Gnulib. */ +#define SHLIB_COMPAT(lib, introduced, obsoleted) 0 +#define compat_symbol(lib, local, symbol, version) extern int dummy +#define versioned_symbol(lib, local, symbol, version) extern int dummy diff --git a/gl/limits.in.h b/gl/limits.in.h new file mode 100644 index 00000000..b77bf75c --- /dev/null +++ b/gl/limits.in.h @@ -0,0 +1,131 @@ +/* A GNU-like . + + Copyright 2016-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined _GL_ALREADY_INCLUDING_LIMITS_H +/* Special invocation convention: + On Haiku/x86_64, we have a sequence of nested includes + -> -> . + In this situation, LONG_MAX and INT_MAX are not yet defined, + therefore we should not attempt to define LONG_BIT. */ + +#@INCLUDE_NEXT@ @NEXT_LIMITS_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_LIMITS_H + +# define _GL_ALREADY_INCLUDING_LIMITS_H + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_LIMITS_H@ + +# undef _GL_ALREADY_INCLUDING_LIMITS_H + +#ifndef _@GUARD_PREFIX@_LIMITS_H +#define _@GUARD_PREFIX@_LIMITS_H + +#ifndef LLONG_MIN +# if defined LONG_LONG_MIN /* HP-UX 11.31 */ +# define LLONG_MIN LONG_LONG_MIN +# elif defined LONGLONG_MIN /* IRIX 6.5 */ +# define LLONG_MIN LONGLONG_MIN +# elif defined __GNUC__ +# define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL) +# endif +#endif +#ifndef LLONG_MAX +# if defined LONG_LONG_MAX /* HP-UX 11.31 */ +# define LLONG_MAX LONG_LONG_MAX +# elif defined LONGLONG_MAX /* IRIX 6.5 */ +# define LLONG_MAX LONGLONG_MAX +# elif defined __GNUC__ +# define LLONG_MAX __LONG_LONG_MAX__ +# endif +#endif +#ifndef ULLONG_MAX +# if defined ULONG_LONG_MAX /* HP-UX 11.31 */ +# define ULLONG_MAX ULONG_LONG_MAX +# elif defined ULONGLONG_MAX /* IRIX 6.5 */ +# define ULLONG_MAX ULONGLONG_MAX +# elif defined __GNUC__ +# define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL) +# endif +#endif + +/* The number of usable bits in an unsigned or signed integer type + with minimum value MIN and maximum value MAX, as an int expression + suitable in #if. Cover all known practical hosts. This + implementation exploits the fact that MAX is 1 less than a power of + 2, and merely counts the number of 1 bits in MAX; "COBn" means + "count the number of 1 bits in the low-order n bits"). */ +#define _GL_INTEGER_WIDTH(min, max) (((min) < 0) + _GL_COB128 (max)) +#define _GL_COB128(n) (_GL_COB64 ((n) >> 31 >> 31 >> 2) + _GL_COB64 (n)) +#define _GL_COB64(n) (_GL_COB32 ((n) >> 31 >> 1) + _GL_COB32 (n)) +#define _GL_COB32(n) (_GL_COB16 ((n) >> 16) + _GL_COB16 (n)) +#define _GL_COB16(n) (_GL_COB8 ((n) >> 8) + _GL_COB8 (n)) +#define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n)) +#define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1)) + +#ifndef WORD_BIT +/* Assume 'int' is 32 bits wide. */ +# define WORD_BIT 32 +#endif +#ifndef LONG_BIT +/* Assume 'long' is 32 or 64 bits wide. */ +# if LONG_MAX == INT_MAX +# define LONG_BIT 32 +# else +# define LONG_BIT 64 +# endif +#endif + +/* Macros specified by C2x and by ISO/IEC TS 18661-1:2014. */ + +#if (! defined ULLONG_WIDTH \ + && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__ \ + || (defined __STDC_VERSION__ && 201710 < __STDC_VERSION__))) +# define CHAR_WIDTH _GL_INTEGER_WIDTH (CHAR_MIN, CHAR_MAX) +# define SCHAR_WIDTH _GL_INTEGER_WIDTH (SCHAR_MIN, SCHAR_MAX) +# define UCHAR_WIDTH _GL_INTEGER_WIDTH (0, UCHAR_MAX) +# define SHRT_WIDTH _GL_INTEGER_WIDTH (SHRT_MIN, SHRT_MAX) +# define USHRT_WIDTH _GL_INTEGER_WIDTH (0, USHRT_MAX) +# define INT_WIDTH _GL_INTEGER_WIDTH (INT_MIN, INT_MAX) +# define UINT_WIDTH _GL_INTEGER_WIDTH (0, UINT_MAX) +# define LONG_WIDTH _GL_INTEGER_WIDTH (LONG_MIN, LONG_MAX) +# define ULONG_WIDTH _GL_INTEGER_WIDTH (0, ULONG_MAX) +# define LLONG_WIDTH _GL_INTEGER_WIDTH (LLONG_MIN, LLONG_MAX) +# define ULLONG_WIDTH _GL_INTEGER_WIDTH (0, ULLONG_MAX) +#endif + +/* Macros specified by C2x. */ + +#if (! defined BOOL_WIDTH \ + && (defined _GNU_SOURCE \ + || (defined __STDC_VERSION__ && 201710 < __STDC_VERSION__))) +# define BOOL_MAX 1 +# define BOOL_WIDTH 1 +#endif + +#endif /* _@GUARD_PREFIX@_LIMITS_H */ +#endif /* _@GUARD_PREFIX@_LIMITS_H */ +#endif diff --git a/gl/localcharset.c b/gl/localcharset.c index a225a2ea..17a4a1ef 100644 --- a/gl/localcharset.c +++ b/gl/localcharset.c @@ -1,19 +1,19 @@ /* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2006, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2000-2006, 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible . */ @@ -22,7 +22,6 @@ /* Specification. */ #include "localcharset.h" -#include #include #include #include @@ -32,8 +31,9 @@ # define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */ #endif -#if defined _WIN32 || defined __WIN32__ +#if defined _WIN32 && !defined __CYGWIN__ # define WINDOWS_NATIVE +# include #endif #if defined __EMX__ @@ -44,11 +44,10 @@ #endif #if !defined WINDOWS_NATIVE -# include # if HAVE_LANGINFO_CODESET # include # else -# if 0 /* see comment below */ +# if 0 /* see comment regarding use of setlocale(), below */ # include # endif # endif @@ -59,6 +58,9 @@ #elif defined WINDOWS_NATIVE # define WIN32_LEAN_AND_MEAN # include + /* For the use of setlocale() below, the Gnulib override in setlocale.c is + not needed; see the platform lists in setlocale_null.m4. */ +# undef setlocale #endif #if defined OS2 # define INCL_DOS @@ -70,288 +72,755 @@ # include #endif -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif -/* Get LIBDIR. */ -#ifndef LIBDIR -# include "configmake.h" -#endif - -/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ -#ifndef O_NOFOLLOW -# define O_NOFOLLOW 0 -#endif - -#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ - /* Native Windows, Cygwin, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#endif - -#ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -#endif +#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2 -#ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -#endif +/* On these platforms, we use a mapping from non-canonical encoding name + to GNU canonical encoding name. */ -#if HAVE_DECL_GETC_UNLOCKED -# undef getc -# define getc getc_unlocked -#endif +/* With glibc-2.1 or newer, we don't need any canonicalization, + because glibc has iconv and both glibc and libiconv support all + GNU canonical names directly. */ +# if !((defined __GNU_LIBRARY__ && __GLIBC__ >= 2) || defined __UCLIBC__) -/* The following static variable is declared 'volatile' to avoid a - possible multithread problem in the function get_charset_aliases. If we - are running in a threaded environment, and if two threads initialize - 'charset_aliases' simultaneously, both will produce the same value, - and everything will be ok if the two assignments to 'charset_aliases' - are atomic. But I don't know what will happen if the two assignments mix. */ -#if __STDC__ != 1 -# define volatile /* empty */ -#endif -/* Pointer to the contents of the charset.alias file, if it has already been - read, else NULL. Its format is: - ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ -static const char * volatile charset_aliases; - -/* Return a pointer to the contents of the charset.alias file. */ -static const char * -get_charset_aliases (void) +struct table_entry { - const char *cp; - - cp = charset_aliases; - if (cp == NULL) - { -#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__) - const char *dir; - const char *base = "charset.alias"; - char *file_name; - - /* Make it possible to override the charset.alias location. This is - necessary for running the testsuite before "make install". */ - dir = getenv ("CHARSETALIASDIR"); - if (dir == NULL || dir[0] == '\0') - dir = relocate (LIBDIR); - - /* Concatenate dir and base into freshly allocated file_name. */ - { - size_t dir_len = strlen (dir); - size_t base_len = strlen (base); - int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); - file_name = (char *) malloc (dir_len + add_slash + base_len + 1); - if (file_name != NULL) - { - memcpy (file_name, dir, dir_len); - if (add_slash) - file_name[dir_len] = DIRECTORY_SEPARATOR; - memcpy (file_name + dir_len + add_slash, base, base_len + 1); - } - } - - if (file_name == NULL) - /* Out of memory. Treat the file as empty. */ - cp = ""; - else - { - int fd; - - /* Open the file. Reject symbolic links on platforms that support - O_NOFOLLOW. This is a security feature. Without it, an attacker - could retrieve parts of the contents (namely, the tail of the - first line that starts with "* ") of an arbitrary file by placing - a symbolic link to that file under the name "charset.alias" in - some writable directory and defining the environment variable - CHARSETALIASDIR to point to that directory. */ - fd = open (file_name, - O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); - if (fd < 0) - /* File not found. Treat it as empty. */ - cp = ""; - else - { - FILE *fp; - - fp = fdopen (fd, "r"); - if (fp == NULL) - { - /* Out of memory. Treat the file as empty. */ - close (fd); - cp = ""; - } - else - { - /* Parse the file's contents. */ - char *res_ptr = NULL; - size_t res_size = 0; - - for (;;) - { - int c; - char buf1[50+1]; - char buf2[50+1]; - size_t l1, l2; - char *old_res_ptr; - - c = getc (fp); - if (c == EOF) - break; - if (c == '\n' || c == ' ' || c == '\t') - continue; - if (c == '#') - { - /* Skip comment, to end of line. */ - do - c = getc (fp); - while (!(c == EOF || c == '\n')); - if (c == EOF) - break; - continue; - } - ungetc (c, fp); - if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) - break; - l1 = strlen (buf1); - l2 = strlen (buf2); - old_res_ptr = res_ptr; - if (res_size == 0) - { - res_size = l1 + 1 + l2 + 1; - res_ptr = (char *) malloc (res_size + 1); - } - else - { - res_size += l1 + 1 + l2 + 1; - res_ptr = (char *) realloc (res_ptr, res_size + 1); - } - if (res_ptr == NULL) - { - /* Out of memory. */ - res_size = 0; - free (old_res_ptr); - break; - } - strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); - strcpy (res_ptr + res_size - (l2 + 1), buf2); - } - fclose (fp); - if (res_size == 0) - cp = ""; - else - { - *(res_ptr + res_size) = '\0'; - cp = res_ptr; - } - } - } + const char alias[11+1]; + const char canonical[11+1]; +}; + +/* Table of platform-dependent mappings, sorted in ascending order. */ +static const struct table_entry alias_table[] = + { +# if defined __FreeBSD__ /* FreeBSD */ + /*{ "ARMSCII-8", "ARMSCII-8" },*/ + { "Big5", "BIG5" }, + { "C", "ASCII" }, + /*{ "CP1131", "CP1131" },*/ + /*{ "CP1251", "CP1251" },*/ + /*{ "CP866", "CP866" },*/ + /*{ "GB18030", "GB18030" },*/ + /*{ "GB2312", "GB2312" },*/ + /*{ "GBK", "GBK" },*/ + /*{ "ISCII-DEV", "?" },*/ + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-13", "ISO-8859-13" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-9", "ISO-8859-9" }, + /*{ "KOI8-R", "KOI8-R" },*/ + /*{ "KOI8-U", "KOI8-U" },*/ + { "SJIS", "SHIFT_JIS" }, + { "US-ASCII", "ASCII" }, + { "eucCN", "GB2312" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" } +# define alias_table_defined +# endif +# if defined __NetBSD__ /* NetBSD */ + { "646", "ASCII" }, + /*{ "ARMSCII-8", "ARMSCII-8" },*/ + /*{ "BIG5", "BIG5" },*/ + { "Big5-HKSCS", "BIG5-HKSCS" }, + /*{ "CP1251", "CP1251" },*/ + /*{ "CP866", "CP866" },*/ + /*{ "GB18030", "GB18030" },*/ + /*{ "GB2312", "GB2312" },*/ + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-13", "ISO-8859-13" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + /*{ "KOI8-R", "KOI8-R" },*/ + /*{ "KOI8-U", "KOI8-U" },*/ + /*{ "PT154", "PT154" },*/ + { "SJIS", "SHIFT_JIS" }, + { "eucCN", "GB2312" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" }, + { "eucTW", "EUC-TW" } +# define alias_table_defined +# endif +# if defined __OpenBSD__ /* OpenBSD */ + { "646", "ASCII" }, + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-13", "ISO-8859-13" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + { "US-ASCII", "ASCII" } +# define alias_table_defined +# endif +# if defined __APPLE__ && defined __MACH__ /* Mac OS X */ + /* Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is + useless: + - It returns the empty string when LANG is set to a locale of the + form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 + LC_CTYPE file. + - The environment variables LANG, LC_CTYPE, LC_ALL are not set by + the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. + - The documentation says: + "... all code that calls BSD system routines should ensure + that the const *char parameters of these routines are in UTF-8 + encoding. All BSD system functions expect their string + parameters to be in UTF-8 encoding and nothing else." + It also says + "An additional caveat is that string parameters for files, + paths, and other file-system entities must be in canonical + UTF-8. In a canonical UTF-8 Unicode string, all decomposable + characters are decomposed ..." + but this is not true: You can pass non-decomposed UTF-8 strings + to file system functions, and it is the OS which will convert + them to decomposed UTF-8 before accessing the file system. + - The Apple Terminal application displays UTF-8 by default. + - However, other applications are free to use different encodings: + - xterm uses ISO-8859-1 by default. + - TextEdit uses MacRoman by default. + We prefer UTF-8 over decomposed UTF-8-MAC because one should + minimize the use of decomposed Unicode. Unfortunately, through the + Darwin file system, decomposed UTF-8 strings are leaked into user + space nevertheless. + Then there are also the locales with encodings other than US-ASCII + and UTF-8. These locales can be occasionally useful to users (e.g. + when grepping through ISO-8859-1 encoded text files), when all their + file names are in US-ASCII. + */ + { "ARMSCII-8", "ARMSCII-8" }, + { "Big5", "BIG5" }, + { "Big5HKSCS", "BIG5-HKSCS" }, + { "CP1131", "CP1131" }, + { "CP1251", "CP1251" }, + { "CP866", "CP866" }, + { "CP949", "CP949" }, + { "GB18030", "GB18030" }, + { "GB2312", "GB2312" }, + { "GBK", "GBK" }, + /*{ "ISCII-DEV", "?" },*/ + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-13", "ISO-8859-13" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-9", "ISO-8859-9" }, + { "KOI8-R", "KOI8-R" }, + { "KOI8-U", "KOI8-U" }, + { "PT154", "PT154" }, + { "SJIS", "SHIFT_JIS" }, + { "eucCN", "GB2312" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" } +# define alias_table_defined +# endif +# if defined _AIX /* AIX */ + /*{ "GBK", "GBK" },*/ + { "IBM-1046", "CP1046" }, + { "IBM-1124", "CP1124" }, + { "IBM-1129", "CP1129" }, + { "IBM-1252", "CP1252" }, + { "IBM-850", "CP850" }, + { "IBM-856", "CP856" }, + { "IBM-921", "ISO-8859-13" }, + { "IBM-922", "CP922" }, + { "IBM-932", "CP932" }, + { "IBM-943", "CP943" }, + { "IBM-eucCN", "GB2312" }, + { "IBM-eucJP", "EUC-JP" }, + { "IBM-eucKR", "EUC-KR" }, + { "IBM-eucTW", "EUC-TW" }, + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-6", "ISO-8859-6" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-8", "ISO-8859-8" }, + { "ISO8859-9", "ISO-8859-9" }, + { "TIS-620", "TIS-620" }, + /*{ "UTF-8", "UTF-8" },*/ + { "big5", "BIG5" } +# define alias_table_defined +# endif +# if defined __hpux /* HP-UX */ + { "SJIS", "SHIFT_JIS" }, + { "arabic8", "HP-ARABIC8" }, + { "big5", "BIG5" }, + { "cp1251", "CP1251" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" }, + { "eucTW", "EUC-TW" }, + { "gb18030", "GB18030" }, + { "greek8", "HP-GREEK8" }, + { "hebrew8", "HP-HEBREW8" }, + { "hkbig5", "BIG5-HKSCS" }, + { "hp15CN", "GB2312" }, + { "iso88591", "ISO-8859-1" }, + { "iso885913", "ISO-8859-13" }, + { "iso885915", "ISO-8859-15" }, + { "iso88592", "ISO-8859-2" }, + { "iso88594", "ISO-8859-4" }, + { "iso88595", "ISO-8859-5" }, + { "iso88596", "ISO-8859-6" }, + { "iso88597", "ISO-8859-7" }, + { "iso88598", "ISO-8859-8" }, + { "iso88599", "ISO-8859-9" }, + { "kana8", "HP-KANA8" }, + { "koi8r", "KOI8-R" }, + { "roman8", "HP-ROMAN8" }, + { "tis620", "TIS-620" }, + { "turkish8", "HP-TURKISH8" }, + { "utf8", "UTF-8" } +# define alias_table_defined +# endif +# if defined __sgi /* IRIX */ + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-9", "ISO-8859-9" }, + { "eucCN", "GB2312" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" }, + { "eucTW", "EUC-TW" } +# define alias_table_defined +# endif +# if defined __osf__ /* OSF/1 */ + /*{ "GBK", "GBK" },*/ + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-8", "ISO-8859-8" }, + { "ISO8859-9", "ISO-8859-9" }, + { "KSC5601", "CP949" }, + { "SJIS", "SHIFT_JIS" }, + { "TACTIS", "TIS-620" }, + /*{ "UTF-8", "UTF-8" },*/ + { "big5", "BIG5" }, + { "cp850", "CP850" }, + { "dechanyu", "DEC-HANYU" }, + { "dechanzi", "GB2312" }, + { "deckanji", "DEC-KANJI" }, + { "deckorean", "EUC-KR" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" }, + { "eucTW", "EUC-TW" }, + { "sdeckanji", "EUC-JP" } +# define alias_table_defined +# endif +# if defined __sun /* Solaris */ + { "5601", "EUC-KR" }, + { "646", "ASCII" }, + /*{ "BIG5", "BIG5" },*/ + { "Big5-HKSCS", "BIG5-HKSCS" }, + { "GB18030", "GB18030" }, + /*{ "GBK", "GBK" },*/ + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-11", "TIS-620" }, + { "ISO8859-13", "ISO-8859-13" }, + { "ISO8859-15", "ISO-8859-15" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-3", "ISO-8859-3" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-6", "ISO-8859-6" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-8", "ISO-8859-8" }, + { "ISO8859-9", "ISO-8859-9" }, + { "PCK", "SHIFT_JIS" }, + { "TIS620.2533", "TIS-620" }, + /*{ "UTF-8", "UTF-8" },*/ + { "ansi-1251", "CP1251" }, + { "cns11643", "EUC-TW" }, + { "eucJP", "EUC-JP" }, + { "gb2312", "GB2312" }, + { "koi8-r", "KOI8-R" } +# define alias_table_defined +# endif +# if defined __minix /* Minix */ + { "646", "ASCII" } +# define alias_table_defined +# endif +# if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Windows */ + { "CP1361", "JOHAB" }, + { "CP20127", "ASCII" }, + { "CP20866", "KOI8-R" }, + { "CP20936", "GB2312" }, + { "CP21866", "KOI8-RU" }, + { "CP28591", "ISO-8859-1" }, + { "CP28592", "ISO-8859-2" }, + { "CP28593", "ISO-8859-3" }, + { "CP28594", "ISO-8859-4" }, + { "CP28595", "ISO-8859-5" }, + { "CP28596", "ISO-8859-6" }, + { "CP28597", "ISO-8859-7" }, + { "CP28598", "ISO-8859-8" }, + { "CP28599", "ISO-8859-9" }, + { "CP28605", "ISO-8859-15" }, + { "CP38598", "ISO-8859-8" }, + { "CP51932", "EUC-JP" }, + { "CP51936", "GB2312" }, + { "CP51949", "EUC-KR" }, + { "CP51950", "EUC-TW" }, + { "CP54936", "GB18030" }, + { "CP65001", "UTF-8" }, + { "CP936", "GBK" } +# define alias_table_defined +# endif +# if defined OS2 /* OS/2 */ + /* The list of encodings is taken from "List of OS/2 Codepages" + by Alex Taylor: + . + See also "__convcp() of kLIBC": + . */ + { "CP1004", "CP1252" }, + /*{ "CP1041", "CP943" },*/ + /*{ "CP1088", "CP949" },*/ + { "CP1089", "ISO-8859-6" }, + /*{ "CP1114", "CP950" },*/ + /*{ "CP1115", "GB2312" },*/ + { "CP1208", "UTF-8" }, + /*{ "CP1380", "GB2312" },*/ + { "CP1381", "GB2312" }, + { "CP1383", "GB2312" }, + { "CP1386", "GBK" }, + /*{ "CP301", "CP943" },*/ + { "CP3372", "EUC-JP" }, + { "CP4946", "CP850" }, + /*{ "CP5048", "JIS_X0208-1990" },*/ + /*{ "CP5049", "JIS_X0212-1990" },*/ + /*{ "CP5067", "KS_C_5601-1987" },*/ + { "CP813", "ISO-8859-7" }, + { "CP819", "ISO-8859-1" }, + { "CP878", "KOI8-R" }, + /*{ "CP897", "CP943" },*/ + { "CP912", "ISO-8859-2" }, + { "CP913", "ISO-8859-3" }, + { "CP914", "ISO-8859-4" }, + { "CP915", "ISO-8859-5" }, + { "CP916", "ISO-8859-8" }, + { "CP920", "ISO-8859-9" }, + { "CP921", "ISO-8859-13" }, + { "CP923", "ISO-8859-15" }, + /*{ "CP941", "CP943" },*/ + /*{ "CP947", "CP950" },*/ + /*{ "CP951", "CP949" },*/ + /*{ "CP952", "JIS_X0208-1990" },*/ + /*{ "CP953", "JIS_X0212-1990" },*/ + { "CP954", "EUC-JP" }, + { "CP964", "EUC-TW" }, + { "CP970", "EUC-KR" }, + /*{ "CP971", "KS_C_5601-1987" },*/ + { "IBM-1004", "CP1252" }, + /*{ "IBM-1006", "?" },*/ + /*{ "IBM-1008", "?" },*/ + /*{ "IBM-1041", "CP943" },*/ + /*{ "IBM-1051", "?" },*/ + /*{ "IBM-1088", "CP949" },*/ + { "IBM-1089", "ISO-8859-6" }, + /*{ "IBM-1098", "?" },*/ + /*{ "IBM-1114", "CP950" },*/ + /*{ "IBM-1115", "GB2312" },*/ + /*{ "IBM-1116", "?" },*/ + /*{ "IBM-1117", "?" },*/ + /*{ "IBM-1118", "?" },*/ + /*{ "IBM-1119", "?" },*/ + { "IBM-1124", "CP1124" }, + { "IBM-1125", "CP1125" }, + { "IBM-1131", "CP1131" }, + { "IBM-1208", "UTF-8" }, + { "IBM-1250", "CP1250" }, + { "IBM-1251", "CP1251" }, + { "IBM-1252", "CP1252" }, + { "IBM-1253", "CP1253" }, + { "IBM-1254", "CP1254" }, + { "IBM-1255", "CP1255" }, + { "IBM-1256", "CP1256" }, + { "IBM-1257", "CP1257" }, + /*{ "IBM-1275", "?" },*/ + /*{ "IBM-1276", "?" },*/ + /*{ "IBM-1277", "?" },*/ + /*{ "IBM-1280", "?" },*/ + /*{ "IBM-1281", "?" },*/ + /*{ "IBM-1282", "?" },*/ + /*{ "IBM-1283", "?" },*/ + /*{ "IBM-1380", "GB2312" },*/ + { "IBM-1381", "GB2312" }, + { "IBM-1383", "GB2312" }, + { "IBM-1386", "GBK" }, + /*{ "IBM-301", "CP943" },*/ + { "IBM-3372", "EUC-JP" }, + { "IBM-367", "ASCII" }, + { "IBM-437", "CP437" }, + { "IBM-4946", "CP850" }, + /*{ "IBM-5048", "JIS_X0208-1990" },*/ + /*{ "IBM-5049", "JIS_X0212-1990" },*/ + /*{ "IBM-5067", "KS_C_5601-1987" },*/ + { "IBM-813", "ISO-8859-7" }, + { "IBM-819", "ISO-8859-1" }, + { "IBM-850", "CP850" }, + /*{ "IBM-851", "?" },*/ + { "IBM-852", "CP852" }, + { "IBM-855", "CP855" }, + { "IBM-856", "CP856" }, + { "IBM-857", "CP857" }, + /*{ "IBM-859", "?" },*/ + { "IBM-860", "CP860" }, + { "IBM-861", "CP861" }, + { "IBM-862", "CP862" }, + { "IBM-863", "CP863" }, + { "IBM-864", "CP864" }, + { "IBM-865", "CP865" }, + { "IBM-866", "CP866" }, + /*{ "IBM-868", "?" },*/ + { "IBM-869", "CP869" }, + { "IBM-874", "CP874" }, + { "IBM-878", "KOI8-R" }, + /*{ "IBM-895", "?" },*/ + /*{ "IBM-897", "CP943" },*/ + /*{ "IBM-907", "?" },*/ + /*{ "IBM-909", "?" },*/ + { "IBM-912", "ISO-8859-2" }, + { "IBM-913", "ISO-8859-3" }, + { "IBM-914", "ISO-8859-4" }, + { "IBM-915", "ISO-8859-5" }, + { "IBM-916", "ISO-8859-8" }, + { "IBM-920", "ISO-8859-9" }, + { "IBM-921", "ISO-8859-13" }, + { "IBM-922", "CP922" }, + { "IBM-923", "ISO-8859-15" }, + { "IBM-932", "CP932" }, + /*{ "IBM-941", "CP943" },*/ + /*{ "IBM-942", "?" },*/ + { "IBM-943", "CP943" }, + /*{ "IBM-947", "CP950" },*/ + { "IBM-949", "CP949" }, + { "IBM-950", "CP950" }, + /*{ "IBM-951", "CP949" },*/ + /*{ "IBM-952", "JIS_X0208-1990" },*/ + /*{ "IBM-953", "JIS_X0212-1990" },*/ + { "IBM-954", "EUC-JP" }, + /*{ "IBM-955", "?" },*/ + { "IBM-964", "EUC-TW" }, + { "IBM-970", "EUC-KR" }, + /*{ "IBM-971", "KS_C_5601-1987" },*/ + { "IBM-eucCN", "GB2312" }, + { "IBM-eucJP", "EUC-JP" }, + { "IBM-eucKR", "EUC-KR" }, + { "IBM-eucTW", "EUC-TW" }, + { "IBM33722", "EUC-JP" }, + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-3", "ISO-8859-3" }, + { "ISO8859-4", "ISO-8859-4" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-6", "ISO-8859-6" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-8", "ISO-8859-8" }, + { "ISO8859-9", "ISO-8859-9" }, + /*{ "JISX0201-1976", "JISX0201-1976" },*/ + /*{ "JISX0208-1978", "?" },*/ + /*{ "JISX0208-1983", "JIS_X0208-1983" },*/ + /*{ "JISX0208-1990", "JIS_X0208-1990" },*/ + /*{ "JISX0212-1990", "JIS_X0212-1990" },*/ + /*{ "KSC5601-1987", "KS_C_5601-1987" },*/ + { "SJIS-1", "CP943" }, + { "SJIS-2", "CP943" }, + { "eucJP", "EUC-JP" }, + { "eucKR", "EUC-KR" }, + { "eucTW-1993", "EUC-TW" } +# define alias_table_defined +# endif +# if defined VMS /* OpenVMS */ + /* The list of encodings is taken from the OpenVMS 7.3-1 documentation + "Compaq C Run-Time Library Reference Manual for OpenVMS systems" + section 10.7 "Handling Different Character Sets". */ + { "DECHANYU", "DEC-HANYU" }, + { "DECHANZI", "GB2312" }, + { "DECKANJI", "DEC-KANJI" }, + { "DECKOREAN", "EUC-KR" }, + { "ISO8859-1", "ISO-8859-1" }, + { "ISO8859-2", "ISO-8859-2" }, + { "ISO8859-5", "ISO-8859-5" }, + { "ISO8859-7", "ISO-8859-7" }, + { "ISO8859-8", "ISO-8859-8" }, + { "ISO8859-9", "ISO-8859-9" }, + { "SDECKANJI", "EUC-JP" }, + { "SJIS", "SHIFT_JIS" }, + { "eucJP", "EUC-JP" }, + { "eucTW", "EUC-TW" } +# define alias_table_defined +# endif +# ifndef alias_table_defined + /* Just a dummy entry, to avoid a C syntax error. */ + { "", "" } +# endif + }; - free (file_name); - } +# endif #else -# if defined DARWIN7 - /* To avoid the trouble of installing a file that is shared by many - GNU packages -- many packaging systems have problems with this --, - simply inline the aliases here. */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-4" "\0" "ISO-8859-4" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - "ISO8859-13" "\0" "ISO-8859-13" "\0" - "ISO8859-15" "\0" "ISO-8859-15" "\0" - "KOI8-R" "\0" "KOI8-R" "\0" - "KOI8-U" "\0" "KOI8-U" "\0" - "CP866" "\0" "CP866" "\0" - "CP949" "\0" "CP949" "\0" - "CP1131" "\0" "CP1131" "\0" - "CP1251" "\0" "CP1251" "\0" - "eucCN" "\0" "GB2312" "\0" - "GB2312" "\0" "GB2312" "\0" - "eucJP" "\0" "EUC-JP" "\0" - "eucKR" "\0" "EUC-KR" "\0" - "Big5" "\0" "BIG5" "\0" - "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" - "GBK" "\0" "GBK" "\0" - "GB18030" "\0" "GB18030" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "ARMSCII-8" "\0" "ARMSCII-8" "\0" - "PT154" "\0" "PT154" "\0" - /*"ISCII-DEV" "\0" "?" "\0"*/ - "*" "\0" "UTF-8" "\0"; -# endif +/* On these platforms, we use a mapping from locale name to GNU canonical + encoding name. */ -# if defined VMS - /* To avoid the troubles of an extra file charset.alias_vms in the - sources of many GNU packages, simply inline the aliases here. */ - /* The list of encodings is taken from the OpenVMS 7.3-1 documentation - "Compaq C Run-Time Library Reference Manual for OpenVMS systems" - section 10.7 "Handling Different Character Sets". */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-8" "\0" "ISO-8859-8" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - /* Japanese */ - "eucJP" "\0" "EUC-JP" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "DECKANJI" "\0" "DEC-KANJI" "\0" - "SDECKANJI" "\0" "EUC-JP" "\0" - /* Chinese */ - "eucTW" "\0" "EUC-TW" "\0" - "DECHANYU" "\0" "DEC-HANYU" "\0" - "DECHANZI" "\0" "GB2312" "\0" - /* Korean */ - "DECKOREAN" "\0" "EUC-KR" "\0"; +struct table_entry +{ + const char locale[17+1]; + const char canonical[11+1]; +}; + +/* Table of platform-dependent mappings, sorted in ascending order. */ +static const struct table_entry locale_table[] = + { +# if defined __FreeBSD__ /* FreeBSD 4.2 */ + { "cs_CZ.ISO_8859-2", "ISO-8859-2" }, + { "da_DK.DIS_8859-15", "ISO-8859-15" }, + { "da_DK.ISO_8859-1", "ISO-8859-1" }, + { "de_AT.DIS_8859-15", "ISO-8859-15" }, + { "de_AT.ISO_8859-1", "ISO-8859-1" }, + { "de_CH.DIS_8859-15", "ISO-8859-15" }, + { "de_CH.ISO_8859-1", "ISO-8859-1" }, + { "de_DE.DIS_8859-15", "ISO-8859-15" }, + { "de_DE.ISO_8859-1", "ISO-8859-1" }, + { "en_AU.DIS_8859-15", "ISO-8859-15" }, + { "en_AU.ISO_8859-1", "ISO-8859-1" }, + { "en_CA.DIS_8859-15", "ISO-8859-15" }, + { "en_CA.ISO_8859-1", "ISO-8859-1" }, + { "en_GB.DIS_8859-15", "ISO-8859-15" }, + { "en_GB.ISO_8859-1", "ISO-8859-1" }, + { "en_US.DIS_8859-15", "ISO-8859-15" }, + { "en_US.ISO_8859-1", "ISO-8859-1" }, + { "es_ES.DIS_8859-15", "ISO-8859-15" }, + { "es_ES.ISO_8859-1", "ISO-8859-1" }, + { "fi_FI.DIS_8859-15", "ISO-8859-15" }, + { "fi_FI.ISO_8859-1", "ISO-8859-1" }, + { "fr_BE.DIS_8859-15", "ISO-8859-15" }, + { "fr_BE.ISO_8859-1", "ISO-8859-1" }, + { "fr_CA.DIS_8859-15", "ISO-8859-15" }, + { "fr_CA.ISO_8859-1", "ISO-8859-1" }, + { "fr_CH.DIS_8859-15", "ISO-8859-15" }, + { "fr_CH.ISO_8859-1", "ISO-8859-1" }, + { "fr_FR.DIS_8859-15", "ISO-8859-15" }, + { "fr_FR.ISO_8859-1", "ISO-8859-1" }, + { "hr_HR.ISO_8859-2", "ISO-8859-2" }, + { "hu_HU.ISO_8859-2", "ISO-8859-2" }, + { "is_IS.DIS_8859-15", "ISO-8859-15" }, + { "is_IS.ISO_8859-1", "ISO-8859-1" }, + { "it_CH.DIS_8859-15", "ISO-8859-15" }, + { "it_CH.ISO_8859-1", "ISO-8859-1" }, + { "it_IT.DIS_8859-15", "ISO-8859-15" }, + { "it_IT.ISO_8859-1", "ISO-8859-1" }, + { "ja_JP.EUC", "EUC-JP" }, + { "ja_JP.SJIS", "SHIFT_JIS" }, + { "ja_JP.Shift_JIS", "SHIFT_JIS" }, + { "ko_KR.EUC", "EUC-KR" }, + { "la_LN.ASCII", "ASCII" }, + { "la_LN.DIS_8859-15", "ISO-8859-15" }, + { "la_LN.ISO_8859-1", "ISO-8859-1" }, + { "la_LN.ISO_8859-2", "ISO-8859-2" }, + { "la_LN.ISO_8859-4", "ISO-8859-4" }, + { "lt_LN.ASCII", "ASCII" }, + { "lt_LN.DIS_8859-15", "ISO-8859-15" }, + { "lt_LN.ISO_8859-1", "ISO-8859-1" }, + { "lt_LN.ISO_8859-2", "ISO-8859-2" }, + { "lt_LT.ISO_8859-4", "ISO-8859-4" }, + { "nl_BE.DIS_8859-15", "ISO-8859-15" }, + { "nl_BE.ISO_8859-1", "ISO-8859-1" }, + { "nl_NL.DIS_8859-15", "ISO-8859-15" }, + { "nl_NL.ISO_8859-1", "ISO-8859-1" }, + { "no_NO.DIS_8859-15", "ISO-8859-15" }, + { "no_NO.ISO_8859-1", "ISO-8859-1" }, + { "pl_PL.ISO_8859-2", "ISO-8859-2" }, + { "pt_PT.DIS_8859-15", "ISO-8859-15" }, + { "pt_PT.ISO_8859-1", "ISO-8859-1" }, + { "ru_RU.CP866", "CP866" }, + { "ru_RU.ISO_8859-5", "ISO-8859-5" }, + { "ru_RU.KOI8-R", "KOI8-R" }, + { "ru_SU.CP866", "CP866" }, + { "ru_SU.ISO_8859-5", "ISO-8859-5" }, + { "ru_SU.KOI8-R", "KOI8-R" }, + { "sl_SI.ISO_8859-2", "ISO-8859-2" }, + { "sv_SE.DIS_8859-15", "ISO-8859-15" }, + { "sv_SE.ISO_8859-1", "ISO-8859-1" }, + { "uk_UA.KOI8-U", "KOI8-U" }, + { "zh_CN.EUC", "GB2312" }, + { "zh_TW.BIG5", "BIG5" }, + { "zh_TW.Big5", "BIG5" } +# define locale_table_defined # endif - -# if defined WINDOWS_NATIVE || defined __CYGWIN__ - /* To avoid the troubles of installing a separate file in the same - directory as the DLL and of retrieving the DLL's directory at - runtime, simply inline the aliases here. */ - - cp = "CP936" "\0" "GBK" "\0" - "CP1361" "\0" "JOHAB" "\0" - "CP20127" "\0" "ASCII" "\0" - "CP20866" "\0" "KOI8-R" "\0" - "CP20936" "\0" "GB2312" "\0" - "CP21866" "\0" "KOI8-RU" "\0" - "CP28591" "\0" "ISO-8859-1" "\0" - "CP28592" "\0" "ISO-8859-2" "\0" - "CP28593" "\0" "ISO-8859-3" "\0" - "CP28594" "\0" "ISO-8859-4" "\0" - "CP28595" "\0" "ISO-8859-5" "\0" - "CP28596" "\0" "ISO-8859-6" "\0" - "CP28597" "\0" "ISO-8859-7" "\0" - "CP28598" "\0" "ISO-8859-8" "\0" - "CP28599" "\0" "ISO-8859-9" "\0" - "CP28605" "\0" "ISO-8859-15" "\0" - "CP38598" "\0" "ISO-8859-8" "\0" - "CP51932" "\0" "EUC-JP" "\0" - "CP51936" "\0" "GB2312" "\0" - "CP51949" "\0" "EUC-KR" "\0" - "CP51950" "\0" "EUC-TW" "\0" - "CP54936" "\0" "GB18030" "\0" - "CP65001" "\0" "UTF-8" "\0"; +# if defined __DJGPP__ /* DOS / DJGPP 2.03 */ + /* The encodings given here may not all be correct. + If you find that the encoding given for your language and + country is not the one your DOS machine actually uses, just + correct it in this file, and send a mail to + Juan Manuel Guerrero + and . */ + { "C", "ASCII" }, + { "ar", "CP864" }, + { "ar_AE", "CP864" }, + { "ar_DZ", "CP864" }, + { "ar_EG", "CP864" }, + { "ar_IQ", "CP864" }, + { "ar_IR", "CP864" }, + { "ar_JO", "CP864" }, + { "ar_KW", "CP864" }, + { "ar_MA", "CP864" }, + { "ar_OM", "CP864" }, + { "ar_QA", "CP864" }, + { "ar_SA", "CP864" }, + { "ar_SY", "CP864" }, + { "be", "CP866" }, + { "be_BE", "CP866" }, + { "bg", "CP866" }, /* not CP855 ?? */ + { "bg_BG", "CP866" }, /* not CP855 ?? */ + { "ca", "CP850" }, + { "ca_ES", "CP850" }, + { "cs", "CP852" }, + { "cs_CZ", "CP852" }, + { "da", "CP865" }, /* not CP850 ?? */ + { "da_DK", "CP865" }, /* not CP850 ?? */ + { "de", "CP850" }, + { "de_AT", "CP850" }, + { "de_CH", "CP850" }, + { "de_DE", "CP850" }, + { "el", "CP869" }, + { "el_GR", "CP869" }, + { "en", "CP850" }, + { "en_AU", "CP850" }, /* not CP437 ?? */ + { "en_CA", "CP850" }, + { "en_GB", "CP850" }, + { "en_NZ", "CP437" }, + { "en_US", "CP437" }, + { "en_ZA", "CP850" }, /* not CP437 ?? */ + { "eo", "CP850" }, + { "eo_EO", "CP850" }, + { "es", "CP850" }, + { "es_AR", "CP850" }, + { "es_BO", "CP850" }, + { "es_CL", "CP850" }, + { "es_CO", "CP850" }, + { "es_CR", "CP850" }, + { "es_CU", "CP850" }, + { "es_DO", "CP850" }, + { "es_EC", "CP850" }, + { "es_ES", "CP850" }, + { "es_GT", "CP850" }, + { "es_HN", "CP850" }, + { "es_MX", "CP850" }, + { "es_NI", "CP850" }, + { "es_PA", "CP850" }, + { "es_PE", "CP850" }, + { "es_PY", "CP850" }, + { "es_SV", "CP850" }, + { "es_UY", "CP850" }, + { "es_VE", "CP850" }, + { "et", "CP850" }, + { "et_EE", "CP850" }, + { "eu", "CP850" }, + { "eu_ES", "CP850" }, + { "fi", "CP850" }, + { "fi_FI", "CP850" }, + { "fr", "CP850" }, + { "fr_BE", "CP850" }, + { "fr_CA", "CP850" }, + { "fr_CH", "CP850" }, + { "fr_FR", "CP850" }, + { "ga", "CP850" }, + { "ga_IE", "CP850" }, + { "gd", "CP850" }, + { "gd_GB", "CP850" }, + { "gl", "CP850" }, + { "gl_ES", "CP850" }, + { "he", "CP862" }, + { "he_IL", "CP862" }, + { "hr", "CP852" }, + { "hr_HR", "CP852" }, + { "hu", "CP852" }, + { "hu_HU", "CP852" }, + { "id", "CP850" }, /* not CP437 ?? */ + { "id_ID", "CP850" }, /* not CP437 ?? */ + { "is", "CP861" }, /* not CP850 ?? */ + { "is_IS", "CP861" }, /* not CP850 ?? */ + { "it", "CP850" }, + { "it_CH", "CP850" }, + { "it_IT", "CP850" }, + { "ja", "CP932" }, + { "ja_JP", "CP932" }, + { "kr", "CP949" }, /* not CP934 ?? */ + { "kr_KR", "CP949" }, /* not CP934 ?? */ + { "lt", "CP775" }, + { "lt_LT", "CP775" }, + { "lv", "CP775" }, + { "lv_LV", "CP775" }, + { "mk", "CP866" }, /* not CP855 ?? */ + { "mk_MK", "CP866" }, /* not CP855 ?? */ + { "mt", "CP850" }, + { "mt_MT", "CP850" }, + { "nb", "CP865" }, /* not CP850 ?? */ + { "nb_NO", "CP865" }, /* not CP850 ?? */ + { "nl", "CP850" }, + { "nl_BE", "CP850" }, + { "nl_NL", "CP850" }, + { "nn", "CP865" }, /* not CP850 ?? */ + { "nn_NO", "CP865" }, /* not CP850 ?? */ + { "no", "CP865" }, /* not CP850 ?? */ + { "no_NO", "CP865" }, /* not CP850 ?? */ + { "pl", "CP852" }, + { "pl_PL", "CP852" }, + { "pt", "CP850" }, + { "pt_BR", "CP850" }, + { "pt_PT", "CP850" }, + { "ro", "CP852" }, + { "ro_RO", "CP852" }, + { "ru", "CP866" }, + { "ru_RU", "CP866" }, + { "sk", "CP852" }, + { "sk_SK", "CP852" }, + { "sl", "CP852" }, + { "sl_SI", "CP852" }, + { "sq", "CP852" }, + { "sq_AL", "CP852" }, + { "sr", "CP852" }, /* CP852 or CP866 or CP855 ?? */ + { "sr_CS", "CP852" }, /* CP852 or CP866 or CP855 ?? */ + { "sr_YU", "CP852" }, /* CP852 or CP866 or CP855 ?? */ + { "sv", "CP850" }, + { "sv_SE", "CP850" }, + { "th", "CP874" }, + { "th_TH", "CP874" }, + { "tr", "CP857" }, + { "tr_TR", "CP857" }, + { "uk", "CP1125" }, + { "uk_UA", "CP1125" }, + { "zh_CN", "GBK" }, + { "zh_TW", "CP950" } /* not CP938 ?? */ +# define locale_table_defined # endif -#endif +# ifndef locale_table_defined + /* Just a dummy entry, to avoid a C syntax error. */ + { "", "" } +# endif + }; - charset_aliases = cp; - } +#endif - return cp; -} /* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. + into one of the canonical names listed below. + The result must not be freed; it is statically allocated. The result + becomes invalid when setlocale() is used to change the global locale, or + when the value of one of the environment variables LC_ALL, LC_CTYPE, LANG + is changed; threads in multithreaded programs should not do this. If the canonical name cannot be determined, the result is a non-canonical name. */ @@ -362,9 +831,15 @@ const char * locale_charset (void) { const char *codeset; - const char *aliases; -#if !(defined WINDOWS_NATIVE || defined OS2) + /* This function must be multithread-safe. To achieve this without using + thread-local storage, we use a simple strcpy or memcpy to fill this static + buffer. Filling it through, for example, strcpy + strcat would not be + guaranteed to leave the buffer's contents intact if another thread is + currently accessing it. If necessary, the contents is first assembled in + a stack-allocated buffer. */ + +#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2 # if HAVE_LANGINFO_CODESET @@ -378,7 +853,7 @@ locale_charset (void) if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) { const char *locale; - static char buf[2 + 10 + 1]; + static char resultbuf[2 + 10 + 1]; locale = getenv ("LC_ALL"); if (locale == NULL || locale[0] == '\0') @@ -402,11 +877,12 @@ locale_charset (void) modifier = strchr (dot, '@'); if (modifier == NULL) return dot; - if (modifier - dot < sizeof (buf)) + if (modifier - dot < sizeof (resultbuf)) { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; + /* This way of filling resultbuf is multithread-safe. */ + memcpy (resultbuf, dot, modifier - dot); + resultbuf [modifier - dot] = '\0'; + return resultbuf; } } } @@ -422,62 +898,65 @@ locale_charset (void) converting to GetConsoleOutputCP(). This leads to correct results, except when SetConsoleOutputCP has been called and a raster font is in use. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - } -# endif - -# else - - /* On old systems which lack it, use setlocale or getenv. */ - const char *locale = NULL; + { + char buf[2 + 10 + 1]; - /* But most old systems don't have a complete set of locales. Some - (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't - use setlocale here; it would return "C" when it doesn't support the - locale name the user has set. */ -# if 0 - locale = setlocale (LC_CTYPE, NULL); -# endif - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } + sprintf (buf, "CP%u", GetACP ()); + strcpy (resultbuf, buf); + codeset = resultbuf; + } } +# endif - /* On some old systems, one used to set locale = "iso8859_1". On others, - you set it to "language_COUNTRY.charset". In any case, we resolve it - through the charset.alias file. */ - codeset = locale; + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; -# endif +# elif defined WINDOWS_NATIVE -#elif defined WINDOWS_NATIVE + char buf[2 + 10 + 1]; + static char resultbuf[2 + 10 + 1]; - static char buf[2 + 10 + 1]; + /* The Windows API has a function returning the locale's codepage as + a number, but the value doesn't change according to what the + 'setlocale' call specified. So we use it as a last resort, in + case the string returned by 'setlocale' doesn't specify the + codepage. */ + char *current_locale = setlocale (LC_CTYPE, NULL); + char *pdot = strrchr (current_locale, '.'); - /* The Windows API has a function returning the locale's codepage as a - number: GetACP(). - When the output goes to a console window, it needs to be provided in - GetOEMCP() encoding if the console is using a raster font, or in - GetConsoleOutputCP() encoding if it is using a TrueType font. - But in GUI programs and for output sent to files and pipes, GetACP() - encoding is the best bet. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; + if (pdot && 2 + strlen (pdot + 1) + 1 <= sizeof (buf)) + sprintf (buf, "CP%s", pdot + 1); + else + { + /* The Windows API has a function returning the locale's codepage as a + number: GetACP(). + When the output goes to a console window, it needs to be provided in + GetOEMCP() encoding if the console is using a raster font, or in + GetConsoleOutputCP() encoding if it is using a TrueType font. + But in GUI programs and for output sent to files and pipes, GetACP() + encoding is the best bet. */ + sprintf (buf, "CP%u", GetACP ()); + } + /* For a locale name such as "French_France.65001", in Windows 10, + setlocale now returns "French_France.utf8" instead. */ + if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0) + codeset = "UTF-8"; + else + { + strcpy (resultbuf, buf); + codeset = resultbuf; + } -#elif defined OS2 +# elif defined OS2 const char *locale; - static char buf[2 + 10 + 1]; + static char resultbuf[2 + 10 + 1]; ULONG cp[3]; ULONG cplen; + codeset = NULL; + /* Allow user to override the codeset, as set in the operating system, with standard language environment variables. */ locale = getenv ("LC_ALL"); @@ -501,51 +980,173 @@ locale_charset (void) modifier = strchr (dot, '@'); if (modifier == NULL) return dot; - if (modifier - dot < sizeof (buf)) + if (modifier - dot < sizeof (resultbuf)) { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; + /* This way of filling resultbuf is multithread-safe. */ + memcpy (resultbuf, dot, modifier - dot); + resultbuf [modifier - dot] = '\0'; + return resultbuf; } } - /* Resolve through the charset.alias file. */ - codeset = locale; + /* For the POSIX locale, don't use the system's codepage. */ + if (strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0) + codeset = ""; } - else + + if (codeset == NULL) { /* OS/2 has a function returning the locale's codepage as a number. */ if (DosQueryCp (sizeof (cp), cp, &cplen)) codeset = ""; else { + char buf[2 + 10 + 1]; + sprintf (buf, "CP%u", cp[0]); - codeset = buf; + strcpy (resultbuf, buf); + codeset = resultbuf; } } -#endif +# else - if (codeset == NULL) - /* The canonical name cannot be determined. */ - codeset = ""; +# error "Add code for other platforms here." + +# endif + + /* Resolve alias. */ + { +# ifdef alias_table_defined + /* On some platforms, UTF-8 locales are the most frequently used ones. + Speed up the common case and slow down the less common cases by + testing for this case first. */ +# if defined __OpenBSD__ || (defined __APPLE__ && defined __MACH__) || defined __sun || defined __CYGWIN__ + if (strcmp (codeset, "UTF-8") == 0) + goto done_table_lookup; + else +# endif + { + const struct table_entry * const table = alias_table; + size_t const table_size = + sizeof (alias_table) / sizeof (struct table_entry); + /* The table is sorted. Perform a binary search. */ + size_t hi = table_size; + size_t lo = 0; + while (lo < hi) + { + /* Invariant: + for i < lo, strcmp (table[i].alias, codeset) < 0, + for i >= hi, strcmp (table[i].alias, codeset) > 0. */ + size_t mid = (hi + lo) >> 1; /* >= lo, < hi */ + int cmp = strcmp (table[mid].alias, codeset); + if (cmp < 0) + lo = mid + 1; + else if (cmp > 0) + hi = mid; + else + { + /* Found an i with + strcmp (table[i].alias, codeset) == 0. */ + codeset = table[mid].canonical; + goto done_table_lookup; + } + } + } + if (0) + done_table_lookup: ; + else +# endif + { + /* Did not find it in the table. */ + /* On Mac OS X, all modern locales use the UTF-8 encoding. + BeOS and Haiku have a single locale, and it has UTF-8 encoding. */ +# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__ + codeset = "UTF-8"; +# else + /* Don't return an empty string. GNU libc and GNU libiconv interpret + the empty string as denoting "the locale's character encoding", + thus GNU libiconv would call this function a second time. */ + if (codeset[0] == '\0') + codeset = "ASCII"; +# endif + } + } + +#else - /* Resolve alias. */ - for (aliases = get_charset_aliases (); - *aliases != '\0'; - aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) - if (strcmp (codeset, aliases) == 0 - || (aliases[0] == '*' && aliases[1] == '\0')) + /* On old systems which lack it, use setlocale or getenv. */ + const char *locale = NULL; + + /* But most old systems don't have a complete set of locales. Some + (like DJGPP) have only the C locale. Therefore we don't use setlocale + here; it would return "C" when it doesn't support the locale name the + user has set. */ +# if 0 + locale = setlocale (LC_CTYPE, NULL); +# endif + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + if (locale == NULL) + locale = ""; + } + } + + /* Map locale name to canonical encoding name. */ + { +# ifdef locale_table_defined + const struct table_entry * const table = locale_table; + size_t const table_size = + sizeof (locale_table) / sizeof (struct table_entry); + /* The table is sorted. Perform a binary search. */ + size_t hi = table_size; + size_t lo = 0; + while (lo < hi) { - codeset = aliases + strlen (aliases) + 1; - break; + /* Invariant: + for i < lo, strcmp (table[i].locale, locale) < 0, + for i >= hi, strcmp (table[i].locale, locale) > 0. */ + size_t mid = (hi + lo) >> 1; /* >= lo, < hi */ + int cmp = strcmp (table[mid].locale, locale); + if (cmp < 0) + lo = mid + 1; + else if (cmp > 0) + hi = mid; + else + { + /* Found an i with + strcmp (table[i].locale, locale) == 0. */ + codeset = table[mid].canonical; + goto done_table_lookup; + } + } + if (0) + done_table_lookup: ; + else +# endif + { + /* Did not find it in the table. */ + /* On Mac OS X, all modern locales use the UTF-8 encoding. + BeOS and Haiku have a single locale, and it has UTF-8 encoding. */ +# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__ + codeset = "UTF-8"; +# else + /* The canonical name cannot be determined. */ + /* Don't return an empty string. GNU libc and GNU libiconv interpret + the empty string as denoting "the locale's character encoding", + thus GNU libiconv would call this function a second time. */ + codeset = "ASCII"; +# endif } + } - /* Don't return an empty string. GNU libc and GNU libiconv interpret - the empty string as denoting "the locale's character encoding", - thus GNU libiconv would call this function a second time. */ - if (codeset[0] == '\0') - codeset = "ASCII"; +#endif #ifdef DARWIN7 /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8" diff --git a/gl/localcharset.h b/gl/localcharset.h index c2098298..62efbf32 100644 --- a/gl/localcharset.h +++ b/gl/localcharset.h @@ -1,19 +1,19 @@ /* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2003, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2000-2003, 2009-2022 Free Software Foundation, Inc. This file is part of the GNU CHARSET Library. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _LOCALCHARSET_H #define _LOCALCHARSET_H @@ -25,12 +25,109 @@ extern "C" { /* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. + into one of the canonical names listed below. + The result must not be freed; it is statically allocated. The result + becomes invalid when setlocale() is used to change the global locale, or + when the value of one of the environment variables LC_ALL, LC_CTYPE, LANG + is changed; threads in multithreaded programs should not do this. If the canonical name cannot be determined, the result is a non-canonical name. */ extern const char * locale_charset (void); +/* About GNU canonical names for character encodings: + + Every canonical name must be supported by GNU libiconv. Support by GNU libc + is also desirable. + + The name is case insensitive. Usually an upper case MIME charset name is + preferred. + + The current list of these GNU canonical names is: + + name MIME? used by which systems + (darwin = Mac OS X, windows = native Windows) + + ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin minix cygwin + ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos + ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos + ISO-8859-3 Y glibc solaris cygwin + ISO-8859-4 Y hpux osf solaris freebsd netbsd openbsd darwin + ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos + ISO-8859-6 Y glibc aix hpux solaris cygwin + ISO-8859-7 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos + ISO-8859-8 Y glibc aix hpux osf solaris cygwin zos + ISO-8859-9 Y glibc aix hpux irix osf solaris freebsd darwin cygwin zos + ISO-8859-13 glibc hpux solaris freebsd netbsd openbsd darwin cygwin + ISO-8859-14 glibc cygwin + ISO-8859-15 glibc aix irix osf solaris freebsd netbsd openbsd darwin cygwin + KOI8-R Y glibc hpux solaris freebsd netbsd openbsd darwin + KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin + KOI8-T glibc + CP437 dos + CP775 dos + CP850 aix osf dos + CP852 dos + CP855 dos + CP856 aix + CP857 dos + CP861 dos + CP862 dos + CP864 dos + CP865 dos + CP866 freebsd netbsd openbsd darwin dos + CP869 dos + CP874 windows dos + CP922 aix + CP932 aix cygwin windows dos + CP943 aix zos + CP949 osf darwin windows dos + CP950 windows dos + CP1046 aix + CP1124 aix + CP1125 dos + CP1129 aix + CP1131 freebsd darwin + CP1250 windows + CP1251 glibc hpux solaris freebsd netbsd openbsd darwin cygwin windows + CP1252 aix windows + CP1253 windows + CP1254 windows + CP1255 glibc windows + CP1256 windows + CP1257 windows + GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin cygwin zos + EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin + EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin zos + EUC-TW glibc aix hpux irix osf solaris netbsd + BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin zos + BIG5-HKSCS glibc hpux solaris netbsd darwin + GBK glibc aix osf solaris freebsd darwin cygwin windows dos + GB18030 glibc hpux solaris freebsd netbsd darwin + SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin + JOHAB glibc solaris windows + TIS-620 glibc aix hpux osf solaris cygwin zos + VISCII Y glibc + TCVN5712-1 glibc + ARMSCII-8 glibc freebsd netbsd darwin + GEORGIAN-PS glibc cygwin + PT154 glibc netbsd cygwin + HP-ROMAN8 hpux + HP-ARABIC8 hpux + HP-GREEK8 hpux + HP-HEBREW8 hpux + HP-TURKISH8 hpux + HP-KANA8 hpux + DEC-KANJI osf + DEC-HANYU osf + UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin zos + + Note: Names which are not marked as being a MIME name should not be used in + Internet protocols for information interchange (mail, news, etc.). + + Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications + must understand both names and treat them as equivalent. + */ + #ifdef __cplusplus } diff --git a/gl/locale.in.h b/gl/locale.in.h index 264161a6..4aef74d4 100644 --- a/gl/locale.in.h +++ b/gl/locale.in.h @@ -1,28 +1,31 @@ /* A POSIX . - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ -#ifdef _GL_ALREADY_INCLUDING_LOCALE_H +#if (defined _WIN32 && !defined __CYGWIN__ && defined __need_locale_t) \ + || defined _GL_ALREADY_INCLUDING_LOCALE_H -/* Special invocation conventions to handle Solaris header files - (through Solaris 10) when combined with gettext's libintl.h. */ +/* Special invocation convention: + - Inside mingw header files, + - To handle Solaris header files (through Solaris 10) when combined + with gettext's libintl.h. */ #@INCLUDE_NEXT@ @NEXT_LOCALE_H@ @@ -61,6 +64,18 @@ # define LC_MESSAGES 1729 #endif +/* On native Windows with MSVC, 'struct lconv' lacks the members int_p_* and + int_n_*. Instead of overriding 'struct lconv', merely define these member + names as macros. This avoids trouble in C++ mode. */ +#if defined _MSC_VER +# define int_p_cs_precedes p_cs_precedes +# define int_p_sign_posn p_sign_posn +# define int_p_sep_by_space p_sep_by_space +# define int_n_cs_precedes n_cs_precedes +# define int_n_sign_posn n_sign_posn +# define int_n_sep_by_space n_sep_by_space +#endif + /* Bionic libc's 'struct lconv' is just a dummy. */ #if @REPLACE_STRUCT_LCONV@ # define lconv rpl_lconv @@ -69,7 +84,7 @@ struct lconv /* All 'char *' are actually 'const char *'. */ /* Members that depend on the LC_NUMERIC category of the locale. See - */ + */ /* Symbol used as decimal point. */ char *decimal_point; @@ -81,7 +96,7 @@ struct lconv char *grouping; /* Members that depend on the LC_MONETARY category of the locale. See - */ + */ /* Symbol used as decimal point. */ char *mon_decimal_point; @@ -153,7 +168,9 @@ _GL_CXXALIAS_RPL (localeconv, struct lconv *, (void)); # else _GL_CXXALIAS_SYS (localeconv, struct lconv *, (void)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (localeconv); +# endif #elif @REPLACE_STRUCT_LCONV@ # undef localeconv # define localeconv localeconv_used_without_requesting_gnulib_module_localeconv @@ -178,7 +195,9 @@ _GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale)); # else _GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (setlocale); +# endif #elif defined GNULIB_POSIXCHECK # undef setlocale # if HAVE_RAW_DECL_SETLOCALE @@ -187,11 +206,50 @@ _GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " # endif #endif -#if @GNULIB_DUPLOCALE@ +#if @GNULIB_SETLOCALE_NULL@ +/* Included here for convenience. */ +# include "setlocale_null.h" +#endif + +#if /*@GNULIB_NEWLOCALE@ ||*/ (@GNULIB_LOCALENAME@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_NEWLOCALE@) +# if @REPLACE_NEWLOCALE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef newlocale +# define newlocale rpl_newlocale +# define GNULIB_defined_newlocale 1 +# endif +_GL_FUNCDECL_RPL (newlocale, locale_t, + (int category_mask, const char *name, locale_t base) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (newlocale, locale_t, + (int category_mask, const char *name, locale_t base)); +# else +# if @HAVE_NEWLOCALE@ +_GL_CXXALIAS_SYS (newlocale, locale_t, + (int category_mask, const char *name, locale_t base)); +# endif +# endif +# if @HAVE_NEWLOCALE@ +_GL_CXXALIASWARN (newlocale); +# endif +# if @HAVE_NEWLOCALE@ || @REPLACE_NEWLOCALE@ +# ifndef HAVE_WORKING_NEWLOCALE +# define HAVE_WORKING_NEWLOCALE 1 +# endif +# endif +#elif defined GNULIB_POSIXCHECK +# undef newlocale +# if HAVE_RAW_DECL_NEWLOCALE +_GL_WARN_ON_USE (newlocale, "newlocale is not portable"); +# endif +#endif + +#if @GNULIB_DUPLOCALE@ || (@GNULIB_LOCALENAME@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_DUPLOCALE@) # if @REPLACE_DUPLOCALE@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef duplocale # define duplocale rpl_duplocale +# define GNULIB_defined_duplocale 1 # endif _GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale)); @@ -203,6 +261,11 @@ _GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale)); # if @HAVE_DUPLOCALE@ _GL_CXXALIASWARN (duplocale); # endif +# if @HAVE_DUPLOCALE@ || @REPLACE_DUPLOCALE@ +# ifndef HAVE_WORKING_DUPLOCALE +# define HAVE_WORKING_DUPLOCALE 1 +# endif +# endif #elif defined GNULIB_POSIXCHECK # undef duplocale # if HAVE_RAW_DECL_DUPLOCALE @@ -211,6 +274,32 @@ _GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - " # endif #endif +#if /*@GNULIB_FREELOCALE@ ||*/ (@GNULIB_LOCALENAME@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_FREELOCALE@) +# if @REPLACE_FREELOCALE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef freelocale +# define freelocale rpl_freelocale +# define GNULIB_defined_freelocale 1 +# endif +_GL_FUNCDECL_RPL (freelocale, void, (locale_t locale) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (freelocale, void, (locale_t locale)); +# else +# if @HAVE_FREELOCALE@ +/* Need to cast, because on FreeBSD and Mac OS X 10.13, the return type is + int. */ +_GL_CXXALIAS_SYS_CAST (freelocale, void, (locale_t locale)); +# endif +# endif +# if @HAVE_FREELOCALE@ +_GL_CXXALIASWARN (freelocale); +# endif +#elif defined GNULIB_POSIXCHECK +# undef freelocale +# if HAVE_RAW_DECL_FREELOCALE +_GL_WARN_ON_USE (freelocale, "freelocale is not portable"); +# endif +#endif + #endif /* _@GUARD_PREFIX@_LOCALE_H */ -#endif /* ! _GL_ALREADY_INCLUDING_LOCALE_H */ #endif /* _@GUARD_PREFIX@_LOCALE_H */ +#endif /* !(__need_locale_t || _GL_ALREADY_INCLUDING_LOCALE_H) */ diff --git a/gl/localeconv.c b/gl/localeconv.c index 7c7c77cf..ef261205 100644 --- a/gl/localeconv.c +++ b/gl/localeconv.c @@ -1,18 +1,18 @@ /* Query locale dependent information for formatting numbers. - Copyright (C) 2012-2013 Free Software Foundation, Inc. + Copyright (C) 2012-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/lseek.c b/gl/lseek.c new file mode 100644 index 00000000..1a9c49bd --- /dev/null +++ b/gl/lseek.c @@ -0,0 +1,89 @@ +/* An lseek() function that detects pipes. + Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Windows platforms. */ +/* Get GetFileType. */ +# include +/* Get _get_osfhandle. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif +#else +# include +#endif +#include + +#undef lseek + +off_t +rpl_lseek (int fd, off_t offset, int whence) +{ +#if defined _WIN32 && ! defined __CYGWIN__ + /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals. */ + HANDLE h = (HANDLE) _get_osfhandle (fd); + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + if (GetFileType (h) != FILE_TYPE_DISK) + { + errno = ESPIPE; + return -1; + } +#elif defined __APPLE__ && defined __MACH__ && defined SEEK_DATA + if (whence == SEEK_DATA) + { + /* If OFFSET points to data, macOS lseek+SEEK_DATA returns the + start S of the first data region that begins *after* OFFSET, + where the region from OFFSET to S consists of possibly-empty + data followed by a possibly-empty hole. To work around this + portability glitch, check whether OFFSET is within data by + using lseek+SEEK_HOLE, and if so return to OFFSET by using + lseek+SEEK_SET. Also, contrary to the macOS documentation, + lseek+SEEK_HOLE can fail with ENXIO if there are no holes on + or after OFFSET. What a mess! */ + off_t next_hole = lseek (fd, offset, SEEK_HOLE); + if (next_hole < 0) + return errno == ENXIO ? offset : next_hole; + if (next_hole != offset) + whence = SEEK_SET; + } +#else + /* BeOS lseek mistakenly succeeds on pipes... */ + struct stat statbuf; + if (fstat (fd, &statbuf) < 0) + return -1; + if (!S_ISREG (statbuf.st_mode)) + { + errno = ESPIPE; + return -1; + } +#endif +#if _GL_WINDOWS_64_BIT_OFF_T || (defined __MINGW32__ && defined _FILE_OFFSET_BITS && (_FILE_OFFSET_BITS == 64)) + return _lseeki64 (fd, offset, whence); +#else + return lseek (fd, offset, whence); +#endif +} diff --git a/gl/m4/00gnulib.m4 b/gl/m4/00gnulib.m4 index d4ad759f..dea34e83 100644 --- a/gl/m4/00gnulib.m4 +++ b/gl/m4/00gnulib.m4 @@ -1,27 +1,82 @@ -# 00gnulib.m4 serial 2 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. +# 00gnulib.m4 serial 8 +dnl Copyright (C) 2009-2022 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 This file must be named something that sorts before all other -dnl gnulib-provided .m4 files. It is needed until such time as we can -dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE semantics. +dnl gnulib-provided .m4 files. It is needed until the clang fix has +dnl been included in Autoconf. -# AC_DEFUN_ONCE([NAME], VALUE) -# ---------------------------- -# Define NAME to expand to VALUE on the first use (whether by direct -# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. -# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This -# definition is slower than the version in Autoconf 2.64, because it -# can only use interfaces that existed since 2.59; but it achieves the -# same effect. Quoting is necessary to avoid confusing Automake. -m4_version_prereq([2.63.263], [], -[m4_define([AC][_DEFUN_ONCE], - [AC][_DEFUN([$1], - [AC_REQUIRE([_gl_DEFUN_ONCE([$1])], - [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl -[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) +# The following definitions arrange to use a compiler option +# -Werror=implicit-function-declaration in AC_CHECK_DECL, when the +# compiler is clang. Without it, clang implicitly declares "known" +# library functions in C mode, but not in C++ mode, which would cause +# Gnulib to omit a declaration and thus later produce an error in C++ +# mode. As of clang 9.0, these "known" functions are identified through +# LIBBUILTIN invocations in the LLVM source file +# llvm/tools/clang/include/clang/Basic/Builtins.def. +# It's not possible to AC_REQUIRE the extra tests from AC_CHECK_DECL, +# because AC_CHECK_DECL, like other Autoconf built-ins, is not supposed +# to AC_REQUIRE anything: some configure.ac files have their first +# AC_CHECK_DECL executed conditionally. Therefore append the extra tests +# to AC_PROG_CC. +AC_DEFUN([gl_COMPILER_CLANG], +[ +dnl AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([whether the compiler is clang], + [gl_cv_compiler_clang], + [dnl Use _AC_COMPILE_IFELSE instead of AC_EGREP_CPP, to avoid error + dnl "circular dependency of AC_LANG_COMPILER(C)" if AC_PROG_CC has + dnl not yet been invoked. + _AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #ifdef __clang__ + barfbarf + #endif + ]],[[]]) + ], + [gl_cv_compiler_clang=no], + [gl_cv_compiler_clang=yes]) + ]) +]) +AC_DEFUN([gl_COMPILER_PREPARE_CHECK_DECL], +[ +dnl AC_REQUIRE([AC_PROG_CC]) +dnl AC_REQUIRE([gl_COMPILER_CLANG]) + AC_CACHE_CHECK([for compiler option needed when checking for declarations], + [gl_cv_compiler_check_decl_option], + [if test $gl_cv_compiler_clang = yes; then + dnl Test whether the compiler supports the option + dnl '-Werror=implicit-function-declaration'. + save_ac_compile="$ac_compile" + ac_compile="$ac_compile -Werror=implicit-function-declaration" + dnl Use _AC_COMPILE_IFELSE instead of AC_COMPILE_IFELSE, to avoid a + dnl warning "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". + _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[]])], + [gl_cv_compiler_check_decl_option='-Werror=implicit-function-declaration'], + [gl_cv_compiler_check_decl_option=none]) + ac_compile="$save_ac_compile" + else + gl_cv_compiler_check_decl_option=none + fi + ]) + if test "x$gl_cv_compiler_check_decl_option" != xnone; then + ac_compile_for_check_decl="$ac_compile $gl_cv_compiler_check_decl_option" + else + ac_compile_for_check_decl="$ac_compile" + fi +]) +dnl Redefine _AC_CHECK_DECL_BODY so that it references ac_compile_for_check_decl +dnl instead of ac_compile. If, for whatever reason, the override of AC_PROG_CC +dnl in zzgnulib.m4 is inactive, use the original ac_compile. +m4_define([_AC_CHECK_DECL_BODY], +[ ac_save_ac_compile="$ac_compile" + if test -n "$ac_compile_for_check_decl"; then + ac_compile="$ac_compile_for_check_decl" + fi] +m4_defn([_AC_CHECK_DECL_BODY])[ ac_compile="$ac_save_ac_compile" +]) # gl_00GNULIB # ----------- diff --git a/gl/m4/__inline.m4 b/gl/m4/__inline.m4 new file mode 100644 index 00000000..fbe2098e --- /dev/null +++ b/gl/m4/__inline.m4 @@ -0,0 +1,22 @@ +# Test for __inline keyword +dnl Copyright 2017-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl___INLINE], +[ + AC_CACHE_CHECK([whether the compiler supports the __inline keyword], + [gl_cv_c___inline], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[typedef int foo_t; + static __inline foo_t foo (void) { return 0; }]], + [[return foo ();]])], + [gl_cv_c___inline=yes], + [gl_cv_c___inline=no])]) + if test $gl_cv_c___inline = yes; then + AC_DEFINE([HAVE___INLINE], [1], + [Define to 1 if the compiler supports the keyword '__inline'.]) + fi +]) diff --git a/gl/m4/absolute-header.m4 b/gl/m4/absolute-header.m4 new file mode 100644 index 00000000..67d6507c --- /dev/null +++ b/gl/m4/absolute-header.m4 @@ -0,0 +1,100 @@ +# absolute-header.m4 serial 17 +dnl Copyright (C) 2006-2022 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 From Derek Price. + +# gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...) +# --------------------------------------- +# Find the absolute name of a header file, testing first if the header exists. +# If the header were sys/inttypes.h, this macro would define +# ABSOLUTE_SYS_INTTYPES_H to the '""' quoted absolute name of sys/inttypes.h +# in config.h +# (e.g. '#define ABSOLUTE_SYS_INTTYPES_H "///usr/include/sys/inttypes.h"'). +# The three "///" are to pacify Sun C 5.8, which otherwise would say +# "warning: #include of /usr/include/... may be non-portable". +# Use '""', not '<>', so that the /// cannot be confused with a C99 comment. +# Note: This macro assumes that the header file is not empty after +# preprocessing, i.e. it does not only define preprocessor macros but also +# provides some type/enum definitions or function/variable declarations. +AC_DEFUN([gl_ABSOLUTE_HEADER], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PREPROC_REQUIRE()dnl +m4_foreach_w([gl_HEADER_NAME], [$1], + [AS_VAR_PUSHDEF([gl_absolute_header], + [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl + AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>], + [gl_absolute_header], + [AS_VAR_PUSHDEF([ac_header_exists], + [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl + AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl + if test AS_VAR_GET([ac_header_exists]) = yes; then + gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME])) + fi + AS_VAR_POPDEF([ac_header_exists])dnl + ])dnl + AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])), + ["AS_VAR_GET([gl_absolute_header])"], + [Define this to an absolute name of <]m4_defn([gl_HEADER_NAME])[>.]) + AS_VAR_POPDEF([gl_absolute_header])dnl +])dnl +])# gl_ABSOLUTE_HEADER + +# gl_ABSOLUTE_HEADER_ONE(HEADER) +# ------------------------------ +# Like gl_ABSOLUTE_HEADER, except that: +# - it assumes that the header exists, +# - it uses the current CPPFLAGS, +# - it does not cache the result, +# - it is silent. +AC_DEFUN([gl_ABSOLUTE_HEADER_ONE], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote([$1])[[>]])]) + dnl AIX "xlc -E" and "cc -E" omit #line directives for header files + dnl that contain only a #include of other header files and no + dnl non-comment tokens of their own. This leads to a failure to + dnl detect the absolute name of , , + dnl and others. The workaround is to force preservation of comments + dnl through option -C. This ensures all necessary #line directives + dnl are present. GCC supports option -C as well. + case "$host_os" in + aix*) gl_absname_cpp="$ac_cpp -C" ;; + *) gl_absname_cpp="$ac_cpp" ;; + esac +changequote(,) + case "$host_os" in + mingw*) + dnl For the sake of native Windows compilers (excluding gcc), + dnl treat backslash as a directory separator, like /. + dnl Actually, these compilers use a double-backslash as + dnl directory separator, inside the + dnl # line "filename" + dnl directives. + gl_dirsep_regex='[/\\]' + ;; + *) + gl_dirsep_regex='\/' + ;; + esac + dnl A sed expression that turns a string into a basic regular + dnl expression, for use within "/.../". + gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' + gl_header_literal_regex=`echo '$1' \ + | sed -e "$gl_make_literal_regex_sed"` + gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ + s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ + s|^/[^/]|//&| + p + q + }' +changequote([,]) + dnl eval is necessary to expand gl_absname_cpp. + dnl Ultrix and Pyramid sh refuse to redirect output of eval, + dnl so use subshell. + AS_VAR_SET([gl_cv_absolute_]AS_TR_SH([[$1]]), +[`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | + sed -n "$gl_absolute_header_sed"`]) +]) diff --git a/gl/m4/af_alg.m4 b/gl/m4/af_alg.m4 new file mode 100644 index 00000000..9c7edf0f --- /dev/null +++ b/gl/m4/af_alg.m4 @@ -0,0 +1,57 @@ +# af_alg.m4 serial 6 +dnl Copyright 2018-2022 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 From Matteo Croce. + +AC_DEFUN_ONCE([gl_AF_ALG], +[ + AC_REQUIRE([gl_SYS_SOCKET_H]) + AC_REQUIRE([AC_C_INLINE]) + + dnl Check whether linux/if_alg.h has needed features. + AC_CACHE_CHECK([whether linux/if_alg.h has struct sockaddr_alg.], + [gl_cv_header_linux_if_alg_salg], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include + #include + struct sockaddr_alg salg = { + .salg_family = AF_ALG, + .salg_type = "hash", + .salg_name = "sha1", + };]])], + [gl_cv_header_linux_if_alg_salg=yes], + [gl_cv_header_linux_if_alg_salg=no])]) + if test "$gl_cv_header_linux_if_alg_salg" = yes; then + AC_DEFINE([HAVE_LINUX_IF_ALG_H], [1], + [Define to 1 if you have 'struct sockaddr_alg' defined.]) + fi + + dnl The default is to not use AF_ALG if available, + dnl as it's system dependent as to whether the kernel + dnl routines are faster than libcrypto for example. + use_af_alg=no + AC_ARG_WITH([linux-crypto], + [AS_HELP_STRING([[--with-linux-crypto]], + [use Linux kernel cryptographic API (if available) for the hash functions + MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 on files])], + [use_af_alg=$withval], + [use_af_alg=no]) + dnl We cannot use it if it is not available. + if test "$gl_cv_header_linux_if_alg_salg" != yes; then + if test "$use_af_alg" != no; then + AC_MSG_WARN([Linux kernel cryptographic API not found]) + fi + use_af_alg=no + fi + + if test "$use_af_alg" != no; then + USE_AF_ALG=1 + else + USE_AF_ALG=0 + fi + AC_DEFINE_UNQUOTED([USE_LINUX_CRYPTO_API], [$USE_AF_ALG], + [Define to 1 if you want to use the Linux kernel cryptographic API.]) +]) diff --git a/gl/m4/alloca.m4 b/gl/m4/alloca.m4 index 270abd0c..dc6f47e3 100644 --- a/gl/m4/alloca.m4 +++ b/gl/m4/alloca.m4 @@ -1,5 +1,5 @@ -# alloca.m4 serial 14 -dnl Copyright (C) 2002-2004, 2006-2007, 2009-2013 Free Software Foundation, +# alloca.m4 serial 21 +dnl Copyright (C) 2002-2004, 2006-2007, 2009-2022 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -26,30 +26,35 @@ AC_DEFUN([gl_FUNC_ALLOCA], AC_DEFINE([HAVE_ALLOCA], [1], [Define to 1 if you have 'alloca' after including , a header that may be supplied by this distribution.]) - ALLOCA_H=alloca.h + GL_GENERATE_ALLOCA_H=true else dnl alloca exists as a library function, i.e. it is slow and probably dnl a memory leak. Don't define HAVE_ALLOCA in this case. - ALLOCA_H= + GL_GENERATE_ALLOCA_H=false fi else - ALLOCA_H=alloca.h + GL_GENERATE_ALLOCA_H=true fi - AC_SUBST([ALLOCA_H]) - AM_CONDITIONAL([GL_GENERATE_ALLOCA_H], [test -n "$ALLOCA_H"]) + + if test $ac_cv_working_alloca_h = yes; then + HAVE_ALLOCA_H=1 + else + HAVE_ALLOCA_H=0 + fi + AC_SUBST([HAVE_ALLOCA_H]) ]) # Prerequisites of lib/alloca.c. # STACK_DIRECTION is already handled by AC_FUNC_ALLOCA. AC_DEFUN([gl_PREREQ_ALLOCA], [:]) -# This works around a bug in autoconf <= 2.68. -# See . +m4_version_prereq([2.70], [], [ -m4_version_prereq([2.69], [] ,[ - -# This is taken from the following Autoconf patch: -# http://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6cd9f12520b0d6f76d3230d7565feba1ecf29497 +# This works around a bug in autoconf <= 2.68 and has simplifications +# from 2.70. See: +# https://lists.gnu.org/r/bug-gnulib/2011-06/msg00277.html +# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6cd9f12520b0d6f76d3230d7565feba1ecf29497 +# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=15edf7fd8094fd14a89d9891dd72a9624762597a # _AC_LIBOBJ_ALLOCA # ----------------- @@ -65,26 +70,6 @@ AC_LIBSOURCES(alloca.c) AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext])dnl AC_DEFINE(C_ALLOCA, 1, [Define to 1 if using 'alloca.c'.]) -AC_CACHE_CHECK(whether 'alloca.c' needs Cray hooks, ac_cv_os_cray, -[AC_EGREP_CPP(webecray, -[#if defined CRAY && ! defined CRAY2 -webecray -#else -wenotbecray -#endif -], ac_cv_os_cray=yes, ac_cv_os_cray=no)]) -if test $ac_cv_os_cray = yes; then - for ac_func in _getb67 GETB67 getb67; do - AC_CHECK_FUNC($ac_func, - [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func, - [Define to one of '_getb67', 'GETB67', - 'getb67' for Cray-2 and Cray-YMP - systems. This function is required for - 'alloca.c' support on those systems.]) - break]) - done -fi - AC_CACHE_CHECK([stack direction for C alloca], [ac_cv_c_stack_direction], [AC_RUN_IFELSE([AC_LANG_SOURCE( @@ -115,7 +100,7 @@ AH_VERBATIM([STACK_DIRECTION], STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ -@%:@undef STACK_DIRECTION])dnl +#undef STACK_DIRECTION])dnl AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction) ])# _AC_LIBOBJ_ALLOCA ]) diff --git a/gl/m4/arpa_inet_h.m4 b/gl/m4/arpa_inet_h.m4 index ea69af57..057e13fc 100644 --- a/gl/m4/arpa_inet_h.m4 +++ b/gl/m4/arpa_inet_h.m4 @@ -1,15 +1,15 @@ -# arpa_inet_h.m4 serial 13 -dnl Copyright (C) 2006, 2008-2013 Free Software Foundation, Inc. +# arpa_inet_h.m4 serial 17 +dnl Copyright (C) 2006, 2008-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Written by Simon Josefsson and Bruno Haible -AC_DEFUN([gl_HEADER_ARPA_INET], +AC_DEFUN_ONCE([gl_ARPA_INET_H], [ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. + dnl Ensure to expand the default settings once only, before all statements + dnl that occur in other macros. AC_REQUIRE([gl_ARPA_INET_H_DEFAULTS]) AC_CHECK_HEADERS_ONCE([arpa/inet.h]) @@ -24,6 +24,8 @@ AC_DEFUN([gl_HEADER_ARPA_INET], AC_REQUIRE([gl_FEATURES_H]) + gl_PREREQ_SYS_H_WS2TCPIP + dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use. gl_WARN_ON_USE_PREPARE([[ @@ -38,17 +40,32 @@ AC_DEFUN([gl_HEADER_ARPA_INET], ]], [inet_ntop inet_pton]) ]) +# gl_ARPA_INET_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_ARPA_INET_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_ARPA_INET_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_ARPA_INET_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_ARPA_INET_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_ARPA_INET_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_INET_NTOP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_INET_PTON]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_ARPA_INET_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_ARPA_INET_H_DEFAULTS]) +]) + AC_DEFUN([gl_ARPA_INET_H_DEFAULTS], [ - GNULIB_INET_NTOP=0; AC_SUBST([GNULIB_INET_NTOP]) - GNULIB_INET_PTON=0; AC_SUBST([GNULIB_INET_PTON]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DECL_INET_NTOP=1; AC_SUBST([HAVE_DECL_INET_NTOP]) HAVE_DECL_INET_PTON=1; AC_SUBST([HAVE_DECL_INET_PTON]) diff --git a/gl/m4/base64.m4 b/gl/m4/base64.m4 index fc19893e..fed3398e 100644 --- a/gl/m4/base64.m4 +++ b/gl/m4/base64.m4 @@ -1,5 +1,5 @@ # base64.m4 serial 4 -dnl Copyright (C) 2004, 2006, 2009-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2004, 2006, 2009-2022 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. diff --git a/gl/m4/btowc.m4 b/gl/m4/btowc.m4 index 978a06e9..45a61f5e 100644 --- a/gl/m4/btowc.m4 +++ b/gl/m4/btowc.m4 @@ -1,5 +1,5 @@ -# btowc.m4 serial 10 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +# btowc.m4 serial 12 +dnl Copyright (C) 2008-2022 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. @@ -10,7 +10,7 @@ AC_DEFUN([gl_FUNC_BTOWC], dnl Check whether is usable at all, first. Otherwise the test dnl program below may lead to an endless loop. See - dnl . + dnl . AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) AC_CHECK_FUNCS_ONCE([btowc]) @@ -28,14 +28,6 @@ AC_DEFUN([gl_FUNC_BTOWC], [ AC_RUN_IFELSE( [AC_LANG_SOURCE([[ -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -50,6 +42,8 @@ changequote(,)dnl case "$host_os" in # Guess no on Cygwin. cygwin*) gl_cv_func_btowc_nul="guessing no" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_btowc_nul="guessing yes" ;; # Guess yes otherwise. *) gl_cv_func_btowc_nul="guessing yes" ;; esac @@ -65,24 +59,19 @@ changequote([,])dnl dnl is present. changequote(,)dnl case "$host_os" in - # Guess no on IRIX. - irix*) gl_cv_func_btowc_eof="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_btowc_eof="guessing yes" ;; + # Guess no on IRIX. + irix*) gl_cv_func_btowc_eof="guessing no" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_btowc_eof="guessing yes" ;; + # Guess yes otherwise. + *) gl_cv_func_btowc_eof="guessing yes" ;; esac changequote([,])dnl if test $LOCALE_FR != none; then AC_RUN_IFELSE( [AC_LANG_SOURCE([[ #include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include #include -#include #include int main () { diff --git a/gl/m4/builtin-expect.m4 b/gl/m4/builtin-expect.m4 new file mode 100644 index 00000000..b1fb12a3 --- /dev/null +++ b/gl/m4/builtin-expect.m4 @@ -0,0 +1,49 @@ +dnl Check for __builtin_expect. + +dnl Copyright 2016-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Paul Eggert. + +AC_DEFUN([gl___BUILTIN_EXPECT], +[ + AC_CACHE_CHECK([for __builtin_expect], + [gl_cv___builtin_expect], + [AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + int + main (int argc, char **argv) + { + argc = __builtin_expect (argc, 100); + return argv[argc != 100][0]; + }]])], + [gl_cv___builtin_expect=yes], + [AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + #include + int + main (int argc, char **argv) + { + argc = __builtin_expect (argc, 100); + return argv[argc != 100][0]; + }]])], + [gl_cv___builtin_expect="in "], + [gl_cv___builtin_expect=no])])]) + if test "$gl_cv___builtin_expect" = yes; then + AC_DEFINE([HAVE___BUILTIN_EXPECT], [1]) + elif test "$gl_cv___builtin_expect" = "in "; then + AC_DEFINE([HAVE___BUILTIN_EXPECT], [2]) + fi + AH_VERBATIM([HAVE___BUILTIN_EXPECT], + [/* Define to 1 if the compiler supports __builtin_expect, + and to 2 if does. */ +#undef HAVE___BUILTIN_EXPECT +#ifndef HAVE___BUILTIN_EXPECT +# define __builtin_expect(e, c) (e) +#elif HAVE___BUILTIN_EXPECT == 2 +# include +#endif + ]) +]) diff --git a/gl/m4/byteswap.m4 b/gl/m4/byteswap.m4 new file mode 100644 index 00000000..99aeb687 --- /dev/null +++ b/gl/m4/byteswap.m4 @@ -0,0 +1,17 @@ +# byteswap.m4 serial 5 +dnl Copyright (C) 2005, 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Oskar Liljeblad. + +AC_DEFUN([gl_BYTESWAP], +[ + dnl Prerequisites of lib/byteswap.in.h. + AC_CHECK_HEADERS([byteswap.h], [ + GL_GENERATE_BYTESWAP_H=false + ], [ + GL_GENERATE_BYTESWAP_H=true + ]) +]) diff --git a/gl/m4/calloc.m4 b/gl/m4/calloc.m4 new file mode 100644 index 00000000..c01520e5 --- /dev/null +++ b/gl/m4/calloc.m4 @@ -0,0 +1,83 @@ +# calloc.m4 serial 29 + +# Copyright (C) 2004-2022 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Written by Jim Meyering. + +# Determine whether calloc (N, S) returns non-NULL when N*S is zero, +# and returns NULL when N*S overflows. +# If so, define HAVE_CALLOC. Otherwise, define calloc to rpl_calloc +# and arrange to use a calloc wrapper function that does work in that case. + +# _AC_FUNC_CALLOC_IF([IF-WORKS], [IF-NOT]) +# ------------------------------------- +# If calloc is compatible with GNU calloc, run IF-WORKS, otherwise, IF-NOT. +AC_DEFUN([_AC_FUNC_CALLOC_IF], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether calloc (0, n) and calloc (n, 0) return nonnull], + [ac_cv_func_calloc_0_nonnull], + [if test $cross_compiling != yes; then + ac_cv_func_calloc_0_nonnull=yes + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT], + [[int result = 0; + char * volatile p = calloc (0, 0); + if (!p) + result |= 1; + free (p); + return result; + ]])], + [], + [ac_cv_func_calloc_0_nonnull=no]) + else + case "$host_os" in + # Guess yes on glibc systems. + *-gnu* | gnu*) ac_cv_func_calloc_0_nonnull="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) ac_cv_func_calloc_0_nonnull="guessing yes" ;; + # Guess yes on native Windows. + mingw*) ac_cv_func_calloc_0_nonnull="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) ac_cv_func_calloc_0_nonnull="$gl_cross_guess_normal" ;; + esac + fi + ]) + AS_CASE([$ac_cv_func_calloc_0_nonnull], [*yes], [$1], [$2]) +]) + + +# gl_FUNC_CALLOC_GNU +# ------------------ +# Replace calloc if it is not compatible with GNU libc. +AC_DEFUN([gl_FUNC_CALLOC_GNU], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_CALLOC_POSIX]) + REPLACE_CALLOC_FOR_CALLOC_GNU="$REPLACE_CALLOC_FOR_CALLOC_POSIX" + if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 0; then + _AC_FUNC_CALLOC_IF([], [REPLACE_CALLOC_FOR_CALLOC_GNU=1]) + fi +])# gl_FUNC_CALLOC_GNU + +# gl_FUNC_CALLOC_POSIX +# -------------------- +# Test whether 'calloc' is POSIX compliant (sets errno to ENOMEM when it +# fails, and doesn't mess up with ptrdiff_t or size_t overflow), +# and replace calloc if it is not. +AC_DEFUN([gl_FUNC_CALLOC_POSIX], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) + if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then + REPLACE_CALLOC_FOR_CALLOC_POSIX=1 + fi + dnl Although in theory we should also test for size_t overflow, + dnl in practice testing for ptrdiff_t overflow suffices + dnl since PTRDIFF_MAX <= SIZE_MAX on all known Gnulib porting targets. + dnl A separate size_t test would slow down 'configure'. +]) diff --git a/gl/m4/close.m4 b/gl/m4/close.m4 new file mode 100644 index 00000000..f95dbc9d --- /dev/null +++ b/gl/m4/close.m4 @@ -0,0 +1,35 @@ +# close.m4 serial 9 +dnl Copyright (C) 2008-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_CLOSE], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + m4_ifdef([gl_MSVC_INVAL], [ + AC_REQUIRE([gl_MSVC_INVAL]) + if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then + REPLACE_CLOSE=1 + fi + ]) + m4_ifdef([gl_PREREQ_SYS_H_WINSOCK2], [ + gl_PREREQ_SYS_H_WINSOCK2 + if test $UNISTD_H_HAVE_WINSOCK2_H = 1; then + dnl Even if the 'socket' module is not used here, another part of the + dnl application may use it and pass file descriptors that refer to + dnl sockets to the close() function. So enable the support for sockets. + REPLACE_CLOSE=1 + fi + ]) + dnl Replace close() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + if test $REPLACE_CLOSE = 0; then + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then + REPLACE_CLOSE=1 + fi + fi + ]) +]) diff --git a/gl/m4/codeset.m4 b/gl/m4/codeset.m4 index c2761be2..eb732601 100644 --- a/gl/m4/codeset.m4 +++ b/gl/m4/codeset.m4 @@ -1,5 +1,6 @@ # codeset.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2000-2002, 2006, 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2022 Free Software +dnl 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. diff --git a/gl/m4/configmake.m4 b/gl/m4/configmake.m4 deleted file mode 100644 index 823ffc0d..00000000 --- a/gl/m4/configmake.m4 +++ /dev/null @@ -1,50 +0,0 @@ -# configmake.m4 serial 1 -dnl Copyright (C) 2010-2013 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. - -# gl_CONFIGMAKE_PREP -# ------------------ -# Guarantee all of the standard directory variables, even when used with -# autoconf 2.59 (datarootdir wasn't supported until 2.59c) or automake -# 1.9.6 (pkglibexecdir wasn't supported until 1.10b.). -AC_DEFUN([gl_CONFIGMAKE_PREP], -[ - dnl Technically, datadir should default to datarootdir. But if - dnl autoconf is too old to provide datarootdir, then reversing the - dnl definition is a reasonable compromise. Only AC_SUBST a variable - dnl if it was not already defined earlier by autoconf. - if test "x$datarootdir" = x; then - AC_SUBST([datarootdir], ['${datadir}']) - fi - dnl Copy the approach used in autoconf 2.60. - if test "x$docdir" = x; then - AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], - ['${datarootdir}/doc/${PACKAGE_TARNAME}'], - ['${datarootdir}/doc/${PACKAGE}'])]) - fi - dnl The remaining variables missing from autoconf 2.59 are easier. - if test "x$htmldir" = x; then - AC_SUBST([htmldir], ['${docdir}']) - fi - if test "x$dvidir" = x; then - AC_SUBST([dvidir], ['${docdir}']) - fi - if test "x$pdfdir" = x; then - AC_SUBST([pdfdir], ['${docdir}']) - fi - if test "x$psdir" = x; then - AC_SUBST([psdir], ['${docdir}']) - fi - if test "x$lispdir" = x; then - AC_SUBST([lispdir], ['${datarootdir}/emacs/site-lisp']) - fi - if test "x$localedir" = x; then - AC_SUBST([localedir], ['${datarootdir}/locale']) - fi - - dnl Automake 1.9.6 only lacks pkglibexecdir; and since 1.11 merely - dnl provides it without AC_SUBST, this blind use of AC_SUBST is safe. - AC_SUBST([pkglibexecdir], ['${libexecdir}/${PACKAGE}']) -]) diff --git a/gl/m4/dirname.m4 b/gl/m4/dirname.m4 deleted file mode 100644 index 5897a2a8..00000000 --- a/gl/m4/dirname.m4 +++ /dev/null @@ -1,19 +0,0 @@ -#serial 10 -*- autoconf -*- -dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_DIRNAME], -[ - AC_REQUIRE([gl_DIRNAME_LGPL]) -]) - -AC_DEFUN([gl_DIRNAME_LGPL], -[ - dnl Prerequisites of lib/dirname.h. - AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) - - dnl No prerequisites of lib/basename-lgpl.c, lib/dirname-lgpl.c, - dnl lib/stripslash.c. -]) diff --git a/gl/m4/double-slash-root.m4 b/gl/m4/double-slash-root.m4 index bd6f8671..09ff5f0d 100644 --- a/gl/m4/double-slash-root.m4 +++ b/gl/m4/double-slash-root.m4 @@ -1,5 +1,5 @@ # double-slash-root.m4 serial 4 -*- Autoconf -*- -dnl Copyright (C) 2006, 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2006, 2008-2022 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. diff --git a/gl/m4/dup2.m4 b/gl/m4/dup2.m4 new file mode 100644 index 00000000..7e777cde --- /dev/null +++ b/gl/m4/dup2.m4 @@ -0,0 +1,105 @@ +#serial 27 +dnl Copyright (C) 2002, 2005, 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_DUP2], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM( + [[#include + #include + #include + #include + #include + ]GL_MDA_DEFINES[ + #ifndef RLIM_SAVED_CUR + # define RLIM_SAVED_CUR RLIM_INFINITY + #endif + #ifndef RLIM_SAVED_MAX + # define RLIM_SAVED_MAX RLIM_INFINITY + #endif + ]], + [[int result = 0; + int bad_fd = INT_MAX; + struct rlimit rlim; + if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX + && rlim.rlim_cur != RLIM_INFINITY + && rlim.rlim_cur != RLIM_SAVED_MAX + && rlim.rlim_cur != RLIM_SAVED_CUR) + bad_fd = rlim.rlim_cur; + #ifdef FD_CLOEXEC + if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1) + result |= 1; + #endif + if (dup2 (1, 1) != 1) + result |= 2; + #ifdef FD_CLOEXEC + if (fcntl (1, F_GETFD) != FD_CLOEXEC) + result |= 4; + #endif + close (0); + if (dup2 (0, 0) != -1) + result |= 8; + /* Many gnulib modules require POSIX conformance of EBADF. */ + if (dup2 (2, bad_fd) == -1 && errno != EBADF) + result |= 16; + /* Flush out some cygwin core dumps. */ + if (dup2 (2, -1) != -1 || errno != EBADF) + result |= 32; + dup2 (2, 255); + dup2 (2, 256); + /* On OS/2 kLIBC, dup2() does not work on a directory fd. */ + { + int fd = open (".", O_RDONLY); + if (fd == -1) + result |= 64; + else if (dup2 (fd, fd + 1) == -1) + result |= 128; + close (fd); + } + return result;]]) + ], + [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no], + [case "$host_os" in + mingw*) # on this platform, dup2 always returns 0 for success + gl_cv_func_dup2_works="guessing no" ;; + cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0 + gl_cv_func_dup2_works="guessing no" ;; + aix* | freebsd*) + # on AIX 7.1 and FreeBSD 6.1, dup2 (1,toobig) gives EMFILE, + # not EBADF. + gl_cv_func_dup2_works="guessing no" ;; + haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC. + gl_cv_func_dup2_works="guessing no" ;; + *-android*) # implemented using dup3(), which fails if oldfd == newfd + gl_cv_func_dup2_works="guessing no" ;; + os2*) # on OS/2 kLIBC, dup2() does not work on a directory fd. + gl_cv_func_dup2_works="guessing no" ;; + *) gl_cv_func_dup2_works="guessing yes" ;; + esac]) + ]) + case "$gl_cv_func_dup2_works" in + *yes) ;; + *) + REPLACE_DUP2=1 + AC_CHECK_FUNCS([setdtablesize]) + ;; + esac + dnl Replace dup2() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then + REPLACE_DUP2=1 + fi + ]) +]) + +# Prerequisites of lib/dup2.c. +AC_DEFUN([gl_PREREQ_DUP2], []) diff --git a/gl/m4/eealloc.m4 b/gl/m4/eealloc.m4 index c640ec12..a6aa2f88 100644 --- a/gl/m4/eealloc.m4 +++ b/gl/m4/eealloc.m4 @@ -1,5 +1,5 @@ # eealloc.m4 serial 3 -dnl Copyright (C) 2003, 2009-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2003, 2009-2022 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. diff --git a/gl/m4/environ.m4 b/gl/m4/environ.m4 index 593a33ed..583dac39 100644 --- a/gl/m4/environ.m4 +++ b/gl/m4/environ.m4 @@ -1,5 +1,5 @@ -# environ.m4 serial 6 -dnl Copyright (C) 2001-2004, 2006-2013 Free Software Foundation, Inc. +# environ.m4 serial 8 +dnl Copyright (C) 2001-2004, 2006-2022 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. @@ -29,16 +29,15 @@ AC_DEFUN_ONCE([gl_ENVIRON], AC_DEFUN([gt_CHECK_VAR_DECL], [ define([gt_cv_var], [gt_cv_var_]$2[_declaration]) - AC_MSG_CHECKING([if $2 is properly declared]) - AC_CACHE_VAL([gt_cv_var], [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[$1 - extern struct { int foo; } $2;]], - [[$2.foo = 1;]])], - [gt_cv_var=no], - [gt_cv_var=yes])]) - AC_MSG_RESULT([$gt_cv_var]) + AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[$1 + typedef struct { int foo; } foo_t; + extern foo_t $2;]], + [[$2.foo = 1;]])], + [gt_cv_var=no], + [gt_cv_var=yes])]) if test $gt_cv_var = yes; then AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1, [Define if you have the declaration of $2.]) diff --git a/gl/m4/errno_h.m4 b/gl/m4/errno_h.m4 index c813ea58..4be9780a 100644 --- a/gl/m4/errno_h.m4 +++ b/gl/m4/errno_h.m4 @@ -1,9 +1,11 @@ -# errno_h.m4 serial 12 -dnl Copyright (C) 2004, 2006, 2008-2013 Free Software Foundation, Inc. +# errno_h.m4 serial 14 +dnl Copyright (C) 2004, 2006, 2008-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. +AC_PREREQ([2.61]) + AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], [ AC_REQUIRE([AC_PROG_CC]) @@ -66,13 +68,11 @@ booboo [gl_cv_header_errno_h_complete=yes]) ]) if test $gl_cv_header_errno_h_complete = yes; then - ERRNO_H='' + GL_GENERATE_ERRNO_H=false else gl_NEXT_HEADERS([errno.h]) - ERRNO_H='errno.h' + GL_GENERATE_ERRNO_H=true fi - AC_SUBST([ERRNO_H]) - AM_CONDITIONAL([GL_GENERATE_ERRNO_H], [test -n "$ERRNO_H"]) gl_REPLACE_ERRNO_VALUE([EMULTIHOP]) gl_REPLACE_ERRNO_VALUE([ENOLINK]) gl_REPLACE_ERRNO_VALUE([EOVERFLOW]) @@ -86,7 +86,7 @@ booboo # Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE. AC_DEFUN([gl_REPLACE_ERRNO_VALUE], [ - if test -n "$ERRNO_H"; then + if $GL_GENERATE_ERRNO_H; then AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [ AC_EGREP_CPP([yes],[ #include @@ -129,9 +129,3 @@ yes AC_SUBST($1[_VALUE]) fi ]) - -dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. -dnl Remove this when we can assume autoconf >= 2.61. -m4_ifdef([AC_COMPUTE_INT], [], [ - AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) -]) diff --git a/gl/m4/error.m4 b/gl/m4/error.m4 index 29e6fdc9..7a103446 100644 --- a/gl/m4/error.m4 +++ b/gl/m4/error.m4 @@ -1,6 +1,6 @@ -#serial 14 +#serial 15 -# Copyright (C) 1996-1998, 2001-2004, 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-1998, 2001-2004, 2009-2022 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -22,6 +22,10 @@ AC_DEFUN([gl_ERROR], # Prerequisites of lib/error.c. AC_DEFUN([gl_PREREQ_ERROR], [ + dnl Use system extensions on Android, so that AC_FUNC_STRERROR_R + dnl discovers the GNU API for strerror_r on Android API level 23 and later. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_FUNC_STRERROR_R]) : ]) diff --git a/gl/m4/exponentd.m4 b/gl/m4/exponentd.m4 index 09df468c..83ac08bf 100644 --- a/gl/m4/exponentd.m4 +++ b/gl/m4/exponentd.m4 @@ -1,5 +1,5 @@ # exponentd.m4 serial 3 -dnl Copyright (C) 2007-2008, 2010-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2007-2008, 2010-2022 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. diff --git a/gl/m4/extensions.m4 b/gl/m4/extensions.m4 index e30f1220..0b3e4b5a 100644 --- a/gl/m4/extensions.m4 +++ b/gl/m4/extensions.m4 @@ -1,14 +1,19 @@ -# serial 13 -*- Autoconf -*- +# serial 22 -*- Autoconf -*- # Enable extensions on systems that normally disable them. -# Copyright (C) 2003, 2006-2013 Free Software Foundation, Inc. +# Copyright (C) 2003, 2006-2022 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +dnl Define to empty for the benefit of Autoconf 2.69 and earlier, so that +dnl AC_USE_SYSTEM_EXTENSIONS (below) can be used unchanged from Autoconf 2.70+. +m4_ifndef([AC_CHECK_INCLUDES_DEFAULT], + [AC_DEFUN([AC_CHECK_INCLUDES_DEFAULT], [])]) + # This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git # Autoconf. Perhaps we can remove this once we can assume Autoconf -# 2.70 or later everywhere, but since Autoconf mutates rapidly +# is recent-enough everywhere, but since Autoconf mutates rapidly # enough in this area it's likely we'll need to redefine # AC_USE_SYSTEM_EXTENSIONS for quite some time. @@ -26,67 +31,121 @@ # its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS # invocation occurs in gl_EARLY, not in gl_INIT. +m4_version_prereq([2.70.1], [], [ + # AC_USE_SYSTEM_EXTENSIONS # ------------------------ # Enable extensions on systems that normally disable them, # typically due to standards-conformance issues. -# -# Remember that #undef in AH_VERBATIM gets replaced with #define by -# AC_DEFINE. The goal here is to define all known feature-enabling -# macros, then, if reports of conflicts are made, disable macros that -# cause problems on some platforms (such as __EXTENSIONS__). +# We unconditionally define as many of the known feature-enabling +# as possible, reserving conditional behavior for macros that are +# known to cause problems on some platforms (such as __EXTENSIONS__). AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], -[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +[AC_BEFORE([$0], [AC_PREPROC_IFELSE])dnl +AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_LINK_IFELSE])dnl AC_BEFORE([$0], [AC_RUN_IFELSE])dnl - - AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) - if test "$MINIX" = yes; then - AC_DEFINE([_POSIX_SOURCE], [1], - [Define to 1 if you need to in order for 'stat' and other - things to work.]) - AC_DEFINE([_POSIX_1_SOURCE], [2], - [Define to 2 if the system does not provide POSIX.1 features - except with this defined.]) - AC_DEFINE([_MINIX], [1], - [Define to 1 if on MINIX.]) - AC_DEFINE([_NETBSD_SOURCE], [1], - [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) - fi - +AC_BEFORE([$0], [AC_CHECK_INCLUDES_DEFAULT])dnl +dnl #undef in AH_VERBATIM gets replaced with #define by AC_DEFINE. dnl Use a different key than __EXTENSIONS__, as that name broke existing dnl configure.ac when using autoheader 2.62. - AH_VERBATIM([USE_SYSTEM_EXTENSIONS], +dnl The macros below are in alphabetical order ignoring leading _ or __ +dnl prefixes. +AH_VERBATIM([USE_SYSTEM_EXTENSIONS], [/* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif -/* Enable general extensions on OS X. */ +/* Enable general extensions on macOS. */ #ifndef _DARWIN_C_SOURCE # undef _DARWIN_C_SOURCE #endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif -/* Enable threading extensions on Solaris. */ +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Identify the host operating system as Minix. + This macro does not affect the system headers' behavior. + A future release of Autoconf may stop defining this macro. */ +#ifndef _MINIX +# undef _MINIX +#endif +/* Enable general extensions on NetBSD. + Enable NetBSD compatibility extensions on Minix. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD compatibility extensions on NetBSD. + Oddly enough, this does nothing on OpenBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Define to 1 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_SOURCE +# undef _POSIX_SOURCE +#endif +/* Define to 2 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_1_SOURCE +# undef _POSIX_1_SOURCE +#endif +/* Enable POSIX-compatible threading on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif -/* Enable X/Open extensions if necessary. HP-UX 11.11 defines - mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of - whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +/* Enable X/Open extensions. Define to 500 only if necessary + to make mbstate_t available. */ #ifndef _XOPEN_SOURCE # undef _XOPEN_SOURCE #endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif -]) +])dnl + + AC_REQUIRE([AC_CHECK_INCLUDES_DEFAULT])dnl + _AC_CHECK_HEADER_ONCE([wchar.h]) + _AC_CHECK_HEADER_ONCE([minix/config.h]) + +dnl Defining __EXTENSIONS__ may break the system headers on some systems. +dnl (FIXME: Which ones?) AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], [ac_cv_safe_to_define___extensions__], [AC_COMPILE_IFELSE( @@ -95,30 +154,56 @@ dnl configure.ac when using autoheader 2.62. ]AC_INCLUDES_DEFAULT])], [ac_cv_safe_to_define___extensions__=yes], [ac_cv_safe_to_define___extensions__=no])]) - test $ac_cv_safe_to_define___extensions__ = yes && - AC_DEFINE([__EXTENSIONS__]) - AC_DEFINE([_ALL_SOURCE]) - AC_DEFINE([_DARWIN_C_SOURCE]) - AC_DEFINE([_GNU_SOURCE]) - AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) - AC_DEFINE([_TANDEM_SOURCE]) + +dnl HP-UX 11.11 defines mbstate_t only if _XOPEN_SOURCE is defined to +dnl 500, regardless of whether compiling with -Ae or -D_HPUX_SOURCE=1. +dnl But defining _XOPEN_SOURCE may turn *off* extensions on platforms +dnl not covered by turn-on-extensions macros (notably Dragonfly, Free, +dnl and OpenBSD, which don't have any equivalent of _NETBSD_SOURCE) so +dnl it should only be defined when necessary. AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], [ac_cv_should_define__xopen_source], [ac_cv_should_define__xopen_source=no - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ + AS_IF([test $ac_cv_header_wchar_h = yes], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ #include mbstate_t x;]])], - [], - [AC_COMPILE_IFELSE( + [], + [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ - #define _XOPEN_SOURCE 500 - #include - mbstate_t x;]])], - [ac_cv_should_define__xopen_source=yes])])]) - test $ac_cv_should_define__xopen_source = yes && - AC_DEFINE([_XOPEN_SOURCE], [500]) + #define _XOPEN_SOURCE 500 + #include + mbstate_t x;]])], + [ac_cv_should_define__xopen_source=yes])])])]) + + AC_DEFINE([_ALL_SOURCE]) + AC_DEFINE([_DARWIN_C_SOURCE]) + AC_DEFINE([_GNU_SOURCE]) + AC_DEFINE([_HPUX_ALT_XOPEN_SOCKET_API]) + AC_DEFINE([_NETBSD_SOURCE]) + AC_DEFINE([_OPENBSD_SOURCE]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([__STDC_WANT_IEC_60559_ATTRIBS_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_BFP_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_DFP_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_FUNCS_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_TYPES_EXT__]) + AC_DEFINE([__STDC_WANT_LIB_EXT2__]) + AC_DEFINE([__STDC_WANT_MATH_SPEC_FUNCS__]) + AC_DEFINE([_TANDEM_SOURCE]) + AS_IF([test $ac_cv_header_minix_config_h = yes], + [MINIX=yes + AC_DEFINE([_MINIX]) + AC_DEFINE([_POSIX_SOURCE]) + AC_DEFINE([_POSIX_1_SOURCE], [2])], + [MINIX=]) + AS_IF([test $ac_cv_safe_to_define___extensions__ = yes], + [AC_DEFINE([__EXTENSIONS__])]) + AS_IF([test $ac_cv_should_define__xopen_source = yes], + [AC_DEFINE([_XOPEN_SOURCE], [500])]) ])# AC_USE_SYSTEM_EXTENSIONS +]) # gl_USE_SYSTEM_EXTENSIONS # ------------------------ @@ -126,13 +211,17 @@ dnl configure.ac when using autoheader 2.62. # typically due to standards-conformance issues. AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], [ - dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. - dnl gnulib does not need it. But if it gets required by third-party macros - dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a - dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". - dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, - dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. - AC_REQUIRE([AC_GNU_SOURCE]) - 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 ]) diff --git a/gl/m4/extern-inline.m4 b/gl/m4/extern-inline.m4 index c4c5e7f2..8a12bddd 100644 --- a/gl/m4/extern-inline.m4 +++ b/gl/m4/extern-inline.m4 @@ -1,61 +1,121 @@ dnl 'extern inline' a la ISO C99. -dnl Copyright 2012-2013 Free Software Foundation, Inc. +dnl Copyright 2012-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_EXTERN_INLINE], [ - AH_VERBATIM([extern_inline], + AC_CACHE_CHECK([whether ctype.h defines __header_inline], + [gl_cv_have___header_inline], + [AC_PREPROC_IFELSE( + [AC_LANG_SOURCE([[#include + #ifndef __header_inline + #error " does not define __header_inline" + #endif + ]])], + [gl_cv_have___header_inline=yes], + [gl_cv_have___header_inline=no])]) + if test "$gl_cv_have___header_inline" = yes; then + AC_DEFINE([HAVE___HEADER_INLINE], [1], + [Define to 1 if ctype.h defines __header_inline.]) + fi + + AH_VERBATIM([HAVE___HEADER_INLINE_1], [/* Please see the Gnulib manual for how to use these macros. Suppress extern inline with HP-UX cc, as it appears to be broken; see - . + . Suppress extern inline with Sun C in standards-conformance mode, as it mishandles inline functions that call each other. E.g., for 'inline void f (void) { } inline void g (void) { f (); }', c99 incorrectly complains 'reference to static identifier "f" in extern inline function'. - This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16. + This bug was observed with Oracle Developer Studio 12.6 + (Sun C 5.15 SunOS_sparc 2017/05/30). + + Suppress extern inline (with or without __attribute__ ((__gnu_inline__))) + on configurations that mistakenly use 'static inline' to implement + functions or macros in standard C headers like . For example, + if isdigit is mistakenly implemented via a static inline function, + a program containing an extern inline function that calls isdigit + may not work since the C standard prohibits extern inline functions + from calling static functions (ISO C 99 section 6.7.4.(3). + This bug is known to occur on: + + OS X 10.8 and earlier; see: + https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html + + DragonFly; see + http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log - Suppress the use of extern inline on Apple's platforms, as Libc at least - through Libc-825.26 (2013-04-09) is incompatible with it; see, e.g., - . - Perhaps Apple will fix this some day. */ + FreeBSD; see: + https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html + + OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and + for clang but remains for g++; see . + Assume DragonFly and FreeBSD will be similar. + + GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. It defines a macro + __GNUC_STDC_INLINE__ to indicate this situation or a macro + __GNUC_GNU_INLINE__ to indicate the opposite situation. + GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline + semantics but warns, unless -fgnu89-inline is used: + warning: C99 inline functions are not supported; using GNU89 + warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute + It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. + */ +#if (((defined __APPLE__ && defined __MACH__) \ + || defined __DragonFly__ || defined __FreeBSD__) \ + && (defined HAVE___HEADER_INLINE \ + ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \ + && ! defined __clang__) \ + : ((! defined _DONT_USE_CTYPE_INLINE_ \ + && (defined __GNUC__ || defined __cplusplus)) \ + || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \ + && defined __GNUC__ && ! defined __cplusplus)))) +# define _GL_EXTERN_INLINE_STDHEADER_BUG +#endif #if ((__GNUC__ \ ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ : (199901L <= __STDC_VERSION__ \ && !defined __HP_cc \ + && !defined __PGI \ && !(defined __SUNPRO_C && __STDC__))) \ - && !defined __APPLE__) + && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) # define _GL_INLINE inline # define _GL_EXTERN_INLINE extern inline +# define _GL_EXTERN_INLINE_IN_USE #elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \ - && !defined __APPLE__) -# if __GNUC_GNU_INLINE__ + && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) +# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__ /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ # define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) # else # define _GL_INLINE extern inline # endif # define _GL_EXTERN_INLINE extern +# define _GL_EXTERN_INLINE_IN_USE #else -# define _GL_INLINE static _GL_UNUSED -# define _GL_EXTERN_INLINE static _GL_UNUSED +# define _GL_INLINE _GL_UNUSED static +# define _GL_EXTERN_INLINE _GL_UNUSED static #endif -#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +/* In GCC 4.6 (inclusive) to 5.1 (exclusive), + suppress bogus "no previous prototype for 'FOO'" + and "no previous declaration for 'FOO'" diagnostics, + when FOO is an inline function in the header; see + and + . */ +#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__ # if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ # define _GL_INLINE_HEADER_CONST_PRAGMA # else # define _GL_INLINE_HEADER_CONST_PRAGMA \ _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") # endif - /* Suppress GCC's bogus "no previous prototype for 'FOO'" - and "no previous declaration for 'FOO'" diagnostics, - when FOO is an inline function in the header; see - . */ # define _GL_INLINE_HEADER_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ diff --git a/gl/m4/fcntl-o.m4 b/gl/m4/fcntl-o.m4 index 87cc4bd2..4dcde9e0 100644 --- a/gl/m4/fcntl-o.m4 +++ b/gl/m4/fcntl-o.m4 @@ -1,23 +1,22 @@ -# fcntl-o.m4 serial 4 -dnl Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. +# fcntl-o.m4 serial 7 +dnl Copyright (C) 2006, 2009-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Written by Paul Eggert. +AC_PREREQ([2.60]) + # Test whether the flags O_NOATIME and O_NOFOLLOW actually work. # Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. # Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. AC_DEFUN([gl_FCNTL_O_FLAGS], [ dnl Persuade glibc to define O_NOATIME and O_NOFOLLOW. - dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes - dnl AC_GNU_SOURCE. - m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], - [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], - [AC_REQUIRE([AC_GNU_SOURCE])]) + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_CHECK_HEADERS_ONCE([unistd.h]) AC_CHECK_FUNCS_ONCE([symlink]) AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h], @@ -33,6 +32,7 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], # defined sleep(n) _sleep ((n) * 1000) #endif #include + ]GL_MDA_DEFINES[ #ifndef O_NOATIME #define O_NOATIME 0 #endif @@ -116,7 +116,13 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( *) gl_cv_header_working_fcntl_h='no';; esac], - [gl_cv_header_working_fcntl_h=cross-compiling])]) + [case "$host_os" in + # Guess 'no' on native Windows. + mingw*) gl_cv_header_working_fcntl_h='no' ;; + *) gl_cv_header_working_fcntl_h=cross-compiling ;; + esac + ]) + ]) case $gl_cv_header_working_fcntl_h in #( *O_NOATIME* | no | cross-compiling) ac_val=0;; #( diff --git a/gl/m4/fcntl.m4 b/gl/m4/fcntl.m4 new file mode 100644 index 00000000..428e5709 --- /dev/null +++ b/gl/m4/fcntl.m4 @@ -0,0 +1,151 @@ +# fcntl.m4 serial 11 +dnl Copyright (C) 2009-2022 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. + +# For now, this module ensures that fcntl() +# - supports F_DUPFD correctly +# - supports or emulates F_DUPFD_CLOEXEC +# - supports F_GETFD +# Still to be ported to mingw: +# - F_SETFD +# - F_GETFL, F_SETFL +# - F_GETOWN, F_SETOWN +# - F_GETLK, F_SETLK, F_SETLKW +AC_DEFUN([gl_FUNC_FCNTL], +[ + dnl Persuade glibc to expose F_DUPFD_CLOEXEC. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS_ONCE([fcntl]) + if test $ac_cv_func_fcntl = no; then + gl_REPLACE_FCNTL + else + dnl cygwin 1.5.x F_DUPFD has wrong errno, and allows negative target + dnl haiku alpha 2 F_DUPFD has wrong errno + AC_CACHE_CHECK([whether fcntl handles F_DUPFD correctly], + [gl_cv_func_fcntl_f_dupfd_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + #include + #include + #include + ]GL_MDA_DEFINES[ + #ifndef RLIM_SAVED_CUR + # define RLIM_SAVED_CUR RLIM_INFINITY + #endif + #ifndef RLIM_SAVED_MAX + # define RLIM_SAVED_MAX RLIM_INFINITY + #endif + ]], + [[int result = 0; + int bad_fd = INT_MAX; + struct rlimit rlim; + if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 + && 0 <= rlim.rlim_cur && rlim.rlim_cur <= INT_MAX + && rlim.rlim_cur != RLIM_INFINITY + && rlim.rlim_cur != RLIM_SAVED_MAX + && rlim.rlim_cur != RLIM_SAVED_CUR) + bad_fd = rlim.rlim_cur; + if (fcntl (0, F_DUPFD, -1) != -1) result |= 1; + if (errno != EINVAL) result |= 2; + if (fcntl (0, F_DUPFD, bad_fd) != -1) result |= 4; + if (errno != EINVAL) result |= 8; + /* On OS/2 kLIBC, F_DUPFD does not work on a directory fd */ + { + int fd; + fd = open (".", O_RDONLY); + if (fd == -1) + result |= 16; + else if (fcntl (fd, F_DUPFD, STDERR_FILENO + 1) == -1) + result |= 32; + + close (fd); + } + return result;]])], + [gl_cv_func_fcntl_f_dupfd_works=yes], + [gl_cv_func_fcntl_f_dupfd_works=no], + [case $host_os in + aix* | cygwin* | haiku*) + gl_cv_func_fcntl_f_dupfd_works="guessing no" ;; + *) gl_cv_func_fcntl_f_dupfd_works="guessing yes" ;; + esac])]) + case $gl_cv_func_fcntl_f_dupfd_works in + *yes) ;; + *) gl_REPLACE_FCNTL + AC_DEFINE([FCNTL_DUPFD_BUGGY], [1], [Define this to 1 if F_DUPFD + behavior does not match POSIX]) ;; + esac + + dnl Many systems lack F_DUPFD_CLOEXEC. + dnl NetBSD 9.0 declares F_DUPFD_CLOEXEC but it works only like F_DUPFD. + AC_CACHE_CHECK([whether fcntl understands F_DUPFD_CLOEXEC], + [gl_cv_func_fcntl_f_dupfd_cloexec], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE( + [[#include + #include + int main (int argc, char *argv[]) + { + if (argc == 1) + /* parent process */ + { + if (fcntl (1, F_DUPFD_CLOEXEC, 10) < 0) + return 1; + return execl ("./conftest", "./conftest", "child", NULL); + } + else + /* child process */ + return (fcntl (10, F_GETFL) < 0 ? 0 : 42); + } + ]]) + ], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef __linux__ +/* The Linux kernel only added F_DUPFD_CLOEXEC in 2.6.24, so we always replace + it to support the semantics on older kernels that failed with EINVAL. */ +choke me +#endif + ]])], + [gl_cv_func_fcntl_f_dupfd_cloexec=yes], + [gl_cv_func_fcntl_f_dupfd_cloexec="needs runtime check"]) + ], + [gl_cv_func_fcntl_f_dupfd_cloexec=no], + [case "$host_os" in + # Guess no on NetBSD. + netbsd*) gl_cv_func_fcntl_f_dupfd_cloexec="guessing no" ;; + *) gl_cv_func_fcntl_f_dupfd_cloexec="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_fcntl_f_dupfd_cloexec" in + *yes) ;; + *) gl_REPLACE_FCNTL + dnl No witness macro needed for this bug. + ;; + esac + fi + dnl Replace fcntl() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then + gl_REPLACE_FCNTL + fi + ]) +]) + +AC_DEFUN([gl_REPLACE_FCNTL], +[ + AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([fcntl]) + if test $ac_cv_func_fcntl = no; then + HAVE_FCNTL=0 + else + REPLACE_FCNTL=1 + fi +]) diff --git a/gl/m4/fcntl_h.m4 b/gl/m4/fcntl_h.m4 new file mode 100644 index 00000000..267f98bf --- /dev/null +++ b/gl/m4/fcntl_h.m4 @@ -0,0 +1,70 @@ +# serial 20 +# Configure fcntl.h. +dnl Copyright (C) 2006-2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Paul Eggert. + +AC_DEFUN_ONCE([gl_FCNTL_H], +[ + AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) + AC_REQUIRE([gl_FCNTL_O_FLAGS]) + gl_NEXT_HEADERS([fcntl.h]) + + dnl Ensure the type pid_t gets defined. + AC_REQUIRE([AC_TYPE_PID_T]) + + dnl Ensure the type mode_t gets defined. + AC_REQUIRE([AC_TYPE_MODE_T]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, if it is not common + dnl enough to be declared everywhere. + gl_WARN_ON_USE_PREPARE([[#include + ]], [fcntl openat]) +]) + +# gl_FCNTL_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. +AC_DEFUN([gl_FCNTL_MODULE_INDICATOR], +[ + dnl Ensure to expand the default settings once only. + gl_FCNTL_H_REQUIRE_DEFAULTS + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_FCNTL_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CREAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCNTL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NONBLOCKING]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CREAT], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_OPEN], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_FCNTL_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_FCNTL_H_DEFAULTS]) +]) + +AC_DEFUN([gl_FCNTL_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL]) + HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) + REPLACE_CREAT=0; AC_SUBST([REPLACE_CREAT]) + REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL]) + REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN]) + REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT]) +]) diff --git a/gl/m4/fflush.m4 b/gl/m4/fflush.m4 new file mode 100644 index 00000000..e36f90ee --- /dev/null +++ b/gl/m4/fflush.m4 @@ -0,0 +1,100 @@ +# fflush.m4 serial 18 + +# Copyright (C) 2007-2022 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +dnl From Eric Blake + +dnl Find out how to obey POSIX semantics of fflush(stdin) discarding +dnl unread input on seekable streams, rather than C99 undefined semantics. + +AC_DEFUN([gl_FUNC_FFLUSH], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + gl_FUNC_FFLUSH_STDIN + case "$gl_cv_func_fflush_stdin" in + *yes) ;; + *) REPLACE_FFLUSH=1 ;; + esac +]) + +dnl Determine whether fflush works on input streams. +dnl Sets gl_cv_func_fflush_stdin. + +AC_DEFUN([gl_FUNC_FFLUSH_STDIN], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CHECK_HEADERS_ONCE([unistd.h]) + AC_CACHE_CHECK([whether fflush works on input streams], + [gl_cv_func_fflush_stdin], + [echo hello world > conftest.txt + AC_RUN_IFELSE([AC_LANG_PROGRAM( + [[ +#include +#if HAVE_UNISTD_H +# include +#else /* on Windows with MSVC */ +# include +#endif + ]GL_MDA_DEFINES], + [[FILE *f = fopen ("conftest.txt", "r"); + char buffer[10]; + int fd; + int c; + if (f == NULL) + return 1; + fd = fileno (f); + if (fd < 0 || fread (buffer, 1, 5, f) != 5) + { fclose (f); return 2; } + /* For deterministic results, ensure f read a bigger buffer. */ + if (lseek (fd, 0, SEEK_CUR) == 5) + { fclose (f); return 3; } + /* POSIX requires fflush-fseek to set file offset of fd. This fails + on BSD systems and on mingw. */ + if (fflush (f) != 0 || fseek (f, 0, SEEK_CUR) != 0) + { fclose (f); return 4; } + if (lseek (fd, 0, SEEK_CUR) != 5) + { fclose (f); return 5; } + /* Verify behaviour of fflush after ungetc. See + */ + /* Verify behaviour of fflush after a backup ungetc. This fails on + mingw. */ + c = fgetc (f); + ungetc (c, f); + fflush (f); + if (fgetc (f) != c) + { fclose (f); return 6; } + /* Verify behaviour of fflush after a non-backup ungetc. This fails + on glibc 2.8 and on BSD systems. */ + c = fgetc (f); + ungetc ('@', f); + fflush (f); + if (fgetc (f) != c) + { fclose (f); return 7; } + fclose (f); + return 0; + ]])], + [gl_cv_func_fflush_stdin=yes], + [gl_cv_func_fflush_stdin=no], + [case "$host_os" in + # Guess no on native Windows. + mingw*) gl_cv_func_fflush_stdin="guessing no" ;; + *) gl_cv_func_fflush_stdin=cross ;; + esac + ]) + rm conftest.txt + ]) + case "$gl_cv_func_fflush_stdin" in + *yes) gl_func_fflush_stdin=1 ;; + *no) gl_func_fflush_stdin=0 ;; + *) gl_func_fflush_stdin='(-1)' ;; + esac + AC_DEFINE_UNQUOTED([FUNC_FFLUSH_STDIN], [$gl_func_fflush_stdin], + [Define to 1 if fflush is known to work on stdin as per POSIX.1-2008, + 0 if fflush is known to not work, -1 if unknown.]) +]) + +# Prerequisites of lib/fflush.c. +AC_DEFUN([gl_PREREQ_FFLUSH], [:]) diff --git a/gl/m4/float_h.m4 b/gl/m4/float_h.m4 index 397f2d1f..0e845726 100644 --- a/gl/m4/float_h.m4 +++ b/gl/m4/float_h.m4 @@ -1,5 +1,5 @@ -# float_h.m4 serial 9 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. +# float_h.m4 serial 13 +dnl Copyright (C) 2007, 2009-2022 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. @@ -8,42 +8,46 @@ AC_DEFUN([gl_FLOAT_H], [ AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) - FLOAT_H= + GL_GENERATE_FLOAT_H=false REPLACE_FLOAT_LDBL=0 case "$host_os" in aix* | beos* | openbsd* | mirbsd* | irix*) - FLOAT_H=float.h + GL_GENERATE_FLOAT_H=true ;; - freebsd*) + freebsd* | dragonfly*) case "$host_cpu" in changequote(,)dnl i[34567]86 ) changequote([,])dnl - FLOAT_H=float.h + GL_GENERATE_FLOAT_H=true ;; x86_64 ) # On x86_64 systems, the C compiler may still be generating # 32-bit code. - AC_EGREP_CPP([yes], - [#if defined __LP64__ || defined __x86_64__ || defined __amd64__ - yes - #endif], + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __x86_64__ || defined __amd64__ + int ok; + #else + error fail + #endif + ]])], [], - [FLOAT_H=float.h]) + [GL_GENERATE_FLOAT_H=true]) ;; esac ;; linux*) case "$host_cpu" in powerpc*) - FLOAT_H=float.h + GL_GENERATE_FLOAT_H=true ;; esac ;; esac case "$host_os" in - aix* | freebsd* | linux*) - if test -n "$FLOAT_H"; then + aix* | freebsd* | dragonfly* | linux*) + if $GL_GENERATE_FLOAT_H; then REPLACE_FLOAT_LDBL=1 fi ;; @@ -69,14 +73,20 @@ int main () [gl_cv_func_itold_works=no], [case "$host" in sparc*-*-linux*) - AC_EGREP_CPP([yes], - [#if defined __LP64__ || defined __arch64__ - yes - #endif], + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], [gl_cv_func_itold_works="guessing no"], [gl_cv_func_itold_works="guessing yes"]) ;; - *) gl_cv_func_itold_works="guessing yes" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_itold_works="guessing yes" ;; + *) gl_cv_func_itold_works="guessing yes" ;; esac ]) ]) @@ -85,14 +95,12 @@ int main () REPLACE_ITOLD=1 dnl We add the workaround to but also to , dnl to increase the chances that the fix function gets pulled in. - FLOAT_H=float.h + GL_GENERATE_FLOAT_H=true ;; esac - if test -n "$FLOAT_H"; then + if $GL_GENERATE_FLOAT_H; then gl_NEXT_HEADERS([float.h]) fi - AC_SUBST([FLOAT_H]) - AM_CONDITIONAL([GL_GENERATE_FLOAT_H], [test -n "$FLOAT_H"]) AC_SUBST([REPLACE_ITOLD]) ]) diff --git a/gl/m4/floorf.m4 b/gl/m4/floorf.m4 index c892ff9c..e8f290b0 100644 --- a/gl/m4/floorf.m4 +++ b/gl/m4/floorf.m4 @@ -1,5 +1,5 @@ -# floorf.m4 serial 13 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. +# floorf.m4 serial 18 +dnl Copyright (C) 2007, 2009-2022 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. @@ -39,7 +39,7 @@ AC_DEFUN([gl_FUNC_FLOORF], static float dummy (float f) { return 0; } int main (int argc, char *argv[]) { - float (*my_floorf) (float) = argc ? floorf : dummy; + float (* volatile my_floorf) (float) = argc ? floorf : dummy; /* Test whether floorf (-0.0f) is -0.0f. */ if (signbitf (minus_zerof) && !signbitf (my_floorf (minus_zerof))) return 1; @@ -49,10 +49,14 @@ int main (int argc, char *argv[]) [gl_cv_func_floorf_ieee=yes], [gl_cv_func_floorf_ieee=no], [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_floorf_ieee="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_floorf_ieee="guessing no" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_floorf_ieee="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_floorf_ieee="guessing yes" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_floorf_ieee="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_floorf_ieee="$gl_cross_guess_normal" ;; esac ]) LIBS="$save_LIBS" diff --git a/gl/m4/fopen.m4 b/gl/m4/fopen.m4 new file mode 100644 index 00000000..50767f82 --- /dev/null +++ b/gl/m4/fopen.m4 @@ -0,0 +1,149 @@ +# fopen.m4 serial 13 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FOPEN], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw* | pw*) + dnl Replace fopen, for handling of "/dev/null". + REPLACE_FOPEN=1 + dnl fopen on mingw also has the trailing slash bug. + gl_cv_func_fopen_slash="guessing no" + ;; + *) + dnl fopen("foo/", "w") should not create a file when the file name has a + dnl trailing slash. + AC_CACHE_CHECK([whether fopen recognizes a trailing slash], + [gl_cv_func_fopen_slash], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int main () +{ + FILE *fp = fopen ("conftest.sl/", "w"); + int result = (fp != NULL); + if (fp != NULL) + fclose (fp); + return result; +}]])], + [gl_cv_func_fopen_slash=yes], + [gl_cv_func_fopen_slash=no], + [ +changequote(,)dnl + case "$host_os" in + aix* | hpux* | solaris2.[0-9] | solaris2.[0-9].*) + gl_cv_func_fopen_slash="guessing no" ;; + *) + gl_cv_func_fopen_slash="guessing yes" ;; + esac +changequote([,])dnl + ]) + rm -f conftest.sl + ]) + ;; + esac + case "$gl_cv_func_fopen_slash" in + *no) + AC_DEFINE([FOPEN_TRAILING_SLASH_BUG], [1], + [Define to 1 if fopen() fails to recognize a trailing slash.]) + REPLACE_FOPEN=1 + ;; + esac +]) + +AC_DEFUN([gl_FUNC_FOPEN_GNU], +[ + AC_REQUIRE([gl_FUNC_FOPEN]) + AC_CACHE_CHECK([whether fopen supports the mode character 'x'], + [gl_cv_func_fopen_mode_x], + [rm -f conftest.x + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int main () +{ + FILE *fp; + fp = fopen ("conftest.x", "w"); + fclose (fp); + fp = fopen ("conftest.x", "wx"); + if (fp != NULL) + /* 'x' ignored */ + return 1; + else if (errno == EEXIST) + return 0; + else + /* 'x' rejected */ + return 2; +}]])], + [gl_cv_func_fopen_mode_x=yes], + [gl_cv_func_fopen_mode_x=no], + [case "$host_os" in + # Guess yes on glibc and musl systems. + linux*-gnu* | gnu* | kfreebsd*-gnu | *-musl*) + gl_cv_func_fopen_mode_x="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) + gl_cv_func_fopen_mode_x="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.x + ]) + AC_CACHE_CHECK([whether fopen supports the mode character 'e'], + [gl_cv_func_fopen_mode_e], + [echo foo > conftest.x + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +]GL_MDA_DEFINES[ +int main () +{ + FILE *fp = fopen ("conftest.x", "re"); + if (fp != NULL) + { + if (fcntl (fileno (fp), F_GETFD) & FD_CLOEXEC) + return 0; + else + /* 'e' ignored */ + return 1; + } + else + /* 'e' rejected */ + return 2; +}]])], + [gl_cv_func_fopen_mode_e=yes], + [gl_cv_func_fopen_mode_e=no], + [case "$host_os" in + # Guess yes on glibc and musl systems. + linux*-gnu* | gnu* | kfreebsd*-gnu | *-musl*) + gl_cv_func_fopen_mode_e="guessing yes" ;; + # Guess no on native Windows. + mingw*) + gl_cv_func_fopen_mode_e="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) + gl_cv_func_fopen_mode_e="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.x + ]) + REPLACE_FOPEN_FOR_FOPEN_GNU="$REPLACE_FOPEN" + case "$gl_cv_func_fopen_mode_x" in + *no) REPLACE_FOPEN_FOR_FOPEN_GNU=1 ;; + esac + case "$gl_cv_func_fopen_mode_e" in + *no) REPLACE_FOPEN_FOR_FOPEN_GNU=1 ;; + esac +]) + +# Prerequisites of lib/fopen.c. +AC_DEFUN([gl_PREREQ_FOPEN], [:]) diff --git a/gl/m4/fpurge.m4 b/gl/m4/fpurge.m4 new file mode 100644 index 00000000..1a154541 --- /dev/null +++ b/gl/m4/fpurge.m4 @@ -0,0 +1,73 @@ +# fpurge.m4 serial 12 +dnl Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FPURGE], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CHECK_HEADERS_ONCE([stdio_ext.h]) + AC_CHECK_FUNCS_ONCE([fpurge]) + AC_CHECK_FUNCS_ONCE([__fpurge]) + AC_CHECK_DECLS([fpurge], , , [[#include ]]) + if test "x$ac_cv_func_fpurge" = xyes; then + HAVE_FPURGE=1 + # Detect BSD bug. Only cygwin 1.7 and musl are known to be immune. + AC_CACHE_CHECK([whether fpurge works], [gl_cv_func_fpurge_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include +]], + [[FILE *f = fopen ("conftest.txt", "w+"); + if (!f) + return 1; + if (fputc ('a', f) != 'a') + { fclose (f); return 2; } + rewind (f); + if (fgetc (f) != 'a') + { fclose (f); return 3; } + if (fgetc (f) != EOF) + { fclose (f); return 4; } + if (fpurge (f) != 0) + { fclose (f); return 5; } + if (putc ('b', f) != 'b') + { fclose (f); return 6; } + if (fclose (f) != 0) + return 7; + if ((f = fopen ("conftest.txt", "r")) == NULL) + return 8; + if (fgetc (f) != 'a') + { fclose (f); return 9; } + if (fgetc (f) != 'b') + { fclose (f); return 10; } + if (fgetc (f) != EOF) + { fclose (f); return 11; } + if (fclose (f) != 0) + return 12; + if (remove ("conftest.txt") != 0) + return 13; + return 0; + ]])], + [gl_cv_func_fpurge_works=yes], + [gl_cv_func_fpurge_works=no], + [case "$host_os" in + # Guess yes on musl systems. + *-musl*) gl_cv_func_fpurge_works="guessing yes" ;; + # Otherwise obey --enable-cross-guesses. + *) gl_cv_func_fpurge_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_fpurge_works" in + *yes) ;; + *) REPLACE_FPURGE=1 ;; + esac + else + HAVE_FPURGE=0 + fi + if test "x$ac_cv_have_decl_fpurge" = xno; then + HAVE_DECL_FPURGE=0 + fi +]) diff --git a/gl/m4/freading.m4 b/gl/m4/freading.m4 new file mode 100644 index 00000000..81b17a64 --- /dev/null +++ b/gl/m4/freading.m4 @@ -0,0 +1,11 @@ +# freading.m4 serial 2 +dnl Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FREADING], +[ + AC_CHECK_HEADERS_ONCE([stdio_ext.h]) + AC_CHECK_FUNCS_ONCE([__freading]) +]) diff --git a/gl/m4/free.m4 b/gl/m4/free.m4 new file mode 100644 index 00000000..dfeecd2b --- /dev/null +++ b/gl/m4/free.m4 @@ -0,0 +1,52 @@ +# free.m4 serial 6 +# Copyright (C) 2003-2005, 2009-2022 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Written by Paul Eggert and Bruno Haible. + +AC_DEFUN([gl_FUNC_FREE], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + + dnl In the next release of POSIX, free must preserve errno. + dnl https://www.austingroupbugs.net/view.php?id=385 + dnl https://sourceware.org/bugzilla/show_bug.cgi?id=17924 + dnl So far, we know of three platforms that do this: + dnl * glibc >= 2.33, thanks to the fix for this bug: + dnl + dnl * OpenBSD >= 4.5, thanks to this commit: + dnl + dnl * Solaris, because its malloc() implementation is based on brk(), + dnl not mmap(); hence its free() implementation makes no system calls. + dnl For other platforms, you can only be sure if they state it in their + dnl documentation, or by code inspection of the free() implementation in libc. + AC_CACHE_CHECK([whether free is known to preserve errno], + [gl_cv_func_free_preserves_errno], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[#if 2 < __GLIBC__ + (33 <= __GLIBC_MINOR__) + #elif defined __OpenBSD__ + #elif defined __sun + #else + #error "'free' is not known to preserve errno" + #endif + ]])], + [gl_cv_func_free_preserves_errno=yes], + [gl_cv_func_free_preserves_errno=no]) + ]) + + case $gl_cv_func_free_preserves_errno in + *yes) + AC_DEFINE([HAVE_FREE_POSIX], [1], + [Define if the 'free' function is guaranteed to preserve errno.]) + ;; + *) REPLACE_FREE=1 ;; + esac +]) + +# Prerequisites of lib/free.c. +AC_DEFUN([gl_PREREQ_FREE], [:]) diff --git a/gl/m4/fseek.m4 b/gl/m4/fseek.m4 new file mode 100644 index 00000000..bd4a55be --- /dev/null +++ b/gl/m4/fseek.m4 @@ -0,0 +1,15 @@ +# fseek.m4 serial 4 +dnl Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FSEEK], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_FSEEKO]) + dnl When fseeko needs fixes, fseek needs them too. + if test $HAVE_FSEEKO = 0 || test $REPLACE_FSEEKO = 1; then + REPLACE_FSEEK=1 + fi +]) diff --git a/gl/m4/fseeko.m4 b/gl/m4/fseeko.m4 new file mode 100644 index 00000000..e50fe398 --- /dev/null +++ b/gl/m4/fseeko.m4 @@ -0,0 +1,77 @@ +# fseeko.m4 serial 20 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FSEEKO], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([gl_STDIN_LARGE_OFFSET]) + AC_REQUIRE([gl_SYS_TYPES_H]) + AC_REQUIRE([AC_PROG_CC]) + + dnl Persuade glibc to declare fseeko(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko], + [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include +]], [[fseeko (stdin, 0, 0);]])], + [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no]) + ]) + + AC_CHECK_DECLS_ONCE([fseeko]) + if test $ac_cv_have_decl_fseeko = no; then + HAVE_DECL_FSEEKO=0 + fi + + if test $gl_cv_func_fseeko = no; then + HAVE_FSEEKO=0 + else + if test $WINDOWS_64_BIT_OFF_T = 1; then + REPLACE_FSEEKO=1 + fi + if test $gl_cv_var_stdin_large_offset = no; then + REPLACE_FSEEKO=1 + fi + m4_ifdef([gl_FUNC_FFLUSH_STDIN], [ + gl_FUNC_FFLUSH_STDIN + case "$gl_cv_func_fflush_stdin" in + *yes) ;; + *) REPLACE_FSEEKO=1 ;; + esac + ]) + fi +]) + +dnl Code shared by fseeko and ftello. Determine if large files are supported, +dnl but stdin does not start as a large file by default. +AC_DEFUN([gl_STDIN_LARGE_OFFSET], + [ + AC_CACHE_CHECK([whether stdin defaults to large file offsets], + [gl_cv_var_stdin_large_offset], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], +[[#if defined __SL64 && defined __SCLE /* cygwin */ + /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making + fseeko/ftello needlessly fail. This bug was fixed in 1.5.25, and + it is easier to do a version check than building a runtime test. */ +# include +# if CYGWIN_VERSION_DLL_COMBINED < CYGWIN_VERSION_DLL_MAKE_COMBINED (1005, 25) + choke me +# endif +#endif]])], + [gl_cv_var_stdin_large_offset=yes], + [gl_cv_var_stdin_large_offset=no])]) +]) + +# Prerequisites of lib/fseeko.c. +AC_DEFUN([gl_PREREQ_FSEEKO], +[ + dnl Native Windows has the function _fseeki64. mingw hides it in some + dnl circumstances, but mingw64 makes it usable again. + AC_CHECK_FUNCS([_fseeki64]) + if test $ac_cv_func__fseeki64 = yes; then + AC_CHECK_DECLS([_fseeki64]) + fi +]) diff --git a/gl/m4/fstat.m4 b/gl/m4/fstat.m4 new file mode 100644 index 00000000..9e61bcce --- /dev/null +++ b/gl/m4/fstat.m4 @@ -0,0 +1,40 @@ +# fstat.m4 serial 8 +dnl Copyright (C) 2011-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FSTAT], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) + + case "$host_os" in + mingw* | solaris*) + dnl On MinGW, the original stat() returns st_atime, st_mtime, + dnl st_ctime values that are affected by the time zone. + dnl Solaris stat can return a negative tv_nsec. + REPLACE_FSTAT=1 + ;; + esac + + dnl Replace fstat() for supporting the gnulib-defined open() on directories. + m4_ifdef([gl_FUNC_FCHDIR], [ + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then + case "$gl_cv_func_open_directory_works" in + *yes) ;; + *) + REPLACE_FSTAT=1 + ;; + esac + fi + ]) +]) + +# Prerequisites of lib/fstat.c and lib/stat-w32.c. +AC_DEFUN([gl_PREREQ_FSTAT], [ + AC_REQUIRE([gl_SYS_STAT_H]) + AC_REQUIRE([gl_PREREQ_STAT_W32]) + : +]) diff --git a/gl/m4/fstypename.m4 b/gl/m4/fstypename.m4 index c72ecb80..67499223 100644 --- a/gl/m4/fstypename.m4 +++ b/gl/m4/fstypename.m4 @@ -6,7 +6,7 @@ dnl See if struct statfs has the f_fstypename member. dnl If so, define HAVE_STRUCT_STATFS_F_FSTYPENAME. dnl -# Copyright (C) 1998-1999, 2001, 2004, 2006, 2009-2013 Free Software +# Copyright (C) 1998-1999, 2001, 2004, 2006, 2009-2022 Free Software # Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/gl/m4/fsusage.m4 b/gl/m4/fsusage.m4 index 6277bfa5..06e60886 100644 --- a/gl/m4/fsusage.m4 +++ b/gl/m4/fsusage.m4 @@ -1,7 +1,7 @@ -# serial 30 +# serial 35 # Obtaining file system usage information. -# Copyright (C) 1997-1998, 2000-2001, 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-1998, 2000-2001, 2003-2022 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -29,27 +29,29 @@ AC_DEFUN([gl_FSUSAGE], AC_DEFUN([gl_FILE_SYSTEM_USAGE], [ -dnl Enable large-file support. This has the effect of changing the size -dnl of field f_blocks in 'struct statvfs' from 32 bit to 64 bit on -dnl glibc/Hurd, HP-UX 11, Solaris (32-bit mode). It also changes the size -dnl of field f_blocks in 'struct statfs' from 32 bit to 64 bit on -dnl Mac OS X >= 10.5 (32-bit mode). -AC_REQUIRE([AC_SYS_LARGEFILE]) + dnl Enable large-file support. This has the effect of changing the size + dnl of field f_blocks in 'struct statvfs' from 32 bit to 64 bit on + dnl glibc/Hurd, HP-UX 11, Solaris (32-bit mode). It also changes the size + dnl of field f_blocks in 'struct statfs' from 32 bit to 64 bit on + dnl Mac OS X >= 10.5 (32-bit mode). + AC_REQUIRE([AC_SYS_LARGEFILE]) -AC_MSG_NOTICE([checking how to get file system space usage]) -ac_fsusage_space=no + ac_fsusage_space=no -# Perform only the link test since it seems there are no variants of the -# statvfs function. This check is more than just AC_CHECK_FUNCS([statvfs]) -# because that got a false positive on SCO OSR5. Adding the declaration -# of a 'struct statvfs' causes this test to fail (as it should) on such -# systems. That system is reported to work fine with STAT_STATFS4 which -# is what it gets when this test fails. -if test $ac_fsusage_space = no; then - # glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, - # OpenBSD >= 4.4, AIX, HP-UX, IRIX, Solaris, Cygwin, Interix, BeOS. - AC_CACHE_CHECK([for statvfs function (SVR4)], [fu_cv_sys_stat_statvfs], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include + # Perform only the link test since it seems there are no variants of the + # statvfs function. This check is more than just AC_CHECK_FUNCS([statvfs]) + # because that got a false positive on SCO OSR5. Adding the declaration + # of a 'struct statvfs' causes this test to fail (as it should) on such + # systems. That system is reported to work fine with STAT_STATFS4 which + # is what it gets when this test fails. + if test $ac_fsusage_space = no; then + # glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, + # OpenBSD >= 4.4, AIX, HP-UX, IRIX, Solaris, Cygwin, Interix, BeOS. + AC_CACHE_CHECK([for statvfs function (SVR4)], + [fu_cv_sys_stat_statvfs], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include #ifdef __osf__ "Do not use Tru64's statvfs implementation" #endif @@ -68,45 +70,47 @@ struct statvfs fsd; int check_f_blocks_size[sizeof fsd.f_blocks * CHAR_BIT <= 32 ? -1 : 1]; #endif ]], - [[statvfs (0, &fsd);]])], - [fu_cv_sys_stat_statvfs=yes], - [fu_cv_sys_stat_statvfs=no])]) - if test $fu_cv_sys_stat_statvfs = yes; then - ac_fsusage_space=yes - # AIX >= 5.2 has statvfs64 that has a wider f_blocks field than statvfs. - # glibc, HP-UX, IRIX, Solaris have statvfs64 as well, but on these systems - # statvfs with large-file support is already equivalent to statvfs64. - AC_CACHE_CHECK([whether to use statvfs64], - [fu_cv_sys_stat_statvfs64], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include - struct statvfs64 fsd; - int check_f_blocks_larger_in_statvfs64 - [sizeof (((struct statvfs64 *) 0)->f_blocks) - > sizeof (((struct statvfs *) 0)->f_blocks) - ? 1 : -1]; - ]], - [[statvfs64 (0, &fsd);]])], - [fu_cv_sys_stat_statvfs64=yes], - [fu_cv_sys_stat_statvfs64=no]) + [[statvfs (0, &fsd);]])], + [fu_cv_sys_stat_statvfs=yes], + [fu_cv_sys_stat_statvfs=no]) ]) - if test $fu_cv_sys_stat_statvfs64 = yes; then - AC_DEFINE([STAT_STATVFS64], [1], - [ Define if statvfs64 should be preferred over statvfs.]) - else - AC_DEFINE([STAT_STATVFS], [1], - [ Define if there is a function named statvfs. (SVR4)]) + if test $fu_cv_sys_stat_statvfs = yes; then + ac_fsusage_space=yes + # AIX >= 5.2 has statvfs64 that has a wider f_blocks field than statvfs. + # glibc, HP-UX, IRIX, Solaris have statvfs64 as well, but on these systems + # statvfs with large-file support is already equivalent to statvfs64. + AC_CACHE_CHECK([whether to use statvfs64], + [fu_cv_sys_stat_statvfs64], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + struct statvfs64 fsd; + int check_f_blocks_larger_in_statvfs64 + [sizeof (((struct statvfs64 *) 0)->f_blocks) + > sizeof (((struct statvfs *) 0)->f_blocks) + ? 1 : -1]; + ]], + [[statvfs64 (0, &fsd);]])], + [fu_cv_sys_stat_statvfs64=yes], + [fu_cv_sys_stat_statvfs64=no]) + ]) + if test $fu_cv_sys_stat_statvfs64 = yes; then + AC_DEFINE([STAT_STATVFS64], [1], + [Define if statvfs64 should be preferred over statvfs.]) + else + AC_DEFINE([STAT_STATVFS], [1], + [Define if there is a function named statvfs. (SVR4)]) + fi fi fi -fi -# Check for this unconditionally so we have a -# good fallback on glibc/Linux > 2.6 < 2.6.36 -AC_MSG_CHECKING([for two-argument statfs with statfs.f_frsize member]) -AC_CACHE_VAL([fu_cv_sys_stat_statfs2_frsize], -[AC_RUN_IFELSE([AC_LANG_SOURCE([[ + # Check for this unconditionally so we have a + # good fallback on glibc/Linux > 2.6 < 2.6.36 + AC_CACHE_CHECK([for two-argument statfs with statfs.f_frsize member], + [fu_cv_sys_stat_statfs2_frsize], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #ifdef HAVE_SYS_PARAM_H #include #endif @@ -119,26 +123,26 @@ AC_CACHE_VAL([fu_cv_sys_stat_statfs2_frsize], int main () { - struct statfs fsd; - fsd.f_frsize = 0; - return statfs (".", &fsd) != 0; + struct statfs fsd; + fsd.f_frsize = 0; + return statfs (".", &fsd) != 0; }]])], - [fu_cv_sys_stat_statfs2_frsize=yes], - [fu_cv_sys_stat_statfs2_frsize=no], - [fu_cv_sys_stat_statfs2_frsize=no])]) -AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_frsize]) -if test $fu_cv_sys_stat_statfs2_frsize = yes; then + [fu_cv_sys_stat_statfs2_frsize=yes], + [fu_cv_sys_stat_statfs2_frsize=no], + [fu_cv_sys_stat_statfs2_frsize=no]) + ]) + if test $fu_cv_sys_stat_statfs2_frsize = yes; then ac_fsusage_space=yes AC_DEFINE([STAT_STATFS2_FRSIZE], [1], -[ Define if statfs takes 2 args and struct statfs has a field named f_frsize. - (glibc/Linux > 2.6)]) -fi + [Define if statfs takes 2 args and struct statfs has a field named f_frsize. + (glibc/Linux > 2.6)]) + fi -if test $ac_fsusage_space = no; then - # DEC Alpha running OSF/1 - AC_MSG_CHECKING([for 3-argument statfs function (DEC OSF/1)]) - AC_CACHE_VAL([fu_cv_sys_stat_statfs3_osf1], - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ + if test $ac_fsusage_space = no; then + # DEC Alpha running OSF/1 + AC_CACHE_CHECK([for 3-argument statfs function (DEC OSF/1)], + [fu_cv_sys_stat_statfs3_osf1], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include #include @@ -149,28 +153,27 @@ if test $ac_fsusage_space = no; then fsd.f_fsize = 0; return statfs (".", &fsd, sizeof (struct statfs)) != 0; }]])], - [fu_cv_sys_stat_statfs3_osf1=yes], - [fu_cv_sys_stat_statfs3_osf1=no], - [fu_cv_sys_stat_statfs3_osf1=no])]) - AC_MSG_RESULT([$fu_cv_sys_stat_statfs3_osf1]) - if test $fu_cv_sys_stat_statfs3_osf1 = yes; then - ac_fsusage_space=yes - AC_DEFINE([STAT_STATFS3_OSF1], [1], - [ Define if statfs takes 3 args. (DEC Alpha running OSF/1)]) + [fu_cv_sys_stat_statfs3_osf1=yes], + [fu_cv_sys_stat_statfs3_osf1=no], + [fu_cv_sys_stat_statfs3_osf1=no]) + ]) + if test $fu_cv_sys_stat_statfs3_osf1 = yes; then + ac_fsusage_space=yes + AC_DEFINE([STAT_STATFS3_OSF1], [1], + [Define if statfs takes 3 args. (DEC Alpha running OSF/1)]) + fi fi -fi -if test $ac_fsusage_space = no; then - # glibc/Linux, Mac OS X, FreeBSD < 5.0, NetBSD < 3.0, OpenBSD < 4.4. - # (glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, - # OpenBSD >= 4.4, AIX, HP-UX, OSF/1, Cygwin already handled above.) - # (On IRIX you need to include , not only and - # .) - # (On Solaris, statfs has 4 arguments.) - AC_MSG_CHECKING([for two-argument statfs with statfs.f_bsize dnl -member (AIX, 4.3BSD)]) - AC_CACHE_VAL([fu_cv_sys_stat_statfs2_bsize], - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ + if test $ac_fsusage_space = no; then + # glibc/Linux, Mac OS X, FreeBSD < 5.0, NetBSD < 3.0, OpenBSD < 4.4. + # (glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, + # OpenBSD >= 4.4, AIX, HP-UX, OSF/1, Cygwin already handled above.) + # (On IRIX you need to include , not only and + # .) + # (On Solaris, statfs has 4 arguments.) + AC_CACHE_CHECK([for two-argument statfs with statfs.f_bsize member (AIX, 4.3BSD)], + [fu_cv_sys_stat_statfs2_bsize], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef HAVE_SYS_PARAM_H #include #endif @@ -183,130 +186,83 @@ member (AIX, 4.3BSD)]) int main () { - struct statfs fsd; - fsd.f_bsize = 0; - return statfs (".", &fsd) != 0; + struct statfs fsd; + fsd.f_bsize = 0; + return statfs (".", &fsd) != 0; }]])], - [fu_cv_sys_stat_statfs2_bsize=yes], - [fu_cv_sys_stat_statfs2_bsize=no], - [fu_cv_sys_stat_statfs2_bsize=no])]) - AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_bsize]) - if test $fu_cv_sys_stat_statfs2_bsize = yes; then - ac_fsusage_space=yes - AC_DEFINE([STAT_STATFS2_BSIZE], [1], -[ Define if statfs takes 2 args and struct statfs has a field named f_bsize. - (4.3BSD, SunOS 4, HP-UX, AIX PS/2)]) + [fu_cv_sys_stat_statfs2_bsize=yes], + [fu_cv_sys_stat_statfs2_bsize=no], + [fu_cv_sys_stat_statfs2_bsize=no]) + ]) + if test $fu_cv_sys_stat_statfs2_bsize = yes; then + ac_fsusage_space=yes + AC_DEFINE([STAT_STATFS2_BSIZE], [1], + [Define if statfs takes 2 args and struct statfs has a field named f_bsize. + (4.3BSD, SunOS 4, HP-UX)]) + fi fi -fi -if test $ac_fsusage_space = no; then - # SVR3 - # (Solaris already handled above.) - AC_MSG_CHECKING([for four-argument statfs (AIX-3.2.5, SVR3)]) - AC_CACHE_VAL([fu_cv_sys_stat_statfs4], - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ + if test $ac_fsusage_space = no; then + # SVR3 + # (Solaris already handled above.) + AC_CACHE_CHECK([for four-argument statfs (SVR3)], + [fu_cv_sys_stat_statfs4], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main () { - struct statfs fsd; - return statfs (".", &fsd, sizeof fsd, 0) != 0; - }]])], - [fu_cv_sys_stat_statfs4=yes], - [fu_cv_sys_stat_statfs4=no], - [fu_cv_sys_stat_statfs4=no])]) - AC_MSG_RESULT([$fu_cv_sys_stat_statfs4]) - if test $fu_cv_sys_stat_statfs4 = yes; then - ac_fsusage_space=yes - AC_DEFINE([STAT_STATFS4], [1], - [ Define if statfs takes 4 args. (SVR3, Dynix, old Irix, old AIX, Dolphin)]) - fi -fi - -if test $ac_fsusage_space = no; then - # 4.4BSD and older NetBSD - # (OSF/1 already handled above.) - # (On AIX, you need to include , not only .) - # (On Solaris, statfs has 4 arguments and 'struct statfs' is not declared in - # .) - AC_MSG_CHECKING([for two-argument statfs with statfs.f_fsize dnl -member (4.4BSD and NetBSD)]) - AC_CACHE_VAL([fu_cv_sys_stat_statfs2_fsize], - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_MOUNT_H -#include -#endif - int - main () - { - struct statfs fsd; - fsd.f_fsize = 0; - return statfs (".", &fsd) != 0; + struct statfs fsd; + return statfs (".", &fsd, sizeof fsd, 0) != 0; }]])], - [fu_cv_sys_stat_statfs2_fsize=yes], - [fu_cv_sys_stat_statfs2_fsize=no], - [fu_cv_sys_stat_statfs2_fsize=no])]) - AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_fsize]) - if test $fu_cv_sys_stat_statfs2_fsize = yes; then - ac_fsusage_space=yes - AC_DEFINE([STAT_STATFS2_FSIZE], [1], -[ Define if statfs takes 2 args and struct statfs has a field named f_fsize. - (4.4BSD, NetBSD)]) + [fu_cv_sys_stat_statfs4=yes], + [fu_cv_sys_stat_statfs4=no], + [fu_cv_sys_stat_statfs4=no]) + ]) + if test $fu_cv_sys_stat_statfs4 = yes; then + ac_fsusage_space=yes + AC_DEFINE([STAT_STATFS4], [1], + [Define if statfs takes 4 args. (SVR3, old Irix)]) + fi fi -fi -if test $ac_fsusage_space = no; then - # Ultrix - AC_MSG_CHECKING([for two-argument statfs with struct fs_data (Ultrix)]) - AC_CACHE_VAL([fu_cv_sys_stat_fs_data], - [AC_RUN_IFELSE([AC_LANG_SOURCE([[ + if test $ac_fsusage_space = no; then + # 4.4BSD and older NetBSD + # (OSF/1 already handled above.) + # (On AIX, you need to include , not only .) + # (On Solaris, statfs has 4 arguments and 'struct statfs' is not declared in + # .) + AC_CACHE_CHECK([for two-argument statfs with statfs.f_fsize member (4.4BSD and NetBSD)], + [fu_cv_sys_stat_statfs2_fsize], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_MOUNT_H #include -#endif -#ifdef HAVE_SYS_FS_TYPES_H -#include #endif int main () { - struct fs_data fsd; - /* Ultrix's statfs returns 1 for success, - 0 for not mounted, -1 for failure. */ - return statfs (".", &fsd) != 1; + struct statfs fsd; + fsd.f_fsize = 0; + return statfs (".", &fsd) != 0; }]])], - [fu_cv_sys_stat_fs_data=yes], - [fu_cv_sys_stat_fs_data=no], - [fu_cv_sys_stat_fs_data=no])]) - AC_MSG_RESULT([$fu_cv_sys_stat_fs_data]) - if test $fu_cv_sys_stat_fs_data = yes; then - ac_fsusage_space=yes - AC_DEFINE([STAT_STATFS2_FS_DATA], [1], -[ Define if statfs takes 2 args and the second argument has - type struct fs_data. (Ultrix)]) + [fu_cv_sys_stat_statfs2_fsize=yes], + [fu_cv_sys_stat_statfs2_fsize=no], + [fu_cv_sys_stat_statfs2_fsize=no]) + ]) + if test $fu_cv_sys_stat_statfs2_fsize = yes; then + ac_fsusage_space=yes + AC_DEFINE([STAT_STATFS2_FSIZE], [1], + [Define if statfs takes 2 args and struct statfs has a field named f_fsize. + (4.4BSD, NetBSD)]) + fi fi -fi -if test $ac_fsusage_space = no; then - # SVR2 - # (AIX, HP-UX, OSF/1 already handled above.) - AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include - ]])], - [AC_DEFINE([STAT_READ_FILSYS], [1], - [Define if there is no specific function for reading file systems usage - information and you have the header file. (SVR2)]) - ac_fsusage_space=yes]) -fi - -AS_IF([test $ac_fsusage_space = yes], [$1], [$2]) + AS_IF([test $ac_fsusage_space = yes], [$1], [$2]) ]) @@ -316,18 +272,22 @@ AS_IF([test $ac_fsusage_space = yes], [$1], [$2]) # enable the work-around code in fsusage.c. AC_DEFUN([gl_STATFS_TRUNCATES], [ - AC_MSG_CHECKING([for statfs that truncates block counts]) - AC_CACHE_VAL([fu_cv_sys_truncating_statfs], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + AC_CACHE_CHECK([for statfs that truncates block counts], + [fu_cv_sys_truncating_statfs], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ #if !defined(sun) && !defined(__sun) choke -- this is a workaround for a Sun-specific problem #endif #include -#include ]], - [[struct statfs t; long c = *(t.f_spare); - if (c) return 0;]])], - [fu_cv_sys_truncating_statfs=yes], - [fu_cv_sys_truncating_statfs=no])]) +#include + ]], + [[struct statfs t; long c = *(t.f_spare); + if (c) return 0; + ]])], + [fu_cv_sys_truncating_statfs=yes], + [fu_cv_sys_truncating_statfs=no]) + ]) if test $fu_cv_sys_truncating_statfs = yes; then AC_DEFINE([STATFS_TRUNCATES_BLOCK_COUNTS], [1], [Define if the block counts reported by statfs may be truncated to 2GB @@ -335,13 +295,12 @@ choke -- this is a workaround for a Sun-specific problem (SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem. SunOS 4.1.1 seems not to be affected.)]) fi - AC_MSG_RESULT([$fu_cv_sys_truncating_statfs]) ]) # Prerequisites of lib/fsusage.c not done by gl_FILE_SYSTEM_USAGE. AC_DEFUN([gl_PREREQ_FSUSAGE_EXTRA], [ - AC_CHECK_HEADERS([dustat.h sys/fs/s5param.h sys/filsys.h sys/statfs.h]) + AC_CHECK_HEADERS([sys/fs/s5param.h sys/statfs.h]) gl_STATFS_TRUNCATES ]) diff --git a/gl/m4/ftell.m4 b/gl/m4/ftell.m4 new file mode 100644 index 00000000..89f2d1bd --- /dev/null +++ b/gl/m4/ftell.m4 @@ -0,0 +1,15 @@ +# ftell.m4 serial 3 +dnl Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FTELL], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_FTELLO]) + dnl When ftello needs fixes, ftell needs them too. + if test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1; then + REPLACE_FTELL=1 + fi +]) diff --git a/gl/m4/ftello.m4 b/gl/m4/ftello.m4 new file mode 100644 index 00000000..919f39d8 --- /dev/null +++ b/gl/m4/ftello.m4 @@ -0,0 +1,151 @@ +# ftello.m4 serial 14 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_FTELLO], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_STDIN_LARGE_OFFSET]) + AC_REQUIRE([gl_SYS_TYPES_H]) + + dnl Persuade glibc to declare ftello(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([ftello]) + if test $ac_cv_have_decl_ftello = no; then + HAVE_DECL_FTELLO=0 + fi + + AC_CACHE_CHECK([for ftello], [gl_cv_func_ftello], + [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ftello (stdin);]])], + [gl_cv_func_ftello=yes], + [gl_cv_func_ftello=no]) + ]) + if test $gl_cv_func_ftello = no; then + HAVE_FTELLO=0 + else + if test $WINDOWS_64_BIT_OFF_T = 1; then + REPLACE_FTELLO=1 + fi + if test $gl_cv_var_stdin_large_offset = no; then + REPLACE_FTELLO=1 + fi + if test $REPLACE_FTELLO = 0; then + dnl Detect bug on Solaris. + dnl ftell and ftello produce incorrect results after putc that followed a + dnl getc call that reached EOF on Solaris. This is because the _IOREAD + dnl flag does not get cleared in this case, even though _IOWRT gets set, + dnl and ftell and ftello look whether the _IOREAD flag is set. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether ftello works], + [gl_cv_func_ftello_works], + [ + dnl Initial guess, used when cross-compiling or when /dev/tty cannot + dnl be opened. +changequote(,)dnl + case "$host_os" in + # Guess no on Solaris. + solaris*) gl_cv_func_ftello_works="guessing no" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_ftello_works="guessing yes" ;; + # Guess yes otherwise. + *) gl_cv_func_ftello_works="guessing yes" ;; + esac +changequote([,])dnl + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#define TESTFILE "conftest.tmp" +int +main (void) +{ + FILE *fp; + + /* Create a file with some contents. */ + fp = fopen (TESTFILE, "w"); + if (fp == NULL) + return 70; + if (fwrite ("foogarsh", 1, 8, fp) < 8) + { fclose (fp); return 71; } + if (fclose (fp)) + return 72; + + /* The file's contents is now "foogarsh". */ + + /* Try writing after reading to EOF. */ + fp = fopen (TESTFILE, "r+"); + if (fp == NULL) + return 73; + if (fseek (fp, -1, SEEK_END)) + { fclose (fp); return 74; } + if (!(getc (fp) == 'h')) + { fclose (fp); return 1; } + if (!(getc (fp) == EOF)) + { fclose (fp); return 2; } + if (!(ftell (fp) == 8)) + { fclose (fp); return 3; } + if (!(ftell (fp) == 8)) + { fclose (fp); return 4; } + if (!(putc ('!', fp) == '!')) + { fclose (fp); return 5; } + if (!(ftell (fp) == 9)) + { fclose (fp); return 6; } + if (!(fclose (fp) == 0)) + return 7; + fp = fopen (TESTFILE, "r"); + if (fp == NULL) + return 75; + { + char buf[10]; + if (!(fread (buf, 1, 10, fp) == 9)) + { fclose (fp); return 10; } + if (!(memcmp (buf, "foogarsh!", 9) == 0)) + { fclose (fp); return 11; } + } + if (!(fclose (fp) == 0)) + return 12; + + /* The file's contents is now "foogarsh!". */ + + return 0; +}]])], + [gl_cv_func_ftello_works=yes], + [gl_cv_func_ftello_works=no], [:]) + ]) + case "$gl_cv_func_ftello_works" in + *yes) ;; + *) + REPLACE_FTELLO=1 + AC_DEFINE([FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE], [1], + [Define to 1 if the system's ftello function has the Solaris bug.]) + ;; + esac + fi + if test $REPLACE_FTELLO = 0; then + dnl Detect bug on macOS >= 10.15. + gl_FUNC_UNGETC_WORKS + if test $gl_ftello_broken_after_ungetc = yes; then + REPLACE_FTELLO=1 + AC_DEFINE([FTELLO_BROKEN_AFTER_UNGETC], [1], + [Define to 1 if the system's ftello function has the macOS bug.]) + fi + fi + fi +]) + +# Prerequisites of lib/ftello.c. +AC_DEFUN([gl_PREREQ_FTELLO], +[ + dnl Native Windows has the function _ftelli64. mingw hides it, but mingw64 + dnl makes it usable again. + AC_CHECK_FUNCS([_ftelli64]) +]) diff --git a/gl/m4/getaddrinfo.m4 b/gl/m4/getaddrinfo.m4 index 1d631f8c..65a0fd0e 100644 --- a/gl/m4/getaddrinfo.m4 +++ b/gl/m4/getaddrinfo.m4 @@ -1,14 +1,13 @@ -# getaddrinfo.m4 serial 30 -dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. +# getaddrinfo.m4 serial 34 +dnl Copyright (C) 2004-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_GETADDRINFO], [ - AC_REQUIRE([gl_HEADER_SYS_SOCKET])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H - AC_REQUIRE([gl_HEADER_NETDB])dnl for HAVE_NETDB_H - AC_MSG_NOTICE([checking how to do getaddrinfo, freeaddrinfo and getnameinfo]) + AC_REQUIRE([gl_SYS_SOCKET_H])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H + AC_REQUIRE([gl_NETDB_H])dnl for HAVE_NETDB_H GETADDRINFO_LIB= gai_saved_LIBS="$LIBS" @@ -55,10 +54,40 @@ AC_DEFUN([gl_GETADDRINFO], if test "$gl_cv_w32_getaddrinfo" = "yes"; then GETADDRINFO_LIB="-lws2_32" LIBS="$gai_saved_LIBS $GETADDRINFO_LIB" + dnl Check for correct signature, in particular for a cdecl-compatible + dnl calling convention. + AC_CACHE_CHECK([for getaddrinfo with POSIX signature], + [gl_cv_func_getaddrinfo_posix_signature], + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_WS2TCPIP_H +#include +#endif +#include +extern +#ifdef __cplusplus +"C" +#endif +int getaddrinfo (const char *, const char *, const struct addrinfo *, struct addrinfo **); +]])], + [gl_cv_func_getaddrinfo_posix_signature=yes], + [gl_cv_func_getaddrinfo_posix_signature=no]) + ]) + if test $gl_cv_func_getaddrinfo_posix_signature = no; then + REPLACE_GETADDRINFO=1 + fi else HAVE_GETADDRINFO=0 fi fi + AC_DEFINE_UNQUOTED([HAVE_GETADDRINFO], [$HAVE_GETADDRINFO], + [Define to 1 if getaddrinfo exists, or to 0 otherwise.]) # We can't use AC_REPLACE_FUNCS here because gai_strerror may be an # inline function declared in ws2tcpip.h, so we need to get that @@ -127,13 +156,13 @@ const char *gai_strerror(int);]])], # Prerequisites of lib/netdb.in.h and lib/getaddrinfo.c. AC_DEFUN([gl_PREREQ_GETADDRINFO], [ AC_REQUIRE([gl_NETDB_H_DEFAULTS]) - AC_REQUIRE([gl_HEADER_SYS_SOCKET])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H + AC_REQUIRE([gl_SYS_SOCKET_H])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H AC_REQUIRE([gl_HOSTENT]) dnl for HOSTENT_LIB AC_REQUIRE([gl_SERVENT]) dnl for SERVENT_LIB AC_REQUIRE([gl_FUNC_INET_NTOP]) dnl for INET_NTOP_LIB AC_REQUIRE([AC_C_RESTRICT]) AC_REQUIRE([gl_SOCKET_FAMILIES]) - AC_REQUIRE([gl_HEADER_SYS_SOCKET]) + AC_REQUIRE([gl_SYS_SOCKET_H]) AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl Including sys/socket.h is wrong for Windows, but Windows does not diff --git a/gl/m4/getdelim.m4 b/gl/m4/getdelim.m4 new file mode 100644 index 00000000..0b63b553 --- /dev/null +++ b/gl/m4/getdelim.m4 @@ -0,0 +1,99 @@ +# getdelim.m4 serial 15 + +dnl Copyright (C) 2005-2007, 2009-2022 Free Software Foundation, Inc. +dnl +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_PREREQ([2.59]) + +AC_DEFUN([gl_FUNC_GETDELIM], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Persuade glibc to declare getdelim(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([getdelim]) + + AC_CHECK_FUNCS_ONCE([getdelim]) + if test $ac_cv_func_getdelim = yes; then + HAVE_GETDELIM=1 + dnl Found it in some library. Verify that it works. + AC_CACHE_CHECK([for working getdelim function], + [gl_cv_func_working_getdelim], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +# include +# include +# include + int main () + { + FILE *in = fopen ("./conftest.data", "r"); + if (!in) + return 1; + { + /* Test result for a NULL buffer and a zero size. + Based on a test program from Karl Heuer. */ + char *line = NULL; + size_t siz = 0; + int len = getdelim (&line, &siz, '\n', in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) + { free (line); fclose (in); return 2; } + free (line); + } + { + /* Test result for a NULL buffer and a non-zero size. + This crashes on FreeBSD 8.0. */ + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getdelim (&line, &siz, '\n', in) == -1) + { fclose (in); return 3; } + free (line); + } + fclose (in); + return 0; + } + ]])], + [gl_cv_func_working_getdelim=yes], + [gl_cv_func_working_getdelim=no], + [dnl We're cross compiling. + dnl Guess it works on glibc2 systems and musl systems. + AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif +#endif + ], + [gl_cv_func_working_getdelim="guessing yes"], + [case "$host_os" in + *-musl*) gl_cv_func_working_getdelim="guessing yes" ;; + *) gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;; + esac + ]) + ]) + ]) + case "$gl_cv_func_working_getdelim" in + *yes) ;; + *) REPLACE_GETDELIM=1 ;; + esac + else + HAVE_GETDELIM=0 + fi + + if test $ac_cv_have_decl_getdelim = no; then + HAVE_DECL_GETDELIM=0 + fi +]) + +# Prerequisites of lib/getdelim.c. +AC_DEFUN([gl_PREREQ_GETDELIM], +[ + AC_CHECK_FUNCS([flockfile funlockfile]) + AC_CHECK_DECLS([getc_unlocked]) +]) diff --git a/gl/m4/getdtablesize.m4 b/gl/m4/getdtablesize.m4 new file mode 100644 index 00000000..6134eaac --- /dev/null +++ b/gl/m4/getdtablesize.m4 @@ -0,0 +1,63 @@ +# getdtablesize.m4 serial 8 +dnl Copyright (C) 2008-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_GETDTABLESIZE], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS_ONCE([getdtablesize]) + AC_CHECK_DECLS_ONCE([getdtablesize]) + if test $ac_cv_func_getdtablesize = yes && + test $ac_cv_have_decl_getdtablesize = yes; then + AC_CACHE_CHECK([whether getdtablesize works], + [gl_cv_func_getdtablesize_works], + [dnl There are two concepts: the "maximum possible file descriptor value + 1" + dnl and the "maximum number of open file descriptors in a process". + dnl Per SUSv2 and POSIX, getdtablesize() should return the first one. + dnl On most platforms, the first and the second concept are the same. + dnl On OpenVMS, however, they are different and getdtablesize() returns + dnl the second one; thus the test below fails. But we don't care + dnl because there's no good way to write a replacement getdtablesize(). + case "$host_os" in + vms*) gl_cv_func_getdtablesize_works="no (limitation)" ;; + *) + dnl Cygwin 1.7.25 automatically increases the RLIMIT_NOFILE soft + dnl limit up to an unchangeable hard limit; all other platforms + dnl correctly require setrlimit before getdtablesize() can report + dnl a larger value. + AC_RUN_IFELSE([ + AC_LANG_PROGRAM( + [[#include ] + GL_MDA_DEFINES + ], + [[int size = getdtablesize(); + if (dup2 (0, getdtablesize()) != -1) + return 1; + if (size != getdtablesize()) + return 2; + ]])], + [gl_cv_func_getdtablesize_works=yes], + [gl_cv_func_getdtablesize_works=no], + [case "$host_os" in + cygwin*) # on cygwin 1.5.25, getdtablesize() automatically grows + gl_cv_func_getdtablesize_works="guessing no" ;; + *) gl_cv_func_getdtablesize_works="guessing yes" ;; + esac + ]) + ;; + esac + ]) + case "$gl_cv_func_getdtablesize_works" in + *yes | "no (limitation)") ;; + *) REPLACE_GETDTABLESIZE=1 ;; + esac + else + HAVE_GETDTABLESIZE=0 + fi +]) + +# Prerequisites of lib/getdtablesize.c. +AC_DEFUN([gl_PREREQ_GETDTABLESIZE], [:]) diff --git a/gl/m4/gethostname.m4 b/gl/m4/gethostname.m4 index 7413f9e3..11f22b2f 100644 --- a/gl/m4/gethostname.m4 +++ b/gl/m4/gethostname.m4 @@ -1,5 +1,5 @@ -# gethostname.m4 serial 13 -dnl Copyright (C) 2002, 2008-2013 Free Software Foundation, Inc. +# gethostname.m4 serial 15 +dnl Copyright (C) 2002, 2008-2022 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. @@ -48,7 +48,7 @@ AC_DEFUN([gl_PREREQ_HOST_NAME_MAX], [ dnl - On most Unix systems, use MAXHOSTNAMELEN from instead. dnl - On Solaris, Cygwin, BeOS, use MAXHOSTNAMELEN from instead. dnl - On mingw, use 256, because - dnl says: + dnl says: dnl "if a buffer of 256 bytes is passed in the name parameter and dnl the namelen parameter is set to 256, the buffer size will always dnl be adequate." @@ -74,7 +74,7 @@ lucky dnl mingw. gl_cv_decl_HOST_NAME_MAX=256 else - _AC_COMPUTE_INT([MAXHOSTNAMELEN], [gl_cv_decl_HOST_NAME_MAX], [ + AC_COMPUTE_INT([gl_cv_decl_HOST_NAME_MAX], [MAXHOSTNAMELEN], [ #include #if HAVE_SYS_PARAM_H # include diff --git a/gl/m4/getline.m4 b/gl/m4/getline.m4 new file mode 100644 index 00000000..ca0301d2 --- /dev/null +++ b/gl/m4/getline.m4 @@ -0,0 +1,109 @@ +# getline.m4 serial 30 + +dnl Copyright (C) 1998-2003, 2005-2007, 2009-2022 Free Software Foundation, +dnl Inc. +dnl +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_PREREQ([2.59]) + +dnl See if there's a working, system-supplied version of the getline function. +dnl We can't just do AC_REPLACE_FUNCS([getline]) because some systems +dnl have a function by that name in -linet that doesn't have anything +dnl to do with the function we need. +AC_DEFUN([gl_FUNC_GETLINE], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Persuade glibc to declare getline(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([getline]) + + gl_getline_needs_run_time_check=no + AC_CHECK_FUNC([getline], + [dnl Found it in some library. Verify that it works. + gl_getline_needs_run_time_check=yes], + [am_cv_func_working_getline=no]) + if test $gl_getline_needs_run_time_check = yes; then + AC_CACHE_CHECK([for working getline function], + [am_cv_func_working_getline], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +# include +# include +# include + int main () + { + FILE *in = fopen ("./conftest.data", "r"); + if (!in) + return 1; + { + /* Test result for a NULL buffer and a zero size. + Based on a test program from Karl Heuer. */ + char *line = NULL; + size_t siz = 0; + int len = getline (&line, &siz, in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) + { free (line); fclose (in); return 2; } + free (line); + } + { + /* Test result for a NULL buffer and a non-zero size. + This crashes on FreeBSD 8.0. */ + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getline (&line, &siz, in) == -1) + { fclose (in); return 3; } + free (line); + } + fclose (in); + return 0; + } + ]])], + [am_cv_func_working_getline=yes], + [am_cv_func_working_getline=no], + [dnl We're cross compiling. + dnl Guess it works on glibc2 systems and musl systems. + AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif +#endif + ], + [am_cv_func_working_getline="guessing yes"], + [case "$host_os" in + *-musl*) am_cv_func_working_getline="guessing yes" ;; + *) am_cv_func_working_getline="$gl_cross_guess_normal" ;; + esac + ]) + ]) + ]) + fi + + if test $ac_cv_have_decl_getline = no; then + HAVE_DECL_GETLINE=0 + fi + + case "$am_cv_func_working_getline" in + *yes) ;; + *) + dnl Set REPLACE_GETLINE always: Even if we have not found the broken + dnl getline function among $LIBS, it may exist in libinet and the + dnl executable may be linked with -linet. + REPLACE_GETLINE=1 + ;; + esac +]) + +# Prerequisites of lib/getline.c. +AC_DEFUN([gl_PREREQ_GETLINE], +[ + : +]) diff --git a/gl/m4/getloadavg.m4 b/gl/m4/getloadavg.m4 index 611372aa..7bb8890b 100644 --- a/gl/m4/getloadavg.m4 +++ b/gl/m4/getloadavg.m4 @@ -1,13 +1,13 @@ # Check for getloadavg. -# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2013 Free Software +# Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2022 Free Software # Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 6 +#serial 10 # Autoconf defines AC_FUNC_GETLOADAVG, but that is obsolescent. # New applications should use gl_GETLOADAVG instead. @@ -22,7 +22,7 @@ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) gl_save_LIBS=$LIBS -# getloadvg is present in libc on glibc >= 2.2, Mac OS X, FreeBSD >= 2.0, +# getloadavg is present in libc on glibc >= 2.2, Mac OS X, FreeBSD >= 2.0, # NetBSD >= 0.9, OpenBSD >= 2.0, Solaris >= 7. HAVE_GETLOADAVG=1 AC_CHECK_FUNC([getloadavg], [], @@ -45,7 +45,9 @@ AC_CHECK_FUNC([getloadavg], [], # There is a commonly available library for RS/6000 AIX. # Since it is not a standard part of AIX, it might be installed locally. gl_getloadavg_LIBS=$LIBS - LIBS="-L/usr/local/lib $LIBS" + if test $cross_compiling != yes; then + LIBS="-L/usr/local/lib $LIBS" + fi AC_CHECK_LIB([getloadavg], [getloadavg], [LIBS="-lgetloadavg $LIBS" gl_func_getloadavg_done=yes], [LIBS=$gl_getloadavg_LIBS]) @@ -92,6 +94,9 @@ else fi AC_CHECK_DECL([getloadavg], [], [HAVE_DECL_GETLOADAVG=0], [[#if HAVE_SYS_LOADAVG_H + /* OpenIndiana has a bug: must be included before + . */ + # include # include #endif #include ]]) @@ -105,7 +110,7 @@ AC_DEFUN([gl_PREREQ_GETLOADAVG], [ # Figure out what our getloadavg.c needs. -AC_CHECK_HEADERS_ONCE([sys/param.h]) +AC_CHECK_HEADERS_ONCE([sys/param.h unistd.h]) # On HPUX9, an unprivileged user can get load averages this way. if test $gl_func_getloadavg_done = no; then @@ -142,7 +147,7 @@ fi AC_CHECK_HEADERS([nlist.h], [AC_CHECK_MEMBERS([struct nlist.n_un.n_name], [], [], - [@%:@include ]) + [#include ]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct nlist x; #ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME diff --git a/gl/m4/getopt.m4 b/gl/m4/getopt.m4 index 50f45091..ff78ed53 100644 --- a/gl/m4/getopt.m4 +++ b/gl/m4/getopt.m4 @@ -1,5 +1,5 @@ -# getopt.m4 serial 44 -dnl Copyright (C) 2002-2006, 2008-2013 Free Software Foundation, Inc. +# getopt.m4 serial 48 +dnl Copyright (C) 2002-2006, 2008-2022 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. @@ -21,6 +21,8 @@ AC_DEFUN([gl_FUNC_GETOPT_POSIX], REPLACE_GETOPT=1 fi ]) + GL_GENERATE_GETOPT_H=false + GL_GENERATE_GETOPT_CDEFS_H=false if test $REPLACE_GETOPT = 1; then dnl Arrange for getopt.h to be created. gl_GETOPT_SUBSTITUTE_HEADER @@ -32,9 +34,16 @@ AC_DEFUN([gl_FUNC_GETOPT_POSIX], # getopt_long_only. AC_DEFUN([gl_FUNC_GETOPT_GNU], [ + dnl Set the variable gl_getopt_required, so that all invocations of + dnl gl_GETOPT_CHECK_HEADERS in the scope of the current configure file + dnl will check for getopt with GNU extensions. + dnl This means that if one gnulib-tool invocation requests getopt-posix + dnl and another gnulib-tool invocation requests getopt-gnu, it is as if + dnl both had requested getopt-gnu. m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU]) - AC_REQUIRE([gl_FUNC_GETOPT_POSIX]) + dnl No need to invoke gl_FUNC_GETOPT_POSIX here; this is automatically + dnl done through the module dependency getopt-gnu -> getopt-posix. ]) # Determine whether to replace the entire getopt facility. @@ -295,8 +304,10 @@ dnl is ambiguous with environment values that contain newlines. ]])], [gl_cv_func_getopt_gnu=yes], [gl_cv_func_getopt_gnu=no], - [dnl Cross compiling. Assume the worst, even on glibc platforms. - gl_cv_func_getopt_gnu="guessing no" + [dnl Cross compiling. + dnl Assume the worst, even on glibc platforms. + dnl But obey --enable-cross-guesses. + gl_cv_func_getopt_gnu="$gl_cross_guess_normal" ]) case $gl_had_POSIXLY_CORRECT in exported) ;; @@ -354,15 +365,17 @@ dnl is ambiguous with environment values that contain newlines. AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], [ - GETOPT_H=getopt.h + AC_CHECK_HEADERS_ONCE([sys/cdefs.h]) + if test $ac_cv_header_sys_cdefs_h = yes; then + HAVE_SYS_CDEFS_H=1 + else + HAVE_SYS_CDEFS_H=0 + fi + AC_SUBST([HAVE_SYS_CDEFS_H]) + AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], [Define to rpl_ if the getopt replacement functions and variables should be used.]) - AC_SUBST([GETOPT_H]) -]) - -# Prerequisites of lib/getopt*. -AC_DEFUN([gl_PREREQ_GETOPT], -[ - AC_CHECK_DECLS_ONCE([getenv]) + GL_GENERATE_GETOPT_H=true + GL_GENERATE_GETOPT_CDEFS_H=true ]) diff --git a/gl/m4/getprogname.m4 b/gl/m4/getprogname.m4 new file mode 100644 index 00000000..b26146e9 --- /dev/null +++ b/gl/m4/getprogname.m4 @@ -0,0 +1,43 @@ +# getprogname.m4 - check for getprogname or replacements for it + +# Copyright (C) 2016-2022 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +AC_DEFUN([gl_FUNC_GETPROGNAME], +[ + AC_CHECK_FUNCS_ONCE([getprogname getexecname]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + ac_found=0 + AC_CHECK_DECLS([program_invocation_name], [ac_found=1], [], + [#include ]) + AC_CHECK_DECLS([program_invocation_short_name], [ac_found=1], [], + [#include ]) + AC_CHECK_DECLS([__argv], [ac_found=1], [], [#include ]) + + # Incur the cost of this test only if none of the above worked. + if test $ac_found = 0; then + # On OpenBSD 5.1, using the global __progname variable appears to be + # the only way to implement getprogname. + AC_CACHE_CHECK([whether __progname is defined in default libraries], + [gl_cv_var___progname], + [ + gl_cv_var___progname= + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern char *__progname;]], + [[return *__progname;]] + )], + [gl_cv_var___progname=yes] + ) + ] + ) + if test "$gl_cv_var___progname" = yes; then + AC_DEFINE([HAVE_VAR___PROGNAME], 1, + [Define if you have a global __progname variable]) + fi + fi +]) diff --git a/gl/m4/gettext.m4 b/gl/m4/gettext.m4 index 8d1f0665..989d6456 100644 --- a/gl/m4/gettext.m4 +++ b/gl/m4/gettext.m4 @@ -1,16 +1,16 @@ -# gettext.m4 serial 66 (gettext-0.18.2) -dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. +# gettext.m4 serial 71 (gettext-0.20.2) +dnl Copyright (C) 1995-2014, 2016, 2018-2022 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: @@ -20,15 +20,13 @@ dnl Bruno Haible , 2000-2006, 2008-2010. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). -dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The -dnl default (if it is not specified or empty) is 'no-libtool'. -dnl INTLSYMBOL should be 'external' for packages with no intl directory, -dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl INTLSYMBOL must be one of 'external', 'use-libtool'. +dnl INTLSYMBOL should be 'external' for packages other than GNU gettext, and +dnl 'use-libtool' for the packages 'gettext-runtime' and 'gettext-tools'. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of -dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library -dnl $(top_builddir)/intl/libintl.a will be created. +dnl AM-DISABLE-SHARED). dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is @@ -57,19 +55,17 @@ dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. - ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT -])])])])]) +])])])]) ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], - [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])]) + [errprint([ERROR: Use of AM_GNU_GETTEXT without [external] argument is no longer supported. +])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define([gt_included_intl], - ifelse([$1], [external], - ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), - [yes])) - define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) + ifelse([$1], [external], [no], [yes])) gt_NEEDS_INIT AM_GNU_GETTEXT_NEED([$2]) @@ -91,8 +87,7 @@ AC_DEFUN([AM_GNU_GETTEXT], dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. - dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not - dnl documented, we avoid it. + dnl Since AC_PROVIDE_IFELSE is not documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) @@ -161,13 +156,18 @@ changequote([,])dnl [AC_LANG_PROGRAM( [[ #include -$gt_revision_test_code +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code ]], [[ bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ]])], [eval "$gt_func_gnugettext_libc=yes"], [eval "$gt_func_gnugettext_libc=no"])]) @@ -193,17 +193,22 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_b [AC_LANG_PROGRAM( [[ #include -$gt_revision_test_code +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code ]], [[ bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ]])], [eval "$gt_func_gnugettext_libintl=yes"], [eval "$gt_func_gnugettext_libintl=no"]) @@ -214,17 +219,22 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a [AC_LANG_PROGRAM( [[ #include -$gt_revision_test_code +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code ]], [[ bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ]])], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" @@ -263,8 +273,8 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a dnl Mark actions used to generate GNU NLS library. BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LTLIBICONV $LTLIBTHREAD" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi @@ -332,43 +342,14 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a fi ifelse(gt_included_intl, yes, [ - dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL - dnl to 'yes' because some of the testsuite requires it. - if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then - BUILD_INCLUDED_LIBINTL=yes - fi + dnl In GNU gettext we have to set BUILD_INCLUDED_LIBINTL to 'yes' + dnl because some of the testsuite requires it. + BUILD_INCLUDED_LIBINTL=yes dnl Make all variables we use known to autoconf. AC_SUBST([BUILD_INCLUDED_LIBINTL]) AC_SUBST([USE_INCLUDED_LIBINTL]) AC_SUBST([CATOBJEXT]) - - dnl For backward compatibility. Some configure.ins may be using this. - nls_cv_header_intl= - nls_cv_header_libgt= - - dnl For backward compatibility. Some Makefiles may be using this. - DATADIRNAME=share - AC_SUBST([DATADIRNAME]) - - dnl For backward compatibility. Some Makefiles may be using this. - INSTOBJEXT=.mo - AC_SUBST([INSTOBJEXT]) - - dnl For backward compatibility. Some Makefiles may be using this. - GENCAT=gencat - AC_SUBST([GENCAT]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLOBJS= - if test "$USE_INCLUDED_LIBINTL" = yes; then - INTLOBJS="\$(GETTOBJS)" - fi - AC_SUBST([INTLOBJS]) - - dnl Enable libtool support if the surrounding package wishes it. - INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix - AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX]) ]) dnl For backward compatibility. Some Makefiles may be using this. @@ -399,3 +380,7 @@ AC_DEFUN([AM_GNU_GETTEXT_NEED], dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) + + +dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], []) diff --git a/gl/m4/gl-openssl.m4 b/gl/m4/gl-openssl.m4 new file mode 100644 index 00000000..d076f844 --- /dev/null +++ b/gl/m4/gl-openssl.m4 @@ -0,0 +1,76 @@ +# gl-openssl.m4 serial 6 +dnl Copyright (C) 2013-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_SET_CRYPTO_CHECK_DEFAULT], +[ + m4_define([gl_CRYPTO_CHECK_DEFAULT], [$1]) +]) +gl_SET_CRYPTO_CHECK_DEFAULT([no]) + +AC_DEFUN([gl_CRYPTO_CHECK], +[ + dnl gnulib users set this before gl_INIT with gl_SET_CRYPTO_CHECK_DEFAULT() + m4_divert_once([DEFAULTS], [with_openssl_default='gl_CRYPTO_CHECK_DEFAULT']) + + dnl Only clear once, so crypto routines can be checked for individually + m4_divert_once([DEFAULTS], [LIB_CRYPTO=]) + + AC_ARG_WITH([openssl], + [[ --with-openssl[=ARG] use libcrypto hash routines for the hash functions + MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512. + Valid ARGs are: + 'yes', + 'no', + 'auto' => use if any version available, + 'auto-gpl-compat' => use if GPL compatible version + available, + 'optional' => use if available + and warn if not available; + Default is ']gl_CRYPTO_CHECK_DEFAULT['.]m4_ifdef([gl_AF_ALG], [ + Note also --with-linux-crypto, which will enable the + use of Linux kernel crypto routines (if available), + which has precedence for files.])], + [], + [with_openssl=$with_openssl_default]) + + AC_SUBST([LIB_CRYPTO]) + if test "x$with_openssl" != xno; then + if test "x$with_openssl" = xauto-gpl-compat; then + AC_CACHE_CHECK([whether openssl is GPL compatible], + [gl_cv_openssl_gpl_compat], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #if OPENSSL_VERSION_MAJOR < 3 + #error "openssl >= version 3 not found" + #endif + ]])], + [gl_cv_openssl_gpl_compat=yes], + [gl_cv_openssl_gpl_compat=no])]) + fi + if test "x$with_openssl" != xauto-gpl-compat || + test "x$gl_cv_openssl_gpl_compat" = xyes; then + AC_CHECK_LIB([crypto], [$1], + [AC_CHECK_HEADERS( + m4_if([$1], [MD5], [openssl/md5.h], [openssl/sha.h]), + [LIB_CRYPTO=-lcrypto + AC_DEFINE([HAVE_OPENSSL_$1], [1], + [Define to 1 if libcrypto is used for $1.])])]) + fi + if test "x$LIB_CRYPTO" = x; then + message='openssl development library not found for $1. + If you want to install it, first find the pre-built package name: + - On Debian and Debian-based systems: libssl-dev, + - On Red Hat distributions: openssl-devel. + - Other: https://repology.org/project/openssl/versions' + if test "x$with_openssl" = xyes; then + AC_MSG_ERROR([$message]) + elif test "x$with_openssl" = xoptional; then + AC_MSG_WARN([$message]) + fi + fi + fi +]) diff --git a/gl/m4/glibc2.m4 b/gl/m4/glibc2.m4 deleted file mode 100644 index 0e506826..00000000 --- a/gl/m4/glibc2.m4 +++ /dev/null @@ -1,31 +0,0 @@ -# glibc2.m4 serial 3 -dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 Free Software Foundation, -dnl 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. - -# Test for the GNU C Library, version 2.0 or newer. -# From Bruno Haible. - -AC_DEFUN([gt_GLIBC2], - [ - AC_CACHE_CHECK([whether we are using the GNU C Library 2 or newer], - [ac_cv_gnu_library_2], - [AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) && !defined __UCLIBC__ - Lucky GNU user - #endif -#endif - ], - [ac_cv_gnu_library_2=yes], - [ac_cv_gnu_library_2=no]) - ] - ) - AC_SUBST([GLIBC2]) - GLIBC2="$ac_cv_gnu_library_2" - ] -) diff --git a/gl/m4/glibc21.m4 b/gl/m4/glibc21.m4 deleted file mode 100644 index 613fb2a4..00000000 --- a/gl/m4/glibc21.m4 +++ /dev/null @@ -1,34 +0,0 @@ -# glibc21.m4 serial 5 -dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 Free Software Foundation, -dnl 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. - -# Test for the GNU C Library, version 2.1 or newer, or uClibc. -# From Bruno Haible. - -AC_DEFUN([gl_GLIBC21], - [ - AC_CACHE_CHECK([whether we are using the GNU C Library >= 2.1 or uClibc], - [ac_cv_gnu_library_2_1], - [AC_EGREP_CPP([Lucky], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) - Lucky GNU user - #endif -#endif -#ifdef __UCLIBC__ - Lucky user -#endif - ], - [ac_cv_gnu_library_2_1=yes], - [ac_cv_gnu_library_2_1=no]) - ] - ) - AC_SUBST([GLIBC21]) - GLIBC21="$ac_cv_gnu_library_2_1" - ] -) diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4 index 90ad4aaa..9d0128a0 100644 --- a/gl/m4/gnulib-cache.m4 +++ b/gl/m4/gnulib-cache.m4 @@ -1,8 +1,8 @@ -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2022 Free Software Foundation, Inc. # # 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 -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This file is distributed in the hope that it will be useful, @@ -11,7 +11,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this file. If not, see . +# along with this file. If not, see . # # As a special exception to the GNU General Public License, # this file may be distributed as part of a program that @@ -27,7 +27,39 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext idpriv-droptemp mountlist regex setenv strcase strcasestr strsep timegm unsetenv vasprintf vsnprintf +# gnulib-tool --import \ +# --lib=libgnu \ +# --source-base=gl \ +# --m4-base=gl/m4 \ +# --doc-base=doc \ +# --tests-base=tests \ +# --aux-dir=build-aux \ +# --no-conditional-dependencies \ +# --no-libtool \ +# --macro-prefix=gl \ +# --no-vc-files \ +# base64 \ +# crypto/sha1 \ +# dirname \ +# environ \ +# floorf \ +# fsusage \ +# getaddrinfo \ +# gethostname \ +# getloadavg \ +# getopt-gnu \ +# gettext \ +# idpriv-droptemp \ +# mountlist \ +# regex \ +# setenv \ +# strcase \ +# strcasestr \ +# strsep \ +# timegm \ +# unsetenv \ +# vasprintf \ +# vsnprintf # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) diff --git a/gl/m4/gnulib-common.m4 b/gl/m4/gnulib-common.m4 index 0ae5a9ec..30911d15 100644 --- a/gl/m4/gnulib-common.m4 +++ b/gl/m4/gnulib-common.m4 @@ -1,25 +1,54 @@ -# gnulib-common.m4 serial 33 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +# gnulib-common.m4 serial 73 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. +AC_PREREQ([2.62]) + # gl_COMMON # is expanded unconditionally through gnulib-tool magic. AC_DEFUN([gl_COMMON], [ dnl Use AC_REQUIRE here, so that the code is expanded once only. AC_REQUIRE([gl_00GNULIB]) AC_REQUIRE([gl_COMMON_BODY]) + AC_REQUIRE([gl_ZZGNULIB]) ]) AC_DEFUN([gl_COMMON_BODY], [ + AH_VERBATIM([_GL_GNUC_PREREQ], +[/* True if the compiler says it groks GNU C version MAJOR.MINOR. */ +#if defined __GNUC__ && defined __GNUC_MINOR__ +# define _GL_GNUC_PREREQ(major, minor) \ + ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__)) +#else +# define _GL_GNUC_PREREQ(major, minor) 0 +#endif +]) AH_VERBATIM([_Noreturn], [/* The _Noreturn keyword of C11. */ -#if ! (defined _Noreturn \ - || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) -# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ - || 0x5110 <= __SUNPRO_C) +#ifndef _Noreturn +# if (defined __cplusplus \ + && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + 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) \ + || (!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__)) -# elif defined _MSC_VER && 1200 <= _MSC_VER +# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) # define _Noreturn __declspec (noreturn) # else # define _Noreturn @@ -36,33 +65,448 @@ AC_DEFUN([gl_COMMON_BODY], [ #if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ # define __GNUC_STDC_INLINE__ 1 #endif]) - AH_VERBATIM([unused_parameter], -[/* Define as a marker that can be attached to declarations that might not - be used. This helps to reduce warnings, such as from - GCC -Wunused-parameter. */ -#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_UNUSED __attribute__ ((__unused__)) + AH_VERBATIM([attribute], +[/* Attributes. */ +#if (defined __has_attribute \ + && (!defined __clang_minor__ \ + || (defined __apple_build_version__ \ + ? 6000000 <= __apple_build_version__ \ + : 3 < __clang_major__ + (5 <= __clang_minor__)))) +# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__) #else -# define _GL_UNUSED +# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr +# define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2) +# define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95) +# define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1) +# define _GL_ATTR_diagnose_if 0 +# define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3) +# define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1) +# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0) +# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7) +# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6) +# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0) +# ifdef _ICC +# define _GL_ATTR_may_alias 0 +# else +# define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3) +# endif +# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1) +# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3) +# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0) +# define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) +# define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) +# define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96) +# define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9) +# define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0) +# define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7) +# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4) #endif -/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name - is a misnomer outside of parameter lists. */ -#define _UNUSED_PARAMETER_ _GL_UNUSED -/* The __pure__ attribute was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#ifdef __has_c_attribute +# if ((defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) <= 201710 \ + && _GL_GNUC_PREREQ (4, 6)) +# pragma GCC diagnostic ignored "-Wpedantic" +# endif +# define _GL_HAS_C_ATTRIBUTE(attr) __has_c_attribute (__##attr##__) +#else +# define _GL_HAS_C_ATTRIBUTE(attr) 0 +#endif + +]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's _Alignas instead. +[ +/* _GL_ATTRIBUTE_ALLOC_SIZE ((N)) declares that the Nth argument of the function + is the size of the returned memory block. + _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied + by the Nth argument of the function is the size of the returned memory block. + */ +/* Applies to: function, pointer to function, function types. */ +#if _GL_HAS_ATTRIBUTE (alloc_size) +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) +#else +# define _GL_ATTRIBUTE_ALLOC_SIZE(args) +#endif + +/* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the + function and report an error if it cannot do so. */ +/* Applies to: function. */ +#if _GL_HAS_ATTRIBUTE (always_inline) +# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) +#else +# define _GL_ATTRIBUTE_ALWAYS_INLINE +#endif + +/* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show + in stack traces when debugging. The compiler should omit the function from + stack traces. */ +/* Applies to: function. */ +#if _GL_HAS_ATTRIBUTE (artificial) +# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) #else -# define _GL_ATTRIBUTE_PURE /* empty */ +# define _GL_ATTRIBUTE_ARTIFICIAL #endif -/* The __const__ attribute was added in gcc 2.95. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +/* _GL_ATTRIBUTE_COLD declares that the function is rarely executed. */ +/* Applies to: functions. */ +/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at + . + Also, Oracle Studio 12.6 requires 'cold' not '__cold__'. */ +#if _GL_HAS_ATTRIBUTE (cold) && !defined __MINGW32__ +# ifndef __SUNPRO_C +# define _GL_ATTRIBUTE_COLD __attribute__ ((__cold__)) +# else +# define _GL_ATTRIBUTE_COLD __attribute__ ((cold)) +# endif +#else +# define _GL_ATTRIBUTE_COLD +#endif + +/* _GL_ATTRIBUTE_CONST declares that it is OK for a compiler to omit duplicate + calls to the function with the same arguments. + This attribute is safe for a function that neither depends on nor affects + observable state, and always returns exactly once - e.g., does not loop + forever, and does not call longjmp. + (This attribute is stricter than _GL_ATTRIBUTE_PURE.) */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (const) # define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) #else -# define _GL_ATTRIBUTE_CONST /* empty */ +# define _GL_ATTRIBUTE_CONST +#endif + +/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers + that can be freed by passing them as the Ith argument to the + function F. + _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that + can be freed via 'free'; it can be used only after declaring 'free'. */ +/* Applies to: functions. Cannot be used on inline functions. */ +#if _GL_GNUC_PREREQ (11, 0) +# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) +#else +# define _GL_ATTRIBUTE_DEALLOC(f, i) +#endif +/* If gnulib's or has already defined this macro, continue + to use this earlier definition, since may not have been included + yet. */ +#ifndef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1) +#endif + +/* _GL_ATTRIBUTE_DEPRECATED: Declares that an entity is deprecated. + The compiler may warn if the entity is used. */ +/* Applies to: + - function, variable, + - struct, union, struct/union member, + - enumeration, enumeration item, + - typedef, + in C++ also: namespace, class, template specialization. */ +#if _GL_HAS_C_ATTRIBUTE (deprecated) +# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]] +#elif _GL_HAS_ATTRIBUTE (deprecated) +# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) +#else +# define _GL_ATTRIBUTE_DEPRECATED +#endif + +/* _GL_ATTRIBUTE_ERROR(msg) requests an error if a function is called and + the function call is not optimized away. + _GL_ATTRIBUTE_WARNING(msg) requests a warning if a function is called and + the function call is not optimized away. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (error) +# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg))) +# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg))) +#elif _GL_HAS_ATTRIBUTE (diagnose_if) +# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, "error"))) +# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, "warning"))) +#else +# define _GL_ATTRIBUTE_ERROR(msg) +# define _GL_ATTRIBUTE_WARNING(msg) +#endif + +/* _GL_ATTRIBUTE_EXTERNALLY_VISIBLE declares that the entity should remain + visible to debuggers etc., even with '-fwhole-program'. */ +/* Applies to: functions, variables. */ +#if _GL_HAS_ATTRIBUTE (externally_visible) +# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible)) +#else +# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE +#endif + +/* _GL_ATTRIBUTE_FALLTHROUGH declares that it is not a programming mistake if + the control flow falls through to the immediately following 'case' or + 'default' label. The compiler should not warn in this case. */ +/* Applies to: Empty statement (;), inside a 'switch' statement. */ +/* Always expands to something. */ +#if _GL_HAS_C_ATTRIBUTE (fallthrough) +# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]] +#elif _GL_HAS_ATTRIBUTE (fallthrough) +# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__)) +#else +# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0) +#endif + +/* _GL_ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)) + declares that the STRING-INDEXth function argument is a format string of + style ARCHETYPE, which is one of: + printf, gnu_printf + scanf, gnu_scanf, + strftime, gnu_strftime, + strfmon, + or the same thing prefixed and suffixed with '__'. + If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK + are suitable for the format string. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (format) +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#else +# define _GL_ATTRIBUTE_FORMAT(spec) +#endif + +/* _GL_ATTRIBUTE_LEAF declares that if the function is called from some other + compilation unit, it executes code from that unit only by return or by + exception handling. This declaration lets the compiler optimize that unit + more aggressively. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (leaf) +# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__)) +#else +# define _GL_ATTRIBUTE_LEAF +#endif + +/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly + allocated memory. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (malloc) +# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +#else +# define _GL_ATTRIBUTE_MALLOC +#endif + +/* _GL_ATTRIBUTE_MAY_ALIAS declares that pointers to the type may point to the + same storage as pointers to other types. Thus this declaration disables + strict aliasing optimization. */ +/* Applies to: types. */ +/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK. */ +#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C +# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__)) +#else +# define _GL_ATTRIBUTE_MAY_ALIAS +#endif + +/* _GL_ATTRIBUTE_MAYBE_UNUSED declares that it is not a programming mistake if + the entity is not used. The compiler should not warn if the entity is not + used. */ +/* Applies to: + - function, variable, + - struct, union, struct/union member, + - enumeration, enumeration item, + - typedef, + in C++ also: class. */ +/* In C++ and C2x, this is spelled [[__maybe_unused__]]. + GCC's syntax is __attribute__ ((__unused__)). + clang supports both syntaxes. */ +#if _GL_HAS_C_ATTRIBUTE (maybe_unused) +# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]] +#else +# define _GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_UNUSED +#endif +/* Alternative spelling of this macro, for convenience. */ +#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED +/* Earlier spellings of this macro. */ +#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED + +/* _GL_ATTRIBUTE_NODISCARD declares that the caller of the function should not + discard the return value. The compiler may warn if the caller does not use + the return value, unless the caller uses something like ignore_value. */ +/* Applies to: function, enumeration, class. */ +#if _GL_HAS_C_ATTRIBUTE (nodiscard) +# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]] +#elif _GL_HAS_ATTRIBUTE (warn_unused_result) +# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__)) +#else +# define _GL_ATTRIBUTE_NODISCARD +#endif + +/* _GL_ATTRIBUTE_NOINLINE tells that the compiler should not inline the + function. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (noinline) +# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__)) +#else +# define _GL_ATTRIBUTE_NOINLINE +#endif + +/* _GL_ATTRIBUTE_NONNULL ((N1, N2,...)) declares that the arguments N1, N2,... + must not be NULL. + _GL_ATTRIBUTE_NONNULL () declares that all pointer arguments must not be + null. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (nonnull) +# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args)) +#else +# define _GL_ATTRIBUTE_NONNULL(args) +#endif + +/* _GL_ATTRIBUTE_NONSTRING declares that the contents of a character array is + not meant to be NUL-terminated. */ +/* Applies to: struct/union members and variables that are arrays of element + type '[[un]signed] char'. */ +#if _GL_HAS_ATTRIBUTE (nonstring) +# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__)) +#else +# define _GL_ATTRIBUTE_NONSTRING +#endif + +/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead. */ + +/* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. + */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus +# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__)) +#else +# define _GL_ATTRIBUTE_NOTHROW +#endif + +/* _GL_ATTRIBUTE_PACKED declares: + For struct members: The member has the smallest possible alignment. + For struct, union, class: All members have the smallest possible alignment, + minimizing the memory required. */ +/* Applies to: struct members, struct, union, + in C++ also: class. */ +#if _GL_HAS_ATTRIBUTE (packed) +# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) +#else +# define _GL_ATTRIBUTE_PACKED +#endif + +/* _GL_ATTRIBUTE_PURE declares that It is OK for a compiler to omit duplicate + calls to the function with the same arguments if observable state is not + changed between calls. + This attribute is safe for a function that does not affect + observable state, and always returns exactly once. + (This attribute is looser than _GL_ATTRIBUTE_CONST.) */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (pure) +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define _GL_ATTRIBUTE_PURE +#endif + +/* _GL_ATTRIBUTE_RETURNS_NONNULL declares that the function's return value is + a non-NULL pointer. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (returns_nonnull) +# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__)) +#else +# define _GL_ATTRIBUTE_RETURNS_NONNULL +#endif + +/* _GL_ATTRIBUTE_SENTINEL(pos) declares that the variadic function expects a + trailing NULL argument. + _GL_ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99). + _GL_ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL. */ +/* Applies to: functions. */ +#if _GL_HAS_ATTRIBUTE (sentinel) +# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos)) +#else +# define _GL_ATTRIBUTE_SENTINEL(pos) +#endif + +/* A helper macro. Don't use it directly. */ +#if _GL_HAS_ATTRIBUTE (unused) +# define _GL_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#else +# define _GL_ATTRIBUTE_UNUSED +#endif + +]dnl There is no _GL_ATTRIBUTE_VISIBILITY; see m4/visibility.m4 instead. +[ +/* _GL_UNUSED_LABEL; declares that it is not a programming mistake if the + immediately preceding label is not used. The compiler should not warn + if the label is not used. */ +/* Applies to: label (both in C and C++). */ +/* Note that g++ < 4.5 does not support the '__attribute__ ((__unused__)) ;' + syntax. But clang does. */ +#if !(defined __cplusplus && !_GL_GNUC_PREREQ (4, 5)) || defined __clang__ +# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_UNUSED +#else +# define _GL_UNUSED_LABEL #endif ]) + AH_VERBATIM([async_safe], +[/* The _GL_ASYNC_SAFE marker should be attached to functions that are + signal handlers (for signals other than SIGABRT, SIGPIPE) or can be + invoked from such signal handlers. Such functions have some restrictions: + * All functions that it calls should be marked _GL_ASYNC_SAFE as well, + or should be listed as async-signal-safe in POSIX + + section 2.4.3. Note that malloc(), sprintf(), and fwrite(), in + particular, are NOT async-signal-safe. + * All memory locations (variables and struct fields) that these functions + access must be marked 'volatile'. This holds for both read and write + accesses. Otherwise the compiler might optimize away stores to and + reads from such locations that occur in the program, depending on its + data flow analysis. For example, when the program contains a loop + that is intended to inspect a variable set from within a signal handler + while (!signal_occurred) + ; + the compiler is allowed to transform this into an endless loop if the + variable 'signal_occurred' is not declared 'volatile'. + Additionally, recall that: + * A signal handler should not modify errno (except if it is a handler + for a fatal signal and ends by raising the same signal again, thus + provoking the termination of the process). If it invokes a function + that may clobber errno, it needs to save and restore the value of + errno. */ +#define _GL_ASYNC_SAFE +]) + AH_VERBATIM([micro_optimizations], +[/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2, where + n1 and n2 are expressions without side effects, that evaluate to real + numbers (excluding NaN). + It returns + 1 if n1 > n2 + 0 if n1 == n2 + -1 if n1 < n2 + The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional + jump with nearly all GCC versions up to GCC 10. + This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional with many + GCC versions up to GCC 9. + The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9 + avoids conditional jumps in all GCC versions >= 3.4. */ +#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) +]) + dnl Hint which direction to take regarding cross-compilation guesses: + dnl When a user installs a program on a platform they are not intimately + dnl familiar with, --enable-cross-guesses=conservative is the appropriate + dnl choice. It implements the "If we don't know, assume the worst" principle. + dnl However, when an operating system developer (on a platform which is not + dnl yet known to gnulib) builds packages for their platform, they want to + dnl expose, not hide, possible platform bugs; in this case, + dnl --enable-cross-guesses=risky is the appropriate choice. + dnl Sets the variables + dnl gl_cross_guess_normal (to be used when 'yes' is good and 'no' is bad), + dnl gl_cross_guess_inverted (to be used when 'no' is good and 'yes' is bad). + AC_ARG_ENABLE([cross-guesses], + [AS_HELP_STRING([--enable-cross-guesses={conservative|risky}], + [specify policy for cross-compilation guesses])], + [if test "x$enableval" != xconservative && test "x$enableval" != xrisky; then + AC_MSG_WARN([invalid argument supplied to --enable-cross-guesses]) + enableval=conservative + fi + gl_cross_guesses="$enableval"], + [gl_cross_guesses=conservative]) + if test $gl_cross_guesses = risky; then + gl_cross_guess_normal="guessing yes" + gl_cross_guess_inverted="guessing no" + else + gl_cross_guess_normal="guessing no" + gl_cross_guess_inverted="guessing yes" + fi dnl Preparation for running test programs: dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not dnl to /dev/tty, so they can be redirected to log files. Such diagnostics @@ -71,6 +515,16 @@ AC_DEFUN([gl_COMMON_BODY], [ export LIBC_FATAL_STDERR_ ]) +# gl_MODULE_INDICATOR_INIT_VARIABLE([variablename]) +# gl_MODULE_INDICATOR_INIT_VARIABLE([variablename], [initialvalue]) +# initializes the shell variable that indicates the presence of the given module +# as a C preprocessor expression. +AC_DEFUN([gl_MODULE_INDICATOR_INIT_VARIABLE], +[ + GL_MODULE_INDICATOR_PREFIX[]_[$1]=m4_if([$2], , [0], [$2]) + AC_SUBST(GL_MODULE_INDICATOR_PREFIX[]_[$1]) +]) + # gl_MODULE_INDICATOR_CONDITION # expands to a C preprocessor expression that evaluates to 1 or 0, depending # whether a gnulib module that has been requested shall be considered present @@ -83,9 +537,9 @@ m4_define([gl_MODULE_INDICATOR_CONDITION], [1]) AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE], [ gl_MODULE_INDICATOR_SET_VARIABLE_AUX( - [GNULIB_[]m4_translit([[$1]], - [abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])], + [GL_MODULE_INDICATOR_PREFIX[]_GNULIB_[]m4_translit([[$1]], + [abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])], [gl_MODULE_INDICATOR_CONDITION]) ]) @@ -197,42 +651,20 @@ AC_DEFUN([gl_FEATURES_H], AC_SUBST([HAVE_FEATURES_H]) ]) -# m4_foreach_w -# is a backport of autoconf-2.59c's m4_foreach_w. -# Remove this macro when we can assume autoconf >= 2.60. -m4_ifndef([m4_foreach_w], - [m4_define([m4_foreach_w], - [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])]) - -# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH]) -# ---------------------------------------------------- -# Backport of autoconf-2.63b's macro. -# Remove this macro when we can assume autoconf >= 2.64. -m4_ifndef([AS_VAR_IF], -[m4_define([AS_VAR_IF], -[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])]) - # gl_PROG_CC_C99 # Modifies the value of the shell variable CC in an attempt to make $CC # understand ISO C99 source code. -# This is like AC_PROG_CC_C99, except that -# - AC_PROG_CC_C99 did not exist in Autoconf versions < 2.60, -# - AC_PROG_CC_C99 does not mix well with AC_PROG_CC_STDC -# , -# but many more packages use AC_PROG_CC_STDC than AC_PROG_CC_C99 -# . -# Remaining problems: -# - When AC_PROG_CC_STDC is invoked twice, it adds the C99 enabling options -# to CC twice -# . -# - AC_PROG_CC_STDC is likely to change now that C11 is an ISO standard. AC_DEFUN([gl_PROG_CC_C99], [ - dnl Change that version number to the minimum Autoconf version that supports - dnl mixing AC_PROG_CC_C99 calls with AC_PROG_CC_STDC calls. - m4_version_prereq([9.0], - [AC_REQUIRE([AC_PROG_CC_C99])], - [AC_REQUIRE([AC_PROG_CC_STDC])]) + dnl Just use AC_PROG_CC_C99. + dnl When AC_PROG_CC_C99 and AC_PROG_CC_STDC are used together, the substituted + dnl value of CC will contain the C99 enabling options twice. But this is only + dnl a cosmetic problem. + dnl With Autoconf >= 2.70, use AC_PROG_CC since it implies AC_PROG_CC_C99; + dnl this avoids a "warning: The macro `AC_PROG_CC_C99' is obsolete." + m4_version_prereq([2.70], + [AC_REQUIRE([AC_PROG_CC])], + [AC_REQUIRE([AC_PROG_CC_C99])]) ]) # gl_PROG_AR_RANLIB @@ -243,9 +675,11 @@ AC_DEFUN([gl_PROG_AR_RANLIB], [ dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler dnl as "cc", and GCC as "gcc". They have different object file formats and - dnl library formats. In particular, the GNU binutils programs ar, ranlib + dnl library formats. In particular, the GNU binutils programs ar and ranlib dnl produce libraries that work only with gcc, not with cc. AC_REQUIRE([AC_PROG_CC]) + dnl The '][' hides this use from 'aclocal'. + AC_BEFORE([$0], [A][M_PROG_AR]) AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler], [ AC_EGREP_CPP([Amsterdam], @@ -257,25 +691,39 @@ Amsterdam [gl_cv_c_amsterdam_compiler=yes], [gl_cv_c_amsterdam_compiler=no]) ]) - if test -z "$AR"; then - if test $gl_cv_c_amsterdam_compiler = yes; then + + dnl Don't compete with AM_PROG_AR's decision about AR/ARFLAGS if we are not + dnl building with __ACK__. + if test $gl_cv_c_amsterdam_compiler = yes; then + if test -z "$AR"; then AR='cc -c.a' - if test -z "$ARFLAGS"; then - ARFLAGS='-o' - fi - else - dnl Use the Automake-documented default values for AR and ARFLAGS, - dnl but prefer ${host}-ar over ar (useful for cross-compiling). - AC_CHECK_TOOL([AR], [ar], [ar]) - if test -z "$ARFLAGS"; then - ARFLAGS='cru' - fi fi - else if test -z "$ARFLAGS"; then - ARFLAGS='cru' + ARFLAGS='-o' fi + else + dnl AM_PROG_AR was added in automake v1.11.2. AM_PROG_AR does not AC_SUBST + dnl ARFLAGS variable (it is filed into Makefile.in directly by automake + dnl script on-demand, if not specified by ./configure of course). + dnl Don't AC_REQUIRE the AM_PROG_AR otherwise the code for __ACK__ above + dnl will be ignored. Also, pay attention to call AM_PROG_AR in else block + dnl because AM_PROG_AR is written so it could re-set AR variable even for + dnl __ACK__. It may seem like its easier to avoid calling the macro here, + dnl but we need to AC_SUBST both AR/ARFLAGS (thus those must have some good + dnl default value and automake should usually know them). + dnl + dnl The '][' hides this use from 'aclocal'. + m4_ifdef([A][M_PROG_AR], [A][M_PROG_AR], [:]) + fi + + dnl In case the code above has not helped with setting AR/ARFLAGS, use + dnl Automake-documented default values for AR and ARFLAGS, but prefer + dnl ${host}-ar over ar (useful for cross-compiling). + AC_CHECK_TOOL([AR], [ar], [ar]) + if test -z "$ARFLAGS"; then + ARFLAGS='cr' fi + AC_SUBST([AR]) AC_SUBST([ARFLAGS]) if test -z "$RANLIB"; then @@ -289,46 +737,29 @@ Amsterdam AC_SUBST([RANLIB]) ]) -# AC_PROG_MKDIR_P -# is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix -# for interoperability with automake-1.9.6 from autoconf-2.62. -# Remove this macro when we can assume autoconf >= 2.62 or -# autoconf >= 2.60 && automake >= 1.10. -# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. -m4_ifndef([AC_AUTOCONF_VERSION],[ -m4_ifdef([AC_PROG_MKDIR_P], [ - dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. - m4_define([AC_PROG_MKDIR_P], - m4_defn([AC_PROG_MKDIR_P])[ - AC_SUBST([MKDIR_P])])], [ - dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P. - AC_DEFUN_ONCE([AC_PROG_MKDIR_P], - [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake - MKDIR_P='$(mkdir_p)' - AC_SUBST([MKDIR_P])])]) -]) - # AC_C_RESTRICT -# This definition overrides the AC_C_RESTRICT macro from autoconf 2.60..2.61, -# so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++ -# works. -# This definition can be removed once autoconf >= 2.62 can be assumed. -# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. -m4_ifndef([AC_AUTOCONF_VERSION],[ +# This definition is copied from post-2.70 Autoconf and overrides the +# AC_C_RESTRICT macro from autoconf 2.60..2.70. +m4_version_prereq([2.70.1], [], [ AC_DEFUN([AC_C_RESTRICT], [AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict], [ac_cv_c_restrict=no - # The order here caters to the fact that C++ does not require restrict. - for ac_kw in __restrict __restrict__ _Restrict restrict; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( - [[typedef int * int_ptr; - int foo (int_ptr $ac_kw ip) { - return ip[0]; - }]], - [[int s[1]; - int * $ac_kw t = s; - t[0] = 0; - return foo(t)]])], + # Put '__restrict__' first, to avoid problems with glibc and non-GCC; see: + # https://lists.gnu.org/archive/html/bug-autoconf/2016-02/msg00006.html + # Put 'restrict' last, because C++ lacks it. + for ac_kw in __restrict__ __restrict _Restrict restrict; do + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[typedef int *int_ptr; + int foo (int_ptr $ac_kw ip) { return ip[0]; } + int bar (int [$ac_kw]); /* Catch GCC bug 14050. */ + int bar (int ip[$ac_kw]) { return ip[0]; } + ]], + [[int s[1]; + int *$ac_kw t = s; + t[0] = 0; + return foo (t) + bar (t); + ]])], [ac_cv_c_restrict=$ac_kw]) test "$ac_cv_c_restrict" != no && break done @@ -336,22 +767,24 @@ AC_DEFUN([AC_C_RESTRICT], AH_VERBATIM([restrict], [/* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is - supported directly. */ + supported only directly. */ #undef restrict -/* Work around a bug in Sun C++: it does not support _Restrict, even - though the corresponding Sun C compiler does, which causes - "#define restrict _Restrict" in the previous line. Perhaps some future - version of Sun C++ will work with _Restrict; if so, it'll probably - define __RESTRICT, just as Sun C does. */ -#if defined __SUNPRO_CC && !defined __RESTRICT +/* Work around a bug in older versions of Sun C++, which did not + #define __restrict__ or support _Restrict or __restrict__ + even though the corresponding Sun C compiler ended up with + "#define restrict _Restrict" or "#define restrict __restrict__" + in the previous line. This workaround can be removed once + we assume Oracle Developer Studio 12.5 (2016) or later. */ +#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__ # define _Restrict +# define __restrict__ #endif]) case $ac_cv_c_restrict in restrict) ;; no) AC_DEFINE([restrict], []) ;; *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;; esac -]) +])# AC_C_RESTRICT ]) # gl_BIGENDIAN @@ -363,6 +796,22 @@ AC_DEFUN([gl_BIGENDIAN], AC_C_BIGENDIAN ]) +# A temporary file descriptor. +# Must be less than 10, because dash 0.5.8 does not support redirections +# with multi-digit file descriptors. +m4_define([GL_TMP_FD], 9) + +# gl_SILENT(command) +# executes command, but without the normal configure output. +# This is useful when you want to invoke AC_CACHE_CHECK (or AC_CHECK_FUNC etc.) +# inside another AC_CACHE_CHECK. +AC_DEFUN([gl_SILENT], +[ + exec GL_TMP_FD>&AS_MESSAGE_FD AS_MESSAGE_FD>/dev/null + $1 + exec AS_MESSAGE_FD>&GL_TMP_FD GL_TMP_FD>&- +]) + # gl_CACHE_VAL_SILENT(cache-id, command-to-set-it) # is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not # output a spurious "(cached)" mark in the midst of other configure output. @@ -370,8 +819,257 @@ AC_DEFUN([gl_BIGENDIAN], # by an AC_MSG_CHECKING/AC_MSG_RESULT pair. AC_DEFUN([gl_CACHE_VAL_SILENT], [ - saved_as_echo_n="$as_echo_n" - as_echo_n=':' - AC_CACHE_VAL([$1], [$2]) - as_echo_n="$saved_as_echo_n" + gl_SILENT([ + AC_CACHE_VAL([$1], [$2]) + ]) +]) + +# gl_CONDITIONAL(conditional, condition) +# is like AM_CONDITIONAL(conditional, condition), except that it does not +# produce an error +# configure: error: conditional "..." was never defined. +# Usually this means the macro was only invoked conditionally. +# when only invoked conditionally. Instead, in that case, both the _TRUE +# and the _FALSE case are disabled. +AC_DEFUN([gl_CONDITIONAL], +[ + pushdef([AC_CONFIG_COMMANDS_PRE], [:])dnl + AM_CONDITIONAL([$1], [$2]) + popdef([AC_CONFIG_COMMANDS_PRE])dnl + if test -z "${[$1]_TRUE}" && test -z "${[$1]_FALSE}"; then + [$1]_TRUE='#' + [$1]_FALSE='#' + fi +]) + +# gl_CC_ALLOW_WARNINGS +# sets and substitutes a variable GL_CFLAG_ALLOW_WARNINGS, to a $(CC) option +# that reverts a preceding '-Werror' option, if available. +# This is expected to be '-Wno-error' on gcc, clang (except clang/MSVC), xlclang +# and empty otherwise. +AC_DEFUN([gl_CC_ALLOW_WARNINGS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([for C compiler option to allow warnings], + [gl_cv_cc_wallow], + [rm -f conftest* + echo 'int dummy;' > conftest.c + AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c 2>conftest1.err]) >/dev/null + AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Wno-error -c conftest.c 2>conftest2.err]) >/dev/null + dnl Test the number of error output lines, because AIX xlc accepts the + dnl option '-Wno-error', just to produce a warning + dnl "Option -Wno-error was incorrectly specified. The option will be ignored." + dnl afterwards. + if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then + gl_cv_cc_wallow='-Wno-error' + else + gl_cv_cc_wallow=none + fi + rm -f conftest* + ]) + case "$gl_cv_cc_wallow" in + none) GL_CFLAG_ALLOW_WARNINGS='' ;; + *) GL_CFLAG_ALLOW_WARNINGS="$gl_cv_cc_wallow" ;; + esac + AC_SUBST([GL_CFLAG_ALLOW_WARNINGS]) +]) + +# gl_CXX_ALLOW_WARNINGS +# sets and substitutes a variable GL_CXXFLAG_ALLOW_WARNINGS, to a $(CC) option +# that reverts a preceding '-Werror' option, if available. +AC_DEFUN([gl_CXX_ALLOW_WARNINGS], +[ + dnl Requires AC_PROG_CXX or gl_PROG_ANSI_CXX. + if test -n "$CXX" && test "$CXX" != no; then + AC_CACHE_CHECK([for C++ compiler option to allow warnings], + [gl_cv_cxx_wallow], + [rm -f conftest* + echo 'int dummy;' > conftest.cc + AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -c conftest.cc 2>conftest1.err]) >/dev/null + AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -Wno-error -c conftest.cc 2>conftest2.err]) >/dev/null + dnl Test the number of error output lines, because AIX xlC accepts the + dnl option '-Wno-error', just to produce a warning + dnl "Option -Wno-error was incorrectly specified. The option will be ignored." + dnl afterwards. + if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then + gl_cv_cxx_wallow='-Wno-error' + else + gl_cv_cxx_wallow=none + fi + rm -f conftest* + ]) + case "$gl_cv_cxx_wallow" in + none) GL_CXXFLAG_ALLOW_WARNINGS='' ;; + *) GL_CXXFLAG_ALLOW_WARNINGS="$gl_cv_cxx_wallow" ;; + esac + else + GL_CXXFLAG_ALLOW_WARNINGS='' + fi + AC_SUBST([GL_CXXFLAG_ALLOW_WARNINGS]) +]) + +# gl_CC_GNULIB_WARNINGS +# sets and substitutes a variable GL_CFLAG_GNULIB_WARNINGS, to a $(CC) option +# set that enables or disables warnings as suitable for the Gnulib coding style. +AC_DEFUN([gl_CC_GNULIB_WARNINGS], +[ + AC_REQUIRE([gl_CC_ALLOW_WARNINGS]) + dnl Assume that the compiler supports -Wno-* options only if it also supports + dnl -Wno-error. + GL_CFLAG_GNULIB_WARNINGS='' + if test -n "$GL_CFLAG_ALLOW_WARNINGS"; then + dnl Enable these warning options: + dnl + dnl GCC clang + dnl -Wno-cast-qual >= 3 >= 3.9 + dnl -Wno-conversion >= 3 >= 3.9 + dnl -Wno-float-conversion >= 4.9 >= 3.9 + dnl -Wno-float-equal >= 3 >= 3.9 + dnl -Wimplicit-fallthrough >= 7 >= 3.9 + dnl -Wno-pedantic >= 4.8 >= 3.9 + dnl -Wno-sign-compare >= 3 >= 3.9 + dnl -Wno-sign-conversion >= 4.3 >= 3.9 + dnl -Wno-type-limits >= 4.3 >= 3.9 + dnl -Wno-undef >= 3 >= 3.9 + dnl -Wno-unsuffixed-float-constants >= 4.5 + dnl -Wno-unused-function >= 3 >= 3.9 + dnl -Wno-unused-parameter >= 3 >= 3.9 + dnl + cat > conftest.c <<\EOF + #if __GNUC__ >= 3 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + -Wno-cast-qual + -Wno-conversion + -Wno-float-equal + -Wno-sign-compare + -Wno-undef + -Wno-unused-function + -Wno-unused-parameter + #endif + #if __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + -Wno-float-conversion + #endif + #if __GNUC__ >= 7 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + -Wimplicit-fallthrough + #endif + #if __GNUC__ + (__GNUC_MINOR__ >= 8) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + -Wno-pedantic + #endif + #if __GNUC__ + (__GNUC_MINOR__ >= 3) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + -Wno-sign-conversion + -Wno-type-limits + #endif + #if __GNUC__ + (__GNUC_MINOR__ >= 5) > 4 + -Wno-unsuffixed-float-constants + #endif +EOF + gl_command="$CC $CFLAGS $CPPFLAGS -E conftest.c > conftest.out" + if AC_TRY_EVAL([gl_command]); then + gl_options=`grep -v '#' conftest.out` + for word in $gl_options; do + GL_CFLAG_GNULIB_WARNINGS="$GL_CFLAG_GNULIB_WARNINGS $word" + done + fi + rm -f conftest.c conftest.out + fi + AC_SUBST([GL_CFLAG_GNULIB_WARNINGS]) +]) + +dnl gl_CONDITIONAL_HEADER([foo.h]) +dnl takes a shell variable GL_GENERATE_FOO_H (with value true or false) as input +dnl and produces +dnl - an AC_SUBSTed variable FOO_H that is either a file name or empty, based +dnl on whether GL_GENERATE_FOO_H is true or false, +dnl - an Automake conditional GL_GENERATE_FOO_H that evaluates to the value of +dnl the shell variable GL_GENERATE_FOO_H. +AC_DEFUN([gl_CONDITIONAL_HEADER], +[ + m4_pushdef([gl_header_name], AS_TR_SH(m4_toupper($1))) + m4_pushdef([gl_generate_var], [GL_GENERATE_]AS_TR_SH(m4_toupper($1))) + m4_pushdef([gl_generate_cond], [GL_GENERATE_]AS_TR_SH(m4_toupper($1))) + case "$gl_generate_var" in + false) gl_header_name='' ;; + true) + dnl It is OK to use a .h file in lib/ from within tests/, but not vice + dnl versa. + if test -z "$gl_header_name"; then + gl_header_name="${gl_source_base_prefix}$1" + fi + ;; + *) echo "*** gl_generate_var is not set correctly" 1>&2; exit 1 ;; + esac + AC_SUBST(gl_header_name) + gl_CONDITIONAL(gl_generate_cond, [$gl_generate_var]) + m4_popdef([gl_generate_cond]) + m4_popdef([gl_generate_var]) + m4_popdef([gl_header_name]) +]) + +dnl Expands to some code for use in .c programs that, on native Windows, defines +dnl the Microsoft deprecated alias function names to the underscore-prefixed +dnl actual function names. With this macro, these function names are available +dnl without linking with '-loldnames' and without generating warnings. +dnl Usage: Use it after all system header files are included. +dnl #include <...> +dnl #include <...> +dnl ]GL_MDA_DEFINES[ +dnl ... +AC_DEFUN([GL_MDA_DEFINES],[ +AC_REQUIRE([_GL_MDA_DEFINES]) +[$gl_mda_defines] +]) +AC_DEFUN([_GL_MDA_DEFINES], +[gl_mda_defines=' +#if defined _WIN32 && !defined __CYGWIN__ +#define access _access +#define chdir _chdir +#define chmod _chmod +#define close _close +#define creat _creat +#define dup _dup +#define dup2 _dup2 +#define ecvt _ecvt +#define execl _execl +#define execle _execle +#define execlp _execlp +#define execv _execv +#define execve _execve +#define execvp _execvp +#define execvpe _execvpe +#define fcloseall _fcloseall +#define fcvt _fcvt +#define fdopen _fdopen +#define fileno _fileno +#define gcvt _gcvt +#define getcwd _getcwd +#define getpid _getpid +#define getw _getw +#define isatty _isatty +#define j0 _j0 +#define j1 _j1 +#define jn _jn +#define lfind _lfind +#define lsearch _lsearch +#define lseek _lseek +#define memccpy _memccpy +#define mkdir _mkdir +#define mktemp _mktemp +#define open _open +#define putenv _putenv +#define putw _putw +#define read _read +#define rmdir _rmdir +#define strdup _strdup +#define swab _swab +#define tempnam _tempnam +#define tzset _tzset +#define umask _umask +#define unlink _unlink +#define utime _utime +#define wcsdup _wcsdup +#define write _write +#define y0 _y0 +#define y1 _y1 +#define yn _yn +#endif +' ]) diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4 index 9a4f5027..a82c5de2 100644 --- a/gl/m4/gnulib-comp.m4 +++ b/gl/m4/gnulib-comp.m4 @@ -1,9 +1,9 @@ # DO NOT EDIT! GENERATED AUTOMATICALLY! -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2022 Free Software Foundation, Inc. # # 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 -# the Free Software Foundation; either version 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This file is distributed in the hope that it will be useful, @@ -12,7 +12,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this file. If not, see . +# along with this file. If not, see . # # As a special exception to the GNU General Public License, # this file may be distributed as part of a program that @@ -37,50 +37,93 @@ AC_DEFUN([gl_EARLY], m4_pattern_allow([^gl_ES$])dnl a valid locale name m4_pattern_allow([^gl_LIBOBJS$])dnl a variable m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable + + # Pre-early section. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_REQUIRE([gl_PROG_AR_RANLIB]) - AC_REQUIRE([AM_PROG_CC_C_O]) + + # Code from module absolute-header: # Code from module alloca-opt: # Code from module arpa_inet: + # Code from module attribute: # Code from module base64: + # Code from module basename-lgpl: # Code from module btowc: - # Code from module configmake: + # Code from module builtin-expect: + # Code from module byteswap: + # Code from module c99: + # Code from module calloc-gnu: + # Code from module calloc-posix: + # Code from module cloexec: + # Code from module close: + # Code from module crypto/af_alg: # Code from module crypto/sha1: + # Code from module crypto/sha1-buffer: # Code from module dirname: # Code from module dirname-lgpl: - # Code from module dosname: # Code from module double-slash-root: + # Code from module dup2: + # Code from module dynarray: # Code from module environ: # Code from module errno: # Code from module error: # Code from module exitfail: # Code from module extensions: - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) # Code from module extern-inline: + # Code from module fcntl: + # Code from module fcntl-h: # Code from module fd-hook: + # Code from module fflush: + AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) + # Code from module filename: # Code from module float: # Code from module floorf: + # Code from module fopen: + # Code from module fopen-gnu: + # Code from module fpurge: + # Code from module freading: + # Code from module free-posix: + # Code from module fseek: + # Code from module fseeko: + AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) + # Code from module fstat: # Code from module fsusage: - # Code from module full-read: + # Code from module ftell: + # Code from module ftello: + AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) + # Code from module gen-header: # Code from module getaddrinfo: + # Code from module getdelim: + # Code from module getdtablesize: # Code from module gethostname: + # Code from module getline: # Code from module getloadavg: # Code from module getopt-gnu: # Code from module getopt-posix: + # Code from module getprogname: # Code from module gettext: # Code from module gettext-h: + # Code from module hard-locale: # Code from module havelib: # Code from module hostent: + # Code from module ialloc: # Code from module idpriv-droptemp: + # Code from module idx: # Code from module include_next: # Code from module inet_ntop: # Code from module intprops: + # Code from module inttypes-incomplete: # Code from module langinfo: # Code from module largefile: AC_REQUIRE([AC_SYS_LARGEFILE]) + AC_REQUIRE([gl_YEAR2038_EARLY]) + # Code from module libc-config: + # Code from module limits-h: # Code from module localcharset: # Code from module locale: # Code from module localeconv: # Code from module lock: + # Code from module lseek: # Code from module malloc-gnu: # Code from module malloc-posix: # Code from module malloca: @@ -89,6 +132,7 @@ AC_DEFUN([gl_EARLY], # Code from module mbsinit: # Code from module mbtowc: # Code from module memchr: + # Code from module minmax: # Code from module mktime: # Code from module mktime-internal: # Code from module mountlist: @@ -99,11 +143,15 @@ AC_DEFUN([gl_EARLY], # Code from module netinet_in: # Code from module nl_langinfo: # Code from module nocrash: - # Code from module read: + # Code from module open: + # Code from module pathmax: + # Code from module realloc-gnu: + # Code from module realloc-posix: + # Code from module reallocarray: # Code from module regex: - # Code from module safe-read: # Code from module servent: # Code from module setenv: + # Code from module setlocale-null: # Code from module size_max: # Code from module snippet/_Noreturn: # Code from module snippet/arg-nonnull: @@ -114,8 +162,12 @@ AC_DEFUN([gl_EARLY], # Code from module sockets: # Code from module socklen: # Code from module ssize_t: + # Code from module stat: + # Code from module stat-time: + # Code from module std-gnu11: # Code from module stdalign: # Code from module stdbool: + # Code from module stdckdint: # Code from module stddef: # Code from module stdint: # Code from module stdio: @@ -128,11 +180,10 @@ AC_DEFUN([gl_EARLY], # Code from module strerror-override: # Code from module string: # Code from module strings: - # Code from module strndup: - # Code from module strnlen: # Code from module strsep: # Code from module strstr-simple: # Code from module sys_socket: + # Code from module sys_stat: # Code from module sys_types: # Code from module sys_uio: # Code from module threadlib: @@ -141,7 +192,9 @@ AC_DEFUN([gl_EARLY], # Code from module time_r: # Code from module timegm: # Code from module unistd: + # Code from module unlocked-io-internal: # Code from module unsetenv: + # Code from module vararrays: # Code from module vasnprintf: # Code from module vasprintf: # Code from module verify: @@ -149,11 +202,14 @@ AC_DEFUN([gl_EARLY], # Code from module wchar: # Code from module wcrtomb: # Code from module wctype-h: + # Code from module windows-mutex: + # Code from module windows-once: + # Code from module windows-recmutex: + # Code from module windows-rwlock: # Code from module xalloc: # Code from module xalloc-die: # Code from module xalloc-oversized: # Code from module xsize: - # Code from module xstrndup: ]) # This macro should be invoked from ./configure.ac, in the section @@ -170,154 +226,300 @@ AC_DEFUN([gl_INIT], m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) m4_pushdef([gl_LIBSOURCES_LIST], []) m4_pushdef([gl_LIBSOURCES_DIR], []) + m4_pushdef([GL_MACRO_PREFIX], [gl]) + m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL]) gl_COMMON gl_source_base='gl' + gl_source_base_prefix= gl_FUNC_ALLOCA - gl_HEADER_ARPA_INET + gl_CONDITIONAL_HEADER([alloca.h]) + AC_PROG_MKDIR_P + gl_ARPA_INET_H + gl_ARPA_INET_H_REQUIRE_DEFAULTS AC_PROG_MKDIR_P gl_FUNC_BASE64 gl_FUNC_BTOWC - if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then - AC_LIBOBJ([btowc]) + gl_CONDITIONAL([GL_COND_OBJ_BTOWC], + [test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1]) + AM_COND_IF([GL_COND_OBJ_BTOWC], [ gl_PREREQ_BTOWC - fi + ]) gl_WCHAR_MODULE_INDICATOR([btowc]) - gl_CONFIGMAKE_PREP + gl___BUILTIN_EXPECT + gl_BYTESWAP + gl_CONDITIONAL_HEADER([byteswap.h]) + AC_PROG_MKDIR_P + gl_FUNC_CALLOC_GNU + if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 1; then + AC_LIBOBJ([calloc]) + fi + gl_STDLIB_MODULE_INDICATOR([calloc-gnu]) + gl_FUNC_CALLOC_POSIX + if test $REPLACE_CALLOC_FOR_CALLOC_POSIX = 1; then + AC_LIBOBJ([calloc]) + fi + gl_STDLIB_MODULE_INDICATOR([calloc-posix]) + gl_MODULE_INDICATOR_FOR_TESTS([cloexec]) + gl_FUNC_CLOSE + gl_CONDITIONAL([GL_COND_OBJ_CLOSE], [test $REPLACE_CLOSE = 1]) + gl_UNISTD_MODULE_INDICATOR([close]) + gl_AF_ALG + AC_REQUIRE([AC_C_RESTRICT]) gl_SHA1 - gl_DIRNAME gl_MODULE_INDICATOR([dirname]) - gl_DIRNAME_LGPL gl_DOUBLE_SLASH_ROOT + gl_FUNC_DUP2 + gl_CONDITIONAL([GL_COND_OBJ_DUP2], [test $REPLACE_DUP2 = 1]) + AM_COND_IF([GL_COND_OBJ_DUP2], [ + gl_PREREQ_DUP2 + ]) + gl_UNISTD_MODULE_INDICATOR([dup2]) + AC_PROG_MKDIR_P gl_ENVIRON gl_UNISTD_MODULE_INDICATOR([environ]) gl_HEADER_ERRNO_H + gl_CONDITIONAL_HEADER([errno.h]) + AC_PROG_MKDIR_P gl_ERROR - if test $ac_cv_lib_error_at_line = no; then - AC_LIBOBJ([error]) + gl_CONDITIONAL([GL_COND_OBJ_ERROR], [test "$ac_cv_lib_error_at_line" = no]) + AM_COND_IF([GL_COND_OBJ_ERROR], [ gl_PREREQ_ERROR - fi + ]) m4_ifdef([AM_XGETTEXT_OPTION], [AM_][XGETTEXT_OPTION([--flag=error:3:c-format]) AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])]) AC_REQUIRE([gl_EXTERN_INLINE]) + gl_FUNC_FCNTL + gl_CONDITIONAL([GL_COND_OBJ_FCNTL], + [test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1]) + gl_FCNTL_MODULE_INDICATOR([fcntl]) + gl_FCNTL_H + gl_FCNTL_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + gl_FUNC_FFLUSH + gl_CONDITIONAL([GL_COND_OBJ_FFLUSH], [test $REPLACE_FFLUSH = 1]) + AM_COND_IF([GL_COND_OBJ_FFLUSH], [ + gl_PREREQ_FFLUSH + ]) + gl_MODULE_INDICATOR([fflush]) + gl_STDIO_MODULE_INDICATOR([fflush]) gl_FLOAT_H - if test $REPLACE_FLOAT_LDBL = 1; then - AC_LIBOBJ([float]) - fi - if test $REPLACE_ITOLD = 1; then - AC_LIBOBJ([itold]) - fi + gl_CONDITIONAL_HEADER([float.h]) + AC_PROG_MKDIR_P + gl_CONDITIONAL([GL_COND_OBJ_FLOAT], [test $REPLACE_FLOAT_LDBL = 1]) + gl_CONDITIONAL([GL_COND_OBJ_ITOLD], [test $REPLACE_ITOLD = 1]) gl_FUNC_FLOORF - if test $HAVE_DECL_FLOORF = 0 || test $REPLACE_FLOORF = 1; then - AC_LIBOBJ([floorf]) - fi + gl_CONDITIONAL([GL_COND_OBJ_FLOORF], + [test $HAVE_DECL_FLOORF = 0 || test $REPLACE_FLOORF = 1]) gl_MATH_MODULE_INDICATOR([floorf]) + gl_FUNC_FOPEN + if test $REPLACE_FOPEN = 1; then + AC_LIBOBJ([fopen]) + gl_PREREQ_FOPEN + fi + gl_STDIO_MODULE_INDICATOR([fopen]) + gl_FUNC_FOPEN_GNU + if test $REPLACE_FOPEN_FOR_FOPEN_GNU = 1; then + AC_LIBOBJ([fopen]) + gl_PREREQ_FOPEN + fi + gl_MODULE_INDICATOR([fopen-gnu]) + gl_STDIO_MODULE_INDICATOR([fopen-gnu]) + gl_FUNC_FPURGE + gl_CONDITIONAL([GL_COND_OBJ_FPURGE], + [test $HAVE_FPURGE = 0 || test $REPLACE_FPURGE = 1]) + gl_STDIO_MODULE_INDICATOR([fpurge]) + gl_FUNC_FREADING + gl_FUNC_FREE + gl_CONDITIONAL([GL_COND_OBJ_FREE], [test $REPLACE_FREE = 1]) + AM_COND_IF([GL_COND_OBJ_FREE], [ + gl_PREREQ_FREE + ]) + gl_STDLIB_MODULE_INDICATOR([free-posix]) + gl_FUNC_FSEEK + gl_CONDITIONAL([GL_COND_OBJ_FSEEK], [test $REPLACE_FSEEK = 1]) + gl_STDIO_MODULE_INDICATOR([fseek]) + gl_FUNC_FSEEKO + gl_CONDITIONAL([GL_COND_OBJ_FSEEKO], + [test $HAVE_FSEEKO = 0 || test $REPLACE_FSEEKO = 1]) + AM_COND_IF([GL_COND_OBJ_FSEEKO], [ + gl_PREREQ_FSEEKO + ]) + gl_STDIO_MODULE_INDICATOR([fseeko]) + gl_FUNC_FSTAT + gl_CONDITIONAL([GL_COND_OBJ_FSTAT], [test $REPLACE_FSTAT = 1]) + AM_COND_IF([GL_COND_OBJ_FSTAT], [ + case "$host_os" in + mingw*) + AC_LIBOBJ([stat-w32]) + ;; + esac + gl_PREREQ_FSTAT + ]) + gl_SYS_STAT_MODULE_INDICATOR([fstat]) gl_FSUSAGE - if test $gl_cv_fs_space = yes; then - AC_LIBOBJ([fsusage]) + gl_CONDITIONAL([GL_COND_OBJ_FSUSAGE], [test $gl_cv_fs_space = yes]) + AM_COND_IF([GL_COND_OBJ_FSUSAGE], [ gl_PREREQ_FSUSAGE_EXTRA - fi + ]) + gl_FUNC_FTELL + gl_CONDITIONAL([GL_COND_OBJ_FTELL], [test $REPLACE_FTELL = 1]) + gl_STDIO_MODULE_INDICATOR([ftell]) + gl_FUNC_FTELLO + gl_CONDITIONAL([GL_COND_OBJ_FTELLO], + [test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1]) + AM_COND_IF([GL_COND_OBJ_FTELLO], [ + gl_PREREQ_FTELLO + ]) + gl_STDIO_MODULE_INDICATOR([ftello]) gl_GETADDRINFO - if test $HAVE_GETADDRINFO = 0; then - AC_LIBOBJ([getaddrinfo]) - fi - if test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1; then - AC_LIBOBJ([gai_strerror]) - fi + gl_CONDITIONAL([GL_COND_OBJ_GETADDRINFO], + [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1]) + gl_CONDITIONAL([GL_COND_OBJ_GAI_STRERROR], + [test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1]) gl_NETDB_MODULE_INDICATOR([getaddrinfo]) + gl_FUNC_GETDELIM + gl_CONDITIONAL([GL_COND_OBJ_GETDELIM], + [test $HAVE_GETDELIM = 0 || test $REPLACE_GETDELIM = 1]) + AM_COND_IF([GL_COND_OBJ_GETDELIM], [ + gl_PREREQ_GETDELIM + ]) + gl_STDIO_MODULE_INDICATOR([getdelim]) + gl_FUNC_GETDTABLESIZE + gl_CONDITIONAL([GL_COND_OBJ_GETDTABLESIZE], + [test $HAVE_GETDTABLESIZE = 0 || test $REPLACE_GETDTABLESIZE = 1]) + AM_COND_IF([GL_COND_OBJ_GETDTABLESIZE], [ + gl_PREREQ_GETDTABLESIZE + ]) + gl_UNISTD_MODULE_INDICATOR([getdtablesize]) gl_FUNC_GETHOSTNAME - if test $HAVE_GETHOSTNAME = 0; then - AC_LIBOBJ([gethostname]) + gl_CONDITIONAL([GL_COND_OBJ_GETHOSTNAME], [test $HAVE_GETHOSTNAME = 0]) + AM_COND_IF([GL_COND_OBJ_GETHOSTNAME], [ gl_PREREQ_GETHOSTNAME - fi + ]) gl_UNISTD_MODULE_INDICATOR([gethostname]) + gl_FUNC_GETLINE + gl_CONDITIONAL([GL_COND_OBJ_GETLINE], [test $REPLACE_GETLINE = 1]) + AM_COND_IF([GL_COND_OBJ_GETLINE], [ + gl_PREREQ_GETLINE + ]) + gl_STDIO_MODULE_INDICATOR([getline]) + AC_REQUIRE([AC_CANONICAL_HOST]) gl_GETLOADAVG - if test $HAVE_GETLOADAVG = 0; then - AC_LIBOBJ([getloadavg]) + gl_CONDITIONAL([GL_COND_OBJ_GETLOADAVG], [test $HAVE_GETLOADAVG = 0]) + AM_COND_IF([GL_COND_OBJ_GETLOADAVG], [ gl_PREREQ_GETLOADAVG - fi + ]) gl_STDLIB_MODULE_INDICATOR([getloadavg]) gl_FUNC_GETOPT_GNU - if test $REPLACE_GETOPT = 1; then - AC_LIBOBJ([getopt]) - AC_LIBOBJ([getopt1]) - gl_PREREQ_GETOPT - dnl Arrange for unistd.h to include getopt.h. - GNULIB_GL_UNISTD_H_GETOPT=1 - fi - AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) - gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) + dnl Because of the way gl_FUNC_GETOPT_GNU is implemented (the gl_getopt_required + dnl mechanism), there is no need to do any AC_LIBOBJ or AC_SUBST here; they are + dnl done in the getopt-posix module. gl_FUNC_GETOPT_POSIX - if test $REPLACE_GETOPT = 1; then - AC_LIBOBJ([getopt]) - AC_LIBOBJ([getopt1]) - gl_PREREQ_GETOPT - dnl Arrange for unistd.h to include getopt.h. - GNULIB_GL_UNISTD_H_GETOPT=1 - fi - AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) + gl_CONDITIONAL_HEADER([getopt.h]) + gl_CONDITIONAL_HEADER([getopt-cdefs.h]) + AC_PROG_MKDIR_P + gl_CONDITIONAL([GL_COND_OBJ_GETOPT], [test $REPLACE_GETOPT = 1]) + AM_COND_IF([GL_COND_OBJ_GETOPT], [ + dnl Define the substituted variable GNULIB_UNISTD_H_GETOPT to 1. + gl_UNISTD_H_REQUIRE_DEFAULTS + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT], [1]) + ]) + gl_UNISTD_MODULE_INDICATOR([getopt-posix]) + gl_FUNC_GETPROGNAME dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac. - AM_GNU_GETTEXT_VERSION([0.18.1]) + AM_GNU_GETTEXT_VERSION([0.20]) AC_SUBST([LIBINTL]) AC_SUBST([LTLIBINTL]) + AC_REQUIRE([gl_FUNC_SETLOCALE_NULL]) + LIB_HARD_LOCALE="$LIB_SETLOCALE_NULL" + AC_SUBST([LIB_HARD_LOCALE]) + AC_DEFUN([gl_HAVE_MODULE_HAVELIB]) gl_HOSTENT gl_IDPRIV gl_FUNC_INET_NTOP - if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then - AC_LIBOBJ([inet_ntop]) + gl_CONDITIONAL([GL_COND_OBJ_INET_NTOP], + [test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1]) + AM_COND_IF([GL_COND_OBJ_INET_NTOP], [ gl_PREREQ_INET_NTOP - fi + ]) gl_ARPA_INET_MODULE_INDICATOR([inet_ntop]) + gl_INTTYPES_INCOMPLETE + gl_INTTYPES_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_LANGINFO_H + gl_LANGINFO_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P AC_REQUIRE([gl_LARGEFILE]) + gl___INLINE + gl_LIMITS_H + gl_CONDITIONAL_HEADER([limits.h]) + AC_PROG_MKDIR_P gl_LOCALCHARSET - LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\"" + dnl For backward compatibility. Some packages still use this. + LOCALCHARSET_TESTS_ENVIRONMENT= AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) gl_LOCALE_H + gl_LOCALE_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_FUNC_LOCALECONV - if test $REPLACE_LOCALECONV = 1; then - AC_LIBOBJ([localeconv]) + gl_CONDITIONAL([GL_COND_OBJ_LOCALECONV], [test $REPLACE_LOCALECONV = 1]) + AM_COND_IF([GL_COND_OBJ_LOCALECONV], [ gl_PREREQ_LOCALECONV - fi + ]) gl_LOCALE_MODULE_INDICATOR([localeconv]) gl_LOCK gl_MODULE_INDICATOR([lock]) + gl_FUNC_LSEEK + gl_CONDITIONAL([GL_COND_OBJ_LSEEK], [test $REPLACE_LSEEK = 1]) + gl_UNISTD_MODULE_INDICATOR([lseek]) gl_FUNC_MALLOC_GNU - if test $REPLACE_MALLOC = 1; then + if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 1; then AC_LIBOBJ([malloc]) fi - gl_MODULE_INDICATOR([malloc-gnu]) - gl_FUNC_MALLOC_POSIX - if test $REPLACE_MALLOC = 1; then + gl_STDLIB_MODULE_INDICATOR([malloc-gnu]) + AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) + if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then AC_LIBOBJ([malloc]) fi gl_STDLIB_MODULE_INDICATOR([malloc-posix]) gl_MALLOCA gl_MATH_H + gl_MATH_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_FUNC_MBRTOWC - if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then - AC_LIBOBJ([mbrtowc]) + gl_CONDITIONAL([GL_COND_OBJ_MBRTOWC], + [test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1]) + AM_COND_IF([GL_COND_OBJ_MBRTOWC], [ + if test $REPLACE_MBSTATE_T = 1; then + AC_LIBOBJ([lc-charset-dispatch]) + AC_LIBOBJ([mbtowc-lock]) + gl_PREREQ_MBTOWC_LOCK + fi gl_PREREQ_MBRTOWC - fi + ]) gl_WCHAR_MODULE_INDICATOR([mbrtowc]) gl_FUNC_MBSINIT - if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then - AC_LIBOBJ([mbsinit]) + gl_CONDITIONAL([GL_COND_OBJ_MBSINIT], + [test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1]) + AM_COND_IF([GL_COND_OBJ_MBSINIT], [ gl_PREREQ_MBSINIT - fi + ]) gl_WCHAR_MODULE_INDICATOR([mbsinit]) gl_FUNC_MBTOWC - if test $REPLACE_MBTOWC = 1; then - AC_LIBOBJ([mbtowc]) + gl_CONDITIONAL([GL_COND_OBJ_MBTOWC], + [test $HAVE_MBTOWC = 0 || test $REPLACE_MBTOWC = 1]) + AM_COND_IF([GL_COND_OBJ_MBTOWC], [ gl_PREREQ_MBTOWC - fi + ]) gl_STDLIB_MODULE_INDICATOR([mbtowc]) gl_FUNC_MEMCHR - if test $HAVE_MEMCHR = 0 || test $REPLACE_MEMCHR = 1; then - AC_LIBOBJ([memchr]) + gl_CONDITIONAL([GL_COND_OBJ_MEMCHR], [test $REPLACE_MEMCHR = 1]) + AM_COND_IF([GL_COND_OBJ_MEMCHR], [ gl_PREREQ_MEMCHR - fi + ]) gl_STRING_MODULE_INDICATOR([memchr]) + gl_MINMAX gl_FUNC_MKTIME if test $REPLACE_MKTIME = 1; then AC_LIBOBJ([mktime]) @@ -325,73 +527,164 @@ AC_DEFUN([gl_INIT], fi gl_TIME_MODULE_INDICATOR([mktime]) gl_FUNC_MKTIME_INTERNAL - if test $REPLACE_MKTIME = 1; then + if test $WANT_MKTIME_INTERNAL = 1; then AC_LIBOBJ([mktime]) gl_PREREQ_MKTIME fi gl_MOUNTLIST - if test $gl_cv_list_mounted_fs = yes; then - AC_LIBOBJ([mountlist]) + gl_CONDITIONAL([GL_COND_OBJ_MOUNTLIST], [test $gl_cv_list_mounted_fs = yes]) + AM_COND_IF([GL_COND_OBJ_MOUNTLIST], [ gl_PREREQ_MOUNTLIST_EXTRA - fi - gl_MSVC_INVAL - if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then - AC_LIBOBJ([msvc-inval]) - fi - gl_MSVC_NOTHROW - if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then - AC_LIBOBJ([msvc-nothrow]) - fi + ]) + AC_REQUIRE([gl_MSVC_INVAL]) + gl_CONDITIONAL([GL_COND_OBJ_MSVC_INVAL], + [test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1]) + AC_REQUIRE([gl_MSVC_NOTHROW]) + gl_CONDITIONAL([GL_COND_OBJ_MSVC_NOTHROW], + [test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1]) + gl_MODULE_INDICATOR([msvc-nothrow]) gl_MULTIARCH - gl_HEADER_NETDB + gl_NETDB_H + gl_NETDB_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_HEADER_NETINET_IN + gl_CONDITIONAL_HEADER([netinet/in.h]) AC_PROG_MKDIR_P gl_FUNC_NL_LANGINFO - if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then - AC_LIBOBJ([nl_langinfo]) + gl_CONDITIONAL([GL_COND_OBJ_NL_LANGINFO], + [test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1]) + gl_CONDITIONAL([GL_COND_OBJ_NL_LANGINFO_LOCK], + [test $REPLACE_NL_LANGINFO = 1 && test $NL_LANGINFO_MTSAFE = 0]) + if test $REPLACE_NL_LANGINFO = 1 && test $NL_LANGINFO_MTSAFE = 0; then + gl_PREREQ_NL_LANGINFO_LOCK fi gl_LANGINFO_MODULE_INDICATOR([nl_langinfo]) - gl_FUNC_READ - if test $REPLACE_READ = 1; then - AC_LIBOBJ([read]) - gl_PREREQ_READ + gl_FUNC_OPEN + gl_CONDITIONAL([GL_COND_OBJ_OPEN], [test $REPLACE_OPEN = 1]) + AM_COND_IF([GL_COND_OBJ_OPEN], [ + gl_PREREQ_OPEN + ]) + gl_FCNTL_MODULE_INDICATOR([open]) + gl_PATHMAX + gl_FUNC_REALLOC_GNU + if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 1; then + AC_LIBOBJ([realloc]) fi - gl_UNISTD_MODULE_INDICATOR([read]) + gl_STDLIB_MODULE_INDICATOR([realloc-gnu]) + gl_FUNC_REALLOC_POSIX + if test $REPLACE_REALLOC_FOR_REALLOC_POSIX = 1; then + AC_LIBOBJ([realloc]) + fi + gl_STDLIB_MODULE_INDICATOR([realloc-posix]) + gl_FUNC_REALLOCARRAY + gl_CONDITIONAL([GL_COND_OBJ_REALLOCARRAY], + [test $HAVE_REALLOCARRAY = 0 || test $REPLACE_REALLOCARRAY = 1]) + AM_COND_IF([GL_COND_OBJ_REALLOCARRAY], [ + gl_PREREQ_REALLOCARRAY + ]) + gl_MODULE_INDICATOR([reallocarray]) + gl_STDLIB_MODULE_INDICATOR([reallocarray]) gl_REGEX - if test $ac_use_included_regex = yes; then - AC_LIBOBJ([regex]) + gl_CONDITIONAL([GL_COND_OBJ_REGEX], [test $ac_use_included_regex = yes]) + AM_COND_IF([GL_COND_OBJ_REGEX], [ gl_PREREQ_REGEX - fi - gl_PREREQ_SAFE_READ + ]) gl_SERVENT gl_FUNC_SETENV - if test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1; then - AC_LIBOBJ([setenv]) - fi + gl_CONDITIONAL([GL_COND_OBJ_SETENV], + [test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1]) gl_STDLIB_MODULE_INDICATOR([setenv]) + gl_FUNC_SETLOCALE_NULL + gl_CONDITIONAL([GL_COND_OBJ_SETLOCALE_LOCK], + [test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0]) + AM_COND_IF([GL_COND_OBJ_SETLOCALE_LOCK], [ + gl_PREREQ_SETLOCALE_LOCK + ]) + gl_LOCALE_MODULE_INDICATOR([setlocale_null]) gl_SIZE_MAX gl_FUNC_SNPRINTF gl_STDIO_MODULE_INDICATOR([snprintf]) gl_MODULE_INDICATOR([snprintf]) - gl_SOCKETLIB - gl_SOCKETS + AC_REQUIRE([gl_SOCKETLIB]) + AC_REQUIRE([gl_SOCKETS]) gl_TYPE_SOCKLEN_T gt_TYPE_SSIZE_T + gl_FUNC_STAT + gl_CONDITIONAL([GL_COND_OBJ_STAT], [test $REPLACE_STAT = 1]) + AM_COND_IF([GL_COND_OBJ_STAT], [ + case "$host_os" in + mingw*) + AC_LIBOBJ([stat-w32]) + ;; + esac + gl_PREREQ_STAT + ]) + gl_SYS_STAT_MODULE_INDICATOR([stat]) + gl_STAT_TIME + gl_STAT_BIRTHTIME gl_STDALIGN_H - AM_STDBOOL_H + gl_CONDITIONAL_HEADER([stdalign.h]) + AC_PROG_MKDIR_P + gl_STDBOOL_H + gl_CONDITIONAL_HEADER([stdbool.h]) + AC_PROG_MKDIR_P + AC_CHECK_HEADERS_ONCE([stdckdint.h]) + if test $ac_cv_header_stdckdint_h = yes; then + GL_GENERATE_STDCKDINT_H=false + else + GL_GENERATE_STDCKDINT_H=true + fi + gl_CONDITIONAL_HEADER([stdckdint.h]) + AC_PROG_MKDIR_P gl_STDDEF_H + gl_STDDEF_H_REQUIRE_DEFAULTS + gl_CONDITIONAL_HEADER([stddef.h]) + AC_PROG_MKDIR_P gl_STDINT_H + gl_CONDITIONAL_HEADER([stdint.h]) + dnl Because of gl_REPLACE_LIMITS_H: + gl_CONDITIONAL_HEADER([limits.h]) + AC_PROG_MKDIR_P gl_STDIO_H + gl_STDIO_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + gl_CONDITIONAL([GL_COND_OBJ_STDIO_READ], [test $REPLACE_STDIO_READ_FUNCS = 1]) + gl_CONDITIONAL([GL_COND_OBJ_STDIO_WRITE], [test $REPLACE_STDIO_WRITE_FUNCS = 1]) + dnl No need to create extra modules for these functions. Everyone who uses + dnl likely needs them. + gl_STDIO_MODULE_INDICATOR([fscanf]) + gl_MODULE_INDICATOR([fscanf]) + gl_STDIO_MODULE_INDICATOR([scanf]) + gl_MODULE_INDICATOR([scanf]) + gl_STDIO_MODULE_INDICATOR([fgetc]) + gl_STDIO_MODULE_INDICATOR([getc]) + gl_STDIO_MODULE_INDICATOR([getchar]) + gl_STDIO_MODULE_INDICATOR([fgets]) + gl_STDIO_MODULE_INDICATOR([fread]) + dnl No need to create extra modules for these functions. Everyone who uses + dnl likely needs them. + gl_STDIO_MODULE_INDICATOR([fprintf]) + gl_STDIO_MODULE_INDICATOR([printf]) + gl_STDIO_MODULE_INDICATOR([vfprintf]) + gl_STDIO_MODULE_INDICATOR([vprintf]) + gl_STDIO_MODULE_INDICATOR([fputc]) + gl_STDIO_MODULE_INDICATOR([putc]) + gl_STDIO_MODULE_INDICATOR([putchar]) + gl_STDIO_MODULE_INDICATOR([fputs]) + gl_STDIO_MODULE_INDICATOR([puts]) + gl_STDIO_MODULE_INDICATOR([fwrite]) gl_STDLIB_H + gl_STDLIB_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_STRCASE - if test $HAVE_STRCASECMP = 0; then - AC_LIBOBJ([strcasecmp]) + gl_CONDITIONAL([GL_COND_OBJ_STRCASECMP], [test $HAVE_STRCASECMP = 0]) + AM_COND_IF([GL_COND_OBJ_STRCASECMP], [ gl_PREREQ_STRCASECMP - fi - if test $HAVE_STRNCASECMP = 0; then - AC_LIBOBJ([strncasecmp]) + ]) + gl_CONDITIONAL([GL_COND_OBJ_STRNCASECMP], [test $HAVE_STRNCASECMP = 0]) + AM_COND_IF([GL_COND_OBJ_STRNCASECMP], [ gl_PREREQ_STRNCASECMP - fi + ]) gl_FUNC_STRCASESTR if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then AC_LIBOBJ([strcasestr]) @@ -404,68 +697,76 @@ AC_DEFUN([gl_INIT], fi gl_STRING_MODULE_INDICATOR([strcasestr]) gl_FUNC_STRERROR - if test $REPLACE_STRERROR = 1; then - AC_LIBOBJ([strerror]) - fi + gl_CONDITIONAL([GL_COND_OBJ_STRERROR], [test $REPLACE_STRERROR = 1]) gl_MODULE_INDICATOR([strerror]) gl_STRING_MODULE_INDICATOR([strerror]) AC_REQUIRE([gl_HEADER_ERRNO_H]) AC_REQUIRE([gl_FUNC_STRERROR_0]) - if test -n "$ERRNO_H" || test $REPLACE_STRERROR_0 = 1; then - AC_LIBOBJ([strerror-override]) + gl_CONDITIONAL([GL_COND_OBJ_STRERROR_OVERRIDE], + [test -n "$ERRNO_H" || test $REPLACE_STRERROR_0 = 1]) + AM_COND_IF([GL_COND_OBJ_STRERROR_OVERRIDE], [ gl_PREREQ_SYS_H_WINSOCK2 - fi - gl_HEADER_STRING_H - gl_HEADER_STRINGS_H - gl_FUNC_STRNDUP - if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then - AC_LIBOBJ([strndup]) - fi - gl_STRING_MODULE_INDICATOR([strndup]) - gl_FUNC_STRNLEN - if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then - AC_LIBOBJ([strnlen]) - gl_PREREQ_STRNLEN - fi - gl_STRING_MODULE_INDICATOR([strnlen]) + ]) + gl_STRING_H + gl_STRING_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + gl_STRINGS_H + gl_STRINGS_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_FUNC_STRSEP - if test $HAVE_STRSEP = 0; then - AC_LIBOBJ([strsep]) + gl_CONDITIONAL([GL_COND_OBJ_STRSEP], [test $HAVE_STRSEP = 0]) + AM_COND_IF([GL_COND_OBJ_STRSEP], [ gl_PREREQ_STRSEP - fi + ]) gl_STRING_MODULE_INDICATOR([strsep]) gl_FUNC_STRSTR_SIMPLE if test $REPLACE_STRSTR = 1; then AC_LIBOBJ([strstr]) fi gl_STRING_MODULE_INDICATOR([strstr]) - gl_HEADER_SYS_SOCKET + gl_SYS_SOCKET_H + gl_SYS_SOCKET_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + gl_SYS_STAT_H + gl_SYS_STAT_H_REQUIRE_DEFAULTS AC_PROG_MKDIR_P gl_SYS_TYPES_H + gl_SYS_TYPES_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + gl_SYS_UIO_H + gl_SYS_UIO_H_REQUIRE_DEFAULTS AC_PROG_MKDIR_P - gl_HEADER_SYS_UIO + AC_REQUIRE([gl_THREADLIB]) + gl_TIME_H + gl_TIME_H_REQUIRE_DEFAULTS AC_PROG_MKDIR_P - gl_THREADLIB - gl_HEADER_TIME_H gl_TIME_R - if test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1; then - AC_LIBOBJ([time_r]) + gl_CONDITIONAL([GL_COND_OBJ_TIME_R], + [test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1]) + AM_COND_IF([GL_COND_OBJ_TIME_R], [ gl_PREREQ_TIME_R - fi + ]) gl_TIME_MODULE_INDICATOR([time_r]) gl_FUNC_TIMEGM - if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then - AC_LIBOBJ([timegm]) + gl_CONDITIONAL([GL_COND_OBJ_TIMEGM], + [test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1]) + AM_COND_IF([GL_COND_OBJ_TIMEGM], [ gl_PREREQ_TIMEGM - fi + ]) gl_TIME_MODULE_INDICATOR([timegm]) gl_UNISTD_H + gl_UNISTD_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + gl_FUNC_GLIBC_UNLOCKED_IO gl_FUNC_UNSETENV - if test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1; then - AC_LIBOBJ([unsetenv]) + gl_CONDITIONAL([GL_COND_OBJ_UNSETENV], + [test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1]) + AM_COND_IF([GL_COND_OBJ_UNSETENV], [ gl_PREREQ_UNSETENV - fi + ]) gl_STDLIB_MODULE_INDICATOR([unsetenv]) + AC_C_VARARRAYS + AC_REQUIRE([AC_C_RESTRICT]) gl_FUNC_VASNPRINTF gl_FUNC_VASPRINTF gl_STDIO_MODULE_INDICATOR([vasprintf]) @@ -475,16 +776,34 @@ AC_DEFUN([gl_INIT], gl_FUNC_VSNPRINTF gl_STDIO_MODULE_INDICATOR([vsnprintf]) gl_WCHAR_H + gl_WCHAR_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P gl_FUNC_WCRTOMB - if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then - AC_LIBOBJ([wcrtomb]) + gl_CONDITIONAL([GL_COND_OBJ_WCRTOMB], + [test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1]) + AM_COND_IF([GL_COND_OBJ_WCRTOMB], [ gl_PREREQ_WCRTOMB - fi + ]) gl_WCHAR_MODULE_INDICATOR([wcrtomb]) gl_WCTYPE_H + gl_WCTYPE_H_REQUIRE_DEFAULTS + AC_PROG_MKDIR_P + AC_REQUIRE([AC_CANONICAL_HOST]) + gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_MUTEX], + [case "$host_os" in mingw*) true;; *) false;; esac]) + AC_REQUIRE([AC_CANONICAL_HOST]) + gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_ONCE], + [case "$host_os" in mingw*) true;; *) false;; esac]) + AC_REQUIRE([AC_CANONICAL_HOST]) + gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_RECMUTEX], + [case "$host_os" in mingw*) true;; *) false;; esac]) + AC_REQUIRE([AC_CANONICAL_HOST]) + gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_RWLOCK], + [case "$host_os" in mingw*) true;; *) false;; esac]) gl_XALLOC + gl_MODULE_INDICATOR([xalloc]) + gl_MODULE_INDICATOR([xalloc-die]) gl_XSIZE - gl_XSTRNDUP # End of code from modules m4_ifval(gl_LIBSOURCES_LIST, [ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || @@ -497,6 +816,8 @@ AC_DEFUN([gl_INIT], m4_if(m4_sysval, [0], [], [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) ]) + m4_popdef([GL_MODULE_INDICATOR_PREFIX]) + m4_popdef([GL_MACRO_PREFIX]) m4_popdef([gl_LIBSOURCES_DIR]) m4_popdef([gl_LIBSOURCES_LIST]) m4_popdef([AC_LIBSOURCES]) @@ -505,16 +826,28 @@ AC_DEFUN([gl_INIT], AC_CONFIG_COMMANDS_PRE([ gl_libobjs= gl_ltlibobjs= + gl_libobjdeps= if test -n "$gl_LIBOBJS"; then # Remove the extension. +changequote(,)dnl sed_drop_objext='s/\.o$//;s/\.obj$//' + sed_dirname1='s,//*,/,g' + sed_dirname2='s,\(.\)/$,\1,' + sed_dirname3='s,^[^/]*$,.,' + sed_dirname4='s,\(.\)/[^/]*$,\1,' + sed_basename1='s,.*/,,' +changequote([, ])dnl for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do gl_libobjs="$gl_libobjs $i.$ac_objext" gl_ltlibobjs="$gl_ltlibobjs $i.lo" + i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3" -e "$sed_dirname4"` + i_base=`echo "$i" | sed -e "$sed_basename1"` + gl_libobjdeps="$gl_libobjdeps $i_dir/\$(DEPDIR)/$i_base.Po" done fi AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) + AC_SUBST([gl_LIBOBJDEPS], [$gl_libobjdeps]) ]) gltests_libdeps= gltests_ltlibdeps= @@ -523,8 +856,11 @@ AC_DEFUN([gl_INIT], m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES])) m4_pushdef([gltests_LIBSOURCES_LIST], []) m4_pushdef([gltests_LIBSOURCES_DIR], []) + m4_pushdef([GL_MACRO_PREFIX], [gltests]) + m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL]) gl_COMMON gl_source_base='tests' + gl_source_base_prefix= changequote(,)dnl gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS changequote([, ])dnl @@ -543,6 +879,8 @@ changequote([, ])dnl m4_if(m4_sysval, [0], [], [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) ]) + m4_popdef([GL_MODULE_INDICATOR_PREFIX]) + m4_popdef([GL_MACRO_PREFIX]) m4_popdef([gltests_LIBSOURCES_DIR]) m4_popdef([gltests_LIBSOURCES_LIST]) m4_popdef([AC_LIBSOURCES]) @@ -551,17 +889,30 @@ changequote([, ])dnl AC_CONFIG_COMMANDS_PRE([ gltests_libobjs= gltests_ltlibobjs= + gltests_libobjdeps= if test -n "$gltests_LIBOBJS"; then # Remove the extension. +changequote(,)dnl sed_drop_objext='s/\.o$//;s/\.obj$//' + sed_dirname1='s,//*,/,g' + sed_dirname2='s,\(.\)/$,\1,' + sed_dirname3='s,^[^/]*$,.,' + sed_dirname4='s,\(.\)/[^/]*$,\1,' + sed_basename1='s,.*/,,' +changequote([, ])dnl for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do gltests_libobjs="$gltests_libobjs $i.$ac_objext" gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" + i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3" -e "$sed_dirname4"` + i_base=`echo "$i" | sed -e "$sed_basename1"` + gltests_libobjdeps="$gltests_libobjdeps $i_dir/\$(DEPDIR)/$i_base.Po" done fi AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) + AC_SUBST([gltests_LIBOBJDEPS], [$gltests_libobjdeps]) ]) + AC_REQUIRE([gl_CC_GNULIB_WARNINGS]) LIBGNU_LIBDEPS="$gl_libdeps" AC_SUBST([LIBGNU_LIBDEPS]) LIBGNU_LTLIBDEPS="$gl_ltlibdeps" @@ -626,75 +977,129 @@ AC_DEFUN([gltests_LIBSOURCES], [ # gnulib-tool and may be removed by future gnulib-tool invocations. AC_DEFUN([gl_FILE_LIST], [ build-aux/config.rpath - build-aux/snippet/_Noreturn.h - build-aux/snippet/arg-nonnull.h - build-aux/snippet/c++defs.h - build-aux/snippet/warn-on-use.h + lib/_Noreturn.h + lib/af_alg.c + lib/af_alg.h lib/alloca.in.h + lib/arg-nonnull.h lib/arpa_inet.in.h lib/asnprintf.c lib/asprintf.c + lib/attribute.h lib/base64.c lib/base64.h lib/basename-lgpl.c + lib/basename-lgpl.h lib/basename.c lib/btowc.c - lib/config.charset + lib/byteswap.in.h + lib/c++defs.h + lib/calloc.c + lib/cdefs.h + lib/cloexec.c + lib/cloexec.h + lib/close.c lib/dirname-lgpl.c lib/dirname.c lib/dirname.h - lib/dosname.h + lib/dup2.c + lib/dynarray.h lib/errno.in.h lib/error.c lib/error.h lib/exitfail.c lib/exitfail.h + lib/fcntl.c + lib/fcntl.in.h lib/fd-hook.c lib/fd-hook.h + lib/fflush.c + lib/filename.h lib/float+.h lib/float.c lib/float.in.h lib/floor.c lib/floorf.c + lib/fopen.c + lib/fpurge.c + lib/freading.c + lib/freading.h + lib/free.c + lib/fseek.c + lib/fseeko.c + lib/fstat.c lib/fsusage.c lib/fsusage.h - lib/full-read.c - lib/full-read.h - lib/full-write.c + lib/ftell.c + lib/ftello.c lib/gai_strerror.c lib/getaddrinfo.c + lib/getdelim.c + lib/getdtablesize.c lib/gethostname.c + lib/getline.c lib/getloadavg.c + lib/getopt-cdefs.in.h + lib/getopt-core.h + lib/getopt-ext.h + lib/getopt-pfx-core.h + lib/getopt-pfx-ext.h lib/getopt.c lib/getopt.in.h lib/getopt1.c lib/getopt_int.h + lib/getprogname.c + lib/getprogname.h lib/gettext.h + lib/gl_openssl.h lib/glthread/lock.c lib/glthread/lock.h lib/glthread/threadlib.c + lib/hard-locale.c + lib/hard-locale.h + lib/ialloc.c + lib/ialloc.h lib/idpriv-droptemp.c lib/idpriv.h + lib/idx.h lib/inet_ntop.c + lib/intprops-internal.h lib/intprops.h + lib/inttypes.in.h lib/itold.c lib/langinfo.in.h + lib/lc-charset-dispatch.c + lib/lc-charset-dispatch.h + lib/libc-config.h + lib/limits.in.h lib/localcharset.c lib/localcharset.h lib/locale.in.h lib/localeconv.c + lib/lseek.c lib/malloc.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/malloca.c lib/malloca.h - lib/malloca.valgrind lib/math.c lib/math.in.h + lib/mbrtowc-impl-utf8.h + lib/mbrtowc-impl.h lib/mbrtowc.c lib/mbsinit.c lib/mbtowc-impl.h + lib/mbtowc-lock.c + lib/mbtowc-lock.h lib/mbtowc.c lib/memchr.c lib/memchr.valgrind + lib/minmax.h lib/mktime-internal.h lib/mktime.c lib/mountlist.c @@ -705,33 +1110,46 @@ AC_DEFUN([gl_FILE_LIST], [ lib/msvc-nothrow.h lib/netdb.in.h lib/netinet_in.in.h + lib/nl_langinfo-lock.c lib/nl_langinfo.c + lib/open.c + lib/pathmax.h lib/printf-args.c lib/printf-args.h lib/printf-parse.c lib/printf-parse.h - lib/read.c - lib/ref-add.sin - lib/ref-del.sin + lib/realloc.c + lib/reallocarray.c lib/regcomp.c lib/regex.c lib/regex.h lib/regex_internal.c lib/regex_internal.h lib/regexec.c - lib/safe-read.c - lib/safe-read.h lib/setenv.c + lib/setlocale-lock.c + lib/setlocale_null.c + lib/setlocale_null.h + lib/sha1-stream.c lib/sha1.c lib/sha1.h lib/size_max.h lib/snprintf.c lib/sockets.c lib/sockets.h + lib/stat-time.c + lib/stat-time.h + lib/stat-w32.c + lib/stat-w32.h + lib/stat.c lib/stdalign.in.h lib/stdbool.in.h + lib/stdckdint.in.h lib/stddef.in.h lib/stdint.in.h + lib/stdio-impl.h + lib/stdio-read.c + lib/stdio-write.c lib/stdio.in.h lib/stdlib.in.h lib/str-two-way.h @@ -745,12 +1163,12 @@ AC_DEFUN([gl_FILE_LIST], [ lib/strings.in.h lib/stripslash.c lib/strncasecmp.c - lib/strndup.c - lib/strnlen.c lib/strsep.c lib/strstr.c + lib/sys-limits.h lib/sys_socket.c lib/sys_socket.in.h + lib/sys_stat.in.h lib/sys_types.in.h lib/sys_uio.in.h lib/time.in.h @@ -758,6 +1176,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/timegm.c lib/unistd.c lib/unistd.in.h + lib/unlocked-io.h lib/unsetenv.c lib/vasnprintf.c lib/vasnprintf.h @@ -765,27 +1184,41 @@ AC_DEFUN([gl_FILE_LIST], [ lib/verify.h lib/vsnprintf.c lib/w32sock.h + lib/warn-on-use.h lib/wchar.in.h lib/wcrtomb.c lib/wctype-h.c lib/wctype.in.h + lib/windows-initguard.h + lib/windows-mutex.c + lib/windows-mutex.h + lib/windows-once.c + lib/windows-once.h + lib/windows-recmutex.c + lib/windows-recmutex.h + lib/windows-rwlock.c + lib/windows-rwlock.h lib/xalloc-die.c lib/xalloc-oversized.h lib/xalloc.h lib/xmalloc.c lib/xsize.c lib/xsize.h - lib/xstrndup.c - lib/xstrndup.h m4/00gnulib.m4 + m4/__inline.m4 + m4/absolute-header.m4 + m4/af_alg.m4 m4/alloca.m4 m4/arpa_inet_h.m4 m4/base64.m4 m4/btowc.m4 + m4/builtin-expect.m4 + m4/byteswap.m4 + m4/calloc.m4 + m4/close.m4 m4/codeset.m4 - m4/configmake.m4 - m4/dirname.m4 m4/double-slash-root.m4 + m4/dup2.m4 m4/eealloc.m4 m4/environ.m4 m4/errno_h.m4 @@ -794,37 +1227,50 @@ AC_DEFUN([gl_FILE_LIST], [ m4/extensions.m4 m4/extern-inline.m4 m4/fcntl-o.m4 + m4/fcntl.m4 + m4/fcntl_h.m4 + m4/fflush.m4 m4/float_h.m4 m4/floorf.m4 + m4/fopen.m4 + m4/fpurge.m4 + m4/freading.m4 + m4/free.m4 + m4/fseek.m4 + m4/fseeko.m4 + m4/fstat.m4 m4/fstypename.m4 m4/fsusage.m4 + m4/ftell.m4 + m4/ftello.m4 m4/getaddrinfo.m4 + m4/getdelim.m4 + m4/getdtablesize.m4 m4/gethostname.m4 + m4/getline.m4 m4/getloadavg.m4 m4/getopt.m4 + m4/getprogname.m4 m4/gettext.m4 - m4/glibc2.m4 - m4/glibc21.m4 + m4/gl-openssl.m4 m4/gnulib-common.m4 + m4/host-cpu-c-abi.m4 m4/hostent.m4 m4/iconv.m4 m4/idpriv.m4 m4/include_next.m4 m4/inet_ntop.m4 - m4/intdiv0.m4 - m4/intl.m4 - m4/intldir.m4 + m4/intl-thread-locale.m4 m4/intlmacosx.m4 - m4/intmax.m4 m4/intmax_t.m4 - m4/inttypes-pri.m4 + m4/inttypes.m4 m4/inttypes_h.m4 m4/langinfo_h.m4 m4/largefile.m4 - m4/lcmessage.m4 m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4 + m4/limits-h.m4 m4/localcharset.m4 m4/locale-fr.m4 m4/locale-ja.m4 @@ -832,8 +1278,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/locale_h.m4 m4/localeconv.m4 m4/lock.m4 - m4/longlong.m4 - m4/ls-mntd-fs.m4 + m4/lseek.m4 m4/malloc.m4 m4/malloca.m4 m4/math_h.m4 @@ -842,8 +1287,10 @@ AC_DEFUN([gl_FILE_LIST], [ m4/mbstate_t.m4 m4/mbtowc.m4 m4/memchr.m4 + m4/minmax.m4 m4/mktime.m4 m4/mmap-anon.m4 + m4/mode_t.m4 m4/mountlist.m4 m4/msvc-inval.m4 m4/msvc-nothrow.m4 @@ -854,16 +1301,21 @@ AC_DEFUN([gl_FILE_LIST], [ m4/nls.m4 m4/nocrash.m4 m4/off_t.m4 - m4/onceonly.m4 + m4/open-cloexec.m4 + m4/open-slash.m4 + m4/open.m4 + m4/pathmax.m4 + m4/pid_t.m4 m4/po.m4 - m4/printf-posix.m4 m4/printf.m4 m4/progtest.m4 - m4/read.m4 + m4/pthread_rwlock_rdlock.m4 + m4/realloc.m4 + m4/reallocarray.m4 m4/regex.m4 - m4/safe-read.m4 m4/servent.m4 m4/setenv.m4 + m4/setlocale_null.m4 m4/sha1.m4 m4/size_max.m4 m4/snprintf.m4 @@ -872,6 +1324,9 @@ AC_DEFUN([gl_FILE_LIST], [ m4/socklen.m4 m4/sockpfaf.m4 m4/ssize_t.m4 + m4/stat-time.m4 + m4/stat.m4 + m4/std-gnu11.m4 m4/stdalign.m4 m4/stdbool.m4 m4/stddef_h.m4 @@ -884,19 +1339,20 @@ AC_DEFUN([gl_FILE_LIST], [ m4/strerror.m4 m4/string_h.m4 m4/strings_h.m4 - m4/strndup.m4 - m4/strnlen.m4 m4/strsep.m4 m4/strstr.m4 m4/sys_socket_h.m4 + m4/sys_stat_h.m4 m4/sys_types_h.m4 m4/sys_uio_h.m4 m4/threadlib.m4 m4/time_h.m4 m4/time_r.m4 m4/timegm.m4 - m4/uintmax_t.m4 + m4/ungetc.m4 m4/unistd_h.m4 + m4/unlocked-io.m4 + m4/vararrays.m4 m4/vasnprintf.m4 m4/vasprintf.m4 m4/visibility.m4 @@ -909,5 +1365,6 @@ AC_DEFUN([gl_FILE_LIST], [ m4/wint_t.m4 m4/xalloc.m4 m4/xsize.m4 - m4/xstrndup.m4 + m4/year2038.m4 + m4/zzgnulib.m4 ]) diff --git a/gl/m4/gnulib-tool.m4 b/gl/m4/gnulib-tool.m4 index f3dea1a9..8428901c 100644 --- a/gl/m4/gnulib-tool.m4 +++ b/gl/m4/gnulib-tool.m4 @@ -1,5 +1,5 @@ -# gnulib-tool.m4 serial 2 -dnl Copyright (C) 2004-2005, 2009-2013 Free Software Foundation, Inc. +# gnulib-tool.m4 serial 4 +dnl Copyright (C) 2004-2005, 2009-2022 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. @@ -44,6 +44,12 @@ AC_DEFUN([gl_LGPL], []) dnl Usage: gl_MAKEFILE_NAME([FILENAME]) AC_DEFUN([gl_MAKEFILE_NAME], []) +dnl Usage: gl_TESTS_MAKEFILE_NAME([FILENAME]) +AC_DEFUN([gl_TESTS_MAKEFILE_NAME], []) + +dnl Usage: gl_AUTOMAKE_SUBDIR +AC_DEFUN([gl_AUTOMAKE_SUBDIR], []) + dnl Usage: gl_LIBTOOL AC_DEFUN([gl_LIBTOOL], []) diff --git a/gl/m4/host-cpu-c-abi.m4 b/gl/m4/host-cpu-c-abi.m4 new file mode 100644 index 00000000..b9223241 --- /dev/null +++ b/gl/m4/host-cpu-c-abi.m4 @@ -0,0 +1,678 @@ +# host-cpu-c-abi.m4 serial 15 +dnl Copyright (C) 2002-2022 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 From Bruno Haible and Sam Steingold. + +dnl Sets the HOST_CPU variable to the canonical name of the CPU. +dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its +dnl C language ABI (application binary interface). +dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in +dnl config.h. +dnl +dnl This canonical name can be used to select a particular assembly language +dnl source file that will interoperate with C code on the given host. +dnl +dnl For example: +dnl * 'i386' and 'sparc' are different canonical names, because code for i386 +dnl will not run on SPARC CPUs and vice versa. They have different +dnl instruction sets. +dnl * 'sparc' and 'sparc64' are different canonical names, because code for +dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code +dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit +dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit +dnl mode, but not both. +dnl * 'mips' and 'mipsn32' are different canonical names, because they use +dnl different argument passing and return conventions for C functions, and +dnl although the instruction set of 'mips' is a large subset of the +dnl instruction set of 'mipsn32'. +dnl * 'mipsn32' and 'mips64' are different canonical names, because they use +dnl different sizes for the C types like 'int' and 'void *', and although +dnl the instruction sets of 'mipsn32' and 'mips64' are the same. +dnl * The same canonical name is used for different endiannesses. You can +dnl determine the endianness through preprocessor symbols: +dnl - 'arm': test __ARMEL__. +dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL. +dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN. +dnl * The same name 'i386' is used for CPUs of type i386, i486, i586 +dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because +dnl - Instructions that do not exist on all of these CPUs (cmpxchg, +dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your +dnl assembly language source files use such instructions, you will +dnl need to make the distinction. +dnl - Speed of execution of the common instruction set is reasonable across +dnl the entire family of CPUs. If you have assembly language source files +dnl that are optimized for particular CPU types (like GNU gmp has), you +dnl will need to make the distinction. +dnl See . +AC_DEFUN([gl_HOST_CPU_C_ABI], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi], + [case "$host_cpu" in + +changequote(,)dnl + i[34567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=x86_64-x32], + [gl_cv_host_cpu_c_abi=x86_64])], + [gl_cv_host_cpu_c_abi=i386]) + ;; + +changequote(,)dnl + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __aarch64__ + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=arm64-ilp32], + [gl_cv_host_cpu_c_abi=arm64])], + [# Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + ]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=hppa64], + [gl_cv_host_cpu_c_abi=hppa]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=ia64-ilp32], + [gl_cv_host_cpu_c_abi=ia64]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mips64], + [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by ), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by ), and _MIPS_SIM == _ABIO32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mipsn32], + [gl_cv_host_cpu_c_abi=mips])]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [# On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=powerpc64-elfv2], + [gl_cv_host_cpu_c_abi=powerpc64]) + ], + [gl_cv_host_cpu_c_abi=powerpc]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + ]])], + [cpu=riscv64], + [cpu=riscv32]) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [main_abi=lp64], + [main_abi=ilp32]) + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + ]])], + [float_abi=d], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + ]])], + [float_abi=f], + [float_abi='']) + ]) + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=s390x], + [gl_cv_host_cpu_c_abi=s390]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=sparc64], + [gl_cv_host_cpu_c_abi=sparc]) + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + ]) + + dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same. + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + AC_SUBST([HOST_CPU]) + AC_SUBST([HOST_CPU_C_ABI]) + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <. +dnl Don't make changes that are incompatible with that documentation! + AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. @@ -72,27 +79,34 @@ AC_DEFUN([AM_ICONV_LINK], if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[ #include #include -int main () -{ - int result = 0; - /* Test against AIX 5.1 bug: Failures are not distinguishable from successful - returns. */ + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + ]], + [[int result = 0; + /* Test against AIX 5.1...7.2 bug: Failures are not distinguishable from + successful returns. This is even documented in + */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { - static const char input[] = "\342\202\254"; /* EURO SIGN */ + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; @@ -105,14 +119,14 @@ int main () iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { - static const char input[] = "\263"; + static ICONV_CONST char input[] = "\263"; char buf[10]; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; @@ -124,14 +138,14 @@ int main () iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { - static const char input[] = "\304"; + static ICONV_CONST char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; @@ -144,14 +158,14 @@ int main () iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { - static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; - const char *inptr = input; + ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, - (char **) &inptr, &inbytesleft, + &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; @@ -161,27 +175,36 @@ int main () #endif /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is provided. */ - if (/* Try standardized names. */ - iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) - /* Try IRIX, OSF/1 names. */ - && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) - /* Try AIX names. */ - && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) - /* Try HP-UX names. */ - && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) - result |= 16; + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 16; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } return result; -}]])], - [am_cv_func_iconv_works=yes], - [am_cv_func_iconv_works=no], - [ -changequote(,)dnl - case "$host_os" in - aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; - esac -changequote([,])dnl - ]) +]])], + [am_cv_func_iconv_works=yes], , + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + test "$am_cv_func_iconv_works" = no || break + done LIBS="$am_save_LIBS" ]) case "$am_cv_func_iconv_works" in @@ -209,60 +232,62 @@ changequote([,])dnl AC_SUBST([LTLIBICONV]) ]) -dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to -dnl avoid warnings like +dnl Define AM_ICONV using AC_DEFUN_ONCE, in order to avoid warnings like dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". -dnl This is tricky because of the way 'aclocal' is implemented: -dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. -dnl Otherwise aclocal's initial scan pass would miss the macro definition. -dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. -dnl Otherwise aclocal would emit many "Use of uninitialized value $1" -dnl warnings. -m4_define([gl_iconv_AC_DEFUN], - m4_version_prereq([2.64], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [m4_ifdef([gl_00GNULIB], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [[AC_DEFUN( - [$1], [$2])]])])) -gl_iconv_AC_DEFUN([AM_ICONV], +AC_DEFUN_ONCE([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL([am_cv_proto_iconv], [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ + AC_CACHE_CHECK([whether iconv is compatible with its POSIX signature], + [gl_cv_iconv_nonconst], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ #include #include extern #ifdef __cplusplus "C" #endif -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - ]], - [[]])], - [am_cv_proto_iconv_arg1=""], - [am_cv_proto_iconv_arg1="const"]) - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([ - $am_cv_proto_iconv]) - AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], - [Define as const if the declaration of iconv() needs const.]) - dnl Also substitute ICONV_CONST in the gnulib generated . - m4_ifdef([gl_ICONV_H_DEFAULTS], - [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) - if test -n "$am_cv_proto_iconv_arg1"; then - ICONV_CONST="const" - fi + ]], + [[]])], + [gl_cv_iconv_nonconst=yes], + [gl_cv_iconv_nonconst=no]) ]) + else + dnl When compiling GNU libiconv on a system that does not have iconv yet, + dnl pick the POSIX compliant declaration without 'const'. + gl_cv_iconv_nonconst=yes + fi + if test $gl_cv_iconv_nonconst = yes; then + iconv_arg1="" + else + iconv_arg1="const" + fi + AC_DEFINE_UNQUOTED([ICONV_CONST], [$iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + dnl Also substitute ICONV_CONST in the gnulib generated . + m4_ifdef([gl_ICONV_H_DEFAULTS], + [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test $gl_cv_iconv_nonconst != yes; then + ICONV_CONST="const" + fi + ]) + + dnl A summary result, for those packages which want to print a summary at the + dnl end of the configuration. + if test "$am_func_iconv" = yes; then + if test -n "$LIBICONV"; then + am_cv_func_iconv_summary='yes, in libiconv' + else + am_cv_func_iconv_summary='yes, in libc' + fi + else + if test "$am_cv_func_iconv" = yes; then + am_cv_func_iconv_summary='not working, consider installing GNU libiconv' + else + am_cv_func_iconv_summary='no, consider installing GNU libiconv' + fi fi ]) diff --git a/gl/m4/idpriv.m4 b/gl/m4/idpriv.m4 index 167f5238..b3b1c7b4 100644 --- a/gl/m4/idpriv.m4 +++ b/gl/m4/idpriv.m4 @@ -1,5 +1,5 @@ # idpriv.m4 serial 1 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2009-2022 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. diff --git a/gl/m4/include_next.m4 b/gl/m4/include_next.m4 index 108d9456..a9247f6f 100644 --- a/gl/m4/include_next.m4 +++ b/gl/m4/include_next.m4 @@ -1,12 +1,13 @@ -# include_next.m4 serial 23 -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. +# include_next.m4 serial 26 +dnl Copyright (C) 2006-2022 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 From Paul Eggert and Derek Price. -dnl Sets INCLUDE_NEXT and PRAGMA_SYSTEM_HEADER. +dnl Sets INCLUDE_NEXT, INCLUDE_NEXT_AS_FIRST_DIRECTIVE, PRAGMA_SYSTEM_HEADER, +dnl and PRAGMA_COLUMNS. dnl dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to dnl 'include' otherwise. @@ -105,19 +106,21 @@ dnl We intentionally avoid using AC_LANG_SOURCE here. AC_SUBST([INCLUDE_NEXT]) AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE]) AC_SUBST([PRAGMA_SYSTEM_HEADER]) - AC_CACHE_CHECK([whether system header files limit the line length], - [gl_cv_pragma_columns], - [dnl HP NonStop systems, which define __TANDEM, have this misfeature. - AC_EGREP_CPP([choke me], + + dnl HP NonStop systems, which define __TANDEM, limit the line length + dnl after including some system header files. + AC_CACHE_CHECK([whether source code line length is unlimited], + [gl_cv_source_line_length_unlimited], + [AC_EGREP_CPP([choke me], [ #ifdef __TANDEM choke me #endif ], - [gl_cv_pragma_columns=yes], - [gl_cv_pragma_columns=no]) + [gl_cv_source_line_length_unlimited=no], + [gl_cv_source_line_length_unlimited=yes]) ]) - if test $gl_cv_pragma_columns = yes; then + if test $gl_cv_source_line_length_unlimited = no; then PRAGMA_COLUMNS="#pragma COLUMNS 10000" else PRAGMA_COLUMNS= @@ -175,89 +178,40 @@ AC_DEFUN([gl_NEXT_HEADERS_INTERNAL], [AC_CHECK_HEADERS_ONCE([$1]) ]) -dnl FIXME: gl_next_header and gl_header_exists must be used unquoted -dnl until we can assume autoconf 2.64 or newer. m4_foreach_w([gl_HEADER_NAME], [$1], [AS_VAR_PUSHDEF([gl_next_header], [gl_cv_next_]m4_defn([gl_HEADER_NAME])) if test $gl_cv_have_include_next = yes; then - AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) + AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) else AC_CACHE_CHECK( [absolute name of <]m4_defn([gl_HEADER_NAME])[>], - m4_defn([gl_next_header]), + [gl_next_header], [m4_if([$2], [check], [AS_VAR_PUSHDEF([gl_header_exists], [ac_cv_header_]m4_defn([gl_HEADER_NAME])) - if test AS_VAR_GET(gl_header_exists) = yes; then + if test AS_VAR_GET([gl_header_exists]) = yes; then AS_VAR_POPDEF([gl_header_exists]) ]) - AC_LANG_CONFTEST( - [AC_LANG_SOURCE( - [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] - )]) - dnl AIX "xlc -E" and "cc -E" omit #line directives for header - dnl files that contain only a #include of other header files and - dnl no non-comment tokens of their own. This leads to a failure - dnl to detect the absolute name of , , - dnl and others. The workaround is to force preservation - dnl of comments through option -C. This ensures all necessary - dnl #line directives are present. GCC supports option -C as well. - case "$host_os" in - aix*) gl_absname_cpp="$ac_cpp -C" ;; - *) gl_absname_cpp="$ac_cpp" ;; - esac -changequote(,) - case "$host_os" in - mingw*) - dnl For the sake of native Windows compilers (excluding gcc), - dnl treat backslash as a directory separator, like /. - dnl Actually, these compilers use a double-backslash as - dnl directory separator, inside the - dnl # line "filename" - dnl directives. - gl_dirsep_regex='[/\\]' - ;; - *) - gl_dirsep_regex='\/' - ;; - esac - dnl A sed expression that turns a string into a basic regular - dnl expression, for use within "/.../". - gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' -changequote([,]) - gl_header_literal_regex=`echo ']m4_defn([gl_HEADER_NAME])[' \ - | sed -e "$gl_make_literal_regex_sed"` - gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ - s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ -changequote(,)dnl - s|^/[^/]|//&| -changequote([,])dnl - p - q - }' - dnl eval is necessary to expand gl_absname_cpp. - dnl Ultrix and Pyramid sh refuse to redirect output of eval, - dnl so use subshell. - AS_VAR_SET(gl_next_header, - ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | - sed -n "$gl_absolute_header_sed"`'"']) + gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME) + AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME)) + AS_VAR_SET([gl_next_header], ['"'$gl_header'"']) m4_if([$2], [check], [else - AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) + AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) fi ]) ]) fi AC_SUBST( AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])), - [AS_VAR_GET(gl_next_header)]) + [AS_VAR_GET([gl_next_header])]) if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' gl_next_as_first_directive='<'gl_HEADER_NAME'>' else # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' - gl_next_as_first_directive=AS_VAR_GET(gl_next_header) + gl_next_as_first_directive=AS_VAR_GET([gl_next_header]) fi AC_SUBST( AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])), diff --git a/gl/m4/inet_ntop.m4 b/gl/m4/inet_ntop.m4 index 476f063f..c335cae7 100644 --- a/gl/m4/inet_ntop.m4 +++ b/gl/m4/inet_ntop.m4 @@ -1,5 +1,5 @@ -# inet_ntop.m4 serial 19 -dnl Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc. +# inet_ntop.m4 serial 21 +dnl Copyright (C) 2005-2006, 2008-2022 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. @@ -16,6 +16,7 @@ AC_DEFUN([gl_FUNC_INET_NTOP], dnl Most platforms that provide inet_ntop define it in libc. dnl Solaris 8..10 provide inet_ntop in libnsl instead. dnl Solaris 2.6..7 provide inet_ntop in libresolv instead. + dnl Haiku provides it in -lnetwork. dnl Native Windows provides it in -lws2_32 instead, with a declaration in dnl , and it uses stdcall calling convention, not cdecl dnl (hence we cannot use AC_CHECK_FUNCS, AC_SEARCH_LIBS to find it). @@ -23,19 +24,20 @@ AC_DEFUN([gl_FUNC_INET_NTOP], INET_NTOP_LIB= gl_PREREQ_SYS_H_WINSOCK2 if test $HAVE_WINSOCK2_H = 1; then + dnl It needs to be overridden, because the stdcall calling convention + dnl is not compliant with POSIX. Set REPLACE_INET_NTOP in order to avoid + dnl a name conflict at the linker level, even though the header file + dnl declares inet_ntop only if _WIN32_WINNT >= 0x0600. + REPLACE_INET_NTOP=1 AC_CHECK_DECLS([inet_ntop],,, [[#include ]]) if test $ac_cv_have_decl_inet_ntop = yes; then - dnl It needs to be overridden, because the stdcall calling convention - dnl is not compliant with POSIX. - REPLACE_INET_NTOP=1 INET_NTOP_LIB="-lws2_32" else HAVE_DECL_INET_NTOP=0 - HAVE_INET_NTOP=0 fi else gl_save_LIBS=$LIBS - AC_SEARCH_LIBS([inet_ntop], [nsl resolv], [], + AC_SEARCH_LIBS([inet_ntop], [nsl resolv network], [], [AC_CHECK_FUNCS([inet_ntop]) if test $ac_cv_func_inet_ntop = no; then HAVE_INET_NTOP=0 diff --git a/gl/m4/intdiv0.m4 b/gl/m4/intdiv0.m4 deleted file mode 100644 index 74d0e80d..00000000 --- a/gl/m4/intdiv0.m4 +++ /dev/null @@ -1,87 +0,0 @@ -# intdiv0.m4 serial 6 (gettext-0.18.2) -dnl Copyright (C) 2002, 2007-2008, 2010-2013 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 From Bruno Haible. - -AC_DEFUN([gt_INTDIV0], -[ - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - - AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], - gt_cv_int_divbyzero_sigfpe, - [ - gt_cv_int_divbyzero_sigfpe= -changequote(,)dnl - case "$host_os" in - macos* | darwin[6-9]* | darwin[1-9][0-9]*) - # On Mac OS X 10.2 or newer, just assume the same as when cross- - # compiling. If we were to perform the real test, 1 Crash Report - # dialog window would pop up. - case "$host_cpu" in - i[34567]86 | x86_64) - gt_cv_int_divbyzero_sigfpe="guessing yes" ;; - esac - ;; - esac -changequote([,])dnl - if test -z "$gt_cv_int_divbyzero_sigfpe"; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include - -static void -sigfpe_handler (int sig) -{ - /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ - exit (sig != SIGFPE); -} - -int x = 1; -int y = 0; -int z; -int nan; - -int main () -{ - signal (SIGFPE, sigfpe_handler); -/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ -#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) - signal (SIGTRAP, sigfpe_handler); -#endif -/* Linux/SPARC yields signal SIGILL. */ -#if defined (__sparc__) && defined (__linux__) - signal (SIGILL, sigfpe_handler); -#endif - - z = x / y; - nan = y / y; - exit (2); -} -]])], - [gt_cv_int_divbyzero_sigfpe=yes], - [gt_cv_int_divbyzero_sigfpe=no], - [ - # Guess based on the CPU. -changequote(,)dnl - case "$host_cpu" in - alpha* | i[34567]86 | x86_64 | m68k | s390*) - gt_cv_int_divbyzero_sigfpe="guessing yes";; - *) - gt_cv_int_divbyzero_sigfpe="guessing no";; - esac -changequote([,])dnl - ]) - fi - ]) - case "$gt_cv_int_divbyzero_sigfpe" in - *yes) value=1;; - *) value=0;; - esac - AC_DEFINE_UNQUOTED([INTDIV0_RAISES_SIGFPE], [$value], - [Define if integer division by zero raises signal SIGFPE.]) -]) diff --git a/gl/m4/intl-thread-locale.m4 b/gl/m4/intl-thread-locale.m4 new file mode 100644 index 00000000..d5d5b26a --- /dev/null +++ b/gl/m4/intl-thread-locale.m4 @@ -0,0 +1,219 @@ +# intl-thread-locale.m4 serial 9 +dnl Copyright (C) 2015-2022 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 +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Check how to retrieve the name of a per-thread locale (POSIX locale_t). +dnl Sets gt_nameless_locales. +AC_DEFUN([gt_INTL_THREAD_LOCALE_NAME], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + + dnl Persuade Solaris to define 'locale_t'. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + dnl Test whether uselocale() exists and works at all. + gt_FUNC_USELOCALE + + dnl On OpenBSD >= 6.2, the locale_t type and the uselocale(), newlocale(), + dnl duplocale(), freelocale() functions exist but are effectively useless, + dnl because the locale_t value depends only on the LC_CTYPE category of the + dnl locale and furthermore contains only one bit of information (it + dnl distinguishes the "C" locale from the *.UTF-8 locales). See + dnl . + dnl In the setlocale() implementation they have thought about the programs + dnl that use the API ("Even though only LC_CTYPE has any effect in the + dnl OpenBSD base system, store complete information about the global locale, + dnl such that third-party software can access it"), but for uselocale() + dnl they did not think about the programs. + dnl In this situation, even the HAVE_NAMELESS_LOCALES support does not work. + dnl So, define HAVE_FAKE_LOCALES and disable all locale_t support. + case "$gt_cv_func_uselocale_works" in + *yes) + AC_CHECK_HEADERS_ONCE([xlocale.h]) + AC_CACHE_CHECK([for fake locale system (OpenBSD)], + [gt_cv_locale_fake], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#if HAVE_XLOCALE_H +# include +#endif +int main () +{ + locale_t loc1, loc2; + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) return 1; + if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL) return 1; + loc1 = newlocale (LC_ALL_MASK, "de_DE.UTF-8", (locale_t)0); + loc2 = newlocale (LC_ALL_MASK, "fr_FR.UTF-8", (locale_t)0); + return !(loc1 == loc2); +}]])], + [gt_cv_locale_fake=yes], + [gt_cv_locale_fake=no], + [dnl Guess the locale system is fake only on OpenBSD. + case "$host_os" in + openbsd*) gt_cv_locale_fake="guessing yes" ;; + *) gt_cv_locale_fake="guessing no" ;; + esac + ]) + ]) + ;; + *) gt_cv_locale_fake=no ;; + esac + case "$gt_cv_locale_fake" in + *yes) + gt_fake_locales=yes + AC_DEFINE([HAVE_FAKE_LOCALES], [1], + [Define if the locale_t type contains insufficient information, as on OpenBSD.]) + ;; + *) + gt_fake_locales=no + ;; + esac + + case "$gt_cv_func_uselocale_works" in + *yes) + AC_CACHE_CHECK([for Solaris 11.4 locale system], + [gt_cv_locale_solaris114], + [case "$host_os" in + solaris*) + dnl Test whether defines locale_t as a typedef of + dnl 'struct _LC_locale_t **' (whereas Illumos defines it as a + dnl typedef of 'struct _locale *'). + dnl Another possible test would be to include + dnl and test whether it defines the _LC_core_data_locale_t type. + dnl This type was added in Solaris 11.4. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + struct _LC_locale_t *x; + locale_t y; + ]], + [[*y = x;]])], + [gt_cv_locale_solaris114=yes], + [gt_cv_locale_solaris114=no]) + ;; + *) gt_cv_locale_solaris114=no ;; + esac + ]) + ;; + *) gt_cv_locale_solaris114=no ;; + esac + if test $gt_cv_locale_solaris114 = yes; then + AC_DEFINE([HAVE_SOLARIS114_LOCALES], [1], + [Define if the locale_t type is as on Solaris 11.4.]) + fi + + dnl Solaris 12 will maybe provide getlocalename_l. If it does, it will + dnl improve the implementation of gl_locale_name_thread(), by removing + dnl the use of undocumented structures. + case "$gt_cv_func_uselocale_works" in + *yes) + AC_CHECK_FUNCS([getlocalename_l]) + ;; + esac + + dnl This code is for platforms where the locale_t type does not provide access + dnl to the name of each locale category. This code has the drawback that it + dnl requires the gnulib overrides of 'newlocale', 'duplocale', 'freelocale', + dnl which is a problem for GNU libunistring. Therefore try hard to avoid + dnl enabling this code! + gt_nameless_locales=no + case "$host_os" in + dnl It's needed on AIX 7.2. + aix*) + gt_nameless_locales=yes + AC_DEFINE([HAVE_NAMELESS_LOCALES], [1], + [Define if the locale_t type does not contain the name of each locale category.]) + ;; + esac + + dnl We cannot support uselocale() on platforms where the locale_t type is + dnl fake. So, set + dnl gt_good_uselocale = gt_working_uselocale && !gt_fake_locales. + if test $gt_working_uselocale = yes && test $gt_fake_locales = no; then + gt_good_uselocale=yes + AC_DEFINE([HAVE_GOOD_USELOCALE], [1], + [Define if the uselocale exists, may be safely called, and returns sufficient information.]) + else + gt_good_uselocale=no + fi + + dnl Set gt_localename_enhances_locale_funcs to indicate whether localename.c + dnl overrides newlocale(), duplocale(), freelocale() to keep track of locale + dnl names. + if test $gt_good_uselocale = yes && test $gt_nameless_locales = yes; then + gt_localename_enhances_locale_funcs=yes + LOCALENAME_ENHANCE_LOCALE_FUNCS=1 + AC_DEFINE([LOCALENAME_ENHANCE_LOCALE_FUNCS], [1], + [Define if localename.c overrides newlocale(), duplocale(), freelocale().]) + else + gt_localename_enhances_locale_funcs=no + fi +]) + +dnl Tests whether uselocale() exists and is usable. +dnl Sets gt_working_uselocale and defines HAVE_WORKING_USELOCALE. +AC_DEFUN([gt_FUNC_USELOCALE], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Persuade glibc and Solaris to define 'locale_t'. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_FUNCS_ONCE([uselocale]) + + dnl On AIX 7.2, the uselocale() function is not documented and leads to + dnl crashes in subsequent setlocale() invocations. + dnl In 2019, some versions of z/OS lack the locale_t type and have a broken + dnl uselocale function. + if test $ac_cv_func_uselocale = yes; then + AC_CHECK_HEADERS_ONCE([xlocale.h]) + AC_CACHE_CHECK([whether uselocale works], + [gt_cv_func_uselocale_works], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#if HAVE_XLOCALE_H +# include +#endif +locale_t loc1; +int main () +{ + uselocale (NULL); + setlocale (LC_ALL, "en_US.UTF-8"); + return 0; +}]])], + [gt_cv_func_uselocale_works=yes], + [gt_cv_func_uselocale_works=no], + [# Guess no on AIX and z/OS, yes otherwise. + case "$host_os" in + aix* | openedition*) gt_cv_func_uselocale_works="guessing no" ;; + *) gt_cv_func_uselocale_works="guessing yes" ;; + esac + ]) + ]) + else + gt_cv_func_uselocale_works=no + fi + case "$gt_cv_func_uselocale_works" in + *yes) + gt_working_uselocale=yes + AC_DEFINE([HAVE_WORKING_USELOCALE], [1], + [Define if the uselocale function exists and may safely be called.]) + ;; + *) + gt_working_uselocale=no + ;; + esac +]) diff --git a/gl/m4/intl.m4 b/gl/m4/intl.m4 deleted file mode 100644 index 959bd042..00000000 --- a/gl/m4/intl.m4 +++ /dev/null @@ -1,271 +0,0 @@ -# intl.m4 serial 23 (gettext-0.18.3) -dnl Copyright (C) 1995-2013 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2009. - -AC_PREREQ([2.60]) - -dnl Checks for all prerequisites of the intl subdirectory, -dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, -dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. -AC_DEFUN([AM_INTL_SUBDIR], -[ - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AC_PROG_MKDIR_P])dnl - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - AC_REQUIRE([gt_GLIBC2])dnl - AC_REQUIRE([AC_PROG_RANLIB])dnl - AC_REQUIRE([gl_VISIBILITY])dnl - AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl - AC_REQUIRE([AC_TYPE_LONG_LONG_INT])dnl - AC_REQUIRE([gt_TYPE_WCHAR_T])dnl - AC_REQUIRE([gt_TYPE_WINT_T])dnl - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gt_TYPE_INTMAX_T]) - AC_REQUIRE([gt_PRINTF_POSIX]) - AC_REQUIRE([gl_GLIBC21])dnl - AC_REQUIRE([gl_XSIZE])dnl - AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl - AC_REQUIRE([gt_INTL_MACOSX])dnl - - dnl Support for automake's --enable-silent-rules. - case "$enable_silent_rules" in - yes) INTL_DEFAULT_VERBOSITY=0;; - no) INTL_DEFAULT_VERBOSITY=1;; - *) INTL_DEFAULT_VERBOSITY=1;; - esac - AC_SUBST([INTL_DEFAULT_VERBOSITY]) - - AC_CHECK_TYPE([ptrdiff_t], , - [AC_DEFINE([ptrdiff_t], [long], - [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) - ]) - AC_CHECK_HEADERS([features.h stddef.h stdlib.h string.h]) - AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \ - snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) - - dnl Use the _snprintf function only if it is declared (because on NetBSD it - dnl is defined as a weak alias of snprintf; we prefer to use the latter). - AC_CHECK_DECLS([_snprintf _snwprintf], , , [#include ]) - - dnl Use the *_unlocked functions only if they are declared. - dnl (because some of them were defined without being declared in Solaris - dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built - dnl on Solaris 2.5.1 to run on Solaris 2.6). - AC_CHECK_DECLS([getc_unlocked], , , [#include ]) - - case $gt_cv_func_printf_posix in - *yes) HAVE_POSIX_PRINTF=1 ;; - *) HAVE_POSIX_PRINTF=0 ;; - esac - AC_SUBST([HAVE_POSIX_PRINTF]) - if test "$ac_cv_func_asprintf" = yes; then - HAVE_ASPRINTF=1 - else - HAVE_ASPRINTF=0 - fi - AC_SUBST([HAVE_ASPRINTF]) - if test "$ac_cv_func_snprintf" = yes; then - HAVE_SNPRINTF=1 - else - HAVE_SNPRINTF=0 - fi - AC_SUBST([HAVE_SNPRINTF]) - if test "$ac_cv_func_newlocale" = yes; then - HAVE_NEWLOCALE=1 - else - HAVE_NEWLOCALE=0 - fi - AC_SUBST([HAVE_NEWLOCALE]) - if test "$ac_cv_func_wprintf" = yes; then - HAVE_WPRINTF=1 - else - HAVE_WPRINTF=0 - fi - AC_SUBST([HAVE_WPRINTF]) - - AM_LANGINFO_CODESET - gt_LC_MESSAGES - - dnl Compilation on mingw and Cygwin needs special Makefile rules, because - dnl 1. when we install a shared library, we must arrange to export - dnl auxiliary pointer variables for every exported variable, - dnl 2. when we install a shared library and a static library simultaneously, - dnl the include file specifies __declspec(dllimport) and therefore we - dnl must arrange to define the auxiliary pointer variables for the - dnl exported variables _also_ in the static library. - if test "$enable_shared" = yes; then - case "$host_os" in - mingw* | cygwin*) is_woe32dll=yes ;; - *) is_woe32dll=no ;; - esac - else - is_woe32dll=no - fi - WOE32DLL=$is_woe32dll - AC_SUBST([WOE32DLL]) - - dnl On mingw and Cygwin, we can activate special Makefile rules which add - dnl version information to the shared libraries and executables. - case "$host_os" in - mingw* | cygwin*) is_woe32=yes ;; - *) is_woe32=no ;; - esac - WOE32=$is_woe32 - AC_SUBST([WOE32]) - if test $WOE32 = yes; then - dnl Check for a program that compiles Windows resource files. - AC_CHECK_TOOL([WINDRES], [windres]) - fi - - dnl Determine whether when creating a library, "-lc" should be passed to - dnl libtool or not. On many platforms, it is required for the libtool option - dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool - dnl in the *.la files - makes it impossible to create multithreaded programs, - dnl because libtool also reorders the -lc to come before the -pthread, and - dnl this disables pthread_create() . - case "$host_os" in - hpux*) LTLIBC="" ;; - *) LTLIBC="-lc" ;; - esac - AC_SUBST([LTLIBC]) - - dnl Rename some macros and functions used for locking. - AH_BOTTOM([ -#define __libc_lock_t gl_lock_t -#define __libc_lock_define gl_lock_define -#define __libc_lock_define_initialized gl_lock_define_initialized -#define __libc_lock_init gl_lock_init -#define __libc_lock_lock gl_lock_lock -#define __libc_lock_unlock gl_lock_unlock -#define __libc_lock_recursive_t gl_recursive_lock_t -#define __libc_lock_define_recursive gl_recursive_lock_define -#define __libc_lock_define_initialized_recursive gl_recursive_lock_define_initialized -#define __libc_lock_init_recursive gl_recursive_lock_init -#define __libc_lock_lock_recursive gl_recursive_lock_lock -#define __libc_lock_unlock_recursive gl_recursive_lock_unlock -#define glthread_in_use libintl_thread_in_use -#define glthread_lock_init_func libintl_lock_init_func -#define glthread_lock_lock_func libintl_lock_lock_func -#define glthread_lock_unlock_func libintl_lock_unlock_func -#define glthread_lock_destroy_func libintl_lock_destroy_func -#define glthread_rwlock_init_multithreaded libintl_rwlock_init_multithreaded -#define glthread_rwlock_init_func libintl_rwlock_init_func -#define glthread_rwlock_rdlock_multithreaded libintl_rwlock_rdlock_multithreaded -#define glthread_rwlock_rdlock_func libintl_rwlock_rdlock_func -#define glthread_rwlock_wrlock_multithreaded libintl_rwlock_wrlock_multithreaded -#define glthread_rwlock_wrlock_func libintl_rwlock_wrlock_func -#define glthread_rwlock_unlock_multithreaded libintl_rwlock_unlock_multithreaded -#define glthread_rwlock_unlock_func libintl_rwlock_unlock_func -#define glthread_rwlock_destroy_multithreaded libintl_rwlock_destroy_multithreaded -#define glthread_rwlock_destroy_func libintl_rwlock_destroy_func -#define glthread_recursive_lock_init_multithreaded libintl_recursive_lock_init_multithreaded -#define glthread_recursive_lock_init_func libintl_recursive_lock_init_func -#define glthread_recursive_lock_lock_multithreaded libintl_recursive_lock_lock_multithreaded -#define glthread_recursive_lock_lock_func libintl_recursive_lock_lock_func -#define glthread_recursive_lock_unlock_multithreaded libintl_recursive_lock_unlock_multithreaded -#define glthread_recursive_lock_unlock_func libintl_recursive_lock_unlock_func -#define glthread_recursive_lock_destroy_multithreaded libintl_recursive_lock_destroy_multithreaded -#define glthread_recursive_lock_destroy_func libintl_recursive_lock_destroy_func -#define glthread_once_func libintl_once_func -#define glthread_once_singlethreaded libintl_once_singlethreaded -#define glthread_once_multithreaded libintl_once_multithreaded -]) -]) - - -dnl Checks for the core files of the intl subdirectory: -dnl dcigettext.c -dnl eval-plural.h -dnl explodename.c -dnl finddomain.c -dnl gettextP.h -dnl gmo.h -dnl hash-string.h hash-string.c -dnl l10nflist.c -dnl libgnuintl.h.in (except the *printf stuff) -dnl loadinfo.h -dnl loadmsgcat.c -dnl localealias.c -dnl log.c -dnl plural-exp.h plural-exp.c -dnl plural.y -dnl Used by libglocale. -AC_DEFUN([gt_INTL_SUBDIR_CORE], -[ - AC_REQUIRE([AC_C_INLINE])dnl - AC_REQUIRE([AC_TYPE_SIZE_T])dnl - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_REQUIRE([AC_FUNC_ALLOCA])dnl - AC_REQUIRE([AC_FUNC_MMAP])dnl - AC_REQUIRE([gt_INTDIV0])dnl - AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl - AC_REQUIRE([gt_INTTYPES_PRI])dnl - AC_REQUIRE([gl_LOCK])dnl - - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }]], - [[]])], - [AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], - [Define to 1 if the compiler understands __builtin_expect.])]) - - AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h]) - AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \ - stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \ - argz_stringify argz_next __fsetlocking]) - - dnl Use the *_unlocked functions only if they are declared. - dnl (because some of them were defined without being declared in Solaris - dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built - dnl on Solaris 2.5.1 to run on Solaris 2.6). - AC_CHECK_DECLS([feof_unlocked fgets_unlocked], , , [#include ]) - - AM_ICONV - - dnl intl/plural.c is generated from intl/plural.y. It requires bison, - dnl because plural.y uses bison specific features. It requires at least - dnl bison-1.26 because earlier versions generate a plural.c that doesn't - dnl compile. - dnl bison is only needed for the maintainer (who touches plural.y). But in - dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put - dnl the rule in general Makefile. Now, some people carelessly touch the - dnl files or have a broken "make" program, hence the plural.c rule will - dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not - dnl present or too old. - AC_CHECK_PROGS([INTLBISON], [bison]) - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - dnl Found it, now check the version. - AC_MSG_CHECKING([version of bison]) -changequote(<<,>>)dnl - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) -changequote([,])dnl - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - AC_MSG_RESULT([$ac_prog_version]) - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi -]) diff --git a/gl/m4/intldir.m4 b/gl/m4/intldir.m4 deleted file mode 100644 index 388ecd6f..00000000 --- a/gl/m4/intldir.m4 +++ /dev/null @@ -1,19 +0,0 @@ -# intldir.m4 serial 2 (gettext-0.18) -dnl Copyright (C) 2006, 2009-2013 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -AC_PREREQ([2.52]) - -dnl Tells the AM_GNU_GETTEXT macro to consider an intl/ directory. -AC_DEFUN([AM_GNU_GETTEXT_INTL_SUBDIR], []) diff --git a/gl/m4/intlmacosx.m4 b/gl/m4/intlmacosx.m4 index ab97d39f..ecc88d6e 100644 --- a/gl/m4/intlmacosx.m4 +++ b/gl/m4/intlmacosx.m4 @@ -1,23 +1,23 @@ -# intlmacosx.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. +# intlmacosx.m4 serial 8 (gettext-0.20.2) +dnl Copyright (C) 2004-2014, 2016, 2019-2022 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Checks for special options needed on Mac OS X. dnl Defines INTL_MACOSX_LIBS. AC_DEFUN([gt_INTL_MACOSX], [ - dnl Check for API introduced in Mac OS X 10.2. + dnl Check for API introduced in Mac OS X 10.4. AC_CACHE_CHECK([for CFPreferencesCopyAppValue], [gt_cv_func_CFPreferencesCopyAppValue], [gt_save_LIBS="$LIBS" @@ -33,23 +33,32 @@ AC_DEFUN([gt_INTL_MACOSX], AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) fi - dnl Check for API introduced in Mac OS X 10.3. - AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], + dnl Don't check for the API introduced in Mac OS X 10.5, CFLocaleCopyCurrent, + dnl because in macOS 10.13.4 it has the following behaviour: + dnl When two or more languages are specified in the + dnl "System Preferences > Language & Region > Preferred Languages" panel, + dnl it returns en_CC where CC is the territory (even when English is not among + dnl the preferred languages!). What we want instead is what + dnl CFLocaleCopyCurrent returned in earlier macOS releases and what + dnl CFPreferencesCopyAppValue still returns, namely ll_CC where ll is the + dnl first among the preferred languages and CC is the territory. + AC_CACHE_CHECK([for CFLocaleCopyPreferredLanguages], [gt_cv_func_CFLocaleCopyPreferredLanguages], [gt_save_LIBS="$LIBS" LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], - [[CFLocaleCopyCurrent();]])], - [gt_cv_func_CFLocaleCopyCurrent=yes], - [gt_cv_func_CFLocaleCopyCurrent=no]) + [[CFLocaleCopyPreferredLanguages();]])], + [gt_cv_func_CFLocaleCopyPreferredLanguages=yes], + [gt_cv_func_CFLocaleCopyPreferredLanguages=no]) LIBS="$gt_save_LIBS"]) - if test $gt_cv_func_CFLocaleCopyCurrent = yes; then - AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], - [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYPREFERREDLANGUAGES], [1], + [Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework.]) fi INTL_MACOSX_LIBS= - if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + if test $gt_cv_func_CFPreferencesCopyAppValue = yes \ + || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi AC_SUBST([INTL_MACOSX_LIBS]) diff --git a/gl/m4/intmax.m4 b/gl/m4/intmax.m4 deleted file mode 100644 index 18733a52..00000000 --- a/gl/m4/intmax.m4 +++ /dev/null @@ -1,36 +0,0 @@ -# intmax.m4 serial 6 (gettext-0.18.2) -dnl Copyright (C) 2002-2005, 2008-2013 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 From Bruno Haible. -dnl Test whether the system has the 'intmax_t' type, but don't attempt to -dnl find a replacement if it is lacking. - -AC_DEFUN([gt_TYPE_INTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -#include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -#include -#endif - ]], - [[intmax_t x = -1; - return !x;]])], - [gt_cv_c_intmax_t=yes], - [gt_cv_c_intmax_t=no])]) - if test $gt_cv_c_intmax_t = yes; then - AC_DEFINE([HAVE_INTMAX_T], [1], - [Define if you have the 'intmax_t' type in or .]) - fi -]) diff --git a/gl/m4/intmax_t.m4 b/gl/m4/intmax_t.m4 index 6ea70531..8a15dabd 100644 --- a/gl/m4/intmax_t.m4 +++ b/gl/m4/intmax_t.m4 @@ -1,5 +1,5 @@ -# intmax_t.m4 serial 8 -dnl Copyright (C) 1997-2004, 2006-2007, 2009-2013 Free Software Foundation, +# intmax_t.m4 serial 9 +dnl Copyright (C) 1997-2004, 2006-2007, 2009-2022 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,11 +19,7 @@ AC_DEFUN([gl_AC_TYPE_INTMAX_T], AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) AC_REQUIRE([gl_AC_HEADER_STDINT_H]) if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - test $ac_cv_type_long_long_int = yes \ - && ac_type='long long' \ - || ac_type='long' - AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], + AC_DEFINE_UNQUOTED([intmax_t], [long long], [Define to long or long long if and don't define.]) else AC_DEFINE([HAVE_INTMAX_T], [1], @@ -57,11 +53,7 @@ AC_DEFUN([gt_AC_TYPE_INTMAX_T], AC_DEFINE([HAVE_INTMAX_T], [1], [Define if you have the 'intmax_t' type in or .]) else - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - test $ac_cv_type_long_long_int = yes \ - && ac_type='long long' \ - || ac_type='long' - AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], + AC_DEFINE_UNQUOTED([intmax_t], [long long], [Define to long or long long if and don't define.]) fi ]) diff --git a/gl/m4/inttypes-pri.m4 b/gl/m4/inttypes-pri.m4 deleted file mode 100644 index e5a1e057..00000000 --- a/gl/m4/inttypes-pri.m4 +++ /dev/null @@ -1,42 +0,0 @@ -# inttypes-pri.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1997-2002, 2006, 2008-2013 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 From Bruno Haible. - -AC_PREREQ([2.53]) - -# Define PRI_MACROS_BROKEN if exists and defines the PRI* -# macros to non-string values. This is the case on AIX 4.3.3. - -AC_DEFUN([gt_INTTYPES_PRI], -[ - AC_CHECK_HEADERS([inttypes.h]) - if test $ac_cv_header_inttypes_h = yes; then - AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], - [gt_cv_inttypes_pri_broken], - [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#ifdef PRId32 -char *p = PRId32; -#endif - ]], - [[]])], - [gt_cv_inttypes_pri_broken=no], - [gt_cv_inttypes_pri_broken=yes]) - ]) - fi - if test "$gt_cv_inttypes_pri_broken" = yes; then - AC_DEFINE_UNQUOTED([PRI_MACROS_BROKEN], [1], - [Define if exists and defines unusable PRI* macros.]) - PRI_MACROS_BROKEN=1 - else - PRI_MACROS_BROKEN=0 - fi - AC_SUBST([PRI_MACROS_BROKEN]) -]) diff --git a/gl/m4/inttypes.m4 b/gl/m4/inttypes.m4 new file mode 100644 index 00000000..df25a21e --- /dev/null +++ b/gl/m4/inttypes.m4 @@ -0,0 +1,180 @@ +# inttypes.m4 serial 36 +dnl Copyright (C) 2006-2022 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 From Derek Price, Bruno Haible. +dnl Test whether is supported or must be substituted. + +AC_DEFUN_ONCE([gl_INTTYPES_H], +[ + AC_REQUIRE([gl_INTTYPES_INCOMPLETE]) + gl_INTTYPES_PRI_SCN +]) + +AC_DEFUN_ONCE([gl_INTTYPES_INCOMPLETE], +[ + AC_REQUIRE([gl_STDINT_H]) + AC_CHECK_HEADERS_ONCE([inttypes.h]) + + dnl Override always, so that the portability warnings work. + AC_REQUIRE([gl_INTTYPES_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([inttypes.h]) + + AC_REQUIRE([gl_MULTIARCH]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[#include + ]], [imaxabs imaxdiv strtoimax strtoumax]) + + AC_REQUIRE([AC_C_RESTRICT]) +]) + +# Ensure that the PRI* and SCN* macros are defined appropriately. +AC_DEFUN([gl_INTTYPES_PRI_SCN], +[ + PRIPTR_PREFIX= + if $GL_GENERATE_STDINT_H; then + dnl Using the gnulib . It defines intptr_t to 'long' or + dnl 'long long', depending on _WIN64. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #ifdef _WIN64 + LLP64 + #endif + ]]) + ], + [PRIPTR_PREFIX='"l"'], + [PRIPTR_PREFIX='"ll"']) + else + dnl Using the system's . + for glpfx in '' l ll I64; do + case $glpfx in + '') gltype1='int';; + l) gltype1='long int';; + ll) gltype1='long long int';; + I64) gltype1='__int64';; + esac + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include + extern intptr_t foo; + extern $gltype1 foo;]])], + [PRIPTR_PREFIX='"'$glpfx'"']) + test -n "$PRIPTR_PREFIX" && break + done + fi + AC_SUBST([PRIPTR_PREFIX]) + + gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( + [INT32_MAX_LT_INTMAX_MAX], + [defined INT32_MAX && defined INTMAX_MAX], + [INT32_MAX < INTMAX_MAX], + [sizeof (int) < sizeof (long long int)]) + if test $APPLE_UNIVERSAL_BUILD = 0; then + gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( + [INT64_MAX_EQ_LONG_MAX], + [defined INT64_MAX], + [INT64_MAX == LONG_MAX], + [sizeof (long long int) == sizeof (long int)]) + else + INT64_MAX_EQ_LONG_MAX=-1 + fi + gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( + [UINT32_MAX_LT_UINTMAX_MAX], + [defined UINT32_MAX && defined UINTMAX_MAX], + [UINT32_MAX < UINTMAX_MAX], + [sizeof (unsigned int) < sizeof (unsigned long long int)]) + if test $APPLE_UNIVERSAL_BUILD = 0; then + gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( + [UINT64_MAX_EQ_ULONG_MAX], + [defined UINT64_MAX], + [UINT64_MAX == ULONG_MAX], + [sizeof (unsigned long long int) == sizeof (unsigned long int)]) + else + UINT64_MAX_EQ_ULONG_MAX=-1 + fi +]) + +# Define the symbol $1 to be 1 if the condition is true, 0 otherwise. +# If $2 is true, the condition is $3; otherwise if long long int is supported +# approximate the condition with $4; otherwise, assume the condition is false. +# The condition should work on all C99 platforms; the approximations should be +# good enough to work on all practical pre-C99 platforms. +# $2 is evaluated by the C preprocessor, $3 and $4 as compile-time constants. +AC_DEFUN([gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION], +[ + AC_CACHE_CHECK([whether $3], + [gl_cv_test_$1], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[/* Work also in C++ mode. */ + #define __STDC_LIMIT_MACROS 1 + + /* Work if build is not clean. */ + #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H + + #include + #if HAVE_STDINT_H + #include + #endif + + #if $2 + #define CONDITION ($3) + #else + #define CONDITION ($4) + #endif + int test[CONDITION ? 1 : -1];]])], + [gl_cv_test_$1=yes], + [gl_cv_test_$1=no])]) + if test $gl_cv_test_$1 = yes; then + $1=1; + else + $1=0; + fi + AC_SUBST([$1]) +]) + +# gl_INTTYPES_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. +AC_DEFUN([gl_INTTYPES_MODULE_INDICATOR], +[ + dnl Ensure to expand the default settings once only. + gl_INTTYPES_H_REQUIRE_DEFAULTS + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +]) + +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_INTTYPES_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_INTTYPES_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_IMAXABS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_IMAXDIV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOIMAX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOUMAX]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_INTTYPES_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_INTTYPES_H_DEFAULTS]) +]) + +AC_DEFUN([gl_INTTYPES_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_DECL_IMAXABS=1; AC_SUBST([HAVE_DECL_IMAXABS]) + HAVE_DECL_IMAXDIV=1; AC_SUBST([HAVE_DECL_IMAXDIV]) + HAVE_DECL_STRTOIMAX=1; AC_SUBST([HAVE_DECL_STRTOIMAX]) + HAVE_DECL_STRTOUMAX=1; AC_SUBST([HAVE_DECL_STRTOUMAX]) + HAVE_IMAXDIV_T=1; AC_SUBST([HAVE_IMAXDIV_T]) + REPLACE_STRTOIMAX=0; AC_SUBST([REPLACE_STRTOIMAX]) + REPLACE_STRTOUMAX=0; AC_SUBST([REPLACE_STRTOUMAX]) + INT32_MAX_LT_INTMAX_MAX=1; AC_SUBST([INT32_MAX_LT_INTMAX_MAX]) + INT64_MAX_EQ_LONG_MAX='defined _LP64'; AC_SUBST([INT64_MAX_EQ_LONG_MAX]) + PRIPTR_PREFIX=__PRIPTR_PREFIX; AC_SUBST([PRIPTR_PREFIX]) + UINT32_MAX_LT_UINTMAX_MAX=1; AC_SUBST([UINT32_MAX_LT_UINTMAX_MAX]) + UINT64_MAX_EQ_ULONG_MAX='defined _LP64'; AC_SUBST([UINT64_MAX_EQ_ULONG_MAX]) +]) diff --git a/gl/m4/inttypes_h.m4 b/gl/m4/inttypes_h.m4 index 5f05ac58..6e9eebf1 100644 --- a/gl/m4/inttypes_h.m4 +++ b/gl/m4/inttypes_h.m4 @@ -1,5 +1,5 @@ # inttypes_h.m4 serial 10 -dnl Copyright (C) 1997-2004, 2006, 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 1997-2004, 2006, 2008-2022 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. diff --git a/gl/m4/langinfo_h.m4 b/gl/m4/langinfo_h.m4 index 73bef8bc..563c8c43 100644 --- a/gl/m4/langinfo_h.m4 +++ b/gl/m4/langinfo_h.m4 @@ -1,10 +1,10 @@ -# langinfo_h.m4 serial 7 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. +# langinfo_h.m4 serial 12 +dnl Copyright (C) 2009-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_LANGINFO_H], +AC_DEFUN_ONCE([gl_LANGINFO_H], [ AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) @@ -17,13 +17,17 @@ AC_DEFUN([gl_LANGINFO_H], dnl Determine whether exists. It is missing on mingw and BeOS. HAVE_LANGINFO_CODESET=0 HAVE_LANGINFO_T_FMT_AMPM=0 + HAVE_LANGINFO_ALTMON=0 HAVE_LANGINFO_ERA=0 HAVE_LANGINFO_YESEXPR=0 AC_CHECK_HEADERS_ONCE([langinfo.h]) if test $ac_cv_header_langinfo_h = yes; then HAVE_LANGINFO_H=1 - dnl Determine what defines. CODESET and ERA etc. are missing - dnl on OpenBSD 3.8. T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3. + dnl Determine what defines. + dnl CODESET is missing on OpenBSD 3.8. + dnl ERA etc. are missing on OpenBSD 6.7. + dnl T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3. + dnl ALTMON_* are missing on glibc 2.26 and many other systems. AC_CACHE_CHECK([whether langinfo.h defines CODESET], [gl_cv_header_langinfo_codeset], [AC_COMPILE_IFELSE( @@ -48,6 +52,18 @@ int a = T_FMT_AMPM; if test $gl_cv_header_langinfo_t_fmt_ampm = yes; then HAVE_LANGINFO_T_FMT_AMPM=1 fi + AC_CACHE_CHECK([whether langinfo.h defines ALTMON_1], + [gl_cv_header_langinfo_altmon], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include +int a = ALTMON_1; +]])], + [gl_cv_header_langinfo_altmon=yes], + [gl_cv_header_langinfo_altmon=no]) + ]) + if test $gl_cv_header_langinfo_altmon = yes; then + HAVE_LANGINFO_ALTMON=1 + fi AC_CACHE_CHECK([whether langinfo.h defines ERA], [gl_cv_header_langinfo_era], [AC_COMPILE_IFELSE( @@ -78,6 +94,7 @@ int a = YESEXPR; AC_SUBST([HAVE_LANGINFO_H]) AC_SUBST([HAVE_LANGINFO_CODESET]) AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM]) + AC_SUBST([HAVE_LANGINFO_ALTMON]) AC_SUBST([HAVE_LANGINFO_ERA]) AC_SUBST([HAVE_LANGINFO_YESEXPR]) @@ -87,18 +104,33 @@ int a = YESEXPR; ]], [nl_langinfo]) ]) +# gl_LANGINFO_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_LANGINFO_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_LANGINFO_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_LANGINFO_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_LANGINFO_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NL_LANGINFO]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_LANGINFO_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) +]) + AC_DEFUN([gl_LANGINFO_H_DEFAULTS], [ - GNULIB_NL_LANGINFO=0; AC_SUBST([GNULIB_NL_LANGINFO]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_NL_LANGINFO=1; AC_SUBST([HAVE_NL_LANGINFO]) REPLACE_NL_LANGINFO=0; AC_SUBST([REPLACE_NL_LANGINFO]) diff --git a/gl/m4/largefile.m4 b/gl/m4/largefile.m4 index 1e605e3d..ec9677c4 100644 --- a/gl/m4/largefile.m4 +++ b/gl/m4/largefile.m4 @@ -1,29 +1,52 @@ # Enable large files on systems where this is not the default. +# Enable support for files on Linux file systems with 64-bit inode numbers. -# Copyright 1992-1996, 1998-2013 Free Software Foundation, Inc. +# Copyright 1992-1996, 1998-2022 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# The following implementation works around a problem in autoconf <= 2.69; +# The following macro works around a problem in Autoconf's AC_FUNC_FSEEKO: +# It does not set _LARGEFILE_SOURCE=1 on HP-UX/ia64 32-bit, although this +# setting of _LARGEFILE_SOURCE is needed so that declares fseeko +# and ftello in C++ mode as well. +# Fixed in Autoconf 2.72, which has AC_SYS_YEAR2038. +AC_DEFUN([gl_SET_LARGEFILE_SOURCE], +[ + m4_ifndef([AC_SYS_YEAR2038], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_FUNC_FSEEKO + case "$host_os" in + hpux*) + AC_DEFINE([_LARGEFILE_SOURCE], [1], + [Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2).]) + ;; + esac + ]) +]) + +# Work around a problem in Autoconf through 2.71 on glibc 2.34+ +# with _TIME_BITS. Also, work around a problem in autoconf <= 2.69: # AC_SYS_LARGEFILE does not configure for large inodes on Mac OS X 10.5, # or configures them incorrectly in some cases. -m4_version_prereq([2.70], [] ,[ +m4_version_prereq([2.70], [], [ # _AC_SYS_LARGEFILE_TEST_INCLUDES # ------------------------------- m4_define([_AC_SYS_LARGEFILE_TEST_INCLUDES], -[@%:@include +[#include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -@%:@define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) +#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]];[]dnl ]) +])# m4_version_prereq 2.70 +m4_ifndef([AC_SYS_YEAR2038], [ # _AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, # CACHE-VAR, @@ -37,7 +60,8 @@ m4_define([_AC_SYS_LARGEFILE_MACRO_VALUE], [AC_LANG_PROGRAM([$5], [$6])], [$3=no; break]) m4_ifval([$6], [AC_LINK_IFELSE], [AC_COMPILE_IFELSE])( - [AC_LANG_PROGRAM([@%:@define $1 $2 + [AC_LANG_PROGRAM([#undef $1 +#define $1 $2 $5], [$6])], [$3=$2; break]) $3=unknown @@ -56,13 +80,15 @@ rm -rf conftest*[]dnl # By default, many hosts won't let programs access large files; # one must use special compiler options to get large-file access to work. # For more details about this brain damage please see: -# http://www.unix-systems.org/version2/whatsnew/lfs20mar.html +# http://www.unix.org/version2/whatsnew/lfs20mar.html +# Additionally, on Linux file systems with 64-bit inodes a file that happens +# to have a 64-bit inode number cannot be accessed by 32-bit applications on +# Linux x86/x86_64. This can occur with file systems such as XFS and NFS. AC_DEFUN([AC_SYS_LARGEFILE], [AC_ARG_ENABLE(largefile, [ --disable-largefile omit support for large files]) -if test "$enable_largefile" != no; then - - AC_CACHE_CHECK([for special C compiler options needed for large files], +AS_IF([test "$enable_largefile" != no], + [AC_CACHE_CHECK([for special C compiler options needed for large files], ac_cv_sys_largefile_CC, [ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then @@ -87,18 +113,16 @@ if test "$enable_largefile" != no; then ac_cv_sys_file_offset_bits, [Number of bits in a file offset, on hosts where this is settable.], [_AC_SYS_LARGEFILE_TEST_INCLUDES]) - if test $ac_cv_sys_file_offset_bits = unknown; then - _AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1, - ac_cv_sys_large_files, - [Define for large files, on AIX-style hosts.], - [_AC_SYS_LARGEFILE_TEST_INCLUDES]) - fi - - AC_DEFINE([_DARWIN_USE_64_BIT_INODE], [1], - [Enable large inode numbers on Mac OS X 10.5.]) -fi + AS_CASE([$ac_cv_sys_file_offset_bits], + [unknown], + [_AC_SYS_LARGEFILE_MACRO_VALUE([_LARGE_FILES], [1], + [ac_cv_sys_large_files], + [Define for large files, on AIX-style hosts.], + [_AC_SYS_LARGEFILE_TEST_INCLUDES])], + [64], + [gl_YEAR2038_BODY([])])]) ])# AC_SYS_LARGEFILE -])# m4_version_prereq 2.70 +])# m4_ifndef AC_SYS_YEAR2038 # Enable large files on systems where this is implemented by Gnulib, not by the # system headers. @@ -126,9 +150,24 @@ AC_DEFUN([gl_LARGEFILE], else WINDOWS_64_BIT_OFF_T=0 fi - dnl But all native Windows platforms (including mingw64) have a 32-bit - dnl st_size member in 'struct stat'. - WINDOWS_64_BIT_ST_SIZE=1 + dnl Some mingw versions define, if _FILE_OFFSET_BITS=64, 'struct stat' + dnl to 'struct _stat32i64' or 'struct _stat64' (depending on + dnl _USE_32BIT_TIME_T), which has a 32-bit st_size member. + AC_CACHE_CHECK([for 64-bit st_size], [gl_cv_member_st_size_64], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + struct stat buf; + int verify_st_size_size[sizeof (buf.st_size) >= 8 ? 1 : -1]; + ]], + [[]])], + [gl_cv_member_st_size_64=yes], [gl_cv_member_st_size_64=no]) + ]) + if test $gl_cv_member_st_size_64 = no; then + WINDOWS_64_BIT_ST_SIZE=1 + else + WINDOWS_64_BIT_ST_SIZE=0 + fi ;; *) dnl Nothing to do on gnulib's side. diff --git a/gl/m4/lcmessage.m4 b/gl/m4/lcmessage.m4 deleted file mode 100644 index d62a175f..00000000 --- a/gl/m4/lcmessage.m4 +++ /dev/null @@ -1,35 +0,0 @@ -# lcmessage.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1995-2002, 2004-2005, 2008-2013 Free Software Foundation, -dnl 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995. - -# Check whether LC_MESSAGES is available in . - -AC_DEFUN([gt_LC_MESSAGES], -[ - AC_CACHE_CHECK([for LC_MESSAGES], [gt_cv_val_LC_MESSAGES], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[return LC_MESSAGES]])], - [gt_cv_val_LC_MESSAGES=yes], - [gt_cv_val_LC_MESSAGES=no])]) - if test $gt_cv_val_LC_MESSAGES = yes; then - AC_DEFINE([HAVE_LC_MESSAGES], [1], - [Define if your file defines LC_MESSAGES.]) - fi -]) diff --git a/gl/m4/lib-ld.m4 b/gl/m4/lib-ld.m4 index c145e478..934207a7 100644 --- a/gl/m4/lib-ld.m4 +++ b/gl/m4/lib-ld.m4 @@ -1,5 +1,5 @@ -# lib-ld.m4 serial 6 -dnl Copyright (C) 1996-2003, 2009-2013 Free Software Foundation, Inc. +# lib-ld.m4 serial 10 +dnl Copyright (C) 1996-2003, 2009-2022 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. @@ -47,73 +47,122 @@ if test "${PATH_SEPARATOR+set}" != set; then } fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. +if test -n "$LD"; then + AC_MSG_CHECKING([for ld]) +elif test "$GCC" = yes; then AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` - while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi -AC_CACHE_VAL([acl_cv_path_LD], -[if test -z "$LD"; then - acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$acl_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 &5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; esac fi - done - IFS="$acl_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 = 1.10 to complain if config.rpath is missing. - m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + dnl Complain if config.rpath is missing. + AC_REQUIRE_AUX_FILE([config.rpath]) AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host @@ -187,17 +187,17 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) - dnl Autoconf >= 2.61 supports dots in --with options. - pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" ]) - AC_ARG_WITH(P_A_C_K[-prefix], -[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib - --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], + AC_ARG_WITH(PACK[-prefix], +[[ --with-]]PACK[[-prefix[=DIR] search for ]]PACKLIBS[[ in DIR/include and DIR/lib + --without-]]PACK[[-prefix don't search for ]]PACKLIBS[[ in includedir and libdir]], [ if test "X$withval" = "Xno"; then use_additional=no @@ -206,17 +206,23 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" - if test "$acl_libdirstem2" != "$acl_libdirstem" \ - && ! test -d "$withval/$acl_libdirstem"; then - additional_libdir="$withval/$acl_libdirstem2" - fi + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" fi fi ]) + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= @@ -272,48 +278,54 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], shrext= fi if test $use_additional = yes; then - dir="$additional_libdir" - dnl The same code as in the loop below: - dnl First look for a shared library. - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then found_dir="$dir" - found_so="$dir/$f" - break + found_a="$dir/$libname.$acl_libext" fi - done + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi fi fi - fi - dnl Then look for a static library. - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi + done fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do @@ -323,7 +335,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], dir=`echo "X$x" | sed -e 's/^X-L//'` dnl First look for a shared library. if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else @@ -333,14 +345,14 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do - if test -f "$dir/$f"; then + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break @@ -351,7 +363,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], fi dnl Then look for a static library. if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi @@ -377,7 +389,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], dnl standard /usr/lib. if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ - || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + || test "X$found_dir" = "X/usr/$acl_libdirstem2" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else @@ -477,6 +490,13 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], fi additional_includedir="$basedir/include" ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. @@ -527,19 +547,21 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], for dep in $dependency_libs; do case "$dep" in -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $dependency_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ - && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then haveit= - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ - || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; @@ -550,29 +572,29 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then + if test "X$x" = "X-L$dependency_libdir"; then haveit=yes break fi done if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + if test -d "$dependency_libdir"; then + dnl Really add $dependency_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$dependency_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then + if test "X$x" = "X-L$dependency_libdir"; then haveit=yes break fi done if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + if test -d "$dependency_libdir"; then + dnl Really add $dependency_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$dependency_libdir" fi fi fi @@ -609,7 +631,20 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], ;; -l*) dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + dnl But on GNU systems, ignore -lc options, because + dnl - linking with libc is the default anyway, + dnl - linking with libc.a may produce an error + dnl "/usr/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie" + dnl or may produce an executable that always crashes, see + dnl . + dep=`echo "X$dep" | sed -e 's/^X-l//'` + if test "X$dep" != Xc \ + || case $host_os in + linux* | gnu* | k*bsd*-gnu) false ;; + *) true ;; + esac; then + names_next_round="$names_next_round $dep" + fi ;; *.la) dnl Handle this in the next round. Throw away the .la's @@ -670,7 +705,6 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY], LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi - popdef([P_A_C_K]) popdef([PACKLIBS]) popdef([PACKUP]) popdef([PACK]) @@ -721,7 +755,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], dir="$next" dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ - && test "X$dir" != "X/usr/$acl_libdirstem2"; then + && test "X$dir" != "X/usr/$acl_libdirstem2" \ + && test "X$dir" != "X/usr/$acl_libdirstem3"; then rpathdirs="$rpathdirs $dir" fi next= @@ -731,7 +766,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ - && test "X$dir" != "X/usr/$acl_libdirstem2"; then + && test "X$dir" != "X/usr/$acl_libdirstem2" \ + && test "X$dir" != "X/usr/$acl_libdirstem3"; then rpathdirs="$rpathdirs $dir" fi next= ;; diff --git a/gl/m4/lib-prefix.m4 b/gl/m4/lib-prefix.m4 index 60908e8f..999f712f 100644 --- a/gl/m4/lib-prefix.m4 +++ b/gl/m4/lib-prefix.m4 @@ -1,18 +1,11 @@ -# lib-prefix.m4 serial 7 (gettext-0.18) -dnl Copyright (C) 2001-2005, 2008-2013 Free Software Foundation, Inc. +# lib-prefix.m4 serial 20 +dnl Copyright (C) 2001-2005, 2008-2022 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 From Bruno Haible. -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed @@ -32,9 +25,9 @@ AC_DEFUN([AC_LIB_PREFIX], eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], + AC_ARG_WITH([lib-prefix], +[[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir]], [ if test "X$withval" = "Xno"; then use_additional=no @@ -154,71 +147,177 @@ AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], ]) dnl AC_LIB_PREPARE_MULTILIB creates -dnl - a variable acl_libdirstem, containing the basename of the libdir, either -dnl "lib" or "lib64" or "lib/64", -dnl - a variable acl_libdirstem2, as a secondary possible value for -dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or -dnl "lib/amd64". +dnl - a function acl_is_expected_elfclass, that tests whether standard input +dn; has a 32-bit or 64-bit ELF header, depending on the host CPU ABI, +dnl - 3 variables acl_libdirstem, acl_libdirstem2, acl_libdirstem3, containing +dnl the basename of the libdir to try in turn, either "lib" or "lib64" or +dnl "lib/64" or "lib32" or "lib/sparcv9" or "lib/amd64" or similar. AC_DEFUN([AC_LIB_PREPARE_MULTILIB], [ - dnl There is no formal standard regarding lib and lib64. - dnl On glibc systems, the current practice is that on a system supporting + dnl There is no formal standard regarding lib, lib32, and lib64. + dnl On most glibc systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under - dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine - dnl the compiler's default mode by looking at the compiler's library search - dnl path. If at least one of its elements ends in /lib64 or points to a - dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. - dnl Otherwise we use the default, namely "lib". + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. However, on + dnl Arch Linux based distributions, it's the opposite: 32-bit libraries go + dnl under $prefix/lib32 and 64-bit libraries go under $prefix/lib. + dnl We determine the compiler's default mode by looking at the compiler's + dnl library search path. If at least one of its elements ends in /lib64 or + dnl points to a directory whose absolute pathname ends in /lib64, we use that + dnl for 64-bit ABIs. Similarly for 32-bit ABIs. Otherwise we use the default, + dnl namely "lib". dnl On Solaris systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. AC_REQUIRE([AC_CANONICAL_HOST]) - acl_libdirstem=lib - acl_libdirstem2= - case "$host_os" in - solaris*) - dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment - dnl . - dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." - dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the - dnl symlink is missing, so we set acl_libdirstem2 too. - AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], - [AC_EGREP_CPP([sixtyfour bits], [ -#ifdef _LP64 -sixtyfour bits -#endif - ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) - ]) - if test $gl_cv_solaris_64bit = yes; then - acl_libdirstem=lib/64 - case "$host_cpu" in - sparc*) acl_libdirstem2=lib/sparcv9 ;; - i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; - esac - fi - ;; - *) - searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` - if test -n "$searchpath"; then - acl_save_IFS="${IFS= }"; IFS=":" - for searchdir in $searchpath; do - if test -d "$searchdir"; then - case "$searchdir" in - */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; - */../ | */.. ) - # Better ignore directories of this form. They are misleading. - ;; - *) searchdir=`cd "$searchdir" && pwd` - case "$searchdir" in - */lib64 ) acl_libdirstem=lib64 ;; - esac ;; - esac - fi - done - IFS="$acl_save_IFS" - fi - ;; - esac - test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT]) + + AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf], + [AC_EGREP_CPP([Extensible Linking Format], + [#if defined __ELF__ || (defined __linux__ && defined __EDG__) + Extensible Linking Format + #endif + ], + [gl_cv_elf=yes], + [gl_cv_elf=no]) + ]) + if test $gl_cv_elf = yes; then + # Extract the ELF class of a file (5th byte) in decimal. + # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + if od -A x < /dev/null >/dev/null 2>/dev/null; then + # Use POSIX od. + func_elfclass () + { + od -A n -t d1 -j 4 -N 1 + } + else + # Use BSD hexdump. + func_elfclass () + { + dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "' + echo + } + fi + # Use 'expr', not 'test', to compare the values of func_elfclass, because on + # Solaris 11 OpenIndiana and Solaris 11 OmniOS, the result is 001 or 002, + # not 1 or 2. +changequote(,)dnl + case $HOST_CPU_C_ABI_32BIT in + yes) + # 32-bit ABI. + acl_is_expected_elfclass () + { + expr "`func_elfclass | sed -e 's/[ ]//g'`" = 1 > /dev/null + } + ;; + no) + # 64-bit ABI. + acl_is_expected_elfclass () + { + expr "`func_elfclass | sed -e 's/[ ]//g'`" = 2 > /dev/null + } + ;; + *) + # Unknown. + acl_is_expected_elfclass () + { + : + } + ;; + esac +changequote([,])dnl + else + acl_is_expected_elfclass () + { + : + } + fi + + dnl Allow the user to override the result by setting acl_cv_libdirstems. + AC_CACHE_CHECK([for the common suffixes of directories in the library search path], + [acl_cv_libdirstems], + [dnl Try 'lib' first, because that's the default for libdir in GNU, see + dnl . + acl_libdirstem=lib + acl_libdirstem2= + acl_libdirstem3= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl . + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + if test $HOST_CPU_C_ABI_32BIT = no; then + acl_libdirstem2=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem3=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem3=lib/amd64 ;; + esac + fi + ;; + *) + dnl If $CC generates code for a 32-bit ABI, the libraries are + dnl surely under $prefix/lib or $prefix/lib32, not $prefix/lib64. + dnl Similarly, if $CC generates code for a 64-bit ABI, the libraries + dnl are surely under $prefix/lib or $prefix/lib64, not $prefix/lib32. + dnl Find the compiler's search path. However, non-system compilers + dnl sometimes have odd library search paths. But we can't simply invoke + dnl '/usr/bin/gcc -print-search-dirs' because that would not take into + dnl account the -m32/-m31 or -m64 options from the $CC or $CFLAGS. + searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test $HOST_CPU_C_ABI_32BIT != no; then + # 32-bit or unknown ABI. + if test -d /usr/lib32; then + acl_libdirstem2=lib32 + fi + fi + if test $HOST_CPU_C_ABI_32BIT != yes; then + # 64-bit or unknown ABI. + if test -d /usr/lib64; then + acl_libdirstem3=lib64 + fi + fi + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;; + */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib32 ) acl_libdirstem2=lib32 ;; + */lib64 ) acl_libdirstem3=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + if test $HOST_CPU_C_ABI_32BIT = yes; then + # 32-bit ABI. + acl_libdirstem3= + fi + if test $HOST_CPU_C_ABI_32BIT = no; then + # 64-bit ABI. + acl_libdirstem2= + fi + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3" + ]) + dnl Decompose acl_cv_libdirstems into acl_libdirstem, acl_libdirstem2, and + dnl acl_libdirstem3. +changequote(,)dnl + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'` + acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'` +changequote([,])dnl ]) diff --git a/gl/m4/limits-h.m4 b/gl/m4/limits-h.m4 new file mode 100644 index 00000000..5d5a5bf5 --- /dev/null +++ b/gl/m4/limits-h.m4 @@ -0,0 +1,41 @@ +dnl Check whether limits.h has needed features. + +dnl Copyright 2016-2022 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 From Paul Eggert. + +AC_DEFUN_ONCE([gl_LIMITS_H], +[ + gl_CHECK_NEXT_HEADERS([limits.h]) + + AC_CACHE_CHECK([whether limits.h has WORD_BIT, BOOL_WIDTH etc.], + [gl_cv_header_limits_width], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ + #define __STDC_WANT_IEC_60559_BFP_EXT__ 1 + #endif + #include + long long llm = LLONG_MAX; + int wb = WORD_BIT; + int ullw = ULLONG_WIDTH; + int bw = BOOL_WIDTH; + ]])], + [gl_cv_header_limits_width=yes], + [gl_cv_header_limits_width=no])]) + if test "$gl_cv_header_limits_width" = yes; then + GL_GENERATE_LIMITS_H=false + else + GL_GENERATE_LIMITS_H=true + fi +]) + +dnl Unconditionally enables the replacement of . +AC_DEFUN([gl_REPLACE_LIMITS_H], +[ + AC_REQUIRE([gl_LIMITS_H]) + GL_GENERATE_LIMITS_H=true +]) diff --git a/gl/m4/localcharset.m4 b/gl/m4/localcharset.m4 index 2e93e581..f5dbbd4f 100644 --- a/gl/m4/localcharset.m4 +++ b/gl/m4/localcharset.m4 @@ -1,5 +1,5 @@ -# localcharset.m4 serial 7 -dnl Copyright (C) 2002, 2004, 2006, 2009-2013 Free Software Foundation, Inc. +# localcharset.m4 serial 8 +dnl Copyright (C) 2002, 2004, 2006, 2009-2022 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. @@ -8,10 +8,4 @@ AC_DEFUN([gl_LOCALCHARSET], [ dnl Prerequisites of lib/localcharset.c. AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_REQUIRE([gl_FCNTL_O_FLAGS]) - AC_CHECK_DECLS_ONCE([getc_unlocked]) - - dnl Prerequisites of the lib/Makefile.am snippet. - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([gl_GLIBC21]) ]) diff --git a/gl/m4/locale-fr.m4 b/gl/m4/locale-fr.m4 index ef199e39..3753891f 100644 --- a/gl/m4/locale-fr.m4 +++ b/gl/m4/locale-fr.m4 @@ -1,5 +1,5 @@ -# locale-fr.m4 serial 17 -dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. +# locale-fr.m4 serial 20 +dnl Copyright (C) 2003, 2005-2022 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. @@ -12,8 +12,7 @@ AC_DEFUN([gt_LOCALE_FR], AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AM_LANGINFO_CODESET]) AC_CACHE_CHECK([for a traditional french locale], [gt_cv_locale_fr], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl + AC_LANG_CONFTEST([AC_LANG_SOURCE([[ #include #include #if HAVE_LANGINFO_CODESET @@ -24,8 +23,14 @@ changequote(,)dnl struct tm t; char buf[16]; int main () { + /* On BeOS and Haiku, locales are not implemented in libc. Rather, libintl + imitates locale dependent behaviour by looking at the environment + variables, and all locales use the UTF-8 encoding. */ +#if defined __BEOS__ || defined __HAIKU__ + return 1; +#else /* Check whether the given locale name is recognized by the system. */ -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +# if defined _WIN32 && !defined __CYGWIN__ /* On native Windows, setlocale(category, "") looks at the system settings, not at the environment variables. Also, when an encoding suffix such as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE @@ -33,9 +38,9 @@ int main () { if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) return 1; -#else +# else if (setlocale (LC_ALL, "") == NULL) return 1; -#endif +# endif /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) is empty, and the behaviour of Tcl 8.4 in this locale is not useful. @@ -44,35 +49,35 @@ int main () { some unit tests fail. On MirBSD 10, when an unsupported locale is specified, setlocale() succeeds but then nl_langinfo(CODESET) is "UTF-8". */ -#if HAVE_LANGINFO_CODESET +# if HAVE_LANGINFO_CODESET { const char *cs = nl_langinfo (CODESET); if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 || strcmp (cs, "UTF-8") == 0) return 1; } -#endif -#ifdef __CYGWIN__ +# endif +# ifdef __CYGWIN__ /* On Cygwin, avoid locale names without encoding suffix, because the locale_charset() function relies on the encoding suffix. Note that LC_ALL is set on the command line. */ if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -#endif +# endif /* Check whether in the abbreviation of the second month, the second character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is only one byte long. This excludes the UTF-8 encoding. */ t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1; -#if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ +# if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ /* Check whether the decimal separator is a comma. On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point are nl_langinfo(RADIXCHAR) are both ".". */ if (localeconv () ->decimal_point[0] != ',') return 1; -#endif +# endif return 0; +#endif } -changequote([,])dnl - ])]) + ]])]) if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then case "$host_os" in # Handle native Windows specially, because there setlocale() interprets @@ -136,8 +141,7 @@ AC_DEFUN([gt_LOCALE_FR_UTF8], [ AC_REQUIRE([AM_LANGINFO_CODESET]) AC_CACHE_CHECK([for a french Unicode locale], [gt_cv_locale_fr_utf8], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl + AC_LANG_CONFTEST([AC_LANG_SOURCE([[ #include #include #if HAVE_LANGINFO_CODESET @@ -153,7 +157,7 @@ int main () { variables, and all locales use the UTF-8 encoding. */ #if !(defined __BEOS__ || defined __HAIKU__) /* Check whether the given locale name is recognized by the system. */ -# if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +# if defined _WIN32 && !defined __CYGWIN__ /* On native Windows, setlocale(category, "") looks at the system settings, not at the environment variables. Also, when an encoding suffix such as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE @@ -199,8 +203,7 @@ int main () { #endif return 0; } -changequote([,])dnl - ])]) + ]])]) if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then case "$host_os" in # Handle native Windows specially, because there setlocale() interprets diff --git a/gl/m4/locale-ja.m4 b/gl/m4/locale-ja.m4 index 132a3e77..73a5d1ae 100644 --- a/gl/m4/locale-ja.m4 +++ b/gl/m4/locale-ja.m4 @@ -1,5 +1,5 @@ -# locale-ja.m4 serial 12 -dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. +# locale-ja.m4 serial 15 +dnl Copyright (C) 2003, 2005-2022 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. @@ -12,8 +12,7 @@ AC_DEFUN([gt_LOCALE_JA], AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AM_LANGINFO_CODESET]) AC_CACHE_CHECK([for a traditional japanese locale], [gt_cv_locale_ja], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl + AC_LANG_CONFTEST([AC_LANG_SOURCE([[ #include #include #if HAVE_LANGINFO_CODESET @@ -25,9 +24,14 @@ struct tm t; char buf[16]; int main () { - const char *p; + /* On BeOS and Haiku, locales are not implemented in libc. Rather, libintl + imitates locale dependent behaviour by looking at the environment + variables, and all locales use the UTF-8 encoding. */ +#if defined __BEOS__ || defined __HAIKU__ + return 1; +#else /* Check whether the given locale name is recognized by the system. */ -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +# if defined _WIN32 && !defined __CYGWIN__ /* On native Windows, setlocale(category, "") looks at the system settings, not at the environment variables. Also, when an encoding suffix such as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE @@ -35,9 +39,9 @@ int main () if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) return 1; -#else +# else if (setlocale (LC_ALL, "") == NULL) return 1; -#endif +# endif /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) is empty, and the behaviour of Tcl 8.4 in this locale is not useful. @@ -46,35 +50,38 @@ int main () some unit tests fail. On MirBSD 10, when an unsupported locale is specified, setlocale() succeeds but then nl_langinfo(CODESET) is "UTF-8". */ -#if HAVE_LANGINFO_CODESET +# if HAVE_LANGINFO_CODESET { const char *cs = nl_langinfo (CODESET); if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 || strcmp (cs, "UTF-8") == 0) return 1; } -#endif -#ifdef __CYGWIN__ +# endif +# ifdef __CYGWIN__ /* On Cygwin, avoid locale names without encoding suffix, because the locale_charset() function relies on the encoding suffix. Note that LC_ALL is set on the command line. */ if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -#endif +# endif /* Check whether MB_CUR_MAX is > 1. This excludes the dysfunctional locales on Cygwin 1.5.x. */ if (MB_CUR_MAX == 1) return 1; /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. This excludes the UTF-8 encoding (except on MirBSD). */ - t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; - if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; - for (p = buf; *p != '\0'; p++) - if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) - return 1; + { + const char *p; + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; + for (p = buf; *p != '\0'; p++) + if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) + return 1; + } return 0; +#endif } -changequote([,])dnl - ])]) + ]])]) if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then case "$host_os" in # Handle native Windows specially, because there setlocale() interprets diff --git a/gl/m4/locale-zh.m4 b/gl/m4/locale-zh.m4 index 4eed73f4..c997971f 100644 --- a/gl/m4/locale-zh.m4 +++ b/gl/m4/locale-zh.m4 @@ -1,5 +1,5 @@ -# locale-zh.m4 serial 12 -dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. +# locale-zh.m4 serial 15 +dnl Copyright (C) 2003, 2005-2022 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. @@ -12,8 +12,7 @@ AC_DEFUN([gt_LOCALE_ZH_CN], AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AM_LANGINFO_CODESET]) AC_CACHE_CHECK([for a transitional chinese locale], [gt_cv_locale_zh_CN], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl + AC_LANG_CONFTEST([AC_LANG_SOURCE([[ #include #include #include @@ -26,9 +25,14 @@ struct tm t; char buf[16]; int main () { - const char *p; + /* On BeOS and Haiku, locales are not implemented in libc. Rather, libintl + imitates locale dependent behaviour by looking at the environment + variables, and all locales use the UTF-8 encoding. */ +#if defined __BEOS__ || defined __HAIKU__ + return 1; +#else /* Check whether the given locale name is recognized by the system. */ -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +# if defined _WIN32 && !defined __CYGWIN__ /* On native Windows, setlocale(category, "") looks at the system settings, not at the environment variables. Also, when an encoding suffix such as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE @@ -36,9 +40,9 @@ int main () if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) return 1; -#else +# else if (setlocale (LC_ALL, "") == NULL) return 1; -#endif +# endif /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) is empty, and the behaviour of Tcl 8.4 in this locale is not useful. @@ -47,35 +51,38 @@ int main () some unit tests fail. On MirBSD 10, when an unsupported locale is specified, setlocale() succeeds but then nl_langinfo(CODESET) is "UTF-8". */ -#if HAVE_LANGINFO_CODESET +# if HAVE_LANGINFO_CODESET { const char *cs = nl_langinfo (CODESET); if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 || strcmp (cs, "UTF-8") == 0) return 1; } -#endif -#ifdef __CYGWIN__ +# endif +# ifdef __CYGWIN__ /* On Cygwin, avoid locale names without encoding suffix, because the locale_charset() function relies on the encoding suffix. Note that LC_ALL is set on the command line. */ if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -#endif +# endif /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. This excludes the UTF-8 encoding (except on MirBSD). */ - t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; - if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; - for (p = buf; *p != '\0'; p++) - if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) - return 1; + { + const char *p; + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; + for (p = buf; *p != '\0'; p++) + if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) + return 1; + } /* Check whether a typical GB18030 multibyte sequence is recognized as a single wide character. This excludes the GB2312 and GBK encodings. */ if (mblen ("\203\062\332\066", 5) != 4) return 1; return 0; +#endif } -changequote([,])dnl - ])]) + ]])]) if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then case "$host_os" in # Handle native Windows specially, because there setlocale() interprets diff --git a/gl/m4/locale_h.m4 b/gl/m4/locale_h.m4 index 8bd12e80..ca5d0d0f 100644 --- a/gl/m4/locale_h.m4 +++ b/gl/m4/locale_h.m4 @@ -1,13 +1,13 @@ -# locale_h.m4 serial 19 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. +# locale_h.m4 serial 28 +dnl Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_LOCALE_H], +AC_DEFUN_ONCE([gl_LOCALE_H], [ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. + dnl Ensure to expand the default settings once only, before all statements + dnl that occur in other macros. AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) dnl Persuade glibc to define locale_t and the int_p_*, int_n_* @@ -17,7 +17,9 @@ AC_DEFUN([gl_LOCALE_H], dnl If is replaced, then must also be replaced. AC_REQUIRE([gl_STDDEF_H]) - dnl Solaris 11 2011-11 defines the int_p_*, int_n_* members of 'struct lconv' + AC_REQUIRE([gl_LOCALE_T]) + + dnl Solaris 11.0 defines the int_p_*, int_n_* members of 'struct lconv' dnl only if _LCONV_C99 is defined. AC_REQUIRE([AC_CANONICAL_HOST]) case "$host_os" in @@ -37,34 +39,6 @@ AC_DEFUN([gl_LOCALE_H], [gl_cv_header_locale_h_posix2001=yes], [gl_cv_header_locale_h_posix2001=no])]) - dnl Check for . - AC_CHECK_HEADERS_ONCE([xlocale.h]) - if test $ac_cv_header_xlocale_h = yes; then - HAVE_XLOCALE_H=1 - dnl Check whether use of locale_t requires inclusion of , - dnl e.g. on Mac OS X 10.5. If does not define locale_t by - dnl itself, we assume that will do so. - AC_CACHE_CHECK([whether locale.h defines locale_t], - [gl_cv_header_locale_has_locale_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - locale_t x;]], - [[]])], - [gl_cv_header_locale_has_locale_t=yes], - [gl_cv_header_locale_has_locale_t=no]) - ]) - if test $gl_cv_header_locale_has_locale_t = yes; then - gl_cv_header_locale_h_needs_xlocale_h=no - else - gl_cv_header_locale_h_needs_xlocale_h=yes - fi - else - HAVE_XLOCALE_H=0 - gl_cv_header_locale_h_needs_xlocale_h=no - fi - AC_SUBST([HAVE_XLOCALE_H]) - dnl Check whether 'struct lconv' is complete. dnl Bionic libc's 'struct lconv' is just a dummy. dnl On OpenBSD 4.9, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 1.5.x, @@ -82,7 +56,20 @@ AC_DEFUN([gl_LOCALE_H], [gl_cv_sys_struct_lconv_ok=no]) ]) if test $gl_cv_sys_struct_lconv_ok = no; then - REPLACE_STRUCT_LCONV=1 + dnl On native Windows with MSVC, merely define these member names as macros. + dnl This avoids trouble in C++ mode. + case "$host_os" in + mingw*) + AC_EGREP_CPP([Special], [ +#ifdef _MSC_VER + Special +#endif + ], + [], + [REPLACE_STRUCT_LCONV=1]) + ;; + *) REPLACE_STRUCT_LCONV=1 ;; + esac fi dnl is always overridden, because of GNULIB_POSIXCHECK. @@ -96,27 +83,92 @@ AC_DEFUN([gl_LOCALE_H], # include #endif ]], - [setlocale duplocale]) + [setlocale newlocale duplocale freelocale]) +]) + +dnl Checks to determine whether the system has the locale_t type, +dnl and how to obtain it. +AC_DEFUN([gl_LOCALE_T], +[ + dnl Persuade glibc and Solaris to define locale_t. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + dnl Check whether use of locale_t requires inclusion of , + dnl e.g. on Mac OS X 10.5. If does not define locale_t by + dnl itself, we assume that will do so. + AC_CACHE_CHECK([whether locale.h defines locale_t], + [gl_cv_header_locale_has_locale_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + locale_t x;]], + [[]])], + [gl_cv_header_locale_has_locale_t=yes], + [gl_cv_header_locale_has_locale_t=no]) + ]) + + dnl Check for . + AC_CHECK_HEADERS_ONCE([xlocale.h]) + if test $ac_cv_header_xlocale_h = yes; then + HAVE_XLOCALE_H=1 + if test $gl_cv_header_locale_has_locale_t = yes; then + gl_cv_header_locale_h_needs_xlocale_h=no + else + gl_cv_header_locale_h_needs_xlocale_h=yes + fi + HAVE_LOCALE_T=1 + else + HAVE_XLOCALE_H=0 + gl_cv_header_locale_h_needs_xlocale_h=no + if test $gl_cv_header_locale_has_locale_t = yes; then + HAVE_LOCALE_T=1 + else + HAVE_LOCALE_T=0 + fi + fi + AC_SUBST([HAVE_XLOCALE_H]) ]) +# gl_LOCALE_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_LOCALE_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_LOCALE_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_LOCALE_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_LOCALE_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALECONV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE_NULL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUPLOCALE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALENAME]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_LOCALE_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) +]) + AC_DEFUN([gl_LOCALE_H_DEFAULTS], [ - GNULIB_LOCALECONV=0; AC_SUBST([GNULIB_LOCALECONV]) - GNULIB_SETLOCALE=0; AC_SUBST([GNULIB_SETLOCALE]) - GNULIB_DUPLOCALE=0; AC_SUBST([GNULIB_DUPLOCALE]) dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_NEWLOCALE=1; AC_SUBST([HAVE_NEWLOCALE]) HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE]) + HAVE_FREELOCALE=1; AC_SUBST([HAVE_FREELOCALE]) REPLACE_LOCALECONV=0; AC_SUBST([REPLACE_LOCALECONV]) REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE]) + REPLACE_NEWLOCALE=0; AC_SUBST([REPLACE_NEWLOCALE]) REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE]) + REPLACE_FREELOCALE=0; AC_SUBST([REPLACE_FREELOCALE]) REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV]) + LOCALENAME_ENHANCE_LOCALE_FUNCS=0; AC_SUBST([LOCALENAME_ENHANCE_LOCALE_FUNCS]) ]) diff --git a/gl/m4/localeconv.m4 b/gl/m4/localeconv.m4 index b8bb5964..09c1a1ac 100644 --- a/gl/m4/localeconv.m4 +++ b/gl/m4/localeconv.m4 @@ -1,5 +1,5 @@ # localeconv.m4 serial 1 -dnl Copyright (C) 2012-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2012-2022 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. diff --git a/gl/m4/lock.m4 b/gl/m4/lock.m4 index aae1701a..c4cbf07b 100644 --- a/gl/m4/lock.m4 +++ b/gl/m4/lock.m4 @@ -1,5 +1,5 @@ -# lock.m4 serial 13 (gettext-0.18.2) -dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. +# lock.m4 serial 14 +dnl Copyright (C) 2005-2022 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. @@ -12,11 +12,16 @@ AC_DEFUN([gl_LOCK], if test "$gl_threads_api" = posix; then # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the # pthread_rwlock_* functions. + has_rwlock=false AC_CHECK_TYPE([pthread_rwlock_t], - [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1], + [has_rwlock=true + AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1], [Define if the POSIX multithreading library has read/write locks.])], [], [#include ]) + if $has_rwlock; then + gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER + fi # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro. AC_COMPILE_IFELSE([ AC_LANG_PROGRAM( diff --git a/gl/m4/longlong.m4 b/gl/m4/longlong.m4 deleted file mode 100644 index 3af6ab5a..00000000 --- a/gl/m4/longlong.m4 +++ /dev/null @@ -1,113 +0,0 @@ -# longlong.m4 serial 17 -dnl Copyright (C) 1999-2007, 2009-2013 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 From Paul Eggert. - -# Define HAVE_LONG_LONG_INT if 'long long int' works. -# This fixes a bug in Autoconf 2.61, and can be faster -# than what's in Autoconf 2.62 through 2.68. - -# Note: If the type 'long long int' exists but is only 32 bits large -# (as on some very old compilers), HAVE_LONG_LONG_INT will not be -# defined. In this case you can treat 'long long int' like 'long int'. - -AC_DEFUN([AC_TYPE_LONG_LONG_INT], -[ - AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) - AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], - [ac_cv_type_long_long_int=yes - if test "x${ac_cv_prog_cc_c99-no}" = xno; then - ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int - if test $ac_cv_type_long_long_int = yes; then - dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. - dnl If cross compiling, assume the bug is not important, since - dnl nobody cross compiles for this platform as far as we know. - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[@%:@include - @%:@ifndef LLONG_MAX - @%:@ define HALF \ - (1LL << (sizeof (long long int) * CHAR_BIT - 2)) - @%:@ define LLONG_MAX (HALF - 1 + HALF) - @%:@endif]], - [[long long int n = 1; - int i; - for (i = 0; ; i++) - { - long long int m = n << i; - if (m >> i != n) - return 1; - if (LLONG_MAX / 2 < m) - break; - } - return 0;]])], - [], - [ac_cv_type_long_long_int=no], - [:]) - fi - fi]) - if test $ac_cv_type_long_long_int = yes; then - AC_DEFINE([HAVE_LONG_LONG_INT], [1], - [Define to 1 if the system has the type 'long long int'.]) - fi -]) - -# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. -# This fixes a bug in Autoconf 2.61, and can be faster -# than what's in Autoconf 2.62 through 2.68. - -# Note: If the type 'unsigned long long int' exists but is only 32 bits -# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT -# will not be defined. In this case you can treat 'unsigned long long int' -# like 'unsigned long int'. - -AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], -[ - AC_CACHE_CHECK([for unsigned long long int], - [ac_cv_type_unsigned_long_long_int], - [ac_cv_type_unsigned_long_long_int=yes - if test "x${ac_cv_prog_cc_c99-no}" = xno; then - AC_LINK_IFELSE( - [_AC_TYPE_LONG_LONG_SNIPPET], - [], - [ac_cv_type_unsigned_long_long_int=no]) - fi]) - if test $ac_cv_type_unsigned_long_long_int = yes; then - AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], - [Define to 1 if the system has the type 'unsigned long long int'.]) - fi -]) - -# Expands to a C program that can be used to test for simultaneous support -# of 'long long' and 'unsigned long long'. We don't want to say that -# 'long long' is available if 'unsigned long long' is not, or vice versa, -# because too many programs rely on the symmetry between signed and unsigned -# integer types (excluding 'bool'). -AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], -[ - AC_LANG_PROGRAM( - [[/* For now, do not test the preprocessor; as of 2007 there are too many - implementations with broken preprocessors. Perhaps this can - be revisited in 2012. In the meantime, code should not expect - #if to work with literals wider than 32 bits. */ - /* Test literals. */ - long long int ll = 9223372036854775807ll; - long long int nll = -9223372036854775807LL; - unsigned long long int ull = 18446744073709551615ULL; - /* Test constant expressions. */ - typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) - ? 1 : -1)]; - typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 - ? 1 : -1)]; - int i = 63;]], - [[/* Test availability of runtime routines for shift and division. */ - long long int llmax = 9223372036854775807ll; - unsigned long long int ullmax = 18446744073709551615ull; - return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) - | (llmax / ll) | (llmax % ll) - | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) - | (ullmax / ull) | (ullmax % ull));]]) -]) diff --git a/gl/m4/ls-mntd-fs.m4 b/gl/m4/ls-mntd-fs.m4 deleted file mode 100644 index fb116c8b..00000000 --- a/gl/m4/ls-mntd-fs.m4 +++ /dev/null @@ -1,357 +0,0 @@ -# serial 30 -# How to list mounted file systems. - -# Copyright (C) 1998-2004, 2006, 2009-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -dnl From Jim Meyering. -dnl -dnl This is not pretty. I've just taken the autoconf code and wrapped -dnl it in an AC_DEFUN and made some other fixes. -dnl - -# Replace Autoconf's AC_FUNC_GETMNTENT to work around a bug in Autoconf -# through Autoconf 2.59. We can remove this once we assume Autoconf 2.60 -# or later. -AC_DEFUN([AC_FUNC_GETMNTENT], -[# getmntent is in the standard C library on UNICOS, in -lsun on Irix 4, -# -lseq on Dynix/PTX, -lgen on Unixware. -AC_SEARCH_LIBS([getmntent], [sun seq gen]) -AC_CHECK_FUNCS([getmntent]) -]) - -# gl_LIST_MOUNTED_FILE_SYSTEMS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -AC_DEFUN([gl_LIST_MOUNTED_FILE_SYSTEMS], - [ -AC_CHECK_FUNCS([listmntent getmntinfo]) -AC_CHECK_HEADERS_ONCE([sys/param.h sys/statvfs.h]) - -# We must include grp.h before ucred.h on OSF V4.0, since ucred.h uses -# NGROUPS (as the array dimension for a struct member) without a definition. -AC_CHECK_HEADERS([sys/ucred.h], [], [], [#include ]) - -AC_CHECK_HEADERS([sys/mount.h], [], [], - [AC_INCLUDES_DEFAULT - [#if HAVE_SYS_PARAM_H - #include - #endif]]) - -AC_CHECK_HEADERS([mntent.h sys/fs_types.h]) - getfsstat_includes="\ -$ac_includes_default -#if HAVE_SYS_PARAM_H -# include /* needed by powerpc-apple-darwin1.3.7 */ -#endif -#if HAVE_SYS_UCRED_H -# include /* needed for definition of NGROUPS */ -# include /* needed by powerpc-apple-darwin1.3.7 */ -#endif -#if HAVE_SYS_MOUNT_H -# include -#endif -#if HAVE_SYS_FS_TYPES_H -# include /* needed by powerpc-apple-darwin1.3.7 */ -#endif -" -AC_CHECK_MEMBERS([struct fsstat.f_fstypename],,,[$getfsstat_includes]) - -# Determine how to get the list of mounted file systems. -ac_list_mounted_fs= - -# If the getmntent function is available but not in the standard library, -# make sure LIBS contains the appropriate -l option. -AC_FUNC_GETMNTENT - -# This test must precede the ones for getmntent because Unicos-9 is -# reported to have the getmntent function, but its support is incompatible -# with other getmntent implementations. - -# NOTE: Normally, I wouldn't use a check for system type as I've done for -# 'CRAY' below since that goes against the whole autoconf philosophy. But -# I think there is too great a chance that some non-Cray system has a -# function named listmntent to risk the false positive. - -if test -z "$ac_list_mounted_fs"; then - # Cray UNICOS 9 - AC_MSG_CHECKING([for listmntent of Cray/Unicos-9]) - AC_CACHE_VAL([fu_cv_sys_mounted_cray_listmntent], - [fu_cv_sys_mounted_cray_listmntent=no - AC_EGREP_CPP([yes], - [#ifdef _CRAY -yes -#endif - ], [test $ac_cv_func_listmntent = yes \ - && fu_cv_sys_mounted_cray_listmntent=yes] - ) - ] - ) - AC_MSG_RESULT([$fu_cv_sys_mounted_cray_listmntent]) - if test $fu_cv_sys_mounted_cray_listmntent = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_LISTMNTENT], [1], - [Define if there is a function named listmntent that can be used to - list all mounted file systems. (UNICOS)]) - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # AIX. - AC_MSG_CHECKING([for mntctl function and struct vmount]) - AC_CACHE_VAL([fu_cv_sys_mounted_vmount], - [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])], - [fu_cv_sys_mounted_vmount=yes], - [fu_cv_sys_mounted_vmount=no])]) - AC_MSG_RESULT([$fu_cv_sys_mounted_vmount]) - if test $fu_cv_sys_mounted_vmount = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_VMOUNT], [1], - [Define if there is a function named mntctl that can be used to read - the list of mounted file systems, and there is a system header file - that declares 'struct vmount'. (AIX)]) - fi -fi - -if test $ac_cv_func_getmntent = yes; then - - # This system has the getmntent function. - # Determine whether it's the one-argument variant or the two-argument one. - - if test -z "$ac_list_mounted_fs"; then - # 4.3BSD, SunOS, HP-UX, Dynix, Irix - AC_MSG_CHECKING([for one-argument getmntent function]) - AC_CACHE_VAL([fu_cv_sys_mounted_getmntent1], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -/* SunOS 4.1.x /usr/include/mntent.h needs this for FILE */ -#include - -#include -#if !defined MOUNTED -# if defined _PATH_MOUNTED /* GNU libc */ -# define MOUNTED _PATH_MOUNTED -# endif -# if defined MNT_MNTTAB /* HP-UX. */ -# define MOUNTED MNT_MNTTAB -# endif -# if defined MNTTABNAME /* Dynix. */ -# define MOUNTED MNTTABNAME -# endif -#endif -]], - [[ struct mntent *mnt = 0; char *table = MOUNTED; - if (sizeof mnt && sizeof table) return 0;]])], - [fu_cv_sys_mounted_getmntent1=yes], - [fu_cv_sys_mounted_getmntent1=no])]) - AC_MSG_RESULT([$fu_cv_sys_mounted_getmntent1]) - if test $fu_cv_sys_mounted_getmntent1 = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_GETMNTENT1], [1], - [Define if there is a function named getmntent for reading the list - of mounted file systems, and that function takes a single argument. - (4.3BSD, SunOS, HP-UX, Dynix, Irix)]) - fi - fi - - if test -z "$ac_list_mounted_fs"; then - # SVR4 - AC_MSG_CHECKING([for two-argument getmntent function]) - AC_CACHE_VAL([fu_cv_sys_mounted_getmntent2], - [AC_EGREP_HEADER([getmntent], [sys/mnttab.h], - fu_cv_sys_mounted_getmntent2=yes, - fu_cv_sys_mounted_getmntent2=no)]) - AC_MSG_RESULT([$fu_cv_sys_mounted_getmntent2]) - if test $fu_cv_sys_mounted_getmntent2 = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_GETMNTENT2], [1], - [Define if there is a function named getmntent for reading the list of - mounted file systems, and that function takes two arguments. (SVR4)]) - AC_CHECK_FUNCS([hasmntopt]) - fi - fi - -fi - -if test -z "$ac_list_mounted_fs"; then - # DEC Alpha running OSF/1, and Apple Darwin 1.3. - # powerpc-apple-darwin1.3.7 needs sys/param.h sys/ucred.h sys/fs_types.h - - AC_MSG_CHECKING([for getfsstat function]) - AC_CACHE_VAL([fu_cv_sys_mounted_getfsstat], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include -#if HAVE_STRUCT_FSSTAT_F_FSTYPENAME -# define FS_TYPE(Ent) ((Ent).f_fstypename) -#else -# define FS_TYPE(Ent) mnt_names[(Ent).f_type] -#endif -$getfsstat_includes]] -, - [[struct statfs *stats; - int numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT); - char *t = FS_TYPE (*stats); ]])], - [fu_cv_sys_mounted_getfsstat=yes], - [fu_cv_sys_mounted_getfsstat=no])]) - AC_MSG_RESULT([$fu_cv_sys_mounted_getfsstat]) - if test $fu_cv_sys_mounted_getfsstat = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_GETFSSTAT], [1], - [Define if there is a function named getfsstat for reading the - list of mounted file systems. (DEC Alpha running OSF/1)]) - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # SVR3 - AC_MSG_CHECKING([for FIXME existence of three headers]) - AC_CACHE_VAL([fu_cv_sys_mounted_fread_fstyp], - [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include ]])], - [fu_cv_sys_mounted_fread_fstyp=yes], - [fu_cv_sys_mounted_fread_fstyp=no])]) - AC_MSG_RESULT([$fu_cv_sys_mounted_fread_fstyp]) - if test $fu_cv_sys_mounted_fread_fstyp = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_FREAD_FSTYP], [1], - [Define if (like SVR2) there is no specific function for reading the - list of mounted file systems, and your system has these header files: - and . (SVR3)]) - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # 4.4BSD and DEC OSF/1. - AC_MSG_CHECKING([for getmntinfo function]) - AC_CACHE_VAL([fu_cv_sys_mounted_getmntinfo], - [ - test "$ac_cv_func_getmntinfo" = yes \ - && fu_cv_sys_mounted_getmntinfo=yes \ - || fu_cv_sys_mounted_getmntinfo=no - ]) - AC_MSG_RESULT([$fu_cv_sys_mounted_getmntinfo]) - if test $fu_cv_sys_mounted_getmntinfo = yes; then - AC_MSG_CHECKING([whether getmntinfo returns statvfs structures]) - AC_CACHE_VAL([fu_cv_sys_mounted_getmntinfo2], - [ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#if HAVE_SYS_PARAM_H -# include -#endif -#include -#if HAVE_SYS_MOUNT_H -# include -#endif -#if HAVE_SYS_STATVFS_H -# include -#endif -extern -#ifdef __cplusplus -"C" -#endif -int getmntinfo (struct statfs **, int); - ]], [])], - [fu_cv_sys_mounted_getmntinfo2=no], - [fu_cv_sys_mounted_getmntinfo2=yes]) - ]) - AC_MSG_RESULT([$fu_cv_sys_mounted_getmntinfo2]) - if test $fu_cv_sys_mounted_getmntinfo2 = no; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_GETMNTINFO], [1], - [Define if there is a function named getmntinfo for reading the - list of mounted file systems and it returns an array of - 'struct statfs'. (4.4BSD, Darwin)]) - else - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_GETMNTINFO2], [1], - [Define if there is a function named getmntinfo for reading the - list of mounted file systems and it returns an array of - 'struct statvfs'. (NetBSD 3.0)]) - fi - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # Ultrix - AC_MSG_CHECKING([for getmnt function]) - AC_CACHE_VAL([fu_cv_sys_mounted_getmnt], - [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ -#include -#include ]])], - [fu_cv_sys_mounted_getmnt=yes], - [fu_cv_sys_mounted_getmnt=no])]) - AC_MSG_RESULT([$fu_cv_sys_mounted_getmnt]) - if test $fu_cv_sys_mounted_getmnt = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_GETMNT], [1], - [Define if there is a function named getmnt for reading the list of - mounted file systems. (Ultrix)]) - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # BeOS - AC_CHECK_FUNCS([next_dev fs_stat_dev]) - AC_CHECK_HEADERS([fs_info.h]) - AC_MSG_CHECKING([for BEOS mounted file system support functions]) - if test $ac_cv_header_fs_info_h = yes \ - && test $ac_cv_func_next_dev = yes \ - && test $ac_cv_func_fs_stat_dev = yes; then - fu_result=yes - else - fu_result=no - fi - AC_MSG_RESULT([$fu_result]) - if test $fu_result = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_FS_STAT_DEV], [1], - [Define if there are functions named next_dev and fs_stat_dev for - reading the list of mounted file systems. (BeOS)]) - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # SVR2 - AC_MSG_CHECKING([whether it is possible to resort to fread on /etc/mnttab]) - AC_CACHE_VAL([fu_cv_sys_mounted_fread], - [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])], - [fu_cv_sys_mounted_fread=yes], - [fu_cv_sys_mounted_fread=no])]) - AC_MSG_RESULT([$fu_cv_sys_mounted_fread]) - if test $fu_cv_sys_mounted_fread = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_FREAD], [1], - [Define if there is no specific function for reading the list of - mounted file systems. fread will be used to read /etc/mnttab. - (SVR2) ]) - fi -fi - -if test -z "$ac_list_mounted_fs"; then - # Interix / BSD alike statvfs - # the code is really interix specific, so make sure, we're on it. - case "$host" in - *-interix*) - AC_CHECK_FUNCS([statvfs]) - if test $ac_cv_func_statvfs = yes; then - ac_list_mounted_fs=found - AC_DEFINE([MOUNTED_INTERIX_STATVFS], [1], - [Define if we are on interix, and ought to use statvfs plus - some special knowledge on where mounted file systems can be - found. (Interix)]) - fi - ;; - esac -fi - -if test -z "$ac_list_mounted_fs"; then - AC_MSG_ERROR([could not determine how to read list of mounted file systems]) - # FIXME -- no need to abort building the whole package - # Can't build mountlist.c or anything that needs its functions -fi - -AS_IF([test $ac_list_mounted_fs = found], [$1], [$2]) - - ]) diff --git a/gl/m4/lseek.m4 b/gl/m4/lseek.m4 new file mode 100644 index 00000000..0583511e --- /dev/null +++ b/gl/m4/lseek.m4 @@ -0,0 +1,78 @@ +# lseek.m4 serial 12 +dnl Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_LSEEK], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_PROG_CC]) + AC_CHECK_HEADERS_ONCE([unistd.h]) + AC_CACHE_CHECK([whether lseek detects pipes], [gl_cv_func_lseek_pipe], + [case "$host_os" in + mingw*) + dnl Native Windows. + dnl The result of lseek (fd, (off_t)0, SEEK_CUR) or + dnl SetFilePointer(handle, 0, NULL, FILE_CURRENT) + dnl for a pipe depends on the environment: In a Cygwin 1.5 + dnl environment it succeeds (wrong); in a Cygwin 1.7 environment + dnl it fails with a wrong errno value. + gl_cv_func_lseek_pipe=no + ;; + *) + if test $cross_compiling = no; then + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include /* for off_t */ +#include /* for SEEK_CUR */ +#if HAVE_UNISTD_H +# include +#else /* on Windows with MSVC */ +# include +#endif +]GL_MDA_DEFINES], +[[ + /* Exit with success only if stdin is seekable. */ + return lseek (0, (off_t)0, SEEK_CUR) < 0; +]])], + [if test -s conftest$ac_exeext \ + && ./conftest$ac_exeext < conftest.$ac_ext \ + && test 1 = "`echo hi \ + | { ./conftest$ac_exeext; echo $?; cat >/dev/null; }`"; then + gl_cv_func_lseek_pipe=yes + else + gl_cv_func_lseek_pipe=no + fi + ], + [gl_cv_func_lseek_pipe=no]) + else + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ +#if defined __BEOS__ +/* BeOS mistakenly return 0 when trying to seek on pipes. */ + Choke me. +#endif]])], + [gl_cv_func_lseek_pipe=yes], [gl_cv_func_lseek_pipe=no]) + fi + ;; + esac + ]) + if test "$gl_cv_func_lseek_pipe" = no; then + REPLACE_LSEEK=1 + AC_DEFINE([LSEEK_PIPE_BROKEN], [1], + [Define to 1 if lseek does not detect pipes.]) + fi + + AC_REQUIRE([gl_SYS_TYPES_H]) + if test $WINDOWS_64_BIT_OFF_T = 1; then + REPLACE_LSEEK=1 + fi + + dnl macOS SEEK_DATA is incompatible with other platforms. + case $host_os in + darwin*) + REPLACE_LSEEK=1;; + esac +]) diff --git a/gl/m4/malloc.m4 b/gl/m4/malloc.m4 index 4b24a0b1..6b76c1e6 100644 --- a/gl/m4/malloc.m4 +++ b/gl/m4/malloc.m4 @@ -1,98 +1,175 @@ -# malloc.m4 serial 14 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. +# malloc.m4 serial 28 +dnl Copyright (C) 2007, 2009-2022 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. -m4_version_prereq([2.70], [] ,[ - -# This is taken from the following Autoconf patch: -# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 +# This is adapted with modifications from upstream Autoconf here: +# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n949 AC_DEFUN([_AC_FUNC_MALLOC_IF], [ - AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles - AC_CHECK_HEADERS([stdlib.h]) - AC_CACHE_CHECK([for GNU libc compatible malloc], + AC_CACHE_CHECK([whether malloc (0) returns nonnull], [ac_cv_func_malloc_0_nonnull], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( - [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H - # include - #else - char *malloc (); - #endif + [[#include ]], - [[return ! malloc (0);]]) + [[void *p = malloc (0); + int result = !p; + free (p); + return result;]]) ], [ac_cv_func_malloc_0_nonnull=yes], [ac_cv_func_malloc_0_nonnull=no], [case "$host_os" in # Guess yes on platforms where we know the result. - *-gnu* | freebsd* | netbsd* | openbsd* \ - | hpux* | solaris* | cygwin* | mingw*) - ac_cv_func_malloc_0_nonnull=yes ;; - # If we don't know, assume the worst. - *) ac_cv_func_malloc_0_nonnull=no ;; + *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ + | gnu* | *-musl* | midnightbsd* \ + | hpux* | solaris* | cygwin* | mingw* | msys* ) + ac_cv_func_malloc_0_nonnull="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) ac_cv_func_malloc_0_nonnull="$gl_cross_guess_normal" ;; esac ]) ]) - AS_IF([test $ac_cv_func_malloc_0_nonnull = yes], [$1], [$2]) + AS_CASE([$ac_cv_func_malloc_0_nonnull], [*yes], [$1], [$2]) ])# _AC_FUNC_MALLOC_IF -]) - # gl_FUNC_MALLOC_GNU # ------------------ -# Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if -# it is not. +# Replace malloc if it is not compatible with GNU libc. AC_DEFUN([gl_FUNC_MALLOC_GNU], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - dnl _AC_FUNC_MALLOC_IF is defined in Autoconf. - _AC_FUNC_MALLOC_IF( - [AC_DEFINE([HAVE_MALLOC_GNU], [1], - [Define to 1 if your system has a GNU libc compatible 'malloc' - function, and to 0 otherwise.])], - [AC_DEFINE([HAVE_MALLOC_GNU], [0]) - REPLACE_MALLOC=1 + AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) + REPLACE_MALLOC_FOR_MALLOC_GNU="$REPLACE_MALLOC_FOR_MALLOC_POSIX" + if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 0; then + _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC_FOR_MALLOC_GNU=1]) + fi +]) + +# gl_FUNC_MALLOC_PTRDIFF +# ---------------------- +# Test whether malloc (N) reliably fails when N exceeds PTRDIFF_MAX, +# and replace malloc otherwise. +AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) + test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC_FOR_MALLOC_POSIX=1 +]) + +# Test whether malloc, realloc, calloc refuse to create objects +# larger than what can be expressed in ptrdiff_t. +# Set gl_cv_func_malloc_gnu to yes or no accordingly. +AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF], +[ + AC_CACHE_CHECK([whether malloc is ptrdiff_t safe], + [gl_cv_malloc_ptrdiff], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[/* 64-bit ptrdiff_t is so wide that no practical platform + can exceed it. */ + #define WIDE_PTRDIFF (PTRDIFF_MAX >> 31 >> 31 != 0) + + /* On rare machines where size_t fits in ptrdiff_t there + is no problem. */ + #define NARROW_SIZE (SIZE_MAX <= PTRDIFF_MAX) + + /* glibc 2.30 and later malloc refuses to exceed ptrdiff_t + bounds even on 32-bit platforms. We don't know which + non-glibc systems are safe. */ + #define KNOWN_SAFE (2 < __GLIBC__ + (30 <= __GLIBC_MINOR__)) + + #if WIDE_PTRDIFF || NARROW_SIZE || KNOWN_SAFE + return 0; + #else + #error "malloc might not be ptrdiff_t safe" + syntax error + #endif + ]])], + [gl_cv_malloc_ptrdiff=yes], + [gl_cv_malloc_ptrdiff=no]) ]) ]) # gl_FUNC_MALLOC_POSIX # -------------------- # Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it -# fails), and replace malloc if it is not. +# fails, and doesn't mess up with ptrdiff_t overflow), and replace +# malloc if it is not. AC_DEFUN([gl_FUNC_MALLOC_POSIX], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_MALLOC_PTRDIFF]) AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) - if test $gl_cv_func_malloc_posix = yes; then + if test "$gl_cv_func_malloc_posix" = yes; then AC_DEFINE([HAVE_MALLOC_POSIX], [1], - [Define if the 'malloc' function is POSIX compliant.]) + [Define if malloc, realloc, and calloc set errno on allocation failure.]) else - REPLACE_MALLOC=1 + REPLACE_MALLOC_FOR_MALLOC_POSIX=1 fi ]) -# Test whether malloc, realloc, calloc are POSIX compliant, +# Test whether malloc, realloc, calloc set errno to ENOMEM on failure. # Set gl_cv_func_malloc_posix to yes or no accordingly. AC_DEFUN([gl_CHECK_MALLOC_POSIX], [ - AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant], + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether malloc, realloc, calloc set errno on failure], [gl_cv_func_malloc_posix], [ dnl It is too dangerous to try to allocate a large amount of memory: dnl some systems go to their knees when you do that. So assume that - dnl all Unix implementations of the function are POSIX compliant. - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[]], - [[#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - choke me - #endif - ]])], - [gl_cv_func_malloc_posix=yes], - [gl_cv_func_malloc_posix=no]) + dnl all Unix implementations of the function set errno on failure, + dnl except on those platforms where we have seen 'test-malloc-gnu', + dnl 'test-realloc-gnu', 'test-calloc-gnu' fail. + case "$host_os" in + mingw*) + gl_cv_func_malloc_posix=no ;; + irix* | solaris*) + dnl On IRIX 6.5, the three functions return NULL with errno unset + dnl when the argument is larger than PTRDIFF_MAX. + dnl On Solaris 11.3, the three functions return NULL with errno set + dnl to EAGAIN, not ENOMEM, when the argument is larger than + dnl PTRDIFF_MAX. + dnl Here is a test program: +m4_divert_push([KILL]) +#include +#include +#include +#define ptrdiff_t long +#ifndef PTRDIFF_MAX +# define PTRDIFF_MAX ((ptrdiff_t) ((1UL << (8 * sizeof (ptrdiff_t) - 1)) - 1)) +#endif + +int main () +{ + void *p; + + fprintf (stderr, "PTRDIFF_MAX = %lu\n", (unsigned long) PTRDIFF_MAX); + + errno = 0; + p = malloc ((unsigned long) PTRDIFF_MAX + 1); + fprintf (stderr, "p=%p errno=%d\n", p, errno); + + errno = 0; + p = calloc (PTRDIFF_MAX / 2 + 1, 2); + fprintf (stderr, "p=%p errno=%d\n", p, errno); + + errno = 0; + p = realloc (NULL, (unsigned long) PTRDIFF_MAX + 1); + fprintf (stderr, "p=%p errno=%d\n", p, errno); + + return 0; +} +m4_divert_pop([KILL]) + gl_cv_func_malloc_posix=no ;; + *) + gl_cv_func_malloc_posix=yes ;; + esac ]) ]) diff --git a/gl/m4/malloca.m4 b/gl/m4/malloca.m4 index 791ce10d..77eb96a0 100644 --- a/gl/m4/malloca.m4 +++ b/gl/m4/malloca.m4 @@ -1,5 +1,5 @@ -# malloca.m4 serial 1 -dnl Copyright (C) 2003-2004, 2006-2007, 2009-2013 Free Software Foundation, +# malloca.m4 serial 2 +dnl Copyright (C) 2003-2004, 2006-2007, 2009-2022 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,5 +11,4 @@ AC_DEFUN([gl_MALLOCA], dnl @ALLOCA@ and @LTALLOCA@. dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies. AC_REQUIRE([gl_EEMALLOC]) - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) ]) diff --git a/gl/m4/math_h.m4 b/gl/m4/math_h.m4 index bf0845fd..a08526a7 100644 --- a/gl/m4/math_h.m4 +++ b/gl/m4/math_h.m4 @@ -1,16 +1,16 @@ -# math_h.m4 serial 114 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +# math_h.m4 serial 125 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_MATH_H], +AC_DEFUN_ONCE([gl_MATH_H], [ AC_REQUIRE([gl_MATH_H_DEFAULTS]) gl_CHECK_NEXT_HEADERS([math.h]) AC_CACHE_CHECK([whether NAN macro works], [gl_cv_header_math_nan_works], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[/* Solaris 10 has a broken definition of NAN. Other platforms fail to provide NAN, or provide it only in C99 mode; this test only needs to fail when NAN is provided but wrong. */ @@ -25,7 +25,7 @@ AC_DEFUN([gl_MATH_H], REPLACE_NAN=1 fi AC_CACHE_CHECK([whether HUGE_VAL works], [gl_cv_header_math_huge_val_works], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[/* Solaris 10 has a broken definition of HUGE_VAL. */ double d = HUGE_VAL; return d == 0;]])], @@ -53,272 +53,310 @@ AC_DEFUN([gl_MATH_H], tanf tanl tanhf trunc truncf truncl]) ]) +# gl_MATH_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_MATH_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_MATH_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_MATH_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_MATH_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACOSF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACOSL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ASINF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ASINL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATANL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATAN2F]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CBRT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CBRTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CBRTL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CEIL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CEILF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CEILL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COPYSIGN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COPYSIGNF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COPYSIGNL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COSF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COSL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COSHF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXP2]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXP2F]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXP2L]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPM1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPM1F]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPM1L]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FABSF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FABSL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FLOOR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FLOORF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FLOORL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FMA]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FMAF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FMAL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FMOD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FMODF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FMODL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXPF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXPL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ILOGB]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ILOGBF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ILOGBL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISFINITE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISINF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISNAN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISNANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISNAND]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISNANL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LDEXPF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LDEXPL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG10]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG10F]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG10L]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG1P]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG1PF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG1PL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG2]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG2F]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOG2L]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGB]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGBF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGBL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODFF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODFL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POWF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REMAINDER]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REMAINDERF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REMAINDERL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RINT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RINTL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ROUND]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ROUNDF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ROUNDL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGNBIT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINHF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SQRTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SQRTL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TANL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TANHF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCL]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_J0], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_J1], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_JN], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_Y0], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_Y1], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_YN], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_MATH_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_MATH_H_DEFAULTS]) +]) + AC_DEFUN([gl_MATH_H_DEFAULTS], [ - GNULIB_ACOSF=0; AC_SUBST([GNULIB_ACOSF]) - GNULIB_ACOSL=0; AC_SUBST([GNULIB_ACOSL]) - GNULIB_ASINF=0; AC_SUBST([GNULIB_ASINF]) - GNULIB_ASINL=0; AC_SUBST([GNULIB_ASINL]) - GNULIB_ATANF=0; AC_SUBST([GNULIB_ATANF]) - GNULIB_ATANL=0; AC_SUBST([GNULIB_ATANL]) - GNULIB_ATAN2F=0; AC_SUBST([GNULIB_ATAN2F]) - GNULIB_CBRT=0; AC_SUBST([GNULIB_CBRT]) - GNULIB_CBRTF=0; AC_SUBST([GNULIB_CBRTF]) - GNULIB_CBRTL=0; AC_SUBST([GNULIB_CBRTL]) - GNULIB_CEIL=0; AC_SUBST([GNULIB_CEIL]) - GNULIB_CEILF=0; AC_SUBST([GNULIB_CEILF]) - GNULIB_CEILL=0; AC_SUBST([GNULIB_CEILL]) - GNULIB_COPYSIGN=0; AC_SUBST([GNULIB_COPYSIGN]) - GNULIB_COPYSIGNF=0; AC_SUBST([GNULIB_COPYSIGNF]) - GNULIB_COPYSIGNL=0; AC_SUBST([GNULIB_COPYSIGNL]) - GNULIB_COSF=0; AC_SUBST([GNULIB_COSF]) - GNULIB_COSL=0; AC_SUBST([GNULIB_COSL]) - GNULIB_COSHF=0; AC_SUBST([GNULIB_COSHF]) - GNULIB_EXPF=0; AC_SUBST([GNULIB_EXPF]) - GNULIB_EXPL=0; AC_SUBST([GNULIB_EXPL]) - GNULIB_EXP2=0; AC_SUBST([GNULIB_EXP2]) - GNULIB_EXP2F=0; AC_SUBST([GNULIB_EXP2F]) - GNULIB_EXP2L=0; AC_SUBST([GNULIB_EXP2L]) - GNULIB_EXPM1=0; AC_SUBST([GNULIB_EXPM1]) - GNULIB_EXPM1F=0; AC_SUBST([GNULIB_EXPM1F]) - GNULIB_EXPM1L=0; AC_SUBST([GNULIB_EXPM1L]) - GNULIB_FABSF=0; AC_SUBST([GNULIB_FABSF]) - GNULIB_FABSL=0; AC_SUBST([GNULIB_FABSL]) - GNULIB_FLOOR=0; AC_SUBST([GNULIB_FLOOR]) - GNULIB_FLOORF=0; AC_SUBST([GNULIB_FLOORF]) - GNULIB_FLOORL=0; AC_SUBST([GNULIB_FLOORL]) - GNULIB_FMA=0; AC_SUBST([GNULIB_FMA]) - GNULIB_FMAF=0; AC_SUBST([GNULIB_FMAF]) - GNULIB_FMAL=0; AC_SUBST([GNULIB_FMAL]) - GNULIB_FMOD=0; AC_SUBST([GNULIB_FMOD]) - GNULIB_FMODF=0; AC_SUBST([GNULIB_FMODF]) - GNULIB_FMODL=0; AC_SUBST([GNULIB_FMODL]) - GNULIB_FREXPF=0; AC_SUBST([GNULIB_FREXPF]) - GNULIB_FREXP=0; AC_SUBST([GNULIB_FREXP]) - GNULIB_FREXPL=0; AC_SUBST([GNULIB_FREXPL]) - GNULIB_HYPOT=0; AC_SUBST([GNULIB_HYPOT]) - GNULIB_HYPOTF=0; AC_SUBST([GNULIB_HYPOTF]) - GNULIB_HYPOTL=0; AC_SUBST([GNULIB_HYPOTL]) - GNULIB_ILOGB=0; AC_SUBST([GNULIB_ILOGB]) - GNULIB_ILOGBF=0; AC_SUBST([GNULIB_ILOGBF]) - GNULIB_ILOGBL=0; AC_SUBST([GNULIB_ILOGBL]) - GNULIB_ISFINITE=0; AC_SUBST([GNULIB_ISFINITE]) - GNULIB_ISINF=0; AC_SUBST([GNULIB_ISINF]) - GNULIB_ISNAN=0; AC_SUBST([GNULIB_ISNAN]) - GNULIB_ISNANF=0; AC_SUBST([GNULIB_ISNANF]) - GNULIB_ISNAND=0; AC_SUBST([GNULIB_ISNAND]) - GNULIB_ISNANL=0; AC_SUBST([GNULIB_ISNANL]) - GNULIB_LDEXPF=0; AC_SUBST([GNULIB_LDEXPF]) - GNULIB_LDEXPL=0; AC_SUBST([GNULIB_LDEXPL]) - GNULIB_LOG=0; AC_SUBST([GNULIB_LOG]) - GNULIB_LOGF=0; AC_SUBST([GNULIB_LOGF]) - GNULIB_LOGL=0; AC_SUBST([GNULIB_LOGL]) - GNULIB_LOG10=0; AC_SUBST([GNULIB_LOG10]) - GNULIB_LOG10F=0; AC_SUBST([GNULIB_LOG10F]) - GNULIB_LOG10L=0; AC_SUBST([GNULIB_LOG10L]) - GNULIB_LOG1P=0; AC_SUBST([GNULIB_LOG1P]) - GNULIB_LOG1PF=0; AC_SUBST([GNULIB_LOG1PF]) - GNULIB_LOG1PL=0; AC_SUBST([GNULIB_LOG1PL]) - GNULIB_LOG2=0; AC_SUBST([GNULIB_LOG2]) - GNULIB_LOG2F=0; AC_SUBST([GNULIB_LOG2F]) - GNULIB_LOG2L=0; AC_SUBST([GNULIB_LOG2L]) - GNULIB_LOGB=0; AC_SUBST([GNULIB_LOGB]) - GNULIB_LOGBF=0; AC_SUBST([GNULIB_LOGBF]) - GNULIB_LOGBL=0; AC_SUBST([GNULIB_LOGBL]) - GNULIB_MODF=0; AC_SUBST([GNULIB_MODF]) - GNULIB_MODFF=0; AC_SUBST([GNULIB_MODFF]) - GNULIB_MODFL=0; AC_SUBST([GNULIB_MODFL]) - GNULIB_POWF=0; AC_SUBST([GNULIB_POWF]) - GNULIB_REMAINDER=0; AC_SUBST([GNULIB_REMAINDER]) - GNULIB_REMAINDERF=0; AC_SUBST([GNULIB_REMAINDERF]) - GNULIB_REMAINDERL=0; AC_SUBST([GNULIB_REMAINDERL]) - GNULIB_RINT=0; AC_SUBST([GNULIB_RINT]) - GNULIB_RINTF=0; AC_SUBST([GNULIB_RINTF]) - GNULIB_RINTL=0; AC_SUBST([GNULIB_RINTL]) - GNULIB_ROUND=0; AC_SUBST([GNULIB_ROUND]) - GNULIB_ROUNDF=0; AC_SUBST([GNULIB_ROUNDF]) - GNULIB_ROUNDL=0; AC_SUBST([GNULIB_ROUNDL]) - GNULIB_SIGNBIT=0; AC_SUBST([GNULIB_SIGNBIT]) - GNULIB_SINF=0; AC_SUBST([GNULIB_SINF]) - GNULIB_SINL=0; AC_SUBST([GNULIB_SINL]) - GNULIB_SINHF=0; AC_SUBST([GNULIB_SINHF]) - GNULIB_SQRTF=0; AC_SUBST([GNULIB_SQRTF]) - GNULIB_SQRTL=0; AC_SUBST([GNULIB_SQRTL]) - GNULIB_TANF=0; AC_SUBST([GNULIB_TANF]) - GNULIB_TANL=0; AC_SUBST([GNULIB_TANL]) - GNULIB_TANHF=0; AC_SUBST([GNULIB_TANHF]) - GNULIB_TRUNC=0; AC_SUBST([GNULIB_TRUNC]) - GNULIB_TRUNCF=0; AC_SUBST([GNULIB_TRUNCF]) - GNULIB_TRUNCL=0; AC_SUBST([GNULIB_TRUNCL]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_ACOSF=1; AC_SUBST([HAVE_ACOSF]) - HAVE_ACOSL=1; AC_SUBST([HAVE_ACOSL]) - HAVE_ASINF=1; AC_SUBST([HAVE_ASINF]) - HAVE_ASINL=1; AC_SUBST([HAVE_ASINL]) - HAVE_ATANF=1; AC_SUBST([HAVE_ATANF]) - HAVE_ATANL=1; AC_SUBST([HAVE_ATANL]) - HAVE_ATAN2F=1; AC_SUBST([HAVE_ATAN2F]) - HAVE_CBRT=1; AC_SUBST([HAVE_CBRT]) - HAVE_CBRTF=1; AC_SUBST([HAVE_CBRTF]) - HAVE_CBRTL=1; AC_SUBST([HAVE_CBRTL]) - HAVE_COPYSIGN=1; AC_SUBST([HAVE_COPYSIGN]) - HAVE_COPYSIGNL=1; AC_SUBST([HAVE_COPYSIGNL]) - HAVE_COSF=1; AC_SUBST([HAVE_COSF]) - HAVE_COSL=1; AC_SUBST([HAVE_COSL]) - HAVE_COSHF=1; AC_SUBST([HAVE_COSHF]) - HAVE_EXPF=1; AC_SUBST([HAVE_EXPF]) - HAVE_EXPL=1; AC_SUBST([HAVE_EXPL]) - HAVE_EXPM1=1; AC_SUBST([HAVE_EXPM1]) - HAVE_EXPM1F=1; AC_SUBST([HAVE_EXPM1F]) - HAVE_FABSF=1; AC_SUBST([HAVE_FABSF]) - HAVE_FABSL=1; AC_SUBST([HAVE_FABSL]) - HAVE_FMA=1; AC_SUBST([HAVE_FMA]) - HAVE_FMAF=1; AC_SUBST([HAVE_FMAF]) - HAVE_FMAL=1; AC_SUBST([HAVE_FMAL]) - HAVE_FMODF=1; AC_SUBST([HAVE_FMODF]) - HAVE_FMODL=1; AC_SUBST([HAVE_FMODL]) - HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF]) - HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF]) - HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL]) - HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB]) - HAVE_ILOGBF=1; AC_SUBST([HAVE_ILOGBF]) - HAVE_ILOGBL=1; AC_SUBST([HAVE_ILOGBL]) - HAVE_ISNANF=1; AC_SUBST([HAVE_ISNANF]) - HAVE_ISNAND=1; AC_SUBST([HAVE_ISNAND]) - HAVE_ISNANL=1; AC_SUBST([HAVE_ISNANL]) - HAVE_LDEXPF=1; AC_SUBST([HAVE_LDEXPF]) - HAVE_LOGF=1; AC_SUBST([HAVE_LOGF]) - HAVE_LOGL=1; AC_SUBST([HAVE_LOGL]) - HAVE_LOG10F=1; AC_SUBST([HAVE_LOG10F]) - HAVE_LOG10L=1; AC_SUBST([HAVE_LOG10L]) - HAVE_LOG1P=1; AC_SUBST([HAVE_LOG1P]) - HAVE_LOG1PF=1; AC_SUBST([HAVE_LOG1PF]) - HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) - HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) - HAVE_LOGBL=1; AC_SUBST([HAVE_LOGBL]) - HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) - HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) - HAVE_POWF=1; AC_SUBST([HAVE_POWF]) - HAVE_REMAINDER=1; AC_SUBST([HAVE_REMAINDER]) - HAVE_REMAINDERF=1; AC_SUBST([HAVE_REMAINDERF]) - HAVE_RINT=1; AC_SUBST([HAVE_RINT]) - HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) - HAVE_SINF=1; AC_SUBST([HAVE_SINF]) - HAVE_SINL=1; AC_SUBST([HAVE_SINL]) - HAVE_SINHF=1; AC_SUBST([HAVE_SINHF]) - HAVE_SQRTF=1; AC_SUBST([HAVE_SQRTF]) - HAVE_SQRTL=1; AC_SUBST([HAVE_SQRTL]) - HAVE_TANF=1; AC_SUBST([HAVE_TANF]) - HAVE_TANL=1; AC_SUBST([HAVE_TANL]) - HAVE_TANHF=1; AC_SUBST([HAVE_TANHF]) - HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) - HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) - HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) - HAVE_DECL_CBRTF=1; AC_SUBST([HAVE_DECL_CBRTF]) - HAVE_DECL_CBRTL=1; AC_SUBST([HAVE_DECL_CBRTL]) - HAVE_DECL_CEILF=1; AC_SUBST([HAVE_DECL_CEILF]) - HAVE_DECL_CEILL=1; AC_SUBST([HAVE_DECL_CEILL]) - HAVE_DECL_COPYSIGNF=1; AC_SUBST([HAVE_DECL_COPYSIGNF]) - HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) - HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) - HAVE_DECL_EXP2=1; AC_SUBST([HAVE_DECL_EXP2]) - HAVE_DECL_EXP2F=1; AC_SUBST([HAVE_DECL_EXP2F]) - HAVE_DECL_EXP2L=1; AC_SUBST([HAVE_DECL_EXP2L]) - HAVE_DECL_EXPM1L=1; AC_SUBST([HAVE_DECL_EXPM1L]) - HAVE_DECL_FLOORF=1; AC_SUBST([HAVE_DECL_FLOORF]) - HAVE_DECL_FLOORL=1; AC_SUBST([HAVE_DECL_FLOORL]) - HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL]) - HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) - HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) - HAVE_DECL_LOG10L=1; AC_SUBST([HAVE_DECL_LOG10L]) - HAVE_DECL_LOG2=1; AC_SUBST([HAVE_DECL_LOG2]) - HAVE_DECL_LOG2F=1; AC_SUBST([HAVE_DECL_LOG2F]) - HAVE_DECL_LOG2L=1; AC_SUBST([HAVE_DECL_LOG2L]) - HAVE_DECL_LOGB=1; AC_SUBST([HAVE_DECL_LOGB]) - HAVE_DECL_REMAINDER=1; AC_SUBST([HAVE_DECL_REMAINDER]) - HAVE_DECL_REMAINDERL=1; AC_SUBST([HAVE_DECL_REMAINDERL]) - HAVE_DECL_RINTF=1; AC_SUBST([HAVE_DECL_RINTF]) - HAVE_DECL_ROUND=1; AC_SUBST([HAVE_DECL_ROUND]) - HAVE_DECL_ROUNDF=1; AC_SUBST([HAVE_DECL_ROUNDF]) - HAVE_DECL_ROUNDL=1; AC_SUBST([HAVE_DECL_ROUNDL]) - HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) - HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) - HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) - HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) - HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) - HAVE_DECL_TRUNCL=1; AC_SUBST([HAVE_DECL_TRUNCL]) - REPLACE_CBRTF=0; AC_SUBST([REPLACE_CBRTF]) - REPLACE_CBRTL=0; AC_SUBST([REPLACE_CBRTL]) - REPLACE_CEIL=0; AC_SUBST([REPLACE_CEIL]) - REPLACE_CEILF=0; AC_SUBST([REPLACE_CEILF]) - REPLACE_CEILL=0; AC_SUBST([REPLACE_CEILL]) - REPLACE_EXPM1=0; AC_SUBST([REPLACE_EXPM1]) - REPLACE_EXPM1F=0; AC_SUBST([REPLACE_EXPM1F]) - REPLACE_EXP2=0; AC_SUBST([REPLACE_EXP2]) - REPLACE_EXP2L=0; AC_SUBST([REPLACE_EXP2L]) - REPLACE_FABSL=0; AC_SUBST([REPLACE_FABSL]) - REPLACE_FLOOR=0; AC_SUBST([REPLACE_FLOOR]) - REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) - REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) - REPLACE_FMA=0; AC_SUBST([REPLACE_FMA]) - REPLACE_FMAF=0; AC_SUBST([REPLACE_FMAF]) - REPLACE_FMAL=0; AC_SUBST([REPLACE_FMAL]) - REPLACE_FMOD=0; AC_SUBST([REPLACE_FMOD]) - REPLACE_FMODF=0; AC_SUBST([REPLACE_FMODF]) - REPLACE_FMODL=0; AC_SUBST([REPLACE_FMODL]) - REPLACE_FREXPF=0; AC_SUBST([REPLACE_FREXPF]) - REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) - REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) - REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL]) - REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT]) - REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF]) - REPLACE_HYPOTL=0; AC_SUBST([REPLACE_HYPOTL]) - REPLACE_ILOGB=0; AC_SUBST([REPLACE_ILOGB]) - REPLACE_ILOGBF=0; AC_SUBST([REPLACE_ILOGBF]) - REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) - REPLACE_ISINF=0; AC_SUBST([REPLACE_ISINF]) - REPLACE_ISNAN=0; AC_SUBST([REPLACE_ISNAN]) - REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) - REPLACE_LOG=0; AC_SUBST([REPLACE_LOG]) - REPLACE_LOGF=0; AC_SUBST([REPLACE_LOGF]) - REPLACE_LOGL=0; AC_SUBST([REPLACE_LOGL]) - REPLACE_LOG10=0; AC_SUBST([REPLACE_LOG10]) - REPLACE_LOG10F=0; AC_SUBST([REPLACE_LOG10F]) - REPLACE_LOG10L=0; AC_SUBST([REPLACE_LOG10L]) - REPLACE_LOG1P=0; AC_SUBST([REPLACE_LOG1P]) - REPLACE_LOG1PF=0; AC_SUBST([REPLACE_LOG1PF]) - REPLACE_LOG1PL=0; AC_SUBST([REPLACE_LOG1PL]) - REPLACE_LOG2=0; AC_SUBST([REPLACE_LOG2]) - REPLACE_LOG2F=0; AC_SUBST([REPLACE_LOG2F]) - REPLACE_LOG2L=0; AC_SUBST([REPLACE_LOG2L]) - REPLACE_LOGB=0; AC_SUBST([REPLACE_LOGB]) - REPLACE_LOGBF=0; AC_SUBST([REPLACE_LOGBF]) - REPLACE_LOGBL=0; AC_SUBST([REPLACE_LOGBL]) - REPLACE_MODF=0; AC_SUBST([REPLACE_MODF]) - REPLACE_MODFF=0; AC_SUBST([REPLACE_MODFF]) - REPLACE_MODFL=0; AC_SUBST([REPLACE_MODFL]) - REPLACE_NAN=0; AC_SUBST([REPLACE_NAN]) - REPLACE_REMAINDER=0; AC_SUBST([REPLACE_REMAINDER]) - REPLACE_REMAINDERF=0; AC_SUBST([REPLACE_REMAINDERF]) - REPLACE_REMAINDERL=0; AC_SUBST([REPLACE_REMAINDERL]) - REPLACE_ROUND=0; AC_SUBST([REPLACE_ROUND]) - REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF]) - REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL]) - REPLACE_SIGNBIT=0; AC_SUBST([REPLACE_SIGNBIT]) - REPLACE_SIGNBIT_USING_GCC=0; AC_SUBST([REPLACE_SIGNBIT_USING_GCC]) - REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) - REPLACE_TRUNC=0; AC_SUBST([REPLACE_TRUNC]) - REPLACE_TRUNCF=0; AC_SUBST([REPLACE_TRUNCF]) - REPLACE_TRUNCL=0; AC_SUBST([REPLACE_TRUNCL]) + HAVE_ACOSF=1; AC_SUBST([HAVE_ACOSF]) + HAVE_ACOSL=1; AC_SUBST([HAVE_ACOSL]) + HAVE_ASINF=1; AC_SUBST([HAVE_ASINF]) + HAVE_ASINL=1; AC_SUBST([HAVE_ASINL]) + HAVE_ATANF=1; AC_SUBST([HAVE_ATANF]) + HAVE_ATANL=1; AC_SUBST([HAVE_ATANL]) + HAVE_ATAN2F=1; AC_SUBST([HAVE_ATAN2F]) + HAVE_CBRT=1; AC_SUBST([HAVE_CBRT]) + HAVE_CBRTF=1; AC_SUBST([HAVE_CBRTF]) + HAVE_CBRTL=1; AC_SUBST([HAVE_CBRTL]) + HAVE_COPYSIGN=1; AC_SUBST([HAVE_COPYSIGN]) + HAVE_COPYSIGNL=1; AC_SUBST([HAVE_COPYSIGNL]) + HAVE_COSF=1; AC_SUBST([HAVE_COSF]) + HAVE_COSL=1; AC_SUBST([HAVE_COSL]) + HAVE_COSHF=1; AC_SUBST([HAVE_COSHF]) + HAVE_EXPF=1; AC_SUBST([HAVE_EXPF]) + HAVE_EXPL=1; AC_SUBST([HAVE_EXPL]) + HAVE_EXPM1=1; AC_SUBST([HAVE_EXPM1]) + HAVE_EXPM1F=1; AC_SUBST([HAVE_EXPM1F]) + HAVE_FABSF=1; AC_SUBST([HAVE_FABSF]) + HAVE_FABSL=1; AC_SUBST([HAVE_FABSL]) + HAVE_FMA=1; AC_SUBST([HAVE_FMA]) + HAVE_FMAF=1; AC_SUBST([HAVE_FMAF]) + HAVE_FMAL=1; AC_SUBST([HAVE_FMAL]) + HAVE_FMODF=1; AC_SUBST([HAVE_FMODF]) + HAVE_FMODL=1; AC_SUBST([HAVE_FMODL]) + HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF]) + HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF]) + HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL]) + HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB]) + HAVE_ILOGBF=1; AC_SUBST([HAVE_ILOGBF]) + HAVE_ILOGBL=1; AC_SUBST([HAVE_ILOGBL]) + HAVE_ISNANF=1; AC_SUBST([HAVE_ISNANF]) + HAVE_ISNAND=1; AC_SUBST([HAVE_ISNAND]) + HAVE_ISNANL=1; AC_SUBST([HAVE_ISNANL]) + HAVE_LDEXPF=1; AC_SUBST([HAVE_LDEXPF]) + HAVE_LOGF=1; AC_SUBST([HAVE_LOGF]) + HAVE_LOGL=1; AC_SUBST([HAVE_LOGL]) + HAVE_LOG10F=1; AC_SUBST([HAVE_LOG10F]) + HAVE_LOG10L=1; AC_SUBST([HAVE_LOG10L]) + HAVE_LOG1P=1; AC_SUBST([HAVE_LOG1P]) + HAVE_LOG1PF=1; AC_SUBST([HAVE_LOG1PF]) + HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) + HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) + HAVE_LOGBL=1; AC_SUBST([HAVE_LOGBL]) + HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) + HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) + HAVE_POWF=1; AC_SUBST([HAVE_POWF]) + HAVE_REMAINDER=1; AC_SUBST([HAVE_REMAINDER]) + HAVE_REMAINDERF=1; AC_SUBST([HAVE_REMAINDERF]) + HAVE_RINT=1; AC_SUBST([HAVE_RINT]) + HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) + HAVE_SINF=1; AC_SUBST([HAVE_SINF]) + HAVE_SINL=1; AC_SUBST([HAVE_SINL]) + HAVE_SINHF=1; AC_SUBST([HAVE_SINHF]) + HAVE_SQRTF=1; AC_SUBST([HAVE_SQRTF]) + HAVE_SQRTL=1; AC_SUBST([HAVE_SQRTL]) + HAVE_TANF=1; AC_SUBST([HAVE_TANF]) + HAVE_TANL=1; AC_SUBST([HAVE_TANL]) + HAVE_TANHF=1; AC_SUBST([HAVE_TANHF]) + HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) + HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) + HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) + HAVE_DECL_CBRTF=1; AC_SUBST([HAVE_DECL_CBRTF]) + HAVE_DECL_CBRTL=1; AC_SUBST([HAVE_DECL_CBRTL]) + HAVE_DECL_CEILF=1; AC_SUBST([HAVE_DECL_CEILF]) + HAVE_DECL_CEILL=1; AC_SUBST([HAVE_DECL_CEILL]) + HAVE_DECL_COPYSIGNF=1; AC_SUBST([HAVE_DECL_COPYSIGNF]) + HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) + HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) + HAVE_DECL_EXP2=1; AC_SUBST([HAVE_DECL_EXP2]) + HAVE_DECL_EXP2F=1; AC_SUBST([HAVE_DECL_EXP2F]) + HAVE_DECL_EXP2L=1; AC_SUBST([HAVE_DECL_EXP2L]) + HAVE_DECL_EXPM1L=1; AC_SUBST([HAVE_DECL_EXPM1L]) + HAVE_DECL_FLOORF=1; AC_SUBST([HAVE_DECL_FLOORF]) + HAVE_DECL_FLOORL=1; AC_SUBST([HAVE_DECL_FLOORL]) + HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL]) + HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) + HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) + HAVE_DECL_LOG10L=1; AC_SUBST([HAVE_DECL_LOG10L]) + HAVE_DECL_LOG2=1; AC_SUBST([HAVE_DECL_LOG2]) + HAVE_DECL_LOG2F=1; AC_SUBST([HAVE_DECL_LOG2F]) + HAVE_DECL_LOG2L=1; AC_SUBST([HAVE_DECL_LOG2L]) + HAVE_DECL_LOGB=1; AC_SUBST([HAVE_DECL_LOGB]) + HAVE_DECL_REMAINDER=1; AC_SUBST([HAVE_DECL_REMAINDER]) + HAVE_DECL_REMAINDERL=1; AC_SUBST([HAVE_DECL_REMAINDERL]) + HAVE_DECL_RINTF=1; AC_SUBST([HAVE_DECL_RINTF]) + HAVE_DECL_ROUND=1; AC_SUBST([HAVE_DECL_ROUND]) + HAVE_DECL_ROUNDF=1; AC_SUBST([HAVE_DECL_ROUNDF]) + HAVE_DECL_ROUNDL=1; AC_SUBST([HAVE_DECL_ROUNDL]) + HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) + HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) + HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) + HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) + HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) + HAVE_DECL_TRUNCL=1; AC_SUBST([HAVE_DECL_TRUNCL]) + REPLACE_ACOSF=0; AC_SUBST([REPLACE_ACOSF]) + REPLACE_ASINF=0; AC_SUBST([REPLACE_ASINF]) + REPLACE_ATANF=0; AC_SUBST([REPLACE_ATANF]) + REPLACE_ATAN2F=0; AC_SUBST([REPLACE_ATAN2F]) + REPLACE_CBRTF=0; AC_SUBST([REPLACE_CBRTF]) + REPLACE_CBRTL=0; AC_SUBST([REPLACE_CBRTL]) + REPLACE_CEIL=0; AC_SUBST([REPLACE_CEIL]) + REPLACE_CEILF=0; AC_SUBST([REPLACE_CEILF]) + REPLACE_CEILL=0; AC_SUBST([REPLACE_CEILL]) + REPLACE_COSF=0; AC_SUBST([REPLACE_COSF]) + REPLACE_COSHF=0; AC_SUBST([REPLACE_COSHF]) + REPLACE_EXPF=0; AC_SUBST([REPLACE_EXPF]) + REPLACE_EXPL=0; AC_SUBST([REPLACE_EXPL]) + REPLACE_EXPM1=0; AC_SUBST([REPLACE_EXPM1]) + REPLACE_EXPM1F=0; AC_SUBST([REPLACE_EXPM1F]) + REPLACE_EXPM1L=0; AC_SUBST([REPLACE_EXPM1L]) + REPLACE_EXP2=0; AC_SUBST([REPLACE_EXP2]) + REPLACE_EXP2L=0; AC_SUBST([REPLACE_EXP2L]) + REPLACE_FABSL=0; AC_SUBST([REPLACE_FABSL]) + REPLACE_FLOOR=0; AC_SUBST([REPLACE_FLOOR]) + REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) + REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) + REPLACE_FMA=0; AC_SUBST([REPLACE_FMA]) + REPLACE_FMAF=0; AC_SUBST([REPLACE_FMAF]) + REPLACE_FMAL=0; AC_SUBST([REPLACE_FMAL]) + REPLACE_FMOD=0; AC_SUBST([REPLACE_FMOD]) + REPLACE_FMODF=0; AC_SUBST([REPLACE_FMODF]) + REPLACE_FMODL=0; AC_SUBST([REPLACE_FMODL]) + REPLACE_FREXPF=0; AC_SUBST([REPLACE_FREXPF]) + REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) + REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) + REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL]) + REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT]) + REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF]) + REPLACE_HYPOTL=0; AC_SUBST([REPLACE_HYPOTL]) + REPLACE_ILOGB=0; AC_SUBST([REPLACE_ILOGB]) + REPLACE_ILOGBF=0; AC_SUBST([REPLACE_ILOGBF]) + REPLACE_ILOGBL=0; AC_SUBST([REPLACE_ILOGBL]) + REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) + REPLACE_ISINF=0; AC_SUBST([REPLACE_ISINF]) + REPLACE_ISNAN=0; AC_SUBST([REPLACE_ISNAN]) + REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) + REPLACE_LOG=0; AC_SUBST([REPLACE_LOG]) + REPLACE_LOGF=0; AC_SUBST([REPLACE_LOGF]) + REPLACE_LOGL=0; AC_SUBST([REPLACE_LOGL]) + REPLACE_LOG10=0; AC_SUBST([REPLACE_LOG10]) + REPLACE_LOG10F=0; AC_SUBST([REPLACE_LOG10F]) + REPLACE_LOG10L=0; AC_SUBST([REPLACE_LOG10L]) + REPLACE_LOG1P=0; AC_SUBST([REPLACE_LOG1P]) + REPLACE_LOG1PF=0; AC_SUBST([REPLACE_LOG1PF]) + REPLACE_LOG1PL=0; AC_SUBST([REPLACE_LOG1PL]) + REPLACE_LOG2=0; AC_SUBST([REPLACE_LOG2]) + REPLACE_LOG2F=0; AC_SUBST([REPLACE_LOG2F]) + REPLACE_LOG2L=0; AC_SUBST([REPLACE_LOG2L]) + REPLACE_LOGB=0; AC_SUBST([REPLACE_LOGB]) + REPLACE_LOGBF=0; AC_SUBST([REPLACE_LOGBF]) + REPLACE_LOGBL=0; AC_SUBST([REPLACE_LOGBL]) + REPLACE_MODF=0; AC_SUBST([REPLACE_MODF]) + REPLACE_MODFF=0; AC_SUBST([REPLACE_MODFF]) + REPLACE_MODFL=0; AC_SUBST([REPLACE_MODFL]) + REPLACE_NAN=0; AC_SUBST([REPLACE_NAN]) + REPLACE_REMAINDER=0; AC_SUBST([REPLACE_REMAINDER]) + REPLACE_REMAINDERF=0; AC_SUBST([REPLACE_REMAINDERF]) + REPLACE_REMAINDERL=0; AC_SUBST([REPLACE_REMAINDERL]) + REPLACE_RINTL=0; AC_SUBST([REPLACE_RINTL]) + REPLACE_ROUND=0; AC_SUBST([REPLACE_ROUND]) + REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF]) + REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL]) + REPLACE_SIGNBIT=0; AC_SUBST([REPLACE_SIGNBIT]) + REPLACE_SIGNBIT_USING_BUILTINS=0; AC_SUBST([REPLACE_SIGNBIT_USING_BUILTINS]) + REPLACE_SINF=0; AC_SUBST([REPLACE_SINF]) + REPLACE_SINHF=0; AC_SUBST([REPLACE_SINHF]) + REPLACE_SQRTF=0; AC_SUBST([REPLACE_SQRTF]) + REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) + REPLACE_TANF=0; AC_SUBST([REPLACE_TANF]) + REPLACE_TANHF=0; AC_SUBST([REPLACE_TANHF]) + REPLACE_TRUNC=0; AC_SUBST([REPLACE_TRUNC]) + REPLACE_TRUNCF=0; AC_SUBST([REPLACE_TRUNCF]) + REPLACE_TRUNCL=0; AC_SUBST([REPLACE_TRUNCL]) ]) # gl_LONG_DOUBLE_VS_DOUBLE diff --git a/gl/m4/mbrtowc.m4 b/gl/m4/mbrtowc.m4 index 4c9f3886..ec8716b5 100644 --- a/gl/m4/mbrtowc.m4 +++ b/gl/m4/mbrtowc.m4 @@ -1,5 +1,5 @@ -# mbrtowc.m4 serial 25 -dnl Copyright (C) 2001-2002, 2004-2005, 2008-2013 Free Software Foundation, +# mbrtowc.m4 serial 38 -*- coding: utf-8 -*- +dnl Copyright (C) 2001-2002, 2004-2005, 2008-2022 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,8 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_MBRTOWC], [ AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + AC_REQUIRE([gl_PTHREADLIB]) + AC_CHECK_HEADERS_ONCE([threads.h]) AC_REQUIRE([AC_TYPE_MBSTATE_T]) gl_MBSTATE_T_BROKEN @@ -16,15 +18,8 @@ AC_DEFUN([gl_FUNC_MBRTOWC], if test $ac_cv_func_mbrtowc = no; then HAVE_MBRTOWC=0 AC_CHECK_DECLS([mbrtowc],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) + #include + ]]) if test $ac_cv_have_decl_mbrtowc = yes; then dnl On Minix 3.1.8, the system's declares mbrtowc() although dnl it does not have the function. Avoid a collision with gnulib's @@ -39,6 +34,9 @@ AC_DEFUN([gl_FUNC_MBRTOWC], gl_MBRTOWC_NULL_ARG2 gl_MBRTOWC_RETVAL gl_MBRTOWC_NUL_RETVAL + gl_MBRTOWC_STORES_INCOMPLETE + gl_MBRTOWC_EMPTY_INPUT + gl_MBRTOWC_C_LOCALE case "$gl_cv_func_mbrtowc_null_arg1" in *yes) ;; *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1], @@ -67,8 +65,47 @@ AC_DEFUN([gl_FUNC_MBRTOWC], REPLACE_MBRTOWC=1 ;; esac + case "$gl_cv_func_mbrtowc_stores_incomplete" in + *no) ;; + *) AC_DEFINE([MBRTOWC_STORES_INCOMPLETE_BUG], [1], + [Define if the mbrtowc function stores a wide character when reporting incomplete input.]) + REPLACE_MBRTOWC=1 + ;; + esac + case "$gl_cv_func_mbrtowc_empty_input" in + *yes) ;; + *) AC_DEFINE([MBRTOWC_EMPTY_INPUT_BUG], [1], + [Define if the mbrtowc function does not return (size_t) -2 + for empty input.]) + REPLACE_MBRTOWC=1 + ;; + esac + case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in + *yes) ;; + *) AC_DEFINE([MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ], [1], + [Define if the mbrtowc function may signal encoding errors in the C locale.]) + REPLACE_MBRTOWC=1 + ;; + esac fi fi + if test $REPLACE_MBSTATE_T = 1; then + case "$host_os" in + mingw*) LIB_MBRTOWC= ;; + *) + gl_WEAK_SYMBOLS + case "$gl_cv_have_weak" in + *yes) LIB_MBRTOWC= ;; + *) LIB_MBRTOWC="$LIBPTHREAD" ;; + esac + ;; + esac + else + LIB_MBRTOWC= + fi + dnl LIB_MBRTOWC is expected to be '-pthread' or '-lpthread' on AIX + dnl with gcc or xlc, and empty otherwise. + AC_SUBST([LIB_MBRTOWC]) ]) dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that @@ -80,11 +117,19 @@ dnl avoid inconsistencies. AC_DEFUN([gl_MBSTATE_T_BROKEN], [ AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_TYPE_MBSTATE_T]) AC_CHECK_FUNCS_ONCE([mbsinit]) AC_CHECK_FUNCS_ONCE([mbrtowc]) - if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then + dnl On native Windows, we know exactly how mbsinit() behaves and don't need + dnl to override it, even if - like on MSVC - mbsinit() is only defined as + dnl an inline function, not as a global function. + if case "$host_os" in + mingw*) true ;; + *) test $ac_cv_func_mbsinit = yes ;; + esac \ + && test $ac_cv_func_mbrtowc = yes; then gl_MBRTOWC_INCOMPLETE_STATE gl_MBRTOWC_SANITYCHECK REPLACE_MBSTATE_T=0 @@ -109,6 +154,7 @@ AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], [ AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], [gl_cv_func_mbrtowc_incomplete_state], @@ -128,13 +174,6 @@ changequote([,])dnl [AC_LANG_SOURCE([[ #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -147,13 +186,39 @@ int main () memset (&state, '\0', sizeof (mbstate_t)); if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) if (mbsinit (&state)) - return 1; + return 2; + } + return 0; +}]])], + [gl_cv_func_mbrtowc_incomplete_state=yes], + [gl_cv_func_mbrtowc_incomplete_state=no], + [:]) + else + if test $LOCALE_FR_UTF8 != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + const char input[] = "B\303\274\303\237er"; /* "Büßer" */ + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) + if (mbsinit (&state)) + return 2; } return 0; }]])], [gl_cv_func_mbrtowc_incomplete_state=yes], [gl_cv_func_mbrtowc_incomplete_state=no], [:]) + fi fi ]) ]) @@ -185,13 +250,6 @@ changequote([,])dnl #include #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -207,7 +265,7 @@ int main () memset (&state, '\0', sizeof (mbstate_t)); if (mbrtowc (&wc, input + 3, 6, &state) != 4 && mbtowc (&wc, input + 3, 6) == 4) - return 1; + return 2; } return 0; }]])], @@ -245,13 +303,6 @@ changequote([,])dnl #include #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -314,13 +365,6 @@ changequote([,])dnl [AC_LANG_SOURCE([[ #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -335,7 +379,7 @@ int main () mbrtowc (&wc, NULL, 5, &state); /* Check that wc was not modified. */ if (wc != (wchar_t) 0xBADFACE) - return 1; + return 2; } return 0; }]])], @@ -376,13 +420,6 @@ changequote([,])dnl [AC_LANG_SOURCE([[ #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -504,13 +541,6 @@ changequote([,])dnl [AC_LANG_SOURCE([[ #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include int main () { @@ -522,7 +552,7 @@ int main () memset (&state, '\0', sizeof (mbstate_t)); if (mbrtowc (&wc, "", 1, &state) != 0) - return 1; + return 2; } return 0; }]])], @@ -533,11 +563,206 @@ int main () ]) ]) -# Prerequisites of lib/mbrtowc.c. +dnl Test whether mbrtowc stores a wide character when reporting incomplete +dnl input. + +AC_DEFUN([gl_MBRTOWC_STORES_INCOMPLETE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc stores incomplete characters], + [gl_cv_func_mbrtowc_stores_incomplete], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess yes on native Windows. + mingw*) gl_cv_func_mbrtowc_stores_incomplete="guessing yes" ;; + *) gl_cv_func_mbrtowc_stores_incomplete="guessing no" ;; + esac +changequote([,])dnl + case "$host_os" in + mingw*) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + int result = 0; + if (setlocale (LC_ALL, "French_France.65001") != NULL) + { + wchar_t wc = (wchar_t) 0xBADFACE; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, "\303", 1, &state) == (size_t)(-2) + && wc != (wchar_t) 0xBADFACE) + result |= 1; + } + if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL) + { + wchar_t wc = (wchar_t) 0xBADFACE; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, "\226", 1, &state) == (size_t)(-2) + && wc != (wchar_t) 0xBADFACE) + result |= 2; + } + if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL) + { + wchar_t wc = (wchar_t) 0xBADFACE; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, "\245", 1, &state) == (size_t)(-2) + && wc != (wchar_t) 0xBADFACE) + result |= 4; + } + if (setlocale (LC_ALL, "Chinese_China.936") != NULL) + { + wchar_t wc = (wchar_t) 0xBADFACE; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, "\261", 1, &state) == (size_t)(-2) + && wc != (wchar_t) 0xBADFACE) + result |= 8; + } + return result; +}]])], + [gl_cv_func_mbrtowc_stores_incomplete=no], + [gl_cv_func_mbrtowc_stores_incomplete=yes], + [:]) + ;; + *) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + if test $LOCALE_FR_UTF8 != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + wchar_t wc = (wchar_t) 0xBADFACE; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, "\303", 1, &state) == (size_t)(-2) + && wc != (wchar_t) 0xBADFACE) + return 1; + } + return 0; +}]])], + [gl_cv_func_mbrtowc_stores_incomplete=no], + [gl_cv_func_mbrtowc_stores_incomplete=yes], + [:]) + fi + ;; + esac + ]) +]) + +dnl Test whether mbrtowc returns the correct value on empty input. + +AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc works on empty input], + [gl_cv_func_mbrtowc_empty_input], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on AIX and glibc systems. + aix* | *-gnu* | gnu*) gl_cv_func_mbrtowc_empty_input="guessing no" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_mbrtowc_empty_input="guessing yes" ;; + *) gl_cv_func_mbrtowc_empty_input="guessing yes" ;; + esac +changequote([,])dnl + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include + static wchar_t wc; + static mbstate_t mbs; + int + main (void) + { + return mbrtowc (&wc, "", 0, &mbs) != (size_t) -2; + }]])], + [gl_cv_func_mbrtowc_empty_input=yes], + [gl_cv_func_mbrtowc_empty_input=no], + [:]) + ]) +]) + +dnl Test whether mbrtowc reports encoding errors in the C locale. +dnl Although POSIX was never intended to allow this, the GNU C Library +dnl and other implementations do it. See: +dnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932 + +AC_DEFUN([gl_MBRTOWC_C_LOCALE], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether the C locale is free of encoding errors], + [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. + gl_cv_func_mbrtowc_C_locale_sans_EILSEQ="$gl_cross_guess_normal" + + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + #include + ]], [[ + int i; + char *locale = setlocale (LC_ALL, "C"); + if (! locale) + return 2; + for (i = CHAR_MIN; i <= CHAR_MAX; i++) + { + char c = i; + wchar_t wc; + mbstate_t mbs = { 0, }; + size_t ss = mbrtowc (&wc, &c, 1, &mbs); + if (1 < ss) + return 3; + } + return 0; + ]])], + [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=yes], + [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=no], + [case "$host_os" in + # Guess yes on native Windows. + mingw*) gl_cv_func_mbrtowc_C_locale_sans_EILSEQ="guessing yes" ;; + esac + ]) + ]) +]) + +# Prerequisites of lib/mbrtowc.c and lib/lc-charset-dispatch.c. AC_DEFUN([gl_PREREQ_MBRTOWC], [ + AC_REQUIRE([AC_C_INLINE]) : ]) +# Prerequisites of lib/mbtowc-lock.c. +AC_DEFUN([gl_PREREQ_MBTOWC_LOCK], +[ + gl_VISIBILITY +]) + dnl From Paul Eggert @@ -547,24 +772,17 @@ AC_DEFUN([AC_FUNC_MBRTOWC], [ dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], - gl_cv_func_mbrtowc, + [gl_cv_func_mbrtowc], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include ]], + [[#include ]], [[wchar_t wc; char const s[] = ""; size_t n = 1; mbstate_t state; return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], - gl_cv_func_mbrtowc=yes, - gl_cv_func_mbrtowc=no)]) + [gl_cv_func_mbrtowc=yes], + [gl_cv_func_mbrtowc=no])]) if test $gl_cv_func_mbrtowc = yes; then AC_DEFINE([HAVE_MBRTOWC], [1], [Define to 1 if mbrtowc and mbstate_t are properly declared.]) diff --git a/gl/m4/mbsinit.m4 b/gl/m4/mbsinit.m4 index 2e6d0921..ebd2d4ff 100644 --- a/gl/m4/mbsinit.m4 +++ b/gl/m4/mbsinit.m4 @@ -1,5 +1,5 @@ -# mbsinit.m4 serial 8 -dnl Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. +# mbsinit.m4 serial 9 +dnl Copyright (C) 2008, 2010-2022 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. @@ -16,15 +16,8 @@ AC_DEFUN([gl_FUNC_MBSINIT], if test $ac_cv_func_mbsinit = no; then HAVE_MBSINIT=0 AC_CHECK_DECLS([mbsinit],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) + #include + ]]) if test $ac_cv_have_decl_mbsinit = yes; then dnl On Minix 3.1.8, the system's declares mbsinit() although dnl it does not have the function. Avoid a collision with gnulib's diff --git a/gl/m4/mbstate_t.m4 b/gl/m4/mbstate_t.m4 index ed001179..a6eba1bc 100644 --- a/gl/m4/mbstate_t.m4 +++ b/gl/m4/mbstate_t.m4 @@ -1,5 +1,5 @@ -# mbstate_t.m4 serial 13 -dnl Copyright (C) 2000-2002, 2008-2013 Free Software Foundation, Inc. +# mbstate_t.m4 serial 14 +dnl Copyright (C) 2000-2002, 2008-2022 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. @@ -20,14 +20,7 @@ AC_DEFUN([AC_TYPE_MBSTATE_T], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [AC_INCLUDES_DEFAULT[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include ]], + #include ]], [[mbstate_t x; return sizeof x;]])], [ac_cv_type_mbstate_t=yes], [ac_cv_type_mbstate_t=no])]) diff --git a/gl/m4/mbtowc.m4 b/gl/m4/mbtowc.m4 index e4794619..2827e833 100644 --- a/gl/m4/mbtowc.m4 +++ b/gl/m4/mbtowc.m4 @@ -1,5 +1,5 @@ -# mbtowc.m4 serial 2 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. +# mbtowc.m4 serial 3 +dnl Copyright (C) 2011-2022 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. @@ -8,8 +8,13 @@ AC_DEFUN([gl_FUNC_MBTOWC], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - if false; then - REPLACE_MBTOWC=1 + AC_CHECK_FUNCS([mbtowc]) + if test $ac_cv_func_mbtowc = no; then + HAVE_MBTOWC=0 + else + if false; then + REPLACE_MBTOWC=1 + fi fi ]) diff --git a/gl/m4/memchr.m4 b/gl/m4/memchr.m4 index 2d8abe75..c7489d87 100644 --- a/gl/m4/memchr.m4 +++ b/gl/m4/memchr.m4 @@ -1,35 +1,30 @@ -# memchr.m4 serial 12 -dnl Copyright (C) 2002-2004, 2009-2013 Free Software Foundation, Inc. +# memchr.m4 serial 18 +dnl Copyright (C) 2002-2004, 2009-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN_ONCE([gl_FUNC_MEMCHR], [ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + dnl Check for prerequisites for memory fence checks. gl_FUNC_MMAP_ANON AC_CHECK_HEADERS_ONCE([sys/mman.h]) AC_CHECK_FUNCS_ONCE([mprotect]) - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - m4_ifdef([gl_FUNC_MEMCHR_OBSOLETE], [ - dnl These days, we assume memchr is present. But if support for old - dnl platforms is desired: - AC_CHECK_FUNCS_ONCE([memchr]) - if test $ac_cv_func_memchr = no; then - HAVE_MEMCHR=0 - fi - ]) - if test $HAVE_MEMCHR = 1; then - # Detect platform-specific bugs in some versions of glibc: - # memchr should not dereference anything with length 0 - # http://bugzilla.redhat.com/499689 - # memchr should not dereference overestimated length after a match - # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 - # http://sourceware.org/bugzilla/show_bug.cgi?id=10162 - # Assume that memchr works on platforms that lack mprotect. - AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + AC_REQUIRE([gl_STRING_H_DEFAULTS]) + # Detect platform-specific bugs in some versions of glibc: + # memchr should not dereference anything with length 0 + # https://bugzilla.redhat.com/show_bug.cgi?id=499689 + # memchr should not dereference overestimated length after a match + # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 + # https://sourceware.org/bugzilla/show_bug.cgi?id=10162 + # memchr should cast the second argument to 'unsigned char'. + # This bug exists in Android 4.3. + # Assume that memchr works on platforms that lack mprotect. + AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include #if HAVE_SYS_MMAN_H # include @@ -64,6 +59,7 @@ AC_DEFUN_ONCE([gl_FUNC_MEMCHR], #endif if (fence) { + /* Test against bugs on glibc systems. */ if (memchr (fence, 0, 0)) result |= 1; strcpy (fence - 9, "12345678"); @@ -71,15 +67,37 @@ AC_DEFUN_ONCE([gl_FUNC_MEMCHR], result |= 2; if (memchr (fence - 1, 0, 3) != fence - 1) result |= 4; + /* Test against bug on AIX 7.2. */ + if (memchr (fence - 4, '6', 16) != fence - 4) + result |= 8; } + /* Test against bug on Android 4.3. */ + { + char input[3]; + input[0] = 'a'; + input[1] = 'b'; + input[2] = 'c'; + if (memchr (input, 0x789abc00 | 'b', 3) != input + 1) + result |= 16; + } return result; -]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no], - [dnl Be pessimistic for now. - gl_cv_func_memchr_works="guessing no"])]) - if test "$gl_cv_func_memchr_works" != yes; then - REPLACE_MEMCHR=1 - fi - fi +]])], + [gl_cv_func_memchr_works=yes], + [gl_cv_func_memchr_works=no], + [case "$host_os" in + # Guess no on Android. + linux*-android*) gl_cv_func_memchr_works="guessing no" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_memchr_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_memchr_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_memchr_works" in + *yes) ;; + *) REPLACE_MEMCHR=1 ;; + esac ]) # Prerequisites of lib/memchr.c. diff --git a/gl/m4/minmax.m4 b/gl/m4/minmax.m4 new file mode 100644 index 00000000..b9767397 --- /dev/null +++ b/gl/m4/minmax.m4 @@ -0,0 +1,44 @@ +# minmax.m4 serial 4 +dnl Copyright (C) 2005, 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_PREREQ([2.53]) + +AC_DEFUN([gl_MINMAX], +[ + AC_REQUIRE([gl_PREREQ_MINMAX]) +]) + +# Prerequisites of lib/minmax.h. +AC_DEFUN([gl_PREREQ_MINMAX], +[ + gl_MINMAX_IN_HEADER([limits.h]) + gl_MINMAX_IN_HEADER([sys/param.h]) +]) + +dnl gl_MINMAX_IN_HEADER(HEADER) +dnl The parameter has to be a literal header name; it cannot be macro, +dnl nor a shell variable. (Because autoheader collects only AC_DEFINE +dnl invocations with a literal macro name.) +AC_DEFUN([gl_MINMAX_IN_HEADER], +[ + m4_pushdef([header], AS_TR_SH([$1])) + m4_pushdef([HEADER], AS_TR_CPP([$1])) + AC_CACHE_CHECK([whether <$1> defines MIN and MAX], + [gl_cv_minmax_in_]header, + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <$1> + int x = MIN (42, 17);]], + [[]])], + [gl_cv_minmax_in_]header[=yes], + [gl_cv_minmax_in_]header[=no])]) + if test $gl_cv_minmax_in_[]header = yes; then + AC_DEFINE([HAVE_MINMAX_IN_]HEADER, 1, + [Define to 1 if <$1> defines the MIN and MAX macros.]) + fi + m4_popdef([HEADER]) + m4_popdef([header]) +]) diff --git a/gl/m4/mktime.m4 b/gl/m4/mktime.m4 index faefb770..431b17dc 100644 --- a/gl/m4/mktime.m4 +++ b/gl/m4/mktime.m4 @@ -1,5 +1,5 @@ -# serial 25 -dnl Copyright (C) 2002-2003, 2005-2007, 2009-2013 Free Software Foundation, +# serial 37 +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2022 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,24 +7,40 @@ dnl with or without modifications, as long as this notice is preserved. dnl From Jim Meyering. -AC_DEFUN([gl_FUNC_MKTIME], +AC_DEFUN([gl_TIME_T_IS_SIGNED], +[ + AC_CACHE_CHECK([whether time_t is signed], + [gl_cv_time_t_is_signed], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include + char time_t_signed[(time_t) -1 < 0 ? 1 : -1];]])], + [gl_cv_time_t_is_signed=yes], + [gl_cv_time_t_is_signed=no])]) + if test $gl_cv_time_t_is_signed = yes; then + AC_DEFINE([TIME_T_IS_SIGNED], [1], [Define to 1 if time_t is signed.]) + fi +]) + +dnl Test whether mktime works. Set gl_cv_func_working_mktime. +AC_DEFUN([gl_FUNC_MKTIME_WORKS], [ - AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) + AC_REQUIRE([gl_TIME_T_IS_SIGNED]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles dnl We don't use AC_FUNC_MKTIME any more, because it is no longer maintained dnl in Autoconf and because it invokes AC_LIBOBJ. AC_CHECK_HEADERS_ONCE([unistd.h]) AC_CHECK_DECLS_ONCE([alarm]) AC_REQUIRE([gl_MULTIARCH]) - if test $APPLE_UNIVERSAL_BUILD = 1; then - # A universal build on Apple Mac OS X platforms. - # The test result would be 'yes' in 32-bit mode and 'no' in 64-bit mode. - # But we need a configuration result that is valid in both modes. - gl_cv_func_working_mktime=no - fi AC_CACHE_CHECK([for working mktime], [gl_cv_func_working_mktime], - [AC_RUN_IFELSE( - [AC_LANG_SOURCE( + [if test $APPLE_UNIVERSAL_BUILD = 1; then + # A universal build on Apple Mac OS X platforms. + # The test result would be 'yes' in 32-bit mode and 'no' in 64-bit mode. + # But we need a configuration result that is valid in both modes. + gl_cv_func_working_mktime="guessing no" + else + AC_RUN_IFELSE( + [AC_LANG_SOURCE( [[/* Test program from Paul Eggert and Tony Leneis. */ #include #include @@ -38,8 +54,11 @@ AC_DEFUN([gl_FUNC_MKTIME], # include #endif -/* Work around redefinition to rpl_putenv by other config tests. */ -#undef putenv +]GL_MDA_DEFINES[ + +#ifndef TIME_T_IS_SIGNED +# define TIME_T_IS_SIGNED 0 +#endif static time_t time_t_max; static time_t time_t_min; @@ -63,7 +82,8 @@ spring_forward_gap () instead of "TZ=America/Vancouver" in order to detect the bug even on systems that don't support the Olson extension, or don't have the full zoneinfo tables installed. */ - putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); + if (putenv ("TZ=PST8PDT,M4.1.0,M10.5.0") != 0) + return -1; tm.tm_year = 98; tm.tm_mon = 3; @@ -151,7 +171,8 @@ year_2050_test () instead of "TZ=America/Vancouver" in order to detect the bug even on systems that don't support the Olson extension, or don't have the full zoneinfo tables installed. */ - putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); + if (putenv ("TZ=PST8PDT,M4.1.0,M10.5.0") != 0) + return -1; t = mktime (&tm); @@ -162,6 +183,25 @@ year_2050_test () || (0 < t && answer - 120 <= t && t <= answer + 120)); } +static int +indiana_test () +{ + if (putenv ("TZ=America/Indiana/Indianapolis") != 0) + return -1; + struct tm tm; + tm.tm_year = 1986 - 1900; tm.tm_mon = 4 - 1; tm.tm_mday = 28; + tm.tm_hour = 16; tm.tm_min = 24; tm.tm_sec = 50; tm.tm_isdst = 0; + time_t std = mktime (&tm); + if (! (std == 515107490 || std == 515107503)) + return 1; + + /* This platform supports TZDB, either without or with leap seconds. + Return true if GNU Bug#48085 is absent. */ + tm.tm_isdst = 1; + time_t dst = mktime (&tm); + return std - dst == 60 * 60; +} + int main () { @@ -169,7 +209,6 @@ main () time_t t, delta; int i, j; int time_t_signed_magnitude = (time_t) ~ (time_t) 0 < (time_t) -1; - int time_t_signed = ! ((time_t) 0 < (time_t) -1); #if HAVE_DECL_ALARM /* This test makes some buggy mktime implementations loop. @@ -179,11 +218,11 @@ main () alarm (60); #endif - time_t_max = (! time_t_signed + time_t_max = (! TIME_T_IS_SIGNED ? (time_t) -1 : ((((time_t) 1 << (sizeof (time_t) * CHAR_BIT - 2)) - 1) * 2 + 1)); - time_t_min = (! time_t_signed + time_t_min = (! TIME_T_IS_SIGNED ? (time_t) 0 : time_t_signed_magnitude ? ~ (time_t) 0 @@ -218,35 +257,62 @@ main () result |= 16; if (! spring_forward_gap ()) result |= 32; - if (! year_2050_test ()) + if (! year_2050_test () || ! indiana_test ()) result |= 64; return result; }]])], - [gl_cv_func_working_mktime=yes], - [gl_cv_func_working_mktime=no], - [gl_cv_func_working_mktime=no]) + [gl_cv_func_working_mktime=yes], + [gl_cv_func_working_mktime=no], + [case "$host_os" in + # Guess no on native Windows. + mingw*) gl_cv_func_working_mktime="guessing no" ;; + *) gl_cv_func_working_mktime="$gl_cross_guess_normal" ;; + esac + ]) + fi ]) +]) + +dnl Main macro of module 'mktime'. +AC_DEFUN([gl_FUNC_MKTIME], +[ + AC_REQUIRE([gl_TIME_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_FUNC_MKTIME_WORKS]) - if test $gl_cv_func_working_mktime = no; then + REPLACE_MKTIME=0 + if test "$gl_cv_func_working_mktime" != yes; then REPLACE_MKTIME=1 - else - REPLACE_MKTIME=0 + AC_DEFINE([NEED_MKTIME_WORKING], [1], + [Define if the compilation of mktime.c should define 'mktime' + with the algorithmic workarounds.]) fi + case "$host_os" in + mingw*) + REPLACE_MKTIME=1 + AC_DEFINE([NEED_MKTIME_WINDOWS], [1], + [Define if the compilation of mktime.c should define 'mktime' + with the native Windows TZ workaround.]) + ;; + esac ]) +dnl Main macro of module 'mktime-internal'. AC_DEFUN([gl_FUNC_MKTIME_INTERNAL], [ - AC_REQUIRE([gl_FUNC_MKTIME]) - if test $REPLACE_MKTIME = 0; then - dnl BeOS has __mktime_internal in libc, but other platforms don't. - AC_CHECK_FUNC([__mktime_internal], - [AC_DEFINE([mktime_internal], [__mktime_internal], - [Define to the real name of the mktime_internal function.]) - ], - [dnl mktime works but it doesn't export __mktime_internal, - dnl so we need to substitute our own mktime implementation. - REPLACE_MKTIME=1 - ]) - fi + AC_REQUIRE([gl_FUNC_MKTIME_WORKS]) + + WANT_MKTIME_INTERNAL=0 + dnl BeOS has __mktime_internal in libc, but other platforms don't. + AC_CHECK_FUNC([__mktime_internal], + [AC_DEFINE([mktime_internal], [__mktime_internal], + [Define to the real name of the mktime_internal function.]) + ], + [dnl mktime works but it doesn't export __mktime_internal, + dnl so we need to substitute our own mktime implementation. + WANT_MKTIME_INTERNAL=1 + AC_DEFINE([NEED_MKTIME_INTERNAL], [1], + [Define if the compilation of mktime.c should define 'mktime_internal'.]) + ]) ]) # Prerequisites of lib/mktime.c. diff --git a/gl/m4/mmap-anon.m4 b/gl/m4/mmap-anon.m4 index 9b60ddfa..a4580ff9 100644 --- a/gl/m4/mmap-anon.m4 +++ b/gl/m4/mmap-anon.m4 @@ -1,5 +1,5 @@ -# mmap-anon.m4 serial 10 -dnl Copyright (C) 2005, 2007, 2009-2013 Free Software Foundation, Inc. +# mmap-anon.m4 serial 12 +dnl Copyright (C) 2005, 2007, 2009-2022 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. @@ -9,11 +9,11 @@ dnl with or without modifications, as long as this notice is preserved. # - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS # and MAP_ANON exist and have the same value. # - On HP-UX, only MAP_ANONYMOUS exists. -# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists. +# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, only MAP_ANON exists. # - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be # used. -AC_DEFUN([gl_FUNC_MMAP_ANON], +AC_DEFUN_ONCE([gl_FUNC_MMAP_ANON], [ dnl Persuade glibc to define MAP_ANONYMOUS. AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) diff --git a/gl/m4/mode_t.m4 b/gl/m4/mode_t.m4 new file mode 100644 index 00000000..e08d27a7 --- /dev/null +++ b/gl/m4/mode_t.m4 @@ -0,0 +1,26 @@ +# mode_t.m4 serial 2 +dnl Copyright (C) 2009-2022 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. + +# For using mode_t, it's sufficient to use AC_TYPE_MODE_T and +# include . + +# Define PROMOTED_MODE_T to the type that is the result of "default argument +# promotion" (ISO C 6.5.2.2.(6)) of the type mode_t. +AC_DEFUN([gl_PROMOTED_TYPE_MODE_T], +[ + AC_REQUIRE([AC_TYPE_MODE_T]) + AC_CACHE_CHECK([for promoted mode_t type], [gl_cv_promoted_mode_t], [ + dnl Assume mode_t promotes to 'int' if and only if it is smaller than 'int', + dnl and to itself otherwise. This assumption is not guaranteed by the ISO C + dnl standard, but we don't know of any real-world counterexamples. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[typedef int array[2 * (sizeof (mode_t) < sizeof (int)) - 1];]])], + [gl_cv_promoted_mode_t='int'], + [gl_cv_promoted_mode_t='mode_t']) + ]) + AC_DEFINE_UNQUOTED([PROMOTED_MODE_T], [$gl_cv_promoted_mode_t], + [Define to the type that is the result of default argument promotions of type mode_t.]) +]) diff --git a/gl/m4/mountlist.m4 b/gl/m4/mountlist.m4 index cd137c91..a3f72dfd 100644 --- a/gl/m4/mountlist.m4 +++ b/gl/m4/mountlist.m4 @@ -1,19 +1,338 @@ -# serial 11 -dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. +# serial 15 +dnl Copyright (C) 2002-2006, 2009-2022 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 From Jim Meyering. + +AC_PREREQ([2.60]) + AC_DEFUN([gl_MOUNTLIST], [ - gl_LIST_MOUNTED_FILE_SYSTEMS([gl_cv_list_mounted_fs=yes], - [gl_cv_list_mounted_fs=no]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS([listmntent]) + AC_CHECK_HEADERS_ONCE([sys/param.h sys/statvfs.h]) + + # We must include grp.h before ucred.h on OSF V4.0, since ucred.h uses + # NGROUPS (as the array dimension for a struct member) without a definition. + AC_CHECK_HEADERS([sys/ucred.h], [], [], [#include ]) + + AC_CHECK_HEADERS([sys/mount.h], [], [], + [AC_INCLUDES_DEFAULT + [#if HAVE_SYS_PARAM_H + #include + #endif + ]]) + + AC_CHECK_HEADERS([mntent.h sys/fs_types.h]) + getfsstat_includes="\ +$ac_includes_default +#if HAVE_SYS_PARAM_H +# include /* needed by powerpc-apple-darwin1.3.7 */ +#endif +#if HAVE_SYS_UCRED_H +# include /* needed for definition of NGROUPS */ +# include /* needed by powerpc-apple-darwin1.3.7 */ +#endif +#if HAVE_SYS_MOUNT_H +# include +#endif +#if HAVE_SYS_FS_TYPES_H +# include /* needed by powerpc-apple-darwin1.3.7 */ +#endif +" + AC_CHECK_MEMBERS([struct fsstat.f_fstypename],,,[$getfsstat_includes]) + + # Determine how to get the list of mounted file systems. + ac_list_mounted_fs= + + # If the getmntent function is available but not in the standard library, + # make sure LIBS contains the appropriate -l option. + AC_FUNC_GETMNTENT + + if test -z "$ac_list_mounted_fs"; then + # AIX. + AC_CACHE_CHECK([for mntctl function and struct vmount], + [fu_cv_sys_mounted_vmount], + [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])], + [fu_cv_sys_mounted_vmount=yes], + [fu_cv_sys_mounted_vmount=no])]) + if test $fu_cv_sys_mounted_vmount = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_VMOUNT], [1], + [Define if there is a function named mntctl that can be used to read + the list of mounted file systems, and there is a system header file + that declares 'struct vmount'. (AIX)]) + fi + fi + + if test $ac_cv_func_getmntent = yes; then + + # This system has the getmntent function. + # Determine whether it's the one-argument variant or the two-argument one. + + if test -z "$ac_list_mounted_fs"; then + # glibc, HP-UX, IRIX, Cygwin, Android, also (obsolete) 4.3BSD, SunOS. + AC_CACHE_CHECK([for one-argument getmntent function], + [fu_cv_sys_mounted_getmntent1], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +/* SunOS 4.1.x /usr/include/mntent.h needs this for FILE */ +#include + +#include +#if defined __ANDROID__ /* Android */ +# undef MOUNTED +# define MOUNTED "/proc/mounts" +#elif !defined MOUNTED +# if defined _PATH_MOUNTED /* GNU libc */ +# define MOUNTED _PATH_MOUNTED +# endif +# if defined MNT_MNTTAB /* HP-UX. */ +# define MOUNTED MNT_MNTTAB +# endif +#endif +]], + [[struct mntent *mnt = 0; char *table = MOUNTED; + if (sizeof mnt && sizeof table) return 0; + ]])], + [fu_cv_sys_mounted_getmntent1=yes], + [fu_cv_sys_mounted_getmntent1=no]) + ]) + if test $fu_cv_sys_mounted_getmntent1 = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETMNTENT1], [1], + [Define if there is a function named getmntent for reading the list + of mounted file systems, and that function takes a single argument. + (4.3BSD, SunOS, HP-UX, Irix)]) + AC_CHECK_FUNCS([setmntent endmntent hasmntopt]) + fi + fi + + if test -z "$ac_list_mounted_fs"; then + # Solaris >= 8. + AC_CACHE_CHECK([for getextmntent function], + [fu_cv_sys_mounted_getextmntent], + [AC_EGREP_HEADER([getextmntent], [sys/mnttab.h], + [fu_cv_sys_mounted_getextmntent=yes], + [fu_cv_sys_mounted_getextmntent=no])]) + if test $fu_cv_sys_mounted_getextmntent = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETEXTMNTENT], [1], + [Define if there is a function named getextmntent for reading the list + of mounted file systems. (Solaris)]) + fi + fi + + if test -z "$ac_list_mounted_fs"; then + # Solaris < 8, also (obsolete) SVR4. + # Solaris >= 8 has the two-argument getmntent but is already handled above. + AC_CACHE_CHECK([for two-argument getmntent function], + [fu_cv_sys_mounted_getmntent2], + [AC_EGREP_HEADER([getmntent], [sys/mnttab.h], + [fu_cv_sys_mounted_getmntent2=yes], + [fu_cv_sys_mounted_getmntent2=no]) + ]) + if test $fu_cv_sys_mounted_getmntent2 = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETMNTENT2], [1], + [Define if there is a function named getmntent for reading the list of + mounted file systems, and that function takes two arguments. (SVR4)]) + AC_CHECK_FUNCS([hasmntopt]) + fi + fi + + fi + + if test -z "$ac_list_mounted_fs"; then + # OSF/1, also (obsolete) Apple Darwin 1.3. + # powerpc-apple-darwin1.3.7 needs sys/param.h sys/ucred.h sys/fs_types.h + + AC_CACHE_CHECK([for getfsstat function], + [fu_cv_sys_mounted_getfsstat], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#if HAVE_STRUCT_FSSTAT_F_FSTYPENAME +# define FS_TYPE(Ent) ((Ent).f_fstypename) +#else +# define FS_TYPE(Ent) mnt_names[(Ent).f_type] +#endif +$getfsstat_includes + ]], + [[struct statfs *stats; + int numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT); + char *t = FS_TYPE (*stats); + ]])], + [fu_cv_sys_mounted_getfsstat=yes], + [fu_cv_sys_mounted_getfsstat=no]) + ]) + if test $fu_cv_sys_mounted_getfsstat = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETFSSTAT], [1], + [Define if there is a function named getfsstat for reading the + list of mounted file systems. (DEC Alpha running OSF/1)]) + fi + fi + + if test -z "$ac_list_mounted_fs"; then + # (obsolete) SVR3 + AC_CACHE_CHECK([for FIXME existence of three headers], + [fu_cv_sys_mounted_fread_fstyp], + [AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include +]])], + [fu_cv_sys_mounted_fread_fstyp=yes], + [fu_cv_sys_mounted_fread_fstyp=no]) + ]) + if test $fu_cv_sys_mounted_fread_fstyp = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_FREAD_FSTYP], [1], + [Define if (like SVR2) there is no specific function for reading the + list of mounted file systems, and your system has these header files: + and . (SVR3)]) + fi + fi + + if test -z "$ac_list_mounted_fs"; then + # Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, also (obsolete) 4.4BSD. + # OSF/1 also has getmntinfo but is already handled above. + # We cannot use AC_CHECK_FUNCS([getmntinfo]) here, because at the linker + # level the function is sometimes called getmntinfo64 or getmntinfo$INODE64 + # on Mac OS X, __getmntinfo13 on NetBSD and Minix, _F64_getmntinfo on OSF/1. + AC_CACHE_CHECK([for getmntinfo function], + [fu_cv_sys_mounted_getmntinfo], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#if HAVE_SYS_PARAM_H +# include +#endif +#include +#if HAVE_SYS_MOUNT_H +# include +#endif +#if HAVE_SYS_STATVFS_H +# include +#endif +#include + ]], + [[int count = getmntinfo (NULL, MNT_WAIT); + ]])], + [fu_cv_sys_mounted_getmntinfo=yes], + [fu_cv_sys_mounted_getmntinfo=no]) + ]) + if test $fu_cv_sys_mounted_getmntinfo = yes; then + AC_CACHE_CHECK([whether getmntinfo returns statvfs structures], + [fu_cv_sys_mounted_getmntinfo2], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +#if HAVE_SYS_PARAM_H +# include +#endif +#include +#if HAVE_SYS_MOUNT_H +# include +#endif +#if HAVE_SYS_STATVFS_H +# include +#endif +extern +#ifdef __cplusplus +"C" +#endif +int getmntinfo (struct statfs **, int); + ]], [[]])], + [fu_cv_sys_mounted_getmntinfo2=no], + [fu_cv_sys_mounted_getmntinfo2=yes]) + ]) + if test $fu_cv_sys_mounted_getmntinfo2 = no; then + # Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD. + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETMNTINFO], [1], + [Define if there is a function named getmntinfo for reading the + list of mounted file systems and it returns an array of + 'struct statfs'. (4.4BSD, Darwin)]) + else + # NetBSD, Minix. + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_GETMNTINFO2], [1], + [Define if there is a function named getmntinfo for reading the + list of mounted file systems and it returns an array of + 'struct statvfs'. (NetBSD 3.0)]) + fi + fi + fi + + if test -z "$ac_list_mounted_fs"; then + # Haiku, also (obsolete) BeOS. + AC_CHECK_FUNCS([next_dev fs_stat_dev]) + AC_CHECK_HEADERS([fs_info.h]) + AC_CACHE_CHECK([for BEOS mounted file system support functions], + [fu_cv_sys_mounted_fs_stat_dev], + [if test $ac_cv_header_fs_info_h = yes \ + && test $ac_cv_func_next_dev = yes \ + && test $ac_cv_func_fs_stat_dev = yes; then + fu_cv_sys_mounted_fs_stat_dev=yes + else + fu_cv_sys_mounted_fs_stat_dev=no + fi + ]) + if test $fu_cv_sys_mounted_fs_stat_dev = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_FS_STAT_DEV], [1], + [Define if there are functions named next_dev and fs_stat_dev for + reading the list of mounted file systems. (BeOS)]) + fi + fi + + if test -z "$ac_list_mounted_fs"; then + # Interix / BSD alike statvfs + # the code is really interix specific, so make sure, we're on it. + case "$host" in + *-interix*) + AC_CHECK_FUNCS([statvfs]) + if test $ac_cv_func_statvfs = yes; then + ac_list_mounted_fs=found + AC_DEFINE([MOUNTED_INTERIX_STATVFS], [1], + [Define if we are on interix, and ought to use statvfs plus + some special knowledge on where mounted file systems can be + found. (Interix)]) + fi + ;; + esac + fi + + if test -z "$ac_list_mounted_fs"; then + AC_MSG_ERROR([could not determine how to read list of mounted file systems]) + # FIXME -- no need to abort building the whole package + # Can't build mountlist.c or anything that needs its functions + fi + + if test $ac_list_mounted_fs = found; then + gl_cv_list_mounted_fs=yes + else + gl_cv_list_mounted_fs=no + fi ]) -# Prerequisites of lib/mountlist.c not done by gl_LIST_MOUNTED_FILE_SYSTEMS. +# Prerequisites of lib/mountlist.c not done by gl_MOUNTLIST. AC_DEFUN([gl_PREREQ_MOUNTLIST_EXTRA], [ - dnl Note gl_LIST_MOUNTED_FILE_SYSTEMS checks for mntent.h, not sys/mntent.h. + dnl Note gl_MOUNTLIST checks for mntent.h, not sys/mntent.h. AC_CHECK_HEADERS([sys/mntent.h]) + AC_HEADER_MAJOR()dnl for use of makedev () gl_FSTYPENAME ]) + +# Replace Autoconf's AC_FUNC_GETMNTENT to omit checks that are unnecessary +# nowadays. +AC_DEFUN([AC_FUNC_GETMNTENT], +[ + # getmntent is in the standard C library on most systems, but in -lgen on + # Unixware. + AC_SEARCH_LIBS([getmntent], [gen]) + AC_CHECK_FUNCS([getmntent]) +]) diff --git a/gl/m4/msvc-inval.m4 b/gl/m4/msvc-inval.m4 index 9a6a47a7..b32cf6eb 100644 --- a/gl/m4/msvc-inval.m4 +++ b/gl/m4/msvc-inval.m4 @@ -1,5 +1,5 @@ # msvc-inval.m4 serial 1 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2011-2022 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. diff --git a/gl/m4/msvc-nothrow.m4 b/gl/m4/msvc-nothrow.m4 index a39618a4..16ceb1f1 100644 --- a/gl/m4/msvc-nothrow.m4 +++ b/gl/m4/msvc-nothrow.m4 @@ -1,5 +1,5 @@ # msvc-nothrow.m4 serial 1 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2011-2022 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. diff --git a/gl/m4/multiarch.m4 b/gl/m4/multiarch.m4 index 552ec7e7..5d942765 100644 --- a/gl/m4/multiarch.m4 +++ b/gl/m4/multiarch.m4 @@ -1,5 +1,5 @@ -# multiarch.m4 serial 7 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +# multiarch.m4 serial 9 +dnl Copyright (C) 2008-2022 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. @@ -21,37 +21,40 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN_ONCE([gl_MULTIARCH], [ dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN. - gl_cv_c_multiarch=no - AC_COMPILE_IFELSE( - [AC_LANG_SOURCE( - [[#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - ]])], - [ - dnl Check for potential -arch flags. It is not universal unless - dnl there are at least two -arch flags with different values. - arch= - prev= - for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do - if test -n "$prev"; then - case $word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$arch" || test "$arch" = "$word"; then - arch="$word" - else - gl_cv_c_multiarch=yes - fi - ;; - esac - prev= - else - if test "x$word" = "x-arch"; then - prev=arch - fi - fi - done + AC_CACHE_CHECK([whether the compiler produces multi-arch binaries], + [gl_cv_c_multiarch], + [gl_cv_c_multiarch=no + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + ]])], + [ + dnl Check for potential -arch flags. It is not universal unless + dnl there are at least two -arch flags with different values. + arch= + prev= + for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do + if test -n "$prev"; then + case $word in + i?86 | x86_64 | ppc | ppc64 | arm | arm64) + if test -z "$arch" || test "$arch" = "$word"; then + arch="$word" + else + gl_cv_c_multiarch=yes + fi + ;; + esac + prev= + else + if test "x$word" = "x-arch"; then + prev=arch + fi + fi + done + ]) ]) if test $gl_cv_c_multiarch = yes; then APPLE_UNIVERSAL_BUILD=1 diff --git a/gl/m4/netdb_h.m4 b/gl/m4/netdb_h.m4 index 2c69f999..d6a9d709 100644 --- a/gl/m4/netdb_h.m4 +++ b/gl/m4/netdb_h.m4 @@ -1,10 +1,10 @@ -# netdb_h.m4 serial 11 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +# netdb_h.m4 serial 15 +dnl Copyright (C) 2008-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_HEADER_NETDB], +AC_DEFUN_ONCE([gl_NETDB_H], [ AC_REQUIRE([gl_NETDB_H_DEFAULTS]) gl_CHECK_NEXT_HEADERS([netdb.h]) @@ -21,18 +21,33 @@ AC_DEFUN([gl_HEADER_NETDB], [getaddrinfo freeaddrinfo gai_strerror getnameinfo]) ]) +# gl_NETDB_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_NETDB_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_NETDB_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_NETDB_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_NETDB_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_NETDB_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETADDRINFO]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_NETDB_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_NETDB_H_DEFAULTS]) +]) + AC_DEFUN([gl_NETDB_H_DEFAULTS], [ - GNULIB_GETADDRINFO=0; AC_SUBST([GNULIB_GETADDRINFO]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_STRUCT_ADDRINFO=1; AC_SUBST([HAVE_STRUCT_ADDRINFO]) HAVE_DECL_FREEADDRINFO=1; AC_SUBST([HAVE_DECL_FREEADDRINFO]) @@ -40,4 +55,5 @@ AC_DEFUN([gl_NETDB_H_DEFAULTS], HAVE_DECL_GETADDRINFO=1; AC_SUBST([HAVE_DECL_GETADDRINFO]) HAVE_DECL_GETNAMEINFO=1; AC_SUBST([HAVE_DECL_GETNAMEINFO]) REPLACE_GAI_STRERROR=0; AC_SUBST([REPLACE_GAI_STRERROR]) + REPLACE_GETADDRINFO=0; AC_SUBST([REPLACE_GETADDRINFO]) ]) diff --git a/gl/m4/netinet_in_h.m4 b/gl/m4/netinet_in_h.m4 index 21971b29..de26fe85 100644 --- a/gl/m4/netinet_in_h.m4 +++ b/gl/m4/netinet_in_h.m4 @@ -1,5 +1,5 @@ -# netinet_in_h.m4 serial 5 -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. +# netinet_in_h.m4 serial 6 +dnl Copyright (C) 2006-2022 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. @@ -14,9 +14,9 @@ AC_DEFUN([gl_HEADER_NETINET_IN], [gl_cv_header_netinet_in_h_selfcontained=no]) ]) if test $gl_cv_header_netinet_in_h_selfcontained = yes; then - NETINET_IN_H='' + GL_GENERATE_NETINET_IN_H=false else - NETINET_IN_H='netinet/in.h' + GL_GENERATE_NETINET_IN_H=true AC_CHECK_HEADERS([netinet/in.h]) gl_CHECK_NEXT_HEADERS([netinet/in.h]) if test $ac_cv_header_netinet_in_h = yes; then @@ -26,6 +26,4 @@ AC_DEFUN([gl_HEADER_NETINET_IN], fi AC_SUBST([HAVE_NETINET_IN_H]) fi - AC_SUBST([NETINET_IN_H]) - AM_CONDITIONAL([GL_GENERATE_NETINET_IN_H], [test -n "$NETINET_IN_H"]) ]) diff --git a/gl/m4/nl_langinfo.m4 b/gl/m4/nl_langinfo.m4 index 25e21015..d20a09cf 100644 --- a/gl/m4/nl_langinfo.m4 +++ b/gl/m4/nl_langinfo.m4 @@ -1,5 +1,5 @@ -# nl_langinfo.m4 serial 5 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. +# nl_langinfo.m4 serial 8 +dnl Copyright (C) 2009-2022 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. @@ -9,7 +9,10 @@ AC_DEFUN([gl_FUNC_NL_LANGINFO], AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) AC_REQUIRE([gl_LANGINFO_H]) AC_CHECK_FUNCS_ONCE([nl_langinfo]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_FUNC_SETLOCALE_NULL]) + AC_REQUIRE([gl_PTHREADLIB]) + AC_CHECK_HEADERS_ONCE([threads.h]) if test $ac_cv_func_nl_langinfo = yes; then # On Irix 6.5, YESEXPR is defined, but nl_langinfo(YESEXPR) is broken. AC_CACHE_CHECK([whether YESEXPR works], @@ -36,8 +39,19 @@ AC_DEFUN([gl_FUNC_NL_LANGINFO], AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS], [$FUNC_NL_LANGINFO_YESEXPR_WORKS], [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.]) - if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1 \ - && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1; then + # On Solaris 10 and Solaris 11.3, nl_langinfo is not multithread-safe. + case "$host_os" in + solaris*) NL_LANGINFO_MTSAFE=0 ;; + *) NL_LANGINFO_MTSAFE=1 ;; + esac + AC_DEFINE_UNQUOTED([NL_LANGINFO_MTSAFE], [$NL_LANGINFO_MTSAFE], + [Define to 1 if nl_langinfo is multithread-safe.]) + if test $HAVE_LANGINFO_CODESET = 1 \ + && test $HAVE_LANGINFO_T_FMT_AMPM = 1 \ + && test $HAVE_LANGINFO_ALTMON = 1 \ + && test $HAVE_LANGINFO_ERA = 1 \ + && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1 \ + && test $NL_LANGINFO_MTSAFE = 1; then : else REPLACE_NL_LANGINFO=1 @@ -47,4 +61,17 @@ AC_DEFUN([gl_FUNC_NL_LANGINFO], else HAVE_NL_LANGINFO=0 fi + if test $HAVE_NL_LANGINFO = 0 || test $HAVE_LANGINFO_CODESET = 0; then + LIB_NL_LANGINFO="$LIB_SETLOCALE_NULL" + else + LIB_NL_LANGINFO= + fi + dnl LIB_NL_LANGINFO is expected to be empty everywhere. + AC_SUBST([LIB_NL_LANGINFO]) +]) + +# Prerequisites of lib/nl_langinfo-lock.c. +AC_DEFUN([gl_PREREQ_NL_LANGINFO_LOCK], +[ + gl_VISIBILITY ]) diff --git a/gl/m4/nls.m4 b/gl/m4/nls.m4 index 8f8a147b..7c11c90f 100644 --- a/gl/m4/nls.m4 +++ b/gl/m4/nls.m4 @@ -1,17 +1,17 @@ -# nls.m4 serial 5 (gettext-0.18) -dnl Copyright (C) 1995-2003, 2005-2006, 2008-2013 Free Software Foundation, -dnl Inc. +# nls.m4 serial 6 (gettext-0.20.2) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019-2022 Free +dnl 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: diff --git a/gl/m4/nocrash.m4 b/gl/m4/nocrash.m4 index 105b884f..91f00c1b 100644 --- a/gl/m4/nocrash.m4 +++ b/gl/m4/nocrash.m4 @@ -1,5 +1,5 @@ -# nocrash.m4 serial 4 -dnl Copyright (C) 2005, 2009-2013 Free Software Foundation, Inc. +# nocrash.m4 serial 5 +dnl Copyright (C) 2005, 2009-2022 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. @@ -53,7 +53,7 @@ nocrash_init (void) /* Allocate a port on which the thread shall listen for exceptions. */ if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port) == KERN_SUCCESS) { - /* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */ + /* See https://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */ if (mach_port_insert_right (self, our_exception_port, our_exception_port, MACH_MSG_TYPE_MAKE_SEND) == KERN_SUCCESS) { @@ -72,14 +72,14 @@ nocrash_init (void) for a particular thread. This has the effect that when our exception port gets the message, the thread specific exception port has already been asked, and we don't need to bother about it. - See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */ + See https://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */ task_set_exception_ports (self, mask, our_exception_port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE); } } } } -#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +#elif defined _WIN32 && ! defined __CYGWIN__ /* Avoid a crash on native Windows. */ #define WIN32_LEAN_AND_MEAN #include @@ -110,11 +110,12 @@ nocrash_init (void) #else /* Avoid a crash on POSIX systems. */ #include +#include /* A POSIX signal handler. */ static void exception_handler (int sig) { - exit (1); + _exit (1); } static void nocrash_init (void) diff --git a/gl/m4/off_t.m4 b/gl/m4/off_t.m4 index d355d013..0890adaf 100644 --- a/gl/m4/off_t.m4 +++ b/gl/m4/off_t.m4 @@ -1,5 +1,5 @@ # off_t.m4 serial 1 -dnl Copyright (C) 2012-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2012-2022 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. diff --git a/gl/m4/onceonly.m4 b/gl/m4/onceonly.m4 deleted file mode 100644 index 0a875a3d..00000000 --- a/gl/m4/onceonly.m4 +++ /dev/null @@ -1,104 +0,0 @@ -# onceonly.m4 serial 9 -dnl Copyright (C) 2002-2003, 2005-2006, 2008-2013 Free Software Foundation, -dnl Inc. -dnl -dnl This file is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3 of the License, or -dnl (at your option) any later version. -dnl -dnl This file is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this file. If not, see . -dnl -dnl As a special exception to the GNU General Public License, -dnl this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl This file defines some "once only" variants of standard autoconf macros. -dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS -dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS -dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS -dnl AC_REQUIRE([AC_FUNC_STRCOLL]) like AC_FUNC_STRCOLL -dnl The advantage is that the check for each of the headers/functions/decls -dnl will be put only once into the 'configure' file. It keeps the size of -dnl the 'configure' file down, and avoids redundant output when 'configure' -dnl is run. -dnl The drawback is that the checks cannot be conditionalized. If you write -dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi -dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to -dnl empty, and the check will be inserted before the body of the AC_DEFUNed -dnl function. - -dnl The original code implemented AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE -dnl in terms of AC_DEFUN and AC_REQUIRE. This implementation uses diversions to -dnl named sections DEFAULTS and INIT_PREPARE in order to check all requested -dnl headers at once, thus reducing the size of 'configure'. It is known to work -dnl with autoconf 2.57..2.62 at least . The size reduction is ca. 9%. - -dnl Autoconf version 2.59 plus gnulib is required; this file is not needed -dnl with Autoconf 2.60 or greater. But note that autoconf's implementation of -dnl AC_CHECK_DECLS_ONCE expects a comma-separated list of symbols as first -dnl argument! -AC_PREREQ([2.59]) - -# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of -# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). -AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ - : - m4_foreach_w([gl_HEADER_NAME], [$1], [ - AC_DEFUN([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, - [./-], [___])), [ - m4_divert_text([INIT_PREPARE], - [gl_header_list="$gl_header_list gl_HEADER_NAME"]) - gl_HEADERS_EXPANSION - AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_HEADER_NAME])), - [Define to 1 if you have the <]m4_defn([gl_HEADER_NAME])[> header file.]) - ]) - AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, - [./-], [___]))) - ]) -]) -m4_define([gl_HEADERS_EXPANSION], [ - m4_divert_text([DEFAULTS], [gl_header_list=]) - AC_CHECK_HEADERS([$gl_header_list]) - m4_define([gl_HEADERS_EXPANSION], []) -]) - -# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of -# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). -AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ - : - m4_foreach_w([gl_FUNC_NAME], [$1], [ - AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [ - m4_divert_text([INIT_PREPARE], - [gl_func_list="$gl_func_list gl_FUNC_NAME"]) - gl_FUNCS_EXPANSION - AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_FUNC_NAME])), - [Define to 1 if you have the ']m4_defn([gl_FUNC_NAME])[' function.]) - ]) - AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME])) - ]) -]) -m4_define([gl_FUNCS_EXPANSION], [ - m4_divert_text([DEFAULTS], [gl_func_list=]) - AC_CHECK_FUNCS([$gl_func_list]) - m4_define([gl_FUNCS_EXPANSION], []) -]) - -# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of -# AC_CHECK_DECLS(DECL1, DECL2, ...). -AC_DEFUN([AC_CHECK_DECLS_ONCE], [ - : - m4_foreach_w([gl_DECL_NAME], [$1], [ - AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [ - AC_CHECK_DECLS(m4_defn([gl_DECL_NAME])) - ]) - AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME])) - ]) -]) diff --git a/gl/m4/open-cloexec.m4 b/gl/m4/open-cloexec.m4 new file mode 100644 index 00000000..16cd5ec4 --- /dev/null +++ b/gl/m4/open-cloexec.m4 @@ -0,0 +1,21 @@ +# Test whether O_CLOEXEC is defined. + +dnl Copyright 2017-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_PREPROC_O_CLOEXEC], +[ + AC_CACHE_CHECK([for O_CLOEXEC], + [gl_cv_macro_O_CLOEXEC], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include + #ifndef O_CLOEXEC + choke me; + #endif + ]], + [[return O_CLOEXEC;]])], + [gl_cv_macro_O_CLOEXEC=yes], + [gl_cv_macro_O_CLOEXEC=no])]) +]) diff --git a/gl/m4/open-slash.m4 b/gl/m4/open-slash.m4 new file mode 100644 index 00000000..4fbf491a --- /dev/null +++ b/gl/m4/open-slash.m4 @@ -0,0 +1,60 @@ +# open-slash.m4 serial 2 +dnl Copyright (C) 2007-2022 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 Tests whether open() and creat() recognize a trailing slash. +dnl Sets gl_cv_func_open_slash. +AC_DEFUN([gl_OPEN_TRAILING_SLASH_BUG], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + dnl open("foo/") should not create a file when the file name has a + dnl trailing slash. FreeBSD only has the problem on symlinks. + AC_CHECK_FUNCS_ONCE([lstat]) + AC_CACHE_CHECK([whether open recognizes a trailing slash], + [gl_cv_func_open_slash], + [# Assume that if we have lstat, we can also check symlinks. + if test $ac_cv_func_lstat = yes; then + touch conftest.tmp + ln -s conftest.tmp conftest.lnk + fi + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#if HAVE_UNISTD_H +# include +#endif +]GL_MDA_DEFINES[ +int main () +{ + int result = 0; +#if HAVE_LSTAT + if (open ("conftest.lnk/", O_RDONLY) != -1) + result |= 1; +#endif + if (open ("conftest.sl/", O_CREAT, 0600) >= 0) + result |= 2; + return result; +}]])], + [gl_cv_func_open_slash=yes], + [gl_cv_func_open_slash=no], + [ +changequote(,)dnl + case "$host_os" in + freebsd* | aix* | hpux* | solaris2.[0-9] | solaris2.[0-9].*) + gl_cv_func_open_slash="guessing no" ;; + *) + gl_cv_func_open_slash="guessing yes" ;; + esac +changequote([,])dnl + ]) + rm -f conftest.sl conftest.tmp conftest.lnk + ]) + case "$gl_cv_func_open_slash" in + *no) + AC_DEFINE([OPEN_TRAILING_SLASH_BUG], [1], + [Define to 1 if open() fails to recognize a trailing slash.]) + ;; + esac +]) diff --git a/gl/m4/open.m4 b/gl/m4/open.m4 new file mode 100644 index 00000000..f82fd6ca --- /dev/null +++ b/gl/m4/open.m4 @@ -0,0 +1,56 @@ +# open.m4 serial 15 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_OPEN], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_PREPROC_O_CLOEXEC]) + case "$host_os" in + mingw* | pw*) + REPLACE_OPEN=1 + ;; + *) + dnl open("foo/") should not create a file when the file name has a + dnl trailing slash. FreeBSD only has the problem on symlinks. + AC_CHECK_FUNCS_ONCE([lstat]) + if test "$gl_cv_macro_O_CLOEXEC" != yes; then + REPLACE_OPEN=1 + fi + gl_OPEN_TRAILING_SLASH_BUG + case "$gl_cv_func_open_slash" in + *no) + REPLACE_OPEN=1 + ;; + esac + ;; + esac + dnl Replace open() for supporting the gnulib-defined fchdir() function, + dnl to keep fchdir's bookkeeping up-to-date. + m4_ifdef([gl_FUNC_FCHDIR], [ + if test $REPLACE_OPEN = 0; then + gl_TEST_FCHDIR + if test $HAVE_FCHDIR = 0; then + REPLACE_OPEN=1 + fi + fi + ]) + dnl Replace open() for supporting the gnulib-defined O_NONBLOCK flag. + m4_ifdef([gl_NONBLOCKING_IO], [ + if test $REPLACE_OPEN = 0; then + gl_NONBLOCKING_IO + if test $gl_cv_have_open_O_NONBLOCK != yes; then + REPLACE_OPEN=1 + fi + fi + ]) +]) + +# Prerequisites of lib/open.c. +AC_DEFUN([gl_PREREQ_OPEN], +[ + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) + : +]) diff --git a/gl/m4/pathmax.m4 b/gl/m4/pathmax.m4 new file mode 100644 index 00000000..44add990 --- /dev/null +++ b/gl/m4/pathmax.m4 @@ -0,0 +1,42 @@ +# pathmax.m4 serial 11 +dnl Copyright (C) 2002-2003, 2005-2006, 2009-2022 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_PATHMAX], +[ + dnl Prerequisites of lib/pathmax.h. + AC_CHECK_HEADERS_ONCE([sys/param.h]) +]) + +# Expands to a piece of C program that defines PATH_MAX in the same way as +# "pathmax.h" will do. +AC_DEFUN([gl_PATHMAX_SNIPPET], [[ +/* Arrange to define PATH_MAX, like "pathmax.h" does. */ +#if HAVE_UNISTD_H +# include +#endif +#include +#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN +# include +#endif +#if !defined PATH_MAX && defined MAXPATHLEN +# define PATH_MAX MAXPATHLEN +#endif +#ifdef __hpux +# undef PATH_MAX +# define PATH_MAX 1024 +#endif +#if defined _WIN32 && ! defined __CYGWIN__ +# undef PATH_MAX +# define PATH_MAX 260 +#endif +]]) + +# Prerequisites of gl_PATHMAX_SNIPPET. +AC_DEFUN([gl_PATHMAX_SNIPPET_PREREQ], +[ + AC_CHECK_HEADERS_ONCE([unistd.h sys/param.h]) +]) diff --git a/gl/m4/pid_t.m4 b/gl/m4/pid_t.m4 new file mode 100644 index 00000000..cb26f361 --- /dev/null +++ b/gl/m4/pid_t.m4 @@ -0,0 +1,38 @@ +# pid_t.m4 serial 4 +dnl Copyright (C) 2020-2022 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. + +# The following implementation works around a problem in autoconf <= 2.69. +m4_version_prereq([2.70], [], [ + +dnl Define pid_t if the headers don't define it. +AC_DEFUN([AC_TYPE_PID_T], +[ + AC_CHECK_TYPE([pid_t], + [], + [dnl On 64-bit native Windows, define it to the equivalent of 'intptr_t' + dnl (= 'long long' = '__int64'), because that is the return type + dnl of the _spawnv* functions + dnl + dnl and the argument type of the _cwait function + dnl . + dnl Otherwise (on 32-bit Windows and on old Unix platforms), define it + dnl to 'int'. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #if defined _WIN64 && !defined __CYGWIN__ + LLP64 + #endif + ]]) + ], + [gl_pid_type='int'], + [gl_pid_type='__int64']) + AC_DEFINE_UNQUOTED([pid_t], [$gl_pid_type], + [Define as a signed integer type capable of holding a process identifier.]) + ], + [AC_INCLUDES_DEFAULT]) +]) + +])# m4_version_prereq 2.70 diff --git a/gl/m4/po.m4 b/gl/m4/po.m4 index 1c70b6c1..ace6f960 100644 --- a/gl/m4/po.m4 +++ b/gl/m4/po.m4 @@ -1,16 +1,16 @@ -# po.m4 serial 21 (gettext-0.18.3) -dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. +# po.m4 serial 31 (gettext-0.20.2) +dnl Copyright (C) 1995-2014, 2016, 2018-2022 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: @@ -30,7 +30,7 @@ AC_DEFUN([AM_PO_SUBDIRS], dnl Release version of the gettext macros. This is used to ensure that dnl the gettext macros and po/Makefile.in.in are in sync. - AC_SUBST([GETTEXT_MACRO_VERSION], [0.18]) + AC_SUBST([GETTEXT_MACRO_VERSION], [0.20]) dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. @@ -45,13 +45,6 @@ AC_DEFUN([AM_PO_SUBDIRS], AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) dnl Test whether it is GNU msgfmt >= 0.15. -changequote(,)dnl - case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; - *) MSGFMT_015=$MSGFMT ;; - esac -changequote([,])dnl - AC_SUBST([MSGFMT_015]) changequote(,)dnl case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; @@ -83,11 +76,21 @@ changequote([,])dnl AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) - dnl Installation directories. - dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we - dnl have to define it here, so that it can be used in po/Makefile. - test -n "$localedir" || localedir='${datadir}/locale' - AC_SUBST([localedir]) + dnl Test whether it is GNU msgmerge >= 0.20. + if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' + else + dnl Test whether it is GNU msgmerge >= 0.12. + if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' + else + dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is + dnl slow. But this is not a big problem, as such old gettext versions are + dnl hardly in use any more. + MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' + fi + fi + AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION]) dnl Support for AM_XGETTEXT_OPTION. test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= @@ -130,14 +133,11 @@ changequote([,])dnl if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) @@ -208,9 +208,8 @@ changequote([,])dnl esac done]], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it - # from automake < 1.5. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. + OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) @@ -311,15 +310,13 @@ changequote([,])dnl fi if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS. sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'` - ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"` + ALL_LINGUAS=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"` fi - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES @@ -329,9 +326,9 @@ changequote([,])dnl # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) # Compute PROPERTIESFILES - # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties) + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).properties) # Compute CLASSFILES - # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class) + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).class) # Compute QMFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm) # Compute MSGFILES @@ -356,8 +353,8 @@ changequote([,])dnl UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties" - CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class" + PROPERTIESFILES="$PROPERTIESFILES \$(srcdir)/\$(DOMAIN)_$lang.properties" + CLASSFILES="$CLASSFILES \$(srcdir)/\$(DOMAIN)_$lang.class" QMFILES="$QMFILES $srcdirpre$lang.qm" frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg" diff --git a/gl/m4/printf-posix.m4 b/gl/m4/printf-posix.m4 deleted file mode 100644 index d7dfb60f..00000000 --- a/gl/m4/printf-posix.m4 +++ /dev/null @@ -1,48 +0,0 @@ -# printf-posix.m4 serial 6 (gettext-0.18.2) -dnl Copyright (C) 2003, 2007, 2009-2013 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 From Bruno Haible. -dnl Test whether the printf() function supports POSIX/XSI format strings with -dnl positions. - -AC_DEFUN([gt_PRINTF_POSIX], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_CACHE_CHECK([whether printf() supports POSIX/XSI format strings], - gt_cv_func_printf_posix, - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* The string "%2$d %1$d", with dollar characters protected from the shell's - dollar expansion (possibly an autoconf bug). */ -static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; -static char buf[100]; -int main () -{ - sprintf (buf, format, 33, 55); - return (strcmp (buf, "55 33") != 0); -}]])], - [gt_cv_func_printf_posix=yes], - [gt_cv_func_printf_posix=no], - [ - AC_EGREP_CPP([notposix], [ -#if defined __NetBSD__ || defined __BEOS__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ - notposix -#endif - ], - [gt_cv_func_printf_posix="guessing no"], - [gt_cv_func_printf_posix="guessing yes"]) - ]) - ]) - case $gt_cv_func_printf_posix in - *yes) - AC_DEFINE([HAVE_POSIX_PRINTF], [1], - [Define if your printf() function supports format strings with positions.]) - ;; - esac -]) diff --git a/gl/m4/printf.m4 b/gl/m4/printf.m4 index ef44f785..667452e3 100644 --- a/gl/m4/printf.m4 +++ b/gl/m4/printf.m4 @@ -1,5 +1,5 @@ -# printf.m4 serial 50 -dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. +# printf.m4 serial 73 +dnl Copyright (C) 2003, 2007-2022 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. @@ -38,6 +38,8 @@ int main () if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0 || strcmp (buf, "12345671 33") != 0) result |= 1; +#else + result |= 1; #endif buf[0] = '\0'; if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0 @@ -56,13 +58,16 @@ int main () [gl_cv_func_printf_sizes_c99=yes], [gl_cv_func_printf_sizes_c99=no], [ -changequote(,)dnl case "$host_os" in +changequote(,)dnl # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_sizes_c99="guessing yes";; + *-gnu* | gnu*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_printf_sizes_c99="guessing yes";; # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_printf_sizes_c99="guessing no";; + freebsd[1-4].*) gl_cv_func_printf_sizes_c99="guessing no";; freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + midnightbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_printf_sizes_c99="guessing no";; darwin*) gl_cv_func_printf_sizes_c99="guessing yes";; @@ -77,10 +82,21 @@ changequote(,)dnl netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) gl_cv_func_printf_sizes_c99="guessing no";; netbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_sizes_c99="guessing no";; - esac + # Guess yes on Android. + linux*-android*) gl_cv_func_printf_sizes_c99="guessing yes";; changequote([,])dnl + # Guess yes on MSVC, no on mingw. + mingw*) AC_EGREP_CPP([Known], [ +#ifdef _MSC_VER + Known +#endif + ], + [gl_cv_func_printf_sizes_c99="guessing yes"], + [gl_cv_func_printf_sizes_c99="guessing no"]) + ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_sizes_c99="$gl_cross_guess_normal";; + esac ]) ]) ]) @@ -120,14 +136,22 @@ int main () }]])], [gl_cv_func_printf_long_double=yes], [gl_cv_func_printf_long_double=no], - [ -changequote(,)dnl - case "$host_os" in - beos*) gl_cv_func_printf_long_double="guessing no";; - mingw* | pw*) gl_cv_func_printf_long_double="guessing no";; - *) gl_cv_func_printf_long_double="guessing yes";; + [case "$host_os" in + # Guess no on BeOS. + beos*) gl_cv_func_printf_long_double="guessing no";; + # Guess yes on Android. + linux*-android*) gl_cv_func_printf_long_double="guessing yes";; + # Guess yes on MSVC, no on mingw. + mingw*) AC_EGREP_CPP([Known], [ +#ifdef _MSC_VER + Known +#endif + ], + [gl_cv_func_printf_long_double="guessing yes"], + [gl_cv_func_printf_long_double="guessing no"]) + ;; + *) gl_cv_func_printf_long_double="guessing yes";; esac -changequote([,])dnl ]) ]) ]) @@ -215,13 +239,16 @@ int main () [gl_cv_func_printf_infinite=yes], [gl_cv_func_printf_infinite=no], [ -changequote(,)dnl case "$host_os" in +changequote(,)dnl # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_infinite="guessing yes";; + *-gnu* | gnu*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_printf_infinite="guessing yes";; # Guess yes on FreeBSD >= 6. - freebsd[1-5]*) gl_cv_func_printf_infinite="guessing no";; + freebsd[1-5].*) gl_cv_func_printf_infinite="guessing no";; freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";; + midnightbsd*) gl_cv_func_printf_infinite="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_printf_infinite="guessing no";; darwin*) gl_cv_func_printf_infinite="guessing yes";; @@ -232,12 +259,26 @@ changequote(,)dnl netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) gl_cv_func_printf_infinite="guessing no";; netbsd*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on OpenBSD >= 6.0. + openbsd[1-5].*) gl_cv_func_printf_infinite="guessing no";; + openbsd*) gl_cv_func_printf_infinite="guessing yes";; # Guess yes on BeOS. beos*) gl_cv_func_printf_infinite="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_infinite="guessing no";; - esac + # Guess no on Android. + linux*-android*) gl_cv_func_printf_infinite="guessing no";; changequote([,])dnl + # Guess yes on MSVC, no on mingw. + mingw*) AC_EGREP_CPP([Known], [ +#ifdef _MSC_VER + Known +#endif + ], + [gl_cv_func_printf_infinite="guessing yes"], + [gl_cv_func_printf_infinite="guessing no"]) + ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_infinite="$gl_cross_guess_normal";; + esac ]) ]) ]) @@ -328,7 +369,7 @@ int main () # ifdef WORDS_BIGENDIAN # define LDBL80_WORDS(exponent,manthi,mantlo) \ { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ - ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ + ((unsigned int) (manthi) << 16) | ((unsigned int) (mantlo) >> 16), \ (unsigned int) (mantlo) << 16 \ } # else @@ -365,66 +406,51 @@ int main () { /* Pseudo-NaN. */ static union { unsigned int word[4]; long double value; } x = { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lf", x.value) <= 0) result |= 4; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Le", x.value) <= 0) result |= 4; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lg", x.value) <= 0) result |= 4; } { /* Pseudo-Infinity. */ static union { unsigned int word[4]; long double value; } x = { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lf", x.value) <= 0) result |= 8; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Le", x.value) <= 0) result |= 8; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lg", x.value) <= 0) result |= 8; } { /* Pseudo-Zero. */ static union { unsigned int word[4]; long double value; } x = { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lf", x.value) <= 0) result |= 16; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Le", x.value) <= 0) result |= 16; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lg", x.value) <= 0) result |= 16; } { /* Unnormalized number. */ static union { unsigned int word[4]; long double value; } x = { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lf", x.value) <= 0) result |= 32; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Le", x.value) <= 0) result |= 32; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lg", x.value) <= 0) result |= 32; } { /* Pseudo-Denormal. */ static union { unsigned int word[4]; long double value; } x = { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lf", x.value) <= 0) result |= 64; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Le", x.value) <= 0) result |= 64; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) + if (sprintf (buf, "%Lg", x.value) <= 0) result |= 64; } #endif @@ -432,27 +458,43 @@ int main () }]])], [gl_cv_func_printf_infinite_long_double=yes], [gl_cv_func_printf_infinite_long_double=no], - [ -changequote(,)dnl - case "$host_cpu" in + [case "$host_cpu" in # Guess no on ia64, x86_64, i386. ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";; *) case "$host_os" in +changequote(,)dnl # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_infinite_long_double="guessing yes";; + *-gnu* | gnu*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_printf_infinite_long_double="guessing yes";; # Guess yes on FreeBSD >= 6. - freebsd[1-5]*) gl_cv_func_printf_infinite_long_double="guessing no";; + freebsd[1-5].*) gl_cv_func_printf_infinite_long_double="guessing no";; freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + midnightbsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; # Guess yes on HP-UX >= 11. hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";; hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_infinite_long_double="guessing no";; + # Guess yes on OpenBSD >= 6.0. + openbsd[1-5].*) gl_cv_func_printf_infinite_long_double="guessing no";; + openbsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_infinite_long_double="guessing no";; +changequote([,])dnl + # Guess yes on MSVC, no on mingw. + mingw*) AC_EGREP_CPP([Known], [ +#ifdef _MSC_VER + Known +#endif + ], + [gl_cv_func_printf_infinite_long_double="guessing yes"], + [gl_cv_func_printf_infinite_long_double="guessing no"]) + ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_infinite_long_double="$gl_cross_guess_normal";; esac ;; esac -changequote([,])dnl ]) ]) ;; @@ -495,15 +537,22 @@ int main () && strcmp (buf, "-0X6.488P-1 33") != 0 && strcmp (buf, "-0XC.91P-2 33") != 0)) result |= 2; - /* This catches a FreeBSD 6.1 bug: it doesn't round. */ + /* This catches a FreeBSD 13.0 bug: it doesn't round. */ if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 || (strcmp (buf, "0x1.83p+0 33") != 0 && strcmp (buf, "0x3.05p-1 33") != 0 && strcmp (buf, "0x6.0ap-2 33") != 0 && strcmp (buf, "0xc.14p-3 33") != 0)) result |= 4; + /* This catches a Mac OS X 10.12.4 (Darwin 16.5) bug: it doesn't round. */ + if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0 + || (strcmp (buf, "0x2p+0 33") != 0 + && strcmp (buf, "0x3p-1 33") != 0 + && strcmp (buf, "0x6p-2 33") != 0 + && strcmp (buf, "0xcp-3 33") != 0)) + result |= 4; /* This catches a FreeBSD 6.1 bug. See - */ + */ if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0 || buf[0] == '0') result |= 8; @@ -515,7 +564,7 @@ int main () && strcmp (buf, "0x8.0p-2") != 0)) result |= 16; /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a - glibc 2.4 bug . */ + glibc 2.4 bug . */ if (sprintf (buf, "%.1La", 1.999L) < 0 || (strcmp (buf, "0x1.0p+1") != 0 && strcmp (buf, "0x2.0p+0") != 0 @@ -529,7 +578,7 @@ int main () [ case "$host_os" in # Guess yes on glibc >= 2.5 systems. - *-gnu*) + *-gnu* | gnu*) AC_EGREP_CPP([BZ2908], [ #include #ifdef __GNU_LIBRARY__ @@ -541,8 +590,14 @@ int main () [gl_cv_func_printf_directive_a="guessing yes"], [gl_cv_func_printf_directive_a="guessing no"]) ;; - # If we don't know, assume the worst. - *) gl_cv_func_printf_directive_a="guessing no";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_printf_directive_a="guessing yes";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_directive_a="guessing no";; + # Guess no on native Windows. + mingw*) gl_cv_func_printf_directive_a="guessing no";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_directive_a="$gl_cross_guess_normal";; esac ]) ]) @@ -583,23 +638,40 @@ int main () [gl_cv_func_printf_directive_f=yes], [gl_cv_func_printf_directive_f=no], [ -changequote(,)dnl case "$host_os" in +changequote(,)dnl # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_directive_f="guessing yes";; + *-gnu* | gnu*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_printf_directive_f="guessing yes";; # Guess yes on FreeBSD >= 6. - freebsd[1-5]*) gl_cv_func_printf_directive_f="guessing no";; + freebsd[1-5].*) gl_cv_func_printf_directive_f="guessing no";; freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";; + midnightbsd*) gl_cv_func_printf_directive_f="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_printf_directive_f="guessing no";; darwin*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on OpenBSD >= 6.0. + openbsd[1-5].*) gl_cv_func_printf_directive_f="guessing no";; + openbsd*) gl_cv_func_printf_directive_f="guessing yes";; # Guess yes on Solaris >= 2.10. - solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; - solaris*) gl_cv_func_printf_sizes_c99="guessing no";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_directive_f="guessing no";; - esac + solaris2.[1-9][0-9]*) gl_cv_func_printf_directive_f="guessing yes";; + solaris*) gl_cv_func_printf_directive_f="guessing no";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_directive_f="guessing no";; changequote([,])dnl + # Guess yes on MSVC, no on mingw. + mingw*) AC_EGREP_CPP([Known], [ +#ifdef _MSC_VER + Known +#endif + ], + [gl_cv_func_printf_directive_f="guessing yes"], + [gl_cv_func_printf_directive_f="guessing no"]) + ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_directive_f="$gl_cross_guess_normal";; + esac ]) ]) ]) @@ -621,7 +693,10 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_N], #include #include #ifdef _MSC_VER -/* See page about "Parameter Validation" on msdn.microsoft.com. */ +#include +/* See page about "Parameter Validation" on msdn.microsoft.com. + + */ static void cdecl invalid_parameter_handler (const wchar_t *expression, const wchar_t *function, @@ -651,13 +726,23 @@ int main () }]])], [gl_cv_func_printf_directive_n=yes], [gl_cv_func_printf_directive_n=no], - [ -changequote(,)dnl - case "$host_os" in - mingw*) gl_cv_func_printf_directive_n="guessing no";; - *) gl_cv_func_printf_directive_n="guessing yes";; + [case "$host_os" in + # Guess no on glibc when _FORTIFY_SOURCE >= 2. + *-gnu* | gnu*) AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if _FORTIFY_SOURCE >= 2 + error fail + #endif + ]])], + [gl_cv_func_printf_directive_n="guessing yes"], + [gl_cv_func_printf_directive_n="guessing no"]) + ;; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_directive_n="guessing no";; + # Guess no on native Windows. + mingw*) gl_cv_func_printf_directive_n="guessing no";; + *) gl_cv_func_printf_directive_n="guessing yes";; esac -changequote([,])dnl ]) ]) ]) @@ -678,13 +763,7 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_LS], [ AC_RUN_IFELSE( [AC_LANG_SOURCE([[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include #include -#include #include #include int main () @@ -732,11 +811,17 @@ int main () [ changequote(,)dnl case "$host_os" in - openbsd*) gl_cv_func_printf_directive_ls="guessing no";; + # Guess yes on OpenBSD >= 6.0. + openbsd[1-5].*) gl_cv_func_printf_directive_ls="guessing no";; + openbsd*) gl_cv_func_printf_directive_ls="guessing yes";; irix*) gl_cv_func_printf_directive_ls="guessing no";; solaris*) gl_cv_func_printf_directive_ls="guessing no";; cygwin*) gl_cv_func_printf_directive_ls="guessing no";; beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_directive_ls="guessing no";; + # Guess yes on native Windows. + mingw*) gl_cv_func_printf_directive_ls="guessing yes";; *) gl_cv_func_printf_directive_ls="guessing yes";; esac changequote([,])dnl @@ -774,10 +859,13 @@ int main () changequote(,)dnl case "$host_os" in netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*) - gl_cv_func_printf_positions="guessing no";; - beos*) gl_cv_func_printf_positions="guessing no";; - mingw* | pw*) gl_cv_func_printf_positions="guessing no";; - *) gl_cv_func_printf_positions="guessing yes";; + gl_cv_func_printf_positions="guessing no";; + beos*) gl_cv_func_printf_positions="guessing no";; + # Guess yes on Android. + linux*-android*) gl_cv_func_printf_positions="guessing yes";; + # Guess no on native Windows. + mingw* | pw*) gl_cv_func_printf_positions="guessing no";; + *) gl_cv_func_printf_positions="guessing yes";; esac changequote([,])dnl ]) @@ -812,10 +900,13 @@ int main () [ changequote(,)dnl case "$host_os" in - cygwin*) gl_cv_func_printf_flag_grouping="guessing no";; - netbsd*) gl_cv_func_printf_flag_grouping="guessing no";; - mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";; - *) gl_cv_func_printf_flag_grouping="guessing yes";; + cygwin*) gl_cv_func_printf_flag_grouping="guessing no";; + netbsd*) gl_cv_func_printf_flag_grouping="guessing no";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_flag_grouping="guessing no";; + # Guess no on native Windows. + mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";; + *) gl_cv_func_printf_flag_grouping="guessing yes";; esac changequote([,])dnl ]) @@ -824,7 +915,7 @@ changequote([,])dnl dnl Test whether the *printf family of functions supports the - flag correctly. dnl (ISO C99.) See -dnl +dnl dnl Result is gl_cv_func_printf_flag_leftadjust. AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST], @@ -852,12 +943,16 @@ int main () [ changequote(,)dnl case "$host_os" in - # Guess yes on HP-UX 11. - hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";; - # Guess no on HP-UX 10 and older. - hpux*) gl_cv_func_printf_flag_leftadjust="guessing no";; - # Guess yes otherwise. - *) gl_cv_func_printf_flag_leftadjust="guessing yes";; + # Guess yes on HP-UX 11. + hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";; + # Guess no on HP-UX 10 and older. + hpux*) gl_cv_func_printf_flag_leftadjust="guessing no";; + # Guess yes on Android. + linux*-android*) gl_cv_func_printf_flag_leftadjust="guessing yes";; + # Guess yes on native Windows. + mingw*) gl_cv_func_printf_flag_leftadjust="guessing yes";; + # Guess yes otherwise. + *) gl_cv_func_printf_flag_leftadjust="guessing yes";; esac changequote([,])dnl ]) @@ -866,7 +961,7 @@ changequote([,])dnl dnl Test whether the *printf family of functions supports padding of non-finite dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See -dnl +dnl dnl Result is gl_cv_func_printf_flag_zero. AC_DEFUN([gl_PRINTF_FLAG_ZERO], @@ -895,12 +990,18 @@ int main () [ changequote(,)dnl case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_printf_flag_zero="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_flag_zero="guessing no";; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_printf_flag_zero="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_printf_flag_zero="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_flag_zero="guessing yes";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_flag_zero="guessing no";; + # Guess no on native Windows. + mingw*) gl_cv_func_printf_flag_zero="guessing no";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_flag_zero="$gl_cross_guess_normal";; esac changequote([,])dnl ]) @@ -953,10 +1054,12 @@ int main () changequote(,)dnl case "$host_os" in # Guess no only on Solaris, native Windows, and BeOS systems. - solaris*) gl_cv_func_printf_precision="guessing no" ;; - mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; - beos*) gl_cv_func_printf_precision="guessing no" ;; - *) gl_cv_func_printf_precision="guessing yes" ;; + solaris*) gl_cv_func_printf_precision="guessing no" ;; + mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; + beos*) gl_cv_func_printf_precision="guessing no" ;; + # Guess yes on Android. + linux*-android*) gl_cv_func_printf_precision="guessing yes" ;; + *) gl_cv_func_printf_precision="guessing yes" ;; esac changequote([,])dnl ]) @@ -978,9 +1081,8 @@ AC_DEFUN([gl_PRINTF_ENOMEM], gl_cv_func_printf_enomem="guessing no" if test "$cross_compiling" = no; then if test $APPLE_UNIVERSAL_BUILD = 0; then - AC_LANG_CONFTEST([AC_LANG_SOURCE([ + AC_LANG_CONFTEST([AC_LANG_SOURCE([[ ]GL_NOCRASH[ -changequote(,)dnl #include #include #include @@ -1025,8 +1127,7 @@ int main() ret = printf ("%.5000000f", 1.0); return !(ret == 5000002 || (ret < 0 && errno == ENOMEM)); } -changequote([,])dnl - ])]) + ]])]) if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then (./conftest 2>&AS_MESSAGE_LOG_FD result=$? @@ -1053,28 +1154,30 @@ changequote([,])dnl if test "$gl_cv_func_printf_enomem" = "guessing no"; then changequote(,)dnl case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on Solaris. - solaris*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on AIX. - aix*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on HP-UX/hppa. - hpux*) case "$host_cpu" in - hppa*) gl_cv_func_printf_enomem="guessing yes";; - *) gl_cv_func_printf_enomem="guessing no";; - esac - ;; - # Guess yes on IRIX. - irix*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on OSF/1. - osf*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on Haiku. - haiku*) gl_cv_func_printf_enomem="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_enomem="guessing no";; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on Solaris. + solaris*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on AIX. + aix*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on HP-UX/hppa. + hpux*) case "$host_cpu" in + hppa*) gl_cv_func_printf_enomem="guessing yes";; + *) gl_cv_func_printf_enomem="guessing no";; + esac + ;; + # Guess yes on IRIX. + irix*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on OSF/1. + osf*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on Haiku. + haiku*) gl_cv_func_printf_enomem="guessing yes";; + # Guess no on Android. + linux*-android*) gl_cv_func_printf_enomem="guessing no";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_printf_enomem="$gl_cross_guess_normal";; esac changequote([,])dnl fi @@ -1093,7 +1196,7 @@ dnl Test whether the string produced by the snprintf function is always NUL dnl terminated. (ISO C99, POSIX:2001) dnl Result is gl_cv_func_snprintf_truncation_c99. -AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99], +AC_DEFUN_ONCE([gl_SNPRINTF_TRUNCATION_C99], [ AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles @@ -1134,10 +1237,13 @@ int main () changequote(,)dnl case "$host_os" in # Guess yes on glibc systems. - *-gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + *-gnu* | gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_snprintf_truncation_c99="guessing yes";; # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + freebsd[1-4].*) gl_cv_func_snprintf_truncation_c99="guessing no";; freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + midnightbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";; darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";; @@ -1166,8 +1272,12 @@ changequote(,)dnl netbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; # Guess yes on BeOS. beos*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_snprintf_truncation_c99="guessing no";; + # Guess yes on Android. + linux*-android*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess no on native Windows. + mingw*) gl_cv_func_snprintf_truncation_c99="guessing no";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_snprintf_truncation_c99="$gl_cross_guess_normal";; esac changequote([,])dnl ]) @@ -1229,14 +1339,16 @@ int main () }]])], [gl_cv_func_snprintf_retval_c99=yes], [gl_cv_func_snprintf_retval_c99=no], - [ + [case "$host_os" in changequote(,)dnl - case "$host_os" in # Guess yes on glibc systems. - *-gnu*) gl_cv_func_snprintf_retval_c99="guessing yes";; + *-gnu* | gnu*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_snprintf_retval_c99="guessing yes";; # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_snprintf_retval_c99="guessing no";; + freebsd[1-4].*) gl_cv_func_snprintf_retval_c99="guessing no";; freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + midnightbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_snprintf_retval_c99="guessing no";; darwin*) gl_cv_func_snprintf_retval_c99="guessing yes";; @@ -1256,10 +1368,21 @@ changequote(,)dnl netbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; # Guess yes on BeOS. beos*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_snprintf_retval_c99="guessing no";; - esac + # Guess yes on Android. + linux*-android*) gl_cv_func_snprintf_retval_c99="guessing yes";; changequote([,])dnl + # Guess yes on MSVC, no on mingw. + mingw*) AC_EGREP_CPP([Known], [ +#ifdef _MSC_VER + Known +#endif + ], + [gl_cv_func_snprintf_retval_c99="guessing yes"], + [gl_cv_func_snprintf_retval_c99="guessing no"]) + ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_snprintf_retval_c99="$gl_cross_guess_normal";; + esac ]) ]) ]) @@ -1311,13 +1434,24 @@ int main () [gl_cv_func_snprintf_directive_n=yes], [gl_cv_func_snprintf_directive_n=no], [ -changequote(,)dnl case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess no on glibc when _FORTIFY_SOURCE >= 2. + *-gnu* | gnu*) AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if _FORTIFY_SOURCE >= 2 + error fail + #endif + ]])], + [gl_cv_func_snprintf_directive_n="guessing yes"], + [gl_cv_func_snprintf_directive_n="guessing no"]) + ;; +changequote(,)dnl + # Guess yes on musl systems. + *-musl*) gl_cv_func_snprintf_directive_n="guessing yes";; # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_snprintf_directive_n="guessing no";; + freebsd[1-4].*) gl_cv_func_snprintf_directive_n="guessing no";; freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";; + midnightbsd*) gl_cv_func_snprintf_directive_n="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_snprintf_directive_n="guessing no";; darwin*) gl_cv_func_snprintf_directive_n="guessing yes";; @@ -1339,10 +1473,14 @@ changequote(,)dnl netbsd*) gl_cv_func_snprintf_directive_n="guessing yes";; # Guess yes on BeOS. beos*) gl_cv_func_snprintf_directive_n="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_snprintf_directive_n="guessing no";; - esac + # Guess no on Android. + linux*-android*) gl_cv_func_snprintf_directive_n="guessing no";; + # Guess no on native Windows. + mingw*) gl_cv_func_snprintf_directive_n="guessing no";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_snprintf_directive_n="$gl_cross_guess_normal";; changequote([,])dnl + esac ]) ]) ]) @@ -1355,6 +1493,7 @@ dnl Result is gl_cv_func_snprintf_size1. AC_DEFUN([gl_SNPRINTF_SIZE1], [ AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_REQUIRE([gl_SNPRINTF_PRESENCE]) AC_CACHE_CHECK([whether snprintf respects a size of 1], [gl_cv_func_snprintf_size1], @@ -1384,7 +1523,14 @@ int main() }]])], [gl_cv_func_snprintf_size1=yes], [gl_cv_func_snprintf_size1=no], - [gl_cv_func_snprintf_size1="guessing yes"]) + [case "$host_os" in + # Guess yes on Android. + linux*-android*) gl_cv_func_snprintf_size1="guessing yes" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_snprintf_size1="guessing yes" ;; + *) gl_cv_func_snprintf_size1="guessing yes" ;; + esac + ]) ]) ]) @@ -1456,10 +1602,13 @@ int main() changequote(,)dnl case "$host_os" in # Guess yes on glibc systems. - *-gnu*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + *-gnu* | gnu*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on musl systems. + *-musl*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + freebsd[1-4].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + midnightbsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; # Guess yes on Mac OS X >= 10.3. darwin[1-6].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; darwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; @@ -1480,10 +1629,12 @@ changequote(,)dnl netbsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; # Guess yes on BeOS. beos*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on mingw. + # Guess yes on Android. + linux*-android*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on native Windows. mingw* | pw*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_vsnprintf_zerosize_c99="$gl_cross_guess_normal";; esac changequote([,])dnl ]) @@ -1539,14 +1690,19 @@ dnl dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . . dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . . +dnl FreeBSD 13.0 . . . . # . . . . . . . . # . . . . . . dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . . +dnl Mac OS X 10.13.5 . . . # # . # . . . . . . . . . . # . . dnl Mac OS X 10.5.8 . . . # # . . . . . . # . . . . . . . . dnl Mac OS X 10.3.9 . . . . # . . . . . . # . # . . . . . . +dnl OpenBSD 6.0, 6.7 . . . . # . . . . . . . . # . . . . . . dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . . dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . . dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . . dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . . -dnl Solaris 11 2011-11 . . # # # . . # . . . # . . . . . . . . +dnl Solaris 11.4 . . # # # . . # . . . # . . . . . . . . +dnl Solaris 11.3 . . . . # . . # . . . . . . . . . . . . +dnl Solaris 11.0 . . # # # . . # . . . # . . . . . . . . dnl Solaris 10 . . # # # . . # . . . # # . . . . . . . dnl Solaris 2.6 ... 9 # . # # # # . # . . . # # . . . # . . . dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # # @@ -1559,11 +1715,13 @@ dnl HP-UX 10.20 # . # . # # . ? . . # # . . . dnl IRIX 6.5 # . # # # # . # . . . # . . . . # . . . dnl OSF/1 5.1 # . # # # # . . . . . # . . . . # . . # dnl OSF/1 4.0d # . # # # # . . . . . # . . # # # # # # +dnl NetBSD 9.0 . . . . # . . . . . . . . . . . . . . . dnl NetBSD 5.0 . . . # # . . . . . . # . # . . . . . . dnl NetBSD 4.0 . ? ? ? ? ? . ? . ? ? ? ? ? . . . ? ? ? dnl NetBSD 3.0 . . . . # # . ? # # ? # . # . . . . . . dnl Haiku . . . # # # . # . . . . . ? . . ? . . . dnl BeOS # # . # # # . ? # . ? . # ? . . ? . . . +dnl Android 4.3 . . # # # # # # . # . # . # . . . # . . dnl old mingw / msvcrt # # # # # # . . # # . # # ? . # # # . . dnl MSVC 9 # # # # # # # . # # . # # ? # # # # . . dnl mingw 2009-2011 . # . # . . . . # # . . . ? . . . . . . diff --git a/gl/m4/progtest.m4 b/gl/m4/progtest.m4 index 7b391232..4a5b0b4c 100644 --- a/gl/m4/progtest.m4 +++ b/gl/m4/progtest.m4 @@ -1,22 +1,22 @@ -# progtest.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1996-2003, 2005, 2008-2013 Free Software Foundation, Inc. +# progtest.m4 serial 9 (gettext-0.21.1) +dnl Copyright (C) 1996-2003, 2005, 2008-2022 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 -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Lesser General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. +dnl by the GNU Lesser General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. -AC_PREREQ([2.50]) +AC_PREREQ([2.53]) # Search path for a program which passes the given test. @@ -61,7 +61,7 @@ AC_CACHE_VAL([ac_cv_path_$1], ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in ifelse([$5], , $PATH, [$5]); do + for ac_dir in m4_if([$5], , $PATH, [$5]); do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do @@ -77,12 +77,12 @@ AC_CACHE_VAL([ac_cv_path_$1], IFS="$ac_save_IFS" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +m4_if([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then +if test m4_if([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$][$1]) else AC_MSG_RESULT([no]) diff --git a/gl/m4/pthread_rwlock_rdlock.m4 b/gl/m4/pthread_rwlock_rdlock.m4 new file mode 100644 index 00000000..8ad78392 --- /dev/null +++ b/gl/m4/pthread_rwlock_rdlock.m4 @@ -0,0 +1,185 @@ +# pthread_rwlock_rdlock.m4 serial 4 +dnl Copyright (C) 2017-2022 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 From Bruno Haible. +dnl Inspired by +dnl https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_rwlock_rdlock/2-2.c +dnl by Intel Corporation. + +dnl Test whether in a situation where +dnl - an rwlock is taken by a reader and has a writer waiting, +dnl - an additional reader requests the lock, +dnl - the waiting writer and the requesting reader threads have the same +dnl priority, +dnl the requesting reader thread gets blocked, so that at some point the +dnl waiting writer can acquire the lock. +dnl Without such a guarantee, when there a N readers and each of the readers +dnl spends more than 1/Nth of the time with the lock held, there is a high +dnl probability that the waiting writer will not get the lock in a given finite +dnl time, a phenomenon called "writer starvation". +dnl Without such a guarantee, applications have a hard time avoiding writer +dnl starvation. +dnl +dnl POSIX:2017 makes this requirement only for implementations that support TPS +dnl (Thread Priority Scheduling) and only for the scheduling policies SCHED_FIFO +dnl and SCHED_RR, see +dnl https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_rdlock.html +dnl but this test verifies the guarantee regardless of TPS and regardless of +dnl scheduling policy. +dnl Glibc does not provide this guarantee (and never will on Linux), see +dnl https://sourceware.org/bugzilla/show_bug.cgi?id=13701 +dnl https://bugzilla.redhat.com/show_bug.cgi?id=1410052 +AC_DEFUN([gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER], +[ + AC_REQUIRE([gl_THREADLIB_EARLY]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether pthread_rwlock_rdlock prefers a writer to a reader], + [gl_cv_pthread_rwlock_rdlock_prefer_writer], + [save_LIBS="$LIBS" + LIBS="$LIBS $LIBMULTITHREAD" + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#include + +#define SUCCEED() exit (0) +#define FAILURE() exit (1) +#define UNEXPECTED(n) (exit (10 + (n))) + +/* The main thread creates the waiting writer and the requesting reader threads + in the default way; this guarantees that they have the same priority. + We can reuse the main thread as first reader thread. */ + +static pthread_rwlock_t lock; +static pthread_t reader1; +static pthread_t writer; +static pthread_t reader2; +static pthread_t timer; +/* Used to pass control from writer to reader2 and from reader2 to timer, + as in a relay race. + Passing control from one running thread to another running thread + is most likely faster than to create the second thread. */ +static pthread_mutex_t baton; + +static void * +timer_func (void *ignored) +{ + /* Step 13 (can be before or after step 12): + The timer thread takes the baton, then waits a moment to make sure + it can tell whether the second reader thread is blocked at step 12. */ + if (pthread_mutex_lock (&baton)) + UNEXPECTED (13); + usleep (100000); + /* By the time we get here, it's clear that the second reader thread is + blocked at step 12. This is the desired behaviour. */ + SUCCEED (); +} + +static void * +reader2_func (void *ignored) +{ + int err; + + /* Step 8 (can be before or after step 7): + The second reader thread takes the baton, then waits a moment to make sure + the writer thread has reached step 7. */ + if (pthread_mutex_lock (&baton)) + UNEXPECTED (8); + usleep (100000); + /* Step 9: The second reader thread requests the lock. */ + err = pthread_rwlock_tryrdlock (&lock); + if (err == 0) + FAILURE (); + else if (err != EBUSY) + UNEXPECTED (9); + /* Step 10: Launch a timer, to test whether the next call blocks. */ + if (pthread_create (&timer, NULL, timer_func, NULL)) + UNEXPECTED (10); + /* Step 11: Release the baton. */ + if (pthread_mutex_unlock (&baton)) + UNEXPECTED (11); + /* Step 12: The second reader thread requests the lock. */ + err = pthread_rwlock_rdlock (&lock); + if (err == 0) + FAILURE (); + else + UNEXPECTED (12); +} + +static void * +writer_func (void *ignored) +{ + /* Step 4: Take the baton, so that the second reader thread does not go ahead + too early. */ + if (pthread_mutex_lock (&baton)) + UNEXPECTED (4); + /* Step 5: Create the second reader thread. */ + if (pthread_create (&reader2, NULL, reader2_func, NULL)) + UNEXPECTED (5); + /* Step 6: Release the baton. */ + if (pthread_mutex_unlock (&baton)) + UNEXPECTED (6); + /* Step 7: The writer thread requests the lock. */ + if (pthread_rwlock_wrlock (&lock)) + UNEXPECTED (7); + return NULL; +} + +int +main () +{ + reader1 = pthread_self (); + + /* Step 1: The main thread initializes the lock and the baton. */ + if (pthread_rwlock_init (&lock, NULL)) + UNEXPECTED (1); + if (pthread_mutex_init (&baton, NULL)) + UNEXPECTED (1); + /* Step 2: The main thread acquires the lock as a reader. */ + if (pthread_rwlock_rdlock (&lock)) + UNEXPECTED (2); + /* Step 3: Create the writer thread. */ + if (pthread_create (&writer, NULL, writer_func, NULL)) + UNEXPECTED (3); + /* Job done. Go to sleep. */ + for (;;) + { + sleep (1); + } +} +]])], + [gl_cv_pthread_rwlock_rdlock_prefer_writer=yes], + [gl_cv_pthread_rwlock_rdlock_prefer_writer=no], + [case "$host_os" in + # Guess no on glibc systems. + *-gnu* | gnu*) gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing no" ;; + # Guess no on musl systems. + *-musl*) gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing no" ;; + # Guess no on bionic systems. + *-android*) gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing no" ;; + # Guess yes on native Windows with the mingw-w64 winpthreads library. + # Guess no on native Windows with the gnulib windows-rwlock module. + mingw*) if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then + gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing yes" + else + gl_cv_pthread_rwlock_rdlock_prefer_writer="guessing no" + fi + ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_pthread_rwlock_rdlock_prefer_writer="$gl_cross_guess_normal" ;; + esac + ]) + LIBS="$save_LIBS" + ]) + case "$gl_cv_pthread_rwlock_rdlock_prefer_writer" in + *yes) + AC_DEFINE([HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER], [1], + [Define if the 'pthread_rwlock_rdlock' function prefers a writer to a reader.]) + ;; + esac +]) diff --git a/gl/m4/read.m4 b/gl/m4/read.m4 deleted file mode 100644 index 81f0f3a9..00000000 --- a/gl/m4/read.m4 +++ /dev/null @@ -1,26 +0,0 @@ -# read.m4 serial 4 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_READ], -[ - AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) - AC_REQUIRE([gl_MSVC_INVAL]) - if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then - REPLACE_READ=1 - fi - dnl This ifdef is just an optimization, to avoid performing a configure - dnl check whose result is not used. It does not make the test of - dnl GNULIB_UNISTD_H_NONBLOCKING or GNULIB_NONBLOCKING redundant. - m4_ifdef([gl_NONBLOCKING_IO], [ - gl_NONBLOCKING_IO - if test $gl_cv_have_nonblocking != yes; then - REPLACE_READ=1 - fi - ]) -]) - -# Prerequisites of lib/read.c. -AC_DEFUN([gl_PREREQ_READ], [:]) diff --git a/gl/m4/realloc.m4 b/gl/m4/realloc.m4 new file mode 100644 index 00000000..86e57c25 --- /dev/null +++ b/gl/m4/realloc.m4 @@ -0,0 +1,63 @@ +# realloc.m4 serial 26 +dnl Copyright (C) 2007, 2009-2022 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. + +# This is adapted with modifications from upstream Autoconf here: +# https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n1455 +AC_DEFUN([_AC_FUNC_REALLOC_IF], +[ + AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles + AC_CACHE_CHECK([whether realloc (0, 0) returns nonnull], + [ac_cv_func_realloc_0_nonnull], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[void *p = realloc (0, 0); + int result = !p; + free (p); + return result;]]) + ], + [ac_cv_func_realloc_0_nonnull=yes], + [ac_cv_func_realloc_0_nonnull=no], + [case "$host_os" in + # Guess yes on platforms where we know the result. + *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ + | gnu* | *-musl* | midnightbsd* \ + | hpux* | solaris* | cygwin* | mingw* | msys* ) + ac_cv_func_realloc_0_nonnull="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) ac_cv_func_realloc_0_nonnull="$gl_cross_guess_normal" ;; + esac + ]) + ]) + AS_CASE([$ac_cv_func_realloc_0_nonnull], [*yes], [$1], [$2]) +])# AC_FUNC_REALLOC + +# gl_FUNC_REALLOC_GNU +# ------------------- +# Replace realloc if it is not compatible with GNU libc. +AC_DEFUN([gl_FUNC_REALLOC_GNU], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_REALLOC_POSIX]) + if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then + _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC_FOR_REALLOC_GNU=1]) + fi +])# gl_FUNC_REALLOC_GNU + +# gl_FUNC_REALLOC_POSIX +# --------------------- +# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it +# fails, and doesn't mess up with ptrdiff_t overflow), +# and replace realloc if it is not. +AC_DEFUN([gl_FUNC_REALLOC_POSIX], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) + if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then + REPLACE_REALLOC_FOR_REALLOC_POSIX=1 + fi +]) diff --git a/gl/m4/reallocarray.m4 b/gl/m4/reallocarray.m4 new file mode 100644 index 00000000..f39ab6ea --- /dev/null +++ b/gl/m4/reallocarray.m4 @@ -0,0 +1,23 @@ +# reallocarray.m4 serial 3 +dnl Copyright (C) 2017-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_REALLOCARRAY], +[ + dnl Persuade glibc to declare reallocarray. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) + AC_CHECK_FUNCS([reallocarray]) + if test "$ac_cv_func_reallocarray" = no; then + HAVE_REALLOCARRAY=0 + elif test "$gl_cv_malloc_ptrdiff" = no; then + REPLACE_REALLOCARRAY=1 + fi +]) + +# Prerequisites of lib/reallocarray.c. +AC_DEFUN([gl_PREREQ_REALLOCARRAY], [:]) diff --git a/gl/m4/regex.m4 b/gl/m4/regex.m4 index 0945c11a..47342986 100644 --- a/gl/m4/regex.m4 +++ b/gl/m4/regex.m4 @@ -1,6 +1,6 @@ -# serial 64 +# serial 73 -# Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2022 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -13,6 +13,7 @@ AC_PREREQ([2.50]) AC_DEFUN([gl_REGEX], [ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_ARG_WITH([included-regex], [AS_HELP_STRING([--without-included-regex], [don't compile regex; this is the default on systems @@ -28,6 +29,7 @@ AC_DEFUN([gl_REGEX], # If cross compiling, assume the test would fail and use the included # regex.c. AC_CHECK_DECLS_ONCE([alarm]) + AC_CHECK_HEADERS_ONCE([malloc.h]) AC_CACHE_CHECK([for working re_compile_pattern], [gl_cv_func_re_compile_pattern_working], [AC_RUN_IFELSE( @@ -37,9 +39,19 @@ AC_DEFUN([gl_REGEX], #include #include #include - #if HAVE_DECL_ALARM - # include + + #if defined M_CHECK_ACTION || HAVE_DECL_ALARM # include + # include + #endif + + #if HAVE_MALLOC_H + # include + #endif + + #ifdef M_CHECK_ACTION + /* Exit with distinguishable exit code. */ + static void sigabrt_no_core (int sig) { raise (SIGTERM); } #endif ]], [[int result = 0; @@ -49,15 +61,22 @@ AC_DEFUN([gl_REGEX], const char *s; struct re_registers regs; + /* Some builds of glibc go into an infinite loop on this + test. Use alarm to force death, and mallopt to avoid + malloc recursion in diagnosing the corrupted heap. */ #if HAVE_DECL_ALARM - /* Some builds of glibc go into an infinite loop on this test. */ signal (SIGALRM, SIG_DFL); alarm (2); #endif +#ifdef M_CHECK_ACTION + signal (SIGABRT, sigabrt_no_core); + mallopt (M_CHECK_ACTION, 2); +#endif + if (setlocale (LC_ALL, "en_US.UTF-8")) { { - /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html + /* https://sourceware.org/ml/libc-hacker/2006-09/msg00008.html This test needs valgrind to catch the bug on Debian GNU/Linux 3.1 x86, but it might catch the bug better on other platforms and it shouldn't hurt to try the @@ -71,16 +90,20 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern (pat, sizeof pat - 1, ®ex); if (s) result |= 1; - else if (re_search (®ex, data, sizeof data - 1, - 0, sizeof data - 1, ®s) - != -1) - result |= 1; + else + { + if (re_search (®ex, data, sizeof data - 1, + 0, sizeof data - 1, ®s) + != -1) + result |= 1; + regfree (®ex); + } } { /* This test is from glibc bug 15078. The test case is from Andreas Schwab in - . + . */ static char const pat[] = "[^x]x"; static char const data[] = @@ -105,6 +128,7 @@ AC_DEFUN([gl_REGEX], 0, sizeof data - 1, 0); if (i != 0 && i != 21) result |= 1; + regfree (®ex); } } @@ -118,9 +142,13 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("a[^x]b", 6, ®ex); if (s) result |= 2; - /* This should fail, but succeeds for glibc-2.5. */ - else if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) - result |= 2; + else + { + /* This should fail, but succeeds for glibc-2.5. */ + if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) + result |= 2; + regfree (®ex); + } /* This regular expression is from Spencer ere test number 75 in grep-2.3. */ @@ -132,7 +160,10 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); /* This should fail with _Invalid character class name_ error. */ if (!s) - result |= 4; + { + result |= 4; + regfree (®ex); + } /* Ensure that [b-a] is diagnosed as invalid, when using RE_NO_EMPTY_RANGES. */ @@ -140,13 +171,18 @@ AC_DEFUN([gl_REGEX], memset (®ex, 0, sizeof regex); s = re_compile_pattern ("a[b-a]", 6, ®ex); if (s == 0) - result |= 8; + { + result |= 8; + regfree (®ex); + } /* This should succeed, but does not for glibc-2.1.3. */ memset (®ex, 0, sizeof regex); s = re_compile_pattern ("{1", 2, ®ex); if (s) result |= 8; + else + regfree (®ex); /* The following example is derived from a problem report against gawk from Jorge Stolfi . */ @@ -154,17 +190,35 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("[an\371]*n", 7, ®ex); if (s) result |= 8; - /* This should match, but does not for glibc-2.2.1. */ - else if (re_match (®ex, "an", 2, 0, ®s) != 2) - result |= 8; + else + { + /* This should match, but does not for glibc-2.2.1. */ + if (re_match (®ex, "an", 2, 0, ®s) != 2) + result |= 8; + else + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } memset (®ex, 0, sizeof regex); s = re_compile_pattern ("x", 1, ®ex); if (s) result |= 8; - /* glibc-2.2.93 does not work with a negative RANGE argument. */ - else if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) - result |= 8; + else + { + /* glibc-2.2.93 does not work with a negative RANGE argument. */ + if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) + result |= 8; + else + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } /* The version of regex.c in older versions of gnulib ignored RE_ICASE. Detect that problem too. */ @@ -173,25 +227,89 @@ AC_DEFUN([gl_REGEX], s = re_compile_pattern ("x", 1, ®ex); if (s) result |= 16; - else if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) - result |= 16; + else + { + if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) + result |= 16; + else + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } /* Catch a bug reported by Vin Shelton in - http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html + https://lists.gnu.org/r/bug-coreutils/2007-06/msg00089.html */ re_set_syntax (RE_SYNTAX_POSIX_BASIC & ~RE_CONTEXT_INVALID_DUP & ~RE_NO_EMPTY_RANGES); memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); + s = re_compile_pattern ("[[:alnum:]_-]\\\\+\$", 16, ®ex); if (s) result |= 32; + else + regfree (®ex); /* REG_STARTEND was added to glibc on 2004-01-15. Reject older versions. */ if (! REG_STARTEND) result |= 64; + /* Matching with the compiled form of this regexp would provoke + an assertion failure prior to glibc-2.28: + regexec.c:1375: pop_fail_stack: Assertion 'num >= 0' failed + With glibc-2.28, compilation fails and reports the invalid + back reference. */ + re_set_syntax (RE_SYNTAX_POSIX_EGREP); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("0|()0|\\\\1|0", 10, ®ex); + if (!s) + { + memset (®s, 0, sizeof regs); + i = re_search (®ex, "x", 1, 0, 1, ®s); + if (i != -1) + result |= 64; + if (0 <= i) + { + free (regs.start); + free (regs.end); + } + regfree (®ex); + } + else + { + if (strcmp (s, "Invalid back reference")) + result |= 64; + } + + /* glibc bug 11053. */ + re_set_syntax (RE_SYNTAX_POSIX_BASIC); + memset (®ex, 0, sizeof regex); + static char const pat_sub2[] = "\\\\(a*\\\\)*a*\\\\1"; + s = re_compile_pattern (pat_sub2, sizeof pat_sub2 - 1, ®ex); + if (s) + result |= 64; + else + { + memset (®s, 0, sizeof regs); + static char const data[] = "a"; + int datalen = sizeof data - 1; + i = re_search (®ex, data, datalen, 0, datalen, ®s); + if (i != 0) + result |= 64; + else if (regs.num_regs < 2) + result |= 64; + else if (! (regs.start[0] == 0 && regs.end[0] == 1)) + result |= 64; + else if (! (regs.start[1] == 0 && regs.end[1] == 0)) + result |= 64; + regfree (®ex); + free (regs.start); + free (regs.end); + } + #if 0 /* It would be nice to reject hosts whose regoff_t values are too narrow (including glibc on hosts with 64-bit ptrdiff_t and @@ -206,13 +324,19 @@ AC_DEFUN([gl_REGEX], return result; ]])], - [gl_cv_func_re_compile_pattern_working=yes], - [gl_cv_func_re_compile_pattern_working=no], - dnl When crosscompiling, assume it is not working. - [gl_cv_func_re_compile_pattern_working=no])]) - case $gl_cv_func_re_compile_pattern_working in #( - yes) ac_use_included_regex=no;; #( - no) ac_use_included_regex=yes;; + [gl_cv_func_re_compile_pattern_working=yes], + [gl_cv_func_re_compile_pattern_working=no], + [case "$host_os" in + # Guess no on native Windows. + mingw*) gl_cv_func_re_compile_pattern_working="guessing no" ;; + # Otherwise obey --enable-cross-guesses. + *) gl_cv_func_re_compile_pattern_working="$gl_cross_guess_normal" ;; + esac + ]) + ]) + case "$gl_cv_func_re_compile_pattern_working" in #( + *yes) ac_use_included_regex=no;; #( + *no) ac_use_included_regex=yes;; esac ;; *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) @@ -266,8 +390,7 @@ AC_DEFUN([gl_PREREQ_REGEX], AC_REQUIRE([AC_C_RESTRICT]) AC_REQUIRE([AC_TYPE_MBSTATE_T]) AC_REQUIRE([gl_EEMALLOC]) - AC_REQUIRE([gl_GLIBC21]) AC_CHECK_HEADERS([libintl.h]) - AC_CHECK_FUNCS_ONCE([isblank iswctype wcscoll]) + AC_CHECK_FUNCS_ONCE([isblank iswctype]) AC_CHECK_DECLS([isblank], [], [], [[#include ]]) ]) diff --git a/gl/m4/safe-read.m4 b/gl/m4/safe-read.m4 deleted file mode 100644 index be5207a5..00000000 --- a/gl/m4/safe-read.m4 +++ /dev/null @@ -1,12 +0,0 @@ -# safe-read.m4 serial 6 -dnl Copyright (C) 2002-2003, 2005-2006, 2009-2013 Free Software Foundation, -dnl 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. - -# Prerequisites of lib/safe-read.c. -AC_DEFUN([gl_PREREQ_SAFE_READ], -[ - AC_REQUIRE([gt_TYPE_SSIZE_T]) -]) diff --git a/gl/m4/servent.m4 b/gl/m4/servent.m4 index 01c037a8..c1b7d154 100644 --- a/gl/m4/servent.m4 +++ b/gl/m4/servent.m4 @@ -1,5 +1,5 @@ -# servent.m4 serial 2 -dnl Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. +# servent.m4 serial 4 +dnl Copyright (C) 2008, 2010-2022 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. @@ -10,12 +10,12 @@ AC_DEFUN([gl_SERVENT], dnl getservbyport() defined? dnl Where are getprotoent(), setprotoent(), endprotoent(), getprotobyname(), dnl getprotobynumber() defined? - dnl - On Solaris, they are in libsocket. Ignore libxnet. + dnl - On Solaris < 11.4, they are in libsocket. Ignore libxnet. dnl - On Haiku, they are in libnetwork. dnl - On BeOS, they are in libnet. dnl - On native Windows, they are in ws2_32.dll. dnl - Otherwise they are in libc. - AC_REQUIRE([gl_HEADER_SYS_SOCKET])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H + AC_REQUIRE([gl_SYS_SOCKET_H])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H SERVENT_LIB= gl_saved_libs="$LIBS" AC_SEARCH_LIBS([getservbyname], [socket network net], diff --git a/gl/m4/setenv.m4 b/gl/m4/setenv.m4 index cb5351a0..2000039a 100644 --- a/gl/m4/setenv.m4 +++ b/gl/m4/setenv.m4 @@ -1,5 +1,5 @@ -# setenv.m4 serial 26 -dnl Copyright (C) 2001-2004, 2006-2013 Free Software Foundation, Inc. +# setenv.m4 serial 30 +dnl Copyright (C) 2001-2004, 2006-2022 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. @@ -35,10 +35,12 @@ AC_DEFUN([gl_FUNC_SETENV], ]])], [gl_cv_func_setenv_works=yes], [gl_cv_func_setenv_works=no], [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_setenv_works="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_setenv_works="guessing no" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_setenv_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_setenv_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_setenv_works="$gl_cross_guess_normal" ;; esac ])]) case "$gl_cv_func_setenv_works" in @@ -104,35 +106,39 @@ int unsetenv (const char *name); dnl OpenBSD 4.7 unsetenv("") does not fail. AC_CACHE_CHECK([whether unsetenv obeys POSIX], [gl_cv_func_unsetenv_works], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - extern char **environ; - ]], [[ - char entry1[] = "a=1"; - char entry2[] = "b=2"; - char *env[] = { entry1, entry2, NULL }; - if (putenv ((char *) "a=1")) return 1; - if (putenv (entry2)) return 2; - entry2[0] = 'a'; - unsetenv ("a"); - if (getenv ("a")) return 3; - if (!unsetenv ("") || errno != EINVAL) return 4; - entry2[0] = 'b'; - environ = env; - if (!getenv ("a")) return 5; - entry2[0] = 'a'; - unsetenv ("a"); - if (getenv ("a")) return 6; - ]])], - [gl_cv_func_unsetenv_works=yes], [gl_cv_func_unsetenv_works=no], - [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_unsetenv_works="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_unsetenv_works="guessing no" ;; - esac - ])]) + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + extern char **environ; + ]GL_MDA_DEFINES], + [[ + char entry1[] = "a=1"; + char entry2[] = "b=2"; + char *env[] = { entry1, entry2, NULL }; + if (putenv ((char *) "a=1")) return 1; + if (putenv (entry2)) return 2; + entry2[0] = 'a'; + unsetenv ("a"); + if (getenv ("a")) return 3; + if (!unsetenv ("") || errno != EINVAL) return 4; + entry2[0] = 'b'; + environ = env; + if (!getenv ("a")) return 5; + entry2[0] = 'a'; + unsetenv ("a"); + if (getenv ("a")) return 6; + ]])], + [gl_cv_func_unsetenv_works=yes], + [gl_cv_func_unsetenv_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_unsetenv_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_unsetenv_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) case "$gl_cv_func_unsetenv_works" in *yes) ;; *) diff --git a/gl/m4/setlocale_null.m4 b/gl/m4/setlocale_null.m4 new file mode 100644 index 00000000..09ea50ea --- /dev/null +++ b/gl/m4/setlocale_null.m4 @@ -0,0 +1,98 @@ +# setlocale_null.m4 serial 5 +dnl Copyright (C) 2019-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_SETLOCALE_NULL], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_PTHREADLIB]) + AC_CHECK_HEADERS_ONCE([threads.h]) + + AC_CACHE_CHECK([whether setlocale (LC_ALL, NULL) is multithread-safe], + [gl_cv_func_setlocale_null_all_mtsafe], + [case "$host_os" in + # Guess no on musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin. + *-musl* | darwin* | freebsd* | midnightbsd* | netbsd* | openbsd* | aix* | haiku* | cygwin*) + gl_cv_func_setlocale_null_all_mtsafe=no ;; + # Guess yes on glibc, HP-UX, IRIX, Solaris, native Windows. + *-gnu* | gnu* | hpux* | irix* | solaris* | mingw*) + gl_cv_func_setlocale_null_all_mtsafe=yes ;; + # If we don't know, obey --enable-cross-guesses. + *) + gl_cv_func_setlocale_null_all_mtsafe="$gl_cross_guess_normal" ;; + esac + ]) + dnl On platforms without multithreading, there is no issue. + case "$host_os" in + mingw*) ;; + *) + if test $gl_pthread_api = no && test $ac_cv_header_threads_h = no; then + gl_cv_func_setlocale_null_all_mtsafe="trivially yes" + fi + ;; + esac + case "$gl_cv_func_setlocale_null_all_mtsafe" in + *yes) SETLOCALE_NULL_ALL_MTSAFE=1 ;; + *) SETLOCALE_NULL_ALL_MTSAFE=0 ;; + esac + AC_DEFINE_UNQUOTED([SETLOCALE_NULL_ALL_MTSAFE], [$SETLOCALE_NULL_ALL_MTSAFE], + [Define to 1 if setlocale (LC_ALL, NULL) is multithread-safe.]) + + dnl This is about a single category (not LC_ALL). + AC_CACHE_CHECK([whether setlocale (category, NULL) is multithread-safe], + [gl_cv_func_setlocale_null_one_mtsafe], + [case "$host_os" in + # Guess no on OpenBSD, AIX. + openbsd* | aix*) + gl_cv_func_setlocale_null_one_mtsafe=no ;; + # Guess yes on glibc, musl libc, macOS, FreeBSD, NetBSD, HP-UX, IRIX, Solaris, Haiku, Cygwin, native Windows. + *-gnu* | gnu* | *-musl* | darwin* | freebsd* | midnightbsd* | netbsd* | hpux* | irix* | solaris* | haiku* | cygwin* | mingw*) + gl_cv_func_setlocale_null_one_mtsafe=yes ;; + # If we don't know, obey --enable-cross-guesses. + *) + gl_cv_func_setlocale_null_one_mtsafe="$gl_cross_guess_normal" ;; + esac + ]) + dnl On platforms without multithreading, there is no issue. + case "$host_os" in + mingw*) ;; + *) + if test $gl_pthread_api = no && test $ac_cv_header_threads_h = no; then + gl_cv_func_setlocale_null_one_mtsafe="trivially yes" + fi + ;; + esac + case "$gl_cv_func_setlocale_null_one_mtsafe" in + *yes) SETLOCALE_NULL_ONE_MTSAFE=1 ;; + *) SETLOCALE_NULL_ONE_MTSAFE=0 ;; + esac + AC_DEFINE_UNQUOTED([SETLOCALE_NULL_ONE_MTSAFE], [$SETLOCALE_NULL_ONE_MTSAFE], + [Define to 1 if setlocale (category, NULL) is multithread-safe.]) + + dnl Determine link dependencies of lib/setlocale_null.c and lib/setlocale-lock.c. + if test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0; then + case "$host_os" in + mingw*) LIB_SETLOCALE_NULL= ;; + *) + gl_WEAK_SYMBOLS + case "$gl_cv_have_weak" in + *yes) LIB_SETLOCALE_NULL= ;; + *) LIB_SETLOCALE_NULL="$LIBPTHREAD" ;; + esac + ;; + esac + else + LIB_SETLOCALE_NULL= + fi + dnl LIB_SETLOCALE_NULL is expected to be '-pthread' or '-lpthread' on AIX + dnl with gcc or xlc, and empty otherwise. + AC_SUBST([LIB_SETLOCALE_NULL]) +]) + +# Prerequisites of lib/setlocale-lock.c. +AC_DEFUN([gl_PREREQ_SETLOCALE_LOCK], +[ + gl_VISIBILITY +]) diff --git a/gl/m4/sha1.m4 b/gl/m4/sha1.m4 index 21c775e3..0d7abc72 100644 --- a/gl/m4/sha1.m4 +++ b/gl/m4/sha1.m4 @@ -1,5 +1,5 @@ -# sha1.m4 serial 11 -dnl Copyright (C) 2002-2006, 2008-2013 Free Software Foundation, Inc. +# sha1.m4 serial 12 +dnl Copyright (C) 2002-2006, 2008-2022 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. @@ -8,5 +8,7 @@ AC_DEFUN([gl_SHA1], [ dnl Prerequisites of lib/sha1.c. AC_REQUIRE([gl_BIGENDIAN]) - : + + dnl Determine HAVE_OPENSSL_SHA1 and LIB_CRYPTO + gl_CRYPTO_CHECK([SHA1]) ]) diff --git a/gl/m4/size_max.m4 b/gl/m4/size_max.m4 index 4b247abc..1d6abaea 100644 --- a/gl/m4/size_max.m4 +++ b/gl/m4/size_max.m4 @@ -1,17 +1,19 @@ -# size_max.m4 serial 10 -dnl Copyright (C) 2003, 2005-2006, 2008-2013 Free Software Foundation, Inc. +# size_max.m4 serial 12 +dnl Copyright (C) 2003, 2005-2006, 2008-2022 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 From Bruno Haible. +AC_PREREQ([2.61]) + AC_DEFUN([gl_SIZE_MAX], [ AC_CHECK_HEADERS([stdint.h]) dnl First test whether the system already has SIZE_MAX. AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [ - gl_cv_size_max= + gl_cv_size_max=no AC_EGREP_CPP([Found it], [ #include #if HAVE_STDINT_H @@ -21,7 +23,7 @@ AC_DEFUN([gl_SIZE_MAX], Found it #endif ], [gl_cv_size_max=yes]) - if test -z "$gl_cv_size_max"; then + if test $gl_cv_size_max != yes; then dnl Define it ourselves. Here we assume that the type 'size_t' is not wider dnl than the type 'unsigned long'. Try hard to find a definition that can dnl be used in a preprocessor #if, i.e. doesn't contain a cast. @@ -71,9 +73,3 @@ Found it # undef SIZE_MAX #endif]) ]) - -dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. -dnl Remove this when we can assume autoconf >= 2.61. -m4_ifdef([AC_COMPUTE_INT], [], [ - AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) -]) diff --git a/gl/m4/snprintf.m4 b/gl/m4/snprintf.m4 index 3698e844..7420591c 100644 --- a/gl/m4/snprintf.m4 +++ b/gl/m4/snprintf.m4 @@ -1,5 +1,5 @@ -# snprintf.m4 serial 6 -dnl Copyright (C) 2002-2004, 2007-2013 Free Software Foundation, Inc. +# snprintf.m4 serial 7 +dnl Copyright (C) 2002-2004, 2007-2022 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. @@ -46,6 +46,14 @@ AC_DEFUN([gl_REPLACE_SNPRINTF], AC_LIBOBJ([snprintf]) if test $ac_cv_func_snprintf = yes; then REPLACE_SNPRINTF=1 + else + AC_CHECK_DECLS_ONCE([snprintf]) + if test $ac_cv_have_decl_snprintf = yes; then + dnl If the function is declared but does not appear to exist, it may be + dnl defined as an inline function. In order to avoid a conflict, we have + dnl to define rpl_snprintf, not snprintf. + REPLACE_SNPRINTF=1 + fi fi gl_PREREQ_SNPRINTF ]) diff --git a/gl/m4/socketlib.m4 b/gl/m4/socketlib.m4 index b08a72f6..b8bd0afa 100644 --- a/gl/m4/socketlib.m4 +++ b/gl/m4/socketlib.m4 @@ -1,5 +1,5 @@ -# socketlib.m4 serial 1 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +# socketlib.m4 serial 3 +dnl Copyright (C) 2008-2022 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. @@ -14,21 +14,27 @@ AC_DEFUN([gl_SOCKETLIB], LIBSOCKET= if test $HAVE_WINSOCK2_H = 1; then dnl Native Windows API (not Cygwin). - AC_CACHE_CHECK([if we need to call WSAStartup in winsock2.h and -lws2_32], - [gl_cv_func_wsastartup], [ - gl_save_LIBS="$LIBS" - LIBS="$LIBS -lws2_32" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + dnl If the function WSAStartup exists (declared in and + dnl defined through -lws2_32), we need to call it. + AC_CACHE_CHECK([for WSAStartup], + [gl_cv_func_wsastartup], [ + gl_save_LIBS="$LIBS" + LIBS="$LIBS -lws2_32" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #ifdef HAVE_WINSOCK2_H # include #endif]], [[ - WORD wVersionRequested = MAKEWORD(1, 1); - WSADATA wsaData; - int err = WSAStartup(wVersionRequested, &wsaData); - WSACleanup ();]])], - gl_cv_func_wsastartup=yes, gl_cv_func_wsastartup=no) - LIBS="$gl_save_LIBS" - ]) + WORD wVersionRequested = MAKEWORD(1, 1); + WSADATA wsaData; + int err = WSAStartup(wVersionRequested, &wsaData); + WSACleanup (); + ]]) + ], + [gl_cv_func_wsastartup=yes], + [gl_cv_func_wsastartup=no]) + LIBS="$gl_save_LIBS" + ]) if test "$gl_cv_func_wsastartup" = "yes"; then AC_DEFINE([WINDOWS_SOCKETS], [1], [Define if WSAStartup is needed.]) LIBSOCKET='-lws2_32' @@ -38,6 +44,10 @@ AC_DEFUN([gl_SOCKETLIB], dnl Solaris has most socket functions in libsocket. dnl Haiku has most socket functions in libnetwork. dnl BeOS has most socket functions in libnet. + dnl On HP-UX, do NOT link with libxnet, because in 64-bit mode this would + dnl break code (e.g. in libraries) that invokes accept(), getpeername(), + dnl getsockname(), getsockopt(), or recvfrom() with a 32-bit addrlen. See + dnl "man xopen_networking" for details. AC_CACHE_CHECK([for library containing setsockopt], [gl_cv_lib_socket], [ gl_cv_lib_socket= AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern diff --git a/gl/m4/sockets.m4 b/gl/m4/sockets.m4 index b407391c..aa04acc3 100644 --- a/gl/m4/sockets.m4 +++ b/gl/m4/sockets.m4 @@ -1,5 +1,5 @@ # sockets.m4 serial 7 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2008-2022 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. diff --git a/gl/m4/socklen.m4 b/gl/m4/socklen.m4 index e3efd6ef..1390ac41 100644 --- a/gl/m4/socklen.m4 +++ b/gl/m4/socklen.m4 @@ -1,5 +1,5 @@ -# socklen.m4 serial 10 -dnl Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. +# socklen.m4 serial 11 +dnl Copyright (C) 2005-2007, 2009-2022 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. @@ -15,8 +15,8 @@ dnl So we have to test to find something that will work. AC_DEFUN([gl_TYPE_SOCKLEN_T], [AC_REQUIRE([gl_CHECK_SOCKET_HEADERS])dnl AC_CHECK_TYPE([socklen_t], , - [AC_MSG_CHECKING([for socklen_t equivalent]) - AC_CACHE_VAL([gl_cv_socklen_t_equiv], + [AC_CACHE_CHECK([for socklen_t equivalent], + [gl_cv_socklen_t_equiv], [# Systems have either "struct sockaddr *" or # "void *" as the second argument to getpeername gl_cv_socklen_t_equiv= @@ -34,11 +34,10 @@ AC_DEFUN([gl_TYPE_SOCKLEN_T], done test "$gl_cv_socklen_t_equiv" != "" && break done - ]) - if test "$gl_cv_socklen_t_equiv" = ""; then - AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) - fi - AC_MSG_RESULT([$gl_cv_socklen_t_equiv]) + if test "$gl_cv_socklen_t_equiv" = ""; then + AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) + fi + ]) AC_DEFINE_UNQUOTED([socklen_t], [$gl_cv_socklen_t_equiv], [type to use in place of socklen_t if not defined])], [gl_SOCKET_HEADERS])]) diff --git a/gl/m4/sockpfaf.m4 b/gl/m4/sockpfaf.m4 index 89557b18..b1c4068a 100644 --- a/gl/m4/sockpfaf.m4 +++ b/gl/m4/sockpfaf.m4 @@ -1,5 +1,5 @@ -# sockpfaf.m4 serial 8 -dnl Copyright (C) 2004, 2006, 2009-2013 Free Software Foundation, Inc. +# sockpfaf.m4 serial 10 +dnl Copyright (C) 2004, 2006, 2009-2022 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. @@ -13,11 +13,11 @@ dnl From Bruno Haible. AC_DEFUN([gl_SOCKET_FAMILIES], [ - AC_REQUIRE([gl_HEADER_SYS_SOCKET]) + AC_REQUIRE([gl_SYS_SOCKET_H]) AC_CHECK_HEADERS_ONCE([netinet/in.h]) - AC_MSG_CHECKING([for IPv4 sockets]) - AC_CACHE_VAL([gl_cv_socket_ipv4], + AC_CACHE_CHECK([for IPv4 sockets], + [gl_cv_socket_ipv4], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #ifdef HAVE_SYS_SOCKET_H #include @@ -31,13 +31,12 @@ AC_DEFUN([gl_SOCKET_FAMILIES], [[int x = AF_INET; struct in_addr y; struct sockaddr_in z; if (&x && &y && &z) return 0;]])], gl_cv_socket_ipv4=yes, gl_cv_socket_ipv4=no)]) - AC_MSG_RESULT([$gl_cv_socket_ipv4]) if test $gl_cv_socket_ipv4 = yes; then AC_DEFINE([HAVE_IPV4], [1], [Define to 1 if defines AF_INET.]) fi - AC_MSG_CHECKING([for IPv6 sockets]) - AC_CACHE_VAL([gl_cv_socket_ipv6], + AC_CACHE_CHECK([for IPv6 sockets], + [gl_cv_socket_ipv6], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #ifdef HAVE_SYS_SOCKET_H #include @@ -54,7 +53,6 @@ AC_DEFUN([gl_SOCKET_FAMILIES], [[int x = AF_INET6; struct in6_addr y; struct sockaddr_in6 z; if (&x && &y && &z) return 0;]])], gl_cv_socket_ipv6=yes, gl_cv_socket_ipv6=no)]) - AC_MSG_RESULT([$gl_cv_socket_ipv6]) if test $gl_cv_socket_ipv6 = yes; then AC_DEFINE([HAVE_IPV6], [1], [Define to 1 if defines AF_INET6.]) fi @@ -62,11 +60,11 @@ AC_DEFUN([gl_SOCKET_FAMILIES], AC_DEFUN([gl_SOCKET_FAMILY_UNIX], [ - AC_REQUIRE([gl_HEADER_SYS_SOCKET]) + AC_REQUIRE([gl_SYS_SOCKET_H]) AC_CHECK_HEADERS_ONCE([sys/un.h]) - AC_MSG_CHECKING([for UNIX domain sockets]) - AC_CACHE_VAL([gl_cv_socket_unix], + AC_CACHE_CHECK([for UNIX domain sockets], + [gl_cv_socket_unix], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #ifdef HAVE_SYS_SOCKET_H #include @@ -80,7 +78,6 @@ AC_DEFUN([gl_SOCKET_FAMILY_UNIX], [[int x = AF_UNIX; struct sockaddr_un y; if (&x && &y) return 0;]])], gl_cv_socket_unix=yes, gl_cv_socket_unix=no)]) - AC_MSG_RESULT([$gl_cv_socket_unix]) if test $gl_cv_socket_unix = yes; then AC_DEFINE([HAVE_UNIXSOCKET], [1], [Define to 1 if defines AF_UNIX.]) fi diff --git a/gl/m4/ssize_t.m4 b/gl/m4/ssize_t.m4 index 63381343..03b2b895 100644 --- a/gl/m4/ssize_t.m4 +++ b/gl/m4/ssize_t.m4 @@ -1,5 +1,5 @@ # ssize_t.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2001-2003, 2006, 2010-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2001-2003, 2006, 2010-2022 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. diff --git a/gl/m4/stat-time.m4 b/gl/m4/stat-time.m4 new file mode 100644 index 00000000..342857d3 --- /dev/null +++ b/gl/m4/stat-time.m4 @@ -0,0 +1,83 @@ +# Checks for stat-related time functions. + +# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2022 Free Software +# Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# st_atim.tv_nsec - Linux, Solaris, Cygwin +# st_atimespec.tv_nsec - FreeBSD, NetBSD, if ! defined _POSIX_SOURCE +# st_atimensec - FreeBSD, NetBSD, if defined _POSIX_SOURCE +# st_atim.st__tim.tv_nsec - UnixWare (at least 2.1.2 through 7.1) + +# st_birthtimespec - FreeBSD, NetBSD (hidden on OpenBSD 3.9, anyway) +# st_birthtim - Cygwin 1.7.0+ + +AC_DEFUN([gl_STAT_TIME], +[ + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_HEADERS_ONCE([sys/time.h]) + + AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec], + [AC_CACHE_CHECK([whether struct stat.st_atim is of type struct timespec], + [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ + #include + #include + #if HAVE_SYS_TIME_H + # include + #endif + #include + struct timespec ts; + struct stat st; + ]], + [[ + st.st_atim = ts; + ]])], + [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=yes], + [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=no])]) + if test $ac_cv_typeof_struct_stat_st_atim_is_struct_timespec = yes; then + AC_DEFINE([TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC], [1], + [Define to 1 if the type of the st_atim member of a struct stat is + struct timespec.]) + fi], + [AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec], [], + [AC_CHECK_MEMBERS([struct stat.st_atimensec], [], + [AC_CHECK_MEMBERS([struct stat.st_atim.st__tim.tv_nsec], [], [], + [#include + #include ])], + [#include + #include ])], + [#include + #include ])], + [#include + #include ]) +]) + +# Check for st_birthtime, a feature from UFS2 (FreeBSD, NetBSD, OpenBSD, etc.) +# and NTFS (Cygwin). +# There was a time when this field was named st_createtime (21 June +# 2002 to 16 July 2002) But that window is very small and applied only +# to development code, so systems still using that configuration are +# not supported. See revisions 1.10 and 1.11 of FreeBSD's +# src/sys/ufs/ufs/dinode.h. +# +AC_DEFUN([gl_STAT_BIRTHTIME], +[ + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_HEADERS_ONCE([sys/time.h]) + AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec], [], + [AC_CHECK_MEMBERS([struct stat.st_birthtimensec], [], + [AC_CHECK_MEMBERS([struct stat.st_birthtim.tv_nsec], [], [], + [#include + #include ])], + [#include + #include ])], + [#include + #include ]) +]) diff --git a/gl/m4/stat.m4 b/gl/m4/stat.m4 new file mode 100644 index 00000000..916eb886 --- /dev/null +++ b/gl/m4/stat.m4 @@ -0,0 +1,85 @@ +# serial 18 + +# Copyright (C) 2009-2022 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STAT], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([lstat]) + case "$host_os" in + mingw*) + dnl On this platform, the original stat() returns st_atime, st_mtime, + dnl st_ctime values that are affected by the time zone. + REPLACE_STAT=1 + ;; + *) + dnl AIX 7.1, Solaris 9, mingw64 mistakenly succeed on stat("file/"). + dnl (For mingw, this is due to a broken stat() override in libmingwex.a.) + dnl FreeBSD 7.2 mistakenly succeeds on stat("link-to-file/"). + AC_CACHE_CHECK([whether stat handles trailing slashes on files], + [gl_cv_func_stat_file_slash], + [touch conftest.tmp + # Assume that if we have lstat, we can also check symlinks. + if test $ac_cv_func_lstat = yes; then + ln -s conftest.tmp conftest.lnk + fi + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include +]], [[int result = 0; + struct stat st; + if (!stat ("conftest.tmp/", &st)) + result |= 1; +#if HAVE_LSTAT + if (!stat ("conftest.lnk/", &st)) + result |= 2; +#endif + return result; + ]])], + [gl_cv_func_stat_file_slash=yes], [gl_cv_func_stat_file_slash=no], + [case "$host_os" in + # Guess yes on Linux systems. + linux-* | linux) gl_cv_func_stat_file_slash="guessing yes" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_stat_file_slash="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_stat_file_slash="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.tmp conftest.lnk]) + case $gl_cv_func_stat_file_slash in + *no) + REPLACE_STAT=1 + AC_DEFINE([REPLACE_FUNC_STAT_FILE], [1], [Define to 1 if stat needs + help when passed a file name with a trailing slash]);; + esac + case $host_os in + dnl Solaris stat can return a negative tv_nsec. + solaris*) + REPLACE_FSTAT=1 ;; + esac + ;; + esac +]) + +# Prerequisites of lib/stat.c and lib/stat-w32.c. +AC_DEFUN([gl_PREREQ_STAT], [ + AC_REQUIRE([gl_SYS_STAT_H]) + AC_REQUIRE([gl_PREREQ_STAT_W32]) + : +]) + +# Prerequisites of lib/stat-w32.c. +AC_DEFUN([gl_PREREQ_STAT_W32], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) + AC_CHECK_HEADERS([sdkddkver.h]) + ;; + esac +]) diff --git a/gl/m4/std-gnu11.m4 b/gl/m4/std-gnu11.m4 new file mode 100644 index 00000000..5ca18607 --- /dev/null +++ b/gl/m4/std-gnu11.m4 @@ -0,0 +1,829 @@ +# Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*- + +# This implementation is taken from GNU Autoconf lib/autoconf/c.m4 +# commit 017d5ddd82854911f0119691d91ea8a1438824d6 +# dated Sun Apr 3 13:57:17 2016 -0700 +# This implementation will be obsolete once we can assume Autoconf 2.70 +# or later is installed everywhere a Gnulib program might be developed. + +m4_version_prereq([2.70], [], [ + + +# Copyright (C) 2001-2022 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 . + +# Written by David MacKenzie, with help from +# Akim Demaille, Paul Eggert, +# François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, +# Roland McGrath, Noah Friedman, david d zuhn, and many others. + + +# AC_PROG_CC([COMPILER ...]) +# -------------------------- +# COMPILER ... is a space separated list of C compilers to search for. +# This just gives the user an opportunity to specify an alternative +# search list for the C compiler. +AC_DEFUN_ONCE([AC_PROG_CC], +[AC_LANG_PUSH(C)dnl +AC_ARG_VAR([CC], [C compiler command])dnl +AC_ARG_VAR([CFLAGS], [C compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +_AC_ARG_VAR_LIBS()dnl +_AC_ARG_VAR_CPPFLAGS()dnl +m4_ifval([$1], + [AC_CHECK_TOOLS(CC, [$1])], +[AC_CHECK_TOOL(CC, gcc) +if test -z "$CC"; then + dnl Here we want: + dnl AC_CHECK_TOOL(CC, cc) + dnl but without the check for a tool without the prefix. + dnl Until the check is removed from there, copy the code: + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc]) + fi +fi +if test -z "$CC"; then + AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) +fi +if test -z "$CC"; then + AC_CHECK_TOOLS(CC, cl.exe) +fi +if test -z "$CC"; then + AC_CHECK_TOOL(CC, clang) +fi +]) + +test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH]) + +# Provide some information about the compiler. +_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 + _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) +done + +m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl +m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl +_AC_LANG_COMPILER_GNU +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +_AC_PROG_CC_G +dnl +dnl Set ac_prog_cc_stdc to the supported C version. +dnl Also set the documented variable ac_cv_prog_cc_stdc; +dnl its name was chosen when it was cached, but it is no longer cached. +_AC_PROG_CC_C11([ac_prog_cc_stdc=c11 + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11], + [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99 + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99], + [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89 + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89], + [ac_prog_cc_stdc=no + ac_cv_prog_cc_stdc=no])])]) +dnl +AC_LANG_POP(C)dnl +])# AC_PROG_CC + + + +# AC_PROG_CXX([LIST-OF-COMPILERS]) +# -------------------------------- +# LIST-OF-COMPILERS is a space separated list of C++ compilers to search +# for (if not specified, a default list is used). This just gives the +# user an opportunity to specify an alternative search list for the C++ +# compiler. +# aCC HP-UX C++ compiler much better than `CC', so test before. +# FCC Fujitsu C++ compiler +# KCC KAI C++ compiler +# RCC Rational C++ +# xlC_r AIX C Set++ (with support for reentrant code) +# xlC AIX C Set++ +AC_DEFUN([AC_PROG_CXX], +[AC_LANG_PUSH(C++)dnl +AC_ARG_VAR([CXX], [C++ compiler command])dnl +AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +_AC_ARG_VAR_LIBS()dnl +_AC_ARG_VAR_CPPFLAGS()dnl +_AC_ARG_VAR_PRECIOUS([CCC])dnl +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + AC_CHECK_TOOLS(CXX, + [m4_default([$1], + [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])], + g++) + fi +fi +# Provide some information about the compiler. +_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 + _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) +done + +m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl +m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl +_AC_LANG_COMPILER_GNU +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +_AC_PROG_CXX_G +_AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11 + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11], + [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98 + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98], + [ac_prog_cxx_stdcxx=no + ac_cv_prog_cxx_stdcxx=no])]) +AC_LANG_POP(C++)dnl +])# AC_PROG_CXX + + +# _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, +# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) +# -------------------------------------------------------------- +# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') +# by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, +# try again with each compiler option in the space-separated OPTION-LIST; if one +# helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, +# else ACTION-IF-UNAVAILABLE. +AC_DEFUN([_AC_C_STD_TRY], +[AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features]) +AC_CACHE_VAL(ac_cv_prog_cc_$1, +[ac_cv_prog_cc_$1=no +ac_save_CC=$CC +AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) +for ac_arg in '' $4 +do + CC="$ac_save_CC $ac_arg" + _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) + test "x$ac_cv_prog_cc_$1" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +])# AC_CACHE_VAL +ac_prog_cc_stdc_options= +case "x$ac_cv_prog_cc_$1" in + x) + AC_MSG_RESULT([none needed]) ;; + xno) + AC_MSG_RESULT([unsupported]) ;; + *) + ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1" + CC=$CC$ac_prog_cc_stdc_options + AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; +esac +AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) +])# _AC_C_STD_TRY + +# _AC_C_C99_TEST_HEADER +# --------------------- +# A C header suitable for testing for C99. +AC_DEFUN([_AC_C_C99_TEST_HEADER], +[[#include +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +}]])# _AC_C_C99_TEST_HEADER + +# _AC_C_C99_TEST_BODY +# ------------------- +# A C body suitable for testing for C99, assuming the corresponding header. +AC_DEFUN([_AC_C_C99_TEST_BODY], +[[ + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); +]]) + +# _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) +# ---------------------------------------------------------------- +# If the C compiler is not in ISO C99 mode by default, try to add an +# option to output variable CC to make it so. This macro tries +# various options that select ISO C99 on some system or another. It +# considers the compiler to be in ISO C99 mode if it handles _Bool, +# // comments, flexible array members, inline, long long int, mixed +# code and declarations, named initialization of structs, restrict, +# va_copy, varargs macros, variable declarations in for loops and +# variable length arrays. +AC_DEFUN([_AC_PROG_CC_C99], +[_AC_C_STD_TRY([c99], +[_AC_C_C99_TEST_HEADER], +[_AC_C_C99_TEST_BODY], +dnl Try +dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) +dnl IBM XL C -qlanglvl=extc1x (V12.1; does not pass C11 test) +dnl IBM XL C -qlanglvl=extc99 +dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdc99) +dnl HP cc -AC99 +dnl Intel ICC -std=c99, -c99 (deprecated) +dnl IRIX -c99 +dnl Solaris -D_STDC_C99= +dnl cc's -xc99 option uses linker magic to define the external +dnl symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99 +dnl behavior for C library functions. This is not wanted here, +dnl because it means that a single module compiled with -xc99 +dnl alters C runtime behavior for the entire program, not for +dnl just the module. Instead, define the (private) symbol +dnl _STDC_C99, which suppresses a bogus failure in . +dnl The resulting compiler passes the test case here, and that's +dnl good enough. For more, please see the thread starting at: +dnl https://lists.gnu.org/r/autoconf/2010-12/msg00059.html +dnl Tru64 -c99 +dnl with extended modes being tried first. +[[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl +])# _AC_PROG_CC_C99 + + +# _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) +# ---------------------------------------------------------------- +# If the C compiler is not in ISO C11 mode by default, try to add an +# option to output variable CC to make it so. This macro tries +# various options that select ISO C11 on some system or another. It +# considers the compiler to be in ISO C11 mode if it handles _Alignas, +# _Alignof, _Noreturn, _Static_assert, UTF-8 string literals, +# duplicate typedefs, and anonymous structures and unions. +AC_DEFUN([_AC_PROG_CC_C11], +[_AC_C_STD_TRY([c11], +[_AC_C_C99_TEST_HEADER[ +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +]], +[_AC_C_C99_TEST_BODY[ + v1.i = 2; + v1.w.k = 5; + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); +]], +dnl Try +dnl GCC -std=gnu11 (unused restrictive mode: -std=c11) +dnl with extended modes being tried first. +dnl +dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as +dnl of September 2012) does not pass the C11 test. For now, try extc1x when +dnl compiling the C99 test instead, since it enables _Static_assert and +dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes +dnl the C11 test in some future version of IBM XL C, we'll add it here, +dnl preferably extc11. +[[-std=gnu11]], [$1], [$2])[]dnl +])# _AC_PROG_CC_C11 + + +# AC_PROG_CC_C89 +# -------------- +# Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC, +# as that'd be incompatible with how Automake redefines AC_PROG_CC. See +# . +AU_DEFUN([AC_PROG_CC_C89], + [AC_REQUIRE([AC_PROG_CC])], + [$0 is obsolete; use AC_PROG_CC] +) + +# AC_PROG_CC_C99 +# -------------- +AU_DEFUN([AC_PROG_CC_C99], + [AC_REQUIRE([AC_PROG_CC])], + [$0 is obsolete; use AC_PROG_CC] +) + +# AC_PROG_CC_STDC +# --------------- +AU_DEFUN([AC_PROG_CC_STDC], + [AC_REQUIRE([AC_PROG_CC])], + [$0 is obsolete; use AC_PROG_CC] +) + + +# AC_C_PROTOTYPES +# --------------- +# Check if the C compiler supports prototypes, included if it needs +# options. +AC_DEFUN([AC_C_PROTOTYPES], +[AC_REQUIRE([AC_PROG_CC])dnl +if test "$ac_prog_cc_stdc" != no; then + AC_DEFINE(PROTOTYPES, 1, + [Define to 1 if the C compiler supports function prototypes.]) + AC_DEFINE(__PROTOTYPES, 1, + [Define like PROTOTYPES; this can be used by system headers.]) +fi +])# AC_C_PROTOTYPES + + +# _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, +# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) +# ---------------------------------------------------------------- +# Check whether the C++ compiler accepts features of STANDARD (e.g +# `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE +# and TEST-BODY. If this fails, try again with each compiler option +# in the space-separated OPTION-LIST; if one helps, append it to CXX. +# If eventually successful, run ACTION-IF-AVAILABLE, else +# ACTION-IF-UNAVAILABLE. +AC_DEFUN([_AC_CXX_STD_TRY], +[AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features]) +AC_LANG_PUSH(C++)dnl +AC_CACHE_VAL(ac_cv_prog_cxx_$1, +[ac_cv_prog_cxx_$1=no +ac_save_CXX=$CXX +AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) +for ac_arg in '' $4 +do + CXX="$ac_save_CXX $ac_arg" + _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg]) + test "x$ac_cv_prog_cxx_$1" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +])# AC_CACHE_VAL +ac_prog_cxx_stdcxx_options= +case "x$ac_cv_prog_cxx_$1" in + x) + AC_MSG_RESULT([none needed]) ;; + xno) + AC_MSG_RESULT([unsupported]) ;; + *) + ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1" + CXX=$CXX$ac_prog_cxx_stdcxx_options + AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;; +esac +AC_LANG_POP(C++)dnl +AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6]) +])# _AC_CXX_STD_TRY + +# _AC_CXX_CXX98_TEST_HEADER +# ------------------------- +# A C++ header suitable for testing for CXX98. +AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER], +[[ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace test { + typedef std::vector string_vec; + typedef std::pair map_value; + typedef std::map map_type; + typedef std::set set_type; + + template + class printer { + public: + printer(std::ostringstream& os): os(os) {} + void operator() (T elem) { os << elem << std::endl; } + private: + std::ostringstream& os; + }; +} +]])# _AC_CXX_CXX98_TEST_HEADER + +# _AC_CXX_CXX98_TEST_BODY +# ----------------------- +# A C++ body suitable for testing for CXX98, assuming the corresponding header. +AC_DEFUN([_AC_CXX_CXX98_TEST_BODY], +[[ + +try { + // Basic string. + std::string teststr("ASCII text"); + teststr += " string"; + + // Simple vector. + test::string_vec testvec; + testvec.push_back(teststr); + testvec.push_back("foo"); + testvec.push_back("bar"); + if (testvec.size() != 3) { + throw std::runtime_error("vector size is not 1"); + } + + // Dump vector into stringstream and obtain string. + std::ostringstream os; + for (test::string_vec::const_iterator i = testvec.begin(); + i != testvec.end(); ++i) { + if (i + 1 != testvec.end()) { + os << teststr << '\n'; + } + } + // Check algorithms work. + std::for_each(testvec.begin(), testvec.end(), test::printer(os)); + std::string os_out = os.str(); + + // Test pair and map. + test::map_type testmap; + testmap.insert(std::make_pair(std::string("key"), + std::make_pair(53,false))); + + // Test set. + int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + test::set_type testset(values, values + sizeof(values)/sizeof(values[0])); + std::list testlist(testset.begin(), testset.end()); + std::copy(testset.begin(), testset.end(), std::back_inserter(testlist)); +} catch (const std::exception& e) { + std::cerr << "Caught exception: " << e.what() << std::endl; + + // Test fstream + std::ofstream of("test.txt"); + of << "Test ASCII text\n" << std::flush; + of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl; + of.close(); +} +std::exit(0); +]]) + +# _AC_CXX_CXX11_TEST_HEADER +# ------------------------- +# A C++ header suitable for testing for CXX11. +AC_DEFUN([_AC_CXX_CXX11_TEST_HEADER], +[[ +#include +#include +#include +#include +#include +#include +#include + +namespace cxx11test +{ + typedef std::shared_ptr sptr; + typedef std::weak_ptr wptr; + + typedef std::tuple tp; + typedef std::array int_array; + + constexpr int get_val() { return 20; } + + struct testinit + { + int i; + double d; + }; + + class delegate { + public: + delegate(int n) : n(n) {} + delegate(): delegate(2354) {} + + virtual int getval() { return this->n; }; + protected: + int n; + }; + + class overridden : public delegate { + public: + overridden(int n): delegate(n) {} + virtual int getval() override final { return this->n * 2; } + }; + + class nocopy { + public: + nocopy(int i): i(i) {} + nocopy() = default; + nocopy(const nocopy&) = delete; + nocopy & operator=(const nocopy&) = delete; + private: + int i; + }; +} +]])# _AC_CXX_CXX11_TEST_HEADER + +# _AC_CXX_CXX11_TEST_BODY +# ----------------------- +# A C++ body suitable for testing for CXX11, assuming the corresponding header. +AC_DEFUN([_AC_CXX_CXX11_TEST_BODY], +[[ +{ + // Test auto and decltype + std::deque d; + d.push_front(43); + d.push_front(484); + d.push_front(3); + d.push_front(844); + int total = 0; + for (auto i = d.begin(); i != d.end(); ++i) { total += *i; } + + auto a1 = 6538; + auto a2 = 48573953.4; + auto a3 = "String literal"; + + decltype(a2) a4 = 34895.034; +} +{ + // Test constexpr + short sa[cxx11test::get_val()] = { 0 }; +} +{ + // Test initializer lists + cxx11test::testinit il = { 4323, 435234.23544 }; +} +{ + // Test range-based for and lambda + cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + for (int &x : array) { x += 23; } + std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; }); +} +{ + using cxx11test::sptr; + using cxx11test::wptr; + + sptr sp(new std::string("ASCII string")); + wptr wp(sp); + sptr sp2(wp); +} +{ + cxx11test::tp tuple("test", 54, 45.53434); + double d = std::get<2>(tuple); + std::string s; + int i; + std::tie(s,i,d) = tuple; +} +{ + static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$"); + std::string testmatch("Test if this string matches"); + bool match = std::regex_search(testmatch, filename_regex); +} +{ + cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + cxx11test::int_array::size_type size = array.size(); +} +{ + // Test constructor delegation + cxx11test::delegate d1; + cxx11test::delegate d2(); + cxx11test::delegate d3(45); +} +{ + // Test override and final + cxx11test::overridden o1(55464); +} +{ + // Test nullptr + char *c = nullptr; +} +{ + // Test template brackets + std::vector> v1; +} +{ + // Unicode literals + char const *utf8 = u8"UTF-8 string \u2500"; + char16_t const *utf16 = u"UTF-8 string \u2500"; + char32_t const *utf32 = U"UTF-32 string \u2500"; +} +]]) + +# _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) +# ------------------------------------------------------------------- + +# If the C++ compiler is not in ISO C++98 mode by default, try to add +# an option to output variable CXX to make it so. This macro tries +# various options that select ISO C++98 on some system or another. It +# considers the compiler to be in ISO C++98 mode if it handles basic +# features of the std namespace including: string, containers (list, +# map, set, vector), streams (fstreams, iostreams, stringstreams, +# iomanip), pair, exceptions and algorithms. + + +AC_DEFUN([_AC_PROG_CXX_CXX98], +[_AC_CXX_STD_TRY([cxx98], +[_AC_CXX_CXX98_TEST_HEADER], +[_AC_CXX_CXX98_TEST_BODY], +dnl Try +dnl GCC -std=gnu++98 (unused restrictive mode: -std=c++98) +dnl IBM XL C -qlanglvl=extended +dnl HP aC++ -AA +dnl Intel ICC -std=gnu++98 +dnl Solaris N/A (default) +dnl Tru64 N/A (default, but -std gnu could be used) +dnl with extended modes being tried first. +[[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl +])# _AC_PROG_CXX_CXX98 + +# _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) +# ------------------------------------------------------------------- +# If the C++ compiler is not in ISO CXX11 mode by default, try to add +# an option to output variable CXX to make it so. This macro tries +# various options that select ISO C++11 on some system or another. It +# considers the compiler to be in ISO C++11 mode if it handles all the +# tests from the C++98 checks, plus the following: Language features +# (auto, constexpr, decltype, default/deleted constructors, delegate +# constructors, final, initializer lists, lambda functions, nullptr, +# override, range-based for loops, template brackets without spaces, +# unicode literals) and library features (array, memory (shared_ptr, +# weak_ptr), regex and tuple types). +AC_DEFUN([_AC_PROG_CXX_CXX11], +[_AC_CXX_STD_TRY([cxx11], +[_AC_CXX_CXX11_TEST_HEADER +_AC_CXX_CXX98_TEST_HEADER], +[_AC_CXX_CXX11_TEST_BODY +_AC_CXX_CXX98_TEST_BODY], +dnl Try +dnl GCC -std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants] +dnl IBM XL C -qlanglvl=extended0x +dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11) +dnl HP aC++ -AA +dnl Intel ICC -std=c++11 -std=c++0x +dnl Solaris N/A (no support) +dnl Tru64 N/A (no support) +dnl with extended modes being tried first. +[[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl +])# _AC_PROG_CXX_CXX11 + + +])# m4_version_prereq diff --git a/gl/m4/stdalign.m4 b/gl/m4/stdalign.m4 index 20be01aa..78577cb2 100644 --- a/gl/m4/stdalign.m4 +++ b/gl/m4/stdalign.m4 @@ -1,6 +1,6 @@ # Check for stdalign.h that conforms to C11. -dnl Copyright 2011-2013 Free Software Foundation, Inc. +dnl Copyright 2011-2022 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. @@ -13,12 +13,13 @@ AC_DEFUN([gl_STDALIGN_H], [gl_cv_header_working_stdalign_h], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[#include + [[#include + #include #include /* Test that alignof yields a result consistent with offsetof. This catches GCC bug 52023 - . */ + . */ #ifdef __cplusplus template struct alignof_helper { char a; t b; }; # define ao(type) offsetof (alignof_helper, b) @@ -32,8 +33,13 @@ AC_DEFUN([gl_STDALIGN_H], /* Test _Alignas only on platforms where gnulib can help. */ #if \ ((defined __cplusplus && 201103 <= __cplusplus) \ - || __GNUC__ || __IBMC__ || __IBMCPP__ || __ICC \ - || 0x5110 <= __SUNPRO_C || 1300 <= _MSC_VER) + || (__TINYC__ && defined __attribute__) \ + || (defined __APPLE__ && defined __MACH__ \ + ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \ + : __GNUC__) \ + || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \ + || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__ \ + || 1300 <= _MSC_VER) struct alignas_test { char c; char alignas (8) alignas_8; }; char test_alignas[offsetof (struct alignas_test, alignas_8) == 8 ? 1 : -1]; @@ -43,11 +49,8 @@ AC_DEFUN([gl_STDALIGN_H], [gl_cv_header_working_stdalign_h=no])]) if test $gl_cv_header_working_stdalign_h = yes; then - STDALIGN_H='' + GL_GENERATE_STDALIGN_H=false else - STDALIGN_H='stdalign.h' + GL_GENERATE_STDALIGN_H=true fi - - AC_SUBST([STDALIGN_H]) - AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"]) ]) diff --git a/gl/m4/stdbool.m4 b/gl/m4/stdbool.m4 index 80d5559a..c67908aa 100644 --- a/gl/m4/stdbool.m4 +++ b/gl/m4/stdbool.m4 @@ -1,27 +1,39 @@ # Check for stdbool.h that conforms to C99. -dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2002-2006, 2009-2022 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. -#serial 5 +#serial 9 # Prepare for substituting if it is not supported. -AC_DEFUN([AM_STDBOOL_H], +AC_DEFUN([gl_STDBOOL_H], [ AC_REQUIRE([AC_CHECK_HEADER_STDBOOL]) + AC_REQUIRE([AC_CANONICAL_HOST]) - # Define two additional variables used in the Makefile substitution. - + dnl On some platforms, does not exist or does not conform to C99. + dnl On Solaris 10 with CC=cc CXX=CC, exists but is not usable + dnl in C++ mode (and no exists). In this case, we use our + dnl replacement, also in C mode (for binary compatibility between C and C++). if test "$ac_cv_header_stdbool_h" = yes; then - STDBOOL_H='' + case "$host_os" in + solaris*) + if test -z "$GCC"; then + GL_GENERATE_STDBOOL_H=true + else + GL_GENERATE_STDBOOL_H=false + fi + ;; + *) + GL_GENERATE_STDBOOL_H=false + ;; + esac else - STDBOOL_H='stdbool.h' + GL_GENERATE_STDBOOL_H=true fi - AC_SUBST([STDBOOL_H]) - AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n "$STDBOOL_H"]) if test "$ac_cv_type__Bool" = yes; then HAVE__BOOL=1 @@ -31,70 +43,76 @@ AC_DEFUN([AM_STDBOOL_H], AC_SUBST([HAVE__BOOL]) ]) -# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future. -AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H]) - -# This version of the macro is needed in autoconf <= 2.68. +m4_version_prereq([2.72], [], [ AC_DEFUN([AC_CHECK_HEADER_STDBOOL], - [AC_CACHE_CHECK([for stdbool.h that conforms to C99], + [AC_CHECK_TYPES([_Bool]) + AC_CACHE_CHECK([for stdbool.h that conforms to C99 or later], [ac_cv_header_stdbool_h], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[ - #include - #ifndef bool - "error: bool is not defined" + [[#include + + /* "true" and "false" should be usable in #if expressions and + integer constant expressions, and "bool" should be a valid + type name. + + Although C 1999 requires bool, true, and false to be macros, + C 2023 and C++ 2011 overrule that, so do not test for that. + Although C 1999 requires __bool_true_false_are_defined and + _Bool, C 2023 says they are obsolescent, so do not require + them. */ + + #if !true + #error "'true' is not true" #endif - #ifndef false - "error: false is not defined" + #if true != 1 + #error "'true' is not equal to 1" #endif + char b[true == 1 ? 1 : -1]; + char c[true]; + #if false - "error: false is not 0" + #error "'false' is not false" #endif - #ifndef true - "error: true is not defined" - #endif - #if true != 1 - "error: true is not 1" - #endif - #ifndef __bool_true_false_are_defined - "error: __bool_true_false_are_defined is not defined" + #if false != 0 + #error "'false' is not equal to 0" #endif + char d[false == 0 ? 1 : -1]; + + enum { e = false, f = true, g = false * true, h = true * 256 }; + + char i[(bool) 0.5 == true ? 1 : -1]; + char j[(bool) 0.0 == false ? 1 : -1]; + char k[sizeof (bool) > 0 ? 1 : -1]; + + struct sb { bool s: 1; bool t; } s; + char l[sizeof s.t > 0 ? 1 : -1]; - struct s { _Bool s: 1; _Bool t; } s; - - char a[true == 1 ? 1 : -1]; - char b[false == 0 ? 1 : -1]; - char c[__bool_true_false_are_defined == 1 ? 1 : -1]; - char d[(bool) 0.5 == true ? 1 : -1]; - /* See body of main program for 'e'. */ - char f[(_Bool) 0.0 == false ? 1 : -1]; - char g[true]; - char h[sizeof (_Bool)]; - char i[sizeof s.t]; - enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ - _Bool n[m]; - char o[sizeof n == m * sizeof n[0] ? 1 : -1]; - char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + bool m[h]; + char n[sizeof m == h * sizeof m[0] ? 1 : -1]; + char o[-1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html */ - _Bool q = true; - _Bool *pq = &q; + bool p = true; + bool *pp = &p; ]], [[ - bool e = &s; - *pq |= q; - *pq |= ! q; - /* Refer to every declared value, to avoid compiler optimizations. */ - return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l - + !m + !n + !o + !p + !q + !pq); + bool ps = &s; + *pp |= p; + *pp |= ! p; + + /* Refer to every declared value, so they cannot be + discarded as unused. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k + + !l + !m + !n + !o + !p + !pp + !ps); ]])], [ac_cv_header_stdbool_h=yes], [ac_cv_header_stdbool_h=no])]) - AC_CHECK_TYPES([_Bool]) -]) +])# AC_CHECK_HEADER_STDBOOL + +]) # m4_version_prereq 2.72 diff --git a/gl/m4/stddef_h.m4 b/gl/m4/stddef_h.m4 index 5da8ab1e..abfd2030 100644 --- a/gl/m4/stddef_h.m4 +++ b/gl/m4/stddef_h.m4 @@ -1,19 +1,54 @@ -dnl A placeholder for POSIX 2008 , for platforms that have issues. -# stddef_h.m4 serial 4 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. +# stddef_h.m4 serial 12 +dnl Copyright (C) 2009-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_STDDEF_H], +dnl A placeholder for , for platforms that have issues. + +AC_DEFUN_ONCE([gl_STDDEF_H], [ AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) AC_REQUIRE([gt_TYPE_WCHAR_T]) - STDDEF_H= + + dnl Persuade OpenBSD to declare max_align_t. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + GL_GENERATE_STDDEF_H=false + + dnl Test whether the type max_align_t exists and whether its alignment + dnl "is as great as is supported by the implementation in all contexts". + AC_CACHE_CHECK([for good max_align_t], + [gl_cv_type_max_align_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + unsigned int s = sizeof (max_align_t); + #if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__ + 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]) + ]) + if test $gl_cv_type_max_align_t = no; then + HAVE_MAX_ALIGN_T=0 + GL_GENERATE_STDDEF_H=true + fi + if test $gt_cv_c_wchar_t = no; then HAVE_WCHAR_T=0 - STDDEF_H=stddef.h + GL_GENERATE_STDDEF_H=true fi + AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], [gl_cv_decl_null_works], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include @@ -23,25 +58,40 @@ AC_DEFUN([gl_STDDEF_H], [gl_cv_decl_null_works=no])]) if test $gl_cv_decl_null_works = no; then REPLACE_NULL=1 - STDDEF_H=stddef.h + GL_GENERATE_STDDEF_H=true fi - AC_SUBST([STDDEF_H]) - AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"]) - if test -n "$STDDEF_H"; then + + if $GL_GENERATE_STDDEF_H; then gl_NEXT_HEADERS([stddef.h]) fi ]) +# gl_STDDEF_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_STDDEF_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_STDDEF_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_STDDEF_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDDEF_H_MODULE_INDICATOR_DEFAULTS], [ + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_STDDEF_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) +]) + AC_DEFUN([gl_STDDEF_H_DEFAULTS], [ dnl Assume proper GNU behavior unless another module says otherwise. REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) + HAVE_MAX_ALIGN_T=1; AC_SUBST([HAVE_MAX_ALIGN_T]) HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) ]) diff --git a/gl/m4/stdint.m4 b/gl/m4/stdint.m4 index 27cdcdb9..c3f08942 100644 --- a/gl/m4/stdint.m4 +++ b/gl/m4/stdint.m4 @@ -1,5 +1,5 @@ -# stdint.m4 serial 43 -dnl Copyright (C) 2001-2013 Free Software Foundation, Inc. +# stdint.m4 serial 61 +dnl Copyright (C) 2001-2022 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. @@ -7,25 +7,22 @@ dnl with or without modifications, as long as this notice is preserved. dnl From Paul Eggert and Bruno Haible. dnl Test whether is supported or must be substituted. +AC_PREREQ([2.61]) + AC_DEFUN_ONCE([gl_STDINT_H], [ AC_PREREQ([2.59])dnl + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - dnl Check for long long int and unsigned long long int. - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - if test $ac_cv_type_long_long_int = yes; then - HAVE_LONG_LONG_INT=1 - else - HAVE_LONG_LONG_INT=0 - fi - AC_SUBST([HAVE_LONG_LONG_INT]) - AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) - if test $ac_cv_type_unsigned_long_long_int = yes; then - HAVE_UNSIGNED_LONG_LONG_INT=1 - else - HAVE_UNSIGNED_LONG_LONG_INT=0 - fi - AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) + AC_REQUIRE([gl_LIMITS_H]) + AC_REQUIRE([gt_TYPE_WINT_T]) + + dnl For backward compatibility. Some packages may still be testing these + dnl macros. + AC_DEFINE([HAVE_LONG_LONG_INT], [1], + [Define to 1 if the system has the type 'long long int'.]) + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], + [Define to 1 if the system has the type 'unsigned long long int'.]) dnl Check for , in the same way as gl_WCHAR_H does. AC_CHECK_HEADERS_ONCE([wchar.h]) @@ -37,7 +34,7 @@ AC_DEFUN_ONCE([gl_STDINT_H], AC_SUBST([HAVE_WCHAR_H]) dnl Check for . - dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. + AC_CHECK_HEADERS_ONCE([inttypes.h]) if test $ac_cv_header_inttypes_h = yes; then HAVE_INTTYPES_H=1 else @@ -46,7 +43,7 @@ AC_DEFUN_ONCE([gl_STDINT_H], AC_SUBST([HAVE_INTTYPES_H]) dnl Check for . - dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h. + AC_CHECK_HEADERS_ONCE([sys/types.h]) if test $ac_cv_header_sys_types_h = yes; then HAVE_SYS_TYPES_H=1 else @@ -70,6 +67,8 @@ AC_DEFUN_ONCE([gl_STDINT_H], AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#define __STDC_CONSTANT_MACROS 1 +#define __STDC_LIMIT_MACROS 1 #include /* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ #if !(defined WCHAR_MIN && defined WCHAR_MAX) @@ -150,6 +149,15 @@ uintptr_t h = UINTPTR_MAX; intmax_t i = INTMAX_MAX; uintmax_t j = UINTMAX_MAX; +/* Check that SIZE_MAX has the correct type, if possible. */ +#if 201112 <= __STDC_VERSION__ +int k = _Generic (SIZE_MAX, size_t: 0); +#elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \ + || (0x5110 <= __SUNPRO_C && !__STDC__)) +extern size_t k; +extern __typeof__ (SIZE_MAX) k; +#endif + #include /* for CHAR_BIT */ #define TYPE_MINIMUM(t) \ ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t))) @@ -162,7 +170,7 @@ struct s { PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) ? 1 : -1; - /* Detect bug in FreeBSD 6.0 / ia64. */ + /* Detect bug in FreeBSD 6.0/ia64 and FreeBSD 13.0/arm64. */ int check_SIG_ATOMIC: SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) @@ -218,6 +226,8 @@ struct s { AC_RUN_IFELSE([ AC_LANG_PROGRAM([[ #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#define __STDC_CONSTANT_MACROS 1 +#define __STDC_LIMIT_MACROS 1 #include ] gl_STDINT_INCLUDES @@ -272,36 +282,88 @@ static const char *macro_values[] = ]])], [gl_cv_header_working_stdint_h=yes], [], - [dnl When cross-compiling, assume it works. - gl_cv_header_working_stdint_h=yes + [case "$host_os" in + # Guess yes on native Windows. + mingw*) gl_cv_header_working_stdint_h="guessing yes" ;; + # In general, assume it works. + *) gl_cv_header_working_stdint_h="guessing yes" ;; + esac ]) ]) ]) fi - if test "$gl_cv_header_working_stdint_h" = yes; then - STDINT_H= - else - dnl Check for , and for - dnl (used in Linux libc4 >= 4.6.7 and libc5). - AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) - if test $ac_cv_header_sys_inttypes_h = yes; then - HAVE_SYS_INTTYPES_H=1 - else - HAVE_SYS_INTTYPES_H=0 - fi - AC_SUBST([HAVE_SYS_INTTYPES_H]) - if test $ac_cv_header_sys_bitypes_h = yes; then - HAVE_SYS_BITYPES_H=1 - else - HAVE_SYS_BITYPES_H=0 - fi - AC_SUBST([HAVE_SYS_BITYPES_H]) - gl_STDINT_TYPE_PROPERTIES - STDINT_H=stdint.h - fi - AC_SUBST([STDINT_H]) - AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"]) + HAVE_C99_STDINT_H=0 + HAVE_SYS_BITYPES_H=0 + HAVE_SYS_INTTYPES_H=0 + GL_GENERATE_STDINT_H=true + case "$gl_cv_header_working_stdint_h" in + *yes) + HAVE_C99_STDINT_H=1 + dnl Now see whether the system works without + dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined. + dnl If not, there would be problems when stdint.h is included from C++. + AC_CACHE_CHECK([whether stdint.h works without ISO C predefines], + [gl_cv_header_stdint_without_STDC_macros], + [gl_cv_header_stdint_without_STDC_macros=no + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#include +] +gl_STDINT_INCLUDES +[ +intmax_t im = INTMAX_MAX; +int32_t i32 = INT32_C (0x7fffffff); + ]])], + [gl_cv_header_stdint_without_STDC_macros=yes]) + ]) + + if test $gl_cv_header_stdint_without_STDC_macros = no; then + AC_DEFINE([__STDC_CONSTANT_MACROS], [1], + [Define to 1 if the system predates C++11.]) + AC_DEFINE([__STDC_LIMIT_MACROS], [1], + [Define to 1 if the system predates C++11.]) + fi + AC_CACHE_CHECK([whether stdint.h has UINTMAX_WIDTH etc.], + [gl_cv_header_stdint_width], + [gl_cv_header_stdint_width=no + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + /* Work if build is not clean. */ + #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 + #ifndef __STDC_WANT_IEC_60559_BFP_EXT__ + #define __STDC_WANT_IEC_60559_BFP_EXT__ 1 + #endif + #include + ]gl_STDINT_INCLUDES[ + int iw = UINTMAX_WIDTH; + ]])], + [gl_cv_header_stdint_width=yes])]) + if test "$gl_cv_header_stdint_width" = yes; then + GL_GENERATE_STDINT_H=false + fi + ;; + *) + dnl Check for , and for + dnl (used in Linux libc4 >= 4.6.7 and libc5). + AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) + if test $ac_cv_header_sys_inttypes_h = yes; then + HAVE_SYS_INTTYPES_H=1 + fi + if test $ac_cv_header_sys_bitypes_h = yes; then + HAVE_SYS_BITYPES_H=1 + fi + gl_STDINT_TYPE_PROPERTIES + ;; + esac + + dnl The substitute stdint.h needs the substitute limit.h's _GL_INTEGER_WIDTH. + gl_REPLACE_LIMITS_H + + AC_SUBST([HAVE_C99_STDINT_H]) + AC_SUBST([HAVE_SYS_BITYPES_H]) + AC_SUBST([HAVE_SYS_INTTYPES_H]) ]) dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) @@ -429,13 +491,9 @@ AC_DEFUN([gl_INTEGER_TYPE_SUFFIX], dnl gl_STDINT_INCLUDES AC_DEFUN([gl_STDINT_INCLUDES], [[ - /* BSD/OS 4.0.1 has a bug: , and must be - included before . */ #include #include #if HAVE_WCHAR_H - # include - # include # include #endif ]]) @@ -467,18 +525,7 @@ AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], dnl requirement that wint_t is "unchanged by default argument promotions". dnl In this case gnulib's and override wint_t. dnl Set the variable BITSIZEOF_WINT_T accordingly. - if test $BITSIZEOF_WINT_T -lt 32; then + if test $GNULIBHEADERS_OVERRIDE_WINT_T = 1; then BITSIZEOF_WINT_T=32 fi ]) - -dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. -dnl Remove this when we can assume autoconf >= 2.61. -m4_ifdef([AC_COMPUTE_INT], [], [ - AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) -]) - -# Hey Emacs! -# Local Variables: -# indent-tabs-mode: nil -# End: diff --git a/gl/m4/stdint_h.m4 b/gl/m4/stdint_h.m4 index 511ab4e9..b8684b61 100644 --- a/gl/m4/stdint_h.m4 +++ b/gl/m4/stdint_h.m4 @@ -1,5 +1,5 @@ # stdint_h.m4 serial 9 -dnl Copyright (C) 1997-2004, 2006, 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 1997-2004, 2006, 2008-2022 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. diff --git a/gl/m4/stdio_h.m4 b/gl/m4/stdio_h.m4 index ebade067..42e96071 100644 --- a/gl/m4/stdio_h.m4 +++ b/gl/m4/stdio_h.m4 @@ -1,72 +1,71 @@ -# stdio_h.m4 serial 43 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +# stdio_h.m4 serial 59 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_STDIO_H], +AC_DEFUN_ONCE([gl_STDIO_H], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AH_VERBATIM([MINGW_ANSI_STDIO], +[/* Use GNU style printf and scanf. */ +#ifndef __USE_MINGW_ANSI_STDIO +# undef __USE_MINGW_ANSI_STDIO +#endif +]) + AC_DEFINE([__USE_MINGW_ANSI_STDIO]) gl_NEXT_HEADERS([stdio.h]) - dnl No need to create extra modules for these functions. Everyone who uses - dnl likely needs them. - GNULIB_FSCANF=1 - gl_MODULE_INDICATOR([fscanf]) - GNULIB_SCANF=1 - gl_MODULE_INDICATOR([scanf]) - GNULIB_FGETC=1 - GNULIB_GETC=1 - GNULIB_GETCHAR=1 - GNULIB_FGETS=1 - GNULIB_FREAD=1 - dnl This ifdef is necessary to avoid an error "missing file lib/stdio-read.c" - dnl "expected source file, required through AC_LIBSOURCES, not found". It is - dnl also an optimization, to avoid performing a configure check whose result - dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING - dnl or GNULIB_NONBLOCKING redundant. + dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and + dnl inttypes.h behave like gnu instead of system; we must give our + dnl printf wrapper the right attribute to match. + AC_CACHE_CHECK([which flavor of printf attribute matches inttypes macros], + [gl_cv_func_printf_attribute_flavor], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #define __STDC_FORMAT_MACROS 1 + #include + #include + /* For non-mingw systems, compilation will trivially succeed. + For mingw, compilation will succeed for older mingw (system + printf, "I64d") and fail for newer mingw (gnu printf, "lld"). */ + #if (defined _WIN32 && ! defined __CYGWIN__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + extern char PRIdMAX_probe[sizeof PRIdMAX == sizeof "I64d" ? 1 : -1]; + #endif + ]])], [gl_cv_func_printf_attribute_flavor=system], + [gl_cv_func_printf_attribute_flavor=gnu])]) + if test "$gl_cv_func_printf_attribute_flavor" = gnu; then + AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1], + [Define to 1 if printf and friends should be labeled with + attribute "__gnu_printf__" instead of "__printf__"]) + fi + + dnl This ifdef is an optimization, to avoid performing a configure check whose + dnl result is not used. But it does not make the test of + dnl GNULIB_STDIO_H_NONBLOCKING or GNULIB_NONBLOCKING redundant. m4_ifdef([gl_NONBLOCKING_IO], [ gl_NONBLOCKING_IO if test $gl_cv_have_nonblocking != yes; then REPLACE_STDIO_READ_FUNCS=1 - AC_LIBOBJ([stdio-read]) fi ]) - dnl No need to create extra modules for these functions. Everyone who uses - dnl likely needs them. - GNULIB_FPRINTF=1 - GNULIB_PRINTF=1 - GNULIB_VFPRINTF=1 - GNULIB_VPRINTF=1 - GNULIB_FPUTC=1 - GNULIB_PUTC=1 - GNULIB_PUTCHAR=1 - GNULIB_FPUTS=1 - GNULIB_PUTS=1 - GNULIB_FWRITE=1 - dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c" - dnl "expected source file, required through AC_LIBSOURCES, not found". It is - dnl also an optimization, to avoid performing a configure check whose result - dnl is not used. But it does not make the test of GNULIB_STDIO_H_SIGPIPE or - dnl GNULIB_SIGPIPE redundant. + dnl This ifdef is an optimization, to avoid performing a configure check whose + dnl result is not used. But it does not make the test of + dnl GNULIB_STDIO_H_SIGPIPE or GNULIB_SIGPIPE redundant. m4_ifdef([gl_SIGNAL_SIGPIPE], [ gl_SIGNAL_SIGPIPE if test $gl_cv_header_signal_h_SIGPIPE != yes; then REPLACE_STDIO_WRITE_FUNCS=1 - AC_LIBOBJ([stdio-write]) fi ]) - dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c" - dnl "expected source file, required through AC_LIBSOURCES, not found". It is - dnl also an optimization, to avoid performing a configure check whose result - dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING - dnl or GNULIB_NONBLOCKING redundant. + dnl This ifdef is an optimization, to avoid performing a configure check whose + dnl result is not used. But it does not make the test of + dnl GNULIB_STDIO_H_NONBLOCKING or GNULIB_NONBLOCKING redundant. m4_ifdef([gl_NONBLOCKING_IO], [ gl_NONBLOCKING_IO if test $gl_cv_have_nonblocking != yes; then REPLACE_STDIO_WRITE_FUNCS=1 - AC_LIBOBJ([stdio-write]) fi ]) @@ -76,73 +75,104 @@ AC_DEFUN([gl_STDIO_H], gl_WARN_ON_USE_PREPARE([[#include ]], [dprintf fpurge fseeko ftello getdelim getline gets pclose popen renameat snprintf tmpfile vdprintf vsnprintf]) + + AC_REQUIRE([AC_C_RESTRICT]) + + AC_CHECK_DECLS_ONCE([fcloseall]) + if test $ac_cv_have_decl_fcloseall = no; then + HAVE_DECL_FCLOSEALL=0 + fi ]) +# gl_STDIO_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_STDIO_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_STDIO_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDIO_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCLOSE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDOPEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFLUSH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FGETC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FGETS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FOPEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FOPEN_GNU]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPRINTF_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPURGE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPUTC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FPUTS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREAD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREOPEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSCANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSEEK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSEEKO]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELLO]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FWRITE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCHAR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDELIM]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLINE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PCLOSE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PERROR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POPEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PRINTF_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTCHAR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REMOVE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAMEAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SPRINTF_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_NONBLOCKING]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCLOSEALL], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FDOPEN], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FILENO], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETW], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_PUTW], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TEMPNAM], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_STDIO_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) +]) + AC_DEFUN([gl_STDIO_H_DEFAULTS], [ - GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) - GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE]) - GNULIB_FDOPEN=0; AC_SUBST([GNULIB_FDOPEN]) - GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH]) - GNULIB_FGETC=0; AC_SUBST([GNULIB_FGETC]) - GNULIB_FGETS=0; AC_SUBST([GNULIB_FGETS]) - GNULIB_FOPEN=0; AC_SUBST([GNULIB_FOPEN]) - GNULIB_FPRINTF=0; AC_SUBST([GNULIB_FPRINTF]) - GNULIB_FPRINTF_POSIX=0; AC_SUBST([GNULIB_FPRINTF_POSIX]) - GNULIB_FPURGE=0; AC_SUBST([GNULIB_FPURGE]) - GNULIB_FPUTC=0; AC_SUBST([GNULIB_FPUTC]) - GNULIB_FPUTS=0; AC_SUBST([GNULIB_FPUTS]) - GNULIB_FREAD=0; AC_SUBST([GNULIB_FREAD]) - GNULIB_FREOPEN=0; AC_SUBST([GNULIB_FREOPEN]) - GNULIB_FSCANF=0; AC_SUBST([GNULIB_FSCANF]) - GNULIB_FSEEK=0; AC_SUBST([GNULIB_FSEEK]) - GNULIB_FSEEKO=0; AC_SUBST([GNULIB_FSEEKO]) - GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL]) - GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO]) - GNULIB_FWRITE=0; AC_SUBST([GNULIB_FWRITE]) - GNULIB_GETC=0; AC_SUBST([GNULIB_GETC]) - GNULIB_GETCHAR=0; AC_SUBST([GNULIB_GETCHAR]) - GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM]) - GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE]) - GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) - GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) - GNULIB_PCLOSE=0; AC_SUBST([GNULIB_PCLOSE]) - GNULIB_PERROR=0; AC_SUBST([GNULIB_PERROR]) - GNULIB_POPEN=0; AC_SUBST([GNULIB_POPEN]) - GNULIB_PRINTF=0; AC_SUBST([GNULIB_PRINTF]) - GNULIB_PRINTF_POSIX=0; AC_SUBST([GNULIB_PRINTF_POSIX]) - GNULIB_PUTC=0; AC_SUBST([GNULIB_PUTC]) - GNULIB_PUTCHAR=0; AC_SUBST([GNULIB_PUTCHAR]) - GNULIB_PUTS=0; AC_SUBST([GNULIB_PUTS]) - GNULIB_REMOVE=0; AC_SUBST([GNULIB_REMOVE]) - GNULIB_RENAME=0; AC_SUBST([GNULIB_RENAME]) - GNULIB_RENAMEAT=0; AC_SUBST([GNULIB_RENAMEAT]) - GNULIB_SCANF=0; AC_SUBST([GNULIB_SCANF]) - GNULIB_SNPRINTF=0; AC_SUBST([GNULIB_SNPRINTF]) - GNULIB_SPRINTF_POSIX=0; AC_SUBST([GNULIB_SPRINTF_POSIX]) - GNULIB_STDIO_H_NONBLOCKING=0; AC_SUBST([GNULIB_STDIO_H_NONBLOCKING]) - GNULIB_STDIO_H_SIGPIPE=0; AC_SUBST([GNULIB_STDIO_H_SIGPIPE]) - GNULIB_TMPFILE=0; AC_SUBST([GNULIB_TMPFILE]) - GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) - GNULIB_VFSCANF=0; AC_SUBST([GNULIB_VFSCANF]) - GNULIB_VSCANF=0; AC_SUBST([GNULIB_VSCANF]) - GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) - GNULIB_VFPRINTF=0; AC_SUBST([GNULIB_VFPRINTF]) - GNULIB_VFPRINTF_POSIX=0; AC_SUBST([GNULIB_VFPRINTF_POSIX]) - GNULIB_VPRINTF=0; AC_SUBST([GNULIB_VPRINTF]) - GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) - GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) - GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_DECL_FCLOSEALL=1; AC_SUBST([HAVE_DECL_FCLOSEALL]) HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) HAVE_DECL_FSEEKO=1; AC_SUBST([HAVE_DECL_FSEEKO]) HAVE_DECL_FTELLO=1; AC_SUBST([HAVE_DECL_FTELLO]) @@ -164,6 +194,7 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], REPLACE_FDOPEN=0; AC_SUBST([REPLACE_FDOPEN]) REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) REPLACE_FOPEN=0; AC_SUBST([REPLACE_FOPEN]) + REPLACE_FOPEN_FOR_FOPEN_GNU=0; AC_SUBST([REPLACE_FOPEN_FOR_FOPEN_GNU]) REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF]) REPLACE_FPURGE=0; AC_SUBST([REPLACE_FPURGE]) REPLACE_FREOPEN=0; AC_SUBST([REPLACE_FREOPEN]) diff --git a/gl/m4/stdlib_h.m4 b/gl/m4/stdlib_h.m4 index 2027ab3c..9e209697 100644 --- a/gl/m4/stdlib_h.m4 +++ b/gl/m4/stdlib_h.m4 @@ -1,10 +1,10 @@ -# stdlib_h.m4 serial 42 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +# stdlib_h.m4 serial 66 +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_STDLIB_H], +AC_DEFUN_ONCE([gl_STDLIB_H], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) gl_NEXT_HEADERS([stdlib.h]) @@ -14,104 +14,187 @@ AC_DEFUN([gl_STDLIB_H], dnl guaranteed by C89. gl_WARN_ON_USE_PREPARE([[#include #if HAVE_SYS_LOADAVG_H +/* OpenIndiana has a bug: must be included before + . */ +# include # include #endif #if HAVE_RANDOM_H # include #endif - ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt - initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps - posix_openpt ptsname ptsname_r random random_r realpath rpmatch - secure_getenv setenv setstate setstate_r srandom srandom_r - strtod strtoll strtoull unlockpt unsetenv]) + ]], [_Exit aligned_alloc atoll canonicalize_file_name free + getloadavg getsubopt grantpt + initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps + posix_memalign posix_openpt ptsname ptsname_r qsort_r + random random_r reallocarray realpath rpmatch secure_getenv setenv + setstate setstate_r srandom srandom_r + strtod strtol strtold strtoll strtoul strtoull unlockpt unsetenv]) + + AC_REQUIRE([AC_C_RESTRICT]) + + AC_CHECK_DECLS_ONCE([ecvt]) + if test $ac_cv_have_decl_ecvt = no; then + HAVE_DECL_ECVT=0 + fi + AC_CHECK_DECLS_ONCE([fcvt]) + if test $ac_cv_have_decl_fcvt = no; then + HAVE_DECL_FCVT=0 + fi + AC_CHECK_DECLS_ONCE([gcvt]) + if test $ac_cv_have_decl_gcvt = no; then + HAVE_DECL_GCVT=0 + fi ]) +# gl_STDLIB_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_STDLIB_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_GNU]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CANONICALIZE_FILE_NAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREE_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOADAVG]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSUBOPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GRANTPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_GNU]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBTOWC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDTEMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKOSTEMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKOSTEMPS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKSTEMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKSTEMPS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_MEMALIGN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_OPENPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTSNAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTSNAME_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTENV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_QSORT_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOCARRAY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_GNU]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALPATH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SECURE_GETENV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETENV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOLD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOLL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOUL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOULL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYSTEM_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLOCKPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNSETENV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTOMB]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ECVT], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCVT], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GCVT], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MKTEMP], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_PUTENV], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) +]) + AC_DEFUN([gl_STDLIB_H_DEFAULTS], [ - GNULIB__EXIT=0; AC_SUBST([GNULIB__EXIT]) - GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL]) - GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX]) - GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME]) - GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG]) - GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) - GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT]) - GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX]) - GNULIB_MBTOWC=0; AC_SUBST([GNULIB_MBTOWC]) - GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) - GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP]) - GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS]) - GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP]) - GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS]) - GNULIB_POSIX_OPENPT=0; AC_SUBST([GNULIB_POSIX_OPENPT]) - GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME]) - GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R]) - GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) - GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM]) - GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) - GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) - GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH]) - GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH]) - GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV]) - GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV]) - GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD]) - GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL]) - GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL]) - GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX]) - GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) - GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) - GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) + HAVE_ALIGNED_ALLOC=1; AC_SUBST([HAVE_ALIGNED_ALLOC]) HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL]) HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME]) + HAVE_DECL_ECVT=1; AC_SUBST([HAVE_DECL_ECVT]) + HAVE_DECL_FCVT=1; AC_SUBST([HAVE_DECL_FCVT]) + HAVE_DECL_GCVT=1; AC_SUBST([HAVE_DECL_GCVT]) HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) HAVE_GRANTPT=1; AC_SUBST([HAVE_GRANTPT]) + HAVE_INITSTATE=1; AC_SUBST([HAVE_INITSTATE]) + HAVE_DECL_INITSTATE=1; AC_SUBST([HAVE_DECL_INITSTATE]) + HAVE_MBTOWC=1; AC_SUBST([HAVE_MBTOWC]) HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP]) HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP]) HAVE_MKOSTEMPS=1; AC_SUBST([HAVE_MKOSTEMPS]) HAVE_MKSTEMP=1; AC_SUBST([HAVE_MKSTEMP]) HAVE_MKSTEMPS=1; AC_SUBST([HAVE_MKSTEMPS]) + HAVE_POSIX_MEMALIGN=1; AC_SUBST([HAVE_POSIX_MEMALIGN]) HAVE_POSIX_OPENPT=1; AC_SUBST([HAVE_POSIX_OPENPT]) HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME]) HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R]) + HAVE_QSORT_R=1; AC_SUBST([HAVE_QSORT_R]) HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM]) HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H]) HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) + HAVE_REALLOCARRAY=1; AC_SUBST([HAVE_REALLOCARRAY]) HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH]) HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) HAVE_SECURE_GETENV=1; AC_SUBST([HAVE_SECURE_GETENV]) HAVE_SETENV=1; AC_SUBST([HAVE_SETENV]) HAVE_DECL_SETENV=1; AC_SUBST([HAVE_DECL_SETENV]) + HAVE_SETSTATE=1; AC_SUBST([HAVE_SETSTATE]) + HAVE_DECL_SETSTATE=1; AC_SUBST([HAVE_DECL_SETSTATE]) HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD]) + HAVE_STRTOL=1; AC_SUBST([HAVE_STRTOL]) + HAVE_STRTOLD=1; AC_SUBST([HAVE_STRTOLD]) HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL]) + HAVE_STRTOUL=1; AC_SUBST([HAVE_STRTOUL]) HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL]) HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV]) - REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC]) + REPLACE_ALIGNED_ALLOC=0; AC_SUBST([REPLACE_ALIGNED_ALLOC]) + REPLACE_CALLOC_FOR_CALLOC_GNU=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_GNU]) + REPLACE_CALLOC_FOR_CALLOC_POSIX=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_POSIX]) REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME]) - REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC]) + REPLACE_FREE=0; AC_SUBST([REPLACE_FREE]) + REPLACE_INITSTATE=0; AC_SUBST([REPLACE_INITSTATE]) + REPLACE_MALLOC_FOR_MALLOC_GNU=0; AC_SUBST([REPLACE_MALLOC_FOR_MALLOC_GNU]) + REPLACE_MALLOC_FOR_MALLOC_POSIX=0; AC_SUBST([REPLACE_MALLOC_FOR_MALLOC_POSIX]) REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC]) REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP]) + REPLACE_POSIX_MEMALIGN=0; AC_SUBST([REPLACE_POSIX_MEMALIGN]) REPLACE_PTSNAME=0; AC_SUBST([REPLACE_PTSNAME]) REPLACE_PTSNAME_R=0; AC_SUBST([REPLACE_PTSNAME_R]) REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) + REPLACE_QSORT_R=0; AC_SUBST([REPLACE_QSORT_R]) + REPLACE_RANDOM=0; AC_SUBST([REPLACE_RANDOM]) REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R]) - REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC]) + REPLACE_REALLOC_FOR_REALLOC_GNU=0; AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_GNU]) + REPLACE_REALLOC_FOR_REALLOC_POSIX=0; AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_POSIX]) + REPLACE_REALLOCARRAY=0; AC_SUBST([REPLACE_REALLOCARRAY]) REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV]) + REPLACE_SETSTATE=0; AC_SUBST([REPLACE_SETSTATE]) REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD]) + REPLACE_STRTOL=0; AC_SUBST([REPLACE_STRTOL]) + REPLACE_STRTOLD=0; AC_SUBST([REPLACE_STRTOLD]) + REPLACE_STRTOLL=0; AC_SUBST([REPLACE_STRTOLL]) + REPLACE_STRTOUL=0; AC_SUBST([REPLACE_STRTOUL]) + REPLACE_STRTOULL=0; AC_SUBST([REPLACE_STRTOULL]) REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) ]) diff --git a/gl/m4/strcase.m4 b/gl/m4/strcase.m4 index 22bf57c9..d1ffaba3 100644 --- a/gl/m4/strcase.m4 +++ b/gl/m4/strcase.m4 @@ -1,5 +1,5 @@ -# strcase.m4 serial 11 -dnl Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc. +# strcase.m4 serial 12 +dnl Copyright (C) 2002, 2005-2022 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. @@ -12,7 +12,7 @@ AC_DEFUN([gl_STRCASE], AC_DEFUN([gl_FUNC_STRCASECMP], [ - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) AC_CHECK_FUNCS([strcasecmp]) if test $ac_cv_func_strcasecmp = no; then HAVE_STRCASECMP=0 @@ -21,7 +21,7 @@ AC_DEFUN([gl_FUNC_STRCASECMP], AC_DEFUN([gl_FUNC_STRNCASECMP], [ - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) AC_CHECK_FUNCS([strncasecmp]) if test $ac_cv_func_strncasecmp = yes; then HAVE_STRNCASECMP=1 diff --git a/gl/m4/strcasestr.m4 b/gl/m4/strcasestr.m4 index 8681a6a4..6344b7e5 100644 --- a/gl/m4/strcasestr.m4 +++ b/gl/m4/strcasestr.m4 @@ -1,5 +1,5 @@ -# strcasestr.m4 serial 21 -dnl Copyright (C) 2005, 2007-2013 Free Software Foundation, Inc. +# strcasestr.m4 serial 28 +dnl Copyright (C) 2005, 2007-2022 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. @@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. dnl Check that strcasestr is present and works. AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE], [ - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REQUIRE([gl_STRING_H_DEFAULTS]) dnl Persuade glibc to declare strcasestr(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) @@ -17,28 +17,38 @@ AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE], if test $ac_cv_func_strcasestr = no; then HAVE_STRCASESTR=0 else - if test "$gl_cv_func_memchr_works" != yes; then + if test $REPLACE_MEMCHR = 1; then REPLACE_STRCASESTR=1 else - dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092. + dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092 + dnl and https://sourceware.org/bugzilla/show_bug.cgi?id=23637. AC_CACHE_CHECK([whether strcasestr works], [gl_cv_func_strcasestr_works_always], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include /* for strcasestr */ + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include /* for __GNU_LIBRARY__, strcasestr */ +#ifdef __GNU_LIBRARY__ + #include + #if __GLIBC__ == 2 && __GLIBC_MINOR__ == 28 + Unlucky user + #endif +#endif #define P "_EF_BF_BD" #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P #define NEEDLE P P P P P -]], [[return !!strcasestr (HAYSTACK, NEEDLE); - ]])], - [gl_cv_func_strcasestr_works_always=yes], - [gl_cv_func_strcasestr_works_always=no], - [dnl glibc 2.12 and cygwin 1.7.7 have a known bug. uClibc is not - dnl affected, since it uses different source code for strcasestr - dnl than glibc. - dnl Assume that it works on all other platforms, even if it is not - dnl linear. - AC_EGREP_CPP([Lucky user], - [ +]], + [[return !!strcasestr (HAYSTACK, NEEDLE); + ]])], + [gl_cv_func_strcasestr_works_always=yes], + [gl_cv_func_strcasestr_works_always=no], + [dnl glibc 2.12 and cygwin 1.7.7 have a known bug. uClibc is not + dnl affected, since it uses different source code for strcasestr + dnl than glibc. + dnl Assume that it works on all other platforms, even if it is not + dnl linear. + AC_EGREP_CPP([Lucky user], + [ +#include /* for __GNU_LIBRARY__ */ #ifdef __GNU_LIBRARY__ #include #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ @@ -53,10 +63,10 @@ AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE], #else Lucky user #endif - ], - [gl_cv_func_strcasestr_works_always="guessing yes"], - [gl_cv_func_strcasestr_works_always="guessing no"]) - ]) + ], + [gl_cv_func_strcasestr_works_always="guessing yes"], + [gl_cv_func_strcasestr_works_always="$gl_cross_guess_normal"]) + ]) ]) case "$gl_cv_func_strcasestr_works_always" in *yes) ;; @@ -80,7 +90,7 @@ AC_DEFUN([gl_FUNC_STRCASESTR], #include /* for strcasestr */ #include /* for malloc */ #include /* for alarm */ -static void quit (int sig) { exit (sig + 128); } +static void quit (int sig) { _exit (sig + 128); } ]], [[ int result = 0; size_t m = 1000000; @@ -102,6 +112,9 @@ static void quit (int sig) { exit (sig + 128); } if (!strcasestr (haystack, needle)) result |= 1; } + /* Free allocated memory, in case some sanitizer is watching. */ + free (haystack); + free (needle); return result; ]])], [gl_cv_func_strcasestr_linear=yes], [gl_cv_func_strcasestr_linear=no], @@ -124,7 +137,7 @@ static void quit (int sig) { exit (sig + 128); } #endif ], [gl_cv_func_strcasestr_linear="guessing yes"], - [gl_cv_func_strcasestr_linear="guessing no"]) + [gl_cv_func_strcasestr_linear="$gl_cross_guess_normal"]) ]) ]) case "$gl_cv_func_strcasestr_linear" in diff --git a/gl/m4/strerror.m4 b/gl/m4/strerror.m4 index 3989844b..4716649b 100644 --- a/gl/m4/strerror.m4 +++ b/gl/m4/strerror.m4 @@ -1,19 +1,19 @@ -# strerror.m4 serial 17 -dnl Copyright (C) 2002, 2007-2013 Free Software Foundation, Inc. +# strerror.m4 serial 23 +dnl Copyright (C) 2002, 2007-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_STRERROR], [ - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REQUIRE([gl_STRING_H_DEFAULTS]) AC_REQUIRE([gl_HEADER_ERRNO_H]) AC_REQUIRE([gl_FUNC_STRERROR_0]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles m4_ifdef([gl_FUNC_STRERROR_R_WORKS], [ AC_REQUIRE([gl_FUNC_STRERROR_R_WORKS]) ]) - if test "$ERRNO_H:$REPLACE_STRERROR_0" = :0; then + if test "$GL_GENERATE_ERRNO_H:$REPLACE_STRERROR_0" = false:0; then AC_CACHE_CHECK([for working strerror function], [gl_cv_func_working_strerror], [AC_RUN_IFELSE( @@ -24,10 +24,12 @@ AC_DEFUN([gl_FUNC_STRERROR], [gl_cv_func_working_strerror=yes], [gl_cv_func_working_strerror=no], [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_working_strerror="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_working_strerror="guessing no" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_working_strerror="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_working_strerror="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_working_strerror="$gl_cross_guess_normal" ;; esac ]) ]) @@ -78,10 +80,14 @@ AC_DEFUN([gl_FUNC_STRERROR_0], [gl_cv_func_strerror_0_works=yes], [gl_cv_func_strerror_0_works=no], [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_strerror_0_works="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_strerror_0_works="guessing no" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_strerror_0_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_strerror_0_works="guessing yes" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_strerror_0_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_strerror_0_works="$gl_cross_guess_normal" ;; esac ]) ]) diff --git a/gl/m4/string_h.m4 b/gl/m4/string_h.m4 index cc5fbbb3..9e09b96e 100644 --- a/gl/m4/string_h.m4 +++ b/gl/m4/string_h.m4 @@ -1,25 +1,19 @@ # Configure a GNU-like replacement for . -# Copyright (C) 2007-2013 Free Software Foundation, Inc. +# Copyright (C) 2007-2022 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 21 +# serial 34 # Written by Paul Eggert. -AC_DEFUN([gl_HEADER_STRING_H], +AC_DEFUN_ONCE([gl_STRING_H], [ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_HEADER_STRING_H_BODY]) -]) - -AC_DEFUN([gl_HEADER_STRING_H_BODY], -[ - AC_REQUIRE([AC_C_RESTRICT]) - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + dnl Ensure to expand the default settings once only, before all statements + dnl that occur in other macros. + AC_REQUIRE([gl_STRING_H_DEFAULTS]) gl_NEXT_HEADERS([string.h]) dnl Check for declarations of anything we want to poison if the @@ -29,62 +23,88 @@ 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 strerrorname_np sigabbrev_np sigdescr_np strsignal strverscmp]) + + AC_REQUIRE([AC_C_RESTRICT]) ]) +# gl_STRING_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_STRING_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_STRING_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) -AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], [ - GNULIB_FFSL=0; AC_SUBST([GNULIB_FFSL]) - GNULIB_FFSLL=0; AC_SUBST([GNULIB_FFSLL]) - GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) - GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) - GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) - GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) - GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR]) - GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY]) - GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY]) - GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL]) - GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP]) - GNULIB_STRNCAT=0; AC_SUBST([GNULIB_STRNCAT]) - GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP]) - GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN]) - GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK]) - GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP]) - GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR]) - GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR]) - GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R]) - GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN]) - GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN]) - GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR]) - GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR]) - GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR]) - GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP]) - GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP]) - GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP]) - GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR]) - GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN]) - GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK]) - GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN]) - GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) - 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_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) - GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) - HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) + m4_defun(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPLICIT_BZERO]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFSL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFSLL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMMEM]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMPCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMRCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RAWMEMCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPNCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCHRNUL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRDUP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNDUP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNLEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPBRK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSEP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSRCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSTR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCASECMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNCASECMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSPCASECMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCASESTR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCSPN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSPBRK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSPN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSEP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOK_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERRORNAME_NP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGABBREV_NP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGDESCR_NP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSIGNAL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRVERSCMP]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MEMCCPY], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_STRDUP], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS]) + dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized. + gl_STDLIB_H_REQUIRE_DEFAULTS + AC_REQUIRE([gl_STRING_H_DEFAULTS]) +]) + +AC_DEFUN([gl_STRING_H_DEFAULTS], +[ + HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO]) HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL]) - HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR]) HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR]) @@ -100,21 +120,26 @@ 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_STRERRORNAME_NP=1; AC_SUBST([HAVE_STRERRORNAME_NP]) + HAVE_SIGABBREV_NP=1; AC_SUBST([HAVE_SIGABBREV_NP]) + 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]) + REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) + REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) + REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) + REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) - REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) + REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) - REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) - REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) - REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) + REPLACE_STRERRORNAME_NP=0; AC_SUBST([REPLACE_STRERRORNAME_NP]) REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) - REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R]) ]) diff --git a/gl/m4/strings_h.m4 b/gl/m4/strings_h.m4 index 76ef2424..6965b7c1 100644 --- a/gl/m4/strings_h.m4 +++ b/gl/m4/strings_h.m4 @@ -1,21 +1,16 @@ # Configure a replacement for . -# serial 6 +# serial 9 -# Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_HEADER_STRINGS_H], +AC_DEFUN_ONCE([gl_STRINGS_H], [ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_HEADER_STRINGS_H_BODY]) -]) - -AC_DEFUN([gl_HEADER_STRINGS_H_BODY], -[ - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + dnl Ensure to expand the default settings once only, before all statements + dnl that occur in other macros. + AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) gl_CHECK_NEXT_HEADERS([strings.h]) if test $ac_cv_header_strings_h = yes; then @@ -35,16 +30,31 @@ AC_DEFUN([gl_HEADER_STRINGS_H_BODY], ]], [ffs strcasecmp strncasecmp]) ]) +# gl_STRINGS_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_STRINGS_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_STRINGS_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ]) -AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS], +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_STRINGS_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_STRINGS_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFS]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_STRINGS_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) +]) + +AC_DEFUN([gl_STRINGS_H_DEFAULTS], [ - GNULIB_FFS=0; AC_SUBST([GNULIB_FFS]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_FFS=1; AC_SUBST([HAVE_FFS]) HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) diff --git a/gl/m4/strndup.m4 b/gl/m4/strndup.m4 deleted file mode 100644 index a1f82743..00000000 --- a/gl/m4/strndup.m4 +++ /dev/null @@ -1,55 +0,0 @@ -# strndup.m4 serial 21 -dnl Copyright (C) 2002-2003, 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_STRNDUP], -[ - dnl Persuade glibc to declare strndup(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - AC_CHECK_DECLS_ONCE([strndup]) - AC_CHECK_FUNCS_ONCE([strndup]) - if test $ac_cv_have_decl_strndup = no; then - HAVE_DECL_STRNDUP=0 - fi - - if test $ac_cv_func_strndup = yes; then - HAVE_STRNDUP=1 - # AIX 4.3.3, AIX 5.1 have a function that fails to add the terminating '\0'. - AC_CACHE_CHECK([for working strndup], [gl_cv_func_strndup_works], - [AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[#include - #include ]], [[ -#if !HAVE_DECL_STRNDUP - extern - #ifdef __cplusplus - "C" - #endif - char *strndup (const char *, size_t); -#endif - char *s; - s = strndup ("some longer string", 15); - free (s); - s = strndup ("shorter string", 13); - return s[13] != '\0';]])], - [gl_cv_func_strndup_works=yes], - [gl_cv_func_strndup_works=no], - [ -changequote(,)dnl - case $host_os in - aix | aix[3-6]*) gl_cv_func_strndup_works="guessing no";; - *) gl_cv_func_strndup_works="guessing yes";; - esac -changequote([,])dnl - ])]) - case $gl_cv_func_strndup_works in - *no) REPLACE_STRNDUP=1 ;; - esac - else - HAVE_STRNDUP=0 - fi -]) diff --git a/gl/m4/strnlen.m4 b/gl/m4/strnlen.m4 deleted file mode 100644 index eae82b77..00000000 --- a/gl/m4/strnlen.m4 +++ /dev/null @@ -1,30 +0,0 @@ -# strnlen.m4 serial 13 -dnl Copyright (C) 2002-2003, 2005-2007, 2009-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_STRNLEN], -[ - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - - dnl Persuade glibc to declare strnlen(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_CHECK_DECLS_ONCE([strnlen]) - if test $ac_cv_have_decl_strnlen = no; then - HAVE_DECL_STRNLEN=0 - else - m4_pushdef([AC_LIBOBJ], [:]) - dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). - AC_FUNC_STRNLEN - m4_popdef([AC_LIBOBJ]) - if test $ac_cv_func_strnlen_working = no; then - REPLACE_STRNLEN=1 - fi - fi -]) - -# Prerequisites of lib/strnlen.c. -AC_DEFUN([gl_PREREQ_STRNLEN], [:]) diff --git a/gl/m4/strsep.m4 b/gl/m4/strsep.m4 index 825fdb81..602f96ab 100644 --- a/gl/m4/strsep.m4 +++ b/gl/m4/strsep.m4 @@ -1,5 +1,5 @@ -# strsep.m4 serial 10 -dnl Copyright (C) 2002-2004, 2007, 2009-2013 Free Software Foundation, Inc. +# strsep.m4 serial 11 +dnl Copyright (C) 2002-2004, 2007, 2009-2022 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. @@ -12,7 +12,7 @@ AC_DEFUN([gl_FUNC_STRSEP], dnl The strsep() declaration in lib/string.in.h uses 'restrict'. AC_REQUIRE([AC_C_RESTRICT]) - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REQUIRE([gl_STRING_H_DEFAULTS]) AC_CHECK_FUNCS([strsep]) if test $ac_cv_func_strsep = no; then HAVE_STRSEP=0 diff --git a/gl/m4/strstr.m4 b/gl/m4/strstr.m4 index c486bdb0..6cc20727 100644 --- a/gl/m4/strstr.m4 +++ b/gl/m4/strstr.m4 @@ -1,5 +1,5 @@ -# strstr.m4 serial 16 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +# strstr.m4 serial 24 +dnl Copyright (C) 2008-2022 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. @@ -7,30 +7,40 @@ dnl with or without modifications, as long as this notice is preserved. dnl Check that strstr works. AC_DEFUN([gl_FUNC_STRSTR_SIMPLE], [ - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REQUIRE([gl_STRING_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_MEMCHR]) - if test "$gl_cv_func_memchr_works" != yes; then + if test $REPLACE_MEMCHR = 1; then REPLACE_STRSTR=1 else - dnl Detect http://sourceware.org/bugzilla/show_bug.cgi?id=12092. + dnl Detect https://sourceware.org/bugzilla/show_bug.cgi?id=12092 + dnl and https://sourceware.org/bugzilla/show_bug.cgi?id=23637. AC_CACHE_CHECK([whether strstr works], [gl_cv_func_strstr_works_always], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include /* for strstr */ + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include /* for __GNU_LIBRARY__, strstr */ +#ifdef __GNU_LIBRARY__ + #include + #if __GLIBC__ == 2 && __GLIBC_MINOR__ == 28 + Unlucky user + #endif +#endif #define P "_EF_BF_BD" #define HAYSTACK "F_BD_CE_BD" P P P P "_C3_88_20" P P P "_C3_A7_20" P #define NEEDLE P P P P P -]], [[return !!strstr (HAYSTACK, NEEDLE); - ]])], - [gl_cv_func_strstr_works_always=yes], - [gl_cv_func_strstr_works_always=no], - [dnl glibc 2.12 and cygwin 1.7.7 have a known bug. uClibc is not - dnl affected, since it uses different source code for strstr than - dnl glibc. - dnl Assume that it works on all other platforms, even if it is not - dnl linear. - AC_EGREP_CPP([Lucky user], - [ +]], + [[return !!strstr (HAYSTACK, NEEDLE); + ]])], + [gl_cv_func_strstr_works_always=yes], + [gl_cv_func_strstr_works_always=no], + [dnl glibc 2.12 and cygwin 1.7.7 have a known bug. uClibc is not + dnl affected, since it uses different source code for strstr than + dnl glibc. + dnl Assume that it works on all other platforms, even if it is not + dnl linear. + AC_EGREP_CPP([Lucky user], + [ +#include /* for __GNU_LIBRARY__ */ #ifdef __GNU_LIBRARY__ #include #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ > 12) || (__GLIBC__ > 2)) \ @@ -45,10 +55,10 @@ AC_DEFUN([gl_FUNC_STRSTR_SIMPLE], #else Lucky user #endif - ], - [gl_cv_func_strstr_works_always="guessing yes"], - [gl_cv_func_strstr_works_always="guessing no"]) - ]) + ], + [gl_cv_func_strstr_works_always="guessing yes"], + [gl_cv_func_strstr_works_always="$gl_cross_guess_normal"]) + ]) ]) case "$gl_cv_func_strstr_works_always" in *yes) ;; @@ -67,11 +77,17 @@ AC_DEFUN([gl_FUNC_STRSTR], AC_CACHE_CHECK([whether strstr works in linear time], [gl_cv_func_strstr_linear], [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#ifdef __MVS__ +/* z/OS does not deliver signals while strstr() is running (thanks to + restrictions on its LE runtime), which prevents us from limiting the + running time of this test. */ +# error "This test does not work properly on z/OS" +#endif #include /* for signal */ #include /* for strstr */ #include /* for malloc */ #include /* for alarm */ -static void quit (int sig) { exit (sig + 128); } +static void quit (int sig) { _exit (sig + 128); } ]], [[ int result = 0; size_t m = 1000000; @@ -93,6 +109,9 @@ static void quit (int sig) { exit (sig + 128); } if (!strstr (haystack, needle)) result |= 1; } + /* Free allocated memory, in case some sanitizer is watching. */ + free (haystack); + free (needle); return result; ]])], [gl_cv_func_strstr_linear=yes], [gl_cv_func_strstr_linear=no], @@ -117,7 +136,7 @@ static void quit (int sig) { exit (sig + 128); } #endif ], [gl_cv_func_strstr_linear="guessing yes"], - [gl_cv_func_strstr_linear="guessing no"]) + [gl_cv_func_strstr_linear="$gl_cross_guess_normal"]) ]) ]) case "$gl_cv_func_strstr_linear" in diff --git a/gl/m4/sys_socket_h.m4 b/gl/m4/sys_socket_h.m4 index 94863776..ba3ae68e 100644 --- a/gl/m4/sys_socket_h.m4 +++ b/gl/m4/sys_socket_h.m4 @@ -1,12 +1,12 @@ -# sys_socket_h.m4 serial 23 -dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. +# sys_socket_h.m4 serial 29 +dnl Copyright (C) 2005-2022 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 From Simon Josefsson. -AC_DEFUN([gl_HEADER_SYS_SOCKET], +AC_DEFUN_ONCE([gl_SYS_SOCKET_H], [ AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) AC_REQUIRE([AC_CANONICAL_HOST]) @@ -22,6 +22,7 @@ AC_DEFUN([gl_HEADER_SYS_SOCKET], ;; esac + GL_GENERATE_SYS_SOCKET_H=false AC_CACHE_CHECK([whether is self-contained], [gl_cv_header_sys_socket_h_selfcontained], [ @@ -44,7 +45,7 @@ AC_DEFUN([gl_HEADER_SYS_SOCKET], [gl_cv_header_sys_socket_h_shut=no]) ]) if test $gl_cv_header_sys_socket_h_shut = no; then - SYS_SOCKET_H='sys/socket.h' + GL_GENERATE_SYS_SOCKET_H=true fi fi fi @@ -83,7 +84,7 @@ AC_DEFUN([gl_HEADER_SYS_SOCKET], fi if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \ || test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then - SYS_SOCKET_H='sys/socket.h' + GL_GENERATE_SYS_SOCKET_H=true fi gl_PREREQ_SYS_H_WINSOCK2 @@ -95,6 +96,8 @@ AC_DEFUN([gl_HEADER_SYS_SOCKET], #include ]], [socket connect accept bind getpeername getsockname getsockopt listen recv send recvfrom sendto setsockopt shutdown accept4]) + + AC_REQUIRE([AC_C_RESTRICT]) ]) AC_DEFUN([gl_PREREQ_SYS_H_SOCKET], @@ -104,17 +107,11 @@ AC_DEFUN([gl_PREREQ_SYS_H_SOCKET], gl_CHECK_NEXT_HEADERS([sys/socket.h]) if test $ac_cv_header_sys_socket_h = yes; then HAVE_SYS_SOCKET_H=1 - HAVE_WS2TCPIP_H=0 else HAVE_SYS_SOCKET_H=0 - if test $ac_cv_header_ws2tcpip_h = yes; then - HAVE_WS2TCPIP_H=1 - else - HAVE_WS2TCPIP_H=0 - fi fi AC_SUBST([HAVE_SYS_SOCKET_H]) - AC_SUBST([HAVE_WS2TCPIP_H]) + gl_PREREQ_SYS_H_WS2TCPIP ]) # Common prerequisites of the replacement and of the @@ -142,32 +139,65 @@ AC_DEFUN([gl_PREREQ_SYS_H_WINSOCK2], AC_SUBST([HAVE_WINSOCK2_H]) ]) +# Common prerequisites of the replacement and of the +# replacement. +# Sets and substitutes HAVE_WS2TCPIP_H. +AC_DEFUN([gl_PREREQ_SYS_H_WS2TCPIP], +[ + AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) + if test $ac_cv_header_sys_socket_h = yes; then + HAVE_WS2TCPIP_H=0 + else + if test $ac_cv_header_ws2tcpip_h = yes; then + HAVE_WS2TCPIP_H=1 + else + HAVE_WS2TCPIP_H=0 + fi + fi + AC_SUBST([HAVE_WS2TCPIP_H]) +]) + +# gl_SYS_SOCKET_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_SYS_SOCKET_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_SYS_SOCKET_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_SOCKET_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SOCKET]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CONNECT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCEPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_BIND]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPEERNAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSOCKNAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSOCKOPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LISTEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RECV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SEND]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RECVFROM]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SENDTO]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETSOCKOPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SHUTDOWN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCEPT4]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_SOCKET_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) +]) + AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS], [ - GNULIB_SOCKET=0; AC_SUBST([GNULIB_SOCKET]) - GNULIB_CONNECT=0; AC_SUBST([GNULIB_CONNECT]) - GNULIB_ACCEPT=0; AC_SUBST([GNULIB_ACCEPT]) - GNULIB_BIND=0; AC_SUBST([GNULIB_BIND]) - GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME]) - GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME]) - GNULIB_GETSOCKOPT=0; AC_SUBST([GNULIB_GETSOCKOPT]) - GNULIB_LISTEN=0; AC_SUBST([GNULIB_LISTEN]) - GNULIB_RECV=0; AC_SUBST([GNULIB_RECV]) - GNULIB_SEND=0; AC_SUBST([GNULIB_SEND]) - GNULIB_RECVFROM=0; AC_SUBST([GNULIB_RECVFROM]) - GNULIB_SENDTO=0; AC_SUBST([GNULIB_SENDTO]) - GNULIB_SETSOCKOPT=0; AC_SUBST([GNULIB_SETSOCKOPT]) - GNULIB_SHUTDOWN=0; AC_SUBST([GNULIB_SHUTDOWN]) - GNULIB_ACCEPT4=0; AC_SUBST([GNULIB_ACCEPT4]) HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) diff --git a/gl/m4/sys_stat_h.m4 b/gl/m4/sys_stat_h.m4 new file mode 100644 index 00000000..2adbfdee --- /dev/null +++ b/gl/m4/sys_stat_h.m4 @@ -0,0 +1,129 @@ +# sys_stat_h.m4 serial 42 -*- Autoconf -*- +dnl Copyright (C) 2006-2022 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 From Eric Blake. +dnl Provide a GNU-like . + +AC_DEFUN_ONCE([gl_SYS_STAT_H], +[ + AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) + + dnl Check for broken stat macros. + AC_REQUIRE([AC_HEADER_STAT]) + + gl_CHECK_NEXT_HEADERS([sys/stat.h]) + + dnl Ensure the type mode_t gets defined. + AC_REQUIRE([AC_TYPE_MODE_T]) + + dnl Whether to enable precise timestamps in 'struct stat'. + m4_ifdef([gl_WINDOWS_STAT_TIMESPEC], [ + AC_REQUIRE([gl_WINDOWS_STAT_TIMESPEC]) + ], [ + WINDOWS_STAT_TIMESPEC=0 + ]) + AC_SUBST([WINDOWS_STAT_TIMESPEC]) + + dnl Whether to ensure that struct stat.st_size is 64-bit wide. + m4_ifdef([gl_LARGEFILE], [ + AC_REQUIRE([gl_LARGEFILE]) + ], [ + WINDOWS_64_BIT_ST_SIZE=0 + ]) + AC_SUBST([WINDOWS_64_BIT_ST_SIZE]) + + dnl Define types that are supposed to be defined in or + dnl . + AC_CHECK_TYPE([nlink_t], [], + [AC_DEFINE([nlink_t], [int], + [Define to the type of st_nlink in struct stat, or a supertype.])], + [#include + #include ]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[#include + ]], [chmod fchmodat fstat fstatat futimens getumask lchmod lstat + mkdirat mkfifo mkfifoat mknod mknodat stat utimensat]) + + AC_REQUIRE([AC_C_RESTRICT]) +]) + +# gl_SYS_STAT_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. +AC_DEFUN([gl_SYS_STAT_MODULE_INDICATOR], +[ + dnl Ensure to expand the default settings once only. + gl_SYS_STAT_H_REQUIRE_DEFAULTS + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_SYS_STAT_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS], [ + gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHMOD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHMODAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FUTIMENS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUMASK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LCHMOD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LSTAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDIR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDIRAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKFIFO]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKFIFOAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKNOD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKNODAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UTIMENSAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OVERRIDES_STRUCT_STAT]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CHMOD], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MKDIR], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_UMASK], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) +]) + +AC_DEFUN([gl_SYS_STAT_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_FCHMODAT=1; AC_SUBST([HAVE_FCHMODAT]) + HAVE_FSTATAT=1; AC_SUBST([HAVE_FSTATAT]) + HAVE_FUTIMENS=1; AC_SUBST([HAVE_FUTIMENS]) + HAVE_GETUMASK=1; AC_SUBST([HAVE_GETUMASK]) + HAVE_LCHMOD=1; AC_SUBST([HAVE_LCHMOD]) + HAVE_LSTAT=1; AC_SUBST([HAVE_LSTAT]) + HAVE_MKDIRAT=1; AC_SUBST([HAVE_MKDIRAT]) + HAVE_MKFIFO=1; AC_SUBST([HAVE_MKFIFO]) + HAVE_MKFIFOAT=1; AC_SUBST([HAVE_MKFIFOAT]) + HAVE_MKNOD=1; AC_SUBST([HAVE_MKNOD]) + HAVE_MKNODAT=1; AC_SUBST([HAVE_MKNODAT]) + HAVE_UTIMENSAT=1; AC_SUBST([HAVE_UTIMENSAT]) + REPLACE_CHMOD=0; AC_SUBST([REPLACE_CHMOD]) + REPLACE_FCHMODAT=0; AC_SUBST([REPLACE_FCHMODAT]) + REPLACE_FSTAT=0; AC_SUBST([REPLACE_FSTAT]) + REPLACE_FSTATAT=0; AC_SUBST([REPLACE_FSTATAT]) + REPLACE_FUTIMENS=0; AC_SUBST([REPLACE_FUTIMENS]) + 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]) +]) diff --git a/gl/m4/sys_types_h.m4 b/gl/m4/sys_types_h.m4 index d15c1b37..a5bef220 100644 --- a/gl/m4/sys_types_h.m4 +++ b/gl/m4/sys_types_h.m4 @@ -1,5 +1,5 @@ -# sys_types_h.m4 serial 5 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. +# sys_types_h.m4 serial 13 +dnl Copyright (C) 2011-2022 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. @@ -7,6 +7,10 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN_ONCE([gl_SYS_TYPES_H], [ AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS]) + + dnl Use sane struct stat types in OpenVMS 8.2 and later. + AC_DEFINE([_USE_STD_STAT], 1, [For standard stat data types on VMS.]) + gl_NEXT_HEADERS([sys/types.h]) dnl Ensure the type pid_t gets defined. @@ -17,8 +21,50 @@ AC_DEFUN_ONCE([gl_SYS_TYPES_H], dnl Whether to override the 'off_t' type. AC_REQUIRE([gl_TYPE_OFF_T]) + + dnl Whether to override the 'dev_t' and 'ino_t' types. + m4_ifdef([gl_WINDOWS_STAT_INODES], [ + AC_REQUIRE([gl_WINDOWS_STAT_INODES]) + ], [ + WINDOWS_STAT_INODES=0 + ]) + AC_SUBST([WINDOWS_STAT_INODES]) +]) + +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_SYS_TYPES_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_TYPE_H_MODULE_INDICATOR_DEFAULTS], [ + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_TYPE_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS]) ]) AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS], [ ]) + +# This works around a buggy version in autoconf <= 2.69. +# See +# The 2.70 version isn't quoted properly, so override it too. + +m4_version_prereq([2.70.1], [], [ + +m4_undefine([AC_HEADER_MAJOR]) +AC_DEFUN([AC_HEADER_MAJOR], +[AC_CHECK_HEADERS_ONCE([sys/types.h]) +AC_CHECK_HEADER([sys/mkdev.h], + [AC_DEFINE([MAJOR_IN_MKDEV], [1], + [Define to 1 if `major', `minor', and `makedev' are + declared in .])]) +if test $ac_cv_header_sys_mkdev_h = no; then + AC_CHECK_HEADER([sys/sysmacros.h], + [AC_DEFINE([MAJOR_IN_SYSMACROS], [1], + [Define to 1 if `major', `minor', and `makedev' + are declared in .])]) +fi +])# AC_HEADER_MAJOR + +]) diff --git a/gl/m4/sys_uio_h.m4 b/gl/m4/sys_uio_h.m4 index c75cbbd0..36f55ead 100644 --- a/gl/m4/sys_uio_h.m4 +++ b/gl/m4/sys_uio_h.m4 @@ -1,10 +1,10 @@ -# sys_uio_h.m4 serial 1 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. +# sys_uio_h.m4 serial 3 +dnl Copyright (C) 2011-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_HEADER_SYS_UIO], +AC_DEFUN_ONCE([gl_SYS_UIO_H], [ AC_REQUIRE([gl_SYS_UIO_H_DEFAULTS]) dnl is always overridden, because of GNULIB_POSIXCHECK. @@ -17,15 +17,30 @@ AC_DEFUN([gl_HEADER_SYS_UIO], AC_SUBST([HAVE_SYS_UIO_H]) ]) +# gl_SYS_UIO_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_SYS_UIO_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_SYS_UIO_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_SYS_UIO_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_SYS_UIO_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_UIO_H_MODULE_INDICATOR_DEFAULTS], [ + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_UIO_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_SYS_UIO_H_DEFAULTS]) +]) + AC_DEFUN([gl_SYS_UIO_H_DEFAULTS], [ ]) diff --git a/gl/m4/threadlib.m4 b/gl/m4/threadlib.m4 index 26bdeb58..ecb4970a 100644 --- a/gl/m4/threadlib.m4 +++ b/gl/m4/threadlib.m4 @@ -1,11 +1,388 @@ -# threadlib.m4 serial 10 (gettext-0.18.2) -dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. +# threadlib.m4 serial 32 +dnl Copyright (C) 2005-2022 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 From Bruno Haible. +AC_PREREQ([2.60]) + +dnl The general structure of the multithreading modules in gnulib is that we +dnl have three set of modules: +dnl +dnl * POSIX API: +dnl pthread, which combines +dnl pthread-h +dnl pthread-thread +dnl pthread-once +dnl pthread-mutex +dnl pthread-rwlock +dnl pthread-cond +dnl pthread-tss +dnl pthread-spin +dnl sched_yield +dnl +dnl * ISO C API: +dnl threads, which combines +dnl threads-h +dnl thrd +dnl mtx +dnl cnd +dnl tss +dnl +dnl * Gnulib API, with an implementation that can be chosen at configure +dnl time through the option --enable-threads=... +dnl thread +dnl lock +dnl cond +dnl tls +dnl yield +dnl +dnl They are independent, except for the fact that +dnl - the implementation of the ISO C API may use the POSIX (or some other +dnl platform dependent) API, +dnl - the implementation of the Gnulib API may use the POSIX or ISO C or +dnl some other platform dependent API, depending on the --enable-threads +dnl option. +dnl +dnl This file contains macros for all of these APIs! + +dnl ============================================================================ +dnl Macros for all thread APIs + +AC_DEFUN([gl_ANYTHREADLIB_EARLY], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + if test -z "$gl_anythreadlib_early_done"; then + case "$host_os" in + osf*) + # On OSF/1, the compiler needs the flag -D_REENTRANT so that it + # groks . cc also understands the flag -pthread, but + # we don't use it because 1. gcc-2.95 doesn't understand -pthread, + # 2. putting a flag into CPPFLAGS that has an effect on the linker + # causes the AC_LINK_IFELSE test below to succeed unexpectedly, + # leading to wrong values of LIBTHREAD and LTLIBTHREAD. + CPPFLAGS="$CPPFLAGS -D_REENTRANT" + ;; + esac + # Some systems optimize for single-threaded programs by default, and + # need special flags to disable these optimizations. For example, the + # definition of 'errno' in . + case "$host_os" in + aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; + solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; + esac + gl_anythreadlib_early_done=done + fi +]) + +dnl Checks whether the compiler and linker support weak declarations of symbols. + +AC_DEFUN([gl_WEAK_SYMBOLS], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether imported symbols can be declared weak], + [gl_cv_have_weak], + [case "$host_os" in + cygwin*) + dnl On Cygwin 3.2.0 with gcc 10.2, the test below would succeed, but + dnl programs that use pthread_in_use() with weak symbol references + dnl crash miserably at runtime. + gl_cv_have_weak="guessing no" + ;; + *) + gl_cv_have_weak=no + dnl First, test whether the compiler accepts it syntactically. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern void xyzzy (); +#pragma weak xyzzy]], + [[xyzzy();]])], + [gl_cv_have_weak=maybe]) + if test $gl_cv_have_weak = maybe; then + dnl Second, test whether it actually works. On Cygwin 1.7.2, with + dnl gcc 4.3, symbols declared weak always evaluate to the address 0. + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#pragma weak fputs +int main () +{ + return (fputs == NULL); +}]])], + [gl_cv_have_weak=yes], + [gl_cv_have_weak=no], + [dnl When cross-compiling, assume that only ELF platforms support + dnl weak symbols. + AC_EGREP_CPP([Extensible Linking Format], + [#ifdef __ELF__ + Extensible Linking Format + #endif + ], + [gl_cv_have_weak="guessing yes"], + [gl_cv_have_weak="guessing no"]) + ]) + fi + ;; + esac + dnl But when linking statically, weak symbols don't work. + case " $LDFLAGS " in + *" -static "*) gl_cv_have_weak=no ;; + esac + dnl Test for a bug in FreeBSD 11: A link error occurs when using a weak + dnl symbol and linking against a shared library that has a dependency on + dnl the shared library that defines the symbol. + case "$gl_cv_have_weak" in + *yes) + case "$host_os" in + freebsd* | dragonfly* | midnightbsd*) + : > conftest1.c + $CC $CPPFLAGS $CFLAGS $LDFLAGS -fPIC -shared -o libempty.so conftest1.c -lpthread >&AS_MESSAGE_LOG_FD 2>&1 + cat < conftest2.c +#include +#pragma weak pthread_mutexattr_gettype +int main () +{ + return (pthread_mutexattr_gettype != NULL); +} +EOF + $CC $CPPFLAGS $CFLAGS $LDFLAGS -o conftest conftest2.c libempty.so >&AS_MESSAGE_LOG_FD 2>&1 \ + || gl_cv_have_weak=no + rm -f conftest1.c libempty.so conftest2.c conftest + ;; + esac + ;; + esac + ]) + case "$gl_cv_have_weak" in + *yes) + AC_DEFINE([HAVE_WEAK_SYMBOLS], [1], + [Define to 1 if the compiler and linker support weak declarations of symbols.]) + ;; + esac +]) + +dnl ============================================================================ +dnl Macros for the POSIX API + +dnl gl_PTHREADLIB +dnl ------------- +dnl Tests for the libraries needs for using the POSIX threads API. +dnl Sets the variable LIBPTHREAD to the linker options for use in a Makefile. +dnl Sets the variable LIBPMULTITHREAD, for programs that really need +dnl multithread functionality. The difference between LIBPTHREAD and +dnl LIBPMULTITHREAD is that on platforms supporting weak symbols, typically +dnl LIBPTHREAD is empty whereas LIBPMULTITHREAD is not. +dnl Sets the variable LIB_SCHED_YIELD to the linker options needed to use the +dnl sched_yield() function. +dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for +dnl multithread-safe programs. +dnl Defines the C macro HAVE_PTHREAD_API if (at least parts of) the POSIX +dnl threads API is available. + +dnl The guts of gl_PTHREADLIB. Needs to be expanded only once. + +AC_DEFUN([gl_PTHREADLIB_BODY], +[ + AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) + if test -z "$gl_pthreadlib_body_done"; then + gl_pthread_api=no + LIBPTHREAD= + LIBPMULTITHREAD= + # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that + # it groks . It's added above, in gl_ANYTHREADLIB_EARLY. + AC_CHECK_HEADER([pthread.h], + [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) + if test "$gl_have_pthread_h" = yes; then + # Other possible tests: + # -lpthreads (FSU threads, PCthreads) + # -lgthreads + # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist + # in libc. IRIX 6.5 has the first one in both libc and libpthread, but + # the second one only in libpthread, and lock.c needs it. + # + # If -pthread works, prefer it to -lpthread, since Ubuntu 14.04 + # needs -pthread for some reason. See: + # https://lists.gnu.org/r/bug-gnulib/2014-09/msg00023.html + save_LIBS=$LIBS + for gl_pthread in '' '-pthread'; do + LIBS="$LIBS $gl_pthread" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include + pthread_mutex_t m; + pthread_mutexattr_t ma; + ]], + [[pthread_mutex_lock (&m); + pthread_mutexattr_init (&ma);]])], + [gl_pthread_api=yes + LIBPTHREAD=$gl_pthread + LIBPMULTITHREAD=$gl_pthread]) + LIBS=$save_LIBS + test $gl_pthread_api = yes && break + done + echo "$as_me:__oline__: gl_pthread_api=$gl_pthread_api" >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: LIBPTHREAD=$LIBPTHREAD" >&AS_MESSAGE_LOG_FD + + gl_pthread_in_glibc=no + # On Linux with glibc >= 2.34, libc contains the fully functional + # pthread functions. + case "$host_os" in + linux*) + AC_EGREP_CPP([Lucky user], + [#include + #ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 34) || (__GLIBC__ > 2) + Lucky user + #endif + #endif + ], + [gl_pthread_in_glibc=yes], + []) + ;; + esac + echo "$as_me:__oline__: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&AS_MESSAGE_LOG_FD + + # Test for libpthread by looking for pthread_kill. (Not pthread_self, + # since it is defined as a macro on OSF/1.) + if test $gl_pthread_api = yes && test -z "$LIBPTHREAD"; then + # The program links fine without libpthread. But it may actually + # need to link with libpthread in order to create multiple threads. + AC_CHECK_LIB([pthread], [pthread_kill], + [if test $gl_pthread_in_glibc = yes; then + LIBPMULTITHREAD= + else + LIBPMULTITHREAD=-lpthread + # On Solaris and HP-UX, most pthread functions exist also in libc. + # Therefore pthread_in_use() needs to actually try to create a + # thread: pthread_create from libc will fail, whereas + # pthread_create will actually create a thread. + # On Solaris 10 or newer, this test is no longer needed, because + # libc contains the fully functional pthread functions. + case "$host_os" in + solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*) + AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], + [Define if the pthread_in_use() detection is hard.]) + esac + fi + ]) + elif test $gl_pthread_api != yes; then + # Some library is needed. Try libpthread and libc_r. + AC_CHECK_LIB([pthread], [pthread_kill], + [gl_pthread_api=yes + LIBPTHREAD=-lpthread + LIBPMULTITHREAD=-lpthread]) + if test $gl_pthread_api != yes; then + # For FreeBSD 4. + AC_CHECK_LIB([c_r], [pthread_kill], + [gl_pthread_api=yes + LIBPTHREAD=-lc_r + LIBPMULTITHREAD=-lc_r]) + fi + fi + echo "$as_me:__oline__: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&AS_MESSAGE_LOG_FD + fi + AC_MSG_CHECKING([whether POSIX threads API is available]) + AC_MSG_RESULT([$gl_pthread_api]) + AC_SUBST([LIBPTHREAD]) + AC_SUBST([LIBPMULTITHREAD]) + if test $gl_pthread_api = yes; then + AC_DEFINE([HAVE_PTHREAD_API], [1], + [Define if you have the header and the POSIX threads API.]) + fi + + dnl On some systems, sched_yield is in librt, rather than in libpthread. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[sched_yield ();]])], + [LIB_SCHED_YIELD= + ], + [dnl Solaris 7...10 has sched_yield in librt, not in libpthread or libc. + AC_CHECK_LIB([rt], [sched_yield], [LIB_SCHED_YIELD=-lrt], + [dnl Solaris 2.5.1, 2.6 has sched_yield in libposix4, not librt. + AC_CHECK_LIB([posix4], [sched_yield], [LIB_SCHED_YIELD=-lposix4])]) + ]) + AC_SUBST([LIB_SCHED_YIELD]) + + gl_pthreadlib_body_done=done + fi +]) + +AC_DEFUN([gl_PTHREADLIB], +[ + AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) + gl_PTHREADLIB_BODY +]) + +dnl ============================================================================ +dnl Macros for the ISO C API + +dnl gl_STDTHREADLIB +dnl --------------- +dnl Tests for the libraries needs for using the ISO C threads API. +dnl Sets the variable LIBSTDTHREAD to the linker options for use in a Makefile. +dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for +dnl multithread-safe programs. +dnl Defines the C macro HAVE_THREADS_H if (at least parts of) the ISO C threads +dnl API is available. + +dnl The guts of gl_STDTHREADLIB. Needs to be expanded only once. + +AC_DEFUN([gl_STDTHREADLIB_BODY], +[ + AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) + AC_REQUIRE([AC_CANONICAL_HOST]) + if test -z "$gl_stdthreadlib_body_done"; then + AC_CHECK_HEADERS_ONCE([threads.h]) + + case "$host_os" in + mingw*) + LIBSTDTHREAD= + ;; + *) + gl_PTHREADLIB_BODY + if test $ac_cv_header_threads_h = yes; then + dnl glibc >= 2.29 has thrd_create in libpthread. + dnl FreeBSD >= 10 has thrd_create in libstdthreads; this library depends + dnl on libpthread (for the symbol 'pthread_mutexattr_gettype'). + dnl glibc >= 2.34, AIX >= 7.1, and Solaris >= 11.4 have thrd_create in + dnl libc. + AC_CHECK_FUNCS([thrd_create]) + if test $ac_cv_func_thrd_create = yes; then + LIBSTDTHREAD= + else + AC_CHECK_LIB([stdthreads], [thrd_create], [ + LIBSTDTHREAD='-lstdthreads -lpthread' + ], [ + dnl Guess that thrd_create is in libpthread. + LIBSTDTHREAD="$LIBPMULTITHREAD" + ]) + fi + else + dnl Libraries needed by thrd.c, mtx.c, cnd.c, tss.c. + LIBSTDTHREAD="$LIBPMULTITHREAD $LIB_SCHED_YIELD" + fi + ;; + esac + AC_SUBST([LIBSTDTHREAD]) + + AC_MSG_CHECKING([whether ISO C threads API is available]) + AC_MSG_RESULT([$ac_cv_header_threads_h]) + gl_stdthreadlib_body_done=done + fi +]) + +AC_DEFUN([gl_STDTHREADLIB], +[ + AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) + gl_STDTHREADLIB_BODY +]) + +dnl ============================================================================ +dnl Macros for the Gnulib API + dnl gl_THREADLIB dnl ------------ dnl Tests for a multithreading library to be used. @@ -14,17 +391,25 @@ dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the dnl default is 'no', otherwise it is system dependent. In both cases, the user dnl can change the choice through the options --enable-threads=choice or dnl --disable-threads. -dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS, -dnl USE_PTH_THREADS, USE_WINDOWS_THREADS +dnl Defines at most one of the macros USE_ISOC_THREADS, USE_POSIX_THREADS, +dnl USE_ISOC_AND_POSIX_THREADS, USE_WINDOWS_THREADS. +dnl The choice --enable-threads=isoc+posix is available only on platforms that +dnl have both the ISO C and the POSIX threads APIs. It has the effect of using +dnl the ISO C API for most things and the POSIX API only for creating and +dnl controlling threads (because there is no equivalent to pthread_atfork in +dnl the ISO C API). dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with dnl libtool). dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for dnl programs that really need multithread functionality. The difference dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak -dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread". +dnl symbols, typically LIBTHREAD is empty whereas LIBMULTITHREAD is not. dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for dnl multithread-safe programs. +dnl Since support for GNU pth was removed, $LTLIBTHREAD and $LIBTHREAD have the +dnl same value, and similarly $LTLIBMULTITHREAD and $LIBMULTITHREAD have the +dnl same value. Only system libraries are needed. AC_DEFUN([gl_THREADLIB_EARLY], [ @@ -43,18 +428,15 @@ AC_DEFUN([gl_THREADLIB_EARLY_BODY], AC_REQUIRE([AC_CANONICAL_HOST]) dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems. - dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes - dnl AC_GNU_SOURCE. - m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], - [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], - [AC_REQUIRE([AC_GNU_SOURCE])]) + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl Check for multithreading. m4_ifdef([gl_THREADLIB_DEFAULT_NO], [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])], [m4_divert_text([DEFAULTS], [gl_use_threads_default=])]) + m4_divert_text([DEFAULTS], [gl_use_winpthreads_default=]) AC_ARG_ENABLE([threads], -AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [ -AC_HELP_STRING([--disable-threads], [build without multithread safety])]), +AS_HELP_STRING([--enable-threads={isoc|posix|isoc+posix|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [ +AS_HELP_STRING([--disable-threads], [build without multithread safety])]), [gl_use_threads=$enableval], [if test -n "$gl_use_threads_default"; then gl_use_threads="$gl_use_threads_default" @@ -64,41 +446,35 @@ changequote(,)dnl dnl Disable multithreading by default on OSF/1, because it interferes dnl with fork()/exec(): When msgexec is linked with -lpthread, its dnl child process gets an endless segmentation fault inside execvp(). + osf*) gl_use_threads=no ;; dnl Disable multithreading by default on Cygwin 1.5.x, because it has dnl bugs that lead to endless loops or crashes. See - dnl . - osf*) gl_use_threads=no ;; + dnl . cygwin*) case `uname -r` in 1.[0-5].*) gl_use_threads=no ;; *) gl_use_threads=yes ;; esac ;; + dnl Obey gl_AVOID_WINPTHREAD on mingw. + mingw*) + case "$gl_use_winpthreads_default" in + yes) gl_use_threads=posix ;; + no) gl_use_threads=windows ;; + *) gl_use_threads=yes ;; + esac + ;; *) gl_use_threads=yes ;; esac changequote([,])dnl fi ]) - if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then - # For using : - case "$host_os" in - osf*) - # On OSF/1, the compiler needs the flag -D_REENTRANT so that it - # groks . cc also understands the flag -pthread, but - # we don't use it because 1. gcc-2.95 doesn't understand -pthread, - # 2. putting a flag into CPPFLAGS that has an effect on the linker - # causes the AC_LINK_IFELSE test below to succeed unexpectedly, - # leading to wrong values of LIBTHREAD and LTLIBTHREAD. - CPPFLAGS="$CPPFLAGS -D_REENTRANT" - ;; - esac - # Some systems optimize for single-threaded programs by default, and - # need special flags to disable these optimizations. For example, the - # definition of 'errno' in . - case "$host_os" in - aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; - solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; - esac + if test "$gl_use_threads" = yes \ + || test "$gl_use_threads" = isoc \ + || test "$gl_use_threads" = posix \ + || test "$gl_use_threads" = isoc+posix; then + # For using or : + gl_ANYTHREADLIB_EARLY fi ]) @@ -114,168 +490,69 @@ AC_DEFUN([gl_THREADLIB_BODY], LTLIBMULTITHREAD= if test "$gl_use_threads" != no; then dnl Check whether the compiler and linker support weak declarations. - AC_CACHE_CHECK([whether imported symbols can be declared weak], - [gl_cv_have_weak], - [gl_cv_have_weak=no - dnl First, test whether the compiler accepts it syntactically. - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[extern void xyzzy (); -#pragma weak xyzzy]], - [[xyzzy();]])], - [gl_cv_have_weak=maybe]) - if test $gl_cv_have_weak = maybe; then - dnl Second, test whether it actually works. On Cygwin 1.7.2, with - dnl gcc 4.3, symbols declared weak always evaluate to the address 0. - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#pragma weak fputs -int main () -{ - return (fputs == NULL); -}]])], - [gl_cv_have_weak=yes], - [gl_cv_have_weak=no], - [dnl When cross-compiling, assume that only ELF platforms support - dnl weak symbols. - AC_EGREP_CPP([Extensible Linking Format], - [#ifdef __ELF__ - Extensible Linking Format - #endif - ], - [gl_cv_have_weak="guessing yes"], - [gl_cv_have_weak="guessing no"]) - ]) - fi - ]) - if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then - # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that - # it groks . It's added above, in gl_THREADLIB_EARLY_BODY. - AC_CHECK_HEADER([pthread.h], - [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) - if test "$gl_have_pthread_h" = yes; then - # Other possible tests: - # -lpthreads (FSU threads, PCthreads) - # -lgthreads - gl_have_pthread= - # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist - # in libc. IRIX 6.5 has the first one in both libc and libpthread, but - # the second one only in libpthread, and lock.c needs it. - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[pthread_mutex_lock((pthread_mutex_t*)0); - pthread_mutexattr_init((pthread_mutexattr_t*)0);]])], - [gl_have_pthread=yes]) - # Test for libpthread by looking for pthread_kill. (Not pthread_self, - # since it is defined as a macro on OSF/1.) - if test -n "$gl_have_pthread"; then - # The program links fine without libpthread. But it may actually - # need to link with libpthread in order to create multiple threads. - AC_CHECK_LIB([pthread], [pthread_kill], - [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread - # On Solaris and HP-UX, most pthread functions exist also in libc. - # Therefore pthread_in_use() needs to actually try to create a - # thread: pthread_create from libc will fail, whereas - # pthread_create will actually create a thread. - case "$host_os" in - solaris* | hpux*) - AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], - [Define if the pthread_in_use() detection is hard.]) - esac - ]) + gl_WEAK_SYMBOLS + if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then + dnl If we use weak symbols to implement pthread_in_use / pth_in_use / + dnl thread_in_use, we also need to test whether the ISO C 11 thrd_create + dnl facility is in use. + AC_CHECK_HEADERS_ONCE([threads.h]) + : + fi + if test "$gl_use_threads" = isoc || test "$gl_use_threads" = isoc+posix; then + AC_CHECK_HEADERS_ONCE([threads.h]) + gl_have_isoc_threads="$ac_cv_header_threads_h" + fi + if test "$gl_use_threads" = yes \ + || test "$gl_use_threads" = posix \ + || test "$gl_use_threads" = isoc+posix; then + gl_PTHREADLIB_BODY + LIBTHREAD=$LIBPTHREAD LTLIBTHREAD=$LIBPTHREAD + LIBMULTITHREAD=$LIBPMULTITHREAD LTLIBMULTITHREAD=$LIBPMULTITHREAD + if test $gl_pthread_api = yes; then + if test "$gl_use_threads" = isoc+posix && test "$gl_have_isoc_threads" = yes; then + gl_threads_api='isoc+posix' + AC_DEFINE([USE_ISOC_AND_POSIX_THREADS], [1], + [Define if the combination of the ISO C and POSIX multithreading APIs can be used.]) + LIBTHREAD= LTLIBTHREAD= else - # Some library is needed. Try libpthread and libc_r. - AC_CHECK_LIB([pthread], [pthread_kill], - [gl_have_pthread=yes - LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread - LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread]) - if test -z "$gl_have_pthread"; then - # For FreeBSD 4. - AC_CHECK_LIB([c_r], [pthread_kill], - [gl_have_pthread=yes - LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r - LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r]) - fi - fi - if test -n "$gl_have_pthread"; then gl_threads_api=posix AC_DEFINE([USE_POSIX_THREADS], [1], [Define if the POSIX multithreading library can be used.]) - if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then + if test -z "$LIBMULTITHREAD" && test -z "$LTLIBMULTITHREAD"; then + AC_DEFINE([USE_POSIX_THREADS_FROM_LIBC], [1], + [Define if references to the POSIX multithreading library are satisfied by libc.]) + else if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then AC_DEFINE([USE_POSIX_THREADS_WEAK], [1], [Define if references to the POSIX multithreading library should be made weak.]) - LIBTHREAD= - LTLIBTHREAD= + LIBTHREAD= LTLIBTHREAD= + else + case "$host_os" in + freebsd* | dragonfly* | midnightbsd*) + if test "x$LIBTHREAD" != "x$LIBMULTITHREAD"; then + dnl If weak symbols can't tell whether pthread_create(), pthread_key_create() + dnl etc. will succeed, we need a runtime test. + AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], + [Define if the pthread_in_use() detection is hard.]) + fi + ;; + esac fi fi fi fi fi - if test -z "$gl_have_pthread"; then - if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then - gl_have_solaristhread= - gl_save_LIBS="$LIBS" - LIBS="$LIBS -lthread" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[thr_self();]])], - [gl_have_solaristhread=yes]) - LIBS="$gl_save_LIBS" - if test -n "$gl_have_solaristhread"; then - gl_threads_api=solaris - LIBTHREAD=-lthread - LTLIBTHREAD=-lthread - LIBMULTITHREAD="$LIBTHREAD" - LTLIBMULTITHREAD="$LTLIBTHREAD" - AC_DEFINE([USE_SOLARIS_THREADS], [1], - [Define if the old Solaris multithreading library can be used.]) - if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then - AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1], - [Define if references to the old Solaris multithreading library should be made weak.]) - LIBTHREAD= - LTLIBTHREAD= - fi - fi + if test $gl_threads_api = none; then + if test "$gl_use_threads" = isoc && test "$gl_have_isoc_threads" = yes; then + gl_STDTHREADLIB_BODY + LIBTHREAD=$LIBSTDTHREAD LTLIBTHREAD=$LIBSTDTHREAD + LIBMULTITHREAD=$LIBSTDTHREAD LTLIBMULTITHREAD=$LIBSTDTHREAD + gl_threads_api=isoc + AC_DEFINE([USE_ISOC_THREADS], [1], + [Define if the ISO C multithreading library can be used.]) fi fi - if test "$gl_use_threads" = pth; then - gl_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_LINKFLAGS([pth]) - gl_have_pth= - gl_save_LIBS="$LIBS" - LIBS="$LIBS $LIBPTH" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include ]], [[pth_self();]])], - [gl_have_pth=yes]) - LIBS="$gl_save_LIBS" - if test -n "$gl_have_pth"; then - gl_threads_api=pth - LIBTHREAD="$LIBPTH" - LTLIBTHREAD="$LTLIBPTH" - LIBMULTITHREAD="$LIBTHREAD" - LTLIBMULTITHREAD="$LTLIBTHREAD" - AC_DEFINE([USE_PTH_THREADS], [1], - [Define if the GNU Pth multithreading library can be used.]) - if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then - if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then - AC_DEFINE([USE_PTH_THREADS_WEAK], [1], - [Define if references to the GNU Pth multithreading library should be made weak.]) - LIBTHREAD= - LTLIBTHREAD= - fi - fi - else - CPPFLAGS="$gl_save_CPPFLAGS" - fi - fi - if test -z "$gl_have_pthread"; then + if test $gl_threads_api = none; then case "$gl_use_threads" in yes | windows | win32) # The 'win32' is for backward compatibility. if { case "$host_os" in @@ -317,6 +594,21 @@ AC_DEFUN([gl_DISABLE_THREADS], [ ]) +dnl gl_AVOID_WINPTHREAD +dnl ------------------- +dnl Sets the gl_THREADLIB default so that on mingw, a dependency to the +dnl libwinpthread DLL (mingw-w64 winpthreads library) is avoided. +dnl The user can still override it at installation time, by using the +dnl configure option '--enable-threads'. + +AC_DEFUN([gl_AVOID_WINPTHREAD], [ + m4_divert_text([INIT_PREPARE], [gl_use_winpthreads_default=no]) +]) + + +dnl ============================================================================ + + dnl Survey of platforms: dnl dnl Platform Available Compiler Supports test-lock @@ -324,7 +616,11 @@ dnl flavours option weak result dnl --------------- --------- --------- -------- --------- dnl Linux 2.4/glibc posix -lpthread Y OK dnl -dnl GNU Hurd/glibc posix +dnl Linux/glibc 2.34 posix Y OK +dnl +dnl GNU Hurd/glibc posix -lpthread Y OK +dnl +dnl Ubuntu 14.04 posix -pthread Y OK dnl dnl FreeBSD 5.3 posix -lc_r Y dnl posix -lkse ? Y @@ -344,7 +640,6 @@ dnl dnl Mac OS X 10.[123] posix -lpthread Y OK dnl dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK -dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK dnl dnl HP-UX 11 posix -lpthread N (cc) OK dnl Y (gcc) @@ -358,8 +653,6 @@ dnl -lpthread (gcc) Y dnl dnl Cygwin posix -lpthread Y OK dnl -dnl Any of the above pth -lpth 0.0 -dnl dnl Mingw windows N OK dnl dnl BeOS 5 -- diff --git a/gl/m4/time_h.m4 b/gl/m4/time_h.m4 index 3b839005..98d7b6e0 100644 --- a/gl/m4/time_h.m4 +++ b/gl/m4/time_h.m4 @@ -1,8 +1,8 @@ # Configure a more-standard replacement for . -# Copyright (C) 2000-2001, 2003-2007, 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2000-2001, 2003-2007, 2009-2022 Free Software Foundation, Inc. -# serial 7 +# serial 19 # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10,23 +10,36 @@ # Written by Paul Eggert and Jim Meyering. -AC_DEFUN([gl_HEADER_TIME_H], +AC_DEFUN_ONCE([gl_TIME_H], [ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_HEADER_TIME_H_BODY]) -]) + dnl Ensure to expand the default settings once only, before all statements + dnl that occur in other macros. + AC_REQUIRE([gl_TIME_H_DEFAULTS]) -AC_DEFUN([gl_HEADER_TIME_H_BODY], -[ - AC_REQUIRE([AC_C_RESTRICT]) - AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) gl_NEXT_HEADERS([time.h]) AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC]) + + AC_REQUIRE([AC_C_RESTRICT]) + + AC_CACHE_CHECK([for TIME_UTC in ], + [gl_cv_time_h_has_TIME_UTC], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[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 -dnl in time.h, sys/time.h, or pthread.h. +dnl in time.h, sys/time.h, pthread.h, or unistd.h. AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC], [ @@ -44,6 +57,7 @@ AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC], TIME_H_DEFINES_STRUCT_TIMESPEC=0 SYS_TIME_H_DEFINES_STRUCT_TIMESPEC=0 PTHREAD_H_DEFINES_STRUCT_TIMESPEC=0 + UNISTD_H_DEFINES_STRUCT_TIMESPEC=0 if test $gl_cv_sys_struct_timespec_in_time_h = yes; then TIME_H_DEFINES_STRUCT_TIMESPEC=1 else @@ -70,40 +84,94 @@ AC_DEFUN([gl_CHECK_TYPE_STRUCT_TIMESPEC], [gl_cv_sys_struct_timespec_in_pthread_h=no])]) if test $gl_cv_sys_struct_timespec_in_pthread_h = yes; then PTHREAD_H_DEFINES_STRUCT_TIMESPEC=1 + else + AC_CACHE_CHECK([for struct timespec in ], + [gl_cv_sys_struct_timespec_in_unistd_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[static struct timespec x; x.tv_sec = x.tv_nsec;]])], + [gl_cv_sys_struct_timespec_in_unistd_h=yes], + [gl_cv_sys_struct_timespec_in_unistd_h=no])]) + if test $gl_cv_sys_struct_timespec_in_unistd_h = yes; then + UNISTD_H_DEFINES_STRUCT_TIMESPEC=1 + fi fi fi fi AC_SUBST([TIME_H_DEFINES_STRUCT_TIMESPEC]) AC_SUBST([SYS_TIME_H_DEFINES_STRUCT_TIMESPEC]) AC_SUBST([PTHREAD_H_DEFINES_STRUCT_TIMESPEC]) + AC_SUBST([UNISTD_H_DEFINES_STRUCT_TIMESPEC]) ]) +# gl_TIME_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_TIME_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_TIME_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) -AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_TIME_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_TIME_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CTIME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKTIME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALTIME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NANOSLEEP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRFTIME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPTIME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMEGM]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GET]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GETRES]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TZSET], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_TIME_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_TIME_H_DEFAULTS]) +]) + +AC_DEFUN([gl_TIME_H_DEFAULTS], [ - GNULIB_MKTIME=0; AC_SUBST([GNULIB_MKTIME]) - GNULIB_NANOSLEEP=0; AC_SUBST([GNULIB_NANOSLEEP]) - GNULIB_STRPTIME=0; AC_SUBST([GNULIB_STRPTIME]) - GNULIB_TIMEGM=0; AC_SUBST([GNULIB_TIMEGM]) - GNULIB_TIME_R=0; AC_SUBST([GNULIB_TIME_R]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DECL_LOCALTIME_R=1; AC_SUBST([HAVE_DECL_LOCALTIME_R]) 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]) + HAVE_TIMESPEC_GETRES=1; AC_SUBST([HAVE_TIMESPEC_GETRES]) + 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. dnl Otherwise, replace only if someone compiles with -DGNULIB_PORTCHECK; dnl this lets maintainers check for portability. + REPLACE_CTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_CTIME]) REPLACE_LOCALTIME_R=GNULIB_PORTCHECK; AC_SUBST([REPLACE_LOCALTIME_R]) REPLACE_MKTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_MKTIME]) REPLACE_NANOSLEEP=GNULIB_PORTCHECK; AC_SUBST([REPLACE_NANOSLEEP]) + REPLACE_STRFTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_STRFTIME]) REPLACE_TIMEGM=GNULIB_PORTCHECK; AC_SUBST([REPLACE_TIMEGM]) + REPLACE_TZSET=GNULIB_PORTCHECK; AC_SUBST([REPLACE_TZSET]) + + dnl Hack so that the time module doesn't depend on the sys_time module. + dnl First, default GNULIB_GETTIMEOFDAY to 0 if sys_time is absent. + : ${GNULIB_GETTIMEOFDAY=0}; AC_SUBST([GNULIB_GETTIMEOFDAY]) + dnl Second, it's OK to not use GNULIB_PORTCHECK for REPLACE_GMTIME + dnl and REPLACE_LOCALTIME, as portability to Solaris 2.6 and earlier + dnl is no longer a big deal. + REPLACE_GMTIME=0; AC_SUBST([REPLACE_GMTIME]) + REPLACE_LOCALTIME=0; AC_SUBST([REPLACE_LOCALTIME]) ]) diff --git a/gl/m4/time_r.m4 b/gl/m4/time_r.m4 index c388a831..8a1ad9da 100644 --- a/gl/m4/time_r.m4 +++ b/gl/m4/time_r.m4 @@ -1,6 +1,6 @@ dnl Reentrant time functions: localtime_r, gmtime_r. -dnl Copyright (C) 2003, 2006-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2003, 2006-2022 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. @@ -12,12 +12,20 @@ AC_DEFUN([gl_TIME_R], dnl Persuade glibc and Solaris to declare localtime_r. AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) + AC_REQUIRE([gl_TIME_H_DEFAULTS]) AC_REQUIRE([AC_C_RESTRICT]) dnl Some systems don't declare localtime_r() and gmtime_r() if _REENTRANT is dnl not defined. - AC_CHECK_DECLS([localtime_r], [], [], [[#include ]]) + AC_CHECK_DECLS([localtime_r], [], [], + [[/* mingw's provides the functions asctime_r, ctime_r, + gmtime_r, localtime_r only if or has + been included before. */ + #if defined __MINGW32__ + # include + #endif + #include + ]]) if test $ac_cv_have_decl_localtime_r = no; then HAVE_DECL_LOCALTIME_R=0 fi @@ -29,7 +37,14 @@ AC_DEFUN([gl_TIME_R], [gl_cv_time_r_posix], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[#include ]], + [[/* mingw's provides the functions asctime_r, ctime_r, + gmtime_r, localtime_r only if or has + been included before. */ + #if defined __MINGW32__ + # include + #endif + #include + ]], [[/* We don't need to append 'restrict's to the argument types, even though the POSIX signature has the 'restrict's, since C99 says they can't affect type compatibility. */ @@ -49,6 +64,32 @@ AC_DEFUN([gl_TIME_R], fi else HAVE_LOCALTIME_R=0 + dnl On mingw, localtime_r() is defined as an inline function; use through a + dnl direct function call works but the use as a function pointer leads to a + dnl link error. + AC_CACHE_CHECK([whether localtime_r exists as an inline function], + [gl_cv_func_localtime_r_inline], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[/* mingw's provides the functions asctime_r, ctime_r, + gmtime_r, localtime_r only if or has + been included before. */ + #if defined __MINGW32__ + # include + #endif + #include + ]], + [[time_t a; + struct tm r; + localtime_r (&a, &r); + ]]) + ], + [gl_cv_func_localtime_r_inline=yes], + [gl_cv_func_localtime_r_inline=no]) + ]) + if test $gl_cv_func_localtime_r_inline = yes; then + REPLACE_LOCALTIME_R=1 + fi fi ]) diff --git a/gl/m4/timegm.m4 b/gl/m4/timegm.m4 index 997953c0..f1893941 100644 --- a/gl/m4/timegm.m4 +++ b/gl/m4/timegm.m4 @@ -1,17 +1,17 @@ -# timegm.m4 serial 11 -dnl Copyright (C) 2003, 2007, 2009-2013 Free Software Foundation, Inc. +# timegm.m4 serial 13 +dnl Copyright (C) 2003, 2007, 2009-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_TIMEGM], [ - AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) - AC_REQUIRE([gl_FUNC_MKTIME]) + AC_REQUIRE([gl_TIME_H_DEFAULTS]) + AC_REQUIRE([gl_FUNC_MKTIME_WORKS]) REPLACE_TIMEGM=0 AC_CHECK_FUNCS_ONCE([timegm]) if test $ac_cv_func_timegm = yes; then - if test $gl_cv_func_working_mktime = no; then + if test "$gl_cv_func_working_mktime" != yes; then # Assume that timegm is buggy if mktime is. REPLACE_TIMEGM=1 fi diff --git a/gl/m4/uintmax_t.m4 b/gl/m4/uintmax_t.m4 deleted file mode 100644 index c6ff8006..00000000 --- a/gl/m4/uintmax_t.m4 +++ /dev/null @@ -1,30 +0,0 @@ -# uintmax_t.m4 serial 12 -dnl Copyright (C) 1997-2004, 2007-2013 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 From Paul Eggert. - -AC_PREREQ([2.13]) - -# Define uintmax_t to 'unsigned long' or 'unsigned long long' -# if it is not already defined in or . - -AC_DEFUN([gl_AC_TYPE_UINTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then - AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) - test $ac_cv_type_unsigned_long_long_int = yes \ - && ac_type='unsigned long long' \ - || ac_type='unsigned long' - AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type], - [Define to unsigned long or unsigned long long - if and don't define.]) - else - AC_DEFINE([HAVE_UINTMAX_T], [1], - [Define if you have the 'uintmax_t' type in or .]) - fi -]) diff --git a/gl/m4/ungetc.m4 b/gl/m4/ungetc.m4 new file mode 100644 index 00000000..12a10991 --- /dev/null +++ b/gl/m4/ungetc.m4 @@ -0,0 +1,73 @@ +# ungetc.m4 serial 10 +dnl Copyright (C) 2009-2022 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN_ONCE([gl_FUNC_UNGETC_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + AC_CACHE_CHECK([whether ungetc works on arbitrary bytes], + [gl_cv_func_ungetc_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[FILE *f; + if (!(f = fopen ("conftest.tmp", "w+"))) + return 1; + if (fputs ("abc", f) < 0) + { fclose (f); return 2; } + rewind (f); + if (fgetc (f) != 'a') + { fclose (f); return 3; } + if (fgetc (f) != 'b') + { fclose (f); return 4; } + if (ungetc ('d', f) != 'd') + { fclose (f); return 5; } + if (ftell (f) != 1) + { fclose (f); return 6; } + if (fgetc (f) != 'd') + { fclose (f); return 7; } + if (ftell (f) != 2) + { fclose (f); return 8; } + if (fseek (f, 0, SEEK_CUR) != 0) + { fclose (f); return 9; } + if (ftell (f) != 2) + { fclose (f); return 10; } + if (fgetc (f) != 'c') + { fclose (f); return 11; } + fclose (f); + remove ("conftest.tmp"); + ]])], + [gl_cv_func_ungetc_works=yes], [gl_cv_func_ungetc_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_ungetc_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl*) gl_cv_func_ungetc_works="guessing yes" ;; + # Guess yes on bionic systems. + *-android*) gl_cv_func_ungetc_works="guessing yes" ;; + # Guess yes on native Windows. + mingw*) gl_cv_func_ungetc_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_ungetc_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) + gl_ftello_broken_after_ungetc=no + case "$gl_cv_func_ungetc_works" in + *yes) ;; + *) + dnl On macOS >= 10.15, where the above program fails with exit code 6, + dnl we fix it through an ftello override. + case "$host_os" in + darwin*) gl_ftello_broken_after_ungetc=yes ;; + *) + AC_DEFINE([FUNC_UNGETC_BROKEN], [1], + [Define to 1 if ungetc is broken when used on arbitrary bytes.]) + ;; + esac + ;; + esac +]) diff --git a/gl/m4/unistd_h.m4 b/gl/m4/unistd_h.m4 index 32dcfa58..4c66ccc0 100644 --- a/gl/m4/unistd_h.m4 +++ b/gl/m4/unistd_h.m4 @@ -1,15 +1,15 @@ -# unistd_h.m4 serial 66 -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. +# unistd_h.m4 serial 90 +dnl Copyright (C) 2006-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Written by Simon Josefsson, Bruno Haible. -AC_DEFUN([gl_UNISTD_H], +AC_DEFUN_ONCE([gl_UNISTD_H], [ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. + dnl Ensure to expand the default settings once only, before all statements + dnl that occur in other macros. AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) gl_CHECK_NEXT_HEADERS([unistd.h]) @@ -37,150 +37,234 @@ AC_DEFUN([gl_UNISTD_H], # include # include # include -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ # include # endif #endif - ]], [chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat - fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups - gethostname getlogin getlogin_r getpagesize + ]], [access chdir chown copy_file_range dup dup2 dup3 environ euidaccess + execl execle execlp execv execve execvp execvpe + faccessat fchdir + fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize + getentropy getgroups gethostname getlogin getlogin_r getpagesize getpass getusershell setusershell endusershell group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite - readlink readlinkat rmdir sethostname sleep symlink symlinkat ttyname_r - unlink unlinkat usleep]) + readlink readlinkat rmdir sethostname sleep symlink symlinkat + truncate ttyname_r unlink unlinkat usleep]) + + AC_REQUIRE([AC_C_RESTRICT]) + + AC_CHECK_DECLS_ONCE([execvpe]) + if test $ac_cv_have_decl_execvpe = no; then + HAVE_DECL_EXECVPE=0 + fi ]) +# gl_UNISTD_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_UNISTD_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_UNISTD_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_UNISTD_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_UNISTD_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCESS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHDIR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHOWN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CLOSE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COPY_FILE_RANGE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP2]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP3]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ENVIRON]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EUIDACCESS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECLE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECLP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECV]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FACCESSAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHDIR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHOWNAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDATASYNC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSYNC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTRUNCATE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCWD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDOMAINNAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDTABLESIZE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETENTROPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETGROUPS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETHOSTNAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOGIN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOGIN_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETOPT_POSIX]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAGESIZE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPASS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPASS_GNU]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUSERSHELL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GROUP_MEMBER]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISATTY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LCHOWN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LINK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LINKAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LSEEK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PIPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PIPE2]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PREAD]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PWRITE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READ]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READLINK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READLINKAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RMDIR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETHOSTNAME]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SLEEP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYMLINK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYMLINKAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCATE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TTYNAME_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_NONBLOCKING]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_SIGPIPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLINK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLINKAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_USLEEP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WRITE]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ACCESS], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CHDIR], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CLOSE], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_DUP], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_DUP2], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECL], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECLE], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECLP], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECV], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVE], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVP], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVPE], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETCWD], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETPID], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ISATTY], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LSEEK], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_READ], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_RMDIR], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_SWAB], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_UNLINK], [1]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WRITE], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_UNISTD_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) +]) + AC_DEFUN([gl_UNISTD_H_DEFAULTS], [ - GNULIB_CHDIR=0; AC_SUBST([GNULIB_CHDIR]) - GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) - GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE]) - GNULIB_DUP=0; AC_SUBST([GNULIB_DUP]) - GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) - GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) - GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) - GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS]) - GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) - GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) - GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) - GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC]) - GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) - GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) - GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) - GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME]) - GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE]) - GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS]) - GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME]) - GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN]) - GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) - GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) - GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL]) - GNULIB_GROUP_MEMBER=0; AC_SUBST([GNULIB_GROUP_MEMBER]) - GNULIB_ISATTY=0; AC_SUBST([GNULIB_ISATTY]) - GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) - GNULIB_LINK=0; AC_SUBST([GNULIB_LINK]) - GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT]) - GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) - GNULIB_PIPE=0; AC_SUBST([GNULIB_PIPE]) - GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2]) - GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD]) - GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE]) - GNULIB_READ=0; AC_SUBST([GNULIB_READ]) - GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) - GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT]) - GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR]) - GNULIB_SETHOSTNAME=0; AC_SUBST([GNULIB_SETHOSTNAME]) - GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) - GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK]) - GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT]) - GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R]) - GNULIB_UNISTD_H_NONBLOCKING=0; AC_SUBST([GNULIB_UNISTD_H_NONBLOCKING]) - GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) - GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK]) - GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) - GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) - GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) - HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) - HAVE_DUP3=1; AC_SUBST([HAVE_DUP3]) - HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS]) - HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) - HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) - HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) - HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC]) - HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) - HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) - HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) - HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS]) - HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) - HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN]) - HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE]) - HAVE_GROUP_MEMBER=1; AC_SUBST([HAVE_GROUP_MEMBER]) - HAVE_LCHOWN=1; AC_SUBST([HAVE_LCHOWN]) - HAVE_LINK=1; AC_SUBST([HAVE_LINK]) - HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT]) - HAVE_PIPE=1; AC_SUBST([HAVE_PIPE]) - HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2]) - HAVE_PREAD=1; AC_SUBST([HAVE_PREAD]) - HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE]) - HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) - HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT]) - HAVE_SETHOSTNAME=1; AC_SUBST([HAVE_SETHOSTNAME]) - HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) - HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK]) - HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT]) - HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT]) - HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP]) - HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) - HAVE_DECL_FCHDIR=1; AC_SUBST([HAVE_DECL_FCHDIR]) - HAVE_DECL_FDATASYNC=1; AC_SUBST([HAVE_DECL_FDATASYNC]) - HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME]) - HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R]) - HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE]) - HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL]) - HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME]) - HAVE_DECL_TTYNAME_R=1; AC_SUBST([HAVE_DECL_TTYNAME_R]) - HAVE_OS_H=0; AC_SUBST([HAVE_OS_H]) - HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H]) - REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN]) - REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) - REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) - REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) - REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) - REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) - REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) - REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) - REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) - REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) - REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) - REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) - REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) - REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) - REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT]) - REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) - REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD]) - REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE]) - REPLACE_READ=0; AC_SUBST([REPLACE_READ]) - REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) - REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) - REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) - REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) - REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R]) - REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK]) - REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) - REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP]) - REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE]) - UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H]) + HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) + HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE]) + HAVE_DUP3=1; AC_SUBST([HAVE_DUP3]) + HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS]) + HAVE_EXECVPE=1; AC_SUBST([HAVE_EXECVPE]) + HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) + HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) + HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) + HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC]) + HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) + HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) + HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) + HAVE_GETENTROPY=1; AC_SUBST([HAVE_GETENTROPY]) + HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS]) + HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) + HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN]) + HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE]) + HAVE_GETPASS=1; AC_SUBST([HAVE_GETPASS]) + HAVE_GROUP_MEMBER=1; AC_SUBST([HAVE_GROUP_MEMBER]) + HAVE_LCHOWN=1; AC_SUBST([HAVE_LCHOWN]) + HAVE_LINK=1; AC_SUBST([HAVE_LINK]) + HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT]) + HAVE_PIPE=1; AC_SUBST([HAVE_PIPE]) + HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2]) + HAVE_PREAD=1; AC_SUBST([HAVE_PREAD]) + HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE]) + HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) + HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT]) + HAVE_SETHOSTNAME=1; AC_SUBST([HAVE_SETHOSTNAME]) + HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) + HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK]) + HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT]) + HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT]) + HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP]) + HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) + HAVE_DECL_EXECVPE=1; AC_SUBST([HAVE_DECL_EXECVPE]) + HAVE_DECL_FCHDIR=1; AC_SUBST([HAVE_DECL_FCHDIR]) + HAVE_DECL_FDATASYNC=1; AC_SUBST([HAVE_DECL_FDATASYNC]) + HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME]) + HAVE_DECL_GETLOGIN=1; AC_SUBST([HAVE_DECL_GETLOGIN]) + HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R]) + HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE]) + HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL]) + HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME]) + HAVE_DECL_TRUNCATE=1; AC_SUBST([HAVE_DECL_TRUNCATE]) + HAVE_DECL_TTYNAME_R=1; AC_SUBST([HAVE_DECL_TTYNAME_R]) + HAVE_OS_H=0; AC_SUBST([HAVE_OS_H]) + HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H]) + REPLACE_ACCESS=0; AC_SUBST([REPLACE_ACCESS]) + REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN]) + REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) + REPLACE_COPY_FILE_RANGE=0; AC_SUBST([REPLACE_COPY_FILE_RANGE]) + REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) + REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) + REPLACE_EXECL=0; AC_SUBST([REPLACE_EXECL]) + REPLACE_EXECLE=0; AC_SUBST([REPLACE_EXECLE]) + REPLACE_EXECLP=0; AC_SUBST([REPLACE_EXECLP]) + REPLACE_EXECV=0; AC_SUBST([REPLACE_EXECV]) + REPLACE_EXECVE=0; AC_SUBST([REPLACE_EXECVE]) + REPLACE_EXECVP=0; AC_SUBST([REPLACE_EXECVP]) + REPLACE_EXECVPE=0; AC_SUBST([REPLACE_EXECVPE]) + REPLACE_FACCESSAT=0; AC_SUBST([REPLACE_FACCESSAT]) + REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) + REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) + REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) + REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) + REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE]) + REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) + REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) + REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) + REPLACE_GETPASS=0; AC_SUBST([REPLACE_GETPASS]) + REPLACE_GETPASS_FOR_GETPASS_GNU=0; AC_SUBST([REPLACE_GETPASS_FOR_GETPASS_GNU]) + REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) + REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) + REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) + REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT]) + REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) + REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD]) + REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE]) + REPLACE_READ=0; AC_SUBST([REPLACE_READ]) + REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) + REPLACE_READLINKAT=0; AC_SUBST([REPLACE_READLINKAT]) + REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) + REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) + REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) + REPLACE_SYMLINKAT=0; AC_SUBST([REPLACE_SYMLINKAT]) + REPLACE_TRUNCATE=0; AC_SUBST([REPLACE_TRUNCATE]) + REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R]) + REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK]) + REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) + REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP]) + REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE]) + UNISTD_H_HAVE_SYS_RANDOM_H=0; AC_SUBST([UNISTD_H_HAVE_SYS_RANDOM_H]) + UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H]) UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS]) ]) diff --git a/gl/m4/unlocked-io.m4 b/gl/m4/unlocked-io.m4 new file mode 100644 index 00000000..d42c95ce --- /dev/null +++ b/gl/m4/unlocked-io.m4 @@ -0,0 +1,36 @@ +# unlocked-io.m4 serial 16 + +# Copyright (C) 1998-2006, 2009-2022 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +dnl From Jim Meyering. +dnl +dnl See if the glibc *_unlocked I/O macros or functions are available. +dnl Use only those *_unlocked macros or functions that are declared +dnl (because some of them were declared in Solaris 2.5.1 but were removed +dnl in Solaris 2.6, whereas we want binaries built on Solaris 2.5.1 to run +dnl on Solaris 2.6). + +AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO], +[ + dnl Persuade glibc and Solaris to declare + dnl fgets_unlocked(), fputs_unlocked() etc. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([clearerr_unlocked]) + AC_CHECK_DECLS_ONCE([feof_unlocked]) + AC_CHECK_DECLS_ONCE([ferror_unlocked]) + AC_CHECK_DECLS_ONCE([fflush_unlocked]) + AC_CHECK_DECLS_ONCE([fgets_unlocked]) + AC_CHECK_DECLS_ONCE([fputc_unlocked]) + AC_CHECK_DECLS_ONCE([fputs_unlocked]) + AC_CHECK_DECLS_ONCE([fread_unlocked]) + AC_CHECK_DECLS_ONCE([fwrite_unlocked]) + AC_CHECK_DECLS_ONCE([getc_unlocked]) + AC_CHECK_DECLS_ONCE([getchar_unlocked]) + AC_CHECK_DECLS_ONCE([putc_unlocked]) + AC_CHECK_DECLS_ONCE([putchar_unlocked]) +]) diff --git a/gl/m4/vararrays.m4 b/gl/m4/vararrays.m4 new file mode 100644 index 00000000..28e22a49 --- /dev/null +++ b/gl/m4/vararrays.m4 @@ -0,0 +1,72 @@ +# Check for variable-length arrays. + +# serial 6 + +# From Paul Eggert + +# Copyright (C) 2001, 2009-2022 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +m4_version_prereq([2.70], [], [ + +# AC_C_VARARRAYS +# -------------- +# Check whether the C compiler supports variable-length arrays. +AC_DEFUN([AC_C_VARARRAYS], +[ + AC_CACHE_CHECK([for variable-length arrays], + ac_cv_c_vararrays, + [AC_EGREP_CPP([defined], + [#ifdef __STDC_NO_VLA__ + defined + #endif + ], + [ac_cv_c_vararrays='no: __STDC_NO_VLA__ is defined'], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[/* Test for VLA support. This test is partly inspired + from examples in the C standard. Use at least two VLA + functions to detect the GCC 3.4.3 bug described in: + https://lists.gnu.org/archive/html/bug-gnulib/2014-08/msg00014.html + */ + #ifdef __STDC_NO_VLA__ + syntax error; + #else + extern int n; + int B[100]; + int fvla (int m, int C[m][m]); + + int + simple (int count, int all[static count]) + { + return all[count - 1]; + } + + int + fvla (int m, int C[m][m]) + { + typedef int VLA[m][m]; + VLA x; + int D[m]; + static int (*q)[m] = &B; + int (*s)[n] = q; + return C && &x[0][0] == &D[0] && &D[0] == s[0]; + } + #endif + ]])], + [ac_cv_c_vararrays=yes], + [ac_cv_c_vararrays=no])])]) + if test "$ac_cv_c_vararrays" = yes; then + dnl This is for compatibility with Autoconf 2.61-2.69. + AC_DEFINE([HAVE_C_VARARRAYS], 1, + [Define to 1 if C supports variable-length arrays.]) + elif test "$ac_cv_c_vararrays" = no; then + AC_DEFINE([__STDC_NO_VLA__], 1, + [Define to 1 if C does not support variable-length arrays, and + if the compiler does not already define this.]) + fi +]) + +]) diff --git a/gl/m4/vasnprintf.m4 b/gl/m4/vasnprintf.m4 index d730e435..afdece71 100644 --- a/gl/m4/vasnprintf.m4 +++ b/gl/m4/vasnprintf.m4 @@ -1,5 +1,5 @@ -# vasnprintf.m4 serial 36 -dnl Copyright (C) 2002-2004, 2006-2013 Free Software Foundation, Inc. +# vasnprintf.m4 serial 38 +dnl Copyright (C) 2002-2004, 2006-2022 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. @@ -32,7 +32,6 @@ AC_DEFUN([gl_REPLACE_VASNPRINTF], # Prerequisites of lib/printf-args.h, lib/printf-args.c. AC_DEFUN([gl_PREREQ_PRINTF_ARGS], [ - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) AC_REQUIRE([gt_TYPE_WCHAR_T]) AC_REQUIRE([gt_TYPE_WINT_T]) ]) @@ -41,7 +40,6 @@ AC_DEFUN([gl_PREREQ_PRINTF_ARGS], AC_DEFUN([gl_PREREQ_PRINTF_PARSE], [ AC_REQUIRE([gl_FEATURES_H]) - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) AC_REQUIRE([gt_TYPE_WCHAR_T]) AC_REQUIRE([gt_TYPE_WINT_T]) AC_REQUIRE([AC_TYPE_SIZE_T]) @@ -56,7 +54,6 @@ AC_DEFUN([gl_PREREQ_PRINTF_PARSE], AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], [ AC_REQUIRE([AC_FUNC_ALLOCA]) - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) AC_REQUIRE([gt_TYPE_WCHAR_T]) AC_REQUIRE([gt_TYPE_WINT_T]) AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) @@ -77,6 +74,16 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], if the buffer had been large enough.]) ;; esac + dnl Additionally, the use of %n can be eliminated by assuming that snprintf + dnl always produces NUL-terminated strings (no truncation). + AC_REQUIRE([gl_SNPRINTF_TRUNCATION_C99]) + case "$gl_cv_func_snprintf_truncation_c99" in + *yes) + AC_DEFINE([HAVE_SNPRINTF_TRUNCATION_C99], [1], + [Define if the string produced by the snprintf function is always NUL + terminated.]) + ;; + esac ]) # Extra prerequisites of lib/vasnprintf.c for supporting 'long double' diff --git a/gl/m4/vasprintf.m4 b/gl/m4/vasprintf.m4 index c214ff11..b92977b6 100644 --- a/gl/m4/vasprintf.m4 +++ b/gl/m4/vasprintf.m4 @@ -1,5 +1,5 @@ # vasprintf.m4 serial 6 -dnl Copyright (C) 2002-2003, 2006-2007, 2009-2013 Free Software Foundation, +dnl Copyright (C) 2002-2003, 2006-2007, 2009-2022 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, diff --git a/gl/m4/visibility.m4 b/gl/m4/visibility.m4 index 6cbd7e5f..4a212a4e 100644 --- a/gl/m4/visibility.m4 +++ b/gl/m4/visibility.m4 @@ -1,5 +1,5 @@ -# visibility.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2005, 2008, 2010-2013 Free Software Foundation, Inc. +# visibility.m4 serial 8 +dnl Copyright (C) 2005, 2008, 2010-2022 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. @@ -29,42 +29,47 @@ AC_DEFUN([gl_VISIBILITY], dnl First, check whether -Werror can be added to the command line, or dnl whether it leads to an error because of some other option that the dnl user has put into $CC $CFLAGS $CPPFLAGS. - AC_MSG_CHECKING([whether the -Werror option is usable]) - AC_CACHE_VAL([gl_cv_cc_vis_werror], [ - gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[]])], - [gl_cv_cc_vis_werror=yes], - [gl_cv_cc_vis_werror=no]) - CFLAGS="$gl_save_CFLAGS"]) - AC_MSG_RESULT([$gl_cv_cc_vis_werror]) + AC_CACHE_CHECK([whether the -Werror option is usable], + [gl_cv_cc_vis_werror], + [gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [gl_cv_cc_vis_werror=yes], + [gl_cv_cc_vis_werror=no]) + CFLAGS="$gl_save_CFLAGS" + ]) dnl Now check whether visibility declarations are supported. - AC_MSG_CHECKING([for simple visibility declarations]) - AC_CACHE_VAL([gl_cv_cc_visibility], [ - gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fvisibility=hidden" - dnl We use the option -Werror and a function dummyfunc, because on some - dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning - dnl "visibility attribute not supported in this configuration; ignored" - dnl at the first function definition in every compilation unit, and we - dnl don't want to use the option in this case. - if test $gl_cv_cc_vis_werror = yes; then - CFLAGS="$CFLAGS -Werror" - fi - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; - extern __attribute__((__visibility__("default"))) int exportedvar; - extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); - extern __attribute__((__visibility__("default"))) int exportedfunc (void); - void dummyfunc (void) {} - ]], - [[]])], - [gl_cv_cc_visibility=yes], - [gl_cv_cc_visibility=no]) - CFLAGS="$gl_save_CFLAGS"]) - AC_MSG_RESULT([$gl_cv_cc_visibility]) + AC_CACHE_CHECK([for simple visibility declarations], + [gl_cv_cc_visibility], + [gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $gl_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void); + int hiddenvar; + int exportedvar; + int hiddenfunc (void) { return 51; } + int exportedfunc (void) { return 1225736919; } + void dummyfunc (void) {} + ]], + [[]])], + [gl_cv_cc_visibility=yes], + [gl_cv_cc_visibility=no]) + CFLAGS="$gl_save_CFLAGS" + ]) if test $gl_cv_cc_visibility = yes; then CFLAG_VISIBILITY="-fvisibility=hidden" HAVE_VISIBILITY=1 diff --git a/gl/m4/vsnprintf.m4 b/gl/m4/vsnprintf.m4 index 4900764e..02b448f3 100644 --- a/gl/m4/vsnprintf.m4 +++ b/gl/m4/vsnprintf.m4 @@ -1,5 +1,5 @@ -# vsnprintf.m4 serial 6 -dnl Copyright (C) 2002-2004, 2007-2013 Free Software Foundation, Inc. +# vsnprintf.m4 serial 7 +dnl Copyright (C) 2002-2004, 2007-2022 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. @@ -46,6 +46,14 @@ AC_DEFUN([gl_REPLACE_VSNPRINTF], AC_LIBOBJ([vsnprintf]) if test $ac_cv_func_vsnprintf = yes; then REPLACE_VSNPRINTF=1 + else + AC_CHECK_DECLS_ONCE([vsnprintf]) + if test $ac_cv_have_decl_vsnprintf = yes; then + dnl If the function is declared but does not appear to exist, it may be + dnl defined as an inline function. In order to avoid a conflict, we have + dnl to define rpl_vsnprintf, not vsnprintf. + REPLACE_VSNPRINTF=1 + fi fi gl_PREREQ_VSNPRINTF ]) diff --git a/gl/m4/warn-on-use.m4 b/gl/m4/warn-on-use.m4 index e43beebd..d43355ab 100644 --- a/gl/m4/warn-on-use.m4 +++ b/gl/m4/warn-on-use.m4 @@ -1,11 +1,13 @@ -# warn-on-use.m4 serial 5 -dnl Copyright (C) 2010-2013 Free Software Foundation, Inc. +# warn-on-use.m4 serial 9 +dnl Copyright (C) 2010-2022 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. # gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) # --------------------------------------- +# If the module 'posixcheck' is in use: +# # For each whitespace-separated element in the list of NAMES, define # HAVE_RAW_DECL_name if the function has a declaration among INCLUDES # even after being undefined as a macro. @@ -23,25 +25,25 @@ dnl with or without modifications, as long as this notice is preserved. # needing gl_WARN_ON_USE_PREPARE. AC_DEFUN([gl_WARN_ON_USE_PREPARE], [ - m4_foreach_w([gl_decl], [$2], - [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), - [Define to 1 if ]m4_defn([gl_decl])[ is declared even after - undefining macros.])])dnl -dnl FIXME: gl_Symbol must be used unquoted until we can assume -dnl autoconf 2.64 or newer. - for gl_func in m4_flatten([$2]); do - AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl - AC_CACHE_CHECK([whether $gl_func is declared without a macro], - gl_Symbol, - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1], -[@%:@undef $gl_func - (void) $gl_func;])], - [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])]) - AS_VAR_IF(gl_Symbol, [yes], - [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) - dnl shortcut - if the raw declaration exists, then set a cache - dnl variable to allow skipping any later AC_CHECK_DECL efforts - eval ac_cv_have_decl_$gl_func=yes]) - AS_VAR_POPDEF([gl_Symbol])dnl - done + m4_ifdef([gl_POSIXCHECK], + [m4_foreach_w([gl_decl], [$2], + [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), + [Define to 1 if ]m4_defn([gl_decl])[ is declared even after + undefining macros.])])dnl + for gl_func in m4_flatten([$2]); do + AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl + AC_CACHE_CHECK([whether $gl_func is declared without a macro], + [gl_Symbol], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1], +[[#undef $gl_func + (void) $gl_func;]])], + [AS_VAR_SET([gl_Symbol], [yes])], [AS_VAR_SET([gl_Symbol], [no])])]) + AS_VAR_IF([gl_Symbol], [yes], + [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) + dnl shortcut - if the raw declaration exists, then set a cache + dnl variable to allow skipping any later AC_CHECK_DECL efforts + eval ac_cv_have_decl_$gl_func=yes]) + AS_VAR_POPDEF([gl_Symbol])dnl + done + ]) ]) diff --git a/gl/m4/wchar_h.m4 b/gl/m4/wchar_h.m4 index bedb15a4..4baba1af 100644 --- a/gl/m4/wchar_h.m4 +++ b/gl/m4/wchar_h.m4 @@ -1,15 +1,15 @@ dnl A placeholder for ISO C99 , for platforms that have issues. -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2007-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Written by Eric Blake. -# wchar_h.m4 serial 39 +# wchar_h.m4 serial 55 -AC_DEFUN([gl_WCHAR_H], +AC_DEFUN_ONCE([gl_WCHAR_H], [ AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) @@ -35,76 +35,82 @@ AC_DEFUN([gl_WCHAR_H], fi AC_SUBST([HAVE_WINT_T]) + AC_REQUIRE([gl_TYPE_WINT_T_PREREQ]) + dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use. gl_WARN_ON_USE_PREPARE([[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#if !(defined __GLIBC__ && !defined __UCLIBC__) -# include -# include -# include -#endif -#include + #include ]], [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb - wcsrtombs wcsnrtombs wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset + wcsrtombs wcsnrtombs wcwidth + wmemchr wmemcmp wmemcpy wmemmove wmempcpy wmemset wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat wcscmp wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr - wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth + wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth wcsftime ]) + + AC_REQUIRE([AC_C_RESTRICT]) + + AC_CHECK_DECLS([wcsdup], [], [], [[ + #include + ]]) + if test $ac_cv_have_decl_wcsdup = no; then + HAVE_DECL_WCSDUP=0 + fi ]) dnl Check whether is usable at all. AC_DEFUN([gl_WCHAR_H_INLINE_OK], [ dnl Test whether suffers due to the transition from '__inline' to - dnl 'gnu_inline'. See - dnl and . In summary, + dnl 'gnu_inline'. See + dnl and . In summary, dnl glibc version 2.5 or older, together with gcc version 4.3 or newer and dnl the option -std=c99 or -std=gnu99, leads to a broken . + AC_REQUIRE([AC_CANONICAL_HOST]) AC_CACHE_CHECK([whether uses 'inline' correctly], [gl_cv_header_wchar_h_correct_inline], [gl_cv_header_wchar_h_correct_inline=yes - AC_LANG_CONFTEST([ - AC_LANG_SOURCE([[#define wcstod renamed_wcstod -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -extern int zero (void); -int main () { return zero(); } -]])]) - if AC_TRY_EVAL([ac_compile]); then - mv conftest.$ac_objext conftest1.$ac_objext - AC_LANG_CONFTEST([ - AC_LANG_SOURCE([[#define wcstod renamed_wcstod -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int zero (void) { return 0; } -]])]) - if AC_TRY_EVAL([ac_compile]); then - mv conftest.$ac_objext conftest2.$ac_objext - if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then - : - else - gl_cv_header_wchar_h_correct_inline=no + case "$host_os" in + *-gnu* | gnu*) + AC_LANG_CONFTEST([ + AC_LANG_SOURCE([[ + #define wcstod renamed_wcstod + #include + extern int zero (void); + int main () { return zero(); } + ]])]) + dnl Do not rename the object file from conftest.$ac_objext to + dnl conftest1.$ac_objext, as this will cause the link to fail on + dnl z/OS when using the XPLINK object format (due to duplicate + dnl CSECT names). Instead, temporarily redefine $ac_compile so + dnl that the object file has the latter name from the start. + save_ac_compile="$ac_compile" + ac_compile=`echo "$save_ac_compile" | sed s/conftest/conftest1/` + if echo '#include "conftest.c"' >conftest1.c \ + && AC_TRY_EVAL([ac_compile]); then + AC_LANG_CONFTEST([ + AC_LANG_SOURCE([[ + #define wcstod renamed_wcstod + #include + int zero (void) { return 0; } + ]])]) + dnl See note above about renaming object files. + ac_compile=`echo "$save_ac_compile" | sed s/conftest/conftest2/` + if echo '#include "conftest.c"' >conftest2.c \ + && AC_TRY_EVAL([ac_compile]); then + if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then + : + else + gl_cv_header_wchar_h_correct_inline=no + fi + fi fi - fi - fi - rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext + ac_compile="$save_ac_compile" + rm -f conftest[12].c conftest[12].$ac_objext conftest$ac_exeext + ;; + esac ]) if test $gl_cv_header_wchar_h_correct_inline = no; then AC_MSG_ERROR([ cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS). @@ -112,63 +118,84 @@ This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in C99 mode. You have four options: - Add the flag -fgnu89-inline to CC and reconfigure, or - Fix your include files, using parts of - , or + , or - Use a gcc version older than 4.3, or - Don't use the flags -std=c99 or -std=gnu99. Configuration aborted.]) fi ]) +# gl_WCHAR_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_WCHAR_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_WCHAR_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_WCHAR_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_WCHAR_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_BTOWC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTOB]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSINIT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBRTOWC]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBRLEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSRTOWCS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNRTOWCS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCRTOMB]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSRTOMBS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNRTOMBS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCWIDTH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMCMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMMOVE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMPCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMSET]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSLEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNLEN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCPCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCPNCPY]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCAT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCASECMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCASECMP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCOLL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSXFRM]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSDUP]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSRCHR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCSPN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSSPN]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSPBRK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSSTR]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSTOK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSWIDTH]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSFTIME]) + dnl Support Microsoft deprecated alias function names by default. + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WCSDUP], [1]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_WCHAR_H_MODULE_INDICATOR_DEFAULTS]) + dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized. + gl_STDLIB_H_REQUIRE_DEFAULTS + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) +]) + AC_DEFUN([gl_WCHAR_H_DEFAULTS], [ - GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC]) - GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB]) - GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT]) - GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC]) - GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN]) - GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS]) - GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS]) - GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB]) - GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS]) - GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) - GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) - GNULIB_WMEMCHR=0; AC_SUBST([GNULIB_WMEMCHR]) - GNULIB_WMEMCMP=0; AC_SUBST([GNULIB_WMEMCMP]) - GNULIB_WMEMCPY=0; AC_SUBST([GNULIB_WMEMCPY]) - GNULIB_WMEMMOVE=0; AC_SUBST([GNULIB_WMEMMOVE]) - GNULIB_WMEMSET=0; AC_SUBST([GNULIB_WMEMSET]) - GNULIB_WCSLEN=0; AC_SUBST([GNULIB_WCSLEN]) - GNULIB_WCSNLEN=0; AC_SUBST([GNULIB_WCSNLEN]) - GNULIB_WCSCPY=0; AC_SUBST([GNULIB_WCSCPY]) - GNULIB_WCPCPY=0; AC_SUBST([GNULIB_WCPCPY]) - GNULIB_WCSNCPY=0; AC_SUBST([GNULIB_WCSNCPY]) - GNULIB_WCPNCPY=0; AC_SUBST([GNULIB_WCPNCPY]) - GNULIB_WCSCAT=0; AC_SUBST([GNULIB_WCSCAT]) - GNULIB_WCSNCAT=0; AC_SUBST([GNULIB_WCSNCAT]) - GNULIB_WCSCMP=0; AC_SUBST([GNULIB_WCSCMP]) - GNULIB_WCSNCMP=0; AC_SUBST([GNULIB_WCSNCMP]) - GNULIB_WCSCASECMP=0; AC_SUBST([GNULIB_WCSCASECMP]) - GNULIB_WCSNCASECMP=0; AC_SUBST([GNULIB_WCSNCASECMP]) - GNULIB_WCSCOLL=0; AC_SUBST([GNULIB_WCSCOLL]) - GNULIB_WCSXFRM=0; AC_SUBST([GNULIB_WCSXFRM]) - GNULIB_WCSDUP=0; AC_SUBST([GNULIB_WCSDUP]) - GNULIB_WCSCHR=0; AC_SUBST([GNULIB_WCSCHR]) - GNULIB_WCSRCHR=0; AC_SUBST([GNULIB_WCSRCHR]) - GNULIB_WCSCSPN=0; AC_SUBST([GNULIB_WCSCSPN]) - GNULIB_WCSSPN=0; AC_SUBST([GNULIB_WCSSPN]) - GNULIB_WCSPBRK=0; AC_SUBST([GNULIB_WCSPBRK]) - GNULIB_WCSSTR=0; AC_SUBST([GNULIB_WCSSTR]) - GNULIB_WCSTOK=0; AC_SUBST([GNULIB_WCSTOK]) - GNULIB_WCSWIDTH=0; AC_SUBST([GNULIB_WCSWIDTH]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) @@ -183,6 +210,7 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], HAVE_WMEMCMP=1; AC_SUBST([HAVE_WMEMCMP]) HAVE_WMEMCPY=1; AC_SUBST([HAVE_WMEMCPY]) HAVE_WMEMMOVE=1; AC_SUBST([HAVE_WMEMMOVE]) + HAVE_WMEMPCPY=1; AC_SUBST([HAVE_WMEMPCPY]) HAVE_WMEMSET=1; AC_SUBST([HAVE_WMEMSET]) HAVE_WCSLEN=1; AC_SUBST([HAVE_WCSLEN]) HAVE_WCSNLEN=1; AC_SUBST([HAVE_WCSNLEN]) @@ -207,7 +235,9 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], HAVE_WCSSTR=1; AC_SUBST([HAVE_WCSSTR]) HAVE_WCSTOK=1; AC_SUBST([HAVE_WCSTOK]) HAVE_WCSWIDTH=1; AC_SUBST([HAVE_WCSWIDTH]) + HAVE_WCSFTIME=1; AC_SUBST([HAVE_WCSFTIME]) HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) + HAVE_DECL_WCSDUP=1; AC_SUBST([HAVE_DECL_WCSDUP]) HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC]) @@ -222,4 +252,6 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS]) REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) REPLACE_WCSWIDTH=0; AC_SUBST([REPLACE_WCSWIDTH]) + REPLACE_WCSFTIME=0; AC_SUBST([REPLACE_WCSFTIME]) + REPLACE_WCSTOK=0; AC_SUBST([REPLACE_WCSTOK]) ]) diff --git a/gl/m4/wchar_t.m4 b/gl/m4/wchar_t.m4 index e1e1e699..268e3e51 100644 --- a/gl/m4/wchar_t.m4 +++ b/gl/m4/wchar_t.m4 @@ -1,5 +1,5 @@ # wchar_t.m4 serial 4 (gettext-0.18.2) -dnl Copyright (C) 2002-2003, 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2002-2003, 2008-2022 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. diff --git a/gl/m4/wcrtomb.m4 b/gl/m4/wcrtomb.m4 index f56b5bae..fee21d7e 100644 --- a/gl/m4/wcrtomb.m4 +++ b/gl/m4/wcrtomb.m4 @@ -1,5 +1,5 @@ -# wcrtomb.m4 serial 11 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +# wcrtomb.m4 serial 17 +dnl Copyright (C) 2008-2022 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. @@ -15,15 +15,8 @@ AC_DEFUN([gl_FUNC_WCRTOMB], if test $ac_cv_func_wcrtomb = no; then HAVE_WCRTOMB=0 AC_CHECK_DECLS([wcrtomb],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) + #include + ]]) if test $ac_cv_have_decl_wcrtomb = yes; then dnl On Minix 3.1.8, the system's declares wcrtomb() although dnl it does not have the function. Avoid a collision with gnulib's @@ -31,17 +24,56 @@ AC_DEFUN([gl_FUNC_WCRTOMB], REPLACE_WCRTOMB=1 fi else - if test $REPLACE_MBSTATE_T = 1; then - REPLACE_WCRTOMB=1 - else - dnl On AIX 4.3, OSF/1 5.1 and Solaris 10, wcrtomb (NULL, 0, NULL) sometimes - dnl returns 0 instead of 1. + dnl We don't actually need to override wcrtomb when redefining the semantics + dnl of the mbstate_t type. Tested on 32-bit AIX. + dnl if test $REPLACE_MBSTATE_T = 1; then + dnl REPLACE_WCRTOMB=1 + dnl fi + if test $REPLACE_WCRTOMB = 0; then + dnl On Android 4.3, wcrtomb produces wrong characters in the C locale. + dnl On AIX 4.3, OSF/1 5.1 and Solaris <= 11.3, wcrtomb (NULL, 0, NULL) + dnl sometimes returns 0 instead of 1. AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([gt_LOCALE_FR]) AC_REQUIRE([gt_LOCALE_FR_UTF8]) AC_REQUIRE([gt_LOCALE_JA]) AC_REQUIRE([gt_LOCALE_ZH_CN]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether wcrtomb works in the C locale], + [gl_cv_func_wcrtomb_works], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + mbstate_t state; + char out[64]; + int count; + memset (&state, 0, sizeof (state)); + out[0] = 'x'; + count = wcrtomb (out, L'a', &state); + return !(count == 1 && out[0] == 'a'); +}]])], + [gl_cv_func_wcrtomb_works=yes], + [gl_cv_func_wcrtomb_works=no], + [case "$host_os" in + # Guess no on Android. + linux*-android*) gl_cv_func_wcrtomb_works="guessing no";; + # Guess yes otherwise. + *) gl_cv_func_wcrtomb_works="guessing yes";; + esac + ]) + ]) + case "$gl_cv_func_wcrtomb_works" in + *yes) ;; + *) AC_DEFINE([WCRTOMB_C_LOCALE_BUG], [1], + [Define if the wcrtomb function does not work in the C locale.]) + REPLACE_WCRTOMB=1 ;; + esac + fi + if test $REPLACE_WCRTOMB = 0; then AC_CACHE_CHECK([whether wcrtomb return value is correct], [gl_cv_func_wcrtomb_retval], [ @@ -49,10 +81,10 @@ AC_DEFUN([gl_FUNC_WCRTOMB], dnl is present. changequote(,)dnl case "$host_os" in - # Guess no on AIX 4, OSF/1 and Solaris. - aix4* | osf* | solaris*) gl_cv_func_wcrtomb_retval="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_wcrtomb_retval="guessing yes" ;; + # Guess no on AIX 4, OSF/1, Solaris, native Windows. + aix4* | osf* | solaris* | mingw*) gl_cv_func_wcrtomb_retval="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_wcrtomb_retval="guessing yes" ;; esac changequote([,])dnl if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then @@ -60,14 +92,8 @@ changequote([,])dnl [AC_LANG_SOURCE([[ #include #include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include #include +#include int main () { int result = 0; @@ -80,6 +106,12 @@ int main () { if (wcrtomb (NULL, 0, NULL) != 1) result |= 2; + { + wchar_t wc = (wchar_t) 0xBADFACE; + if (mbtowc (&wc, "\303\274", 2) == 2) + if (wcrtomb (NULL, wc, NULL) != 1) + result |= 2; + } } if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) { @@ -100,7 +132,9 @@ int main () ]) case "$gl_cv_func_wcrtomb_retval" in *yes) ;; - *) REPLACE_WCRTOMB=1 ;; + *) AC_DEFINE([WCRTOMB_RETVAL_BUG], [1], + [Define if the wcrtomb function has an incorrect return value.]) + REPLACE_WCRTOMB=1 ;; esac fi fi diff --git a/gl/m4/wctype_h.m4 b/gl/m4/wctype_h.m4 index 82ada0ee..702cb39c 100644 --- a/gl/m4/wctype_h.m4 +++ b/gl/m4/wctype_h.m4 @@ -1,15 +1,15 @@ -# wctype_h.m4 serial 18 +# wctype_h.m4 serial 30 dnl A placeholder for ISO C99 , for platforms that lack it. -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2006-2022 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Written by Paul Eggert. -AC_DEFUN([gl_WCTYPE_H], +AC_DEFUN_ONCE([gl_WCTYPE_H], [ AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) AC_REQUIRE([AC_PROG_CC]) @@ -30,6 +30,8 @@ AC_DEFUN([gl_WCTYPE_H], fi AC_SUBST([HAVE_WINT_T]) + AC_REQUIRE([gl_TYPE_WINT_T_PREREQ]) + gl_CHECK_NEXT_HEADERS([wctype.h]) if test $ac_cv_header_wctype_h = yes; then if test $ac_cv_func_iswcntrl = yes; then @@ -39,22 +41,16 @@ AC_DEFUN([gl_WCTYPE_H], [ AC_RUN_IFELSE( [AC_LANG_SOURCE([[ - /* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include #include #include int main () { return iswprint ('x') == 0; } ]])], [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + [dnl Guess no on Linux libc5, yes otherwise. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #if __GNU_LIBRARY__ == 1 Linux libc5 i18n is broken. - #endif]], [])], + #endif]], [[]])], [gl_cv_func_iswcntrl_works="guessing yes"], [gl_cv_func_iswcntrl_works="guessing no"]) ]) @@ -66,10 +62,14 @@ AC_DEFUN([gl_WCTYPE_H], fi AC_SUBST([HAVE_WCTYPE_H]) - case "$gl_cv_func_iswcntrl_works" in - *yes) REPLACE_ISWCNTRL=0 ;; - *) REPLACE_ISWCNTRL=1 ;; - esac + if test $GNULIBHEADERS_OVERRIDE_WINT_T = 1; then + REPLACE_ISWCNTRL=1 + else + case "$gl_cv_func_iswcntrl_works" in + *yes) REPLACE_ISWCNTRL=0 ;; + *) REPLACE_ISWCNTRL=1 ;; + esac + fi AC_SUBST([REPLACE_ISWCNTRL]) if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then @@ -85,14 +85,7 @@ AC_DEFUN([gl_WCTYPE_H], REPLACE_TOWLOWER=0 else AC_CHECK_DECLS([towlower],,, - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include + [[#include #if HAVE_WCTYPE_H # include #endif @@ -121,14 +114,7 @@ AC_DEFUN([gl_WCTYPE_H], AC_CACHE_CHECK([for wctype_t], [gl_cv_type_wctype_t], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include + [[#include #if HAVE_WCTYPE_H # include #endif @@ -147,14 +133,7 @@ AC_DEFUN([gl_WCTYPE_H], AC_CACHE_CHECK([for wctrans_t], [gl_cv_type_wctrans_t], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include + [[#include #include wctrans_t a; ]], @@ -169,14 +148,7 @@ AC_DEFUN([gl_WCTYPE_H], dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use. gl_WARN_ON_USE_PREPARE([[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ #if !(defined __GLIBC__ && !defined __UCLIBC__) -# include -# include -# include # include #endif #include @@ -185,25 +157,44 @@ AC_DEFUN([gl_WCTYPE_H], ]) ]) +# gl_WCTYPE_MODULE_INDICATOR([modulename]) +# sets the shell variable that indicates the presence of the given module +# to a C preprocessor expression that will evaluate to 1. +# This macro invocation must not occur in macros that are AC_REQUIREd. AC_DEFUN([gl_WCTYPE_MODULE_INDICATOR], [ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) + dnl Ensure to expand the default settings once only. + gl_WCTYPE_H_REQUIRE_DEFAULTS gl_MODULE_INDICATOR_SET_VARIABLE([$1]) dnl Define it also as a C macro, for the benefit of the unit tests. gl_MODULE_INDICATOR_FOR_TESTS([$1]) ]) +# Initializes the default values for AC_SUBSTed shell variables. +# This macro must not be AC_REQUIREd. It must only be invoked, and only +# outside of macros or in macros that are not AC_REQUIREd. +AC_DEFUN([gl_WCTYPE_H_REQUIRE_DEFAULTS], +[ + m4_defun(GL_MODULE_INDICATOR_PREFIX[_WCTYPE_H_MODULE_INDICATOR_DEFAULTS], [ + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWBLANK]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWDIGIT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWXDIGIT]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTYPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWCTYPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTRANS]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TOWCTRANS]) + ]) + m4_require(GL_MODULE_INDICATOR_PREFIX[_WCTYPE_H_MODULE_INDICATOR_DEFAULTS]) + AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) +]) + AC_DEFUN([gl_WCTYPE_H_DEFAULTS], [ - GNULIB_ISWBLANK=0; AC_SUBST([GNULIB_ISWBLANK]) - GNULIB_WCTYPE=0; AC_SUBST([GNULIB_WCTYPE]) - GNULIB_ISWCTYPE=0; AC_SUBST([GNULIB_ISWCTYPE]) - GNULIB_WCTRANS=0; AC_SUBST([GNULIB_WCTRANS]) - GNULIB_TOWCTRANS=0; AC_SUBST([GNULIB_TOWCTRANS]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_ISWBLANK=1; AC_SUBST([HAVE_ISWBLANK]) HAVE_WCTYPE_T=1; AC_SUBST([HAVE_WCTYPE_T]) HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T]) REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK]) + REPLACE_ISWDIGIT=0; AC_SUBST([REPLACE_ISWDIGIT]) + REPLACE_ISWXDIGIT=0; AC_SUBST([REPLACE_ISWXDIGIT]) ]) diff --git a/gl/m4/wint_t.m4 b/gl/m4/wint_t.m4 index d7cd3db9..adc58661 100644 --- a/gl/m4/wint_t.m4 +++ b/gl/m4/wint_t.m4 @@ -1,11 +1,12 @@ -# wint_t.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. +# wint_t.m4 serial 11 +dnl Copyright (C) 2003, 2007-2022 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 From Bruno Haible. -dnl Test whether has the 'wint_t' type. +dnl Test whether has the 'wint_t' type and whether gnulib's +dnl or would, if present, override 'wint_t'. dnl Prerequisite: AC_PROG_CC AC_DEFUN([gt_TYPE_WINT_T], @@ -13,20 +14,44 @@ AC_DEFUN([gt_TYPE_WINT_T], AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be included - before . */ -#include -#include -#include -#include + [[#include wint_t foo = (wchar_t)'\0';]], [[]])], [gt_cv_c_wint_t=yes], [gt_cv_c_wint_t=no])]) if test $gt_cv_c_wint_t = yes; then AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.]) + + dnl Determine whether gnulib's or would, if present, + dnl override 'wint_t'. + AC_CACHE_CHECK([whether wint_t is large enough], + [gl_cv_type_wint_t_large_enough], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + int verify[sizeof (wint_t) < sizeof (int) ? -1 : 1]; + ]])], + [gl_cv_type_wint_t_large_enough=yes], + [gl_cv_type_wint_t_large_enough=no])]) + if test $gl_cv_type_wint_t_large_enough = no; then + GNULIBHEADERS_OVERRIDE_WINT_T=1 + else + GNULIBHEADERS_OVERRIDE_WINT_T=0 + fi + else + GNULIBHEADERS_OVERRIDE_WINT_T=0 + fi + AC_SUBST([GNULIBHEADERS_OVERRIDE_WINT_T]) +]) + +dnl Prerequisites of the 'wint_t' override. +AC_DEFUN([gl_TYPE_WINT_T_PREREQ], +[ + AC_CHECK_HEADERS_ONCE([crtdefs.h]) + if test $ac_cv_header_crtdefs_h = yes; then + HAVE_CRTDEFS_H=1 + else + HAVE_CRTDEFS_H=0 fi + AC_SUBST([HAVE_CRTDEFS_H]) ]) diff --git a/gl/m4/xalloc.m4 b/gl/m4/xalloc.m4 index 64ca7014..17a9c06d 100644 --- a/gl/m4/xalloc.m4 +++ b/gl/m4/xalloc.m4 @@ -1,5 +1,5 @@ # xalloc.m4 serial 18 -dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2002-2006, 2009-2022 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. diff --git a/gl/m4/xsize.m4 b/gl/m4/xsize.m4 index 8ea9f2cd..0109049e 100644 --- a/gl/m4/xsize.m4 +++ b/gl/m4/xsize.m4 @@ -1,5 +1,5 @@ # xsize.m4 serial 5 -dnl Copyright (C) 2003-2004, 2008-2013 Free Software Foundation, Inc. +dnl Copyright (C) 2003-2004, 2008-2022 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. diff --git a/gl/m4/xstrndup.m4 b/gl/m4/xstrndup.m4 deleted file mode 100644 index 4a9330bb..00000000 --- a/gl/m4/xstrndup.m4 +++ /dev/null @@ -1,15 +0,0 @@ -# xstrndup.m4 serial 2 -dnl Copyright (C) 2003, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_XSTRNDUP], -[ - gl_PREREQ_XSTRNDUP -]) - -# Prerequisites of lib/xstrndup.c. -AC_DEFUN([gl_PREREQ_XSTRNDUP], [ - : -]) diff --git a/gl/m4/year2038.m4 b/gl/m4/year2038.m4 new file mode 100644 index 00000000..2e4427e6 --- /dev/null +++ b/gl/m4/year2038.m4 @@ -0,0 +1,132 @@ +# year2038.m4 serial 8 +dnl Copyright (C) 2017-2022 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 Attempt to ensure that 'time_t' can go past the year 2038 and that +dnl the functions 'time', 'stat', etc. work with post-2038 timestamps. + +m4_ifdef([AC_SYS_YEAR2038], [ + AC_DEFUN([gl_YEAR2038_EARLY]) + AC_DEFUN([gl_YEAR2038], [AC_SYS_YEAR2038]) + AC_DEFUN([gl_YEAR2038_BODY], [_AC_SYS_YEAR2038]) +], [ + +AC_DEFUN([gl_YEAR2038_EARLY], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) + AC_DEFINE([__MINGW_USE_VC2005_COMPAT], [1], + [For 64-bit time_t on 32-bit mingw.]) + ;; + esac +]) + +# gl_YEAR2038_TEST_INCLUDES +# ------------------------- +AC_DEFUN([gl_YEAR2038_TEST_INCLUDES], +[[ + #include + /* Check that time_t can represent 2**32 - 1 correctly. */ + #define LARGE_TIME_T \\ + ((time_t) (((time_t) 1 << 30) - 1 + 3 * ((time_t) 1 << 30))) + int verify_time_t_range[(LARGE_TIME_T / 65537 == 65535 + && LARGE_TIME_T % 65537 == 0) + ? 1 : -1]; +]]) + +# gl_YEAR2038_BODY(REQUIRE-YEAR2038-SAFE) +----------------------------------------- +AC_DEFUN([gl_YEAR2038_BODY], +[ + AC_ARG_ENABLE([year2038], + [ --disable-year2038 omit support for timestamps past the year 2038]) + AS_IF([test "$enable_year2038" != no], + [ + dnl On many systems, time_t is already a 64-bit type. + dnl On those systems where time_t is still 32-bit, it requires kernel + dnl and libc support to make it 64-bit. For glibc 2.34 and later on Linux, + dnl defining _TIME_BITS=64 and _FILE_OFFSET_BITS=64 is needed on x86 and ARM. + dnl + dnl On native Windows, the system include files define types __time32_t + dnl and __time64_t. By default, time_t is an alias of + dnl - __time32_t on 32-bit mingw, + dnl - __time64_t on 64-bit mingw and on MSVC (since MSVC 8). + dnl But when compiling with -D__MINGW_USE_VC2005_COMPAT, time_t is an + dnl alias of __time64_t. + dnl And when compiling with -D_USE_32BIT_TIME_T, time_t is an alias of + dnl __time32_t. + AC_CACHE_CHECK([for time_t past the year 2038], [gl_cv_type_time_t_y2038], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([gl_YEAR2038_TEST_INCLUDES])], + [gl_cv_type_time_t_y2038=yes], [gl_cv_type_time_t_y2038=no]) + ]) + if test "$gl_cv_type_time_t_y2038" = no; then + AC_CACHE_CHECK([for 64-bit time_t with _TIME_BITS=64], + [gl_cv_type_time_t_bits_macro], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[#define _TIME_BITS 64 + #define _FILE_OFFSET_BITS 64 + ]gl_YEAR2038_TEST_INCLUDES])], + [gl_cv_type_time_t_bits_macro=yes], + [gl_cv_type_time_t_bits_macro=no]) + ]) + if test "$gl_cv_type_time_t_bits_macro" = yes; then + AC_DEFINE([_TIME_BITS], [64], + [Number of bits in a timestamp, on hosts where this is settable.]) + dnl AC_SYS_LARGFILE also defines this; it's OK if we do too. + AC_DEFINE([_FILE_OFFSET_BITS], [64], + [Number of bits in a file offset, on hosts where this is settable.]) + gl_cv_type_time_t_y2038=yes + fi + fi + if test $gl_cv_type_time_t_y2038 = no; then + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _USE_32BIT_TIME_T + int ok; + #else + error fail + #endif + ]])], + [AC_MSG_FAILURE( + [The 'time_t' type stops working after January 2038. + Remove _USE_32BIT_TIME_T from the compiler flags.])], + [# If not cross-compiling and $1 says we should check, + # and 'touch' works with a large timestamp, then evidently wider time_t + # is desired and supported, so fail and ask the builder to fix the + # problem. Otherwise, just warn the builder. + m4_ifval([$1], + [if test $cross_compiling = no \ + && TZ=UTC0 touch -t 210602070628.15 conftest.time 2>/dev/null; then + case `TZ=UTC0 LC_ALL=C ls -l conftest.time 2>/dev/null` in + *'Feb 7 2106'* | *'Feb 7 17:10'*) + AC_MSG_FAILURE( + [The 'time_t' type stops working after January 2038, + and your system appears to support a wider 'time_t'. + Try configuring with 'CC="${CC} -m64"'. + To build with a 32-bit time_t anyway (not recommended), + configure with '--disable-year2038'.]);; + esac + rm -f conftest.time + fi]) + if test "$gl_warned_about_y2038" != yes; then + AC_MSG_WARN( + [The 'time_t' type stops working after January 2038, + and this package needs a wider 'time_t' type + if there is any way to access timestamps after that. + Configure with 'CC="${CC} -m64"' perhaps?]) + gl_warned_about_y2038=yes + fi + ]) + fi]) +]) + +AC_DEFUN([gl_YEAR2038], +[ + gl_YEAR2038_BODY([require-year2038-safe]) +]) + +]) # m4_ifndef AC_SYS_YEAR2038 diff --git a/gl/m4/zzgnulib.m4 b/gl/m4/zzgnulib.m4 new file mode 100644 index 00000000..fd73a201 --- /dev/null +++ b/gl/m4/zzgnulib.m4 @@ -0,0 +1,23 @@ +# zzgnulib.m4 serial 1 +dnl Copyright (C) 2020-2022 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 This file must be named something that sorts after all other +dnl package- or gnulib-provided .m4 files - at least for those packages +dnl that redefine AC_PROG_CC. + +dnl Redefine AC_PROG_CC so that it ends with invocations of gl_COMPILER_CLANG +dnl and gl_COMPILER_PREPARE_CHECK_DECL. +m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[ +gl_COMPILER_CLANG +gl_COMPILER_PREPARE_CHECK_DECL +]) + +# gl_ZZGNULIB +# ----------- +# Witness macro that this file has been included. Needed to force +# Automake to include this file after all other gnulib .m4 files. +AC_DEFUN([gl_ZZGNULIB]) diff --git a/gl/malloc.c b/gl/malloc.c index 908735d2..f334dd6e 100644 --- a/gl/malloc.c +++ b/gl/malloc.c @@ -1,51 +1,46 @@ /* malloc() function that is glibc compatible. - Copyright (C) 1997-1998, 2006-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1997-1998, 2006-2007, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* written by Jim Meyering and Bruno Haible */ #define _GL_USE_STDLIB_ALLOC 1 #include -/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ -#ifdef malloc -# define NEED_MALLOC_GNU 1 -# undef malloc -/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ -#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU -# define NEED_MALLOC_GNU 1 -#endif #include #include -/* Allocate an N-byte block of memory from the heap. - If N is zero, allocate a 1-byte block. */ +#include "xalloc-oversized.h" + +/* Allocate an N-byte block of memory from the heap, even if N is 0. */ void * rpl_malloc (size_t n) { - void *result; - -#if NEED_MALLOC_GNU if (n == 0) n = 1; -#endif - result = malloc (n); + if (xalloc_oversized (n, 1)) + { + errno = ENOMEM; + return NULL; + } + + void *result = malloc (n); #if !HAVE_MALLOC_POSIX if (result == NULL) diff --git a/gl/malloc/dynarray-skeleton.c b/gl/malloc/dynarray-skeleton.c new file mode 100644 index 00000000..bad548a4 --- /dev/null +++ b/gl/malloc/dynarray-skeleton.c @@ -0,0 +1,528 @@ +/* Type-safe arrays which grow dynamically. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* 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 + +#include +#include +#include + +#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. */ +__attribute_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__ __attribute_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. */ +__attribute_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. */ +__attribute_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. */ +__attribute_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. */ +__attribute_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. */ +__attribute_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. */ +__attribute_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. */ +__attribute_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__ +__attribute_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__ __attribute_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__ __attribute_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__ __attribute_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__ +__attribute_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__ +__attribute_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 diff --git a/gl/malloc/dynarray.h b/gl/malloc/dynarray.h new file mode 100644 index 00000000..f16fd950 --- /dev/null +++ b/gl/malloc/dynarray.h @@ -0,0 +1,178 @@ +/* Type-safe arrays which grow dynamically. Shared definitions. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* To use the dynarray facility, you need to include + 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 + + 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 + + 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 +#include +#include + +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 */ diff --git a/gl/malloc/dynarray_at_failure.c b/gl/malloc/dynarray_at_failure.c new file mode 100644 index 00000000..062ab706 --- /dev/null +++ b/gl/malloc/dynarray_at_failure.c @@ -0,0 +1,40 @@ +/* Report an dynamic array index out of bounds condition. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +# include +#endif + +#include +#include + +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); + __libc_fatal (buf); +#else + abort (); +#endif +} +libc_hidden_def (__libc_dynarray_at_failure) diff --git a/gl/malloc/dynarray_emplace_enlarge.c b/gl/malloc/dynarray_emplace_enlarge.c new file mode 100644 index 00000000..0cff2e70 --- /dev/null +++ b/gl/malloc/dynarray_emplace_enlarge.c @@ -0,0 +1,77 @@ +/* Increase the size of a dynamic array in preparation of an emplace operation. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +#endif + +#include +#include +#include +#include +#include + +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) diff --git a/gl/malloc/dynarray_finalize.c b/gl/malloc/dynarray_finalize.c new file mode 100644 index 00000000..3f360c3a --- /dev/null +++ b/gl/malloc/dynarray_finalize.c @@ -0,0 +1,66 @@ +/* Copy the dynamically-allocated area to an explicitly-sized heap allocation. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +#endif + +#include +#include +#include + +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) diff --git a/gl/malloc/dynarray_resize.c b/gl/malloc/dynarray_resize.c new file mode 100644 index 00000000..8d1922e5 --- /dev/null +++ b/gl/malloc/dynarray_resize.c @@ -0,0 +1,68 @@ +/* Increase the size of a dynamic array. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +#endif + +#include +#include +#include +#include +#include + +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) diff --git a/gl/malloc/dynarray_resize_clear.c b/gl/malloc/dynarray_resize_clear.c new file mode 100644 index 00000000..8cf1b0d0 --- /dev/null +++ b/gl/malloc/dynarray_resize_clear.c @@ -0,0 +1,39 @@ +/* Increase the size of a dynamic array and clear the new part. + Copyright (C) 2017-2022 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +#endif + +#include +#include + +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) diff --git a/gl/malloca.c b/gl/malloca.c index 311be569..183783a7 100644 --- a/gl/malloca.c +++ b/gl/malloca.c @@ -1,19 +1,19 @@ /* Safe automatic memory allocation. - Copyright (C) 2003, 2006-2007, 2009-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2003. + Copyright (C) 2003, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003, 2018. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #define _GL_USE_STDLIB_ALLOC 1 #include @@ -21,82 +21,57 @@ /* Specification. */ #include "malloca.h" -#include +#include +#include "idx.h" #include "verify.h" /* The speed critical point in this file is freea() applied to an alloca() result: it must be fast, to match the speed of alloca(). The speed of mmalloca() and freea() in the other case are not critical, because they - are only invoked for big memory sizes. */ - -#if HAVE_ALLOCA - -/* Store the mmalloca() results in a hash table. This is needed to reliably - distinguish a mmalloca() result and an alloca() result. - - Although it is possible that the same pointer is returned by alloca() and - by mmalloca() at different times in the same application, it does not lead - to a bug in freea(), because: - - Before a pointer returned by alloca() can point into malloc()ed memory, - the function must return, and once this has happened the programmer must - not call freea() on it anyway. - - Before a pointer returned by mmalloca() can point into the stack, it - must be freed. The only function that can free it is freea(), and - when freea() frees it, it also removes it from the hash table. */ - -#define MAGIC_NUMBER 0x1415fb4a -#define MAGIC_SIZE sizeof (int) -/* This is how the header info would look like without any alignment - considerations. */ -struct preliminary_header { void *next; int magic; }; -/* But the header's size must be a multiple of sa_alignment_max. */ -#define HEADER_SIZE \ - (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max) -union header { - void *next; - struct { - char room[HEADER_SIZE - MAGIC_SIZE]; - int word; - } magic; -}; -verify (HEADER_SIZE == sizeof (union header)); -/* We make the hash table quite big, so that during lookups the probability - of empty hash buckets is quite high. There is no need to make the hash - table resizable, because when the hash table gets filled so much that the - lookup becomes slow, it means that the application has memory leaks. */ -#define HASH_TABLE_SIZE 257 -static void * mmalloca_results[HASH_TABLE_SIZE]; - -#endif + are only invoked for big memory sizes. + Here we use a bit in the address as an indicator, an idea by OndÅ™ej Bílka. + malloca() can return three types of pointers: + - Pointers ≡ 0 mod 2*sa_alignment_max come from stack allocation. + - Pointers ≡ sa_alignment_max mod 2*sa_alignment_max come from heap + allocation. + - NULL comes from a failed heap allocation. */ + +/* Type for holding very small pointer differences. */ +typedef unsigned char small_t; +/* Verify that it is wide enough. */ +verify (2 * sa_alignment_max - 1 <= (small_t) -1); void * mmalloca (size_t n) { #if HAVE_ALLOCA - /* Allocate one more word, that serves as an indicator for malloc()ed - memory, so that freea() of an alloca() result is fast. */ - size_t nplus = n + HEADER_SIZE; - - if (nplus >= n) + /* Allocate one more word, used to determine the address to pass to freea(), + and room for the alignment ≡ sa_alignment_max mod 2*sa_alignment_max. */ + uintptr_t alignment2_mask = 2 * sa_alignment_max - 1; + int plus = sizeof (small_t) + alignment2_mask; + idx_t nplus; + if (!ckd_add (&nplus, n, plus) && !xalloc_oversized (nplus, 1)) { - void *p = malloc (nplus); + char *mem = (char *) malloc (nplus); - if (p != NULL) + if (mem != NULL) { - size_t slot; - union header *h = p; - - p = h + 1; - - /* Put a magic number into the indicator word. */ - h->magic.word = MAGIC_NUMBER; - - /* Enter p into the hash table. */ - slot = (uintptr_t) p % HASH_TABLE_SIZE; - h->next = mmalloca_results[slot]; - mmalloca_results[slot] = p; - + uintptr_t umem = (uintptr_t)mem, umemplus; + /* The ckd_add avoids signed integer overflow on + theoretical platforms where UINTPTR_MAX <= INT_MAX. */ + ckd_add (&umemplus, umem, sizeof (small_t) + sa_alignment_max - 1); + idx_t offset = ((umemplus & ~alignment2_mask) + + sa_alignment_max - umem); + void *vp = mem + offset; + small_t *p = vp; + /* Here p >= mem + sizeof (small_t), + and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1 + hence p + n <= mem + nplus. + So, the memory range [p, p+n) lies in the allocated memory range + [mem, mem + nplus). */ + p[-1] = offset; + /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */ return p; } } @@ -115,35 +90,24 @@ mmalloca (size_t n) void freea (void *p) { - /* mmalloca() may have returned NULL. */ - if (p != NULL) + /* Check argument. */ + if ((uintptr_t) p & (sa_alignment_max - 1)) { - /* Attempt to quickly distinguish the mmalloca() result - which has - a magic indicator word - and the alloca() result - which has an - uninitialized indicator word. It is for this test that sa_increment - additional bytes are allocated in the alloca() case. */ - if (((int *) p)[-1] == MAGIC_NUMBER) - { - /* Looks like a mmalloca() result. To see whether it really is one, - perform a lookup in the hash table. */ - size_t slot = (uintptr_t) p % HASH_TABLE_SIZE; - void **chain = &mmalloca_results[slot]; - for (; *chain != NULL;) - { - union header *h = p; - if (*chain == p) - { - /* Found it. Remove it from the hash table and free it. */ - union header *p_begin = h - 1; - *chain = p_begin->next; - free (p_begin); - return; - } - h = *chain; - chain = &h[-1].next; - } - } - /* At this point, we know it was not a mmalloca() result. */ + /* p was not the result of a malloca() call. Invalid argument. */ + abort (); + } + /* Determine whether p was a non-NULL pointer returned by mmalloca(). */ + if ((uintptr_t) p & sa_alignment_max) + { + void *mem = (char *) p - ((small_t *) p)[-1]; + free (mem); } } #endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/gl/malloca.h b/gl/malloca.h index 6fbe45ea..7ec235f3 100644 --- a/gl/malloca.h +++ b/gl/malloca.h @@ -1,19 +1,19 @@ /* Safe automatic memory allocation. - Copyright (C) 2003-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2003. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _MALLOCA_H #define _MALLOCA_H @@ -21,6 +21,9 @@ #include #include #include +#include + +#include "xalloc-oversized.h" #ifdef __cplusplus @@ -48,40 +51,37 @@ extern "C" { # define safe_alloca(N) ((void) (N), NULL) #endif +/* Free a block of memory allocated through malloca(). */ +#if HAVE_ALLOCA +extern void freea (void *p); +#else +# define freea free +#endif + /* malloca(N) is a safe variant of alloca(N). It allocates N bytes of memory allocated on the stack, that must be freed using freea() before the function returns. Upon failure, it returns NULL. */ #if HAVE_ALLOCA # define malloca(N) \ - ((N) < 4032 - sa_increment \ - ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \ + ((N) < 4032 - (2 * sa_alignment_max - 1) \ + ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \ + + (2 * sa_alignment_max - 1)) \ + & ~(uintptr_t)(2 * sa_alignment_max - 1)) \ : mmalloca (N)) #else # define malloca(N) \ mmalloca (N) #endif -extern void * mmalloca (size_t n); - -/* Free a block of memory allocated through malloca(). */ -#if HAVE_ALLOCA -extern void freea (void *p); -#else -# define freea free -#endif +extern void *mmalloca (size_t n) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (freea, 1) + _GL_ATTRIBUTE_ALLOC_SIZE ((1)); /* nmalloca(N,S) is an overflow-safe variant of malloca (N * S). It allocates an array of N objects, each with S bytes of memory, - on the stack. S must be positive and N must be nonnegative. + on the stack. N and S should be nonnegative and free of side effects. The array must be freed using freea() before the function returns. */ -#if 1 -/* Cf. the definition of xalloc_oversized. */ -# define nmalloca(n, s) \ - ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \ - ? NULL \ - : malloca ((n) * (s))) -#else -extern void * nmalloca (size_t n, size_t s); -#endif +#define nmalloca(n, s) \ + (xalloc_oversized (n, s) ? NULL : malloca ((n) * (size_t) (s))) #ifdef __cplusplus @@ -92,7 +92,7 @@ extern void * nmalloca (size_t n, size_t s); /* ------------------- Auxiliary, non-public definitions ------------------- */ /* Determine the alignment of a type at compile time. */ -#if defined __GNUC__ || defined __IBM__ALIGNOF__ +#if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__ # define sa_alignof __alignof__ #elif defined __cplusplus template struct sa_alignof_helper { char __slot1; type __slot2; }; @@ -115,19 +115,12 @@ enum among all elementary types. */ sa_alignment_long = sa_alignof (long), sa_alignment_double = sa_alignof (double), -#if HAVE_LONG_LONG_INT sa_alignment_longlong = sa_alignof (long long), -#endif sa_alignment_longdouble = sa_alignof (long double), sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) -#if HAVE_LONG_LONG_INT | (sa_alignment_longlong - 1) -#endif | (sa_alignment_longdouble - 1) - ) + 1, -/* The increment that guarantees room for a magic word must be >= sizeof (int) - and a multiple of sa_alignment_max. */ - sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max + ) + 1 }; #endif /* _MALLOCA_H */ diff --git a/gl/malloca.valgrind b/gl/malloca.valgrind deleted file mode 100644 index 52f0a50f..00000000 --- a/gl/malloca.valgrind +++ /dev/null @@ -1,7 +0,0 @@ -# Suppress a valgrind message about use of uninitialized memory in freea(). -# This use is OK because it provides only a speedup. -{ - freea - Memcheck:Cond - fun:freea -} diff --git a/gl/math.c b/gl/math.c index ddb2ded5..1502a1fd 100644 --- a/gl/math.c +++ b/gl/math.c @@ -1,3 +1,22 @@ +/* Inline functions for . + + Copyright (C) 2012-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + #include + #define _GL_MATH_INLINE _GL_EXTERN_INLINE #include "math.h" +typedef int dummy; diff --git a/gl/math.in.h b/gl/math.in.h index 7189819b..a74a95da 100644 --- a/gl/math.in.h +++ b/gl/math.in.h @@ -1,19 +1,19 @@ /* A GNU-like . - Copyright (C) 2002-2003, 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2007-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_MATH_H @@ -22,17 +22,50 @@ #endif @PRAGMA_COLUMNS@ +#if defined _GL_INCLUDING_MATH_H +/* Special invocation convention: + - On FreeBSD 12.2 we have a sequence of nested includes + -> -> -> -> + -> -> -> -> + In this situation, the functions are not yet declared, therefore we cannot + provide the C++ aliases. */ + +#@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_MATH_H@ + +#else +/* Normal invocation convention. */ + /* The include_next requires a split double-inclusion guard. */ +#define _GL_INCLUDING_MATH_H #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_MATH_H@ +#undef _GL_INCLUDING_MATH_H #ifndef _@GUARD_PREFIX@_MATH_H #define _@GUARD_PREFIX@_MATH_H +/* On OpenVMS, NAN, INFINITY, and HUGEVAL macros are defined in . */ +#if defined __VMS && ! defined NAN +# include +#endif + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif _GL_INLINE_HEADER_BEGIN #ifndef _GL_MATH_INLINE # define _GL_MATH_INLINE _GL_INLINE #endif +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The attribute __const__ was added in gcc 2.95. */ +#ifndef _GL_ATTRIBUTE_CONST +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined __clang__ +# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) +# else +# define _GL_ATTRIBUTE_CONST /* empty */ +# endif +#endif + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ /* The definition of _GL_ARG_NONNULL is copied here. */ @@ -59,22 +92,24 @@ _gl_cxx_ ## func ## l (long double l) \ { \ return func (l); \ } -# define _GL_MATH_CXX_REAL_FLOATING_DECL_2(func) \ -inline int \ -func (float f) \ +# define _GL_MATH_CXX_REAL_FLOATING_DECL_2(func,rpl_func,rettype) \ +_GL_BEGIN_NAMESPACE \ +inline rettype \ +rpl_func (float f) \ { \ return _gl_cxx_ ## func ## f (f); \ } \ -inline int \ -func (double d) \ +inline rettype \ +rpl_func (double d) \ { \ return _gl_cxx_ ## func ## d (d); \ } \ -inline int \ -func (long double l) \ +inline rettype \ +rpl_func (long double l) \ { \ return _gl_cxx_ ## func ## l (l); \ -} +} \ +_GL_END_NAMESPACE #endif /* Helper macros to define a portability warning for the @@ -82,27 +117,27 @@ func (long double l) \ classification macros with an argument of real-floating (that is, one of float, double, or long double). */ #define _GL_WARN_REAL_FLOATING_DECL(func) \ -_GL_MATH_INLINE int \ -rpl_ ## func ## f (float f) \ -{ \ - return func (f); \ -} \ -_GL_MATH_INLINE int \ -rpl_ ## func ## d (double d) \ -{ \ - return func (d); \ -} \ -_GL_MATH_INLINE int \ -rpl_ ## func ## l (long double l) \ -{ \ - return func (l); \ -} \ -_GL_WARN_ON_USE (rpl_ ## func ## f, #func " is unportable - " \ - "use gnulib module " #func " for portability"); \ -_GL_WARN_ON_USE (rpl_ ## func ## d, #func " is unportable - " \ - "use gnulib module " #func " for portability"); \ -_GL_WARN_ON_USE (rpl_ ## func ## l, #func " is unportable - " \ - "use gnulib module " #func " for portability") +_GL_MATH_INLINE int \ +_GL_WARN_ON_USE_ATTRIBUTE (#func " is unportable - " \ + "use gnulib module " #func " for portability") \ +rpl_ ## func ## f (float f) \ +{ \ + return func (f); \ +} \ +_GL_MATH_INLINE int \ +_GL_WARN_ON_USE_ATTRIBUTE (#func " is unportable - " \ + "use gnulib module " #func " for portability") \ +rpl_ ## func ## d (double d) \ +{ \ + return func (d); \ +} \ +_GL_MATH_INLINE int \ +_GL_WARN_ON_USE_ATTRIBUTE (#func " is unportable - " \ + "use gnulib module " #func " for portability") \ +rpl_ ## func ## l (long double l) \ +{ \ + return func (l); \ +} #define _GL_WARN_REAL_FLOATING_IMPL(func, value) \ (sizeof (value) == sizeof (float) ? rpl_ ## func ## f (value) \ : sizeof (value) == sizeof (double) ? rpl_ ## func ## d (value) \ @@ -184,8 +219,17 @@ _NaN () #endif -/* Ensure FP_ILOGB0 and FP_ILOGBNAN are defined. */ -#if !(defined FP_ILOGB0 && defined FP_ILOGBNAN) +#if defined FP_ILOGB0 && defined FP_ILOGBNAN + /* Ensure FP_ILOGB0 and FP_ILOGBNAN are correct. */ +# if defined __HAIKU__ + /* Haiku: match what ilogb() does */ +# undef FP_ILOGB0 +# undef FP_ILOGBNAN +# define FP_ILOGB0 (- 2147483647 - 1) /* INT_MIN */ +# define FP_ILOGBNAN (- 2147483647 - 1) /* INT_MIN */ +# endif +#else + /* Ensure FP_ILOGB0 and FP_ILOGBNAN are defined. */ # if defined __NetBSD__ || defined __sgi /* NetBSD, IRIX 6.5: match what ilogb() does */ # define FP_ILOGB0 (- 2147483647 - 1) /* INT_MIN */ @@ -207,11 +251,20 @@ _NaN () #if @GNULIB_ACOSF@ -# if !@HAVE_ACOSF@ -# undef acosf +# if @REPLACE_ACOSF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef acosf +# define acosf rpl_acosf +# endif +_GL_FUNCDECL_RPL (acosf, float, (float x)); +_GL_CXXALIAS_RPL (acosf, float, (float x)); +# else +# if !@HAVE_ACOSF@ +# undef acosf _GL_FUNCDECL_SYS (acosf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (acosf, float, (float x)); +# endif _GL_CXXALIASWARN (acosf); #elif defined GNULIB_POSIXCHECK # undef acosf @@ -227,7 +280,9 @@ _GL_WARN_ON_USE (acosf, "acosf is unportable - " _GL_FUNCDECL_SYS (acosl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (acosl, long double, (long double x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (acosl); +# endif #elif defined GNULIB_POSIXCHECK # undef acosl # if HAVE_RAW_DECL_ACOSL @@ -238,11 +293,20 @@ _GL_WARN_ON_USE (acosl, "acosl is unportable - " #if @GNULIB_ASINF@ -# if !@HAVE_ASINF@ -# undef asinf +# if @REPLACE_ASINF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef asinf +# define asinf rpl_asinf +# endif +_GL_FUNCDECL_RPL (asinf, float, (float x)); +_GL_CXXALIAS_RPL (asinf, float, (float x)); +# else +# if !@HAVE_ASINF@ +# undef asinf _GL_FUNCDECL_SYS (asinf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (asinf, float, (float x)); +# endif _GL_CXXALIASWARN (asinf); #elif defined GNULIB_POSIXCHECK # undef asinf @@ -258,7 +322,9 @@ _GL_WARN_ON_USE (asinf, "asinf is unportable - " _GL_FUNCDECL_SYS (asinl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (asinl, long double, (long double x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (asinl); +# endif #elif defined GNULIB_POSIXCHECK # undef asinl # if HAVE_RAW_DECL_ASINL @@ -269,11 +335,20 @@ _GL_WARN_ON_USE (asinl, "asinl is unportable - " #if @GNULIB_ATANF@ -# if !@HAVE_ATANF@ -# undef atanf +# if @REPLACE_ATANF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef atanf +# define atanf rpl_atanf +# endif +_GL_FUNCDECL_RPL (atanf, float, (float x)); +_GL_CXXALIAS_RPL (atanf, float, (float x)); +# else +# if !@HAVE_ATANF@ +# undef atanf _GL_FUNCDECL_SYS (atanf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (atanf, float, (float x)); +# endif _GL_CXXALIASWARN (atanf); #elif defined GNULIB_POSIXCHECK # undef atanf @@ -289,7 +364,9 @@ _GL_WARN_ON_USE (atanf, "atanf is unportable - " _GL_FUNCDECL_SYS (atanl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (atanl, long double, (long double x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (atanl); +# endif #elif defined GNULIB_POSIXCHECK # undef atanl # if HAVE_RAW_DECL_ATANL @@ -300,11 +377,20 @@ _GL_WARN_ON_USE (atanl, "atanl is unportable - " #if @GNULIB_ATAN2F@ -# if !@HAVE_ATAN2F@ -# undef atan2f +# if @REPLACE_ATAN2F@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef atan2f +# define atan2f rpl_atan2f +# endif +_GL_FUNCDECL_RPL (atan2f, float, (float y, float x)); +_GL_CXXALIAS_RPL (atan2f, float, (float y, float x)); +# else +# if !@HAVE_ATAN2F@ +# undef atan2f _GL_FUNCDECL_SYS (atan2f, float, (float y, float x)); -# endif +# endif _GL_CXXALIAS_SYS (atan2f, float, (float y, float x)); +# endif _GL_CXXALIASWARN (atan2f); #elif defined GNULIB_POSIXCHECK # undef atan2f @@ -343,7 +429,9 @@ _GL_WARN_ON_USE (cbrtf, "cbrtf is unportable - " _GL_FUNCDECL_SYS (cbrt, double, (double x)); # endif _GL_CXXALIAS_SYS (cbrt, double, (double x)); -_GL_CXXALIASWARN (cbrt); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (cbrt, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef cbrt # if HAVE_RAW_DECL_CBRT @@ -403,6 +491,7 @@ _GL_WARN_ON_USE (ceilf, "ceilf is unportable - " #if @GNULIB_CEIL@ # if @REPLACE_CEIL@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ceil # define ceil rpl_ceil # endif _GL_FUNCDECL_RPL (ceil, double, (double x)); @@ -410,7 +499,9 @@ _GL_CXXALIAS_RPL (ceil, double, (double x)); # else _GL_CXXALIAS_SYS (ceil, double, (double x)); # endif -_GL_CXXALIASWARN (ceil); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (ceil, double, (double x)); +# endif #endif #if @GNULIB_CEILL@ @@ -428,7 +519,9 @@ _GL_FUNCDECL_SYS (ceill, long double, (long double x)); # endif _GL_CXXALIAS_SYS (ceill, long double, (long double x)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (ceill); +# endif #elif defined GNULIB_POSIXCHECK # undef ceill # if HAVE_RAW_DECL_CEILL @@ -440,6 +533,7 @@ _GL_WARN_ON_USE (ceill, "ceill is unportable - " #if @GNULIB_COPYSIGNF@ # if !@HAVE_DECL_COPYSIGNF@ +# undef copysignf _GL_FUNCDECL_SYS (copysignf, float, (float x, float y)); # endif _GL_CXXALIAS_SYS (copysignf, float, (float x, float y)); @@ -457,7 +551,9 @@ _GL_WARN_ON_USE (copysignf, "copysignf is unportable - " _GL_FUNCDECL_SYS (copysign, double, (double x, double y)); # endif _GL_CXXALIAS_SYS (copysign, double, (double x, double y)); -_GL_CXXALIASWARN (copysign); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (copysign, double, (double x, double y)); +# endif #elif defined GNULIB_POSIXCHECK # undef copysign # if HAVE_RAW_DECL_COPYSIGN @@ -482,11 +578,20 @@ _GL_WARN_ON_USE (copysign, "copysignl is unportable - " #if @GNULIB_COSF@ -# if !@HAVE_COSF@ -# undef cosf +# if @REPLACE_COSF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef cosf +# define cosf rpl_cosf +# endif +_GL_FUNCDECL_RPL (cosf, float, (float x)); +_GL_CXXALIAS_RPL (cosf, float, (float x)); +# else +# if !@HAVE_COSF@ +# undef cosf _GL_FUNCDECL_SYS (cosf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (cosf, float, (float x)); +# endif _GL_CXXALIASWARN (cosf); #elif defined GNULIB_POSIXCHECK # undef cosf @@ -502,7 +607,9 @@ _GL_WARN_ON_USE (cosf, "cosf is unportable - " _GL_FUNCDECL_SYS (cosl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (cosl, long double, (long double x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (cosl); +# endif #elif defined GNULIB_POSIXCHECK # undef cosl # if HAVE_RAW_DECL_COSL @@ -513,11 +620,20 @@ _GL_WARN_ON_USE (cosl, "cosl is unportable - " #if @GNULIB_COSHF@ -# if !@HAVE_COSHF@ -# undef coshf +# if @REPLACE_COSHF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef coshf +# define coshf rpl_coshf +# endif +_GL_FUNCDECL_RPL (coshf, float, (float x)); +_GL_CXXALIAS_RPL (coshf, float, (float x)); +# else +# if !@HAVE_COSHF@ +# undef coshf _GL_FUNCDECL_SYS (coshf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (coshf, float, (float x)); +# endif _GL_CXXALIASWARN (coshf); #elif defined GNULIB_POSIXCHECK # undef coshf @@ -529,11 +645,20 @@ _GL_WARN_ON_USE (coshf, "coshf is unportable - " #if @GNULIB_EXPF@ -# if !@HAVE_EXPF@ -# undef expf +# if @REPLACE_EXPF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef expf +# define expf rpl_expf +# endif +_GL_FUNCDECL_RPL (expf, float, (float x)); +_GL_CXXALIAS_RPL (expf, float, (float x)); +# else +# if !@HAVE_EXPF@ +# undef expf _GL_FUNCDECL_SYS (expf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (expf, float, (float x)); +# endif _GL_CXXALIASWARN (expf); #elif defined GNULIB_POSIXCHECK # undef expf @@ -544,12 +669,23 @@ _GL_WARN_ON_USE (expf, "expf is unportable - " #endif #if @GNULIB_EXPL@ -# if !@HAVE_EXPL@ || !@HAVE_DECL_EXPL@ -# undef expl +# if @REPLACE_EXPL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef expl +# define expl rpl_expl +# endif +_GL_FUNCDECL_RPL (expl, long double, (long double x)); +_GL_CXXALIAS_RPL (expl, long double, (long double x)); +# else +# if !@HAVE_EXPL@ || !@HAVE_DECL_EXPL@ +# undef expl _GL_FUNCDECL_SYS (expl, long double, (long double x)); -# endif +# endif _GL_CXXALIAS_SYS (expl, long double, (long double x)); +# endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (expl); +# endif #elif defined GNULIB_POSIXCHECK # undef expl # if HAVE_RAW_DECL_EXPL @@ -587,7 +723,9 @@ _GL_FUNCDECL_SYS (exp2, double, (double x)); # endif _GL_CXXALIAS_SYS (exp2, double, (double x)); # endif -_GL_CXXALIASWARN (exp2); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (exp2, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef exp2 # if HAVE_RAW_DECL_EXP2 @@ -658,7 +796,9 @@ _GL_FUNCDECL_SYS (expm1, double, (double x)); # endif _GL_CXXALIAS_SYS (expm1, double, (double x)); # endif -_GL_CXXALIASWARN (expm1); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (expm1, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef expm1 # if HAVE_RAW_DECL_EXPM1 @@ -668,11 +808,22 @@ _GL_WARN_ON_USE (expm1, "expm1 is unportable - " #endif #if @GNULIB_EXPM1L@ -# if !@HAVE_DECL_EXPM1L@ -# undef expm1l +# if @REPLACE_EXPM1L@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef expm1l +# define expm1l rpl_expm1l +# endif +_GL_FUNCDECL_RPL (expm1l, long double, (long double x)); +_GL_CXXALIAS_RPL (expm1l, long double, (long double x)); +# else +# if !@HAVE_DECL_EXPM1L@ +# undef expm1l +# if !(defined __cplusplus && defined _AIX) _GL_FUNCDECL_SYS (expm1l, long double, (long double x)); -# endif +# endif +# endif _GL_CXXALIAS_SYS (expm1l, long double, (long double x)); +# endif _GL_CXXALIASWARN (expm1l); #elif defined GNULIB_POSIXCHECK # undef expm1l @@ -689,7 +840,9 @@ _GL_WARN_ON_USE (expm1l, "expm1l is unportable - " _GL_FUNCDECL_SYS (fabsf, float, (float x)); # endif _GL_CXXALIAS_SYS (fabsf, float, (float x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fabsf); +# endif #elif defined GNULIB_POSIXCHECK # undef fabsf # if HAVE_RAW_DECL_FABSF @@ -713,7 +866,9 @@ _GL_FUNCDECL_SYS (fabsl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (fabsl, long double, (long double x)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fabsl); +# endif #elif defined GNULIB_POSIXCHECK # undef fabsl # if HAVE_RAW_DECL_FABSL @@ -750,6 +905,7 @@ _GL_WARN_ON_USE (floorf, "floorf is unportable - " #if @GNULIB_FLOOR@ # if @REPLACE_FLOOR@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef floor # define floor rpl_floor # endif _GL_FUNCDECL_RPL (floor, double, (double x)); @@ -757,7 +913,9 @@ _GL_CXXALIAS_RPL (floor, double, (double x)); # else _GL_CXXALIAS_SYS (floor, double, (double x)); # endif -_GL_CXXALIASWARN (floor); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (floor, double, (double x)); +# endif #endif #if @GNULIB_FLOORL@ @@ -775,7 +933,9 @@ _GL_FUNCDECL_SYS (floorl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (floorl, long double, (long double x)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (floorl); +# endif #elif defined GNULIB_POSIXCHECK # undef floorl # if HAVE_RAW_DECL_FLOORL @@ -795,6 +955,7 @@ _GL_FUNCDECL_RPL (fmaf, float, (float x, float y, float z)); _GL_CXXALIAS_RPL (fmaf, float, (float x, float y, float z)); # else # if !@HAVE_FMAF@ +# undef fmaf _GL_FUNCDECL_SYS (fmaf, float, (float x, float y, float z)); # endif _GL_CXXALIAS_SYS (fmaf, float, (float x, float y, float z)); @@ -818,11 +979,14 @@ _GL_FUNCDECL_RPL (fma, double, (double x, double y, double z)); _GL_CXXALIAS_RPL (fma, double, (double x, double y, double z)); # else # if !@HAVE_FMA@ +# undef fma _GL_FUNCDECL_SYS (fma, double, (double x, double y, double z)); # endif _GL_CXXALIAS_SYS (fma, double, (double x, double y, double z)); # endif -_GL_CXXALIASWARN (fma); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (fma, double, (double x, double y, double z)); +# endif #elif defined GNULIB_POSIXCHECK # undef fma # if HAVE_RAW_DECL_FMA @@ -844,8 +1008,10 @@ _GL_CXXALIAS_RPL (fmal, long double, # else # if !@HAVE_FMAL@ # undef fmal +# if !(defined __cplusplus && defined _AIX) _GL_FUNCDECL_SYS (fmal, long double, (long double x, long double y, long double z)); +# endif # endif _GL_CXXALIAS_SYS (fmal, long double, (long double x, long double y, long double z)); @@ -895,7 +1061,9 @@ _GL_CXXALIAS_RPL (fmod, double, (double x, double y)); # else _GL_CXXALIAS_SYS (fmod, double, (double x, double y)); # endif -_GL_CXXALIASWARN (fmod); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (fmod, double, (double x, double y)); +# endif #elif defined GNULIB_POSIXCHECK # undef fmod # if HAVE_RAW_DECL_FMOD @@ -919,7 +1087,9 @@ _GL_FUNCDECL_SYS (fmodl, long double, (long double x, long double y)); # endif _GL_CXXALIAS_SYS (fmodl, long double, (long double x, long double y)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fmodl); +# endif #elif defined GNULIB_POSIXCHECK # undef fmodl # if HAVE_RAW_DECL_FMODL @@ -951,7 +1121,9 @@ _GL_FUNCDECL_SYS (frexpf, float, (float x, int *expptr) _GL_ARG_NONNULL ((2))); # endif _GL_CXXALIAS_SYS (frexpf, float, (float x, int *expptr)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (frexpf); +# endif #elif defined GNULIB_POSIXCHECK # undef frexpf # if HAVE_RAW_DECL_FREXPF @@ -970,6 +1142,7 @@ _GL_WARN_ON_USE (frexpf, "frexpf is unportable - " #if @GNULIB_FREXP@ # if @REPLACE_FREXP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef frexp # define frexp rpl_frexp # endif _GL_FUNCDECL_RPL (frexp, double, (double x, int *expptr) _GL_ARG_NONNULL ((2))); @@ -977,7 +1150,9 @@ _GL_CXXALIAS_RPL (frexp, double, (double x, int *expptr)); # else _GL_CXXALIAS_SYS (frexp, double, (double x, int *expptr)); # endif -_GL_CXXALIASWARN (frexp); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (frexp, double, (double x, int *expptr)); +# endif #elif defined GNULIB_POSIXCHECK # undef frexp /* Assume frexp is always declared. */ @@ -1010,7 +1185,9 @@ _GL_CXXALIAS_SYS (frexpl, long double, (long double x, int *expptr)); # endif #endif #if @GNULIB_FREXPL@ && !(@REPLACE_FREXPL@ && !@HAVE_DECL_FREXPL@) +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (frexpl); +# endif #endif #if !@GNULIB_FREXPL@ && defined GNULIB_POSIXCHECK # undef frexpl @@ -1036,7 +1213,9 @@ _GL_FUNCDECL_SYS (hypotf, float, (float x, float y)); # endif _GL_CXXALIAS_SYS (hypotf, float, (float x, float y)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (hypotf); +# endif #elif defined GNULIB_POSIXCHECK # undef hypotf # if HAVE_RAW_DECL_HYPOTF @@ -1057,7 +1236,9 @@ _GL_CXXALIAS_RPL (hypot, double, (double x, double y)); # else _GL_CXXALIAS_SYS (hypot, double, (double x, double y)); # endif -_GL_CXXALIASWARN (hypot); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (hypot, double, (double x, double y)); +# endif #elif defined GNULIB_POSIXCHECK # undef hypot # if HAVE_RAW_DECL_HYPOT @@ -1081,7 +1262,9 @@ _GL_FUNCDECL_SYS (hypotl, long double, (long double x, long double y)); # endif _GL_CXXALIAS_SYS (hypotl, long double, (long double x, long double y)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (hypotl); +# endif #elif defined GNULIB_POSIXCHECK # undef hypotl # if HAVE_RAW_DECL_HYPOTL @@ -1128,7 +1311,9 @@ _GL_FUNCDECL_SYS (ilogb, int, (double x)); # endif _GL_CXXALIAS_SYS (ilogb, int, (double x)); # endif -_GL_CXXALIASWARN (ilogb); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (ilogb, int, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef ilogb # if HAVE_RAW_DECL_ILOGB @@ -1138,10 +1323,20 @@ _GL_WARN_ON_USE (ilogb, "ilogb is unportable - " #endif #if @GNULIB_ILOGBL@ -# if !@HAVE_ILOGBL@ +# if @REPLACE_ILOGBL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ilogbl +# define ilogbl rpl_ilogbl +# endif +_GL_FUNCDECL_RPL (ilogbl, int, (long double x)); +_GL_CXXALIAS_RPL (ilogbl, int, (long double x)); +# else +# if !@HAVE_ILOGBL@ +# undef ilogbl _GL_FUNCDECL_SYS (ilogbl, int, (long double x)); -# endif +# endif _GL_CXXALIAS_SYS (ilogbl, int, (long double x)); +# endif _GL_CXXALIASWARN (ilogbl); #elif defined GNULIB_POSIXCHECK # undef ilogbl @@ -1152,6 +1347,55 @@ _GL_WARN_ON_USE (ilogbl, "ilogbl is unportable - " #endif +#if @GNULIB_MDA_J0@ +/* On native Windows, map 'j0' to '_j0', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::j0 always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef j0 +# define j0 _j0 +# endif +_GL_CXXALIAS_MDA (j0, double, (double x)); +# else +_GL_CXXALIAS_SYS (j0, double, (double x)); +# endif +_GL_CXXALIASWARN (j0); +#endif + +#if @GNULIB_MDA_J1@ +/* On native Windows, map 'j1' to '_j1', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::j1 always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef j1 +# define j1 _j1 +# endif +_GL_CXXALIAS_MDA (j1, double, (double x)); +# else +_GL_CXXALIAS_SYS (j1, double, (double x)); +# endif +_GL_CXXALIASWARN (j1); +#endif + +#if @GNULIB_MDA_JN@ +/* On native Windows, map 'jn' to '_jn', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::jn always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef jn +# define jn _jn +# endif +_GL_CXXALIAS_MDA (jn, double, (int n, double x)); +# else +_GL_CXXALIAS_SYS (jn, double, (int n, double x)); +# endif +_GL_CXXALIASWARN (jn); +#endif + + /* Return x * 2^exp. */ #if @GNULIB_LDEXPF@ # if !@HAVE_LDEXPF@ @@ -1159,7 +1403,9 @@ _GL_WARN_ON_USE (ilogbl, "ilogbl is unportable - " _GL_FUNCDECL_SYS (ldexpf, float, (float x, int exp)); # endif _GL_CXXALIAS_SYS (ldexpf, float, (float x, int exp)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (ldexpf); +# endif #elif defined GNULIB_POSIXCHECK # undef ldexpf # if HAVE_RAW_DECL_LDEXPF @@ -1185,7 +1431,9 @@ _GL_CXXALIAS_SYS (ldexpl, long double, (long double x, int exp)); # endif #endif #if @GNULIB_LDEXPL@ +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (ldexpl); +# endif #endif #if !@GNULIB_LDEXPL@ && defined GNULIB_POSIXCHECK # undef ldexpl @@ -1231,7 +1479,9 @@ _GL_CXXALIAS_RPL (log, double, (double x)); # else _GL_CXXALIAS_SYS (log, double, (double x)); # endif -_GL_CXXALIASWARN (log); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (log, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef log # if HAVE_RAW_DECL_LOG @@ -1255,7 +1505,9 @@ _GL_FUNCDECL_SYS (logl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (logl, long double, (long double x)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (logl); +# endif #elif defined GNULIB_POSIXCHECK # undef logl # if HAVE_RAW_DECL_LOGL @@ -1300,7 +1552,9 @@ _GL_CXXALIAS_RPL (log10, double, (double x)); # else _GL_CXXALIAS_SYS (log10, double, (double x)); # endif -_GL_CXXALIASWARN (log10); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (log10, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef log10 # if HAVE_RAW_DECL_LOG10 @@ -1324,7 +1578,9 @@ _GL_FUNCDECL_SYS (log10l, long double, (long double x)); # endif _GL_CXXALIAS_SYS (log10l, long double, (long double x)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (log10l); +# endif #elif defined GNULIB_POSIXCHECK # undef log10l # if HAVE_RAW_DECL_LOG10L @@ -1371,7 +1627,9 @@ _GL_FUNCDECL_SYS (log1p, double, (double x)); # endif _GL_CXXALIAS_SYS (log1p, double, (double x)); # endif -_GL_CXXALIASWARN (log1p); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (log1p, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef log1p # if HAVE_RAW_DECL_LOG1P @@ -1443,7 +1701,9 @@ _GL_FUNCDECL_SYS (log2, double, (double x)); # endif _GL_CXXALIAS_SYS (log2, double, (double x)); # endif -_GL_CXXALIASWARN (log2); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (log2, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef log2 # if HAVE_RAW_DECL_LOG2 @@ -1513,7 +1773,9 @@ _GL_FUNCDECL_SYS (logb, double, (double x)); # endif _GL_CXXALIAS_SYS (logb, double, (double x)); # endif -_GL_CXXALIASWARN (logb); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (logb, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef logb # if HAVE_RAW_DECL_LOGB @@ -1581,7 +1843,9 @@ _GL_CXXALIAS_RPL (modf, double, (double x, double *iptr)); # else _GL_CXXALIAS_SYS (modf, double, (double x, double *iptr)); # endif -_GL_CXXALIASWARN (modf); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (modf, double, (double x, double *iptr)); +# endif #elif defined GNULIB_POSIXCHECK # undef modf # if HAVE_RAW_DECL_MODF @@ -1607,7 +1871,9 @@ _GL_FUNCDECL_SYS (modfl, long double, (long double x, long double *iptr) # endif _GL_CXXALIAS_SYS (modfl, long double, (long double x, long double *iptr)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (modfl); +# endif #elif defined GNULIB_POSIXCHECK # undef modfl # if HAVE_RAW_DECL_MODFL @@ -1670,7 +1936,9 @@ _GL_FUNCDECL_SYS (remainder, double, (double x, double y)); # endif _GL_CXXALIAS_SYS (remainder, double, (double x, double y)); # endif -_GL_CXXALIASWARN (remainder); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (remainder, double, (double x, double y)); +# endif #elif defined GNULIB_POSIXCHECK # undef remainder # if HAVE_RAW_DECL_REMAINDER @@ -1690,7 +1958,9 @@ _GL_CXXALIAS_RPL (remainderl, long double, (long double x, long double y)); # else # if !@HAVE_DECL_REMAINDERL@ # undef remainderl +# if !(defined __cplusplus && defined _AIX) _GL_FUNCDECL_SYS (remainderl, long double, (long double x, long double y)); +# endif # endif _GL_CXXALIAS_SYS (remainderl, long double, (long double x, long double y)); # endif @@ -1723,7 +1993,9 @@ _GL_WARN_ON_USE (rintf, "rintf is unportable - " _GL_FUNCDECL_SYS (rint, double, (double x)); # endif _GL_CXXALIAS_SYS (rint, double, (double x)); -_GL_CXXALIASWARN (rint); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (rint, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef rint # if HAVE_RAW_DECL_RINT @@ -1733,10 +2005,19 @@ _GL_WARN_ON_USE (rint, "rint is unportable - " #endif #if @GNULIB_RINTL@ -# if !@HAVE_RINTL@ +# if @REPLACE_RINTL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef rintl +# define rintl rpl_rintl +# endif +_GL_FUNCDECL_RPL (rintl, long double, (long double x)); +_GL_CXXALIAS_RPL (rintl, long double, (long double x)); +# else +# if !@HAVE_RINTL@ _GL_FUNCDECL_SYS (rintl, long double, (long double x)); -# endif +# endif _GL_CXXALIAS_SYS (rintl, long double, (long double x)); +# endif _GL_CXXALIASWARN (rintl); #elif defined GNULIB_POSIXCHECK # undef rintl @@ -1784,7 +2065,9 @@ _GL_FUNCDECL_SYS (round, double, (double x)); # endif _GL_CXXALIAS_SYS (round, double, (double x)); # endif -_GL_CXXALIASWARN (round); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (round, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef round # if HAVE_RAW_DECL_ROUND @@ -1804,7 +2087,9 @@ _GL_CXXALIAS_RPL (roundl, long double, (long double x)); # else # if !@HAVE_DECL_ROUNDL@ # undef roundl +# if !(defined __cplusplus && defined _AIX) _GL_FUNCDECL_SYS (roundl, long double, (long double x)); +# endif # endif _GL_CXXALIAS_SYS (roundl, long double, (long double x)); # endif @@ -1819,11 +2104,20 @@ _GL_WARN_ON_USE (roundl, "roundl is unportable - " #if @GNULIB_SINF@ -# if !@HAVE_SINF@ -# undef sinf +# if @REPLACE_SINF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef sinf +# define sinf rpl_sinf +# endif +_GL_FUNCDECL_RPL (sinf, float, (float x)); +_GL_CXXALIAS_RPL (sinf, float, (float x)); +# else +# if !@HAVE_SINF@ +# undef sinf _GL_FUNCDECL_SYS (sinf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (sinf, float, (float x)); +# endif _GL_CXXALIASWARN (sinf); #elif defined GNULIB_POSIXCHECK # undef sinf @@ -1839,7 +2133,9 @@ _GL_WARN_ON_USE (sinf, "sinf is unportable - " _GL_FUNCDECL_SYS (sinl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (sinl, long double, (long double x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (sinl); +# endif #elif defined GNULIB_POSIXCHECK # undef sinl # if HAVE_RAW_DECL_SINL @@ -1850,11 +2146,20 @@ _GL_WARN_ON_USE (sinl, "sinl is unportable - " #if @GNULIB_SINHF@ -# if !@HAVE_SINHF@ -# undef sinhf +# if @REPLACE_SINHF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef sinhf +# define sinhf rpl_sinhf +# endif +_GL_FUNCDECL_RPL (sinhf, float, (float x)); +_GL_CXXALIAS_RPL (sinhf, float, (float x)); +# else +# if !@HAVE_SINHF@ +# undef sinhf _GL_FUNCDECL_SYS (sinhf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (sinhf, float, (float x)); +# endif _GL_CXXALIASWARN (sinhf); #elif defined GNULIB_POSIXCHECK # undef sinhf @@ -1866,11 +2171,20 @@ _GL_WARN_ON_USE (sinhf, "sinhf is unportable - " #if @GNULIB_SQRTF@ -# if !@HAVE_SQRTF@ -# undef sqrtf +# if @REPLACE_SQRTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef sqrtf +# define sqrtf rpl_sqrtf +# endif +_GL_FUNCDECL_RPL (sqrtf, float, (float x)); +_GL_CXXALIAS_RPL (sqrtf, float, (float x)); +# else +# if !@HAVE_SQRTF@ +# undef sqrtf _GL_FUNCDECL_SYS (sqrtf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (sqrtf, float, (float x)); +# endif _GL_CXXALIASWARN (sqrtf); #elif defined GNULIB_POSIXCHECK # undef sqrtf @@ -1895,7 +2209,9 @@ _GL_FUNCDECL_SYS (sqrtl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (sqrtl, long double, (long double x)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (sqrtl); +# endif #elif defined GNULIB_POSIXCHECK # undef sqrtl # if HAVE_RAW_DECL_SQRTL @@ -1906,11 +2222,20 @@ _GL_WARN_ON_USE (sqrtl, "sqrtl is unportable - " #if @GNULIB_TANF@ -# if !@HAVE_TANF@ -# undef tanf +# if @REPLACE_TANF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tanf +# define tanf rpl_tanf +# endif +_GL_FUNCDECL_RPL (tanf, float, (float x)); +_GL_CXXALIAS_RPL (tanf, float, (float x)); +# else +# if !@HAVE_TANF@ +# undef tanf _GL_FUNCDECL_SYS (tanf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (tanf, float, (float x)); +# endif _GL_CXXALIASWARN (tanf); #elif defined GNULIB_POSIXCHECK # undef tanf @@ -1926,7 +2251,9 @@ _GL_WARN_ON_USE (tanf, "tanf is unportable - " _GL_FUNCDECL_SYS (tanl, long double, (long double x)); # endif _GL_CXXALIAS_SYS (tanl, long double, (long double x)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (tanl); +# endif #elif defined GNULIB_POSIXCHECK # undef tanl # if HAVE_RAW_DECL_TANL @@ -1937,11 +2264,20 @@ _GL_WARN_ON_USE (tanl, "tanl is unportable - " #if @GNULIB_TANHF@ -# if !@HAVE_TANHF@ -# undef tanhf +# if @REPLACE_TANHF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tanhf +# define tanhf rpl_tanhf +# endif +_GL_FUNCDECL_RPL (tanhf, float, (float x)); +_GL_CXXALIAS_RPL (tanhf, float, (float x)); +# else +# if !@HAVE_TANHF@ +# undef tanhf _GL_FUNCDECL_SYS (tanhf, float, (float x)); -# endif +# endif _GL_CXXALIAS_SYS (tanhf, float, (float x)); +# endif _GL_CXXALIASWARN (tanhf); #elif defined GNULIB_POSIXCHECK # undef tanhf @@ -1955,6 +2291,7 @@ _GL_WARN_ON_USE (tanhf, "tanhf is unportable - " #if @GNULIB_TRUNCF@ # if @REPLACE_TRUNCF@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef truncf # define truncf rpl_truncf # endif _GL_FUNCDECL_RPL (truncf, float, (float x)); @@ -1977,6 +2314,7 @@ _GL_WARN_ON_USE (truncf, "truncf is unportable - " #if @GNULIB_TRUNC@ # if @REPLACE_TRUNC@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef trunc # define trunc rpl_trunc # endif _GL_FUNCDECL_RPL (trunc, double, (double x)); @@ -1987,7 +2325,9 @@ _GL_FUNCDECL_SYS (trunc, double, (double x)); # endif _GL_CXXALIAS_SYS (trunc, double, (double x)); # endif -_GL_CXXALIASWARN (trunc); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN1 (trunc, double, (double x)); +# endif #elif defined GNULIB_POSIXCHECK # undef trunc # if HAVE_RAW_DECL_TRUNC @@ -2020,6 +2360,55 @@ _GL_WARN_ON_USE (truncl, "truncl is unportable - " #endif +#if @GNULIB_MDA_Y0@ +/* On native Windows, map 'y0' to '_y0', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::y0 always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef y0 +# define y0 _y0 +# endif +_GL_CXXALIAS_MDA (y0, double, (double x)); +# else +_GL_CXXALIAS_SYS (y0, double, (double x)); +# endif +_GL_CXXALIASWARN (y0); +#endif + +#if @GNULIB_MDA_Y1@ +/* On native Windows, map 'y1' to '_y1', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::y1 always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef y1 +# define y1 _y1 +# endif +_GL_CXXALIAS_MDA (y1, double, (double x)); +# else +_GL_CXXALIAS_SYS (y1, double, (double x)); +# endif +_GL_CXXALIASWARN (y1); +#endif + +#if @GNULIB_MDA_YN@ +/* On native Windows, map 'yn' to '_yn', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::yn always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef yn +# define yn _yn +# endif +_GL_CXXALIAS_MDA (yn, double, (int n, double x)); +# else +_GL_CXXALIAS_SYS (yn, double, (int n, double x)); +# endif +_GL_CXXALIASWARN (yn); +#endif + + /* Definitions of function-like macros come here, after the function declarations. */ @@ -2036,10 +2425,18 @@ _GL_EXTERN_C int gl_isfinitel (long double x); gl_isfinitef (x)) # endif # ifdef __cplusplus -# ifdef isfinite +# if defined isfinite || defined GNULIB_NAMESPACE _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite) # undef isfinite -_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite) +# if __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined _AIX || (defined _WIN32 && !defined __CYGWIN__))) + /* This platform's possibly defines isfinite through a set of inline + functions. */ +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, rpl_isfinite, bool) +# define isfinite rpl_isfinite +# define GNULIB_NAMESPACE_LACKS_ISFINITE 1 +# else +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, isfinite, bool) +# endif # endif # endif #elif defined GNULIB_POSIXCHECK @@ -2063,10 +2460,18 @@ _GL_EXTERN_C int gl_isinfl (long double x); gl_isinff (x)) # endif # ifdef __cplusplus -# ifdef isinf +# if defined isinf || defined GNULIB_NAMESPACE _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isinf) # undef isinf -_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf) +# if __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || (defined _WIN32 && !defined __CYGWIN__))) + /* This platform's possibly defines isinf through a set of inline + functions. */ +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf, rpl_isinf, bool) +# define isinf rpl_isinf +# define GNULIB_NAMESPACE_LACKS_ISINF 1 +# else +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf, isinf, bool) +# endif # endif # endif #elif defined GNULIB_POSIXCHECK @@ -2083,10 +2488,11 @@ _GL_WARN_REAL_FLOATING_DECL (isinf); # if @HAVE_ISNANF@ /* The original included above provides a declaration of isnan macro or (older) isnanf function. */ -# if __GNUC__ >= 4 - /* GCC 4.0 and newer provides three built-ins for isnan. */ +# if (__GNUC__ >= 4) || (__clang_major__ >= 4) + /* GCC >= 4.0 and clang provide a type-generic built-in for isnan. + GCC >= 4.0 also provides __builtin_isnanf, but clang doesn't. */ # undef isnanf -# define isnanf(x) __builtin_isnanf ((float)(x)) +# define isnanf(x) __builtin_isnan ((float)(x)) # elif defined isnan # undef isnanf # define isnanf(x) isnan ((float)(x)) @@ -2106,8 +2512,8 @@ _GL_EXTERN_C int isnanf (float x); # if @HAVE_ISNAND@ /* The original included above provides a declaration of isnan macro. */ -# if __GNUC__ >= 4 - /* GCC 4.0 and newer provides three built-ins for isnan. */ +# if (__GNUC__ >= 4) || (__clang_major__ >= 4) + /* GCC >= 4.0 and clang provide a type-generic built-in for isnan. */ # undef isnand # define isnand(x) __builtin_isnan ((double)(x)) # else @@ -2127,10 +2533,11 @@ _GL_EXTERN_C int isnand (double x); # if @HAVE_ISNANL@ /* The original included above provides a declaration of isnan macro or (older) isnanl function. */ -# if __GNUC__ >= 4 - /* GCC 4.0 and newer provides three built-ins for isnan. */ +# if (__GNUC__ >= 4) || (__clang_major__ >= 4) + /* GCC >= 4.0 and clang provide a type-generic built-in for isnan. + GCC >= 4.0 also provides __builtin_isnanl, but clang doesn't. */ # undef isnanl -# define isnanl(x) __builtin_isnanl ((long double)(x)) +# define isnanl(x) __builtin_isnan ((long double)(x)) # elif defined isnan # undef isnanl # define isnanl(x) isnan ((long double)(x)) @@ -2150,20 +2557,20 @@ _GL_EXTERN_C int isnanl (long double x) _GL_ATTRIBUTE_CONST; isnanf.h (e.g.) here, because those may end up being macros that recursively expand back to isnan. So use the gnulib replacements for them directly. */ -# if @HAVE_ISNANF@ && __GNUC__ >= 4 -# define gl_isnan_f(x) __builtin_isnanf ((float)(x)) +# if @HAVE_ISNANF@ && (__GNUC__ >= 4) || (__clang_major__ >= 4) +# define gl_isnan_f(x) __builtin_isnan ((float)(x)) # else _GL_EXTERN_C int rpl_isnanf (float x); # define gl_isnan_f(x) rpl_isnanf (x) # endif -# if @HAVE_ISNAND@ && __GNUC__ >= 4 +# if @HAVE_ISNAND@ && (__GNUC__ >= 4) || (__clang_major__ >= 4) # define gl_isnan_d(x) __builtin_isnan ((double)(x)) # else _GL_EXTERN_C int rpl_isnand (double x); # define gl_isnan_d(x) rpl_isnand (x) # endif -# if @HAVE_ISNANL@ && __GNUC__ >= 4 -# define gl_isnan_l(x) __builtin_isnanl ((long double)(x)) +# if @HAVE_ISNANL@ && (__GNUC__ >= 4) || (__clang_major__ >= 4) +# define gl_isnan_l(x) __builtin_isnan ((long double)(x)) # else _GL_EXTERN_C int rpl_isnanl (long double x) _GL_ATTRIBUTE_CONST; # define gl_isnan_l(x) rpl_isnanl (x) @@ -2173,18 +2580,26 @@ _GL_EXTERN_C int rpl_isnanl (long double x) _GL_ATTRIBUTE_CONST; (sizeof (x) == sizeof (long double) ? gl_isnan_l (x) : \ sizeof (x) == sizeof (double) ? gl_isnan_d (x) : \ gl_isnan_f (x)) -# elif __GNUC__ >= 4 +# elif (__GNUC__ >= 4) || (__clang_major__ >= 4) # undef isnan # define isnan(x) \ - (sizeof (x) == sizeof (long double) ? __builtin_isnanl ((long double)(x)) : \ + (sizeof (x) == sizeof (long double) ? __builtin_isnan ((long double)(x)) : \ sizeof (x) == sizeof (double) ? __builtin_isnan ((double)(x)) : \ - __builtin_isnanf ((float)(x))) + __builtin_isnan ((float)(x))) # endif # ifdef __cplusplus -# ifdef isnan +# if defined isnan || defined GNULIB_NAMESPACE _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isnan) # undef isnan -_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan) +# if __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__ && __clang_major__ < 12) || (defined __FreeBSD__ && __clang_major__ < 7) || defined __OpenBSD__ || (defined _WIN32 && !defined __CYGWIN__))) + /* This platform's possibly defines isnan through a set of inline + functions. */ +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, rpl_isnan, bool) +# define isnan rpl_isnan +# define GNULIB_NAMESPACE_LACKS_ISNAN 1 +# else +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, isnan, bool) +# endif # endif # else /* Ensure isnan is a macro. */ @@ -2202,20 +2617,21 @@ _GL_WARN_REAL_FLOATING_DECL (isnan); #if @GNULIB_SIGNBIT@ -# if @REPLACE_SIGNBIT_USING_GCC@ +# if (@REPLACE_SIGNBIT_USING_BUILTINS@ \ + && (!defined __cplusplus || __cplusplus < 201103)) # undef signbit - /* GCC 4.0 and newer provides three built-ins for signbit. */ + /* GCC >= 4.0 and clang provide three built-ins for signbit. */ # define signbit(x) \ (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \ sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \ __builtin_signbitf (x)) # endif -# if @REPLACE_SIGNBIT@ +# if @REPLACE_SIGNBIT@ && !GNULIB_defined_signbit # undef signbit _GL_EXTERN_C int gl_signbitf (float arg); _GL_EXTERN_C int gl_signbitd (double arg); _GL_EXTERN_C int gl_signbitl (long double arg); -# if __GNUC__ >= 2 && !defined __STRICT_ANSI__ +# if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__ # define _GL_NUM_UINT_WORDS(type) \ ((sizeof (type) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) # if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT && !defined gl_signbitf @@ -2253,12 +2669,21 @@ _GL_EXTERN_C int gl_signbitl (long double arg); (sizeof (x) == sizeof (long double) ? gl_signbitl (x) : \ sizeof (x) == sizeof (double) ? gl_signbitd (x) : \ gl_signbitf (x)) +# define GNULIB_defined_signbit 1 # endif # ifdef __cplusplus -# ifdef signbit +# if defined signbit || defined GNULIB_NAMESPACE _GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit) # undef signbit -_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit) +# if __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined _AIX || (defined _WIN32 && !defined __CYGWIN__))) + /* This platform's possibly defines signbit through a set of inline + functions. */ +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, rpl_signbit, bool) +# define signbit rpl_signbit +# define GNULIB_NAMESPACE_LACKS_SIGNBIT 1 +# else +_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, signbit, bool) +# endif # endif # endif #elif defined GNULIB_POSIXCHECK @@ -2272,4 +2697,5 @@ _GL_WARN_REAL_FLOATING_DECL (signbit); _GL_INLINE_HEADER_END #endif /* _@GUARD_PREFIX@_MATH_H */ +#endif /* _GL_INCLUDING_MATH_H */ #endif /* _@GUARD_PREFIX@_MATH_H */ diff --git a/gl/mbrtowc-impl-utf8.h b/gl/mbrtowc-impl-utf8.h new file mode 100644 index 00000000..8e5ac14e --- /dev/null +++ b/gl/mbrtowc-impl-utf8.h @@ -0,0 +1,138 @@ +/* Convert multibyte character to wide character. + Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2008. */ + +/* This file contains the part of the body of the mbrtowc and mbrtoc32 functions + that handles the special case of the UTF-8 encoding. */ + + /* Cf. unistr/u8-mbtouc.c. */ + unsigned char c = (unsigned char) p[0]; + + if (c < 0x80) + { + if (pwc != NULL) + *pwc = c; + res = (c == 0 ? 0 : 1); + goto success; + } + if (c >= 0xc2) + { + if (c < 0xe0) + { + if (m == 1) + goto incomplete; + else /* m >= 2 */ + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (c2 ^ 0x80); + res = 2; + goto success; + } + } + } + else if (c < 0xf0) + { + if (m == 1) + goto incomplete; + else + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + { + if (m == 2) + goto incomplete; + else /* m >= 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if ((c3 ^ 0x80) < 0x40) + { + unsigned int wc = + (((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (c2 ^ 0x80) << 6) + | (unsigned int) (c3 ^ 0x80)); + + if (FITS_IN_CHAR_TYPE (wc)) + { + if (pwc != NULL) + *pwc = wc; + res = 3; + goto success; + } + } + } + } + } + } + else if (c <= 0xf4) + { + if (m == 1) + goto incomplete; + else + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (/* c == 0xf4 && */ c2 < 0x90))) + { + if (m == 2) + goto incomplete; + else + { + unsigned char c3 = (unsigned char) p[2]; + + if ((c3 ^ 0x80) < 0x40) + { + if (m == 3) + goto incomplete; + else /* m >= 4 */ + { + unsigned char c4 = (unsigned char) p[3]; + + if ((c4 ^ 0x80) < 0x40) + { + unsigned int wc = + (((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (c2 ^ 0x80) << 12) + | ((unsigned int) (c3 ^ 0x80) << 6) + | (unsigned int) (c4 ^ 0x80)); + + if (FITS_IN_CHAR_TYPE (wc)) + { + if (pwc != NULL) + *pwc = wc; + res = 4; + goto success; + } + } + } + } + } + } + } + } + } + goto invalid; diff --git a/gl/mbrtowc-impl.h b/gl/mbrtowc-impl.h new file mode 100644 index 00000000..65538e74 --- /dev/null +++ b/gl/mbrtowc-impl.h @@ -0,0 +1,262 @@ +/* Convert multibyte character to wide character. + Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2008. */ + +/* This file contains the body of the mbrtowc and mbrtoc32 functions, + when GNULIB_defined_mbstate_t is defined. */ + + char *pstate = (char *)ps; + + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } + + if (n == 0) + return (size_t)(-2); + + /* Here n > 0. */ + + if (pstate == NULL) + pstate = internal_state; + + { + size_t nstate = pstate[0]; + char buf[4]; + const char *p; + size_t m; + enc_t enc; + int res; + + switch (nstate) + { + case 0: + p = s; + m = n; + break; + case 3: + buf[2] = pstate[3]; + FALLTHROUGH; + case 2: + buf[1] = pstate[2]; + FALLTHROUGH; + case 1: + buf[0] = pstate[1]; + p = buf; + m = nstate; + buf[m++] = s[0]; + if (n >= 2 && m < 4) + { + buf[m++] = s[1]; + if (n >= 3 && m < 4) + buf[m++] = s[2]; + } + break; + default: + errno = EINVAL; + return (size_t)(-1); + } + + /* Here m > 0. */ + + enc = locale_encoding_classification (); + + if (enc == enc_utf8) /* UTF-8 */ + { + /* Achieve + - multi-thread safety and + - the ability to produce wide character values > WCHAR_MAX + by not calling mbtowc() at all. */ +#include "mbrtowc-impl-utf8.h" + } + else + { + /* The hidden internal state of mbtowc would make this function not + multi-thread safe. Achieve multi-thread safety through a lock. */ + wchar_t wc; + res = mbtowc_with_lock (&wc, p, m); + + if (res >= 0) + { + if ((wc == 0) != (res == 0)) + abort (); + if (pwc != NULL) + *pwc = wc; + goto success; + } + + /* mbtowc does not distinguish between invalid and incomplete multibyte + sequences. But mbrtowc needs to make this distinction. + There are two possible approaches: + - Use iconv() and its return value. + - Use built-in knowledge about the possible encodings. + Given the low quality of implementation of iconv() on the systems + that lack mbrtowc(), we use the second approach. + The possible encodings are: + - 8-bit encodings, + - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, + - UTF-8 (already handled above). + Use specialized code for each. */ + if (m >= 4 || m >= MB_CUR_MAX) + goto invalid; + /* Here MB_CUR_MAX > 1 and 0 < m < 4. */ + switch (enc) + { + /* As a reference for this code, you can use the GNU libiconv + implementation. Look for uses of the RET_TOOFEW macro. */ + + case enc_eucjp: /* EUC-JP */ + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f) + goto incomplete; + } + if (m == 2) + { + unsigned char c = (unsigned char) p[0]; + + if (c == 0x8f) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0xa1 && c2 < 0xff) + goto incomplete; + } + } + goto invalid; + } + + case enc_94: /* EUC-KR, GB2312, BIG5 */ + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0xa1 && c < 0xff) + goto incomplete; + } + goto invalid; + } + + case enc_euctw: /* EUC-TW */ + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0xa1 && c < 0xff) || c == 0x8e) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c == 0x8e) + goto incomplete; + } + goto invalid; + } + + case enc_gb18030: /* GB18030 */ + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0x90 && c <= 0xe3) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0x30 && c2 <= 0x39) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if (c3 >= 0x81 && c3 <= 0xfe) + goto incomplete; + } + } + } + } + goto invalid; + } + + case enc_sjis: /* SJIS */ + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea) + || (c >= 0xf0 && c <= 0xf9)) + goto incomplete; + } + goto invalid; + } + + default: + /* An unknown multibyte encoding. */ + goto incomplete; + } + } + + success: + /* res >= 0 is the corrected return value of + mbtowc_with_lock (&wc, p, m). */ + if (nstate >= (res > 0 ? res : 1)) + abort (); + res -= nstate; + pstate[0] = 0; + return res; + + incomplete: + { + size_t k = nstate; + /* Here 0 <= k < m < 4. */ + pstate[++k] = s[0]; + if (k < m) + { + pstate[++k] = s[1]; + if (k < m) + pstate[++k] = s[2]; + } + if (k != m) + abort (); + } + pstate[0] = m; + return (size_t)(-2); + + invalid: + errno = EILSEQ; + /* The conversion state is undefined, says POSIX. */ + return (size_t)(-1); + } diff --git a/gl/mbrtowc.c b/gl/mbrtowc.c index 5ee44aea..4b164edd 100644 --- a/gl/mbrtowc.c +++ b/gl/mbrtowc.c @@ -1,19 +1,19 @@ /* Convert multibyte character to wide character. - Copyright (C) 1999-2002, 2005-2013 Free Software Foundation, Inc. + Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2008. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -21,314 +21,67 @@ #include #if GNULIB_defined_mbstate_t -/* Implement mbrtowc() on top of mbtowc(). */ +/* Implement mbrtowc() on top of mbtowc() for the non-UTF-8 locales + and directly for the UTF-8 locales. */ # include +# include # include -# include "localcharset.h" -# include "streq.h" -# include "verify.h" - - -verify (sizeof (mbstate_t) >= 4); - -static char internal_state[4]; - -size_t -mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) -{ - char *pstate = (char *)ps; - - if (s == NULL) - { - pwc = NULL; - s = ""; - n = 1; - } +# if defined _WIN32 && !defined __CYGWIN__ - if (n == 0) - return (size_t)(-2); +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include - /* Here n > 0. */ +# elif HAVE_PTHREAD_API - if (pstate == NULL) - pstate = internal_state; +# include +# if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS +# include +# pragma weak thrd_exit +# define c11_threads_in_use() (thrd_exit != NULL) +# else +# define c11_threads_in_use() 0 +# endif - { - size_t nstate = pstate[0]; - char buf[4]; - const char *p; - size_t m; +# elif HAVE_THREADS_H - switch (nstate) - { - case 0: - p = s; - m = n; - break; - case 3: - buf[2] = pstate[3]; - /*FALLTHROUGH*/ - case 2: - buf[1] = pstate[2]; - /*FALLTHROUGH*/ - case 1: - buf[0] = pstate[1]; - p = buf; - m = nstate; - buf[m++] = s[0]; - if (n >= 2 && m < 4) - { - buf[m++] = s[1]; - if (n >= 3 && m < 4) - buf[m++] = s[2]; - } - break; - default: - errno = EINVAL; - return (size_t)(-1); - } +# include - /* Here m > 0. */ - -# if __GLIBC__ || defined __UCLIBC__ - /* Work around bug */ - mbtowc (NULL, NULL, 0); # endif - { - int res = mbtowc (pwc, p, m); - - if (res >= 0) - { - if (pwc != NULL && ((*pwc == 0) != (res == 0))) - abort (); - if (nstate >= (res > 0 ? res : 1)) - abort (); - res -= nstate; - pstate[0] = 0; - return res; - } - - /* mbtowc does not distinguish between invalid and incomplete multibyte - sequences. But mbrtowc needs to make this distinction. - There are two possible approaches: - - Use iconv() and its return value. - - Use built-in knowledge about the possible encodings. - Given the low quality of implementation of iconv() on the systems that - lack mbrtowc(), we use the second approach. - The possible encodings are: - - 8-bit encodings, - - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, - - UTF-8. - Use specialized code for each. */ - if (m >= 4 || m >= MB_CUR_MAX) - goto invalid; - /* Here MB_CUR_MAX > 1 and 0 < m < 4. */ - { - const char *encoding = locale_charset (); - - if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) - { - /* Cf. unistr/u8-mblen.c. */ - unsigned char c = (unsigned char) p[0]; - - if (c >= 0xc2) - { - if (c < 0xe0) - { - if (m == 1) - goto incomplete; - } - else if (c < 0xf0) - { - if (m == 1) - goto incomplete; - if (m == 2) - { - unsigned char c2 = (unsigned char) p[1]; - - if ((c2 ^ 0x80) < 0x40 - && (c >= 0xe1 || c2 >= 0xa0) - && (c != 0xed || c2 < 0xa0)) - goto incomplete; - } - } - else if (c <= 0xf4) - { - if (m == 1) - goto incomplete; - else /* m == 2 || m == 3 */ - { - unsigned char c2 = (unsigned char) p[1]; - - if ((c2 ^ 0x80) < 0x40 - && (c >= 0xf1 || c2 >= 0x90) - && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) - { - if (m == 2) - goto incomplete; - else /* m == 3 */ - { - unsigned char c3 = (unsigned char) p[2]; - - if ((c3 ^ 0x80) < 0x40) - goto incomplete; - } - } - } - } - } - goto invalid; - } - - /* As a reference for this code, you can use the GNU libiconv - implementation. Look for uses of the RET_TOOFEW macro. */ - - if (STREQ_OPT (encoding, - "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f) - goto incomplete; - } - if (m == 2) - { - unsigned char c = (unsigned char) p[0]; - - if (c == 0x8f) - { - unsigned char c2 = (unsigned char) p[1]; - - if (c2 >= 0xa1 && c2 < 0xff) - goto incomplete; - } - } - goto invalid; - } - if (STREQ_OPT (encoding, - "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) - || STREQ_OPT (encoding, - "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) - || STREQ_OPT (encoding, - "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if (c >= 0xa1 && c < 0xff) - goto incomplete; - } - goto invalid; - } - if (STREQ_OPT (encoding, - "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0xa1 && c < 0xff) || c == 0x8e) - goto incomplete; - } - else /* m == 2 || m == 3 */ - { - unsigned char c = (unsigned char) p[0]; - - if (c == 0x8e) - goto incomplete; - } - goto invalid; - } - if (STREQ_OPT (encoding, - "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) - goto incomplete; - } - else /* m == 2 || m == 3 */ - { - unsigned char c = (unsigned char) p[0]; - - if (c >= 0x90 && c <= 0xe3) - { - unsigned char c2 = (unsigned char) p[1]; - - if (c2 >= 0x30 && c2 <= 0x39) - { - if (m == 2) - goto incomplete; - else /* m == 3 */ - { - unsigned char c3 = (unsigned char) p[2]; - - if (c3 >= 0x81 && c3 <= 0xfe) - goto incomplete; - } - } - } - } - goto invalid; - } - if (STREQ_OPT (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea) - || (c >= 0xf0 && c <= 0xf9)) - goto incomplete; - } - goto invalid; - } - /* An unknown multibyte encoding. */ - goto incomplete; - } +# include "attribute.h" +# include "verify.h" +# include "lc-charset-dispatch.h" +# include "mbtowc-lock.h" - incomplete: - { - size_t k = nstate; - /* Here 0 <= k < m < 4. */ - pstate[++k] = s[0]; - if (k < m) - { - pstate[++k] = s[1]; - if (k < m) - pstate[++k] = s[2]; - } - if (k != m) - abort (); - } - pstate[0] = m; - return (size_t)(-2); +verify (sizeof (mbstate_t) >= 4); +static char internal_state[4]; - invalid: - errno = EILSEQ; - /* The conversion state is undefined, says POSIX. */ - return (size_t)(-1); - } - } +size_t +mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ +# define FITS_IN_CHAR_TYPE(wc) ((wc) <= WCHAR_MAX) +# include "mbrtowc-impl.h" } #else /* Override the system's mbrtowc() function. */ +# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ +# include "hard-locale.h" +# include +# endif + # undef mbrtowc size_t rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) { -# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG + size_t ret; + wchar_t wc; + +# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG if (s == NULL) { pwc = NULL; @@ -337,6 +90,14 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) } # endif +# if MBRTOWC_EMPTY_INPUT_BUG + if (n == 0) + return (size_t) -2; +# endif + + if (! pwc) + pwc = &wc; + # if MBRTOWC_RETVAL_BUG { static mbstate_t internal_state; @@ -352,8 +113,7 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) size_t count = 0; for (; n > 0; s++, n--) { - wchar_t wc; - size_t ret = mbrtowc (&wc, s, 1, ps); + ret = mbrtowc (&wc, s, 1, ps); if (ret == (size_t)(-1)) return (size_t)(-1); @@ -361,8 +121,7 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) if (ret != (size_t)(-2)) { /* The multibyte character has been completed. */ - if (pwc != NULL) - *pwc = wc; + *pwc = wc; return (wc == 0 ? 0 : count); } } @@ -371,32 +130,29 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) } # endif -# if MBRTOWC_NUL_RETVAL_BUG - { - wchar_t wc; - size_t ret = mbrtowc (&wc, s, n, ps); - - if (ret != (size_t)(-1) && ret != (size_t)(-2)) - { - if (pwc != NULL) - *pwc = wc; - if (wc == 0) - ret = 0; - } - return ret; - } +# if MBRTOWC_STORES_INCOMPLETE_BUG + ret = mbrtowc (&wc, s, n, ps); + if (ret < (size_t) -2 && pwc != NULL) + *pwc = wc; # else - { -# if MBRTOWC_NULL_ARG1_BUG - wchar_t dummy; + ret = mbrtowc (pwc, s, n, ps); +# endif - if (pwc == NULL) - pwc = &dummy; -# endif +# if MBRTOWC_NUL_RETVAL_BUG + if (ret < (size_t) -2 && !*pwc) + return 0; +# endif - return mbrtowc (pwc, s, n, ps); - } +# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ + if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE)) + { + unsigned char uc = *s; + *pwc = uc; + return 1; + } # endif + + return ret; } #endif diff --git a/gl/mbsinit.c b/gl/mbsinit.c index 26fbb7fa..9621defc 100644 --- a/gl/mbsinit.c +++ b/gl/mbsinit.c @@ -1,19 +1,19 @@ /* Test for initial conversion state. - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2008. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -22,17 +22,7 @@ #include "verify.h" -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - -/* On native Windows, 'mbstate_t' is defined as 'int'. */ - -int -mbsinit (const mbstate_t *ps) -{ - return ps == NULL || *ps == 0; -} - -#else +#if GNULIB_defined_mbstate_t /* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs() and wcrtomb(), wcsrtombs(). @@ -45,6 +35,7 @@ mbsinit (const mbstate_t *ps) We define the meaning of mbstate_t as follows: - In mb -> wc direction, mbstate_t's first byte contains the number of buffered bytes (in the range 0..3), followed by up to 3 buffered bytes. + See mbrtowc.c. - In wc -> mb direction, mbstate_t contains no information. In other words, it is always in the initial state. */ @@ -58,4 +49,22 @@ mbsinit (const mbstate_t *ps) return pstate == NULL || pstate[0] == 0; } +#else + +int +mbsinit (const mbstate_t *ps) +{ +# if defined _WIN32 && !defined __CYGWIN__ + /* Native Windows. */ + /* MSVC defines 'mbstate_t' as an 8-byte struct; the first 4 bytes matter. + On mingw, 'mbstate_t' is sometimes defined as 'int', sometimes defined as + an 8-byte struct, of which the first 4 bytes matter. */ + return ps == NULL || *(const unsigned int *)ps == 0; +# else + /* Minix, HP-UX 11.00, Solaris 2.6, Interix, ... */ + /* Maybe this definition works, maybe not... */ + return ps == NULL || *(const char *)ps == 0; +# endif +} + #endif diff --git a/gl/mbtowc-impl.h b/gl/mbtowc-impl.h index 767ab397..2b27bafd 100644 --- a/gl/mbtowc-impl.h +++ b/gl/mbtowc-impl.h @@ -1,19 +1,19 @@ /* Convert multibyte character to wide character. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2011. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* We don't need a static internal state, because the encoding is not state dependent, and when mbrtowc returns (size_t)(-2). we throw the result diff --git a/gl/mbtowc-lock.c b/gl/mbtowc-lock.c new file mode 100644 index 00000000..06d32246 --- /dev/null +++ b/gl/mbtowc-lock.c @@ -0,0 +1,150 @@ +/* Return the internal lock used by mbrtowc and mbrtoc32. + Copyright (C) 2019-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019-2020. */ + +#include + +/* When it is known that the gl_get_mbtowc_lock function is defined + by a dependency library, it should not be defined here. */ +#if OMIT_MBTOWC_LOCK + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#else + +/* This file defines the internal lock used by mbrtowc and mbrtoc32. + It is a separate compilation unit, so that only one copy of it is + present when linking statically. */ + +/* Prohibit renaming this symbol. */ +# undef gl_get_mbtowc_lock + +/* Macro for exporting a symbol (function, not variable) defined in this file, + when compiled into a shared library. */ +# ifndef DLL_EXPORTED +# if HAVE_VISIBILITY + /* Override the effect of the compiler option '-fvisibility=hidden'. */ +# define DLL_EXPORTED __attribute__((__visibility__("default"))) +# elif defined _WIN32 || defined __CYGWIN__ +# define DLL_EXPORTED __declspec(dllexport) +# else +# define DLL_EXPORTED +# endif +# endif + +# if defined _WIN32 && !defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# include "windows-initguard.h" + +/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *', + because the latter is not guaranteed to be a stable ABI in the future. */ + +/* Make sure the function gets exported from DLLs. */ +DLL_EXPORTED CRITICAL_SECTION *gl_get_mbtowc_lock (void); + +static glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT; +static CRITICAL_SECTION lock; + +/* Returns the internal lock used by mbrtowc and mbrtoc32. */ +CRITICAL_SECTION * +gl_get_mbtowc_lock (void) +{ + if (!guard.done) + { + if (InterlockedIncrement (&guard.started) == 0) + { + /* This thread is the first one to need the lock. Initialize it. */ + InitializeCriticalSection (&lock); + guard.done = 1; + } + else + { + /* Don't let guard.started grow and wrap around. */ + InterlockedDecrement (&guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!guard.done) + Sleep (0); + } + } + return &lock; +} + +# elif HAVE_PTHREAD_API + +# include + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Make sure the function gets exported from shared libraries. */ +DLL_EXPORTED pthread_mutex_t *gl_get_mbtowc_lock (void); + +/* Returns the internal lock used by mbrtowc and mbrtoc32. */ +pthread_mutex_t * +gl_get_mbtowc_lock (void) +{ + return &mutex; +} + +# elif HAVE_THREADS_H + +# include +# include + +static int volatile init_needed = 1; +static once_flag init_once = ONCE_FLAG_INIT; +static mtx_t mutex; + +static void +atomic_init (void) +{ + if (mtx_init (&mutex, mtx_plain) != thrd_success) + abort (); + init_needed = 0; +} + +/* Make sure the function gets exported from shared libraries. */ +DLL_EXPORTED mtx_t *gl_get_mbtowc_lock (void); + +/* Returns the internal lock used by mbrtowc and mbrtoc32. */ +mtx_t * +gl_get_mbtowc_lock (void) +{ + if (init_needed) + call_once (&init_once, atomic_init); + return &mutex; +} + +# endif + +# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER +/* Make sure the '__declspec(dllimport)' in mbrtowc.c and mbrtoc32.c does not + cause a link failure when no DLLs are involved. */ +# if defined _WIN64 || defined _LP64 +# define IMP(x) __imp_##x +# else +# define IMP(x) _imp__##x +# endif +void * IMP(gl_get_mbtowc_lock) = &gl_get_mbtowc_lock; +# endif + +#endif diff --git a/gl/mbtowc-lock.h b/gl/mbtowc-lock.h new file mode 100644 index 00000000..ecfd44e8 --- /dev/null +++ b/gl/mbtowc-lock.h @@ -0,0 +1,125 @@ +/* Use the internal lock used by mbrtowc and mbrtoc32. + Copyright (C) 2019-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019-2020. */ + +/* Use a lock, so that no two threads can invoke mbtowc at the same time. */ + +static inline int +mbtowc_unlocked (wchar_t *pwc, const char *p, size_t m) +{ + /* Put the hidden internal state of mbtowc into its initial state. + This is needed at least with glibc, uClibc, and MSVC CRT. + See . */ + mbtowc (NULL, NULL, 0); + + return mbtowc (pwc, p, m); +} + +/* Prohibit renaming this symbol. */ +#undef gl_get_mbtowc_lock + +#if GNULIB_MBRTOWC_SINGLE_THREAD + +/* All uses of this function are in a single thread. No locking needed. */ + +static int +mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m) +{ + return mbtowc_unlocked (pwc, p, m); +} + +#elif defined _WIN32 && !defined __CYGWIN__ + +extern __declspec(dllimport) CRITICAL_SECTION *gl_get_mbtowc_lock (void); + +static int +mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m) +{ + CRITICAL_SECTION *lock = gl_get_mbtowc_lock (); + int ret; + + EnterCriticalSection (lock); + ret = mbtowc_unlocked (pwc, p, m); + LeaveCriticalSection (lock); + + return ret; +} + +#elif HAVE_PTHREAD_API /* AIX, IRIX, Cygwin */ + +extern +# if defined _WIN32 || defined __CYGWIN__ + __declspec(dllimport) +# endif + pthread_mutex_t *gl_get_mbtowc_lock (void); + +# if HAVE_WEAK_SYMBOLS /* IRIX */ + + /* Avoid the need to link with '-lpthread'. */ +# pragma weak pthread_mutex_lock +# pragma weak pthread_mutex_unlock + + /* Determine whether libpthread is in use. */ +# pragma weak pthread_mutexattr_gettype + /* See the comments in lock.h. */ +# define pthread_in_use() \ + (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) + +# else +# define pthread_in_use() 1 +# endif + +static int +mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m) +{ + if (pthread_in_use()) + { + pthread_mutex_t *lock = gl_get_mbtowc_lock (); + int ret; + + if (pthread_mutex_lock (lock)) + abort (); + ret = mbtowc_unlocked (pwc, p, m); + if (pthread_mutex_unlock (lock)) + abort (); + + return ret; + } + else + return mbtowc_unlocked (pwc, p, m); +} + +#elif HAVE_THREADS_H + +extern mtx_t *gl_get_mbtowc_lock (void); + +static int +mbtowc_with_lock (wchar_t *pwc, const char *p, size_t m) +{ + mtx_t *lock = gl_get_mbtowc_lock (); + int ret; + + if (mtx_lock (lock) != thrd_success) + abort (); + ret = mbtowc_unlocked (pwc, p, m); + if (mtx_unlock (lock) != thrd_success) + abort (); + + return ret; +} + +#endif diff --git a/gl/mbtowc.c b/gl/mbtowc.c index 632f2e1d..a9a79951 100644 --- a/gl/mbtowc.c +++ b/gl/mbtowc.c @@ -1,19 +1,19 @@ /* Convert multibyte character to wide character. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2011. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/memchr.c b/gl/memchr.c index 3db38a94..0ca7b30a 100644 --- a/gl/memchr.c +++ b/gl/memchr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2013 +/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2022 Free Software Foundation, Inc. Based on strlen implementation by Torbjorn Granlund (tege@sics.se), @@ -7,21 +7,21 @@ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), and implemented by Roland McGrath (roland@ai.mit.edu). -NOTE: The canonical source of this file is maintained with the GNU C Library. -Bugs can be reported to bug-glibc@prep.ai.mit.edu. + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@prep.ai.mit.edu. -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 any -later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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. + This file 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 Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _LIBC # include diff --git a/gl/memchr.valgrind b/gl/memchr.valgrind index 60f247e1..cb0f351c 100644 --- a/gl/memchr.valgrind +++ b/gl/memchr.valgrind @@ -1,4 +1,20 @@ # Suppress a valgrind message about use of uninitialized memory in memchr(). + +# Copyright (C) 2009-2022 Free Software Foundation, Inc. +# +# This file is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# This file 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + # POSIX states that when the character is found, memchr must not read extra # bytes in an overestimated length (for example, where memchr is used to # implement strnlen). However, we use a safe word read to provide a speedup. diff --git a/gl/minmax.h b/gl/minmax.h new file mode 100644 index 00000000..b4b1345b --- /dev/null +++ b/gl/minmax.h @@ -0,0 +1,60 @@ +/* MIN, MAX macros. + Copyright (C) 1995, 1998, 2001, 2003, 2005, 2009-2022 Free Software + Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _MINMAX_H +#define _MINMAX_H + +/* Note: MIN, MAX are also defined in on some systems + (glibc, IRIX, HP-UX, OSF/1). Therefore you might get warnings about + MIN, MAX macro redefinitions on some systems; the workaround is to + #include this file as the last one among the #include list. */ + +/* Before we define the following symbols we get the file + since otherwise we get redefinitions on some systems if is + included after this file. Likewise for . + If more than one of these system headers define MIN and MAX, pick just + one of the headers (because the definitions most likely are the same). */ +#if HAVE_MINMAX_IN_LIMITS_H +# include +#elif HAVE_MINMAX_IN_SYS_PARAM_H +# include +#endif + +/* Note: MIN and MAX should be used with two arguments of the + same type. They might not return the minimum and maximum of their two + arguments, if the arguments have different types or have unusual + floating-point values. For example, on a typical host with 32-bit 'int', + 64-bit 'long long', and 64-bit IEEE 754 'double' types: + + MAX (-1, 2147483648) returns 4294967295. + MAX (9007199254740992.0, 9007199254740993) returns 9007199254740992.0. + MAX (NaN, 0.0) returns 0.0. + MAX (+0.0, -0.0) returns -0.0. + + and in each case the answer is in some sense bogus. */ + +/* MAX(a,b) returns the maximum of A and B. */ +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/* MIN(a,b) returns the minimum of A and B. */ +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#endif /* _MINMAX_H */ diff --git a/gl/mktime-internal.h b/gl/mktime-internal.h index 4287acf4..170764ea 100644 --- a/gl/mktime-internal.h +++ b/gl/mktime-internal.h @@ -1,4 +1,79 @@ -#include -time_t mktime_internal (struct tm *, - struct tm * (*) (time_t const *, struct tm *), - time_t *); +/* Internals of mktime and related functions + Copyright 2016-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Eggert . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _LIBC +# include +#endif + +/* mktime_offset_t is a signed type wide enough to hold a UTC offset + in seconds, and used as part of the type of the offset-guess + argument to mktime_internal. In Glibc, it is always long int. + When in Gnulib, use time_t on platforms where time_t + is signed, to be compatible with platforms like BeOS that export + this implementation detail of mktime. On platforms where time_t is + unsigned, GNU and POSIX code can assume 'int' is at least 32 bits + which is wide enough for a UTC offset. */ +#ifdef _LIBC +typedef long int mktime_offset_t; +#elif defined TIME_T_IS_SIGNED +typedef time_t mktime_offset_t; +#else +typedef int mktime_offset_t; +#endif + +/* The source code uses identifiers like __time64_t for glibc + timestamps that can contain 64-bit values even when time_t is only + 32 bits. These are just macros for the ordinary identifiers unless + compiling within glibc when time_t is 32 bits. */ +#if ! (defined _LIBC && __TIMESIZE != 64) +# undef __time64_t +# define __time64_t time_t +# define __gmtime64_r __gmtime_r +# define __localtime64_r __localtime_r +# define __mktime64 mktime +# define __timegm64 timegm +#endif + +#ifndef _LIBC + +/* Although glibc source code uses leading underscores, Gnulib wants + ordinary names. + + Portable standalone applications should supply a that + declares a POSIX-compliant localtime_r, for the benefit of older + implementations that lack localtime_r or have a nonstandard one. + Similarly for gmtime_r. See the gnulib time_r module for one way + to implement this. */ + +# undef __gmtime_r +# undef __localtime_r +# define __gmtime_r gmtime_r +# define __localtime_r localtime_r + +# define __mktime_internal mktime_internal + +#endif + +/* Subroutine of mktime. Return the time_t representation of TP and + normalize TP, given that a struct tm * maps to a time_t as performed + by FUNC. Record next guess for localtime-gmtime offset in *OFFSET. */ +extern __time64_t __mktime_internal (struct tm *tp, + struct tm *(*func) (__time64_t const *, + struct tm *), + mktime_offset_t *offset) attribute_hidden; diff --git a/gl/mktime.c b/gl/mktime.c index e660a23c..7dc9d67e 100644 --- a/gl/mktime.c +++ b/gl/mktime.c @@ -1,28 +1,37 @@ /* Convert a 'struct tm' to a time_t value. - Copyright (C) 1993-2013 Free Software Foundation, Inc. + Copyright (C) 1993-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Eggert . The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ -/* Define this to have a standalone program to test this implementation of - mktime. */ -/* #define DEBUG 1 */ +/* The following macros influence what gets defined when this file is compiled: + + Macro/expression Which gnulib module This compilation unit + should define + + _LIBC (glibc proper) mktime + + NEED_MKTIME_WORKING mktime rpl_mktime + || NEED_MKTIME_WINDOWS + + NEED_MKTIME_INTERNAL mktime-internal mktime_internal + */ #ifndef _LIBC -# include +# include #endif /* Assume that leap seconds are possible, unless told otherwise. @@ -34,115 +43,123 @@ #include +#include #include +#include +#include +#include + +#include +#include + +#ifndef NEED_MKTIME_INTERNAL +# define NEED_MKTIME_INTERNAL 0 +#endif +#ifndef NEED_MKTIME_WINDOWS +# define NEED_MKTIME_WINDOWS 0 +#endif +#ifndef NEED_MKTIME_WORKING +# define NEED_MKTIME_WORKING 0 +#endif + +#include "mktime-internal.h" -#include /* For the real memcpy prototype. */ - -#if DEBUG -# include -# include -/* Make it work even if the system's libc has its own mktime routine. */ -# undef mktime -# define mktime my_mktime -#endif /* DEBUG */ - -/* Some of the code in this file assumes that signed integer overflow - silently wraps around. This assumption can't easily be programmed - around, nor can it be checked for portably at compile-time or - easily eliminated at run-time. - - Define WRAPV to 1 if the assumption is valid and if - #pragma GCC optimize ("wrapv") - does not trigger GCC bug 51793 - . - Otherwise, define it to 0; this forces the use of slower code that, - while not guaranteed by the C Standard, works on all production - platforms that we know about. */ -#ifndef WRAPV -# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \ - && defined __GLIBC__) -# pragma GCC optimize ("wrapv") -# define WRAPV 1 +#if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS) +static void +my_tzset (void) +{ +# if NEED_MKTIME_WINDOWS + /* Rectify the value of the environment variable TZ. + There are four possible kinds of such values: + - Traditional US time zone names, e.g. "PST8PDT". Syntax: see + + - Time zone names based on geography, that contain one or more + slashes, e.g. "Europe/Moscow". + - Time zone names based on geography, without slashes, e.g. + "Singapore". + - Time zone names that contain explicit DST rules. Syntax: see + + The Microsoft CRT understands only the first kind. It produces incorrect + results if the value of TZ is of the other kinds. + But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value + of the second kind for most geographies, or of the first kind in a few + other geographies. If it is of the second kind, neutralize it. For the + Microsoft CRT, an absent or empty TZ means the time zone that the user + has set in the Windows Control Panel. + If the value of TZ is of the third or fourth kind -- Cygwin programs + understand these syntaxes as well --, it does not matter whether we + neutralize it or not, since these values occur only when a Cygwin user + has set TZ explicitly; this case is 1. rare and 2. under the user's + responsibility. */ + const char *tz = getenv ("TZ"); + if (tz != NULL && strchr (tz, '/') != NULL) + _putenv ("TZ="); # else -# define WRAPV 0 + tzset (); # endif +} +# undef __tzset +# define __tzset() my_tzset () #endif -/* Verify a requirement at compile-time (unlike assert, which is runtime). */ -#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } +#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL + +/* A signed type that can represent an integer number of years + multiplied by four times the number of seconds in a year. It is + needed when converting a tm_year value times the number of seconds + in a year. The factor of four comes because these products need + to be subtracted from each other, and sometimes with an offset + added to them, and then with another timestamp added, without + worrying about overflow. -/* A signed type that is at least one bit wider than int. */ -#if INT_MAX <= LONG_MAX / 2 + Much of the code uses long_int to represent __time64_t values, to + lessen the hassle of dealing with platforms where __time64_t is + unsigned, and because long_int should suffice to represent all + __time64_t values that mktime can generate even on platforms where + __time64_t is wider than the int components of struct tm. */ + +#if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 typedef long int long_int; #else typedef long long int long_int; #endif -verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2); +verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); /* Shift A right by B bits portably, by dividing A by 2**B and - truncating towards minus infinity. A and B should be free of side - effects, and B should be in the range 0 <= B <= INT_BITS - 2, where - INT_BITS is the number of useful bits in an int. GNU code can - assume that INT_BITS is at least 32. + truncating towards minus infinity. B should be in the range 0 <= B + <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful + bits in a long_int. LONG_INT_BITS is at least 32. ISO C99 says that A >> B is implementation-defined if A < 0. Some implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift right in the usual way when A < 0, so SHR falls back on division if ordinary A >> B doesn't seem to be the usual signed shift. */ -#define SHR(a, b) \ - ((-1 >> 1 == -1 \ - && (long_int) -1 >> 1 == -1 \ - && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \ - ? (a) >> (b) \ - : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if the arithmetic type T is an integer type. bool counts as - an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) - -/* True if negative values of the signed integer type T use two's - complement, or if T is an unsigned integer type. */ -#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) - -/* True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* The maximum and minimum values for the integer type T. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ -#define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : ~ TYPE_MAXIMUM (t))) -#define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) - -#ifndef TIME_T_MIN -# define TIME_T_MIN TYPE_MINIMUM (time_t) -#endif -#ifndef TIME_T_MAX -# define TIME_T_MAX TYPE_MAXIMUM (time_t) -#endif -#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) -verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); -verify (twos_complement_arithmetic, - (TYPE_TWOS_COMPLEMENT (int) - && TYPE_TWOS_COMPLEMENT (long_int) - && TYPE_TWOS_COMPLEMENT (time_t))); +static long_int +shr (long_int a, int b) +{ + long_int one = 1; + return (-one >> 1 == -1 + ? a >> b + : (a + (a < 0)) / (one << b) - (a < 0)); +} + +/* Bounds for the intersection of __time64_t and long_int. */ + +static long_int const mktime_min + = ((TYPE_SIGNED (__time64_t) + && TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int)) + ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t)); +static long_int const mktime_max + = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t) + ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t)); #define EPOCH_YEAR 1970 #define TM_YEAR_BASE 1900 -verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); +verify (TM_YEAR_BASE % 100 == 0); -/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ -static int +/* Is YEAR + TM_YEAR_BASE a leap year? */ +static bool leapyear (long_int year) { /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. @@ -166,20 +183,9 @@ const unsigned short int __mon_yday[2][13] = }; -#ifndef _LIBC -/* Portable standalone applications should supply a that - declares a POSIX-compliant localtime_r, for the benefit of older - implementations that lack localtime_r or have a nonstandard one. - See the gnulib time_r module for one way to implement this. */ -# undef __localtime_r -# define __localtime_r localtime_r -# define __mktime_internal mktime_internal -# include "mktime-internal.h" -#endif - -/* Return 1 if the values A and B differ according to the rules for - tm_isdst: A and B differ if one is zero and the other positive. */ -static int +/* Do the values A and B differ according to the rules for tm_isdst? + A and B differ if one is zero and the other positive. */ +static bool isdst_differ (int a, int b) { return (!a != !b) && (0 <= a) && (0 <= b); @@ -187,171 +193,135 @@ isdst_differ (int a, int b) /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks - were not adjusted between the time stamps. + were not adjusted between the timestamps. The YEAR values uses the same numbering as TP->tm_year. Values - need not be in the usual range. However, YEAR1 must not be less - than 2 * INT_MIN or greater than 2 * INT_MAX. + need not be in the usual range. However, YEAR1 - YEAR0 must not + overflow even when multiplied by three times the number of seconds + in a year, and likewise for YDAY1 - YDAY0 and three times the + number of seconds in a day. */ - The result may overflow. It is the caller's responsibility to - detect overflow. */ - -static time_t +static long_int ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, int year0, int yday0, int hour0, int min0, int sec0) { - verify (C99_integer_division, -1 / 2 == 0); + verify (-1 / 2 == 0); /* Compute intervening leap days correctly even if year is negative. Take care to avoid integer overflow here. */ - int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3); - int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3); - int a100 = a4 / 25 - (a4 % 25 < 0); - int b100 = b4 / 25 - (b4 % 25 < 0); - int a400 = SHR (a100, 2); - int b400 = SHR (b100, 2); + int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3); + int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3); + int a100 = (a4 + (a4 < 0)) / 25 - (a4 < 0); + int b100 = (b4 + (b4 < 0)) / 25 - (b4 < 0); + int a400 = shr (a100, 2); + int b400 = shr (b100, 2); int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); - /* Compute the desired time in time_t precision. Overflow might - occur here. */ - time_t tyear1 = year1; - time_t years = tyear1 - year0; - time_t days = 365 * years + yday1 - yday0 + intervening_leap_days; - time_t hours = 24 * days + hour1 - hour0; - time_t minutes = 60 * hours + min1 - min0; - time_t seconds = 60 * minutes + sec1 - sec0; + /* Compute the desired time without overflowing. */ + long_int years = year1 - year0; + long_int days = 365 * years + yday1 - yday0 + intervening_leap_days; + long_int hours = 24 * days + hour1 - hour0; + long_int minutes = 60 * hours + min1 - min0; + long_int seconds = 60 * minutes + sec1 - sec0; return seconds; } -/* Return the average of A and B, even if A + B would overflow. */ -static time_t -time_t_avg (time_t a, time_t b) +/* Return the average of A and B, even if A + B would overflow. + Round toward positive infinity. */ +static long_int +long_int_avg (long_int a, long_int b) { - return SHR (a, 1) + SHR (b, 1) + (a & b & 1); + return shr (a, 1) + shr (b, 1) + ((a | b) & 1); } -/* Return 1 if A + B does not overflow. If time_t is unsigned and if - B's top bit is set, assume that the sum represents A - -B, and - return 1 if the subtraction does not wrap around. */ -static int -time_t_add_ok (time_t a, time_t b) -{ - if (! TYPE_SIGNED (time_t)) - { - time_t sum = a + b; - return (sum < a) == (TIME_T_MIDPOINT <= b); - } - else if (WRAPV) - { - time_t sum = a + b; - return (sum < a) == (b < 0); - } - else - { - time_t avg = time_t_avg (a, b); - return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; - } -} +/* Return a long_int value corresponding to (YEAR-YDAY HOUR:MIN:SEC) + minus *TP seconds, assuming no clock adjustments occurred between + the two timestamps. -/* Return 1 if A + B does not overflow. */ -static int -time_t_int_add_ok (time_t a, int b) + YEAR and YDAY must not be so large that multiplying them by three times the + number of seconds in a year (or day, respectively) would overflow long_int. + *TP should be in the usual range. */ +static long_int +tm_diff (long_int year, long_int yday, int hour, int min, int sec, + struct tm const *tp) { - verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX); - if (WRAPV) - { - time_t sum = a + b; - return (sum < a) == (b < 0); - } - else - { - int a_odd = a & 1; - time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b)); - return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; - } + return ydhms_diff (year, yday, hour, min, sec, + tp->tm_year, tp->tm_yday, + tp->tm_hour, tp->tm_min, tp->tm_sec); } -/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), - assuming that *T corresponds to *TP and that no clock adjustments - occurred between *TP and the desired time. - If TP is null, return a value not equal to *T; this avoids false matches. - If overflow occurs, yield the minimal or maximal value, except do not - yield a value equal to *T. */ -static time_t -guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, - const time_t *t, const struct tm *tp) +/* Use CONVERT to convert T to a struct tm value in *TM. T must be in + range for __time64_t. Return TM if successful, NULL (setting errno) on + failure. */ +static struct tm * +convert_time (struct tm *(*convert) (const __time64_t *, struct tm *), + long_int t, struct tm *tm) { - if (tp) - { - time_t d = ydhms_diff (year, yday, hour, min, sec, - tp->tm_year, tp->tm_yday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - if (time_t_add_ok (*t, d)) - return *t + d; - } - - /* Overflow occurred one way or another. Return the nearest result - that is actually in range, except don't report a zero difference - if the actual difference is nonzero, as that would cause a false - match; and don't oscillate between two values, as that would - confuse the spring-forward gap detector. */ - return (*t < TIME_T_MIDPOINT - ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN) - : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX)); + __time64_t x = t; + return convert (&x, tm); } /* Use CONVERT to convert *T to a broken down time in *TP. If *T is out of range for conversion, adjust it so that - it is the nearest in-range value and then convert that. */ + it is the nearest in-range value and then convert that. + A value is in range if it fits in both __time64_t and long_int. + Return TP on success, NULL (setting errno) on failure. */ static struct tm * -ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), - time_t *t, struct tm *tp) +ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), + long_int *t, struct tm *tp) { - struct tm *r = convert (t, tp); - - if (!r && *t) + long_int t1 = (*t < mktime_min ? mktime_min + : *t <= mktime_max ? *t : mktime_max); + struct tm *r = convert_time (convert, t1, tp); + if (r) { - time_t bad = *t; - time_t ok = 0; + *t = t1; + return r; + } + if (errno != EOVERFLOW) + return NULL; - /* BAD is a known unconvertible time_t, and OK is a known good one. - Use binary search to narrow the range between BAD and OK until - they differ by 1. */ - while (bad != ok + (bad < 0 ? -1 : 1)) - { - time_t mid = *t = time_t_avg (ok, bad); - r = convert (t, tp); - if (r) - ok = mid; - else - bad = mid; - } + long_int bad = t1; + long_int ok = 0; + struct tm oktm; oktm.tm_sec = -1; - if (!r && ok) - { - /* The last conversion attempt failed; - revert to the most recent successful attempt. */ - *t = ok; - r = convert (t, tp); - } + /* BAD is a known out-of-range value, and OK is a known in-range one. + Use binary search to narrow the range between BAD and OK until + they differ by 1. */ + while (true) + { + long_int mid = long_int_avg (ok, bad); + if (mid == ok || mid == bad) + break; + if (convert_time (convert, mid, tp)) + ok = mid, oktm = *tp; + else if (errno != EOVERFLOW) + return NULL; + else + bad = mid; } - return r; + if (oktm.tm_sec < 0) + return NULL; + *t = ok; + *tp = oktm; + return tp; } -/* Convert *TP to a time_t value, inverting +/* Convert *TP to a __time64_t value, inverting the monotonic and mostly-unit-linear conversion function CONVERT. Use *OFFSET to keep track of a guess at the offset of the result, compared to what the result would be for UTC without leap seconds. If *OFFSET's guess is correct, only one CONVERT call is needed. + If successful, set *TP to the canonicalized struct tm; + otherwise leave *TP alone, return ((time_t) -1) and set errno. This function is external because it is used also by timegm.c. */ -time_t +__time64_t __mktime_internal (struct tm *tp, - struct tm *(*convert) (const time_t *, struct tm *), - time_t *offset) + struct tm *(*convert) (const __time64_t *, struct tm *), + mktime_offset_t *offset) { - time_t t, gt, t0, t1, t2; struct tm tm; /* The maximum number of probes (calls to CONVERT) should be enough @@ -371,7 +341,7 @@ __mktime_internal (struct tm *tp, int isdst = tp->tm_isdst; /* 1 if the previous probe was DST. */ - int dst2; + int dst2 = 0; /* Ensure that mon is in range, and set year accordingly. */ int mon_remainder = mon % 12; @@ -381,9 +351,7 @@ __mktime_internal (struct tm *tp, long_int year = lyear_requested + mon_years; /* The other values need not be in range: - the remaining code handles minor overflows correctly, - assuming int and time_t arithmetic wraps around. - Major overflows are caught at the end. */ + the remaining code handles overflows correctly. */ /* Calculate day of year from year, month, and day of month. The result need not be in range. */ @@ -393,14 +361,15 @@ __mktime_internal (struct tm *tp, long_int lmday = mday; long_int yday = mon_yday + lmday; - time_t guessed_offset = *offset; + mktime_offset_t off = *offset; + int negative_offset_guess; int sec_requested = sec; if (LEAP_SECONDS_POSSIBLE) { /* Handle out-of-range seconds specially, - since ydhms_tm_diff assumes every minute has 60 seconds. */ + since ydhms_diff assumes every minute has 60 seconds. */ if (sec < 0) sec = 0; if (59 < sec) @@ -410,91 +379,47 @@ __mktime_internal (struct tm *tp, /* Invert CONVERT by probing. First assume the same offset as last time. */ - t0 = ydhms_diff (year, yday, hour, min, sec, - EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset); + INT_SUBTRACT_WRAPV (0, off, &negative_offset_guess); + long_int t0 = ydhms_diff (year, yday, hour, min, sec, + EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, + negative_offset_guess); + long_int t = t0, t1 = t0, t2 = t0; + + /* Repeatedly use the error to improve the guess. */ - if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) + while (true) { - /* time_t isn't large enough to rule out overflows, so check - for major overflows. A gross check suffices, since if t0 - has overflowed, it is off by a multiple of TIME_T_MAX - - TIME_T_MIN + 1. So ignore any component of the difference - that is bounded by a small value. */ - - /* Approximate log base 2 of the number of time units per - biennium. A biennium is 2 years; use this unit instead of - years to avoid integer overflow. For example, 2 average - Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds, - which is 63113904 seconds, and rint (log2 (63113904)) is - 26. */ - int ALOG2_SECONDS_PER_BIENNIUM = 26; - int ALOG2_MINUTES_PER_BIENNIUM = 20; - int ALOG2_HOURS_PER_BIENNIUM = 14; - int ALOG2_DAYS_PER_BIENNIUM = 10; - int LOG2_YEARS_PER_BIENNIUM = 1; - - int approx_requested_biennia = - (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM) - - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM) - + SHR (mday, ALOG2_DAYS_PER_BIENNIUM) - + SHR (hour, ALOG2_HOURS_PER_BIENNIUM) - + SHR (min, ALOG2_MINUTES_PER_BIENNIUM) - + (LEAP_SECONDS_POSSIBLE - ? 0 - : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM))); - - int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); - int diff = approx_biennia - approx_requested_biennia; - int approx_abs_diff = diff < 0 ? -1 - diff : diff; - - /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously - gives a positive value of 715827882. Setting a variable - first then doing math on it seems to work. - (ghazi@caip.rutgers.edu) */ - time_t time_t_max = TIME_T_MAX; - time_t time_t_min = TIME_T_MIN; - time_t overflow_threshold = - (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM; - - if (overflow_threshold < approx_abs_diff) + if (! ranged_convert (convert, &t, &tm)) + return -1; + long_int dt = tm_diff (year, yday, hour, min, sec, &tm); + if (dt == 0) + break; + + if (t == t1 && t != t2 + && (tm.tm_isdst < 0 + || (isdst < 0 + ? dst2 <= (tm.tm_isdst != 0) + : (isdst != 0) != (tm.tm_isdst != 0)))) + /* We can't possibly find a match, as we are oscillating + between two values. The requested time probably falls + within a spring-forward gap of size DT. Follow the common + practice in this case, which is to return a time that is DT + away from the requested time, preferring a time whose + tm_isdst differs from the requested value. (If no tm_isdst + was requested and only one of the two values has a nonzero + tm_isdst, prefer that value.) In practice, this is more + useful than returning -1. */ + goto offset_found; + + remaining_probes--; + if (remaining_probes == 0) { - /* Overflow occurred. Try repairing it; this might work if - the time zone offset is enough to undo the overflow. */ - time_t repaired_t0 = -1 - t0; - approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); - diff = approx_biennia - approx_requested_biennia; - approx_abs_diff = diff < 0 ? -1 - diff : diff; - if (overflow_threshold < approx_abs_diff) - return -1; - guessed_offset += repaired_t0 - t0; - t0 = repaired_t0; + __set_errno (EOVERFLOW); + return -1; } - } - - /* Repeatedly use the error to improve the guess. */ - for (t = t1 = t2 = t0, dst2 = 0; - (gt = guess_time_tm (year, yday, hour, min, sec, &t, - ranged_convert (convert, &t, &tm)), - t != gt); - t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0) - if (t == t1 && t != t2 - && (tm.tm_isdst < 0 - || (isdst < 0 - ? dst2 <= (tm.tm_isdst != 0) - : (isdst != 0) != (tm.tm_isdst != 0)))) - /* We can't possibly find a match, as we are oscillating - between two values. The requested time probably falls - within a spring-forward gap of size GT - T. Follow the common - practice in this case, which is to return a time that is GT - T - away from the requested time, preferring a time whose - tm_isdst differs from the requested value. (If no tm_isdst - was requested and only one of the two values has a nonzero - tm_isdst, prefer that value.) In practice, this is more - useful than returning -1. */ - goto offset_found; - else if (--remaining_probes == 0) - return -1; + t1 = t2, t2 = t, t += dt, dst2 = tm.tm_isdst != 0; + } /* We have a match. Check whether tm.tm_isdst has the requested value, if any. */ @@ -504,8 +429,13 @@ __mktime_internal (struct tm *tp, time with the right value, and use its UTC offset. Heuristic: probe the adjacent timestamps in both directions, - looking for the desired isdst. This should work for all real - time zone histories in the tz database. */ + looking for the desired isdst. If none is found within a + reasonable duration bound, assume a one-hour DST difference. + This should work for all real time zone histories in the tz + database. */ + + /* +1 if we wanted standard time but got DST, -1 if the reverse. */ + int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); /* Distance between probes when looking for a DST boundary. In tzdata2003a, the shortest period of DST is 601200 seconds @@ -516,12 +446,14 @@ __mktime_internal (struct tm *tp, periods when probing. */ int stride = 601200; - /* The longest period of DST in tzdata2003a is 536454000 seconds - (e.g., America/Jujuy starting 1946-10-01 01:00). The longest - period of non-DST is much longer, but it makes no real sense - to search for more than a year of non-DST, so use the DST - max. */ - int duration_max = 536454000; + /* In TZDB 2021e, the longest period of DST (or of non-DST), in + which the DST (or adjacent DST) difference is not one hour, + is 457243209 seconds: e.g., America/Cambridge_Bay with leap + seconds, starting 1965-10-31 00:00 in a switch from + double-daylight time (-05) to standard time (-07), and + continuing to 1980-04-27 02:00 in a switch from standard time + (-07) to daylight time (-06). */ + int duration_max = 457243209; /* Search in both directions, so the maximum distance is half the duration; add the stride to avoid off-by-1 problems. */ @@ -531,211 +463,116 @@ __mktime_internal (struct tm *tp, for (delta = stride; delta < delta_bound; delta += stride) for (direction = -1; direction <= 1; direction += 2) - if (time_t_int_add_ok (t, delta * direction)) - { - time_t ot = t + delta * direction; - struct tm otm; - ranged_convert (convert, &ot, &otm); - if (! isdst_differ (isdst, otm.tm_isdst)) - { - /* We found the desired tm_isdst. - Extrapolate back to the desired time. */ - t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); - ranged_convert (convert, &t, &tm); - goto offset_found; - } - } + { + long_int ot; + if (! INT_ADD_WRAPV (t, delta * direction, &ot)) + { + struct tm otm; + if (! ranged_convert (convert, &ot, &otm)) + return -1; + if (! isdst_differ (isdst, otm.tm_isdst)) + { + /* We found the desired tm_isdst. + Extrapolate back to the desired time. */ + long_int gt = ot + tm_diff (year, yday, hour, min, sec, + &otm); + if (mktime_min <= gt && gt <= mktime_max) + { + if (convert_time (convert, gt, &tm)) + { + t = gt; + goto offset_found; + } + if (errno != EOVERFLOW) + return -1; + } + } + } + } + + /* No unusual DST offset was found nearby. Assume one-hour DST. */ + t += 60 * 60 * dst_difference; + if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) + goto offset_found; + + __set_errno (EOVERFLOW); + return -1; } offset_found: - *offset = guessed_offset + t - t0; + /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS. + This is just a heuristic to speed up the next mktime call, and + correctness is unaffected if integer overflow occurs here. */ + INT_SUBTRACT_WRAPV (t, t0, offset); + INT_SUBTRACT_WRAPV (*offset, negative_offset_guess, offset); if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) { /* Adjust time to reflect the tm_sec requested, not the normalized value. Also, repair any damage from a false match due to a leap second. */ - int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; - if (! time_t_int_add_ok (t, sec_requested)) - return -1; - t1 = t + sec_requested; - if (! time_t_int_add_ok (t1, sec_adjustment)) - return -1; - t2 = t1 + sec_adjustment; - if (! convert (&t2, &tm)) + long_int sec_adjustment = sec == 0 && tm.tm_sec == 60; + sec_adjustment -= sec; + sec_adjustment += sec_requested; + if (INT_ADD_WRAPV (t, sec_adjustment, &t) + || ! (mktime_min <= t && t <= mktime_max)) + { + __set_errno (EOVERFLOW); + return -1; + } + if (! convert_time (convert, t, &tm)) return -1; - t = t2; } *tp = tm; return t; } +#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */ -/* FIXME: This should use a signed type wide enough to hold any UTC - offset in seconds. 'int' should be good enough for GNU code. We - can't fix this unilaterally though, as other modules invoke - __mktime_internal. */ -static time_t localtime_offset; +#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS -/* Convert *TP to a time_t value. */ -time_t -mktime (struct tm *tp) +/* Convert *TP to a __time64_t value. */ +__time64_t +__mktime64 (struct tm *tp) { -#ifdef _LIBC /* POSIX.1 8.1.1 requires that whenever mktime() is called, the time zone names contained in the external variable 'tzname' shall be set as if the tzset() function had been called. */ __tzset (); -#endif - return __mktime_internal (tp, __localtime_r, &localtime_offset); +# if defined _LIBC || NEED_MKTIME_WORKING + static mktime_offset_t localtime_offset; + return __mktime_internal (tp, __localtime64_r, &localtime_offset); +# else +# undef mktime + return mktime (tp); +# endif } +#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ -#ifdef weak_alias -weak_alias (mktime, timelocal) -#endif - -#ifdef _LIBC -libc_hidden_def (mktime) -libc_hidden_weak (timelocal) -#endif - -#if DEBUG +#if defined _LIBC && __TIMESIZE != 64 -static int -not_equal_tm (const struct tm *a, const struct tm *b) -{ - return ((a->tm_sec ^ b->tm_sec) - | (a->tm_min ^ b->tm_min) - | (a->tm_hour ^ b->tm_hour) - | (a->tm_mday ^ b->tm_mday) - | (a->tm_mon ^ b->tm_mon) - | (a->tm_year ^ b->tm_year) - | (a->tm_yday ^ b->tm_yday) - | isdst_differ (a->tm_isdst, b->tm_isdst)); -} +libc_hidden_def (__mktime64) -static void -print_tm (const struct tm *tp) -{ - if (tp) - printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d", - tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec, - tp->tm_yday, tp->tm_wday, tp->tm_isdst); - else - printf ("0"); -} - -static int -check_result (time_t tk, struct tm tmk, time_t tl, const struct tm *lt) -{ - if (tk != tl || !lt || not_equal_tm (&tmk, lt)) - { - printf ("mktime ("); - print_tm (lt); - printf (")\nyields ("); - print_tm (&tmk); - printf (") == %ld, should be %ld\n", (long int) tk, (long int) tl); - return 1; - } - - return 0; -} - -int -main (int argc, char **argv) +time_t +mktime (struct tm *tp) { - int status = 0; - struct tm tm, tmk, tml; - struct tm *lt; - time_t tk, tl, tl1; - char trailer; - - if ((argc == 3 || argc == 4) - && (sscanf (argv[1], "%d-%d-%d%c", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) - == 3) - && (sscanf (argv[2], "%d:%d:%d%c", - &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer) - == 3)) + struct tm tm = *tp; + __time64_t t = __mktime64 (&tm); + if (in_time_t_range (t)) { - tm.tm_year -= TM_YEAR_BASE; - tm.tm_mon--; - tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); - tmk = tm; - tl = mktime (&tmk); - lt = localtime (&tl); - if (lt) - { - tml = *lt; - lt = &tml; - } - printf ("mktime returns %ld == ", (long int) tl); - print_tm (&tmk); - printf ("\n"); - status = check_result (tl, tmk, tl, lt); + *tp = tm; + return t; } - else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0)) + else { - time_t from = atol (argv[1]); - time_t by = atol (argv[2]); - time_t to = atol (argv[3]); - - if (argc == 4) - for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) - { - lt = localtime (&tl); - if (lt) - { - tmk = tml = *lt; - tk = mktime (&tmk); - status |= check_result (tk, tmk, tl, &tml); - } - else - { - printf ("localtime (%ld) yields 0\n", (long int) tl); - status = 1; - } - tl1 = tl + by; - if ((tl1 < tl) != (by < 0)) - break; - } - else - for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) - { - /* Null benchmark. */ - lt = localtime (&tl); - if (lt) - { - tmk = tml = *lt; - tk = tl; - status |= check_result (tk, tmk, tl, &tml); - } - else - { - printf ("localtime (%ld) yields 0\n", (long int) tl); - status = 1; - } - tl1 = tl + by; - if ((tl1 < tl) != (by < 0)) - break; - } + __set_errno (EOVERFLOW); + return -1; } - else - printf ("Usage:\ -\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\ -\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\ -\t%s FROM BY TO - # Do not test those values (for benchmark).\n", - argv[0], argv[0], argv[0]); - - return status; } -#endif /* DEBUG */ - -/* -Local Variables: -compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime" -End: -*/ +#endif + +weak_alias (mktime, timelocal) +libc_hidden_def (mktime) +libc_hidden_weak (timelocal) diff --git a/gl/mountlist.c b/gl/mountlist.c index 30f42861..fac5c45e 100644 --- a/gl/mountlist.c +++ b/gl/mountlist.c @@ -1,10 +1,10 @@ /* mountlist.c -- return a list of mounted file systems - Copyright (C) 1991-1992, 1997-2013 Free Software Foundation, Inc. + Copyright (C) 1991-1992, 1997-2022 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 + 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, @@ -13,7 +13,7 @@ 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 . */ + along with this program. If not, see . */ #include @@ -37,7 +37,13 @@ # include #endif -#if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */ +#if MAJOR_IN_MKDEV +# include +#elif MAJOR_IN_SYSMACROS +# include +#endif + +#if defined MOUNTED_GETFSSTAT /* OSF/1, also (obsolete) Apple Darwin 1.3 */ # if HAVE_SYS_UCRED_H # include /* needed on OSF V4.0 for definition of NGROUPS, NGROUPS is used as an array dimension in ucred.h */ @@ -56,102 +62,104 @@ # endif #endif /* MOUNTED_GETFSSTAT */ -#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ +#ifdef MOUNTED_GETMNTENT1 /* glibc, HP-UX, IRIX, Cygwin, Android, + also (obsolete) 4.3BSD, SunOS */ # include -# if !defined MOUNTED +# include +# if defined __ANDROID__ /* Android */ + /* Bionic versions from between 2014-01-09 and 2015-01-08 define MOUNTED to + an incorrect value; older Bionic versions don't define it at all. */ +# undef MOUNTED +# define MOUNTED "/proc/mounts" +# elif !defined MOUNTED # if defined _PATH_MOUNTED /* GNU libc */ # define MOUNTED _PATH_MOUNTED # endif # if defined MNT_MNTTAB /* HP-UX. */ # define MOUNTED MNT_MNTTAB # endif -# if defined MNTTABNAME /* Dynix. */ -# define MOUNTED MNTTABNAME -# endif # endif #endif -#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ +#ifdef MOUNTED_GETMNTINFO /* Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD */ # include #endif -#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ +#ifdef MOUNTED_GETMNTINFO2 /* NetBSD, Minix */ # include #endif -#ifdef MOUNTED_GETMNT /* Ultrix. */ -# include -# include -#endif - -#ifdef MOUNTED_FS_STAT_DEV /* BeOS. */ +#ifdef MOUNTED_FS_STAT_DEV /* Haiku, also (obsolete) BeOS */ # include # include #endif -#ifdef MOUNTED_FREAD /* SVR2. */ -# include -#endif - -#ifdef MOUNTED_FREAD_FSTYP /* SVR3. */ +#ifdef MOUNTED_FREAD_FSTYP /* (obsolete) SVR3 */ # include # include # include #endif -#ifdef MOUNTED_LISTMNTENT -# include +#ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */ +# include #endif -#ifdef MOUNTED_GETMNTENT2 /* SVR4. */ +#ifdef MOUNTED_GETMNTENT2 /* Solaris < 8, also (obsolete) SVR4 */ # include #endif -#ifdef MOUNTED_VMOUNT /* AIX. */ +#ifdef MOUNTED_VMOUNT /* AIX */ # include # include #endif -#ifdef MOUNTED_INTERIX_STATVFS /* Interix. */ +#ifdef MOUNTED_INTERIX_STATVFS /* Interix */ # include # include #endif -#ifdef DOLPHIN -/* So special that it's not worth putting this in autoconf. */ -# undef MOUNTED_FREAD_FSTYP -# define MOUNTED_GETMNTTBL -#endif - #if HAVE_SYS_MNTENT_H /* This is to get MNTOPT_IGNORE on e.g. SVR4. */ # include #endif +#ifdef MOUNTED_GETMNTENT1 +# if !HAVE_SETMNTENT /* Android <= 4.4 */ +# define setmntent(fp,mode) fopen (fp, mode "e") +# endif +# if !HAVE_ENDMNTENT /* Android <= 4.4 */ +# define endmntent(fp) fclose (fp) +# endif +#endif + #ifndef HAVE_HASMNTOPT # define hasmntopt(mnt, opt) ((char *) 0) #endif #undef MNT_IGNORE #ifdef MNTOPT_IGNORE -# define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE) +# if defined __sun && defined __SVR4 +/* Solaris defines hasmntopt(struct mnttab *, char *) + while it is otherwise hasmntopt(struct mnttab *, const char *). */ +# define MNT_IGNORE(M) hasmntopt (M, (char *) MNTOPT_IGNORE) +# else +# define MNT_IGNORE(M) hasmntopt (M, MNTOPT_IGNORE) +# endif #else # define MNT_IGNORE(M) 0 #endif -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close +/* Each of the FILE streams in this file is only used in a single thread. */ +#include "unlocked-io.h" /* The results of opendir() in this file are not used with dirfd and fchdir, therefore save some unnecessary work in fchdir.c. */ -#undef opendir -#undef closedir +#ifdef GNULIB_defined_opendir +# undef opendir +#endif +#ifdef GNULIB_defined_closedir +# undef closedir +#endif #define ME_DUMMY_0(Fs_name, Fs_type) \ (strcmp (Fs_type, "autofs") == 0 \ @@ -161,6 +169,7 @@ || strcmp (Fs_type, "debugfs") == 0 \ || strcmp (Fs_type, "devpts") == 0 \ || strcmp (Fs_type, "fusectl") == 0 \ + || strcmp (Fs_type, "fuse.portal") == 0 \ || strcmp (Fs_type, "mqueue") == 0 \ || strcmp (Fs_type, "rpc_pipefs") == 0 \ || strcmp (Fs_type, "sysfs") == 0 \ @@ -176,10 +185,9 @@ we grant an exception to any with "bind" in its list of mount options. I.e., those are *not* dummy entries. */ #ifdef MOUNTED_GETMNTENT1 -# define ME_DUMMY(Fs_name, Fs_type, Fs_ent) \ +# define ME_DUMMY(Fs_name, Fs_type, Bind) \ (ME_DUMMY_0 (Fs_name, Fs_type) \ - || (strcmp (Fs_type, "none") == 0 \ - && !hasmntopt (Fs_ent, "bind"))) + || (strcmp (Fs_type, "none") == 0 && !Bind)) #else # define ME_DUMMY(Fs_name, Fs_type) \ (ME_DUMMY_0 (Fs_name, Fs_type) || strcmp (Fs_type, "none") == 0) @@ -187,11 +195,14 @@ #ifdef __CYGWIN__ # include +/* Don't assume that UNICODE is not defined. */ +# undef GetDriveType +# define GetDriveType GetDriveTypeA # define ME_REMOTE me_remote /* All cygwin mount points include ':' or start with '//'; so it requires a native Windows call to determine remote disks. */ static bool -me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) +me_remote (char const *fs_name, _GL_UNUSED char const *fs_type) { if (fs_name[0] && fs_name[1] == ':') { @@ -212,16 +223,30 @@ me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) #ifndef ME_REMOTE /* A file system is "remote" if its Fs_name contains a ':' - or if (it is of type (smbfs or cifs) and its Fs_name starts with '//'). */ + or if (it is of type (smbfs or cifs) and its Fs_name starts with '//') + or if it is of any other of the listed types + or Fs_name is equal to "-hosts" (used by autofs to mount remote fs). + "VM" file systems like prl_fs or vboxsf are not considered remote here. */ # define ME_REMOTE(Fs_name, Fs_type) \ (strchr (Fs_name, ':') != NULL \ || ((Fs_name)[0] == '/' \ && (Fs_name)[1] == '/' \ && (strcmp (Fs_type, "smbfs") == 0 \ - || strcmp (Fs_type, "cifs") == 0))) + || strcmp (Fs_type, "smb3") == 0 \ + || strcmp (Fs_type, "cifs") == 0)) \ + || strcmp (Fs_type, "acfs") == 0 \ + || strcmp (Fs_type, "afs") == 0 \ + || strcmp (Fs_type, "coda") == 0 \ + || strcmp (Fs_type, "auristorfs") == 0 \ + || strcmp (Fs_type, "fhgfs") == 0 \ + || strcmp (Fs_type, "gpfs") == 0 \ + || strcmp (Fs_type, "ibrix") == 0 \ + || strcmp (Fs_type, "ocfs2") == 0 \ + || strcmp (Fs_type, "vxfs") == 0 \ + || strcmp ("-hosts", Fs_name) == 0) #endif -#if MOUNTED_GETMNTINFO +#if MOUNTED_GETMNTINFO /* Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD */ # if ! HAVE_STRUCT_STATFS_F_FSTYPENAME static char * @@ -331,7 +356,7 @@ fsp_to_string (const struct statfs *fsp) #endif /* MOUNTED_GETMNTINFO */ -#ifdef MOUNTED_VMOUNT /* AIX. */ +#ifdef MOUNTED_VMOUNT /* AIX */ static char * fstype_to_string (int t) { @@ -382,6 +407,46 @@ dev_from_mount_options (char const *mount_options) #endif +#if defined MOUNTED_GETMNTENT1 && (defined __linux__ || defined __ANDROID__) /* GNU/Linux, Android */ + +/* Unescape the paths in mount tables. + STR is updated in place. */ + +static void +unescape_tab (char *str) +{ + size_t i, j = 0; + size_t len = strlen (str) + 1; + for (i = 0; i < len; i++) + { + if (str[i] == '\\' && (i + 4 < len) + && str[i + 1] >= '0' && str[i + 1] <= '3' + && str[i + 2] >= '0' && str[i + 2] <= '7' + && str[i + 3] >= '0' && str[i + 3] <= '7') + { + str[j++] = (str[i + 1] - '0') * 64 + + (str[i + 2] - '0') * 8 + + (str[i + 3] - '0'); + i += 3; + } + else + str[j++] = str[i]; + } +} + +/* Find the next space in STR, terminate the string there in place, + and return that position. Otherwise return NULL. */ + +static char * +terminate_at_blank (char *str) +{ + char *s = strchr (str, ' '); + if (s) + *s = '\0'; + return s; +} +#endif + /* Return a list of the currently mounted file systems, or NULL on error. Add each entry to the tail of the list so that they stay in order. If NEED_FS_TYPE is true, ensure that the file system type fields in @@ -395,69 +460,141 @@ read_file_system_list (bool need_fs_type) struct mount_entry **mtail = &mount_list; (void) need_fs_type; -#ifdef MOUNTED_LISTMNTENT +#ifdef MOUNTED_GETMNTENT1 /* glibc, HP-UX, IRIX, Cygwin, Android, + also (obsolete) 4.3BSD, SunOS */ { - struct tabmntent *mntlist, *p; - struct mntent *mnt; - struct mount_entry *me; - - /* the third and fourth arguments could be used to filter mounts, - but Crays doesn't seem to have any mounts that we want to - remove. Specifically, automount create normal NFS mounts. - */ + FILE *fp; - if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0) - return NULL; - for (p = mntlist; p; p = p->next) +# if defined __linux__ || defined __ANDROID__ + /* Try parsing mountinfo first, as that make device IDs available. + Note we could use libmount routines to simplify this parsing a little + (and that code is in previous versions of this function), however + libmount depends on libselinux which pulls in many dependencies. */ + char const *mountinfo = "/proc/self/mountinfo"; + fp = fopen (mountinfo, "re"); + if (fp != NULL) { - mnt = p->ment; - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (mnt->mnt_fsname); - me->me_mountdir = xstrdup (mnt->mnt_dir); - me->me_type = xstrdup (mnt->mnt_type); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = -1; - *mtail = me; - mtail = &me->me_next; - } - freemntlist (mntlist); - } -#endif + char *line = NULL; + size_t buf_size = 0; -#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ - { - struct mntent *mnt; - char const *table = MOUNTED; - FILE *fp; + while (getline (&line, &buf_size, fp) != -1) + { + unsigned int devmaj, devmin; + int rc, mntroot_s; - fp = setmntent (table, "r"); - if (fp == NULL) - return NULL; + rc = sscanf(line, "%*u " /* id - discarded */ + "%*u " /* parent - discarded */ + "%u:%u " /* dev major:minor */ + "%n", /* mountroot (start) */ + &devmaj, &devmin, + &mntroot_s); - while ((mnt = getmntent (fp))) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (mnt->mnt_fsname); - me->me_mountdir = xstrdup (mnt->mnt_dir); - me->me_type = xstrdup (mnt->mnt_type); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, mnt); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = dev_from_mount_options (mnt->mnt_opts); + if (rc != 2 && rc != 3) /* 3 if %n included in count. */ + continue; - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; + /* find end of MNTROOT. */ + char *mntroot = line + mntroot_s; + char *blank = terminate_at_blank (mntroot); + if (! blank) + continue; + + /* find end of TARGET. */ + char *target = blank + 1; + blank = terminate_at_blank (target); + if (! blank) + continue; + + /* skip optional fields, terminated by " - " */ + char *dash = strstr (blank + 1, " - "); + if (! dash) + continue; + + /* advance past the " - " separator. */ + char *fstype = dash + 3; + blank = terminate_at_blank (fstype); + if (! blank) + continue; + + /* find end of SOURCE. */ + char *source = blank + 1; + if (! terminate_at_blank (source)) + continue; + + /* manipulate the sub-strings in place. */ + unescape_tab (source); + unescape_tab (target); + unescape_tab (mntroot); + unescape_tab (fstype); + + me = xmalloc (sizeof *me); + + me->me_devname = xstrdup (source); + me->me_mountdir = xstrdup (target); + me->me_mntroot = xstrdup (mntroot); + me->me_type = xstrdup (fstype); + me->me_type_malloced = 1; + me->me_dev = makedev (devmaj, devmin); + /* we pass "false" for the "Bind" option as that's only + significant when the Fs_type is "none" which will not be + the case when parsing "/proc/self/mountinfo", and only + applies for static /etc/mtab files. */ + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, false); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + free (line); + + if (ferror (fp)) + { + int saved_errno = errno; + fclose (fp); + errno = saved_errno; + goto free_then_fail; + } + + if (fclose (fp) == EOF) + goto free_then_fail; } + else /* fallback to /proc/self/mounts (/etc/mtab). */ +# endif /* __linux __ || __ANDROID__ */ + { + struct mntent *mnt; + char const *table = MOUNTED; - if (endmntent (fp) == 0) - goto free_then_fail; + fp = setmntent (table, "r"); + if (fp == NULL) + return NULL; + + while ((mnt = getmntent (fp))) + { + bool bind = hasmntopt (mnt, "bind"); + + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (mnt->mnt_fsname); + me->me_mountdir = xstrdup (mnt->mnt_dir); + me->me_mntroot = NULL; + me->me_type = xstrdup (mnt->mnt_type); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type, bind); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = dev_from_mount_options (mnt->mnt_opts); + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + if (endmntent (fp) == 0) + goto free_then_fail; + } } #endif /* MOUNTED_GETMNTENT1. */ -#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ +#ifdef MOUNTED_GETMNTINFO /* Mac OS X, FreeBSD, OpenBSD, also (obsolete) 4.4BSD */ { struct statfs *fsp; int entries; @@ -472,6 +609,7 @@ read_file_system_list (bool need_fs_type) me = xmalloc (sizeof *me); me->me_devname = xstrdup (fsp->f_mntfromname); me->me_mountdir = xstrdup (fsp->f_mntonname); + me->me_mntroot = NULL; me->me_type = fs_type; me->me_type_malloced = 0; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); @@ -485,7 +623,7 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_GETMNTINFO */ -#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ +#ifdef MOUNTED_GETMNTINFO2 /* NetBSD, Minix */ { struct statvfs *fsp; int entries; @@ -498,6 +636,7 @@ read_file_system_list (bool need_fs_type) me = xmalloc (sizeof *me); me->me_devname = xstrdup (fsp->f_mntfromname); me->me_mountdir = xstrdup (fsp->f_mntonname); + me->me_mntroot = NULL; me->me_type = xstrdup (fsp->f_fstypename); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); @@ -511,35 +650,7 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_GETMNTINFO2 */ -#ifdef MOUNTED_GETMNT /* Ultrix. */ - { - int offset = 0; - int val; - struct fs_data fsd; - - while (errno = 0, - 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, - (char *) 0))) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (fsd.fd_req.devname); - me->me_mountdir = xstrdup (fsd.fd_req.path); - me->me_type = gt_names[fsd.fd_req.fstype]; - me->me_type_malloced = 0; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = fsd.fd_req.dev; - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - if (val < 0) - goto free_then_fail; - } -#endif /* MOUNTED_GETMNT. */ - -#if defined MOUNTED_FS_STAT_DEV /* BeOS */ +#if defined MOUNTED_FS_STAT_DEV /* Haiku, also (obsolete) BeOS */ { /* The next_dev() and fs_stat_dev() system calls give the list of all file systems, including the information returned by statvfs() @@ -622,6 +733,7 @@ read_file_system_list (bool need_fs_type) me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name); + me->me_mntroot = NULL; me->me_type = xstrdup (fi.fsh_name); me->me_type_malloced = 1; me->me_dev = fi.dev; @@ -644,7 +756,7 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_FS_STAT_DEV */ -#if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */ +#if defined MOUNTED_GETFSSTAT /* OSF/1, also (obsolete) Apple Darwin 1.3 */ { int numsys, counter; size_t bufsize; @@ -671,6 +783,7 @@ read_file_system_list (bool need_fs_type) me = xmalloc (sizeof *me); me->me_devname = xstrdup (stats[counter].f_mntfromname); me->me_mountdir = xstrdup (stats[counter].f_mntonname); + me->me_mntroot = NULL; me->me_type = xstrdup (FS_TYPE (stats[counter])); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); @@ -686,31 +799,25 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_GETFSSTAT */ -#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */ +#if defined MOUNTED_FREAD_FSTYP /* (obsolete) SVR3 */ { struct mnttab mnt; char *table = "/etc/mnttab"; FILE *fp; - fp = fopen (table, "r"); + fp = fopen (table, "re"); if (fp == NULL) return NULL; while (fread (&mnt, sizeof mnt, 1, fp) > 0) { me = xmalloc (sizeof *me); -# ifdef GETFSTYP /* SVR3. */ me->me_devname = xstrdup (mnt.mt_dev); -# else - me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); - strcpy (me->me_devname, "/dev/"); - strcpy (me->me_devname + 5, mnt.mt_dev); -# endif me->me_mountdir = xstrdup (mnt.mt_filsys); + me->me_mntroot = NULL; me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ me->me_type = ""; me->me_type_malloced = 0; -# ifdef GETFSTYP /* SVR3. */ if (need_fs_type) { struct statfs fsd; @@ -723,7 +830,6 @@ read_file_system_list (bool need_fs_type) me->me_type_malloced = 1; } } -# endif me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); @@ -744,34 +850,57 @@ read_file_system_list (bool need_fs_type) if (fclose (fp) == EOF) goto free_then_fail; } -#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ +#endif /* MOUNTED_FREAD_FSTYP. */ -#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ +#ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */ { - struct mntent **mnttbl = getmnttbl (), **ent; - for (ent = mnttbl; *ent; ent++) + struct extmnttab mnt; + const char *table = MNTTAB; + FILE *fp; + int ret; + + /* No locking is needed, because the contents of /etc/mnttab is generated + by the kernel. */ + + errno = 0; + fp = fopen (table, "re"); + if (fp == NULL) + ret = errno; + else { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup ((*ent)->mt_resource); - me->me_mountdir = xstrdup ((*ent)->mt_directory); - me->me_type = xstrdup ((*ent)->mt_fstype); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + while ((ret = getextmntent (fp, &mnt, 1)) == 0) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (mnt.mnt_special); + me->me_mountdir = xstrdup (mnt.mnt_mountp); + me->me_mntroot = NULL; + me->me_type = xstrdup (mnt.mnt_fstype); + me->me_type_malloced = 1; + me->me_dummy = MNT_IGNORE (&mnt) != 0; + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = makedev (mnt.mnt_major, mnt.mnt_minor); - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; + /* Here ret = -1 means success, ret >= 0 means failure. */ + } + + if (0 <= ret) + { + errno = ret; + goto free_then_fail; } - endmnttbl (); } -#endif +#endif /* MOUNTED_GETEXTMNTENT */ -#ifdef MOUNTED_GETMNTENT2 /* SVR4. */ +#ifdef MOUNTED_GETMNTENT2 /* Solaris < 8, also (obsolete) SVR4 */ { struct mnttab mnt; - char *table = MNTTAB; + const char *table = MNTTAB; FILE *fp; int ret; int lockfd = -1; @@ -784,7 +913,7 @@ read_file_system_list (bool need_fs_type) # ifndef MNTTAB_LOCK # define MNTTAB_LOCK "/etc/.mnttab.lock" # endif - lockfd = open (MNTTAB_LOCK, O_RDONLY); + lockfd = open (MNTTAB_LOCK, O_RDONLY | O_CLOEXEC); if (0 <= lockfd) { struct flock flock; @@ -806,7 +935,7 @@ read_file_system_list (bool need_fs_type) # endif errno = 0; - fp = fopen (table, "r"); + fp = fopen (table, "re"); if (fp == NULL) ret = errno; else @@ -816,6 +945,7 @@ read_file_system_list (bool need_fs_type) me = xmalloc (sizeof *me); me->me_devname = xstrdup (mnt.mnt_special); me->me_mountdir = xstrdup (mnt.mnt_mountp); + me->me_mntroot = NULL; me->me_type = xstrdup (mnt.mnt_fstype); me->me_type_malloced = 1; me->me_dummy = MNT_IGNORE (&mnt) != 0; @@ -828,6 +958,7 @@ read_file_system_list (bool need_fs_type) } ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; + /* Here ret = -1 means success, ret >= 0 means failure. */ } if (0 <= lockfd && close (lockfd) != 0) @@ -841,26 +972,26 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_GETMNTENT2. */ -#ifdef MOUNTED_VMOUNT /* AIX. */ +#ifdef MOUNTED_VMOUNT /* AIX */ { int bufsize; - char *entries, *thisent; + void *entries; + char *thisent; struct vmount *vmp; int n_entries; int i; /* Ask how many bytes to allocate for the mounted file system info. */ - if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0) + entries = &bufsize; + if (mntctl (MCTL_QUERY, sizeof bufsize, entries) != 0) return NULL; entries = xmalloc (bufsize); /* Get the list of mounted file systems. */ - n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); + n_entries = mntctl (MCTL_QUERY, bufsize, entries); if (n_entries < 0) { - int saved_errno = errno; free (entries); - errno = saved_errno; return NULL; } @@ -892,6 +1023,7 @@ read_file_system_list (bool need_fs_type) vmp->vmt_data[VMT_OBJECT].vmt_off); } me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); + me->me_mntroot = NULL; me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); me->me_type_malloced = 1; options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; @@ -910,7 +1042,7 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_VMOUNT. */ -#ifdef MOUNTED_INTERIX_STATVFS +#ifdef MOUNTED_INTERIX_STATVFS /* Interix */ { DIR *dirp = opendir ("/dev/fs"); char node[9 + NAME_MAX]; @@ -924,6 +1056,8 @@ read_file_system_list (bool need_fs_type) struct dirent entry; struct dirent *result; + /* FIXME: readdir_r is planned to be withdrawn from POSIX and + marked obsolescent in glibc. Use readdir instead. */ if (readdir_r (dirp, &entry, &result) || result == NULL) break; @@ -935,6 +1069,7 @@ read_file_system_list (bool need_fs_type) me = xmalloc (sizeof *me); me->me_devname = xstrdup (dev.f_mntfromname); me->me_mountdir = xstrdup (dev.f_mntonname); + me->me_mntroot = NULL; me->me_type = xstrdup (dev.f_fstypename); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); @@ -946,6 +1081,7 @@ read_file_system_list (bool need_fs_type) mtail = &me->me_next; } } + closedir (dirp); } #endif /* MOUNTED_INTERIX_STATVFS */ @@ -953,7 +1089,7 @@ read_file_system_list (bool need_fs_type) return mount_list; - free_then_fail: + free_then_fail: _GL_UNUSED_LABEL; { int saved_errno = errno; *mtail = NULL; @@ -972,10 +1108,12 @@ read_file_system_list (bool need_fs_type) /* Free a mount entry as returned from read_file_system_list (). */ -void free_mount_entry (struct mount_entry *me) +void +free_mount_entry (struct mount_entry *me) { free (me->me_devname); free (me->me_mountdir); + free (me->me_mntroot); if (me->me_type_malloced) free (me->me_type); free (me); diff --git a/gl/mountlist.h b/gl/mountlist.h index 55877e23..6edac121 100644 --- a/gl/mountlist.h +++ b/gl/mountlist.h @@ -1,11 +1,11 @@ /* mountlist.h -- declarations for list of mounted file systems - Copyright (C) 1991-1992, 1998, 2000-2005, 2009-2013 Free Software + Copyright (C) 1991-1992, 1998, 2000-2005, 2009-2022 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 + 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, @@ -14,7 +14,7 @@ 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 . */ + along with this program. If not, see . */ #ifndef MOUNTLIST_H_ # define MOUNTLIST_H_ @@ -27,15 +27,18 @@ struct mount_entry { char *me_devname; /* Device node name, including "/dev/". */ char *me_mountdir; /* Mount point directory name. */ + char *me_mntroot; /* Directory on filesystem of device used */ + /* as root for the (bind) mount. */ char *me_type; /* "nfs", "4.2", etc. */ dev_t me_dev; /* Device number of me_mountdir. */ unsigned int me_dummy : 1; /* Nonzero for dummy file systems. */ - unsigned int me_remote : 1; /* Nonzero for remote fileystems. */ + unsigned int me_remote : 1; /* Nonzero for remote file systems. */ unsigned int me_type_malloced : 1; /* Nonzero if me_type was malloced. */ struct mount_entry *me_next; }; -struct mount_entry *read_file_system_list (bool need_fs_type); +struct mount_entry *read_file_system_list (bool need_fs_type) + _GL_ATTRIBUTE_MALLOC; void free_mount_entry (struct mount_entry *entry); #endif diff --git a/gl/msvc-inval.c b/gl/msvc-inval.c index 396031e4..d6651caa 100644 --- a/gl/msvc-inval.c +++ b/gl/msvc-inval.c @@ -1,18 +1,18 @@ /* Invalid parameter handler for MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/msvc-inval.h b/gl/msvc-inval.h index dcb0353d..1230b899 100644 --- a/gl/msvc-inval.h +++ b/gl/msvc-inval.h @@ -1,18 +1,18 @@ /* Invalid parameter handler for MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _MSVC_INVAL_H #define _MSVC_INVAL_H @@ -95,7 +95,7 @@ extern void gl_msvc_inval_ensure_handler (void); /* Gnulib can define its own status codes, as described in the page "Raising Software Exceptions" on microsoft.com - . + . Our status codes are composed of - 0xE0000000, mandatory for all user-defined status codes, - 0x474E550, a API identifier ("GNU"), @@ -106,7 +106,7 @@ extern void gl_msvc_inval_ensure_handler (void); # if defined _MSC_VER /* A compiler that supports __try/__except, as described in the page "try-except statement" on microsoft.com - . + . With __try/__except, we can use the multithread-safe exception handling. */ # ifdef __cplusplus diff --git a/gl/msvc-nothrow.c b/gl/msvc-nothrow.c index 8d65472a..aa069643 100644 --- a/gl/msvc-nothrow.c +++ b/gl/msvc-nothrow.c @@ -1,19 +1,19 @@ /* Wrappers that don't throw invalid parameter notifications with MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -24,7 +24,9 @@ #define WIN32_LEAN_AND_MEAN #include -#include "msvc-inval.h" +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +#endif #undef _get_osfhandle diff --git a/gl/msvc-nothrow.h b/gl/msvc-nothrow.h index 5f521813..53451557 100644 --- a/gl/msvc-nothrow.h +++ b/gl/msvc-nothrow.h @@ -1,19 +1,19 @@ /* Wrappers that don't throw invalid parameter notifications with MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _MSVC_NOTHROW_H #define _MSVC_NOTHROW_H @@ -25,7 +25,7 @@ This file defines wrappers that turn such an invalid parameter notification into an error code. */ -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +#if defined _WIN32 && ! defined __CYGWIN__ /* Get original declaration of _get_osfhandle. */ # include diff --git a/gl/netdb.in.h b/gl/netdb.in.h index 0da1800a..e05cf4b1 100644 --- a/gl/netdb.in.h +++ b/gl/netdb.in.h @@ -1,19 +1,19 @@ /* Provide a netdb.h header file for systems lacking it (read: MinGW). - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 Free Software Foundation, Inc. Written by Simon Josefsson. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This file is supposed to be used on platforms that lack . It is intended to provide definitions and prototypes needed by an @@ -158,33 +158,61 @@ struct addrinfo # endif # endif -# if !@HAVE_DECL_GETADDRINFO@ /* Translate name of a service location and/or a service name to set of socket addresses. - For more details, see the POSIX:2001 specification - . */ + For more details, see the POSIX:2008 specification + . */ +# if @REPLACE_GETADDRINFO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getaddrinfo +# define getaddrinfo rpl_getaddrinfo +# endif +_GL_FUNCDECL_RPL (getaddrinfo, int, + (const char *restrict nodename, + const char *restrict servname, + const struct addrinfo *restrict hints, + struct addrinfo **restrict res) + _GL_ARG_NONNULL ((4))); +_GL_CXXALIAS_RPL (getaddrinfo, int, + (const char *restrict nodename, + const char *restrict servname, + const struct addrinfo *restrict hints, + struct addrinfo **restrict res)); +# else +# if !@HAVE_DECL_GETADDRINFO@ _GL_FUNCDECL_SYS (getaddrinfo, int, (const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints, struct addrinfo **restrict res) _GL_ARG_NONNULL ((4))); -# endif +# endif _GL_CXXALIAS_SYS (getaddrinfo, int, (const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints, struct addrinfo **restrict res)); +# endif _GL_CXXALIASWARN (getaddrinfo); -# if !@HAVE_DECL_FREEADDRINFO@ /* Free 'addrinfo' structure AI including associated storage. - For more details, see the POSIX:2001 specification - . */ + For more details, see the POSIX:2008 specification + . */ +# if @REPLACE_GETADDRINFO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef freeaddrinfo +# define freeaddrinfo rpl_freeaddrinfo +# endif +_GL_FUNCDECL_RPL (freeaddrinfo, void, (struct addrinfo *ai) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (freeaddrinfo, void, (struct addrinfo *ai)); +# else +# if !@HAVE_DECL_FREEADDRINFO@ _GL_FUNCDECL_SYS (freeaddrinfo, void, (struct addrinfo *ai) _GL_ARG_NONNULL ((1))); -# endif +# endif _GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai)); +# endif _GL_CXXALIASWARN (freeaddrinfo); # if @REPLACE_GAI_STRERROR@ @@ -197,18 +225,20 @@ _GL_CXXALIAS_RPL (gai_strerror, const char *, (int ecode)); # else # if !@HAVE_DECL_GAI_STRERROR@ /* Convert error return from getaddrinfo() to a string. - For more details, see the POSIX:2001 specification - . */ + For more details, see the POSIX:2008 specification + . */ _GL_FUNCDECL_SYS (gai_strerror, const char *, (int ecode)); # endif _GL_CXXALIAS_SYS (gai_strerror, const char *, (int ecode)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (gai_strerror); +# endif # if !@HAVE_DECL_GETNAMEINFO@ /* Convert socket address to printable node and service names. - For more details, see the POSIX:2001 specification - . */ + For more details, see the POSIX:2008 specification + . */ _GL_FUNCDECL_SYS (getnameinfo, int, (const struct sockaddr *restrict sa, socklen_t salen, char *restrict node, socklen_t nodelen, diff --git a/gl/netinet_in.in.h b/gl/netinet_in.in.h index b456c4f9..e23807ca 100644 --- a/gl/netinet_in.in.h +++ b/gl/netinet_in.in.h @@ -1,18 +1,18 @@ /* Substitute for . - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_NETINET_IN_H diff --git a/gl/nl_langinfo-lock.c b/gl/nl_langinfo-lock.c new file mode 100644 index 00000000..c36882d5 --- /dev/null +++ b/gl/nl_langinfo-lock.c @@ -0,0 +1,150 @@ +/* Return the internal lock used by nl_langinfo. + Copyright (C) 2019-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019-2020. */ + +#include + +/* When it is known that the gl_get_nl_langinfo_lock function is defined + by a dependency library, it should not be defined here. */ +#if OMIT_NL_LANGINFO_LOCK + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#else + +/* This file defines the internal lock used by nl_langinfo. + It is a separate compilation unit, so that only one copy of it is + present when linking statically. */ + +/* Prohibit renaming this symbol. */ +# undef gl_get_nl_langinfo_lock + +/* Macro for exporting a symbol (function, not variable) defined in this file, + when compiled into a shared library. */ +# ifndef DLL_EXPORTED +# if HAVE_VISIBILITY + /* Override the effect of the compiler option '-fvisibility=hidden'. */ +# define DLL_EXPORTED __attribute__((__visibility__("default"))) +# elif defined _WIN32 || defined __CYGWIN__ +# define DLL_EXPORTED __declspec(dllexport) +# else +# define DLL_EXPORTED +# endif +# endif + +# if defined _WIN32 && !defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# include "windows-initguard.h" + +/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *', + because the latter is not guaranteed to be a stable ABI in the future. */ + +/* Make sure the function gets exported from DLLs. */ +DLL_EXPORTED CRITICAL_SECTION *gl_get_nl_langinfo_lock (void); + +static glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT; +static CRITICAL_SECTION lock; + +/* Returns the internal lock used by nl_langinfo. */ +CRITICAL_SECTION * +gl_get_nl_langinfo_lock (void) +{ + if (!guard.done) + { + if (InterlockedIncrement (&guard.started) == 0) + { + /* This thread is the first one to need the lock. Initialize it. */ + InitializeCriticalSection (&lock); + guard.done = 1; + } + else + { + /* Don't let guard.started grow and wrap around. */ + InterlockedDecrement (&guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!guard.done) + Sleep (0); + } + } + return &lock; +} + +# elif HAVE_PTHREAD_API + +# include + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Make sure the function gets exported from shared libraries. */ +DLL_EXPORTED pthread_mutex_t *gl_get_nl_langinfo_lock (void); + +/* Returns the internal lock used by nl_langinfo. */ +pthread_mutex_t * +gl_get_nl_langinfo_lock (void) +{ + return &mutex; +} + +# elif HAVE_THREADS_H + +# include +# include + +static int volatile init_needed = 1; +static once_flag init_once = ONCE_FLAG_INIT; +static mtx_t mutex; + +static void +atomic_init (void) +{ + if (mtx_init (&mutex, mtx_plain) != thrd_success) + abort (); + init_needed = 0; +} + +/* Make sure the function gets exported from shared libraries. */ +DLL_EXPORTED mtx_t *gl_get_nl_langinfo_lock (void); + +/* Returns the internal lock used by nl_langinfo. */ +mtx_t * +gl_get_nl_langinfo_lock (void) +{ + if (init_needed) + call_once (&init_once, atomic_init); + return &mutex; +} + +# endif + +# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER +/* Make sure the '__declspec(dllimport)' in nl_langinfo.c does not cause + a link failure when no DLLs are involved. */ +# if defined _WIN64 || defined _LP64 +# define IMP(x) __imp_##x +# else +# define IMP(x) _imp__##x +# endif +void * IMP(gl_get_nl_langinfo_lock) = &gl_get_nl_langinfo_lock; +# endif + +#endif diff --git a/gl/nl_langinfo.c b/gl/nl_langinfo.c index 771c9533..3fa47822 100644 --- a/gl/nl_langinfo.c +++ b/gl/nl_langinfo.c @@ -1,34 +1,278 @@ /* nl_langinfo() replacement: query locale dependent information. - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include /* Specification. */ #include +#include +#include +#include +#if defined _WIN32 && ! defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include +# include +#endif + +#if REPLACE_NL_LANGINFO && !NL_LANGINFO_MTSAFE +# if defined _WIN32 && !defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# elif HAVE_PTHREAD_API + +# include +# if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS +# include +# pragma weak thrd_exit +# define c11_threads_in_use() (thrd_exit != NULL) +# else +# define c11_threads_in_use() 0 +# endif + +# elif HAVE_THREADS_H + +# include + +# endif +#endif + +/* nl_langinfo() must be multithread-safe. To achieve this without using + thread-local storage: + 1. We use a specific static buffer for each possible argument. + So that different threads can call nl_langinfo with different arguments, + without interfering. + 2. We use a simple strcpy or memcpy to fill this static buffer. Filling it + through, for example, strcpy + strcat would not be guaranteed to leave + the buffer's contents intact if another thread is currently accessing + it. If necessary, the contents is first assembled in a stack-allocated + buffer. */ + +#if !REPLACE_NL_LANGINFO || GNULIB_defined_CODESET +/* Return the codeset of the current locale, if this is easily deducible. + Otherwise, return "". */ +static char * +ctype_codeset (void) +{ + static char result[2 + 10 + 1]; + char buf[2 + 10 + 1]; + char locale[SETLOCALE_NULL_MAX]; + char *codeset; + size_t codesetlen; + + if (setlocale_null_r (LC_CTYPE, locale, sizeof (locale))) + locale[0] = '\0'; + + codeset = buf; + codeset[0] = '\0'; + + if (locale[0]) + { + /* If the locale name contains an encoding after the dot, return it. */ + char *dot = strchr (locale, '.'); + + if (dot) + { + /* Look for the possible @... trailer and remove it, if any. */ + char *codeset_start = dot + 1; + char const *modifier = strchr (codeset_start, '@'); + + if (! modifier) + codeset = codeset_start; + else + { + codesetlen = modifier - codeset_start; + if (codesetlen < sizeof buf) + { + codeset = memcpy (buf, codeset_start, codesetlen); + codeset[codesetlen] = '\0'; + } + } + } + } + +# if defined _WIN32 && ! defined __CYGWIN__ + /* If setlocale is successful, it returns the number of the + codepage, as a string. Otherwise, fall back on Windows API + GetACP, which returns the locale's codepage as a number (although + this doesn't change according to what the 'setlocale' call specified). + Either way, prepend "CP" to make it a valid codeset name. */ + codesetlen = strlen (codeset); + if (0 < codesetlen && codesetlen < sizeof buf - 2) + memmove (buf + 2, codeset, codesetlen + 1); + else + sprintf (buf + 2, "%u", GetACP ()); + /* For a locale name such as "French_France.65001", in Windows 10, + setlocale now returns "French_France.utf8" instead. */ + if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0) + return (char *) "UTF-8"; + else + { + memcpy (buf, "CP", 2); + strcpy (result, buf); + return result; + } +# else + strcpy (result, codeset); + return result; +#endif +} +#endif + + #if REPLACE_NL_LANGINFO /* Override nl_langinfo with support for added nl_item values. */ -# include -# include - # undef nl_langinfo +/* Without locking, on Solaris 11.3, test-nl_langinfo-mt fails, with message + "thread5 disturbed by threadN!", even when threadN invokes only + nl_langinfo (CODESET); + nl_langinfo (CRNCYSTR); + Similarly on Solaris 10. */ + +# if !NL_LANGINFO_MTSAFE /* Solaris */ + +# define ITEMS (MAXSTRMSG + 1) +# define MAX_RESULT_LEN 80 + +static char * +nl_langinfo_unlocked (nl_item item) +{ + static char result[ITEMS][MAX_RESULT_LEN]; + + /* The result of nl_langinfo is in storage that can be overwritten by + other calls to nl_langinfo. */ + char *tmp = nl_langinfo (item); + if (item >= 0 && item < ITEMS && tmp != NULL) + { + size_t tmp_len = strlen (tmp); + if (tmp_len < MAX_RESULT_LEN) + strcpy (result[item], tmp); + else + { + /* Produce a truncated result. Oh well... */ + result[item][MAX_RESULT_LEN - 1] = '\0'; + memcpy (result[item], tmp, MAX_RESULT_LEN - 1); + } + return result[item]; + } + else + return tmp; +} + +/* Use a lock, so that no two threads can invoke nl_langinfo_unlocked + at the same time. */ + +/* Prohibit renaming this symbol. */ +# undef gl_get_nl_langinfo_lock + +# if defined _WIN32 && !defined __CYGWIN__ + +extern __declspec(dllimport) CRITICAL_SECTION *gl_get_nl_langinfo_lock (void); + +static char * +nl_langinfo_with_lock (nl_item item) +{ + CRITICAL_SECTION *lock = gl_get_nl_langinfo_lock (); + char *ret; + + EnterCriticalSection (lock); + ret = nl_langinfo_unlocked (item); + LeaveCriticalSection (lock); + + return ret; +} + +# elif HAVE_PTHREAD_API + +extern +# if defined _WIN32 || defined __CYGWIN__ + __declspec(dllimport) +# endif + pthread_mutex_t *gl_get_nl_langinfo_lock (void); + +# if HAVE_WEAK_SYMBOLS /* musl libc, FreeBSD, NetBSD, OpenBSD, Haiku */ + + /* Avoid the need to link with '-lpthread'. */ +# pragma weak pthread_mutex_lock +# pragma weak pthread_mutex_unlock + + /* Determine whether libpthread is in use. */ +# pragma weak pthread_mutexattr_gettype + /* See the comments in lock.h. */ +# define pthread_in_use() \ + (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) + +# else +# define pthread_in_use() 1 +# endif + +static char * +nl_langinfo_with_lock (nl_item item) +{ + if (pthread_in_use()) + { + pthread_mutex_t *lock = gl_get_nl_langinfo_lock (); + char *ret; + + if (pthread_mutex_lock (lock)) + abort (); + ret = nl_langinfo_unlocked (item); + if (pthread_mutex_unlock (lock)) + abort (); + + return ret; + } + else + return nl_langinfo_unlocked (item); +} + +# elif HAVE_THREADS_H + +extern mtx_t *gl_get_nl_langinfo_lock (void); + +static char * +nl_langinfo_with_lock (nl_item item) +{ + mtx_t *lock = gl_get_nl_langinfo_lock (); + char *ret; + + if (mtx_lock (lock) != thrd_success) + abort (); + ret = nl_langinfo_unlocked (item); + if (mtx_unlock (lock) != thrd_success) + abort (); + + return ret; +} + +# endif + +# else + +/* On other platforms, no lock is needed. */ +# define nl_langinfo_with_lock nl_langinfo + +# endif + char * rpl_nl_langinfo (nl_item item) { @@ -36,47 +280,36 @@ rpl_nl_langinfo (nl_item item) { # if GNULIB_defined_CODESET case CODESET: - { - const char *locale; - static char buf[2 + 10 + 1]; - - locale = setlocale (LC_CTYPE, NULL); - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return - it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - } - return ""; - } + return ctype_codeset (); # endif # if GNULIB_defined_T_FMT_AMPM case T_FMT_AMPM: - return "%I:%M:%S %p"; + return (char *) "%I:%M:%S %p"; +# endif +# if GNULIB_defined_ALTMON + case ALTMON_1: + case ALTMON_2: + case ALTMON_3: + case ALTMON_4: + case ALTMON_5: + case ALTMON_6: + case ALTMON_7: + case ALTMON_8: + case ALTMON_9: + case ALTMON_10: + case ALTMON_11: + case ALTMON_12: + /* We don't ship the appropriate localizations with gnulib. Therefore, + treat ALTMON_i like MON_i. */ + item = item - ALTMON_1 + MON_1; + break; # endif # if GNULIB_defined_ERA case ERA: /* The format is not standardized. In glibc it is a sequence of strings of the form "direction:offset:start_date:end_date:era_name:era_format" with an empty string at the end. */ - return ""; + return (char *) ""; case ERA_D_FMT: /* The %Ex conversion in strftime behaves like %x if the locale does not have an alternative time format. */ @@ -95,176 +328,244 @@ rpl_nl_langinfo (nl_item item) case ALT_DIGITS: /* The format is not standardized. In glibc it is a sequence of 10 strings, appended in memory. */ - return "\0\0\0\0\0\0\0\0\0\0"; + return (char *) "\0\0\0\0\0\0\0\0\0\0"; # endif # if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS case YESEXPR: - return "^[yY]"; + return (char *) "^[yY]"; case NOEXPR: - return "^[nN]"; + return (char *) "^[nN]"; # endif default: break; } - return nl_langinfo (item); + return nl_langinfo_with_lock (item); } #else -/* Provide nl_langinfo from scratch. */ - -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Provide nl_langinfo from scratch, either for native MS-Windows, or + for old Unix platforms without locales, such as Linux libc5 or + BeOS. */ -/* Native Windows platforms. */ - -# define WIN32_LEAN_AND_MEAN /* avoid including junk */ -# include - -# include - -# else - -/* An old Unix platform without locales, such as Linux libc5 or BeOS. */ - -# endif - -# include +# include char * nl_langinfo (nl_item item) { + char buf[100]; + struct tm tmm = { 0 }; + switch (item) { /* nl_langinfo items of the LC_CTYPE category */ case CODESET: -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ { - static char buf[2 + 10 + 1]; - - /* The Windows API has a function returning the locale's codepage as - a number. */ - sprintf (buf, "CP%u", GetACP ()); - return buf; + char *codeset = ctype_codeset (); + if (*codeset) + return codeset; } -# elif defined __BEOS__ - return "UTF-8"; +# ifdef __BEOS__ + return (char *) "UTF-8"; # else - return "ISO-8859-1"; + return (char *) "ISO-8859-1"; # endif /* nl_langinfo items of the LC_NUMERIC category */ case RADIXCHAR: return localeconv () ->decimal_point; case THOUSEP: return localeconv () ->thousands_sep; +# ifdef GROUPING + case GROUPING: + return localeconv () ->grouping; +# endif /* nl_langinfo items of the LC_TIME category. TODO: Really use the locale. */ case D_T_FMT: case ERA_D_T_FMT: - return "%a %b %e %H:%M:%S %Y"; + return (char *) "%a %b %e %H:%M:%S %Y"; case D_FMT: case ERA_D_FMT: - return "%m/%d/%y"; + return (char *) "%m/%d/%y"; case T_FMT: case ERA_T_FMT: - return "%H:%M:%S"; + return (char *) "%H:%M:%S"; case T_FMT_AMPM: - return "%I:%M:%S %p"; + return (char *) "%I:%M:%S %p"; case AM_STR: - return "AM"; + { + static char result[80]; + if (!strftime (buf, sizeof result, "%p", &tmm)) + return (char *) "AM"; + strcpy (result, buf); + return result; + } case PM_STR: - return "PM"; + { + static char result[80]; + tmm.tm_hour = 12; + if (!strftime (buf, sizeof result, "%p", &tmm)) + return (char *) "PM"; + strcpy (result, buf); + return result; + } case DAY_1: - return "Sunday"; case DAY_2: - return "Monday"; case DAY_3: - return "Tuesday"; case DAY_4: - return "Wednesday"; case DAY_5: - return "Thursday"; case DAY_6: - return "Friday"; case DAY_7: - return "Saturday"; + { + static char result[7][50]; + static char const days[][sizeof "Wednesday"] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday" + }; + tmm.tm_wday = item - DAY_1; + if (!strftime (buf, sizeof result[0], "%A", &tmm)) + return (char *) days[item - DAY_1]; + strcpy (result[item - DAY_1], buf); + return result[item - DAY_1]; + } case ABDAY_1: - return "Sun"; case ABDAY_2: - return "Mon"; case ABDAY_3: - return "Tue"; case ABDAY_4: - return "Wed"; case ABDAY_5: - return "Thu"; case ABDAY_6: - return "Fri"; case ABDAY_7: - return "Sat"; - case MON_1: - return "January"; - case MON_2: - return "February"; - case MON_3: - return "March"; - case MON_4: - return "April"; - case MON_5: - return "May"; - case MON_6: - return "June"; - case MON_7: - return "July"; - case MON_8: - return "August"; - case MON_9: - return "September"; - case MON_10: - return "October"; - case MON_11: - return "November"; - case MON_12: - return "December"; + { + static char result[7][30]; + static char const abdays[][sizeof "Sun"] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + tmm.tm_wday = item - ABDAY_1; + if (!strftime (buf, sizeof result[0], "%a", &tmm)) + return (char *) abdays[item - ABDAY_1]; + strcpy (result[item - ABDAY_1], buf); + return result[item - ABDAY_1]; + } + { + static char const months[][sizeof "September"] = { + "January", "February", "March", "April", "May", "June", "July", + "September", "October", "November", "December" + }; + case MON_1: + case MON_2: + case MON_3: + case MON_4: + case MON_5: + case MON_6: + case MON_7: + case MON_8: + case MON_9: + case MON_10: + case MON_11: + case MON_12: + { + static char result[12][50]; + tmm.tm_mon = item - MON_1; + if (!strftime (buf, sizeof result[0], "%B", &tmm)) + return (char *) months[item - MON_1]; + strcpy (result[item - MON_1], buf); + return result[item - MON_1]; + } + case ALTMON_1: + case ALTMON_2: + case ALTMON_3: + case ALTMON_4: + case ALTMON_5: + case ALTMON_6: + case ALTMON_7: + case ALTMON_8: + case ALTMON_9: + case ALTMON_10: + case ALTMON_11: + case ALTMON_12: + { + static char result[12][50]; + tmm.tm_mon = item - ALTMON_1; + /* The platforms without nl_langinfo() don't support strftime with + %OB. We don't even need to try. */ + #if 0 + if (!strftime (buf, sizeof result[0], "%OB", &tmm)) + #endif + if (!strftime (buf, sizeof result[0], "%B", &tmm)) + return (char *) months[item - ALTMON_1]; + strcpy (result[item - ALTMON_1], buf); + return result[item - ALTMON_1]; + } + } case ABMON_1: - return "Jan"; case ABMON_2: - return "Feb"; case ABMON_3: - return "Mar"; case ABMON_4: - return "Apr"; case ABMON_5: - return "May"; case ABMON_6: - return "Jun"; case ABMON_7: - return "Jul"; case ABMON_8: - return "Aug"; case ABMON_9: - return "Sep"; case ABMON_10: - return "Oct"; case ABMON_11: - return "Nov"; case ABMON_12: - return "Dec"; + { + static char result[12][30]; + static char const abmonths[][sizeof "Jan"] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", + "Sep", "Oct", "Nov", "Dec" + }; + tmm.tm_mon = item - ABMON_1; + if (!strftime (buf, sizeof result[0], "%b", &tmm)) + return (char *) abmonths[item - ABMON_1]; + strcpy (result[item - ABMON_1], buf); + return result[item - ABMON_1]; + } case ERA: - return ""; + return (char *) ""; case ALT_DIGITS: - return "\0\0\0\0\0\0\0\0\0\0"; - /* nl_langinfo items of the LC_MONETARY category - TODO: Really use the locale. */ + return (char *) "\0\0\0\0\0\0\0\0\0\0"; + /* nl_langinfo items of the LC_MONETARY category. */ case CRNCYSTR: - return "-"; + return localeconv () ->currency_symbol; +# ifdef INT_CURR_SYMBOL + case INT_CURR_SYMBOL: + return localeconv () ->int_curr_symbol; + case MON_DECIMAL_POINT: + return localeconv () ->mon_decimal_point; + case MON_THOUSANDS_SEP: + return localeconv () ->mon_thousands_sep; + case MON_GROUPING: + return localeconv () ->mon_grouping; + case POSITIVE_SIGN: + return localeconv () ->positive_sign; + case NEGATIVE_SIGN: + return localeconv () ->negative_sign; + case FRAC_DIGITS: + return & localeconv () ->frac_digits; + case INT_FRAC_DIGITS: + return & localeconv () ->int_frac_digits; + case P_CS_PRECEDES: + return & localeconv () ->p_cs_precedes; + case N_CS_PRECEDES: + return & localeconv () ->n_cs_precedes; + case P_SEP_BY_SPACE: + return & localeconv () ->p_sep_by_space; + case N_SEP_BY_SPACE: + return & localeconv () ->n_sep_by_space; + case P_SIGN_POSN: + return & localeconv () ->p_sign_posn; + case N_SIGN_POSN: + return & localeconv () ->n_sign_posn; +# endif /* nl_langinfo items of the LC_MESSAGES category TODO: Really use the locale. */ case YESEXPR: - return "^[yY]"; + return (char *) "^[yY]"; case NOEXPR: - return "^[nN]"; + return (char *) "^[nN]"; default: - return ""; + return (char *) ""; } } diff --git a/gl/open.c b/gl/open.c new file mode 100644 index 00000000..170bff10 --- /dev/null +++ b/gl/open.c @@ -0,0 +1,209 @@ +/* Open a descriptor to a file. + Copyright (C) 2007-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2007. */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_open doesn't recurse to + rpl_open. */ +#define __need_system_fcntl_h +#include + +/* Get the original definition of open. It might be defined as a macro. */ +#include +#include +#undef __need_system_fcntl_h + +static int +orig_open (const char *filename, int flags, mode_t mode) +{ +#if defined _WIN32 && !defined __CYGWIN__ + return _open (filename, flags, mode); +#else + return open (filename, flags, mode); +#endif +} + +/* Specification. */ +/* Write "fcntl.h" here, not , otherwise OSF/1 5.1 DTK cc eliminates + this include because of the preliminary #include above. */ +#include "fcntl.h" + +#include "cloexec.h" + +#include +#include +#include +#include +#include +#include + +#ifndef REPLACE_OPEN_DIRECTORY +# define REPLACE_OPEN_DIRECTORY 0 +#endif + +int +open (const char *filename, int flags, ...) +{ + /* 0 = unknown, 1 = yes, -1 = no. */ +#if GNULIB_defined_O_CLOEXEC + int have_cloexec = -1; +#else + static int have_cloexec; +#endif + + mode_t mode; + int fd; + + mode = 0; + if (flags & O_CREAT) + { + va_list arg; + va_start (arg, flags); + + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (arg, PROMOTED_MODE_T); + + va_end (arg); + } + +#if GNULIB_defined_O_NONBLOCK + /* The only known platform that lacks O_NONBLOCK is mingw, but it + also lacks named pipes and Unix sockets, which are the only two + file types that require non-blocking handling in open(). + Therefore, it is safe to ignore O_NONBLOCK here. It is handy + that mingw also lacks openat(), so that is also covered here. */ + flags &= ~O_NONBLOCK; +#endif + +#if defined _WIN32 && ! defined __CYGWIN__ + if (strcmp (filename, "/dev/null") == 0) + filename = "NUL"; +#endif + +#if OPEN_TRAILING_SLASH_BUG + /* Fail if one of O_CREAT, O_WRONLY, O_RDWR is specified and the filename + ends in a slash, as POSIX says such a filename must name a directory + : + "A pathname that contains at least one non- character and that + ends with one or more trailing characters shall not be resolved + successfully unless the last pathname component before the trailing + characters names an existing directory" + If the named file already exists as a directory, then + - if O_CREAT is specified, open() must fail because of the semantics + of O_CREAT, + - if O_WRONLY or O_RDWR is specified, open() must fail because POSIX + + says that it fails with errno = EISDIR in this case. + If the named file does not exist or does not name a directory, then + - if O_CREAT is specified, open() must fail since open() cannot create + directories, + - if O_WRONLY or O_RDWR is specified, open() must fail because the + file does not contain a '.' directory. */ + if ((flags & O_CREAT) + || (flags & O_ACCMODE) == O_RDWR + || (flags & O_ACCMODE) == O_WRONLY) + { + size_t len = strlen (filename); + if (len > 0 && filename[len - 1] == '/') + { + errno = EISDIR; + return -1; + } + } +#endif + + fd = orig_open (filename, + flags & ~(have_cloexec < 0 ? O_CLOEXEC : 0), mode); + + if (flags & O_CLOEXEC) + { + if (! have_cloexec) + { + if (0 <= fd) + have_cloexec = 1; + else if (errno == EINVAL) + { + fd = orig_open (filename, flags & ~O_CLOEXEC, mode); + have_cloexec = -1; + } + } + if (have_cloexec < 0 && 0 <= fd) + set_cloexec_flag (fd, true); + } + + +#if REPLACE_FCHDIR + /* Implementing fchdir and fdopendir requires the ability to open a + directory file descriptor. If open doesn't support that (as on + mingw), we use a dummy file that behaves the same as directories + on Linux (ie. always reports EOF on attempts to read()), and + override fstat() in fchdir.c to hide the fact that we have a + dummy. */ + if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES + && ((flags & O_ACCMODE) == O_RDONLY + || (O_SEARCH != O_RDONLY && (flags & O_ACCMODE) == O_SEARCH))) + { + struct stat statbuf; + if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) + { + /* Maximum recursion depth of 1. */ + fd = open ("/dev/null", flags, mode); + if (0 <= fd) + fd = _gl_register_fd (fd, filename); + } + else + errno = EACCES; + } +#endif + +#if OPEN_TRAILING_SLASH_BUG + /* If the filename ends in a slash and fd does not refer to a directory, + then fail. + Rationale: POSIX says such a filename must name a directory + : + "A pathname that contains at least one non- character and that + ends with one or more trailing characters shall not be resolved + successfully unless the last pathname component before the trailing + characters names an existing directory" + If the named file without the slash is not a directory, open() must fail + with ENOTDIR. */ + if (fd >= 0) + { + /* We know len is positive, since open did not fail with ENOENT. */ + size_t len = strlen (filename); + if (filename[len - 1] == '/') + { + struct stat statbuf; + + if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) + { + close (fd); + errno = ENOTDIR; + return -1; + } + } + } +#endif + +#if REPLACE_FCHDIR + if (!REPLACE_OPEN_DIRECTORY && 0 <= fd) + fd = _gl_register_fd (fd, filename); +#endif + + return fd; +} diff --git a/gl/pathmax.h b/gl/pathmax.h new file mode 100644 index 00000000..19b93d7e --- /dev/null +++ b/gl/pathmax.h @@ -0,0 +1,83 @@ +/* Define PATH_MAX somehow. Requires sys/types.h. + Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2022 Free Software + Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _PATHMAX_H +# define _PATHMAX_H + +/* POSIX:2008 defines PATH_MAX to be the maximum number of bytes in a filename, + including the terminating NUL byte. + + PATH_MAX is not defined on systems which have no limit on filename length, + such as GNU/Hurd. + + This file does *not* define PATH_MAX always. Programs that use this file + can handle the GNU/Hurd case in several ways: + - Either with a package-wide handling, or with a per-file handling, + - Either through a + #ifdef PATH_MAX + or through a fallback like + #ifndef PATH_MAX + # define PATH_MAX 8192 + #endif + or through a fallback like + #ifndef PATH_MAX + # define PATH_MAX pathconf ("/", _PC_PATH_MAX) + #endif + */ + +# include + +# include + +# ifndef _POSIX_PATH_MAX +# define _POSIX_PATH_MAX 256 +# endif + +/* Don't include sys/param.h if it already has been. */ +# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN +# include +# endif + +# if !defined PATH_MAX && defined MAXPATHLEN +# define PATH_MAX MAXPATHLEN +# endif + +# ifdef __hpux +/* On HP-UX, PATH_MAX designates the maximum number of bytes in a filename, + *not* including the terminating NUL byte, and is set to 1023. + Additionally, when _XOPEN_SOURCE is defined to 500 or more, PATH_MAX is + not defined at all any more. */ +# undef PATH_MAX +# define PATH_MAX 1024 +# endif + +# if defined _WIN32 && ! defined __CYGWIN__ +/* The page "Naming Files, Paths, and Namespaces" on msdn.microsoft.com, + section "Maximum Path Length Limitation", + + explains that the maximum size of a filename, including the terminating + NUL byte, is 260 = 3 + 256 + 1. + This is the same value as + - FILENAME_MAX in , + - _MAX_PATH in , + - MAX_PATH in . + Undefine the original value, because mingw's gets it wrong. */ +# undef PATH_MAX +# define PATH_MAX 260 +# endif + +#endif /* _PATHMAX_H */ diff --git a/gl/printf-args.c b/gl/printf-args.c index c27e6bc6..669c24a4 100644 --- a/gl/printf-args.c +++ b/gl/printf-args.c @@ -1,19 +1,19 @@ /* Decomposed printf argument list. - Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2013 Free Software + Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This file can be parametrized with the following macros: ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. @@ -65,14 +65,12 @@ PRINTF_FETCHARGS (va_list args, arguments *a) case TYPE_ULONGINT: ap->a.a_ulongint = va_arg (args, unsigned long int); break; -#if HAVE_LONG_LONG_INT case TYPE_LONGLONGINT: ap->a.a_longlongint = va_arg (args, long long int); break; case TYPE_ULONGLONGINT: ap->a.a_ulonglongint = va_arg (args, unsigned long long int); break; -#endif case TYPE_DOUBLE: ap->a.a_double = va_arg (args, double); break; @@ -135,11 +133,9 @@ PRINTF_FETCHARGS (va_list args, arguments *a) case TYPE_COUNT_LONGINT_POINTER: ap->a.a_count_longint_pointer = va_arg (args, long int *); break; -#if HAVE_LONG_LONG_INT case TYPE_COUNT_LONGLONGINT_POINTER: ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); break; -#endif #if ENABLE_UNISTDIO /* The unistdio extensions. */ case TYPE_U8_STRING: diff --git a/gl/printf-args.h b/gl/printf-args.h index 2a9c2a3f..553fe961 100644 --- a/gl/printf-args.h +++ b/gl/printf-args.h @@ -1,19 +1,19 @@ /* Decomposed printf argument list. - Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2013 Free Software + Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _PRINTF_ARGS_H #define _PRINTF_ARGS_H @@ -57,10 +57,8 @@ typedef enum TYPE_UINT, TYPE_LONGINT, TYPE_ULONGINT, -#if HAVE_LONG_LONG_INT TYPE_LONGLONGINT, TYPE_ULONGLONGINT, -#endif TYPE_DOUBLE, TYPE_LONGDOUBLE, TYPE_CHAR, @@ -75,10 +73,8 @@ typedef enum TYPE_COUNT_SCHAR_POINTER, TYPE_COUNT_SHORT_POINTER, TYPE_COUNT_INT_POINTER, - TYPE_COUNT_LONGINT_POINTER -#if HAVE_LONG_LONG_INT -, TYPE_COUNT_LONGLONGINT_POINTER -#endif + TYPE_COUNT_LONGINT_POINTER, + TYPE_COUNT_LONGLONGINT_POINTER #if ENABLE_UNISTDIO /* The unistdio extensions. */ , TYPE_U8_STRING @@ -101,10 +97,8 @@ typedef struct unsigned int a_uint; long int a_longint; unsigned long int a_ulongint; -#if HAVE_LONG_LONG_INT long long int a_longlongint; unsigned long long int a_ulonglongint; -#endif float a_float; double a_double; long double a_longdouble; @@ -121,9 +115,7 @@ typedef struct short * a_count_short_pointer; int * a_count_int_pointer; long int * a_count_longint_pointer; -#if HAVE_LONG_LONG_INT long long int * a_count_longlongint_pointer; -#endif #if ENABLE_UNISTDIO /* The unistdio extensions. */ const uint8_t * a_u8_string; diff --git a/gl/printf-parse.c b/gl/printf-parse.c index 23cacc1d..aab02dc5 100644 --- a/gl/printf-parse.c +++ b/gl/printf-parse.c @@ -1,18 +1,18 @@ /* Formatted output to strings. - Copyright (C) 1999-2000, 2002-2003, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 1999-2000, 2002-2003, 2006-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This file can be parametrized with the following macros: CHAR_T The element type of the format string. @@ -48,16 +48,7 @@ #include /* Get intmax_t. */ -#if defined IN_LIBINTL || defined IN_LIBASPRINTF -# if HAVE_STDINT_H_WITH_UINTMAX -# include -# endif -# if HAVE_INTTYPES_H_WITH_UINTMAX -# include -# endif -#else -# include -#endif +#include /* malloc(), realloc(), free(). */ #include @@ -419,7 +410,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) cp++; } #endif -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +#if defined _WIN32 && ! defined __CYGWIN__ /* On native Windows, PRIdMAX is defined as "I64d". We cannot change it to "lld" because PRIdMAX must also be understood by the system's printf routines. */ @@ -447,14 +438,12 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) switch (c) { case 'd': case 'i': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ + /* If 'long long' is larger than 'long': */ if (flags >= 16 || (flags & 4)) type = TYPE_LONGLONGINT; else -#endif - /* If 'long long' exists and is the same as 'long', we parse - "lld" into TYPE_LONGINT. */ + /* If 'long long' is the same as 'long', we parse "lld" into + TYPE_LONGINT. */ if (flags >= 8) type = TYPE_LONGINT; else if (flags & 2) @@ -465,14 +454,12 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) type = TYPE_INT; break; case 'o': case 'u': case 'x': case 'X': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ + /* If 'unsigned long long' is larger than 'unsigned long': */ if (flags >= 16 || (flags & 4)) type = TYPE_ULONGLONGINT; else -#endif - /* If 'unsigned long long' exists and is the same as - 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ + /* If 'unsigned long long' is the same as 'unsigned long', we + parse "llu" into TYPE_ULONGINT. */ if (flags >= 8) type = TYPE_ULONGINT; else if (flags & 2) @@ -525,14 +512,12 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) type = TYPE_POINTER; break; case 'n': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ + /* If 'long long' is larger than 'long': */ if (flags >= 16 || (flags & 4)) type = TYPE_COUNT_LONGLONGINT_POINTER; else -#endif - /* If 'long long' exists and is the same as 'long', we parse - "lln" into TYPE_COUNT_LONGINT_POINTER. */ + /* If 'long long' is the same as 'long', we parse "lln" into + TYPE_COUNT_LONGINT_POINTER. */ if (flags >= 8) type = TYPE_COUNT_LONGINT_POINTER; else if (flags & 2) diff --git a/gl/printf-parse.h b/gl/printf-parse.h index d8474bee..b12ccea3 100644 --- a/gl/printf-parse.h +++ b/gl/printf-parse.h @@ -1,19 +1,19 @@ /* Parse printf format string. - Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2013 Free Software + Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _PRINTF_PARSE_H #define _PRINTF_PARSE_H diff --git a/gl/read.c b/gl/read.c deleted file mode 100644 index 0fe0306f..00000000 --- a/gl/read.c +++ /dev/null @@ -1,85 +0,0 @@ -/* POSIX compatible read() function. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2011. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - -# include -# include - -# define WIN32_LEAN_AND_MEAN /* avoid including junk */ -# include - -# include "msvc-inval.h" -# include "msvc-nothrow.h" - -# undef read - -# if HAVE_MSVC_INVALID_PARAMETER_HANDLER -static ssize_t -read_nothrow (int fd, void *buf, size_t count) -{ - ssize_t result; - - TRY_MSVC_INVAL - { - result = read (fd, buf, count); - } - CATCH_MSVC_INVAL - { - result = -1; - errno = EBADF; - } - DONE_MSVC_INVAL; - - return result; -} -# else -# define read_nothrow read -# endif - -ssize_t -rpl_read (int fd, void *buf, size_t count) -{ - ssize_t ret = read_nothrow (fd, buf, count); - -# if GNULIB_NONBLOCKING - if (ret < 0 - && GetLastError () == ERROR_NO_DATA) - { - HANDLE h = (HANDLE) _get_osfhandle (fd); - if (GetFileType (h) == FILE_TYPE_PIPE) - { - /* h is a pipe or socket. */ - DWORD state; - if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0) - && (state & PIPE_NOWAIT) != 0) - /* h is a pipe in non-blocking mode. - Change errno from EINVAL to EAGAIN. */ - errno = EAGAIN; - } - } -# endif - - return ret; -} - -#endif diff --git a/gl/realloc.c b/gl/realloc.c new file mode 100644 index 00000000..c8783815 --- /dev/null +++ b/gl/realloc.c @@ -0,0 +1,63 @@ +/* realloc() function that is glibc compatible. + + Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2022 Free Software + Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* written by Jim Meyering and Bruno Haible */ + +#include + +#include + +#include + +#include "xalloc-oversized.h" + +/* Call the system's realloc below. This file does not define + _GL_USE_STDLIB_ALLOC because it needs Gnulib's malloc if present. */ +#undef realloc + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. If P is NULL, use malloc. Otherwise if N is zero, + free P and return NULL. */ + +void * +rpl_realloc (void *p, size_t n) +{ + if (p == NULL) + return malloc (n); + + if (n == 0) + { + free (p); + return NULL; + } + + if (xalloc_oversized (n, 1)) + { + errno = ENOMEM; + return NULL; + } + + void *result = realloc (p, n); + +#if !HAVE_MALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/gl/reallocarray.c b/gl/reallocarray.c new file mode 100644 index 00000000..70c1b478 --- /dev/null +++ b/gl/reallocarray.c @@ -0,0 +1,38 @@ +/* reallocarray function that is glibc compatible. + + Copyright (C) 2017-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* written by Darshit Shah */ + +#include + +#include +#include +#include + +void * +reallocarray (void *ptr, size_t nmemb, size_t size) +{ + size_t nbytes; + if (ckd_mul (&nbytes, nmemb, size)) + { + errno = ENOMEM; + return NULL; + } + + /* Rely on the semantics of GNU realloc. */ + return realloc (ptr, nbytes); +} diff --git a/gl/ref-add.sin b/gl/ref-add.sin deleted file mode 100644 index 112bcdc64..00000000 --- a/gl/ref-add.sin +++ /dev/null @@ -1,29 +0,0 @@ -# Add this package to a list of references stored in a text file. -# -# Copyright (C) 2000, 2009-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, see . -# -# Written by Bruno Haible . -# -/^# Packages using this file: / { - s/# Packages using this file:// - ta - :a - s/ @PACKAGE@ / @PACKAGE@ / - tb - s/ $/ @PACKAGE@ / - :b - s/^/# Packages using this file:/ -} diff --git a/gl/ref-del.sin b/gl/ref-del.sin deleted file mode 100644 index 6f738684..00000000 --- a/gl/ref-del.sin +++ /dev/null @@ -1,24 +0,0 @@ -# Remove this package from a list of references stored in a text file. -# -# Copyright (C) 2000, 2009-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, see . -# -# Written by Bruno Haible . -# -/^# Packages using this file: / { - s/# Packages using this file:// - s/ @PACKAGE@ / / - s/^/# Packages using this file:/ -} diff --git a/gl/regcomp.c b/gl/regcomp.c index f0b2e522..122c3de5 100644 --- a/gl/regcomp.c +++ b/gl/regcomp.c @@ -1,21 +1,25 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ + +#ifdef _LIBC +# include +#endif static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, size_t length, reg_syntax_t syntax); @@ -23,14 +27,10 @@ static void re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, char *fastmap); static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len); -#ifdef RE_ENABLE_I18N static void free_charset (re_charset_t *cset); -#endif /* RE_ENABLE_I18N */ static void free_workarea_compile (regex_t *preg); static reg_errcode_t create_initial_state (re_dfa_t *dfa); -#ifdef RE_ENABLE_I18N static void optimize_utf8 (re_dfa_t *dfa); -#endif static reg_errcode_t analyze (regex_t *preg); static reg_errcode_t preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), @@ -55,7 +55,7 @@ static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); static Idx fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax); static int peek_token (re_token_t *token, re_string_t *input, - reg_syntax_t syntax) internal_function; + reg_syntax_t syntax); static bin_tree_t *parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, reg_errcode_t *err); static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg, @@ -85,7 +85,6 @@ static reg_errcode_t parse_bracket_element (bracket_elem_t *elem, static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, re_token_t *token); -#ifdef RE_ENABLE_I18N static reg_errcode_t build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, Idx *equiv_class_alloc, @@ -96,14 +95,6 @@ static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, Idx *char_class_alloc, const char *class_name, reg_syntax_t syntax); -#else /* not RE_ENABLE_I18N */ -static reg_errcode_t build_equiv_class (bitset_t sbcset, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - const char *class_name, - reg_syntax_t syntax); -#endif /* not RE_ENABLE_I18N */ static bin_tree_t *build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, const char *class_name, @@ -149,9 +140,9 @@ static const char __re_error_msgid[] = gettext_noop ("Invalid back reference") /* REG_ESUBREG */ "\0" #define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") - gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */ + gettext_noop ("Unmatched [, [^, [:, [., or [=") /* REG_EBRACK */ "\0" -#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^") +#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [, [^, [:, [., or [=") gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ "\0" #define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(") @@ -209,17 +200,9 @@ static const size_t __re_error_msgid_idx[] = Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields are set in BUFP on entry. */ -#ifdef _LIBC -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - size_t length; - struct re_pattern_buffer *bufp; -#else /* size_t might promote */ const char * re_compile_pattern (const char *pattern, size_t length, struct re_pattern_buffer *bufp) -#endif { reg_errcode_t ret; @@ -237,9 +220,7 @@ re_compile_pattern (const char *pattern, size_t length, return NULL; return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); } -#ifdef _LIBC weak_alias (__re_compile_pattern, re_compile_pattern) -#endif /* Set by 're_set_syntax' to the current regexp syntax to recognize. Can also be assigned to arbitrarily: each pattern buffer stores its own @@ -257,21 +238,17 @@ reg_syntax_t re_syntax_options; defined in regex.h. We return the old syntax. */ reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; +re_set_syntax (reg_syntax_t syntax) { reg_syntax_t ret = re_syntax_options; re_syntax_options = syntax; return ret; } -#ifdef _LIBC weak_alias (__re_set_syntax, re_set_syntax) -#endif int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; +re_compile_fastmap (struct re_pattern_buffer *bufp) { re_dfa_t *dfa = bufp->buffer; char *fastmap = bufp->fastmap; @@ -287,12 +264,9 @@ re_compile_fastmap (bufp) bufp->fastmap_accurate = 1; return 0; } -#ifdef _LIBC weak_alias (__re_compile_fastmap, re_compile_fastmap) -#endif -static inline void -__attribute__ ((always_inline)) +static __always_inline void re_set_fastmap (char *fastmap, bool icase, int ch) { fastmap[ch] = 1; @@ -318,7 +292,6 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, if (type == CHARACTER) { re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); -#ifdef RE_ENABLE_I18N if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) { unsigned char buf[MB_LEN_MAX]; @@ -335,11 +308,10 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, memset (&state, '\0', sizeof (state)); if (__mbrtowc (&wc, (const char *) buf, p - buf, &state) == p - buf - && (__wcrtomb ((char *) buf, towlower (wc), &state) + && (__wcrtomb ((char *) buf, __towlower (wc), &state) != (size_t) -1)) re_set_fastmap (fastmap, false, buf[0]); } -#endif } else if (type == SIMPLE_BRACKET) { @@ -353,13 +325,12 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, re_set_fastmap (fastmap, icase, ch); } } -#ifdef RE_ENABLE_I18N else if (type == COMPLEX_BRACKET) { re_charset_t *cset = dfa->nodes[node].opr.mbcset; Idx i; -# ifdef _LIBC +#ifdef _LIBC /* See if we have to try all bytes which start multiple collation elements. e.g. In da_DK, we want to catch 'a' since "aa" is a valid @@ -375,7 +346,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, if (table[i] < 0) re_set_fastmap (fastmap, icase, i); } -# endif /* _LIBC */ +#endif /* _LIBC */ /* See if we have to start the match at all multibyte characters, i.e. where we would not find an invalid sequence. This only @@ -383,9 +354,9 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, sets, the SIMPLE_BRACKET again suffices. */ if (dfa->mb_cur_max > 1 && (cset->nchar_classes || cset->non_match || cset->nranges -# ifdef _LIBC +#ifdef _LIBC || cset->nequiv_classes -# endif /* _LIBC */ +#endif /* _LIBC */ )) { unsigned char c = 0; @@ -411,19 +382,14 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, re_set_fastmap (fastmap, icase, *(unsigned char *) buf); if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) { - if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) + if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state) != (size_t) -1) re_set_fastmap (fastmap, false, *(unsigned char *) buf); } } } } -#endif /* RE_ENABLE_I18N */ - else if (type == OP_PERIOD -#ifdef RE_ENABLE_I18N - || type == OP_UTF8_PERIOD -#endif /* RE_ENABLE_I18N */ - || type == END_OF_RE) + else if (type == OP_PERIOD || type == OP_UTF8_PERIOD || type == END_OF_RE) { memset (fastmap, '\1', sizeof (char) * SBC_MAX); if (type == END_OF_RE) @@ -470,10 +436,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, the return codes and their meanings.) */ int -regcomp (preg, pattern, cflags) - regex_t *_Restrict_ preg; - const char *_Restrict_ pattern; - int cflags; +regcomp (regex_t *__restrict preg, const char *__restrict pattern, int cflags) { reg_errcode_t ret; reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED @@ -485,7 +448,7 @@ regcomp (preg, pattern, cflags) /* Try to allocate space for the fastmap. */ preg->fastmap = re_malloc (char, SBC_MAX); - if (BE (preg->fastmap == NULL, 0)) + if (__glibc_unlikely (preg->fastmap == NULL)) return REG_ESPACE; syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0; @@ -511,7 +474,7 @@ regcomp (preg, pattern, cflags) ret = REG_EPAREN; /* We have already checked preg->fastmap != NULL. */ - if (BE (ret == REG_NOERROR, 1)) + if (__glibc_likely (ret == REG_NOERROR)) /* Compute the fastmap now, since regexec cannot modify the pattern buffer. This function never fails in this implementation. */ (void) re_compile_fastmap (preg); @@ -524,32 +487,21 @@ regcomp (preg, pattern, cflags) return (int) ret; } -#ifdef _LIBC +libc_hidden_def (__regcomp) weak_alias (__regcomp, regcomp) -#endif /* Returns a message corresponding to an error code, ERRCODE, returned from either regcomp or regexec. We don't use PREG here. */ -#ifdef _LIBC -size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *_Restrict_ preg; - char *_Restrict_ errbuf; - size_t errbuf_size; -#else /* size_t might promote */ size_t -regerror (int errcode, const regex_t *_Restrict_ preg, - char *_Restrict_ errbuf, size_t errbuf_size) -#endif +regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf, + size_t errbuf_size) { const char *msg; size_t msg_size; + int nerrcodes = sizeof __re_error_msgid_idx / sizeof __re_error_msgid_idx[0]; - if (BE (errcode < 0 - || errcode >= (int) (sizeof (__re_error_msgid_idx) - / sizeof (__re_error_msgid_idx[0])), 0)) + if (__glibc_unlikely (errcode < 0 || errcode >= nerrcodes)) /* Only error codes returned by the rest of the code should be passed to this routine. If we are given anything else, or if other regex code generates an invalid error code, then the program has a bug. @@ -560,10 +512,10 @@ regerror (int errcode, const regex_t *_Restrict_ preg, msg_size = strlen (msg) + 1; /* Includes the null. */ - if (BE (errbuf_size != 0, 1)) + if (__glibc_likely (errbuf_size != 0)) { size_t cpy_size = msg_size; - if (BE (msg_size > errbuf_size, 0)) + if (__glibc_unlikely (msg_size > errbuf_size)) { cpy_size = errbuf_size - 1; errbuf[cpy_size] = '\0'; @@ -573,12 +525,9 @@ regerror (int errcode, const regex_t *_Restrict_ preg, return msg_size; } -#ifdef _LIBC weak_alias (__regerror, regerror) -#endif -#ifdef RE_ENABLE_I18N /* This static array is used for the map to single-byte characters when UTF-8 is used. Otherwise we would allocate memory just to initialize it the same all the time. UTF-8 is the preferred encoding so this is @@ -586,25 +535,24 @@ weak_alias (__regerror, regerror) static const bitset_t utf8_sb_map = { /* Set the first 128 bits. */ -# if defined __GNUC__ && !defined __STRICT_ANSI__ +#if (defined __GNUC__ || __clang_major__ >= 4) && !defined __STRICT_ANSI__ [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX -# else -# if 4 * BITSET_WORD_BITS < ASCII_CHARS -# error "bitset_word_t is narrower than 32 bits" -# elif 3 * BITSET_WORD_BITS < ASCII_CHARS +#else +# if 4 * BITSET_WORD_BITS < ASCII_CHARS +# error "bitset_word_t is narrower than 32 bits" +# elif 3 * BITSET_WORD_BITS < ASCII_CHARS BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, -# elif 2 * BITSET_WORD_BITS < ASCII_CHARS +# elif 2 * BITSET_WORD_BITS < ASCII_CHARS BITSET_WORD_MAX, BITSET_WORD_MAX, -# elif 1 * BITSET_WORD_BITS < ASCII_CHARS +# elif 1 * BITSET_WORD_BITS < ASCII_CHARS BITSET_WORD_MAX, -# endif +# endif (BITSET_WORD_MAX >> (SBC_MAX % BITSET_WORD_BITS == 0 ? 0 : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) -# endif -}; #endif +}; static void @@ -642,10 +590,8 @@ free_dfa_content (re_dfa_t *dfa) re_free (entry->array); } re_free (dfa->state_table); -#ifdef RE_ENABLE_I18N if (dfa->sb_char != utf8_sb_map) re_free (dfa->sb_char); -#endif re_free (dfa->subexp_map); #ifdef DEBUG re_free (dfa->re_str); @@ -658,11 +604,10 @@ free_dfa_content (re_dfa_t *dfa) /* Free dynamically allocated space used by PREG. */ void -regfree (preg) - regex_t *preg; +regfree (regex_t *preg) { re_dfa_t *dfa = preg->buffer; - if (BE (dfa != NULL, 1)) + if (__glibc_likely (dfa != NULL)) { lock_fini (dfa->lock); free_dfa_content (dfa); @@ -676,9 +621,8 @@ regfree (preg) re_free (preg->translate); preg->translate = NULL; } -#ifdef _LIBC +libc_hidden_def (__regfree) weak_alias (__regfree, regfree) -#endif /* Entry points compatible with 4.2 BSD regex library. We don't define them unless specifically requested. */ @@ -695,8 +639,7 @@ char * regcomp/regexec above without link errors. */ weak_function # endif -re_comp (s) - const char *s; +re_comp (const char *s) { reg_errcode_t ret; char *fastmap; @@ -719,7 +662,7 @@ re_comp (s) if (re_comp_buf.fastmap == NULL) { - re_comp_buf.fastmap = (char *) malloc (SBC_MAX); + re_comp_buf.fastmap = re_malloc (char, SBC_MAX); if (re_comp_buf.fastmap == NULL) return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) REG_ESPACE]); @@ -772,7 +715,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length, /* Initialize the dfa. */ dfa = preg->buffer; - if (BE (preg->allocated < sizeof (re_dfa_t), 0)) + if (__glibc_unlikely (preg->allocated < sizeof (re_dfa_t))) { /* If zero allocated, but buffer is non-null, try to realloc enough space. This loses if buffer's address is bogus, but @@ -787,9 +730,9 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length, preg->used = sizeof (re_dfa_t); err = init_dfa (dfa, length); - if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0)) + if (__glibc_unlikely (err == REG_NOERROR && lock_init (dfa->lock) != 0)) err = REG_ESPACE; - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { free_dfa_content (dfa); preg->buffer = NULL; @@ -804,7 +747,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length, err = re_string_construct (®exp, pattern, length, preg->translate, (syntax & RE_ICASE) != 0, dfa); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_compile_internal_free_return: free_workarea_compile (preg); @@ -819,19 +762,17 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length, /* Parse the regular expression, and build a structure tree. */ preg->re_nsub = 0; dfa->str_tree = parse (®exp, preg, syntax, &err); - if (BE (dfa->str_tree == NULL, 0)) + if (__glibc_unlikely (dfa->str_tree == NULL)) goto re_compile_internal_free_return; /* Analyze the tree and create the nfa. */ err = analyze (preg); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto re_compile_internal_free_return; -#ifdef RE_ENABLE_I18N /* If possible, do searching in single byte encoding to speed things up. */ if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) optimize_utf8 (dfa); -#endif /* Then create the initial state of the dfa. */ err = create_initial_state (dfa); @@ -840,7 +781,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length, free_workarea_compile (preg); re_string_destruct (®exp); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { lock_fini (dfa->lock); free_dfa_content (dfa); @@ -861,11 +802,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) #ifndef _LIBC const char *codeset_name; #endif -#ifdef RE_ENABLE_I18N size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); -#else - size_t max_i18n_object_size = 0; -#endif size_t max_object_size = MAX (sizeof (struct re_state_table_entry), MAX (sizeof (re_token_t), @@ -882,7 +819,8 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) calculation below, and for similar doubling calculations elsewhere. And it's <= rather than <, because some of the doubling calculations add 1 afterwards. */ - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 <= pat_len, 0)) + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 + <= pat_len)) return REG_ESPACE; dfa->nodes_alloc = pat_len + 1; @@ -916,7 +854,6 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) dfa->map_notascii = 0; #endif -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) { if (dfa->is_utf8) @@ -926,7 +863,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) int i, j, ch; dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); - if (BE (dfa->sb_char == NULL, 0)) + if (__glibc_unlikely (dfa->sb_char == NULL)) return REG_ESPACE; /* Set the bits corresponding to single byte chars. */ @@ -936,16 +873,15 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) wint_t wch = __btowc (ch); if (wch != WEOF) dfa->sb_char[i] |= (bitset_word_t) 1 << j; -# ifndef _LIBC +#ifndef _LIBC if (isascii (ch) && wch != ch) dfa->map_notascii = 1; -# endif +#endif } } } -#endif - if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) + if (__glibc_unlikely (dfa->nodes == NULL || dfa->state_table == NULL)) return REG_ESPACE; return REG_NOERROR; } @@ -955,14 +891,13 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) character used by some operators like "\<", "\>", etc. */ static void -internal_function init_word_char (re_dfa_t *dfa) { int i = 0; int j; int ch = 0; dfa->word_ops_used = 1; - if (BE (dfa->map_notascii == 0, 1)) + if (__glibc_likely (dfa->map_notascii == 0)) { bitset_word_t bits0 = 0x00000000; bitset_word_t bits1 = 0x03ff0000; @@ -970,6 +905,7 @@ init_word_char (re_dfa_t *dfa) bitset_word_t bits3 = 0x07fffffe; if (BITSET_WORD_BITS == 64) { + /* Pacify gcc -Woverflow on 32-bit platformns. */ dfa->word_char[0] = bits1 << 31 << 1 | bits0; dfa->word_char[1] = bits3 << 31 << 1 | bits2; i = 2; @@ -986,7 +922,7 @@ init_word_char (re_dfa_t *dfa) goto general_case; ch = 128; - if (BE (dfa->is_utf8, 1)) + if (__glibc_likely (dfa->is_utf8)) { memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8); return; @@ -1033,7 +969,7 @@ create_initial_state (re_dfa_t *dfa) first = dfa->str_tree->first->node_idx; dfa->init_node = first; err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; /* The back-references which are in initial states can epsilon transit, @@ -1077,7 +1013,7 @@ create_initial_state (re_dfa_t *dfa) /* It must be the first time to invoke acquire_state. */ dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); /* We don't check ERR here, since the initial state must not be NULL. */ - if (BE (dfa->init_state == NULL, 0)) + if (__glibc_unlikely (dfa->init_state == NULL)) return err; if (dfa->init_state->has_constraint) { @@ -1089,8 +1025,9 @@ create_initial_state (re_dfa_t *dfa) &init_nodes, CONTEXT_NEWLINE | CONTEXT_BEGBUF); - if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) + if (__glibc_unlikely (dfa->init_state_word == NULL + || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL)) return err; } else @@ -1101,7 +1038,6 @@ create_initial_state (re_dfa_t *dfa) return REG_NOERROR; } -#ifdef RE_ENABLE_I18N /* If it is possible to do searching in single byte encoding instead of UTF-8 to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change DFA nodes where needed. */ @@ -1181,7 +1117,6 @@ optimize_utf8 (re_dfa_t *dfa) dfa->is_utf8 = 0; dfa->has_mb_node = dfa->nbackref > 0 || has_period; } -#endif /* Analyze the structure tree, and calculate "first", "next", "edest", "eclosure", and "inveclosure". */ @@ -1197,8 +1132,8 @@ analyze (regex_t *preg) dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc); dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); - if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL - || dfa->eclosures == NULL, 0)) + if (__glibc_unlikely (dfa->nexts == NULL || dfa->org_indices == NULL + || dfa->edests == NULL || dfa->eclosures == NULL)) return REG_ESPACE; dfa->subexp_map = re_malloc (Idx, preg->re_nsub); @@ -1213,23 +1148,23 @@ analyze (regex_t *preg) break; if (i == preg->re_nsub) { - free (dfa->subexp_map); + re_free (dfa->subexp_map); dfa->subexp_map = NULL; } } ret = postorder (dfa->str_tree, lower_subexps, preg); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; ret = postorder (dfa->str_tree, calc_first, dfa); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; preorder (dfa->str_tree, calc_next, dfa); ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; ret = calc_eclosure (dfa); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; /* We only need this during the prune_impossible_nodes pass in regexec.c; @@ -1238,7 +1173,7 @@ analyze (regex_t *preg) || dfa->nbackref) { dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); - if (BE (dfa->inveclosures == NULL, 0)) + if (__glibc_unlikely (dfa->inveclosures == NULL)) return REG_ESPACE; ret = calc_inveclosure (dfa); } @@ -1268,7 +1203,7 @@ postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), do { reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; if (node->parent == NULL) return REG_NOERROR; @@ -1290,7 +1225,7 @@ preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), for (node = root; ; ) { reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; /* Go to the left node, or up and to the right. */ @@ -1391,7 +1326,8 @@ lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP); tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls; tree = create_tree (dfa, op, tree1, CONCAT); - if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) + if (__glibc_unlikely (tree == NULL || tree1 == NULL + || op == NULL || cls == NULL)) { *err = REG_ESPACE; return NULL; @@ -1417,7 +1353,7 @@ calc_first (void *extra, bin_tree_t *node) { node->first = node; node->node_idx = re_dfa_add_node (dfa, node->token); - if (BE (node->node_idx == REG_MISSING, 0)) + if (__glibc_unlikely (node->node_idx == -1)) return REG_ESPACE; if (node->token.type == ANCHOR) dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; @@ -1462,7 +1398,7 @@ link_nfa_nodes (void *extra, bin_tree_t *node) break; case END_OF_RE: - assert (node->next == NULL); + DEBUG_ASSERT (node->next == NULL); break; case OP_DUP_ASTERISK: @@ -1478,8 +1414,8 @@ link_nfa_nodes (void *extra, bin_tree_t *node) right = node->right->first->node_idx; else right = node->next->node_idx; - assert (REG_VALID_INDEX (left)); - assert (REG_VALID_INDEX (right)); + DEBUG_ASSERT (left > -1); + DEBUG_ASSERT (right > -1); err = re_node_set_init_2 (dfa->edests + idx, left, right); } break; @@ -1497,7 +1433,7 @@ link_nfa_nodes (void *extra, bin_tree_t *node) break; default: - assert (!IS_EPSILON_NODE (node->token.type)); + DEBUG_ASSERT (!IS_EPSILON_NODE (node->token.type)); dfa->nexts[idx] = node->next->node_idx; break; } @@ -1510,7 +1446,6 @@ link_nfa_nodes (void *extra, bin_tree_t *node) to their own constraint. */ static reg_errcode_t -internal_function duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, Idx root_node, unsigned int init_constraint) { @@ -1529,11 +1464,11 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, org_dest = dfa->nexts[org_node]; re_node_set_empty (dfa->edests + clone_node); clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) + if (__glibc_unlikely (clone_dest == -1)) return REG_ESPACE; dfa->nexts[clone_node] = dfa->nexts[org_node]; ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } else if (dfa->edests[org_node].nelem == 0) @@ -1555,17 +1490,17 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, if (org_node == root_node && clone_node != org_node) { ok = re_node_set_insert (dfa->edests + clone_node, org_dest); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; break; } /* In case the node has another constraint, append it. */ constraint |= dfa->nodes[org_node].constraint; clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) + if (__glibc_unlikely (clone_dest == -1)) return REG_ESPACE; ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } else /* dfa->edests[org_node].nelem == 2 */ @@ -1576,19 +1511,19 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, re_node_set_empty (dfa->edests + clone_node); /* Search for a duplicated node which satisfies the constraint. */ clone_dest = search_duplicated_node (dfa, org_dest, constraint); - if (clone_dest == REG_MISSING) + if (clone_dest == -1) { /* There is no such duplicated node, create a new one. */ reg_errcode_t err; clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) + if (__glibc_unlikely (clone_dest == -1)) return REG_ESPACE; ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; err = duplicate_node_closure (dfa, org_dest, clone_dest, root_node, constraint); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } else @@ -1596,16 +1531,16 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, /* There is a duplicated node which satisfies the constraint, use it to avoid infinite loop. */ ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } org_dest = dfa->edests[org_node].elems[1]; clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) + if (__glibc_unlikely (clone_dest == -1)) return REG_ESPACE; ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } org_node = org_dest; @@ -1628,18 +1563,18 @@ search_duplicated_node (const re_dfa_t *dfa, Idx org_node, && constraint == dfa->nodes[idx].constraint) return idx; /* Found. */ } - return REG_MISSING; /* Not found. */ + return -1; /* Not found. */ } /* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT. - Return the index of the new node, or REG_MISSING if insufficient storage is + Return the index of the new node, or -1 if insufficient storage is available. */ static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint) { Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); - if (BE (dup_idx != REG_MISSING, 1)) + if (__glibc_likely (dup_idx != -1)) { dfa->nodes[dup_idx].constraint = constraint; dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint; @@ -1665,7 +1600,7 @@ calc_inveclosure (re_dfa_t *dfa) for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) { ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } } @@ -1680,9 +1615,7 @@ calc_eclosure (re_dfa_t *dfa) { Idx node_idx; bool incomplete; -#ifdef DEBUG - assert (dfa->nodes_len > 0); -#endif + DEBUG_ASSERT (dfa->nodes_len > 0); incomplete = false; /* For each nodes, calculate epsilon closure. */ for (node_idx = 0; ; ++node_idx) @@ -1697,16 +1630,14 @@ calc_eclosure (re_dfa_t *dfa) node_idx = 0; } -#ifdef DEBUG - assert (dfa->eclosures[node_idx].nelem != REG_MISSING); -#endif + DEBUG_ASSERT (dfa->eclosures[node_idx].nelem != -1); /* If we have already calculated, skip it. */ if (dfa->eclosures[node_idx].nelem != 0) continue; /* Calculate epsilon closure of 'node_idx'. */ err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; if (dfa->eclosures[node_idx].nelem == 0) @@ -1726,15 +1657,17 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) reg_errcode_t err; Idx i; re_node_set eclosure; - bool ok; bool incomplete = false; err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; + /* An epsilon closure includes itself. */ + eclosure.elems[eclosure.nelem++] = node; + /* This indicates that we are calculating this node now. We reference this value to avoid infinite loop. */ - dfa->eclosures[node].nelem = REG_MISSING; + dfa->eclosures[node].nelem = -1; /* If the current node has constraints, duplicate all nodes since they must inherit the constraints. */ @@ -1744,7 +1677,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) { err = duplicate_node_closure (dfa, node, node, node, dfa->nodes[node].constraint); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } @@ -1756,7 +1689,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) Idx edest = dfa->edests[node].elems[i]; /* If calculating the epsilon closure of 'edest' is in progress, return intermediate result. */ - if (dfa->eclosures[edest].nelem == REG_MISSING) + if (dfa->eclosures[edest].nelem == -1) { incomplete = true; continue; @@ -1766,14 +1699,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) if (dfa->eclosures[edest].nelem == 0) { err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } else eclosure_elem = dfa->eclosures[edest]; /* Merge the epsilon closure of 'edest'. */ err = re_node_set_merge (&eclosure, &eclosure_elem); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; /* If the epsilon closure of 'edest' is incomplete, the epsilon closure of this node is also incomplete. */ @@ -1784,10 +1717,6 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) } } - /* An epsilon closure includes itself. */ - ok = re_node_set_insert (&eclosure, node); - if (BE (! ok, 0)) - return REG_ESPACE; if (incomplete && !root) dfa->eclosures[node].nelem = 0; else @@ -1802,7 +1731,6 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) We must not use this function inside bracket expressions. */ static void -internal_function fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) { re_string_skip_bytes (input, peek_token (result, input, syntax)); @@ -1812,7 +1740,6 @@ fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) We must not use this function inside bracket expressions. */ static int -internal_function peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) { unsigned char c; @@ -1827,16 +1754,14 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) token->opr.c = c; token->word_char = 0; -#ifdef RE_ENABLE_I18N token->mb_partial = 0; - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) + if (input->mb_cur_max > 1 + && !re_string_first_byte (input, re_string_cur_idx (input))) { token->type = CHARACTER; token->mb_partial = 1; return 1; } -#endif if (c == '\\') { unsigned char c2; @@ -1849,7 +1774,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) c2 = re_string_peek_byte_case (input, 1); token->opr.c = c2; token->type = CHARACTER; -#ifdef RE_ENABLE_I18N if (input->mb_cur_max > 1) { wint_t wc = re_string_wchar_at (input, @@ -1857,7 +1781,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; } else -#endif token->word_char = IS_WORD_CHAR (c2) != 0; switch (c2) @@ -1963,14 +1886,12 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) } token->type = CHARACTER; -#ifdef RE_ENABLE_I18N if (input->mb_cur_max > 1) { wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; } else -#endif token->word_char = IS_WORD_CHAR (token->opr.c); switch (c) @@ -2017,8 +1938,8 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) token->type = OP_PERIOD; break; case '^': - if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) && - re_string_cur_idx (input) != 0) + if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) + && re_string_cur_idx (input) != 0) { char prev = re_string_peek_byte (input, -1); if (!(syntax & RE_NEWLINE_ALT) || prev != '\n') @@ -2028,8 +1949,8 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) token->opr.ctx_type = LINE_FIRST; break; case '$': - if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) && - re_string_cur_idx (input) + 1 != re_string_length (input)) + if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) + && re_string_cur_idx (input) + 1 != re_string_length (input)) { re_token_t next; re_string_skip_bytes (input, 1); @@ -2051,7 +1972,6 @@ peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) We must not use this function out of bracket expressions. */ static int -internal_function peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) { unsigned char c; @@ -2063,14 +1983,12 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) c = re_string_peek_byte (input, 0); token->opr.c = c; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) + if (input->mb_cur_max > 1 + && !re_string_first_byte (input, re_string_cur_idx (input))) { token->type = CHARACTER; return 1; } -#endif /* RE_ENABLE_I18N */ if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && re_string_cur_idx (input) + 1 < re_string_length (input)) @@ -2098,16 +2016,18 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) case '.': token->type = OP_OPEN_COLL_ELEM; break; + case '=': token->type = OP_OPEN_EQUIV_CLASS; break; + case ':': if (syntax & RE_CHAR_CLASSES) { token->type = OP_OPEN_CHAR_CLASS; break; } - /* else fall through. */ + FALLTHROUGH; default: token->type = CHARACTER; token->opr.c = c; @@ -2118,15 +2038,25 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) } switch (c) { - case '-': - token->type = OP_CHARSET_RANGE; - break; case ']': token->type = OP_CLOSE_BRACKET; break; case '^': token->type = OP_NON_MATCH_LIST; break; + case '-': + /* In V7 Unix grep and Unix awk and mawk, [...---...] + (3 adjacent minus signs) stands for a single minus sign. + Support that without breaking anything else. */ + if (! (re_string_cur_idx (input) + 2 < re_string_length (input) + && re_string_peek_byte (input, 1) == '-' + && re_string_peek_byte (input, 2) == '-')) + { + token->type = OP_CHARSET_RANGE; + break; + } + re_string_skip_bytes (input, 2); + FALLTHROUGH; default: token->type = CHARACTER; } @@ -2157,14 +2087,14 @@ parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, dfa->syntax = syntax; fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE); tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; eor = create_tree (dfa, NULL, NULL, END_OF_RE); if (tree != NULL) root = create_tree (dfa, tree, eor, CONCAT); else root = eor; - if (BE (eor == NULL || root == NULL, 0)) + if (__glibc_unlikely (eor == NULL || root == NULL)) { *err = REG_ESPACE; return NULL; @@ -2187,8 +2117,9 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, { re_dfa_t *dfa = preg->buffer; bin_tree_t *tree, *branch = NULL; + bitset_word_t initial_bkref_map = dfa->completed_bkref_map; tree = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; while (token->type == OP_ALT) @@ -2197,14 +2128,21 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, if (token->type != OP_ALT && token->type != END_OF_RE && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) { + bitset_word_t accumulated_bkref_map = dfa->completed_bkref_map; + dfa->completed_bkref_map = initial_bkref_map; branch = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && branch == NULL, 0)) - return NULL; + if (__glibc_unlikely (*err != REG_NOERROR && branch == NULL)) + { + if (tree != NULL) + postorder (tree, free_tree, NULL); + return NULL; + } + dfa->completed_bkref_map |= accumulated_bkref_map; } else branch = NULL; tree = create_tree (dfa, tree, branch, OP_ALT); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; @@ -2229,14 +2167,14 @@ parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, bin_tree_t *tree, *expr; re_dfa_t *dfa = preg->buffer; tree = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; while (token->type != OP_ALT && token->type != END_OF_RE && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) { expr = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && expr == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && expr == NULL)) { if (tree != NULL) postorder (tree, free_tree, NULL); @@ -2277,12 +2215,11 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, { case CHARACTER: tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; } -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) { while (!re_string_eoi (regexp) @@ -2292,34 +2229,36 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, fetch_token (token, regexp, syntax); mbc_remain = create_token_tree (dfa, NULL, NULL, token); tree = create_tree (dfa, tree, mbc_remain, CONCAT); - if (BE (mbc_remain == NULL || tree == NULL, 0)) + if (__glibc_unlikely (mbc_remain == NULL || tree == NULL)) { *err = REG_ESPACE; return NULL; } } } -#endif break; + case OP_OPEN_SUBEXP: tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; break; + case OP_OPEN_BRACKET: tree = parse_bracket_exp (regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; break; + case OP_BACK_REF: - if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1)) + if (!__glibc_likely (dfa->completed_bkref_map & (1 << token->opr.idx))) { *err = REG_ESUBREG; return NULL; } dfa->used_bkref_map |= 1 << token->opr.idx; tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; @@ -2327,13 +2266,14 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, ++dfa->nbackref; dfa->has_mb_node = 1; break; + case OP_OPEN_DUP_NUM: if (syntax & RE_CONTEXT_INVALID_DUP) { *err = REG_BADRPT; return NULL; } - /* FALLTHROUGH */ + FALLTHROUGH; case OP_DUP_ASTERISK: case OP_DUP_PLUS: case OP_DUP_QUESTION: @@ -2347,15 +2287,15 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, fetch_token (token, regexp, syntax); return parse_expression (regexp, preg, token, syntax, nest, err); } - /* else fall through */ + FALLTHROUGH; case OP_CLOSE_SUBEXP: - if ((token->type == OP_CLOSE_SUBEXP) && - !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) + if ((token->type == OP_CLOSE_SUBEXP) + && !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) { *err = REG_ERPAREN; return NULL; } - /* else fall through */ + FALLTHROUGH; case OP_CLOSE_DUP_NUM: /* We treat it as a normal character. */ @@ -2364,12 +2304,13 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, /* mb_partial and word_char bits should be initialized already by peek_token. */ tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; } break; + case ANCHOR: if ((token->opr.ctx_type & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST)) @@ -2393,7 +2334,8 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, } tree_last = create_token_tree (dfa, NULL, NULL, token); tree = create_tree (dfa, tree_first, tree_last, OP_ALT); - if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) + if (__glibc_unlikely (tree_first == NULL || tree_last == NULL + || tree == NULL)) { *err = REG_ESPACE; return NULL; @@ -2402,7 +2344,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, else { tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; @@ -2414,9 +2356,10 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, it must not be "". */ fetch_token (token, regexp, syntax); return tree; + case OP_PERIOD: tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; @@ -2424,35 +2367,38 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, if (dfa->mb_cur_max > 1) dfa->has_mb_node = 1; break; + case OP_WORD: case OP_NOTWORD: tree = build_charclass_op (dfa, regexp->trans, "alnum", "_", token->type == OP_NOTWORD, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; break; + case OP_SPACE: case OP_NOTSPACE: tree = build_charclass_op (dfa, regexp->trans, "space", "", token->type == OP_NOTSPACE, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) + if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) return NULL; break; + case OP_ALT: case END_OF_RE: return NULL; + case BACK_SLASH: *err = REG_EESCAPE; return NULL; + default: /* Must not happen? */ -#ifdef DEBUG - assert (0); -#endif + DEBUG_ASSERT (false); return NULL; } fetch_token (token, regexp, syntax); @@ -2460,14 +2406,22 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) { - tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; + bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, + syntax, err); + if (__glibc_unlikely (*err != REG_NOERROR && dup_tree == NULL)) + { + if (tree != NULL) + postorder (tree, free_tree, NULL); + return NULL; + } + tree = dup_tree; /* In BRE consecutive duplications are not allowed. */ if ((syntax & RE_CONTEXT_INVALID_DUP) && (token->type == OP_DUP_ASTERISK || token->type == OP_OPEN_DUP_NUM)) { + if (tree != NULL) + postorder (tree, free_tree, NULL); *err = REG_BADRPT; return NULL; } @@ -2500,13 +2454,14 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, else { tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); - if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) + if (__glibc_unlikely (*err == REG_NOERROR + && token->type != OP_CLOSE_SUBEXP)) { if (tree != NULL) postorder (tree, free_tree, NULL); *err = REG_EPAREN; } - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) return NULL; } @@ -2514,7 +2469,7 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, dfa->completed_bkref_map |= 1 << cur_nsub; tree = create_tree (dfa, tree, NULL, SUBEXP); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) { *err = REG_ESPACE; return NULL; @@ -2537,7 +2492,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, { end = 0; start = fetch_number (regexp, token, syntax); - if (start == REG_MISSING) + if (start == -1) { if (token->type == CHARACTER && token->opr.c == ',') start = 0; /* We treat "{,m}" as "{0,m}". */ @@ -2547,17 +2502,17 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, return NULL; } } - if (BE (start != REG_ERROR, 1)) + if (__glibc_likely (start != -2)) { /* We treat "{n}" as "{n,n}". */ end = ((token->type == OP_CLOSE_DUP_NUM) ? start : ((token->type == CHARACTER && token->opr.c == ',') - ? fetch_number (regexp, token, syntax) : REG_ERROR)); + ? fetch_number (regexp, token, syntax) : -2)); } - if (BE (start == REG_ERROR || end == REG_ERROR, 0)) + if (__glibc_unlikely (start == -2 || end == -2)) { /* Invalid sequence. */ - if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) + if (__glibc_unlikely (!(syntax & RE_INVALID_INTERVAL_ORD))) { if (token->type == END_OF_RE) *err = REG_EBRACE; @@ -2576,15 +2531,15 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, return elem; } - if (BE ((end != REG_MISSING && start > end) - || token->type != OP_CLOSE_DUP_NUM, 0)) + if (__glibc_unlikely ((end != -1 && start > end) + || token->type != OP_CLOSE_DUP_NUM)) { /* First number greater than second. */ *err = REG_BADBR; return NULL; } - if (BE (RE_DUP_MAX < (end == REG_MISSING ? start : end), 0)) + if (__glibc_unlikely (RE_DUP_MAX < (end == -1 ? start : end))) { *err = REG_ESIZE; return NULL; @@ -2593,28 +2548,28 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, else { start = (token->type == OP_DUP_PLUS) ? 1 : 0; - end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING; + end = (token->type == OP_DUP_QUESTION) ? 1 : -1; } fetch_token (token, regexp, syntax); - if (BE (elem == NULL, 0)) + if (__glibc_unlikely (elem == NULL)) return NULL; - if (BE (start == 0 && end == 0, 0)) + if (__glibc_unlikely (start == 0 && end == 0)) { postorder (elem, free_tree, NULL); return NULL; } /* Extract "{n,m}" to "...{0,}". */ - if (BE (start > 0, 0)) + if (__glibc_unlikely (start > 0)) { tree = elem; for (i = 2; i <= start; ++i) { elem = duplicate_tree (elem, dfa); tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) + if (__glibc_unlikely (elem == NULL || tree == NULL)) goto parse_dup_op_espace; } @@ -2623,6 +2578,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, /* Duplicate ELEM before it is marked optional. */ elem = duplicate_tree (elem, dfa); + if (__glibc_unlikely (elem == NULL)) + goto parse_dup_op_espace; old_tree = tree; } else @@ -2635,27 +2592,23 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, } tree = create_tree (dfa, elem, NULL, - (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT)); - if (BE (tree == NULL, 0)) + (end == -1 ? OP_DUP_ASTERISK : OP_ALT)); + if (__glibc_unlikely (tree == NULL)) goto parse_dup_op_espace; -/* From gnulib's "intprops.h": - True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - - /* This loop is actually executed only when end != REG_MISSING, + /* This loop is actually executed only when end != -1, to rewrite {0,n} as ((...?)?)?... We have already created the start+1-th copy. */ - if (TYPE_SIGNED (Idx) || end != REG_MISSING) + if (TYPE_SIGNED (Idx) || end != -1) for (i = start + 2; i <= end; ++i) { elem = duplicate_tree (elem, dfa); tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) + if (__glibc_unlikely (elem == NULL || tree == NULL)) goto parse_dup_op_espace; tree = create_tree (dfa, tree, NULL, OP_ALT); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) goto parse_dup_op_espace; } @@ -2674,146 +2627,131 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, #define BRACKET_NAME_BUF_SIZE 32 #ifndef _LIBC - /* Local function for parse_bracket_exp only used in case of NOT _LIBC. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument since we may - update it. */ + +/* Convert the byte B to the corresponding wide character. In a + unibyte locale, treat B as itself. In a multibyte locale, return + WEOF if B is an encoding error. */ +static wint_t +parse_byte (unsigned char b, re_dfa_t const *dfa) +{ + return dfa->mb_cur_max > 1 ? __btowc (b) : b; +} + +/* Local function for parse_bracket_exp used in _LIBC environment. + Build the range expression which starts from START_ELEM, and ends + at END_ELEM. The result are written to MBCSET and SBCSET. + RANGE_ALLOC is the allocated size of mbcset->range_starts, and + mbcset->range_ends, is a pointer argument since we may + update it. */ static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N -build_range_exp (const reg_syntax_t syntax, - bitset_t sbcset, - re_charset_t *mbcset, - Idx *range_alloc, - const bracket_elem_t *start_elem, - const bracket_elem_t *end_elem) -# else /* not RE_ENABLE_I18N */ -build_range_exp (const reg_syntax_t syntax, - bitset_t sbcset, - const bracket_elem_t *start_elem, - const bracket_elem_t *end_elem) -# endif /* not RE_ENABLE_I18N */ +build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, + bracket_elem_t *start_elem, bracket_elem_t *end_elem, + re_dfa_t *dfa, reg_syntax_t syntax, uint_fast32_t nrules, + const unsigned char *collseqmb, const char *collseqwc, + int_fast32_t table_size, const void *symb_table, + const unsigned char *extra) { - unsigned int start_ch, end_ch; /* Equivalence Classes and Character Classes can't be a range start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) + if (__glibc_unlikely (start_elem->type == EQUIV_CLASS + || start_elem->type == CHAR_CLASS + || end_elem->type == EQUIV_CLASS + || end_elem->type == CHAR_CLASS)) return REG_ERANGE; /* We can handle no multi character collating elements without libc support. */ - if (BE ((start_elem->type == COLL_SYM - && strlen ((char *) start_elem->opr.name) > 1) - || (end_elem->type == COLL_SYM - && strlen ((char *) end_elem->opr.name) > 1), 0)) + if (__glibc_unlikely ((start_elem->type == COLL_SYM + && strlen ((char *) start_elem->opr.name) > 1) + || (end_elem->type == COLL_SYM + && strlen ((char *) end_elem->opr.name) > 1))) return REG_ECOLLATE; -# ifdef RE_ENABLE_I18N - { - wchar_t wc; - wint_t start_wc; - wint_t end_wc; - + unsigned int start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); + : 0)), end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] : 0)); + wint_t start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) - ? __btowc (start_ch) : start_elem->opr.wch); + ? parse_byte (start_ch, dfa) : start_elem->opr.wch), end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) - ? __btowc (end_ch) : end_elem->opr.wch); - if (start_wc == WEOF || end_wc == WEOF) - return REG_ECOLLATE; - else if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_wc > end_wc, 0)) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, for !_LIBC we have no collation elements: if the - character set is single byte, the single byte character set - that we build below suffices. parse_bracket_exp passes - no MBCSET if dfa->mb_cur_max == 1. */ - if (mbcset) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - wchar_t *new_array_start, *new_array_end; - Idx new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - /* Use realloc since mbcset->range_starts and mbcset->range_ends - are NULL if *range_alloc == 0. */ - new_array_start = re_realloc (mbcset->range_starts, wchar_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, wchar_t, - new_nranges); + ? parse_byte (end_ch, dfa) : end_elem->opr.wch); - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; + if (start_wc == WEOF || end_wc == WEOF) + return REG_ECOLLATE; + else if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES) + && start_wc > end_wc)) + return REG_ERANGE; - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } + /* Got valid collation sequence values, add them as a new entry. + However, for !_LIBC we have no collation elements: if the + character set is single byte, the single byte character set + that we build below suffices. parse_bracket_exp passes + no MBCSET if dfa->mb_cur_max == 1. */ + if (dfa->mb_cur_max > 1) + { + /* Check the space of the arrays. */ + if (__glibc_unlikely (*range_alloc == mbcset->nranges)) + { + /* There is not enough space, need realloc. */ + wchar_t *new_array_start, *new_array_end; + Idx new_nranges; - mbcset->range_starts[mbcset->nranges] = start_wc; - mbcset->range_ends[mbcset->nranges++] = end_wc; - } + /* +1 in case of mbcset->nranges is 0. */ + new_nranges = 2 * mbcset->nranges + 1; + /* Use realloc since mbcset->range_starts and mbcset->range_ends + are NULL if *range_alloc == 0. */ + new_array_start = re_realloc (mbcset->range_starts, wchar_t, + new_nranges); + new_array_end = re_realloc (mbcset->range_ends, wchar_t, + new_nranges); + + if (__glibc_unlikely (new_array_start == NULL + || new_array_end == NULL)) + { + re_free (new_array_start); + re_free (new_array_end); + return REG_ESPACE; + } + + mbcset->range_starts = new_array_start; + mbcset->range_ends = new_array_end; + *range_alloc = new_nranges; + } + + mbcset->range_starts[mbcset->nranges] = start_wc; + mbcset->range_ends[mbcset->nranges++] = end_wc; + } + + /* Build the table for single byte characters. */ + for (wchar_t wc = 0; wc < SBC_MAX; ++wc) + { + if (start_wc <= wc && wc <= end_wc) + bitset_set (sbcset, wc); + } - /* Build the table for single byte characters. */ - for (wc = 0; wc < SBC_MAX; ++wc) - { - if (start_wc <= wc && wc <= end_wc) - bitset_set (sbcset, wc); - } - } -# else /* not RE_ENABLE_I18N */ - { - unsigned int ch; - start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); - if (start_ch > end_ch) - return REG_ERANGE; - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ++ch) - if (start_ch <= ch && ch <= end_ch) - bitset_set (sbcset, ch); - } -# endif /* not RE_ENABLE_I18N */ return REG_NOERROR; } #endif /* not _LIBC */ #ifndef _LIBC -/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.. +/* Helper function for parse_bracket_exp only used in case of NOT _LIBC. Build the collating element which is represented by NAME. The result are written to MBCSET and SBCSET. COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a pointer argument since we may update it. */ static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, - Idx *coll_sym_alloc, const unsigned char *name) -# else /* not RE_ENABLE_I18N */ -build_collating_symbol (bitset_t sbcset, const unsigned char *name) -# endif /* not RE_ENABLE_I18N */ + Idx *coll_sym_alloc, const unsigned char *name, + uint_fast32_t nrules, int_fast32_t table_size, + const void *symb_table, const unsigned char *extra) { size_t name_len = strlen ((const char *) name); - if (BE (name_len != 1, 0)) + if (__glibc_unlikely (name_len != 1)) return REG_ECOLLATE; else { @@ -2823,267 +2761,280 @@ build_collating_symbol (bitset_t sbcset, const unsigned char *name) } #endif /* not _LIBC */ -/* This function parse bracket expression like "[abc]", "[a-c]", - "[[.a-a.]]" etc. */ - -static bin_tree_t * -parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err) -{ #ifdef _LIBC - const unsigned char *collseqmb; - const char *collseqwc; - uint32_t nrules; - int32_t table_size; - const int32_t *symb_table; - const unsigned char *extra; - - /* Local function for parse_bracket_exp used in _LIBC environment. - Seek the collating symbol entry corresponding to NAME. - Return the index of the symbol in the SYMB_TABLE, - or -1 if not found. */ - - auto inline int32_t - __attribute__ ((always_inline)) - seek_collating_symbol_entry (const unsigned char *name, size_t name_len) - { - int32_t elem; - - for (elem = 0; elem < table_size; elem++) - if (symb_table[2 * elem] != 0) - { - int32_t idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - if (/* Compare the length of the name. */ - name_len == extra[idx] - /* Compare the name. */ - && memcmp (name, &extra[idx + 1], name_len) == 0) - /* Yep, this is the entry. */ - return elem; - } - return -1; - } +/* Local function for parse_bracket_exp used in _LIBC environment. + Seek the collating symbol entry corresponding to NAME. + Return the index of the symbol in the SYMB_TABLE, + or -1 if not found. */ + +static __always_inline int32_t +seek_collating_symbol_entry (const unsigned char *name, size_t name_len, + const int32_t *symb_table, + int_fast32_t table_size, + const unsigned char *extra) +{ + int_fast32_t elem; - /* Local function for parse_bracket_exp used in _LIBC environment. - Look up the collation sequence value of BR_ELEM. - Return the value if succeeded, UINT_MAX otherwise. */ + for (elem = 0; elem < table_size; elem++) + if (symb_table[2 * elem] != 0) + { + int32_t idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + if (/* Compare the length of the name. */ + name_len == extra[idx] + /* Compare the name. */ + && memcmp (name, &extra[idx + 1], name_len) == 0) + /* Yep, this is the entry. */ + return elem; + } + return -1; +} - auto inline unsigned int - __attribute__ ((always_inline)) - lookup_collation_sequence_value (bracket_elem_t *br_elem) +/* Local function for parse_bracket_exp used in _LIBC environment. + Look up the collation sequence value of BR_ELEM. + Return the value if succeeded, UINT_MAX otherwise. */ + +static __always_inline unsigned int +lookup_collation_sequence_value (bracket_elem_t *br_elem, uint32_t nrules, + const unsigned char *collseqmb, + const char *collseqwc, + int_fast32_t table_size, + const int32_t *symb_table, + const unsigned char *extra) +{ + if (br_elem->type == SB_CHAR) { - if (br_elem->type == SB_CHAR) - { - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - return collseqmb[br_elem->opr.ch]; - else - { - wint_t wc = __btowc (br_elem->opr.ch); - return __collseq_table_lookup (collseqwc, wc); - } - } - else if (br_elem->type == MB_CHAR) + /* if (MB_CUR_MAX == 1) */ + if (nrules == 0) + return collseqmb[br_elem->opr.ch]; + else { - if (nrules != 0) - return __collseq_table_lookup (collseqwc, br_elem->opr.wch); + wint_t wc = __btowc (br_elem->opr.ch); + return __collseq_table_lookup (collseqwc, wc); } - else if (br_elem->type == COLL_SYM) + } + else if (br_elem->type == MB_CHAR) + { + if (nrules != 0) + return __collseq_table_lookup (collseqwc, br_elem->opr.wch); + } + else if (br_elem->type == COLL_SYM) + { + size_t sym_name_len = strlen ((char *) br_elem->opr.name); + if (nrules != 0) { - size_t sym_name_len = strlen ((char *) br_elem->opr.name); - if (nrules != 0) + int32_t elem, idx; + elem = seek_collating_symbol_entry (br_elem->opr.name, + sym_name_len, + symb_table, table_size, + extra); + if (elem != -1) { - int32_t elem, idx; - elem = seek_collating_symbol_entry (br_elem->opr.name, - sym_name_len); - if (elem != -1) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - /* Skip the byte sequence of the collating element. */ - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the multibyte collation sequence value. */ - idx += sizeof (unsigned int); - /* Skip the wide char sequence of the collating element. */ - idx += sizeof (unsigned int) * - (1 + *(unsigned int *) (extra + idx)); - /* Return the collation sequence value. */ - return *(unsigned int *) (extra + idx); - } - else if (sym_name_len == 1) - { - /* No valid character. Match it as a single byte - character. */ - return collseqmb[br_elem->opr.name[0]]; - } + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + /* Skip the byte sequence of the collating element. */ + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + /* Skip the multibyte collation sequence value. */ + idx += sizeof (unsigned int); + /* Skip the wide char sequence of the collating element. */ + idx += sizeof (unsigned int) * + (1 + *(unsigned int *) (extra + idx)); + /* Return the collation sequence value. */ + return *(unsigned int *) (extra + idx); } else if (sym_name_len == 1) - return collseqmb[br_elem->opr.name[0]]; + { + /* No valid character. Match it as a single byte + character. */ + return collseqmb[br_elem->opr.name[0]]; + } } - return UINT_MAX; + else if (sym_name_len == 1) + return collseqmb[br_elem->opr.name[0]]; } + return UINT_MAX; +} - /* Local function for parse_bracket_exp used in _LIBC environment. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument since we may - update it. */ - - auto inline reg_errcode_t - __attribute__ ((always_inline)) - build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc, - bracket_elem_t *start_elem, bracket_elem_t *end_elem) - { - unsigned int ch; - uint32_t start_collseq; - uint32_t end_collseq; - - /* Equivalence Classes and Character Classes can't be a range - start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; +/* Local function for parse_bracket_exp used in _LIBC environment. + Build the range expression which starts from START_ELEM, and ends + at END_ELEM. The result are written to MBCSET and SBCSET. + RANGE_ALLOC is the allocated size of mbcset->range_starts, and + mbcset->range_ends, is a pointer argument since we may + update it. */ + +static __always_inline reg_errcode_t +build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, + bracket_elem_t *start_elem, bracket_elem_t *end_elem, + re_dfa_t *dfa, reg_syntax_t syntax, uint32_t nrules, + const unsigned char *collseqmb, const char *collseqwc, + int_fast32_t table_size, const int32_t *symb_table, + const unsigned char *extra) +{ + unsigned int ch; + uint32_t start_collseq; + uint32_t end_collseq; + + /* Equivalence Classes and Character Classes can't be a range + start/end. */ + if (__glibc_unlikely (start_elem->type == EQUIV_CLASS + || start_elem->type == CHAR_CLASS + || end_elem->type == EQUIV_CLASS + || end_elem->type == CHAR_CLASS)) + return REG_ERANGE; - /* FIXME: Implement rational ranges here, too. */ - start_collseq = lookup_collation_sequence_value (start_elem); - end_collseq = lookup_collation_sequence_value (end_elem); - /* Check start/end collation sequence values. */ - if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) - return REG_ECOLLATE; - if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) - return REG_ERANGE; + /* FIXME: Implement rational ranges here, too. */ + start_collseq = lookup_collation_sequence_value (start_elem, nrules, collseqmb, collseqwc, + table_size, symb_table, extra); + end_collseq = lookup_collation_sequence_value (end_elem, nrules, collseqmb, collseqwc, + table_size, symb_table, extra); + /* Check start/end collation sequence values. */ + if (__glibc_unlikely (start_collseq == UINT_MAX + || end_collseq == UINT_MAX)) + return REG_ECOLLATE; + if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES) + && start_collseq > end_collseq)) + return REG_ERANGE; - /* Got valid collation sequence values, add them as a new entry. - However, if we have no collation elements, and the character set - is single byte, the single byte character set that we - build below suffices. */ - if (nrules > 0 || dfa->mb_cur_max > 1) + /* Got valid collation sequence values, add them as a new entry. + However, if we have no collation elements, and the character set + is single byte, the single byte character set that we + build below suffices. */ + if (nrules > 0 || dfa->mb_cur_max > 1) + { + /* Check the space of the arrays. */ + if (__glibc_unlikely (*range_alloc == mbcset->nranges)) { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - uint32_t *new_array_start; - uint32_t *new_array_end; - Idx new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - new_array_start = re_realloc (mbcset->range_starts, uint32_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, uint32_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; + /* There is not enough space, need realloc. */ + uint32_t *new_array_start; + uint32_t *new_array_end; + int new_nranges; - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } + /* +1 in case of mbcset->nranges is 0. */ + new_nranges = 2 * mbcset->nranges + 1; + new_array_start = re_realloc (mbcset->range_starts, uint32_t, + new_nranges); + new_array_end = re_realloc (mbcset->range_ends, uint32_t, + new_nranges); - mbcset->range_starts[mbcset->nranges] = start_collseq; - mbcset->range_ends[mbcset->nranges++] = end_collseq; - } + if (__glibc_unlikely (new_array_start == NULL + || new_array_end == NULL)) + return REG_ESPACE; - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ch++) - { - uint32_t ch_collseq; - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - ch_collseq = collseqmb[ch]; - else - ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); - if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) - bitset_set (sbcset, ch); + mbcset->range_starts = new_array_start; + mbcset->range_ends = new_array_end; + *range_alloc = new_nranges; } - return REG_NOERROR; + + mbcset->range_starts[mbcset->nranges] = start_collseq; + mbcset->range_ends[mbcset->nranges++] = end_collseq; } - /* Local function for parse_bracket_exp used in _LIBC environment. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument since we may update it. */ + /* Build the table for single byte characters. */ + for (ch = 0; ch < SBC_MAX; ch++) + { + uint32_t ch_collseq; + /* if (MB_CUR_MAX == 1) */ + if (nrules == 0) + ch_collseq = collseqmb[ch]; + else + ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); + if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) + bitset_set (sbcset, ch); + } + return REG_NOERROR; +} - auto inline reg_errcode_t - __attribute__ ((always_inline)) - build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, - Idx *coll_sym_alloc, const unsigned char *name) +/* Local function for parse_bracket_exp used in _LIBC environment. + Build the collating element which is represented by NAME. + The result are written to MBCSET and SBCSET. + COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a + pointer argument since we may update it. */ + +static __always_inline reg_errcode_t +build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, + Idx *coll_sym_alloc, const unsigned char *name, + uint_fast32_t nrules, int_fast32_t table_size, + const int32_t *symb_table, const unsigned char *extra) +{ + int32_t elem, idx; + size_t name_len = strlen ((const char *) name); + if (nrules != 0) { - int32_t elem, idx; - size_t name_len = strlen ((const char *) name); - if (nrules != 0) + elem = seek_collating_symbol_entry (name, name_len, symb_table, + table_size, extra); + if (elem != -1) { - elem = seek_collating_symbol_entry (name, name_len); - if (elem != -1) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - } - else if (name_len == 1) - { - /* No valid character, treat it as a normal - character. */ - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - else - return REG_ECOLLATE; - - /* Got valid collation sequence, add it as a new entry. */ - /* Check the space of the arrays. */ - if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->ncoll_syms is 0. */ - Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; - /* Use realloc since mbcset->coll_syms is NULL - if *alloc == 0. */ - int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, - new_coll_sym_alloc); - if (BE (new_coll_syms == NULL, 0)) - return REG_ESPACE; - mbcset->coll_syms = new_coll_syms; - *coll_sym_alloc = new_coll_sym_alloc; - } - mbcset->coll_syms[mbcset->ncoll_syms++] = idx; + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + } + else if (name_len == 1) + { + /* No valid character, treat it as a normal + character. */ + bitset_set (sbcset, name[0]); return REG_NOERROR; } else + return REG_ECOLLATE; + + /* Got valid collation sequence, add it as a new entry. */ + /* Check the space of the arrays. */ + if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms)) { - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } + /* Not enough, realloc it. */ + /* +1 in case of mbcset->ncoll_syms is 0. */ + int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; + /* Use realloc since mbcset->coll_syms is NULL + if *alloc == 0. */ + int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, + new_coll_sym_alloc); + if (__glibc_unlikely (new_coll_syms == NULL)) + return REG_ESPACE; + mbcset->coll_syms = new_coll_syms; + *coll_sym_alloc = new_coll_sym_alloc; } + mbcset->coll_syms[mbcset->ncoll_syms++] = idx; + return REG_NOERROR; } -#endif + else + { + if (__glibc_unlikely (name_len != 1)) + return REG_ECOLLATE; + else + { + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } + } +} +#endif /* _LIBC */ + +/* This function parse bracket expression like "[abc]", "[a-c]", + "[[.a-a.]]" etc. */ + +static bin_tree_t * +parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + reg_syntax_t syntax, reg_errcode_t *err) +{ + const unsigned char *collseqmb = NULL; + const char *collseqwc = NULL; + uint_fast32_t nrules = 0; + int_fast32_t table_size = 0; + const void *symb_table = NULL; + const unsigned char *extra = NULL; re_token_t br_token; re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N re_charset_t *mbcset; Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; Idx equiv_class_alloc = 0, char_class_alloc = 0; -#endif /* not RE_ENABLE_I18N */ bool non_match = false; bin_tree_t *work_tree; int token_len; @@ -3099,47 +3050,36 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, */ collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); + symb_table = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_TABLEMB); extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); } #endif sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else - if (BE (sbcset == NULL, 0)) -#endif /* RE_ENABLE_I18N */ + if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) { re_free (sbcset); -#ifdef RE_ENABLE_I18N re_free (mbcset); -#endif *err = REG_ESPACE; return NULL; } token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) + if (__glibc_unlikely (token->type == END_OF_RE)) { *err = REG_BADPAT; goto parse_bracket_exp_free_return; } if (token->type == OP_NON_MATCH_LIST) { -#ifdef RE_ENABLE_I18N mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ non_match = true; if (syntax & RE_HAT_LISTS_NOT_NEWLINE) bitset_set (sbcset, '\n'); re_string_skip_bytes (regexp, token_len); /* Skip a token. */ token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) + if (__glibc_unlikely (token->type == END_OF_RE)) { *err = REG_BADPAT; goto parse_bracket_exp_free_return; @@ -3161,9 +3101,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, re_token_t token2; start_elem.opr.name = start_name_buf; + start_elem.type = COLL_SYM; ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, syntax, first_round); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) { *err = ret; goto parse_bracket_exp_free_return; @@ -3176,7 +3117,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, /* Do not check for ranges if we know they are not allowed. */ if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) { - if (BE (token->type == END_OF_RE, 0)) + if (__glibc_unlikely (token->type == END_OF_RE)) { *err = REG_EBRACK; goto parse_bracket_exp_free_return; @@ -3185,7 +3126,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, { re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ token_len2 = peek_token_bracket (&token2, regexp, syntax); - if (BE (token2.type == END_OF_RE, 0)) + if (__glibc_unlikely (token2.type == END_OF_RE)) { *err = REG_EBRACK; goto parse_bracket_exp_free_return; @@ -3204,9 +3145,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, if (is_range_exp == true) { end_elem.opr.name = end_name_buf; + end_elem.type = COLL_SYM; ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, dfa, syntax, true); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) { *err = ret; goto parse_bracket_exp_free_return; @@ -3214,19 +3156,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, token_len = peek_token_bracket (token, regexp, syntax); -#ifdef _LIBC *err = build_range_exp (sbcset, mbcset, &range_alloc, - &start_elem, &end_elem); -#else -# ifdef RE_ENABLE_I18N - *err = build_range_exp (syntax, sbcset, - dfa->mb_cur_max > 1 ? mbcset : NULL, - &range_alloc, &start_elem, &end_elem); -# else - *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem); -# endif -#endif /* RE_ENABLE_I18N */ - if (BE (*err != REG_NOERROR, 0)) + &start_elem, &end_elem, + dfa, syntax, nrules, collseqmb, collseqwc, + table_size, symb_table, extra); + if (__glibc_unlikely (*err != REG_NOERROR)) goto parse_bracket_exp_free_return; } else @@ -3236,10 +3170,9 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, case SB_CHAR: bitset_set (sbcset, start_elem.opr.ch); break; -#ifdef RE_ENABLE_I18N case MB_CHAR: /* Check whether the array has enough space. */ - if (BE (mbchar_alloc == mbcset->nmbchars, 0)) + if (__glibc_unlikely (mbchar_alloc == mbcset->nmbchars)) { wchar_t *new_mbchars; /* Not enough, realloc it. */ @@ -3248,47 +3181,41 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, /* Use realloc since array is NULL if *alloc == 0. */ new_mbchars = re_realloc (mbcset->mbchars, wchar_t, mbchar_alloc); - if (BE (new_mbchars == NULL, 0)) + if (__glibc_unlikely (new_mbchars == NULL)) goto parse_bracket_exp_espace; mbcset->mbchars = new_mbchars; } mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; break; -#endif /* RE_ENABLE_I18N */ case EQUIV_CLASS: *err = build_equiv_class (sbcset, -#ifdef RE_ENABLE_I18N mbcset, &equiv_class_alloc, -#endif /* RE_ENABLE_I18N */ start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) goto parse_bracket_exp_free_return; break; case COLL_SYM: *err = build_collating_symbol (sbcset, -#ifdef RE_ENABLE_I18N mbcset, &coll_sym_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) + start_elem.opr.name, + nrules, table_size, symb_table, extra); + if (__glibc_unlikely (*err != REG_NOERROR)) goto parse_bracket_exp_free_return; break; case CHAR_CLASS: *err = build_charclass (regexp->trans, sbcset, -#ifdef RE_ENABLE_I18N mbcset, &char_class_alloc, -#endif /* RE_ENABLE_I18N */ (const char *) start_elem.opr.name, syntax); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) goto parse_bracket_exp_free_return; break; default: - assert (0); + DEBUG_ASSERT (false); break; } } - if (BE (token->type == END_OF_RE, 0)) + if (__glibc_unlikely (token->type == END_OF_RE)) { *err = REG_EBRACK; goto parse_bracket_exp_free_return; @@ -3303,7 +3230,6 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, if (non_match) bitset_not (sbcset); -#ifdef RE_ENABLE_I18N /* Ensure only single byte characters are set. */ if (dfa->mb_cur_max > 1) bitset_mask (sbcset, dfa->sb_char); @@ -3319,7 +3245,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, br_token.type = COMPLEX_BRACKET; br_token.opr.mbcset = mbcset; mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) + if (__glibc_unlikely (mbc_tree == NULL)) goto parse_bracket_exp_espace; for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx) if (sbcset[sbc_idx]) @@ -3332,12 +3258,12 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, br_token.type = SIMPLE_BRACKET; br_token.opr.sbcset = sbcset; work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) + if (__glibc_unlikely (work_tree == NULL)) goto parse_bracket_exp_espace; /* Then join them by ALT node. */ work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); - if (BE (work_tree == NULL, 0)) + if (__glibc_unlikely (work_tree == NULL)) goto parse_bracket_exp_espace; } else @@ -3347,16 +3273,13 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, } } else -#endif /* not RE_ENABLE_I18N */ { -#ifdef RE_ENABLE_I18N free_charset (mbcset); -#endif /* Build a tree for simple bracket. */ br_token.type = SIMPLE_BRACKET; br_token.opr.sbcset = sbcset; work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) + if (__glibc_unlikely (work_tree == NULL)) goto parse_bracket_exp_espace; } return work_tree; @@ -3365,9 +3288,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, *err = REG_ESPACE; parse_bracket_exp_free_return: re_free (sbcset); -#ifdef RE_ENABLE_I18N free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ return NULL; } @@ -3378,7 +3299,6 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, re_token_t *token, int token_len, re_dfa_t *dfa, reg_syntax_t syntax, bool accept_hyphen) { -#ifdef RE_ENABLE_I18N int cur_char_size; cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); if (cur_char_size > 1) @@ -3388,12 +3308,11 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, re_string_skip_bytes (regexp, cur_char_size); return REG_NOERROR; } -#endif /* RE_ENABLE_I18N */ re_string_skip_bytes (regexp, token_len); /* Skip a token. */ if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS || token->type == OP_OPEN_EQUIV_CLASS) return parse_bracket_symbol (elem, regexp, token); - if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen) + if (__glibc_unlikely (token->type == OP_CHARSET_RANGE) && !accept_hyphen) { /* A '-' must only appear as anything but a range indicator before the closing bracket. Everything else is an error. */ @@ -3461,12 +3380,8 @@ parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, is a pointer argument since we may update it. */ static reg_errcode_t -#ifdef RE_ENABLE_I18N build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, Idx *equiv_class_alloc, const unsigned char *name) -#else /* not RE_ENABLE_I18N */ -build_equiv_class (bitset_t sbcset, const unsigned char *name) -#endif /* not RE_ENABLE_I18N */ { #ifdef _LIBC uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); @@ -3478,8 +3393,6 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) int32_t idx1, idx2; unsigned int ch; size_t len; - /* This #include defines a local function! */ -# include /* Calculate the index for equivalence class. */ cp = name; table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); @@ -3489,8 +3402,8 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - idx1 = findidx (&cp, -1); - if (BE (idx1 == 0 || *cp != '\0', 0)) + idx1 = findidx (table, indirect, extra, &cp, -1); + if (__glibc_unlikely (idx1 == 0 || *cp != '\0')) /* This isn't a valid character. */ return REG_ECOLLATE; @@ -3500,7 +3413,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) { char_buf[0] = ch; cp = char_buf; - idx2 = findidx (&cp, 1); + idx2 = findidx (table, indirect, extra, &cp, 1); /* idx2 = table[ch]; */ @@ -3509,21 +3422,13 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) continue; /* Compare only if the length matches and the collation rule index is the same. */ - if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)) - { - int cnt = 0; - - while (cnt <= len && - weights[(idx1 & 0xffffff) + 1 + cnt] - == weights[(idx2 & 0xffffff) + 1 + cnt]) - ++cnt; - - if (cnt > len) - bitset_set (sbcset, ch); - } + if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24) + && memcmp (weights + (idx1 & 0xffffff) + 1, + weights + (idx2 & 0xffffff) + 1, len) == 0) + bitset_set (sbcset, ch); } /* Check whether the array has enough space. */ - if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0)) + if (__glibc_unlikely (*equiv_class_alloc == mbcset->nequiv_classes)) { /* Not enough, realloc it. */ /* +1 in case of mbcset->nequiv_classes is 0. */ @@ -3532,7 +3437,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, int32_t, new_equiv_class_alloc); - if (BE (new_equiv_classes == NULL, 0)) + if (__glibc_unlikely (new_equiv_classes == NULL)) return REG_ESPACE; mbcset->equiv_classes = new_equiv_classes; *equiv_class_alloc = new_equiv_class_alloc; @@ -3542,7 +3447,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) else #endif /* _LIBC */ { - if (BE (strlen ((const char *) name) != 1, 0)) + if (__glibc_unlikely (strlen ((const char *) name) != 1)) return REG_ECOLLATE; bitset_set (sbcset, *name); } @@ -3556,14 +3461,9 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) is a pointer argument since we may update it. */ static reg_errcode_t -#ifdef RE_ENABLE_I18N build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, re_charset_t *mbcset, Idx *char_class_alloc, const char *class_name, reg_syntax_t syntax) -#else /* not RE_ENABLE_I18N */ -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - const char *class_name, reg_syntax_t syntax) -#endif /* not RE_ENABLE_I18N */ { int i; const char *name = class_name; @@ -3574,9 +3474,8 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0)) name = "alpha"; -#ifdef RE_ENABLE_I18N /* Check the space of the arrays. */ - if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) + if (__glibc_unlikely (*char_class_alloc == mbcset->nchar_classes)) { /* Not enough, realloc it. */ /* +1 in case of mbcset->nchar_classes is 0. */ @@ -3584,17 +3483,16 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, /* Use realloc since array is NULL if *alloc == 0. */ wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t, new_char_class_alloc); - if (BE (new_char_classes == NULL, 0)) + if (__glibc_unlikely (new_char_classes == NULL)) return REG_ESPACE; mbcset->char_classes = new_char_classes; *char_class_alloc = new_char_class_alloc; } mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); -#endif /* RE_ENABLE_I18N */ #define BUILD_CHARCLASS_LOOP(ctype_func) \ do { \ - if (BE (trans != NULL, 0)) \ + if (__glibc_unlikely (trans != NULL)) \ { \ for (i = 0; i < SBC_MAX; ++i) \ if (ctype_func (i)) \ @@ -3645,49 +3543,33 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, reg_errcode_t *err) { re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N re_charset_t *mbcset; Idx alloc = 0; -#endif /* not RE_ENABLE_I18N */ reg_errcode_t ret; - re_token_t br_token; bin_tree_t *tree; sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ - -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else /* not RE_ENABLE_I18N */ - if (BE (sbcset == NULL, 0)) -#endif /* not RE_ENABLE_I18N */ + if (__glibc_unlikely (sbcset == NULL)) { *err = REG_ESPACE; return NULL; } - - if (non_match) + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); + if (__glibc_unlikely (mbcset == NULL)) { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ + re_free (sbcset); + *err = REG_ESPACE; + return NULL; } + mbcset->non_match = non_match; /* We don't care the syntax in this case. */ - ret = build_charclass (trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &alloc, -#endif /* RE_ENABLE_I18N */ - class_name, 0); + ret = build_charclass (trans, sbcset, mbcset, &alloc, class_name, 0); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) { re_free (sbcset); -#ifdef RE_ENABLE_I18N free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ *err = ret; return NULL; } @@ -3699,20 +3581,16 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, if (non_match) bitset_not (sbcset); -#ifdef RE_ENABLE_I18N /* Ensure only single byte characters are set. */ if (dfa->mb_cur_max > 1) bitset_mask (sbcset, dfa->sb_char); -#endif /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; + re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset }; tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (tree == NULL, 0)) + if (__glibc_unlikely (tree == NULL)) goto build_word_op_espace; -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) { bin_tree_t *mbc_tree; @@ -3721,11 +3599,11 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, br_token.opr.mbcset = mbcset; dfa->has_mb_node = 1; mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) + if (__glibc_unlikely (mbc_tree == NULL)) goto build_word_op_espace; /* Then join them by ALT node. */ tree = create_tree (dfa, tree, mbc_tree, OP_ALT); - if (BE (mbc_tree != NULL, 1)) + if (__glibc_likely (mbc_tree != NULL)) return tree; } else @@ -3733,63 +3611,55 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, free_charset (mbcset); return tree; } -#else /* not RE_ENABLE_I18N */ - return tree; -#endif /* not RE_ENABLE_I18N */ build_word_op_espace: re_free (sbcset); -#ifdef RE_ENABLE_I18N free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ *err = REG_ESPACE; return NULL; } /* This is intended for the expressions like "a{1,3}". Fetch a number from 'input', and return the number. - Return REG_MISSING if the number field is empty like "{,1}". + Return -1 if the number field is empty like "{,1}". Return RE_DUP_MAX + 1 if the number field is too large. - Return REG_ERROR if an error occurred. */ + Return -2 if an error occurred. */ static Idx fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) { - Idx num = REG_MISSING; + Idx num = -1; unsigned char c; while (1) { fetch_token (token, input, syntax); c = token->opr.c; - if (BE (token->type == END_OF_RE, 0)) - return REG_ERROR; + if (__glibc_unlikely (token->type == END_OF_RE)) + return -2; if (token->type == OP_CLOSE_DUP_NUM || c == ',') break; - num = ((token->type != CHARACTER || c < '0' || '9' < c - || num == REG_ERROR) - ? REG_ERROR - : num == REG_MISSING + num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2) + ? -2 + : num == -1 ? c - '0' : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); } return num; } -#ifdef RE_ENABLE_I18N static void free_charset (re_charset_t *cset) { re_free (cset->mbchars); -# ifdef _LIBC +#ifdef _LIBC re_free (cset->coll_syms); re_free (cset->equiv_classes); +#endif re_free (cset->range_starts); re_free (cset->range_ends); -# endif re_free (cset->char_classes); re_free (cset); } -#endif /* RE_ENABLE_I18N */ /* Functions for binary tree operation. */ @@ -3799,8 +3669,7 @@ static bin_tree_t * create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, re_token_type_t type) { - re_token_t t; - t.type = type; + re_token_t t = { .type = type }; return create_token_tree (dfa, left, right, &t); } @@ -3809,7 +3678,7 @@ create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, const re_token_t *token) { bin_tree_t *tree; - if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0)) + if (__glibc_unlikely (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE)) { bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); @@ -3829,7 +3698,7 @@ create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, tree->token.opt_subexp = 0; tree->first = NULL; tree->next = NULL; - tree->node_idx = REG_MISSING; + tree->node_idx = -1; if (left != NULL) left->parent = tree; @@ -3856,13 +3725,10 @@ mark_opt_subexp (void *extra, bin_tree_t *node) static void free_token (re_token_t *node) { -#ifdef RE_ENABLE_I18N if (node->type == COMPLEX_BRACKET && node->duplicated == 0) free_charset (node->opr.mbcset); - else -#endif /* RE_ENABLE_I18N */ - if (node->type == SIMPLE_BRACKET && node->duplicated == 0) - re_free (node->opr.sbcset); + else if (node->type == SIMPLE_BRACKET && node->duplicated == 0) + re_free (node->opr.sbcset); } /* Worker function for tree walking. Free the allocated memory inside NODE diff --git a/gl/regex.c b/gl/regex.c index 5a0332e0..ff117678 100644 --- a/gl/regex.c +++ b/gl/regex.c @@ -1,29 +1,32 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ + +#define __STDC_WANT_IEC_60559_BFP_EXT__ #ifndef _LIBC -# include +# include -# if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ +# if __GNUC_PREREQ (4, 6) # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" +# pragma GCC diagnostic ignored "-Wvla" # endif -# if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ +# if __GNUC_PREREQ (4, 3) # pragma GCC diagnostic ignored "-Wold-style-definition" # pragma GCC diagnostic ignored "-Wtype-limits" # endif diff --git a/gl/regex.h b/gl/regex.h index 854c6eda..a7e0bd02 100644 --- a/gl/regex.h +++ b/gl/regex.h @@ -1,22 +1,21 @@ /* Definitions for data structures and routines for the regular expression library. - Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2013 Free Software - Foundation, Inc. + Copyright (C) 1985, 1989-2022 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 + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ #ifndef _REGEX_H #define _REGEX_H 1 @@ -42,11 +41,6 @@ extern "C" { supported within glibc itself, and glibc users should not define _REGEX_LARGE_OFFSETS. */ -/* The type of nonnegative object indexes. Traditionally, GNU regex - uses 'int' for these. Code that uses __re_idx_t should work - regardless of whether the type is signed. */ -typedef size_t __re_idx_t; - /* The type of object sizes. */ typedef size_t __re_size_t; @@ -58,7 +52,6 @@ typedef size_t __re_long_size_t; /* The traditional GNU regex implementation mishandles strings longer than INT_MAX. */ -typedef int __re_idx_t; typedef unsigned int __re_size_t; typedef unsigned long int __re_long_size_t; @@ -244,19 +237,16 @@ extern reg_syntax_t re_syntax_options; | RE_INVALID_INTERVAL_ORD) # define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) + ((RE_SYNTAX_POSIX_BASIC | RE_NEWLINE_ALT) \ + & ~(RE_CONTEXT_INVALID_DUP | RE_DOT_NOT_NULL)) # define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) + ((RE_SYNTAX_POSIX_EXTENDED | RE_INVALID_INTERVAL_ORD | RE_NEWLINE_ALT) \ + & ~(RE_CONTEXT_INVALID_OPS | RE_DOT_NOT_NULL)) +/* POSIX grep -E behavior is no longer incompatible with GNU. */ # define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ - | RE_INVALID_INTERVAL_ORD) + RE_SYNTAX_EGREP /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ # define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC @@ -491,7 +481,8 @@ typedef struct re_pattern_buffer regex_t; #ifdef _REGEX_LARGE_OFFSETS /* POSIX 1003.1-2008 requires that regoff_t be at least as wide as ptrdiff_t and ssize_t. We don't know of any hosts where ptrdiff_t - is wider than ssize_t, so ssize_t is safe. */ + is wider than ssize_t, so ssize_t is safe. ptrdiff_t is not + visible here, so use ssize_t. */ typedef ssize_t regoff_t; #else /* The traditional GNU regex implementation mishandles strings longer @@ -531,6 +522,30 @@ typedef struct /* Declarations for routines. */ +#ifndef _REGEX_NELTS +# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \ + && !defined __STDC_NO_VLA__) +# define _REGEX_NELTS(n) n +# else +# define _REGEX_NELTS(n) +# endif +#endif + +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wvla" +#endif + +#ifndef _Attr_access_ +# ifdef __attr_access +# define _Attr_access_(arg) __attr_access (arg) +# elif defined __GNUC__ && 10 <= __GNUC__ +# define _Attr_access_(x) __attribute__ ((__access__ x)) +# else +# define _Attr_access_(x) +# endif +#endif + #ifdef __USE_GNU /* Sets the current default syntax to SYNTAX, and return the old syntax. You can also simply assign to the 're_syntax_options' variable. */ @@ -541,11 +556,12 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); BUFFER. Return NULL if successful, and an error string if not. To free the allocated storage, you must call 'regfree' on BUFFER. - Note that the translate table must either have been initialised by + Note that the translate table must either have been initialized by 'regcomp', with a malloc'ed value, or set to NULL before calling 'regfree'. */ extern const char *re_compile_pattern (const char *__pattern, size_t __length, - struct re_pattern_buffer *__buffer); + struct re_pattern_buffer *__buffer) + _Attr_access_ ((__read_only__, 1, 2)); /* Compile a fastmap for the compiled pattern in BUFFER; used to @@ -560,34 +576,40 @@ extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ extern regoff_t re_search (struct re_pattern_buffer *__buffer, - const char *__string, __re_idx_t __length, - __re_idx_t __start, regoff_t __range, - struct re_registers *__regs); + const char *__String, regoff_t __length, + regoff_t __start, regoff_t __range, + struct re_registers *__regs) + _Attr_access_ ((__read_only__, 2, 3)); /* Like 're_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, - const char *__string1, __re_idx_t __length1, - const char *__string2, __re_idx_t __length2, - __re_idx_t __start, regoff_t __range, + const char *__string1, regoff_t __length1, + const char *__string2, regoff_t __length2, + regoff_t __start, regoff_t __range, struct re_registers *__regs, - __re_idx_t __stop); + regoff_t __stop) + _Attr_access_ ((__read_only__, 2, 3)) + _Attr_access_ ((__read_only__, 4, 5)); /* Like 're_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ extern regoff_t re_match (struct re_pattern_buffer *__buffer, - const char *__string, __re_idx_t __length, - __re_idx_t __start, struct re_registers *__regs); + const char *__String, regoff_t __length, + regoff_t __start, struct re_registers *__regs) + _Attr_access_ ((__read_only__, 2, 3)); /* Relates to 're_match' as 're_search_2' relates to 're_search'. */ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, - const char *__string1, __re_idx_t __length1, - const char *__string2, __re_idx_t __length2, - __re_idx_t __start, struct re_registers *__regs, - __re_idx_t __stop); + const char *__string1, regoff_t __length1, + const char *__string2, regoff_t __length2, + regoff_t __start, struct re_registers *__regs, + regoff_t __stop) + _Attr_access_ ((__read_only__, 2, 3)) + _Attr_access_ ((__read_only__, 4, 5)); /* Set REGS to hold NUM_REGS registers, storing them in STARTS and @@ -608,36 +630,41 @@ extern void re_set_registers (struct re_pattern_buffer *__buffer, regoff_t *__starts, regoff_t *__ends); #endif /* Use GNU */ -#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_BSD) -# ifndef _CRAY +#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_MISC) /* 4.2 bsd compatibility. */ extern char *re_comp (const char *); extern int re_exec (const char *); -# endif #endif -/* GCC 2.95 and later have "__restrict"; C99 compilers have +/* For plain 'restrict', use glibc's __restrict if defined. + Otherwise, GCC 2.95 and later have "__restrict"; C99 compilers have "restrict", and "configure" may have defined "restrict". Other compilers use __restrict, __restrict__, and _Restrict, and 'configure' might #define 'restrict' to those words, so pick a different name. */ #ifndef _Restrict_ -# if 199901L <= __STDC_VERSION__ -# define _Restrict_ restrict -# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) +# if defined __restrict \ + || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ + || __clang_major__ >= 3 # define _Restrict_ __restrict +# elif 199901L <= __STDC_VERSION__ || defined restrict +# define _Restrict_ restrict # else # define _Restrict_ # endif #endif -/* gcc 3.1 and up support the [restrict] syntax. Don't trust - sys/cdefs.h's definition of __restrict_arr, though, as it - mishandles gcc -ansi -pedantic. */ +/* For the ISO C99 syntax + array_name[restrict] + use glibc's __restrict_arr if available. + Otherwise, GCC 3.1 and clang support this syntax (but not in C++ mode). + Other ISO C99 compilers support it as well. */ #ifndef _Restrict_arr_ -# if ((199901L <= __STDC_VERSION__ \ - || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ - && !defined __STRICT_ANSI__)) \ - && !defined __GNUG__) +# ifdef __restrict_arr +# define _Restrict_arr_ __restrict_arr +# elif ((199901L <= __STDC_VERSION__ \ + || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \ + || __clang_major__ >= 3) \ + && !defined __cplusplus) # define _Restrict_arr_ _Restrict_ # else # define _Restrict_arr_ @@ -650,15 +677,20 @@ extern int regcomp (regex_t *_Restrict_ __preg, int __cflags); extern int regexec (const regex_t *_Restrict_ __preg, - const char *_Restrict_ __string, size_t __nmatch, - regmatch_t __pmatch[_Restrict_arr_], + const char *_Restrict_ __String, size_t __nmatch, + regmatch_t __pmatch[_Restrict_arr_ + _REGEX_NELTS (__nmatch)], int __eflags); extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, - char *_Restrict_ __errbuf, size_t __errbuf_size); + char *_Restrict_ __errbuf, size_t __errbuf_size) + _Attr_access_ ((__write_only__, 3, 4)); extern void regfree (regex_t *__preg); +#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic pop +#endif #ifdef __cplusplus } diff --git a/gl/regex_internal.c b/gl/regex_internal.c index 899b0ae6..0e6919f3 100644 --- a/gl/regex_internal.c +++ b/gl/regex_internal.c @@ -1,33 +1,41 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ static void re_string_construct_common (const char *str, Idx len, re_string_t *pstr, RE_TRANSLATE_TYPE trans, bool icase, - const re_dfa_t *dfa) internal_function; + const re_dfa_t *dfa); static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - re_hashval_t hash) internal_function; + re_hashval_t hash); static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context, - re_hashval_t hash) internal_function; + re_hashval_t hash); +static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, + Idx new_buf_len); +static void build_wcs_buffer (re_string_t *pstr); +static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr); +static void build_upper_buffer (re_string_t *pstr); +static void re_string_translate_buffer (re_string_t *pstr); +static unsigned int re_string_context_at (const re_string_t *input, Idx idx, + int eflags) __attribute__ ((pure)); /* Functions for string operation. */ @@ -35,7 +43,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, re_string_reconstruct before using the object. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) { @@ -49,7 +57,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, re_string_construct_common (str, len, pstr, trans, icase, dfa); ret = re_string_realloc_buffers (pstr, init_buf_len); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; pstr->word_char = dfa->word_char; @@ -63,7 +71,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, /* This function allocate the buffers, and initialize them. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_string_construct (re_string_t *pstr, const char *str, Idx len, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) { @@ -74,41 +82,37 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len, if (len > 0) { ret = re_string_realloc_buffers (pstr, len + 1); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; } pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; if (icase) { -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) { while (1) { ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; if (pstr->valid_raw_len >= len) break; if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) break; ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; } } else -#endif /* RE_ENABLE_I18N */ build_upper_buffer (pstr); } else { -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) build_wcs_buffer (pstr); else -#endif /* RE_ENABLE_I18N */ { if (trans != NULL) re_string_translate_buffer (pstr); @@ -126,37 +130,36 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len, /* Helper functions for re_string_allocate, and re_string_construct. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) { -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) { wint_t *new_wcs; /* Avoid overflow in realloc. */ const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_buf_len, 0)) + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) + < new_buf_len)) return REG_ESPACE; new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); - if (BE (new_wcs == NULL, 0)) + if (__glibc_unlikely (new_wcs == NULL)) return REG_ESPACE; pstr->wcs = new_wcs; if (pstr->offsets != NULL) { Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); - if (BE (new_offsets == NULL, 0)) + if (__glibc_unlikely (new_offsets == NULL)) return REG_ESPACE; pstr->offsets = new_offsets; } } -#endif /* RE_ENABLE_I18N */ if (pstr->mbs_allocated) { unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, new_buf_len); - if (BE (new_mbs == NULL, 0)) + if (__glibc_unlikely (new_mbs == NULL)) return REG_ESPACE; pstr->mbs = new_mbs; } @@ -166,7 +169,6 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) static void -internal_function re_string_construct_common (const char *str, Idx len, re_string_t *pstr, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) @@ -184,7 +186,6 @@ re_string_construct_common (const char *str, Idx len, re_string_t *pstr, pstr->raw_stop = pstr->stop; } -#ifdef RE_ENABLE_I18N /* Build wide character buffer PSTR->WCS. If the byte sequence of the string are: @@ -198,12 +199,11 @@ re_string_construct_common (const char *str, Idx len, re_string_t *pstr, built and starts from PSTR->VALID_LEN. */ static void -internal_function build_wcs_buffer (re_string_t *pstr) { #ifdef _LIBC unsigned char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); + DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max); #else unsigned char buf[64]; #endif @@ -222,7 +222,7 @@ build_wcs_buffer (re_string_t *pstr) remain_len = end_idx - byte_idx; prev_st = pstr->cur_state; /* Apply the translation if we need. */ - if (BE (pstr->trans != NULL, 0)) + if (__glibc_unlikely (pstr->trans != NULL)) { int i, ch; @@ -236,17 +236,18 @@ build_wcs_buffer (re_string_t *pstr) else p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -1 || mbclen == 0 - || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0)) + if (__glibc_unlikely (mbclen == (size_t) -1 || mbclen == 0 + || (mbclen == (size_t) -2 + && pstr->bufs_len >= pstr->len))) { /* We treat these cases as a singlebyte character. */ mbclen = 1; wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - if (BE (pstr->trans != NULL, 0)) + if (__glibc_unlikely (pstr->trans != NULL)) wc = pstr->trans[wc]; pstr->cur_state = prev_st; } - else if (BE (mbclen == (size_t) -2, 0)) + else if (__glibc_unlikely (mbclen == (size_t) -2)) { /* The buffer doesn't have enough space, finish to build. */ pstr->cur_state = prev_st; @@ -267,7 +268,7 @@ build_wcs_buffer (re_string_t *pstr) but for REG_ICASE. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ build_wcs_upper_buffer (re_string_t *pstr) { mbstate_t prev_st; @@ -275,7 +276,7 @@ build_wcs_upper_buffer (re_string_t *pstr) size_t mbclen; #ifdef _LIBC char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); + DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX); #else char buf[64]; #endif @@ -290,18 +291,20 @@ build_wcs_upper_buffer (re_string_t *pstr) while (byte_idx < end_idx) { wchar_t wc; + unsigned char ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) - && mbsinit (&pstr->cur_state)) + if (isascii (ch) && mbsinit (&pstr->cur_state)) { - /* In case of a singlebyte character. */ - pstr->mbs[byte_idx] - = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]); /* The next step uses the assumption that wchar_t is encoded ASCII-safe: all ASCII values can be converted like this. */ - pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; - ++byte_idx; - continue; + wchar_t wcu = __towupper (ch); + if (isascii (wcu)) + { + pstr->mbs[byte_idx] = wcu; + pstr->wcs[byte_idx] = wcu; + byte_idx++; + continue; + } } remain_len = end_idx - byte_idx; @@ -309,16 +312,15 @@ build_wcs_upper_buffer (re_string_t *pstr) mbclen = __mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx), remain_len, &pstr->cur_state); - if (BE (mbclen < (size_t) -2, 1)) + if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2)) { - wchar_t wcu = wc; - if (iswlower (wc)) + wchar_t wcu = __towupper (wc); + if (wcu != wc) { size_t mbcdlen; - wcu = towupper (wc); - mbcdlen = wcrtomb (buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) + mbcdlen = __wcrtomb (buf, wcu, &prev_st); + if (__glibc_likely (mbclen == mbcdlen)) memcpy (pstr->mbs + byte_idx, buf, mbclen); else { @@ -339,11 +341,10 @@ build_wcs_upper_buffer (re_string_t *pstr) { /* It is an invalid character, an incomplete character at the end of the string, or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; pstr->mbs[byte_idx] = ch; /* And also cast it to wide char. */ pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) + if (__glibc_unlikely (mbclen == (size_t) -1)) pstr->cur_state = prev_st; } else @@ -365,7 +366,7 @@ build_wcs_upper_buffer (re_string_t *pstr) offsets_needed: remain_len = end_idx - byte_idx; prev_st = pstr->cur_state; - if (BE (pstr->trans != NULL, 0)) + if (__glibc_unlikely (pstr->trans != NULL)) { int i, ch; @@ -379,16 +380,15 @@ build_wcs_upper_buffer (re_string_t *pstr) else p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen < (size_t) -2, 1)) + if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2)) { - wchar_t wcu = wc; - if (iswlower (wc)) + wchar_t wcu = __towupper (wc); + if (wcu != wc) { size_t mbcdlen; - wcu = towupper (wc); - mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) + mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st); + if (__glibc_likely (mbclen == mbcdlen)) memcpy (pstr->mbs + byte_idx, buf, mbclen); else if (mbcdlen != (size_t) -1) { @@ -438,7 +438,7 @@ build_wcs_upper_buffer (re_string_t *pstr) else memcpy (pstr->mbs + byte_idx, p, mbclen); - if (BE (pstr->offsets_needed != 0, 0)) + if (__glibc_unlikely (pstr->offsets_needed != 0)) { size_t i; for (i = 0; i < mbclen; ++i) @@ -457,17 +457,17 @@ build_wcs_upper_buffer (re_string_t *pstr) /* It is an invalid character or '\0'. Just use the byte. */ int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; - if (BE (pstr->trans != NULL, 0)) + if (__glibc_unlikely (pstr->trans != NULL)) ch = pstr->trans [ch]; pstr->mbs[byte_idx] = ch; - if (BE (pstr->offsets_needed != 0, 0)) + if (__glibc_unlikely (pstr->offsets_needed != 0)) pstr->offsets[byte_idx] = src_idx; ++src_idx; /* And also cast it to wide char. */ pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) + if (__glibc_unlikely (mbclen == (size_t) -1)) pstr->cur_state = prev_st; } else @@ -486,7 +486,6 @@ build_wcs_upper_buffer (re_string_t *pstr) Return the index. */ static Idx -internal_function re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) { mbstate_t prev_st; @@ -503,7 +502,8 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) prev_st = pstr->cur_state; mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) + if (__glibc_unlikely (mbclen == (size_t) -2 || mbclen == (size_t) -1 + || mbclen == 0)) { /* We treat these cases as a single byte character. */ if (mbclen == 0 || remain_len == 0) @@ -521,13 +521,11 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) *last_wc = wc; return rawbuf_idx; } -#endif /* RE_ENABLE_I18N */ /* Build the buffer PSTR->MBS, and apply the translation if we need. This function is used in case of REG_ICASE. */ static void -internal_function build_upper_buffer (re_string_t *pstr) { Idx char_idx, end_idx; @@ -536,12 +534,9 @@ build_upper_buffer (re_string_t *pstr) for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) { int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; - if (BE (pstr->trans != NULL, 0)) + if (__glibc_unlikely (pstr->trans != NULL)) ch = pstr->trans[ch]; - if (islower (ch)) - pstr->mbs[char_idx] = toupper (ch); - else - pstr->mbs[char_idx] = ch; + pstr->mbs[char_idx] = toupper (ch); } pstr->valid_len = char_idx; pstr->valid_raw_len = char_idx; @@ -550,7 +545,6 @@ build_upper_buffer (re_string_t *pstr) /* Apply TRANS to the buffer in PSTR. */ static void -internal_function re_string_translate_buffer (re_string_t *pstr) { Idx buf_idx, end_idx; @@ -571,20 +565,18 @@ re_string_translate_buffer (re_string_t *pstr) convert to upper case in case of REG_ICASE, apply translation. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) { Idx offset; - if (BE (pstr->raw_mbs_idx <= idx, 0)) + if (__glibc_unlikely (pstr->raw_mbs_idx <= idx)) offset = idx - pstr->raw_mbs_idx; else { /* Reset buffer. */ -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); -#endif /* RE_ENABLE_I18N */ pstr->len = pstr->raw_len; pstr->stop = pstr->raw_stop; pstr->valid_len = 0; @@ -598,14 +590,13 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) offset = idx; } - if (BE (offset != 0, 1)) + if (__glibc_likely (offset != 0)) { /* Should the already checked characters be kept? */ - if (BE (offset < pstr->valid_raw_len, 1)) + if (__glibc_likely (offset < pstr->valid_raw_len)) { /* Yes, move them to the front of the buffer. */ -#ifdef RE_ENABLE_I18N - if (BE (pstr->offsets_needed, 0)) + if (__glibc_unlikely (pstr->offsets_needed)) { Idx low = 0, high = pstr->valid_len, mid; do @@ -668,40 +659,32 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) } } else -#endif { pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags); -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) memmove (pstr->wcs, pstr->wcs + offset, (pstr->valid_len - offset) * sizeof (wint_t)); -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) + if (__glibc_unlikely (pstr->mbs_allocated)) memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset); pstr->valid_len -= offset; pstr->valid_raw_len -= offset; -#if DEBUG - assert (pstr->valid_len > 0); -#endif + DEBUG_ASSERT (pstr->valid_len > 0); } } else { -#ifdef RE_ENABLE_I18N /* No, skip all characters until IDX. */ Idx prev_valid_len = pstr->valid_len; - if (BE (pstr->offsets_needed, 0)) + if (__glibc_unlikely (pstr->offsets_needed)) { pstr->len = pstr->raw_len - idx + offset; pstr->stop = pstr->raw_stop - idx + offset; pstr->offsets_needed = 0; } -#endif pstr->valid_len = 0; -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) { Idx wcs_idx; @@ -721,7 +704,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) #ifdef _LIBC /* We know the wchar_t encoding is UCS4, so for the simple case, ASCII characters, skip the conversion step. */ - if (isascii (*p) && BE (pstr->trans == NULL, 1)) + if (isascii (*p) && __glibc_likely (pstr->trans == NULL)) { memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); /* pstr->valid_len = 0; */ @@ -739,7 +722,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) size_t mbclen; const unsigned char *pp = p; - if (BE (pstr->trans != NULL, 0)) + if (__glibc_unlikely (pstr->trans != NULL)) { int i = mlen < 6 ? mlen : 6; while (--i >= 0) @@ -769,13 +752,13 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) pstr->tip_context = re_string_context_at (pstr, prev_valid_len - 1, eflags); else - pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) + pstr->tip_context = ((__glibc_unlikely (pstr->word_ops_used != 0) && IS_WIDE_WORD_CHAR (wc)) ? CONTEXT_WORD : ((IS_WIDE_NEWLINE (wc) && pstr->newline_anchor) ? CONTEXT_NEWLINE : 0)); - if (BE (pstr->valid_len, 0)) + if (__glibc_unlikely (pstr->valid_len)) { for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) pstr->wcs[wcs_idx] = WEOF; @@ -785,7 +768,6 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) pstr->valid_raw_len = pstr->valid_len; } else -#endif /* RE_ENABLE_I18N */ { int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; pstr->valid_raw_len = 0; @@ -797,7 +779,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) ? CONTEXT_NEWLINE : 0)); } } - if (!BE (pstr->mbs_allocated, 0)) + if (!__glibc_unlikely (pstr->mbs_allocated)) pstr->mbs += offset; } pstr->raw_mbs_idx = idx; @@ -805,21 +787,19 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) pstr->stop -= offset; /* Then build the buffers. */ -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) { if (pstr->icase) { reg_errcode_t ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; } else build_wcs_buffer (pstr); } else -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) + if (__glibc_unlikely (pstr->mbs_allocated)) { if (pstr->icase) build_upper_buffer (pstr); @@ -834,50 +814,42 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) } static unsigned char -internal_function __attribute__ ((pure)) +__attribute__ ((pure)) re_string_peek_byte_case (const re_string_t *pstr, Idx idx) { int ch; Idx off; /* Handle the common (easiest) cases first. */ - if (BE (!pstr->mbs_allocated, 1)) + if (__glibc_likely (!pstr->mbs_allocated)) return re_string_peek_byte (pstr, idx); -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1 && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) return re_string_peek_byte (pstr, idx); -#endif off = pstr->cur_idx + idx; -#ifdef RE_ENABLE_I18N if (pstr->offsets_needed) off = pstr->offsets[off]; -#endif ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; -#ifdef RE_ENABLE_I18N /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I this function returns CAPITAL LETTER I instead of first byte of DOTLESS SMALL LETTER I. The latter would confuse the parser, since peek_byte_case doesn't advance cur_idx in any way. */ if (pstr->offsets_needed && !isascii (ch)) return re_string_peek_byte (pstr, idx); -#endif return ch; } static unsigned char -internal_function re_string_fetch_byte_case (re_string_t *pstr) { - if (BE (!pstr->mbs_allocated, 1)) + if (__glibc_likely (!pstr->mbs_allocated)) return re_string_fetch_byte (pstr); -#ifdef RE_ENABLE_I18N if (pstr->offsets_needed) { Idx off; @@ -903,19 +875,15 @@ re_string_fetch_byte_case (re_string_t *pstr) re_string_char_size_at (pstr, pstr->cur_idx)); return ch; } -#endif return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; } static void -internal_function re_string_destruct (re_string_t *pstr) { -#ifdef RE_ENABLE_I18N re_free (pstr->wcs); re_free (pstr->offsets); -#endif /* RE_ENABLE_I18N */ if (pstr->mbs_allocated) re_free (pstr->mbs); } @@ -923,40 +891,35 @@ re_string_destruct (re_string_t *pstr) /* Return the context at IDX in INPUT. */ static unsigned int -internal_function re_string_context_at (const re_string_t *input, Idx idx, int eflags) { int c; - if (BE (! REG_VALID_INDEX (idx), 0)) + if (__glibc_unlikely (idx < 0)) /* In this case, we use the value stored in input->tip_context, since we can't know the character in input->mbs[-1] here. */ return input->tip_context; - if (BE (idx == input->len, 0)) + if (__glibc_unlikely (idx == input->len)) return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF : CONTEXT_NEWLINE | CONTEXT_ENDBUF); -#ifdef RE_ENABLE_I18N if (input->mb_cur_max > 1) { wint_t wc; Idx wc_idx = idx; while(input->wcs[wc_idx] == WEOF) { -#ifdef DEBUG - /* It must not happen. */ - assert (REG_VALID_INDEX (wc_idx)); -#endif + DEBUG_ASSERT (wc_idx >= 0); --wc_idx; - if (! REG_VALID_INDEX (wc_idx)) + if (wc_idx < 0) return input->tip_context; } wc = input->wcs[wc_idx]; - if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) + if (__glibc_unlikely (input->word_ops_used != 0) + && IS_WIDE_WORD_CHAR (wc)) return CONTEXT_WORD; return (IS_WIDE_NEWLINE (wc) && input->newline_anchor ? CONTEXT_NEWLINE : 0); } else -#endif { c = re_string_byte_at (input, idx); if (bitset_contain (input->word_char, c)) @@ -968,25 +931,26 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags) /* Functions for set operation. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_alloc (re_node_set *set, Idx size) { set->alloc = size; set->nelem = 0; set->elems = re_malloc (Idx, size); - if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0)) + if (__glibc_unlikely (set->elems == NULL) + && (MALLOC_0_IS_NONNULL || size != 0)) return REG_ESPACE; return REG_NOERROR; } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_init_1 (re_node_set *set, Idx elem) { set->alloc = 1; set->nelem = 1; set->elems = re_malloc (Idx, 1); - if (BE (set->elems == NULL, 0)) + if (__glibc_unlikely (set->elems == NULL)) { set->alloc = set->nelem = 0; return REG_ESPACE; @@ -996,12 +960,12 @@ re_node_set_init_1 (re_node_set *set, Idx elem) } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) { set->alloc = 2; set->elems = re_malloc (Idx, 2); - if (BE (set->elems == NULL, 0)) + if (__glibc_unlikely (set->elems == NULL)) return REG_ESPACE; if (elem1 == elem2) { @@ -1026,7 +990,7 @@ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_init_copy (re_node_set *dest, const re_node_set *src) { dest->nelem = src->nelem; @@ -1034,7 +998,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src) { dest->alloc = dest->nelem; dest->elems = re_malloc (Idx, dest->alloc); - if (BE (dest->elems == NULL, 0)) + if (__glibc_unlikely (dest->elems == NULL)) { dest->alloc = dest->nelem = 0; return REG_ESPACE; @@ -1051,7 +1015,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src) Note: We assume dest->elems is NULL, when dest->alloc is 0. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, const re_node_set *src2) { @@ -1065,7 +1029,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, { Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); - if (BE (new_elems == NULL, 0)) + if (__glibc_unlikely (new_elems == NULL)) return REG_ESPACE; dest->elems = new_elems; dest->alloc = new_alloc; @@ -1082,25 +1046,25 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, if (src1->elems[i1] == src2->elems[i2]) { /* Try to find the item in DEST. Maybe we could binary search? */ - while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) + while (id >= 0 && dest->elems[id] > src1->elems[i1]) --id; - if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) + if (id < 0 || dest->elems[id] != src1->elems[i1]) dest->elems[--sbase] = src1->elems[i1]; - if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) + if (--i1 < 0 || --i2 < 0) break; } /* Lower the highest of the two items. */ else if (src1->elems[i1] < src2->elems[i2]) { - if (! REG_VALID_INDEX (--i2)) + if (--i2 < 0) break; } else { - if (! REG_VALID_INDEX (--i1)) + if (--i1 < 0) break; } } @@ -1113,7 +1077,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, DEST elements are already in place; this is more or less the same loop that is in re_node_set_merge. */ dest->nelem += delta; - if (delta > 0 && REG_VALID_INDEX (id)) + if (delta > 0 && id >= 0) for (;;) { if (dest->elems[is] > dest->elems[id]) @@ -1127,7 +1091,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, { /* Slide from the bottom. */ dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) + if (--id < 0) break; } } @@ -1142,7 +1106,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_init_union (re_node_set *dest, const re_node_set *src1, const re_node_set *src2) { @@ -1151,7 +1115,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1, { dest->alloc = src1->nelem + src2->nelem; dest->elems = re_malloc (Idx, dest->alloc); - if (BE (dest->elems == NULL, 0)) + if (__glibc_unlikely (dest->elems == NULL)) return REG_ESPACE; } else @@ -1195,7 +1159,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1, DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_merge (re_node_set *dest, const re_node_set *src) { Idx is, id, sbase, delta; @@ -1205,14 +1169,18 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) { Idx new_alloc = 2 * (src->nelem + dest->alloc); Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); - if (BE (new_buffer == NULL, 0)) + if (__glibc_unlikely (new_buffer == NULL)) return REG_ESPACE; dest->elems = new_buffer; dest->alloc = new_alloc; } - if (BE (dest->nelem == 0, 0)) + if (__glibc_unlikely (dest->nelem == 0)) { + /* Although we already guaranteed above that dest->alloc != 0 and + therefore dest->elems != NULL, add a debug assertion to pacify + GCC 11.2.1's -fanalyzer. */ + DEBUG_ASSERT (dest->elems); dest->nelem = src->nelem; memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); return REG_NOERROR; @@ -1221,8 +1189,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) /* Copy into the top of DEST the items of SRC that are not found in DEST. Maybe we could binary search in DEST? */ for (sbase = dest->nelem + 2 * src->nelem, - is = src->nelem - 1, id = dest->nelem - 1; - REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) + is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; ) { if (dest->elems[id] == src->elems[is]) is--, id--; @@ -1232,7 +1199,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) --id; } - if (REG_VALID_INDEX (is)) + if (is >= 0) { /* If DEST is exhausted, the remaining items of SRC must be unique. */ sbase -= is + 1; @@ -1261,7 +1228,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) { /* Slide from the bottom. */ dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) + if (--id < 0) { /* Copy remaining SRC elements. */ memcpy (dest->elems, dest->elems + sbase, @@ -1279,17 +1246,20 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) Return true if successful. */ static bool -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_insert (re_node_set *set, Idx elem) { Idx idx; /* In case the set is empty. */ if (set->alloc == 0) - return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); + return __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR); - if (BE (set->nelem, 0) == 0) + if (__glibc_unlikely (set->nelem) == 0) { - /* We already guaranteed above that set->alloc != 0. */ + /* Although we already guaranteed above that set->alloc != 0 and + therefore set->elems != NULL, add a debug assertion to pacify + GCC 11.2 -fanalyzer. */ + DEBUG_ASSERT (set->elems); set->elems[0] = elem; ++set->nelem; return true; @@ -1301,7 +1271,7 @@ re_node_set_insert (re_node_set *set, Idx elem) Idx *new_elems; set->alloc = set->alloc * 2; new_elems = re_realloc (set->elems, Idx, set->alloc); - if (BE (new_elems == NULL, 0)) + if (__glibc_unlikely (new_elems == NULL)) return false; set->elems = new_elems; } @@ -1310,7 +1280,6 @@ re_node_set_insert (re_node_set *set, Idx elem) first element separately to skip a check in the inner loop. */ if (elem < set->elems[0]) { - idx = 0; for (idx = set->nelem; idx > 0; idx--) set->elems[idx] = set->elems[idx - 1]; } @@ -1318,6 +1287,7 @@ re_node_set_insert (re_node_set *set, Idx elem) { for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) set->elems[idx] = set->elems[idx - 1]; + DEBUG_ASSERT (set->elems[idx - 1] < elem); } /* Insert the new element. */ @@ -1331,7 +1301,7 @@ re_node_set_insert (re_node_set *set, Idx elem) Return true if successful. */ static bool -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_node_set_insert_last (re_node_set *set, Idx elem) { /* Realloc if we need. */ @@ -1340,7 +1310,7 @@ re_node_set_insert_last (re_node_set *set, Idx elem) Idx *new_elems; set->alloc = (set->alloc + 1) * 2; new_elems = re_realloc (set->elems, Idx, set->alloc); - if (BE (new_elems == NULL, 0)) + if (__glibc_unlikely (new_elems == NULL)) return false; set->elems = new_elems; } @@ -1354,13 +1324,13 @@ re_node_set_insert_last (re_node_set *set, Idx elem) Return true if SET1 and SET2 are equivalent. */ static bool -internal_function __attribute__ ((pure)) +__attribute__ ((pure)) re_node_set_compare (const re_node_set *set1, const re_node_set *set2) { Idx i; if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) return false; - for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) + for (i = set1->nelem ; --i >= 0 ; ) if (set1->elems[i] != set2->elems[i]) return false; return true; @@ -1369,11 +1339,11 @@ re_node_set_compare (const re_node_set *set1, const re_node_set *set2) /* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ static Idx -internal_function __attribute__ ((pure)) +__attribute__ ((pure)) re_node_set_contains (const re_node_set *set, Idx elem) { __re_size_t idx, right, mid; - if (! REG_VALID_NONZERO_INDEX (set->nelem)) + if (set->nelem <= 0) return 0; /* Binary search the element. */ @@ -1391,7 +1361,6 @@ re_node_set_contains (const re_node_set *set, Idx elem) } static void -internal_function re_node_set_remove_at (re_node_set *set, Idx idx) { if (idx < 0 || idx >= set->nelem) @@ -1403,13 +1372,12 @@ re_node_set_remove_at (re_node_set *set, Idx idx) /* Add the token TOKEN to dfa->nodes, and return the index of the token. - Or return REG_MISSING if an error occurred. */ + Or return -1 if an error occurred. */ static Idx -internal_function re_dfa_add_node (re_dfa_t *dfa, re_token_t token) { - if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) + if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc)) { size_t new_nodes_alloc = dfa->nodes_alloc * 2; Idx *new_nexts, *new_indices; @@ -1420,41 +1388,43 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token) const size_t max_object_size = MAX (sizeof (re_token_t), MAX (sizeof (re_node_set), sizeof (Idx))); - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_nodes_alloc, 0)) - return REG_MISSING; + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) + < new_nodes_alloc)) + return -1; new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); - if (BE (new_nodes == NULL, 0)) - return REG_MISSING; + if (__glibc_unlikely (new_nodes == NULL)) + return -1; dfa->nodes = new_nodes; + dfa->nodes_alloc = new_nodes_alloc; new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); + if (new_nexts != NULL) + dfa->nexts = new_nexts; new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); + if (new_indices != NULL) + dfa->org_indices = new_indices; new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); + if (new_edests != NULL) + dfa->edests = new_edests; new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); - if (BE (new_nexts == NULL || new_indices == NULL - || new_edests == NULL || new_eclosures == NULL, 0)) - return REG_MISSING; - dfa->nexts = new_nexts; - dfa->org_indices = new_indices; - dfa->edests = new_edests; - dfa->eclosures = new_eclosures; - dfa->nodes_alloc = new_nodes_alloc; + if (new_eclosures != NULL) + dfa->eclosures = new_eclosures; + if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL + || new_edests == NULL || new_eclosures == NULL)) + return -1; } dfa->nodes[dfa->nodes_len] = token; dfa->nodes[dfa->nodes_len].constraint = 0; -#ifdef RE_ENABLE_I18N dfa->nodes[dfa->nodes_len].accept_mb = ((token.type == OP_PERIOD && dfa->mb_cur_max > 1) || token.type == COMPLEX_BRACKET); -#endif - dfa->nexts[dfa->nodes_len] = REG_MISSING; + dfa->nexts[dfa->nodes_len] = -1; re_node_set_init_empty (dfa->edests + dfa->nodes_len); re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); return dfa->nodes_len++; } static re_hashval_t -internal_function calc_state_hash (const re_node_set *nodes, unsigned int context) { re_hashval_t hash = nodes->nelem + context; @@ -1474,7 +1444,7 @@ calc_state_hash (const re_node_set *nodes, unsigned int context) optimization. */ static re_dfastate_t * -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, const re_node_set *nodes) { @@ -1482,11 +1452,11 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, re_dfastate_t *new_state; struct re_state_table_entry *spot; Idx i; -#ifdef lint +#if defined GCC_LINT || defined lint /* Suppress bogus uninitialized-variable warnings. */ *err = REG_NOERROR; #endif - if (BE (nodes->nelem == 0, 0)) + if (__glibc_unlikely (nodes->nelem == 0)) { *err = REG_NOERROR; return NULL; @@ -1505,7 +1475,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, /* There are no appropriate state in the dfa, create the new one. */ new_state = create_ci_newstate (dfa, nodes, hash); - if (BE (new_state == NULL, 0)) + if (__glibc_unlikely (new_state == NULL)) *err = REG_ESPACE; return new_state; @@ -1522,7 +1492,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, optimization. */ static re_dfastate_t * -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context) { @@ -1530,7 +1500,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, re_dfastate_t *new_state; struct re_state_table_entry *spot; Idx i; -#ifdef lint +#if defined GCC_LINT || defined lint /* Suppress bogus uninitialized-variable warnings. */ *err = REG_NOERROR; #endif @@ -1552,7 +1522,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, } /* There are no appropriate state in 'dfa', create the new one. */ new_state = create_cd_newstate (dfa, nodes, context, hash); - if (BE (new_state == NULL, 0)) + if (__glibc_unlikely (new_state == NULL)) *err = REG_ESPACE; return new_state; @@ -1573,7 +1543,7 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, newstate->hash = hash; err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return REG_ESPACE; for (i = 0; i < newstate->nodes.nelem; i++) { @@ -1584,12 +1554,12 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, } spot = dfa->state_table + (hash & dfa->state_hash_mask); - if (BE (spot->alloc <= spot->num, 0)) + if (__glibc_unlikely (spot->alloc <= spot->num)) { Idx new_alloc = 2 * spot->num + 2; re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, new_alloc); - if (BE (new_array == NULL, 0)) + if (__glibc_unlikely (new_array == NULL)) return REG_ESPACE; spot->array = new_array; spot->alloc = new_alloc; @@ -1618,7 +1588,7 @@ free_state (re_dfastate_t *state) Return the new state if succeeded, otherwise return NULL. */ static re_dfastate_t * -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, re_hashval_t hash) { @@ -1627,10 +1597,10 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, re_dfastate_t *newstate; newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) + if (__glibc_unlikely (newstate == NULL)) return NULL; err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_free (newstate); return NULL; @@ -1643,9 +1613,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, re_token_type_t type = node->type; if (type == CHARACTER && !node->constraint) continue; -#ifdef RE_ENABLE_I18N newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ /* If the state has the halt node, the state is a halt state. */ if (type == END_OF_RE) @@ -1656,7 +1624,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, newstate->has_constraint = 1; } err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { free_state (newstate); newstate = NULL; @@ -1668,7 +1636,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, Return the new state if succeeded, otherwise return NULL. */ static re_dfastate_t * -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context, re_hashval_t hash) { @@ -1677,10 +1645,10 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, re_dfastate_t *newstate; newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) + if (__glibc_unlikely (newstate == NULL)) return NULL; err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_free (newstate); return NULL; @@ -1697,9 +1665,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, if (type == CHARACTER && !constraint) continue; -#ifdef RE_ENABLE_I18N newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ /* If the state has the halt node, the state is a halt state. */ if (type == END_OF_RE) @@ -1711,15 +1677,19 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, { if (newstate->entrance_nodes == &newstate->nodes) { - newstate->entrance_nodes = re_malloc (re_node_set, 1); - if (BE (newstate->entrance_nodes == NULL, 0)) + re_node_set *entrance_nodes = re_malloc (re_node_set, 1); + if (__glibc_unlikely (entrance_nodes == NULL)) { free_state (newstate); return NULL; } + newstate->entrance_nodes = entrance_nodes; if (re_node_set_init_copy (newstate->entrance_nodes, nodes) != REG_NOERROR) - return NULL; + { + free_state (newstate); + return NULL; + } nctx_nodes = 0; newstate->has_constraint = 1; } @@ -1732,7 +1702,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, } } err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { free_state (newstate); newstate = NULL; diff --git a/gl/regex_internal.h b/gl/regex_internal.h index a2b8f16f..57a455b1 100644 --- a/gl/regex_internal.h +++ b/gl/regex_internal.h @@ -1,26 +1,25 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ #ifndef _REGEX_INTERNAL_H #define _REGEX_INTERNAL_H 1 -#include #include #include #include @@ -33,36 +32,35 @@ #include #include +#ifndef _LIBC +# include +#endif + +#include +#include + +#if defined DEBUG && DEBUG != 0 +# include +# define DEBUG_ASSERT(x) assert (x) +#else +# define DEBUG_ASSERT(x) assume (x) +#endif + #ifdef _LIBC -# include +# include # define lock_define(name) __libc_lock_define (, name) # define lock_init(lock) (__libc_lock_init (lock), 0) -# define lock_fini(lock) 0 +# define lock_fini(lock) ((void) 0) # define lock_lock(lock) __libc_lock_lock (lock) # define lock_unlock(lock) __libc_lock_unlock (lock) -#elif defined GNULIB_LOCK +#elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD # include "glthread/lock.h" - /* Use gl_lock_define if empty macro arguments are known to work. - Otherwise, fall back on less-portable substitutes. */ -# if ((defined __GNUC__ && !defined __STRICT_ANSI__) \ - || (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__)) -# define lock_define(name) gl_lock_define (, name) -# elif USE_POSIX_THREADS -# define lock_define(name) pthread_mutex_t name; -# elif USE_PTH_THREADS -# define lock_define(name) pth_mutex_t name; -# elif USE_SOLARIS_THREADS -# define lock_define(name) mutex_t name; -# elif USE_WINDOWS_THREADS -# define lock_define(name) gl_lock_t name; -# else -# define lock_define(name) -# endif +# define lock_define(name) gl_lock_define (, name) # define lock_init(lock) glthread_lock_init (&(lock)) # define lock_fini(lock) glthread_lock_destroy (&(lock)) # define lock_lock(lock) glthread_lock_lock (&(lock)) # define lock_unlock(lock) glthread_lock_unlock (&(lock)) -#elif defined GNULIB_PTHREAD +#elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD # include # define lock_define(name) pthread_mutex_t name; # define lock_init(lock) pthread_mutex_init (&(lock), 0) @@ -83,11 +81,18 @@ # define isblank(ch) ((ch) == ' ' || (ch) == '\t') #endif +/* regex code assumes isascii has its usual numeric meaning, + even if the portable character set uses EBCDIC encoding, + and even if wint_t is wider than int. */ +#ifndef _LIBC +# undef isascii +# define isascii(c) (((c) & ~0x7f) == 0) +#endif + #ifdef _LIBC # ifndef _RE_DEFINE_LOCALE_FUNCTIONS # define _RE_DEFINE_LOCALE_FUNCTIONS 1 # include -# include # include # endif #endif @@ -101,6 +106,7 @@ __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) # endif #else +# undef gettext # define gettext(msgid) (msgid) #endif @@ -110,16 +116,6 @@ # define gettext_noop(String) String #endif -#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC -# define RE_ENABLE_I18N -#endif - -#if __GNUC__ >= 3 -# define BE(expr, val) __builtin_expect (expr, val) -#else -# define BE(expr, val) (expr) -#endif - /* Number of ASCII characters. */ #define ASCII_CHARS 0x80 @@ -135,45 +131,60 @@ /* Rename to standard API for using out of glibc. */ #ifndef _LIBC # undef __wctype +# undef __iswalnum # undef __iswctype +# undef __towlower +# undef __towupper # define __wctype wctype +# define __iswalnum iswalnum # define __iswctype iswctype +# define __towlower towlower +# define __towupper towupper # define __btowc btowc # define __mbrtowc mbrtowc # define __wcrtomb wcrtomb # define __regfree regfree -# define attribute_hidden #endif /* not _LIBC */ -#if __GNUC__ < 3 + (__GNUC_MINOR__ < 1) -# define __attribute__(arg) -#endif +/* Types related to integers. Unless protected by #ifdef _LIBC, the + regex code should avoid exact-width types like int32_t and uint64_t + as some non-GCC platforms lack them, an issue when this code is + used in Gnulib. */ -typedef __re_idx_t Idx; -#ifdef _REGEX_LARGE_OFFSETS -# define IDX_MAX (SIZE_MAX - 2) -#else -# define IDX_MAX INT_MAX +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) #endif - -/* Special return value for failure to match. */ -#define REG_MISSING ((Idx) -1) - -/* Special return value for internal error. */ -#define REG_ERROR ((Idx) -2) - -/* Test whether N is a valid index, and is not one of the above. */ -#ifdef _REGEX_LARGE_OFFSETS -# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR) -#else -# define REG_VALID_INDEX(n) (0 <= (n)) +#ifndef ULONG_WIDTH +# define ULONG_WIDTH REGEX_UINTEGER_WIDTH (ULONG_MAX) +/* The number of usable bits in an unsigned integer type with maximum + value MAX, as an int expression suitable in #if. Cover all known + practical hosts. This implementation exploits the fact that MAX is + 1 less than a power of 2, and merely counts the number of 1 bits in + MAX; "COBn" means "count the number of 1 bits in the low-order n bits". */ +# define REGEX_UINTEGER_WIDTH(max) REGEX_COB128 (max) +# define REGEX_COB128(n) (REGEX_COB64 ((n) >> 31 >> 31 >> 2) + REGEX_COB64 (n)) +# define REGEX_COB64(n) (REGEX_COB32 ((n) >> 31 >> 1) + REGEX_COB32 (n)) +# define REGEX_COB32(n) (REGEX_COB16 ((n) >> 16) + REGEX_COB16 (n)) +# define REGEX_COB16(n) (REGEX_COB8 ((n) >> 8) + REGEX_COB8 (n)) +# define REGEX_COB8(n) (REGEX_COB4 ((n) >> 4) + REGEX_COB4 (n)) +# define REGEX_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + ((n) & 1)) +# if ULONG_MAX / 2 + 1 != 1ul << (ULONG_WIDTH - 1) +# error "ULONG_MAX out of range" +# endif #endif -/* Test whether N is a valid nonzero index. */ +/* The type of indexes into strings. This is signed, not size_t, + since the API requires indexes to fit in regoff_t anyway, and using + signed integers makes the code a bit smaller and presumably faster. + The traditional GNU regex implementation uses int for indexes. + The POSIX-compatible implementation uses a possibly-wider type. + The name 'Idx' is three letters to minimize the hassle of + reindenting a lot of regex code that formerly used 'int'. */ +typedef regoff_t Idx; #ifdef _REGEX_LARGE_OFFSETS -# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1)) +# define IDX_MAX SSIZE_MAX #else -# define REG_VALID_NONZERO_INDEX(n) (0 < (n)) +# define IDX_MAX INT_MAX #endif /* A hash value, suitable for computing hash tables. */ @@ -184,36 +195,8 @@ typedef __re_size_t re_hashval_t; typedef unsigned long int bitset_word_t; /* All bits set in a bitset_word_t. */ #define BITSET_WORD_MAX ULONG_MAX - -/* Number of bits in a bitset_word_t. For portability to hosts with - padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)'; - instead, deduce it directly from BITSET_WORD_MAX. Avoid - greater-than-32-bit integers and unconditional shifts by more than - 31 bits, as they're not portable. */ -#if BITSET_WORD_MAX == 0xffffffffUL -# define BITSET_WORD_BITS 32 -#elif BITSET_WORD_MAX >> 31 >> 4 == 1 -# define BITSET_WORD_BITS 36 -#elif BITSET_WORD_MAX >> 31 >> 16 == 1 -# define BITSET_WORD_BITS 48 -#elif BITSET_WORD_MAX >> 31 >> 28 == 1 -# define BITSET_WORD_BITS 60 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1 -# define BITSET_WORD_BITS 64 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1 -# define BITSET_WORD_BITS 72 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1 -# define BITSET_WORD_BITS 128 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1 -# define BITSET_WORD_BITS 256 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1 -# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */ -# if BITSET_WORD_BITS <= SBC_MAX -# error "Invalid SBC_MAX" -# endif -#else -# error "Add case for new bitset_word_t size" -#endif +/* Number of bits in a bitset_word_t. */ +#define BITSET_WORD_BITS ULONG_WIDTH /* Number of bitset_word_t values in a bitset_t. */ #define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS) @@ -264,10 +247,8 @@ typedef enum SIMPLE_BRACKET = 3, OP_BACK_REF = 4, OP_PERIOD = 5, -#ifdef RE_ENABLE_I18N COMPLEX_BRACKET = 6, OP_UTF8_PERIOD = 7, -#endif /* RE_ENABLE_I18N */ /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used when the debugger shows values of this enum type. */ @@ -305,30 +286,29 @@ typedef enum } re_token_type_t; -#ifdef RE_ENABLE_I18N typedef struct { /* Multibyte characters. */ wchar_t *mbchars; +#ifdef _LIBC /* Collating symbols. */ -# ifdef _LIBC int32_t *coll_syms; -# endif +#endif +#ifdef _LIBC /* Equivalence classes. */ -# ifdef _LIBC int32_t *equiv_classes; -# endif +#endif /* Range expressions. */ -# ifdef _LIBC +#ifdef _LIBC uint32_t *range_starts; uint32_t *range_ends; -# else /* not _LIBC */ +#else wchar_t *range_starts; wchar_t *range_ends; -# endif /* not _LIBC */ +#endif /* Character classes. */ wctype_t *char_classes; @@ -351,7 +331,6 @@ typedef struct /* # of character classes. */ Idx nchar_classes; } re_charset_t; -#endif /* RE_ENABLE_I18N */ typedef struct { @@ -359,13 +338,11 @@ typedef struct { unsigned char c; /* for CHARACTER */ re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ -#ifdef RE_ENABLE_I18N re_charset_t *mbcset; /* for COMPLEX_BRACKET */ -#endif /* RE_ENABLE_I18N */ Idx idx; /* for BACK_REF */ re_context_type ctx_type; /* for ANCHOR */ } opr; -#if __GNUC__ >= 2 && !defined __STRICT_ANSI__ +#if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__ re_token_type_t type : 8; #else re_token_type_t type; @@ -373,12 +350,10 @@ typedef struct unsigned int constraint : 10; /* context constraint */ unsigned int duplicated : 1; unsigned int opt_subexp : 1; -#ifdef RE_ENABLE_I18N unsigned int accept_mb : 1; /* These 2 bits can be moved into the union if needed (e.g. if running out of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ unsigned int mb_partial : 1; -#endif unsigned int word_char : 1; } re_token_t; @@ -393,12 +368,10 @@ struct re_string_t REG_ICASE, upper cases of the string are stored, otherwise MBS points the same address that RAW_MBS points. */ unsigned char *mbs; -#ifdef RE_ENABLE_I18N /* Store the wide character string which is corresponding to MBS. */ wint_t *wcs; Idx *offsets; mbstate_t cur_state; -#endif /* Index in RAW_MBS. Each character mbs[i] corresponds to raw_mbs[raw_mbs_idx + i]. */ Idx raw_mbs_idx; @@ -446,24 +419,9 @@ struct re_dfa_t; typedef struct re_dfa_t re_dfa_t; #ifndef _LIBC -# define internal_function +# define IS_IN(libc) false #endif -#ifndef NOT_IN_libc -static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, - Idx new_buf_len) - internal_function; -# ifdef RE_ENABLE_I18N -static void build_wcs_buffer (re_string_t *pstr) internal_function; -static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) - internal_function; -# endif /* RE_ENABLE_I18N */ -static void build_upper_buffer (re_string_t *pstr) internal_function; -static void re_string_translate_buffer (re_string_t *pstr) internal_function; -static unsigned int re_string_context_at (const re_string_t *input, Idx idx, - int eflags) - internal_function __attribute__ ((pure)); -#endif #define re_string_peek_byte(pstr, offset) \ ((pstr)->mbs[(pstr)->cur_idx + offset]) #define re_string_fetch_byte(pstr) \ @@ -481,25 +439,6 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx idx, #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 -#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 @@ -556,7 +495,7 @@ typedef struct bin_tree_storage_t bin_tree_storage_t; #define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_') #define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR) -#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_') +#define IS_WIDE_WORD_CHAR(ch) (__iswalnum (ch) || (ch) == L'_') #define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) #define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ @@ -636,20 +575,15 @@ struct re_backref_cache_entry Idx str_idx; Idx subexp_from; Idx subexp_to; + bitset_word_t eps_reachable_subexps_map; char more; - char unused; - unsigned short int eps_reachable_subexps_map; }; typedef struct { /* The string object corresponding to the input string. */ re_string_t input; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) const re_dfa_t *const dfa; -#else - const re_dfa_t *dfa; -#endif /* EFLAGS of the argument of regexec. */ int eflags; /* Where the matching ends. */ @@ -769,31 +703,31 @@ typedef struct /* Functions for bitset_t operation. */ -static void +static inline void bitset_set (bitset_t set, Idx i) { set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; } -static void +static inline void bitset_clear (bitset_t set, Idx i) { set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); } -static bool +static inline bool bitset_contain (const bitset_t set, Idx i) { return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; } -static void +static inline void bitset_empty (bitset_t set) { memset (set, '\0', sizeof (bitset_t)); } -static void +static inline void bitset_set_all (bitset_t set) { memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); @@ -802,13 +736,13 @@ bitset_set_all (bitset_t set) ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; } -static void +static inline void bitset_copy (bitset_t dest, const bitset_t src) { memcpy (dest, src, sizeof (bitset_t)); } -static void __attribute__ ((unused)) +static inline void bitset_not (bitset_t set) { int bitset_i; @@ -820,7 +754,7 @@ bitset_not (bitset_t set) & ~set[BITSET_WORDS - 1]); } -static void __attribute__ ((unused)) +static inline void bitset_merge (bitset_t dest, const bitset_t src) { int bitset_i; @@ -828,7 +762,7 @@ bitset_merge (bitset_t dest, const bitset_t src) dest[bitset_i] |= src[bitset_i]; } -static void __attribute__ ((unused)) +static inline void bitset_mask (bitset_t dest, const bitset_t src) { int bitset_i; @@ -836,10 +770,9 @@ bitset_mask (bitset_t dest, const bitset_t src) dest[bitset_i] &= src[bitset_i]; } -#ifdef RE_ENABLE_I18N /* Functions for re_string. */ static int -internal_function __attribute__ ((pure, unused)) +__attribute__ ((pure, unused)) re_string_char_size_at (const re_string_t *pstr, Idx idx) { int byte_idx; @@ -852,7 +785,7 @@ re_string_char_size_at (const re_string_t *pstr, Idx idx) } static wint_t -internal_function __attribute__ ((pure, unused)) +__attribute__ ((pure, unused)) re_string_wchar_at (const re_string_t *pstr, Idx idx) { if (pstr->mb_cur_max == 1) @@ -860,15 +793,17 @@ re_string_wchar_at (const re_string_t *pstr, Idx idx) return (wint_t) pstr->wcs[idx]; } -# ifndef NOT_IN_libc +#ifdef _LIBC +# include +#endif + static int -internal_function __attribute__ ((pure, unused)) +__attribute__ ((pure, unused)) re_string_elem_size_at (const re_string_t *pstr, Idx idx) { -# ifdef _LIBC +#ifdef _LIBC const unsigned char *p, *extra; const int32_t *table, *indirect; -# include uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); if (nrules != 0) @@ -879,31 +814,22 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx) indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); p = pstr->mbs + idx; - findidx (&p, pstr->len - idx); + findidx (table, indirect, extra, &p, pstr->len - idx); return p - pstr->mbs - idx; } - else -# endif /* _LIBC */ - return 1; +#endif /* _LIBC */ + + return 1; } -# endif -#endif /* RE_ENABLE_I18N */ -#ifndef __GNUC_PREREQ -# if defined __GNUC__ && defined __GNUC_MINOR__ -# define __GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#ifdef _LIBC +# if __GNUC__ >= 7 +# define FALLTHROUGH __attribute__ ((__fallthrough__)) # else -# define __GNUC_PREREQ(maj, min) 0 +# define FALLTHROUGH ((void) 0) # endif -#endif - -#if __GNUC_PREREQ (3,4) -# undef __attribute_warn_unused_result__ -# define __attribute_warn_unused_result__ \ - __attribute__ ((__warn_unused_result__)) #else -# define __attribute_warn_unused_result__ /* empty */ +# include "attribute.h" #endif #endif /* _REGEX_INTERNAL_H */ diff --git a/gl/regexec.c b/gl/regexec.c index d29d442b..521cb028 100644 --- a/gl/regexec.c +++ b/gl/regexec.c @@ -1,206 +1,170 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. + version 2.1 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. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - . */ + . */ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, - Idx n) internal_function; -static void match_ctx_clean (re_match_context_t *mctx) internal_function; -static void match_ctx_free (re_match_context_t *cache) internal_function; + Idx n); +static void match_ctx_clean (re_match_context_t *mctx); +static void match_ctx_free (re_match_context_t *cache); static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node, - Idx str_idx, Idx from, Idx to) - internal_function; -static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) - internal_function; + Idx str_idx, Idx from, Idx to); +static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx); static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node, - Idx str_idx) internal_function; + Idx str_idx); static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, - Idx node, Idx str_idx) - internal_function; + Idx node, Idx str_idx); static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, re_dfastate_t **limited_sts, Idx last_node, - Idx last_str_idx) - internal_function; + Idx last_str_idx); static reg_errcode_t re_search_internal (const regex_t *preg, const char *string, Idx length, Idx start, Idx last_start, Idx stop, size_t nmatch, regmatch_t pmatch[], - int eflags) internal_function; + int eflags); static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp, const char *string1, Idx length1, const char *string2, Idx length2, Idx start, regoff_t range, struct re_registers *regs, - Idx stop, bool ret_len) internal_function; + Idx stop, bool ret_len); static regoff_t re_search_stub (struct re_pattern_buffer *bufp, const char *string, Idx length, Idx start, regoff_t range, Idx stop, struct re_registers *regs, - bool ret_len) internal_function; + bool ret_len); static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, - Idx nregs, int regs_allocated) internal_function; -static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx) - internal_function; + Idx nregs, int regs_allocated); +static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx); static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match, - Idx *p_match_first) internal_function; + Idx *p_match_first); static Idx check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, Idx idx) - internal_function; + const re_dfastate_t *state, Idx idx); static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, regmatch_t *prev_idx_match, Idx cur_node, - Idx cur_idx, Idx nmatch) internal_function; + Idx cur_idx, Idx nmatch); static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, Idx nregs, - regmatch_t *regs, - re_node_set *eps_via_nodes) - internal_function; + regmatch_t *regs, regmatch_t *prevregs, + re_node_set *eps_via_nodes); static reg_errcode_t set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, regmatch_t *pmatch, - bool fl_backtrack) internal_function; -static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) - internal_function; + bool fl_backtrack); +static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs); -#ifdef RE_ENABLE_I18N static int sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx node_idx, Idx str_idx, Idx max_str_idx) - internal_function; -#endif /* RE_ENABLE_I18N */ + Idx node_idx, Idx str_idx, Idx max_str_idx); static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, - re_sift_context_t *sctx) - internal_function; + re_sift_context_t *sctx); static reg_errcode_t build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, - re_node_set *cur_dest) - internal_function; + re_node_set *cur_dest); static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, - re_node_set *dest_nodes) - internal_function; + re_node_set *dest_nodes); static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates) - internal_function; + const re_node_set *candidates); static bool check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, Idx dst_node, Idx dst_idx, Idx src_node, - Idx src_idx) internal_function; + Idx src_idx); static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, Idx subexp_idx, - Idx from_node, Idx bkref_idx) - internal_function; + Idx from_node, Idx bkref_idx); static int check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, Idx subexp_idx, Idx node, Idx str_idx, - Idx bkref_idx) internal_function; + Idx bkref_idx); static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, const re_node_set *candidates, re_node_set *limits, struct re_backref_cache_entry *bkref_ents, - Idx str_idx) internal_function; + Idx str_idx); static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx str_idx, const re_node_set *candidates) - internal_function; + Idx str_idx, const re_node_set *candidates); static reg_errcode_t merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, - re_dfastate_t **src, Idx num) - internal_function; + re_dfastate_t **src, Idx num); static re_dfastate_t *find_recover_state (reg_errcode_t *err, - re_match_context_t *mctx) internal_function; + re_match_context_t *mctx); static re_dfastate_t *transit_state (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) internal_function; + re_dfastate_t *state); static re_dfastate_t *merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *next_state) - internal_function; + re_dfastate_t *next_state); static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, - Idx str_idx) internal_function; + Idx str_idx); #if 0 static re_dfastate_t *transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; + re_dfastate_t *pstate); #endif -#ifdef RE_ENABLE_I18N static reg_errcode_t transit_state_mb (re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif /* RE_ENABLE_I18N */ + re_dfastate_t *pstate); static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, - const re_node_set *nodes) - internal_function; + const re_node_set *nodes); static reg_errcode_t get_subexp (re_match_context_t *mctx, - Idx bkref_node, Idx bkref_str_idx) - internal_function; + Idx bkref_node, Idx bkref_str_idx); static reg_errcode_t get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, re_sub_match_last_t *sub_last, - Idx bkref_node, Idx bkref_str) - internal_function; + Idx bkref_node, Idx bkref_str); static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - Idx subexp_idx, int type) internal_function; + Idx subexp_idx, int type); static reg_errcode_t check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, Idx top_str, Idx last_node, Idx last_str, - int type) internal_function; + int type); static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, re_node_set *cur_nodes, - re_node_set *next_nodes) - internal_function; + re_node_set *next_nodes); static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, - Idx ex_subexp, int type) - internal_function; + Idx ex_subexp, int type); static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, Idx target, Idx ex_subexp, - int type) internal_function; + int type); static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, Idx cur_str, - Idx subexp_num, int type) - internal_function; -static bool build_trtable (const re_dfa_t *dfa, - re_dfastate_t *state) internal_function; -#ifdef RE_ENABLE_I18N + Idx subexp_num, int type); +static bool build_trtable (const re_dfa_t *dfa, re_dfastate_t *state); static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, - const re_string_t *input, Idx idx) - internal_function; -# ifdef _LIBC + const re_string_t *input, Idx idx); +#ifdef _LIBC static unsigned int find_collation_sequence_value (const unsigned char *mbs, - size_t name_len) - internal_function; -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ + size_t name_len); +#endif static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, re_node_set *states_node, - bitset_t *states_ch) internal_function; + bitset_t *states_ch); static bool check_node_accept (const re_match_context_t *mctx, - const re_token_t *node, Idx idx) - internal_function; -static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len) - internal_function; + const re_token_t *node, Idx idx); +static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len); /* Entry point for POSIX code. */ @@ -216,15 +180,12 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len) REG_NOTBOL is set, then ^ does not match at the beginning of the string; if REG_NOTEOL is set, then $ does not match at the end. - We return 0 if we find a match and REG_NOMATCH if not. */ + Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if + EFLAGS is invalid. */ int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *_Restrict_ preg; - const char *_Restrict_ string; - size_t nmatch; - regmatch_t pmatch[_Restrict_arr_]; - int eflags; +regexec (const regex_t *__restrict preg, const char *__restrict string, + size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) { reg_errcode_t err; Idx start, length; @@ -256,6 +217,8 @@ regexec (preg, string, nmatch, pmatch, eflags) } #ifdef _LIBC +libc_hidden_def (__regexec) + # include versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); @@ -264,9 +227,9 @@ __typeof__ (__regexec) __compat_regexec; int attribute_compat_text_section -__compat_regexec (const regex_t *_Restrict_ preg, - const char *_Restrict_ string, size_t nmatch, - regmatch_t pmatch[], int eflags) +__compat_regexec (const regex_t *__restrict preg, + const char *__restrict string, size_t nmatch, + regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) { return regexec (preg, string, nmatch, pmatch, eflags & (REG_NOTBOL | REG_NOTEOL)); @@ -301,15 +264,12 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); strings.) On success, re_match* functions return the length of the match, re_search* - return the position of the start of the match. Return value -1 means no - match was found and -2 indicates an internal error. */ + return the position of the start of the match. They return -1 on + match failure, -2 on error. */ regoff_t -re_match (bufp, string, length, start, regs) - struct re_pattern_buffer *bufp; - const char *string; - Idx length, start; - struct re_registers *regs; +re_match (struct re_pattern_buffer *bufp, const char *string, Idx length, + Idx start, struct re_registers *regs) { return re_search_stub (bufp, string, length, start, 0, length, regs, true); } @@ -318,12 +278,8 @@ weak_alias (__re_match, re_match) #endif regoff_t -re_search (bufp, string, length, start, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - Idx length, start; - regoff_t range; - struct re_registers *regs; +re_search (struct re_pattern_buffer *bufp, const char *string, Idx length, + Idx start, regoff_t range, struct re_registers *regs) { return re_search_stub (bufp, string, length, start, range, length, regs, false); @@ -333,11 +289,9 @@ weak_alias (__re_search, re_search) #endif regoff_t -re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - Idx length1, length2, start, stop; - struct re_registers *regs; +re_match_2 (struct re_pattern_buffer *bufp, const char *string1, Idx length1, + const char *string2, Idx length2, Idx start, + struct re_registers *regs, Idx stop) { return re_search_2_stub (bufp, string1, length1, string2, length2, start, 0, regs, stop, true); @@ -347,12 +301,9 @@ weak_alias (__re_match_2, re_match_2) #endif regoff_t -re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - Idx length1, length2, start, stop; - regoff_t range; - struct re_registers *regs; +re_search_2 (struct re_pattern_buffer *bufp, const char *string1, Idx length1, + const char *string2, Idx length2, Idx start, regoff_t range, + struct re_registers *regs, Idx stop) { return re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs, stop, false); @@ -362,18 +313,18 @@ weak_alias (__re_search_2, re_search_2) #endif static regoff_t -re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, Idx length1, - const char *string2, Idx length2, - Idx start, regoff_t range, struct re_registers *regs, +re_search_2_stub (struct re_pattern_buffer *bufp, const char *string1, + Idx length1, const char *string2, Idx length2, Idx start, + regoff_t range, struct re_registers *regs, Idx stop, bool ret_len) { const char *str; regoff_t rval; - Idx len = length1 + length2; + Idx len; char *s = NULL; - if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0)) + if (__glibc_unlikely ((length1 < 0 || length2 < 0 || stop < 0 + || INT_ADD_WRAPV (length1, length2, &len)))) return -2; /* Concatenate the strings. */ @@ -382,7 +333,7 @@ re_search_2_stub (struct re_pattern_buffer *bufp, { s = re_malloc (char, len); - if (BE (s == NULL, 0)) + if (__glibc_unlikely (s == NULL)) return -2; #ifdef _LIBC memcpy (__mempcpy (s, string1, length1), string2, length2); @@ -409,8 +360,7 @@ re_search_2_stub (struct re_pattern_buffer *bufp, otherwise the position of the match is returned. */ static regoff_t -re_search_stub (struct re_pattern_buffer *bufp, - const char *string, Idx length, +re_search_stub (struct re_pattern_buffer *bufp, const char *string, Idx length, Idx start, regoff_t range, Idx stop, struct re_registers *regs, bool ret_len) { @@ -423,11 +373,13 @@ re_search_stub (struct re_pattern_buffer *bufp, Idx last_start = start + range; /* Check for out-of-range. */ - if (BE (start < 0 || start > length, 0)) + if (__glibc_unlikely (start < 0 || start > length)) return -1; - if (BE (length < last_start || (0 <= range && last_start < start), 0)) + if (__glibc_unlikely (length < last_start + || (0 <= range && last_start < start))) last_start = length; - else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0)) + else if (__glibc_unlikely (last_start < 0 + || (range < 0 && start <= last_start))) last_start = 0; lock_lock (dfa->lock); @@ -439,17 +391,17 @@ re_search_stub (struct re_pattern_buffer *bufp, if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate) re_compile_fastmap (bufp); - if (BE (bufp->no_sub, 0)) + if (__glibc_unlikely (bufp->no_sub)) regs = NULL; /* We need at least 1 register. */ if (regs == NULL) nregs = 1; - else if (BE (bufp->regs_allocated == REGS_FIXED - && regs->num_regs <= bufp->re_nsub, 0)) + else if (__glibc_unlikely (bufp->regs_allocated == REGS_FIXED + && regs->num_regs <= bufp->re_nsub)) { nregs = regs->num_regs; - if (BE (nregs < 1, 0)) + if (__glibc_unlikely (nregs < 1)) { /* Nothing can be copied to regs. */ regs = NULL; @@ -459,7 +411,7 @@ re_search_stub (struct re_pattern_buffer *bufp, else nregs = bufp->re_nsub + 1; pmatch = re_malloc (regmatch_t, nregs); - if (BE (pmatch == NULL, 0)) + if (__glibc_unlikely (pmatch == NULL)) { rval = -2; goto out; @@ -478,15 +430,15 @@ re_search_stub (struct re_pattern_buffer *bufp, /* If caller wants register contents data back, copy them. */ bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs, bufp->regs_allocated); - if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0)) + if (__glibc_unlikely (bufp->regs_allocated == REGS_UNALLOCATED)) rval = -2; } - if (BE (rval == 0, 1)) + if (__glibc_likely (rval == 0)) { if (ret_len) { - assert (pmatch[0].rm_so == start); + DEBUG_ASSERT (pmatch[0].rm_so == start); rval = pmatch[0].rm_eo - start; } else @@ -512,10 +464,10 @@ re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, if (regs_allocated == REGS_UNALLOCATED) { /* No. So allocate them with malloc. */ regs->start = re_malloc (regoff_t, need_regs); - if (BE (regs->start == NULL, 0)) + if (__glibc_unlikely (regs->start == NULL)) return REGS_UNALLOCATED; regs->end = re_malloc (regoff_t, need_regs); - if (BE (regs->end == NULL, 0)) + if (__glibc_unlikely (regs->end == NULL)) { re_free (regs->start); return REGS_UNALLOCATED; @@ -526,14 +478,14 @@ re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, { /* Yes. If we need more elements than were already allocated, reallocate them. If we need fewer, just leave it alone. */ - if (BE (need_regs > regs->num_regs, 0)) + if (__glibc_unlikely (need_regs > regs->num_regs)) { regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); regoff_t *new_end; - if (BE (new_start == NULL, 0)) + if (__glibc_unlikely (new_start == NULL)) return REGS_UNALLOCATED; new_end = re_realloc (regs->end, regoff_t, need_regs); - if (BE (new_end == NULL, 0)) + if (__glibc_unlikely (new_end == NULL)) { re_free (new_start); return REGS_UNALLOCATED; @@ -545,9 +497,9 @@ re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, } else { - assert (regs_allocated == REGS_FIXED); + DEBUG_ASSERT (regs_allocated == REGS_FIXED); /* This function may not be called with REGS_FIXED and nregs too big. */ - assert (regs->num_regs >= nregs); + DEBUG_ASSERT (nregs <= regs->num_regs); rval = REGS_FIXED; } @@ -577,11 +529,8 @@ re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, freeing the old data. */ void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - __re_size_t num_regs; - regoff_t *starts, *ends; +re_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs, + __re_size_t num_regs, regoff_t *starts, regoff_t *ends) { if (num_regs) { @@ -609,8 +558,7 @@ int # ifdef _LIBC weak_function # endif -re_exec (s) - const char *s; +re_exec (const char *s) { return 0 == regexec (&re_comp_buf, s, 0, NULL, 0); } @@ -629,11 +577,9 @@ re_exec (s) static reg_errcode_t __attribute_warn_unused_result__ -re_search_internal (const regex_t *preg, - const char *string, Idx length, - Idx start, Idx last_start, Idx stop, - size_t nmatch, regmatch_t pmatch[], - int eflags) +re_search_internal (const regex_t *preg, const char *string, Idx length, + Idx start, Idx last_start, Idx stop, size_t nmatch, + regmatch_t pmatch[], int eflags) { reg_errcode_t err; const re_dfa_t *dfa = preg->buffer; @@ -642,38 +588,28 @@ re_search_internal (const regex_t *preg, bool fl_longest_match; int match_kind; Idx match_first; - Idx match_last = REG_MISSING; + Idx match_last = -1; Idx extra_nmatch; bool sb; int ch; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) re_match_context_t mctx = { .dfa = dfa }; -#else - re_match_context_t mctx; -#endif char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate && start != last_start && !preg->can_be_null) ? preg->fastmap : NULL); RE_TRANSLATE_TYPE t = preg->translate; -#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) - memset (&mctx, '\0', sizeof (re_match_context_t)); - mctx.dfa = dfa; -#endif - extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; nmatch -= extra_nmatch; /* Check if the DFA haven't been compiled. */ - if (BE (preg->used == 0 || dfa->init_state == NULL - || dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) + if (__glibc_unlikely (preg->used == 0 || dfa->init_state == NULL + || dfa->init_state_word == NULL + || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL)) return REG_NOMATCH; -#ifdef DEBUG /* We assume front-end functions already check them. */ - assert (0 <= last_start && last_start <= length); -#endif + DEBUG_ASSERT (0 <= last_start && last_start <= length); /* If initial states with non-begbuf contexts have no elements, the regex must be anchored. If preg->newline_anchor is set, @@ -694,14 +630,14 @@ re_search_internal (const regex_t *preg, err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, preg->translate, (preg->syntax & RE_ICASE) != 0, dfa); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; mctx.input.stop = stop; mctx.input.raw_stop = stop; mctx.input.newline_anchor = preg->newline_anchor; err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; /* We will log all the DFA states through which the dfa pass, @@ -711,22 +647,20 @@ re_search_internal (const regex_t *preg, if (nmatch > 1 || dfa->has_mb_node) { /* Avoid overflow. */ - if (BE ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) - <= mctx.input.bufs_len), 0)) + if (__glibc_unlikely ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) + <= mctx.input.bufs_len))) { err = REG_ESPACE; goto free_return; } mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1); - if (BE (mctx.state_log == NULL, 0)) + if (__glibc_unlikely (mctx.state_log == NULL)) { err = REG_ESPACE; goto free_return; } } - else - mctx.state_log = NULL; match_first = start; mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF @@ -763,19 +697,19 @@ re_search_internal (const regex_t *preg, case 7: /* Fastmap with single-byte translation, match forward. */ - while (BE (match_first < right_lim, 1) + while (__glibc_likely (match_first < right_lim) && !fastmap[t[(unsigned char) string[match_first]]]) ++match_first; goto forward_match_found_start_or_reached_end; case 6: /* Fastmap without translation, match forward. */ - while (BE (match_first < right_lim, 1) + while (__glibc_likely (match_first < right_lim) && !fastmap[(unsigned char) string[match_first]]) ++match_first; forward_match_found_start_or_reached_end: - if (BE (match_first == right_lim, 0)) + if (__glibc_unlikely (match_first == right_lim)) { ch = match_first >= length ? 0 : (unsigned char) string[match_first]; @@ -808,19 +742,19 @@ re_search_internal (const regex_t *preg, /* If MATCH_FIRST is out of the valid range, reconstruct the buffers. */ __re_size_t offset = match_first - mctx.input.raw_mbs_idx; - if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0)) + if (__glibc_unlikely (offset + >= (__re_size_t) mctx.input.valid_raw_len)) { err = re_string_reconstruct (&mctx.input, match_first, eflags); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; offset = match_first - mctx.input.raw_mbs_idx; } - /* If MATCH_FIRST is out of the buffer, leave it as '\0'. - Note that MATCH_FIRST must not be smaller than 0. */ - ch = (match_first >= length - ? 0 : re_string_byte_at (&mctx.input, offset)); + /* Use buffer byte if OFFSET is in buffer, otherwise '\0'. */ + ch = (offset < mctx.input.valid_len + ? re_string_byte_at (&mctx.input, offset) : 0); if (fastmap[ch]) break; match_first += incr; @@ -836,24 +770,22 @@ re_search_internal (const regex_t *preg, /* Reconstruct the buffers so that the matcher can assume that the matching starts from the beginning of the buffer. */ err = re_string_reconstruct (&mctx.input, match_first, eflags); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; -#ifdef RE_ENABLE_I18N - /* Don't consider this char as a possible match start if it part, - yet isn't the head, of a multibyte character. */ + /* Don't consider this char as a possible match start if it part, + yet isn't the head, of a multibyte character. */ if (!sb && !re_string_first_byte (&mctx.input, 0)) continue; -#endif /* It seems to be appropriate one, then use the matcher. */ /* We assume that the matching starts from 0. */ mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0; match_last = check_matching (&mctx, fl_longest_match, start <= last_start ? &match_first : NULL); - if (match_last != REG_MISSING) + if (match_last != -1) { - if (BE (match_last == REG_ERROR, 0)) + if (__glibc_unlikely (match_last == -2)) { err = REG_ESPACE; goto free_return; @@ -873,9 +805,9 @@ re_search_internal (const regex_t *preg, err = prune_impossible_nodes (&mctx); if (err == REG_NOERROR) break; - if (BE (err != REG_NOMATCH, 0)) + if (__glibc_unlikely (err != REG_NOMATCH)) goto free_return; - match_last = REG_MISSING; + match_last = -1; } else break; /* We found a match. */ @@ -885,10 +817,8 @@ re_search_internal (const regex_t *preg, match_ctx_clean (&mctx); } -#ifdef DEBUG - assert (match_last != REG_MISSING); - assert (err == REG_NOERROR); -#endif + DEBUG_ASSERT (match_last != -1); + DEBUG_ASSERT (err == REG_NOERROR); /* Set pmatch[] if we need. */ if (nmatch > 0) @@ -910,7 +840,7 @@ re_search_internal (const regex_t *preg, { err = set_regs (preg, &mctx, nmatch, pmatch, dfa->has_plural_match && dfa->nbackref > 0); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; } @@ -920,8 +850,7 @@ re_search_internal (const regex_t *preg, for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) if (pmatch[reg_idx].rm_so != -1) { -#ifdef RE_ENABLE_I18N - if (BE (mctx.input.offsets_needed != 0, 0)) + if (__glibc_unlikely (mctx.input.offsets_needed != 0)) { pmatch[reg_idx].rm_so = (pmatch[reg_idx].rm_so == mctx.input.valid_len @@ -932,9 +861,6 @@ re_search_internal (const regex_t *preg, ? mctx.input.valid_raw_len : mctx.input.offsets[pmatch[reg_idx].rm_eo]); } -#else - assert (mctx.input.offsets_needed == 0); -#endif pmatch[reg_idx].rm_so += match_first; pmatch[reg_idx].rm_eo += match_first; } @@ -973,18 +899,17 @@ prune_impossible_nodes (re_match_context_t *mctx) re_dfastate_t **sifted_states; re_dfastate_t **lim_states = NULL; re_sift_context_t sctx; -#ifdef DEBUG - assert (mctx->state_log != NULL); -#endif + DEBUG_ASSERT (mctx->state_log != NULL); match_last = mctx->match_last; halt_node = mctx->last_node; /* Avoid overflow. */ - if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) <= match_last, 0)) + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) + <= match_last)) return REG_ESPACE; sifted_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (sifted_states == NULL, 0)) + if (__glibc_unlikely (sifted_states == NULL)) { ret = REG_ESPACE; goto free_return; @@ -992,7 +917,7 @@ prune_impossible_nodes (re_match_context_t *mctx) if (dfa->nbackref) { lim_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (lim_states == NULL, 0)) + if (__glibc_unlikely (lim_states == NULL)) { ret = REG_ESPACE; goto free_return; @@ -1005,14 +930,14 @@ prune_impossible_nodes (re_match_context_t *mctx) match_last); ret = sift_states_backward (mctx, &sctx); re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) goto free_return; if (sifted_states[0] != NULL || lim_states[0] != NULL) break; do { --match_last; - if (! REG_VALID_INDEX (match_last)) + if (match_last < 0) { ret = REG_NOMATCH; goto free_return; @@ -1027,7 +952,7 @@ prune_impossible_nodes (re_match_context_t *mctx) match_last + 1); re_free (lim_states); lim_states = NULL; - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) goto free_return; } else @@ -1035,7 +960,7 @@ prune_impossible_nodes (re_match_context_t *mctx) sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last); ret = sift_states_backward (mctx, &sctx); re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) goto free_return; if (sifted_states[0] == NULL) { @@ -1059,8 +984,7 @@ prune_impossible_nodes (re_match_context_t *mctx) We must select appropriate initial state depending on the context, since initial states may have constraints like "\<", "^", etc.. */ -static inline re_dfastate_t * -__attribute__ ((always_inline)) internal_function +static __always_inline re_dfastate_t * acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, Idx idx) { @@ -1093,8 +1017,8 @@ acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, } /* Check whether the regular expression match input string INPUT or not, - and return the index where the matching end. Return REG_MISSING if - there is no match, and return REG_ERROR in case of an error. + and return the index where the matching end. Return -1 if + there is no match, and return -2 in case of an error. FL_LONGEST_MATCH means we want the POSIX longest matching. If P_MATCH_FIRST is not NULL, and the match fails, it is set to the next place where we may want to try matching. @@ -1102,14 +1026,14 @@ acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, index of the buffer. */ static Idx -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ check_matching (re_match_context_t *mctx, bool fl_longest_match, Idx *p_match_first) { const re_dfa_t *const dfa = mctx->dfa; reg_errcode_t err; Idx match = 0; - Idx match_last = REG_MISSING; + Idx match_last = -1; Idx cur_str_idx = re_string_cur_idx (&mctx->input); re_dfastate_t *cur_state; bool at_init_state = p_match_first != NULL; @@ -1118,10 +1042,10 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, err = REG_NOERROR; cur_state = acquire_init_state_context (&err, mctx, cur_str_idx); /* An initial state must not be NULL (invalid). */ - if (BE (cur_state == NULL, 0)) + if (__glibc_unlikely (cur_state == NULL)) { - assert (err == REG_ESPACE); - return REG_ERROR; + DEBUG_ASSERT (err == REG_ESPACE); + return -2; } if (mctx->state_log != NULL) @@ -1130,24 +1054,24 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, /* Check OP_OPEN_SUBEXP in the initial state in case that we use them later. E.g. Processing back references. */ - if (BE (dfa->nbackref, 0)) + if (__glibc_unlikely (dfa->nbackref)) { at_init_state = false; err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; if (cur_state->has_backref) { err = transit_state_bkref (mctx, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } } } /* If the RE accepts NULL string. */ - if (BE (cur_state->halt, 0)) + if (__glibc_unlikely (cur_state->halt)) { if (!cur_state->has_constraint || check_halt_state_context (mctx, cur_state, cur_str_idx)) @@ -1167,16 +1091,16 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, re_dfastate_t *old_state = cur_state; Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1; - if ((BE (next_char_idx >= mctx->input.bufs_len, 0) + if ((__glibc_unlikely (next_char_idx >= mctx->input.bufs_len) && mctx->input.bufs_len < mctx->input.len) - || (BE (next_char_idx >= mctx->input.valid_len, 0) + || (__glibc_unlikely (next_char_idx >= mctx->input.valid_len) && mctx->input.valid_len < mctx->input.len)) { err = extend_buffers (mctx, next_char_idx + 1); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { - assert (err == REG_ESPACE); - return REG_ERROR; + DEBUG_ASSERT (err == REG_ESPACE); + return -2; } } @@ -1189,8 +1113,8 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, /* Reached the invalid state or an error. Try to recover a valid state using the state log, if available and if we have not already found a valid (even if not the longest) match. */ - if (BE (err != REG_NOERROR, 0)) - return REG_ERROR; + if (__glibc_unlikely (err != REG_NOERROR)) + return -2; if (mctx->state_log == NULL || (match && !fl_longest_match) @@ -1198,7 +1122,7 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, break; } - if (BE (at_init_state, 0)) + if (__glibc_unlikely (at_init_state)) { if (old_state == cur_state) next_start_idx = next_char_idx; @@ -1235,7 +1159,6 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, /* Check NODE match the current context. */ static bool -internal_function check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) { re_token_type_t type = dfa->nodes[node].type; @@ -1254,15 +1177,12 @@ check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) match the context, return the node. */ static Idx -internal_function check_halt_state_context (const re_match_context_t *mctx, const re_dfastate_t *state, Idx idx) { Idx i; unsigned int context; -#ifdef DEBUG - assert (state->halt); -#endif + DEBUG_ASSERT (state->halt); context = re_string_context_at (&mctx->input, idx, mctx->eflags); for (i = 0; i < state->nodes.nelem; ++i) if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context)) @@ -1273,33 +1193,35 @@ check_halt_state_context (const re_match_context_t *mctx, /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA corresponding to the DFA). Return the destination node, and update EPS_VIA_NODES; - return REG_MISSING in case of errors. */ + return -1 on match failure, -2 on error. */ static Idx -internal_function proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + regmatch_t *prevregs, Idx *pidx, Idx node, re_node_set *eps_via_nodes, struct re_fail_stack_t *fs) { const re_dfa_t *const dfa = mctx->dfa; - Idx i; - bool ok; if (IS_EPSILON_NODE (dfa->nodes[node].type)) { re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; re_node_set *edests = &dfa->edests[node]; - Idx dest_node; - ok = re_node_set_insert (eps_via_nodes, node); - if (BE (! ok, 0)) - return REG_ERROR; - /* Pick up a valid destination, or return REG_MISSING if none - is found. */ - for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i) + + if (! re_node_set_contains (eps_via_nodes, node)) + { + bool ok = re_node_set_insert (eps_via_nodes, node); + if (__glibc_unlikely (! ok)) + return -2; + } + + /* Pick a valid destination, or return -1 if none is found. */ + Idx dest_node = -1; + for (Idx i = 0; i < edests->nelem; i++) { Idx candidate = edests->elems[i]; if (!re_node_set_contains (cur_nodes, candidate)) continue; - if (dest_node == REG_MISSING) + if (dest_node == -1) dest_node = candidate; else @@ -1312,8 +1234,8 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, /* Otherwise, push the second epsilon-transition on the fail stack. */ else if (fs != NULL && push_fail_stack (fs, *pidx, candidate, nregs, regs, - eps_via_nodes)) - return REG_ERROR; + prevregs, eps_via_nodes)) + return -2; /* We know we are going to exit. */ break; @@ -1326,34 +1248,36 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, Idx naccepted = 0; re_token_type_t type = dfa->nodes[node].type; -#ifdef RE_ENABLE_I18N if (dfa->nodes[node].accept_mb) naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); - else -#endif /* RE_ENABLE_I18N */ - if (type == OP_BACK_REF) + else if (type == OP_BACK_REF) { Idx subexp_idx = dfa->nodes[node].opr.idx + 1; - naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; + if (subexp_idx < nregs) + naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; if (fs != NULL) { - if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1) - return REG_MISSING; + if (subexp_idx >= nregs + || regs[subexp_idx].rm_so == -1 + || regs[subexp_idx].rm_eo == -1) + return -1; else if (naccepted) { char *buf = (char *) re_string_get_buffer (&mctx->input); - if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, - naccepted) != 0) - return REG_MISSING; + if (mctx->input.valid_len - *pidx < naccepted + || (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, + naccepted) + != 0)) + return -1; } } if (naccepted == 0) { Idx dest_node; - ok = re_node_set_insert (eps_via_nodes, node); - if (BE (! ok, 0)) - return REG_ERROR; + bool ok = re_node_set_insert (eps_via_nodes, node); + if (__glibc_unlikely (! ok)) + return -2; dest_node = dfa->edests[node].elems[0]; if (re_node_set_contains (&mctx->state_log[*pidx]->nodes, dest_node)) @@ -1369,26 +1293,27 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL || !re_node_set_contains (&mctx->state_log[*pidx]->nodes, dest_node))) - return REG_MISSING; + return -1; re_node_set_empty (eps_via_nodes); return dest_node; } } - return REG_MISSING; + return -1; } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, - Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) + Idx nregs, regmatch_t *regs, regmatch_t *prevregs, + re_node_set *eps_via_nodes) { reg_errcode_t err; - Idx num = fs->num++; - if (fs->num == fs->alloc) + Idx num = fs->num; + if (num == fs->alloc) { struct re_fail_stack_ent_t *new_array; - new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) - * fs->alloc * 2)); + new_array = re_realloc (fs->stack, struct re_fail_stack_ent_t, + fs->alloc * 2); if (new_array == NULL) return REG_ESPACE; fs->alloc *= 2; @@ -1396,36 +1321,47 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, } fs->stack[num].idx = str_idx; fs->stack[num].node = dest_node; - fs->stack[num].regs = re_malloc (regmatch_t, nregs); + fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs); if (fs->stack[num].regs == NULL) return REG_ESPACE; + fs->num = num + 1; memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); + memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs); err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); return err; } static Idx -internal_function pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, - regmatch_t *regs, re_node_set *eps_via_nodes) + regmatch_t *regs, regmatch_t *prevregs, + re_node_set *eps_via_nodes) { + if (fs == NULL || fs->num == 0) + return -1; Idx num = --fs->num; - assert (REG_VALID_INDEX (num)); *pidx = fs->stack[num].idx; memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); + memcpy (prevregs, fs->stack[num].regs + nregs, sizeof (regmatch_t) * nregs); re_node_set_free (eps_via_nodes); re_free (fs->stack[num].regs); *eps_via_nodes = fs->stack[num].eps_via_nodes; + DEBUG_ASSERT (0 <= fs->stack[num].node); return fs->stack[num].node; } + +#define DYNARRAY_STRUCT regmatch_list +#define DYNARRAY_ELEMENT regmatch_t +#define DYNARRAY_PREFIX regmatch_list_ +#include + /* Set the positions where the subexpressions are starts/ends to registers PMATCH. Note: We assume that pmatch[0] is already set, and pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, regmatch_t *pmatch, bool fl_backtrack) { @@ -1434,13 +1370,11 @@ 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); -#ifdef DEBUG - assert (nmatch > 1); - assert (mctx->state_log != NULL); -#endif + DEBUG_ASSERT (nmatch > 1); + DEBUG_ASSERT (mctx->state_log != NULL); if (fl_backtrack) { fs = &fs_body; @@ -1454,85 +1388,73 @@ 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 ;) { update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); - if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) + if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node) + || (fs && re_node_set_contains (&eps_via_nodes, cur_node))) { Idx reg_idx; + cur_node = -1; if (fs) { for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) - break; - if (reg_idx == nmatch) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); - } - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); + { + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + prev_idx_match, &eps_via_nodes); + break; + } } - else + if (cur_node < 0) { re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOERROR; + regmatch_list_free (&prev_match); + return free_fail_stack_return (fs); } } /* Proceed to next node. */ - cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, + cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match, + &idx, cur_node, &eps_via_nodes, fs); - if (BE (! REG_VALID_INDEX (cur_node), 0)) + if (__glibc_unlikely (cur_node < 0)) { - if (BE (cur_node == REG_ERROR, 0)) + 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; } - if (fs) - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - else + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + prev_idx_match, &eps_via_nodes); + if (cur_node < 0) { 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_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); } static reg_errcode_t -internal_function free_fail_stack_return (struct re_fail_stack_t *fs) { if (fs) @@ -1549,7 +1471,6 @@ free_fail_stack_return (struct re_fail_stack_t *fs) } static void -internal_function update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch) { @@ -1567,10 +1488,10 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, } else if (type == OP_CLOSE_SUBEXP) { + /* We are at the last node of this sub expression. */ Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; if (reg_num < nmatch) { - /* We are at the last node of this sub expression. */ if (pmatch[reg_num].rm_so < cur_idx) { pmatch[reg_num].rm_eo = cur_idx; @@ -1621,7 +1542,6 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) static reg_errcode_t -internal_function sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) { reg_errcode_t err; @@ -1629,17 +1549,15 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) Idx str_idx = sctx->last_str_idx; re_node_set cur_dest; -#ifdef DEBUG - assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); -#endif + DEBUG_ASSERT (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); /* Build sifted state_log[str_idx]. It has the nodes which can epsilon transit to the last_node and the last_node itself. */ err = re_node_set_init_1 (&cur_dest, sctx->last_node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; /* Then check each states in the state_log. */ @@ -1660,7 +1578,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) if (mctx->state_log[str_idx]) { err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; } @@ -1669,7 +1587,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) - It is in CUR_SRC. And update state_log. */ err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; } err = REG_NOERROR; @@ -1679,7 +1597,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, re_node_set *cur_dest) { @@ -1699,17 +1617,12 @@ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx prev_node = cur_src->elems[i]; int naccepted = 0; bool ok; + DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[prev_node].type)); -#ifdef DEBUG - re_token_type_t type = dfa->nodes[prev_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N /* If the node may accept "multi byte". */ if (dfa->nodes[prev_node].accept_mb) naccepted = sift_states_iter_mb (mctx, sctx, prev_node, str_idx, sctx->last_str_idx); -#endif /* RE_ENABLE_I18N */ /* We don't check backreferences here. See update_cur_sifted_state(). */ @@ -1731,7 +1644,7 @@ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, continue; } ok = re_node_set_insert (cur_dest, prev_node); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } @@ -1741,7 +1654,6 @@ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, /* Helper functions. */ static reg_errcode_t -internal_function clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) { Idx top = mctx->state_log_top; @@ -1753,12 +1665,13 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) { reg_errcode_t err; err = extend_buffers (mctx, next_state_log_idx + 1); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } if (top < next_state_log_idx) { + DEBUG_ASSERT (mctx->state_log != NULL); memset (mctx->state_log + top + 1, '\0', sizeof (re_dfastate_t *) * (next_state_log_idx - top)); mctx->state_log_top = next_state_log_idx; @@ -1767,7 +1680,6 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) } static reg_errcode_t -internal_function merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, re_dfastate_t **src, Idx num) { @@ -1782,11 +1694,11 @@ merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, re_node_set merged_set; err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes, &src[st_idx]->nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; dst[st_idx] = re_acquire_state (&err, dfa, &merged_set); re_node_set_free (&merged_set); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } } @@ -1794,7 +1706,6 @@ merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, } static reg_errcode_t -internal_function update_cur_sifted_state (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, re_node_set *dest_nodes) @@ -1814,7 +1725,7 @@ update_cur_sifted_state (const re_match_context_t *mctx, /* At first, add the nodes which can epsilon transit to a node in DEST_NODE. */ err = add_epsilon_src_nodes (dfa, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; /* Then, check the limitations in the current sift_context. */ @@ -1822,27 +1733,27 @@ update_cur_sifted_state (const re_match_context_t *mctx, { err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits, mctx->bkref_ents, str_idx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } } sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } if (candidates && mctx->state_log[str_idx]->has_backref) { err = sift_states_bkref (mctx, sctx, str_idx, candidates); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } return REG_NOERROR; } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, const re_node_set *candidates) { @@ -1850,19 +1761,19 @@ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, Idx i; re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; if (!state->inveclosure.alloc) { err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return REG_ESPACE; for (i = 0; i < dest_nodes->nelem; i++) { err = re_node_set_merge (&state->inveclosure, dfa->inveclosures + dest_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return REG_ESPACE; } } @@ -1871,7 +1782,6 @@ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, } static reg_errcode_t -internal_function sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, const re_node_set *candidates) { @@ -1889,16 +1799,16 @@ sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, { Idx edst1 = dfa->edests[cur_node].elems[0]; Idx edst2 = ((dfa->edests[cur_node].nelem > 1) - ? dfa->edests[cur_node].elems[1] : REG_MISSING); + ? dfa->edests[cur_node].elems[1] : -1); if ((!re_node_set_contains (inv_eclosure, edst1) && re_node_set_contains (dest_nodes, edst1)) - || (REG_VALID_NONZERO_INDEX (edst2) + || (edst2 > 0 && !re_node_set_contains (inv_eclosure, edst2) && re_node_set_contains (dest_nodes, edst2))) { err = re_node_set_add_intersect (&except_nodes, candidates, dfa->inveclosures + cur_node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&except_nodes); return err; @@ -1920,7 +1830,6 @@ sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, } static bool -internal_function check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx) { @@ -1956,7 +1865,6 @@ check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, } static int -internal_function check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, Idx subexp_idx, Idx from_node, Idx bkref_idx) { @@ -1972,7 +1880,7 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, switch (dfa->nodes[node].type) { case OP_BACK_REF: - if (bkref_idx != REG_MISSING) + if (bkref_idx != -1) { struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; do @@ -2038,7 +1946,6 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, } static int -internal_function check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, Idx subexp_idx, Idx from_node, Idx str_idx, Idx bkref_idx) @@ -2068,7 +1975,6 @@ check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, which are against limitations from DEST_NODES. */ static reg_errcode_t -internal_function check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, const re_node_set *candidates, re_node_set *limits, struct re_backref_cache_entry *bkref_ents, Idx str_idx) @@ -2088,8 +1994,8 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, subexp_idx = dfa->nodes[ent->node].opr.idx; if (ent->subexp_to == str_idx) { - Idx ops_node = REG_MISSING; - Idx cls_node = REG_MISSING; + Idx ops_node = -1; + Idx cls_node = -1; for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) { Idx node = dest_nodes->elems[node_idx]; @@ -2104,16 +2010,16 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, /* Check the limitation of the open subexpression. */ /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */ - if (REG_VALID_INDEX (ops_node)) + if (ops_node >= 0) { err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } /* Check the limitation of the close subexpression. */ - if (REG_VALID_INDEX (cls_node)) + if (cls_node >= 0) for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) { Idx node = dest_nodes->elems[node_idx]; @@ -2126,7 +2032,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, Remove it form the current sifted state. */ err = sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; --node_idx; } @@ -2146,7 +2052,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, Remove it form the current sifted state. */ err = sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } } @@ -2156,7 +2062,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, } static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, const re_node_set *candidates) { @@ -2166,7 +2072,7 @@ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, re_sift_context_t local_sctx; Idx first_idx = search_cur_bkref_entry (mctx, str_idx); - if (first_idx == REG_MISSING) + if (first_idx == -1) return REG_NOERROR; local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */ @@ -2212,27 +2118,27 @@ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, { local_sctx = *sctx; err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; } local_sctx.last_node = node; local_sctx.last_str_idx = str_idx; ok = re_node_set_insert (&local_sctx.limits, enabled_idx); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) { err = REG_ESPACE; goto free_return; } cur_state = local_sctx.sifted_states[str_idx]; err = sift_states_backward (mctx, &local_sctx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; if (sctx->limited_states != NULL) { err = merge_state_array (dfa, sctx->limited_states, local_sctx.sifted_states, str_idx + 1); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; } local_sctx.sifted_states[str_idx] = cur_state; @@ -2254,9 +2160,7 @@ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, } -#ifdef RE_ENABLE_I18N static int -internal_function sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx node_idx, Idx str_idx, Idx max_str_idx) { @@ -2264,44 +2168,41 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, int naccepted; /* Check the node can accept "multi byte". */ naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx); - if (naccepted > 0 && str_idx + naccepted <= max_str_idx && - !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted], - dfa->nexts[node_idx])) + if (naccepted > 0 && str_idx + naccepted <= max_str_idx + && !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted], + dfa->nexts[node_idx])) /* The node can't accept the "multi byte", or the destination was already thrown away, then the node - could't accept the current input "multi byte". */ + couldn't accept the current input "multi byte". */ naccepted = 0; /* Otherwise, it is sure that the node could accept 'naccepted' bytes input. */ return naccepted; } -#endif /* RE_ENABLE_I18N */ - /* Functions for state transition. */ /* Return the next state to which the current state STATE will transit by accepting the current input byte, and update STATE_LOG if necessary. + Return NULL on failure. If STATE can accept a multibyte char/collating element/back reference update the destination of STATE_LOG. */ static re_dfastate_t * -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ transit_state (reg_errcode_t *err, re_match_context_t *mctx, re_dfastate_t *state) { re_dfastate_t **trtable; unsigned char ch; -#ifdef RE_ENABLE_I18N /* If the current state can accept multibyte. */ - if (BE (state->accept_mb, 0)) + if (__glibc_unlikely (state->accept_mb)) { *err = transit_state_mb (mctx, state); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) return NULL; } -#endif /* RE_ENABLE_I18N */ /* Then decide the next state with the single byte. */ #if 0 @@ -2315,11 +2216,11 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx, for (;;) { trtable = state->trtable; - if (BE (trtable != NULL, 1)) + if (__glibc_likely (trtable != NULL)) return trtable[ch]; trtable = state->word_trtable; - if (BE (trtable != NULL, 1)) + if (__glibc_likely (trtable != NULL)) { unsigned int context; context @@ -2344,7 +2245,6 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx, /* Update the state_log if we need */ static re_dfastate_t * -internal_function merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, re_dfastate_t *next_state) { @@ -2376,7 +2276,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, table_nodes = next_state->entrance_nodes; *err = re_node_set_init_union (&next_nodes, table_nodes, log_nodes); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) return NULL; } else @@ -2396,21 +2296,21 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, re_node_set_free (&next_nodes); } - if (BE (dfa->nbackref, 0) && next_state != NULL) + if (__glibc_unlikely (dfa->nbackref) && next_state != NULL) { /* Check OP_OPEN_SUBEXP in the current state in case that we use them later. We must check them here, since the back references in the next state might use them. */ *err = check_subexp_matching_top (mctx, &next_state->nodes, cur_idx); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) return NULL; /* If the next state has back references. */ if (next_state->has_backref) { *err = transit_state_bkref (mctx, &next_state->nodes); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) return NULL; next_state = mctx->state_log[cur_idx]; } @@ -2423,7 +2323,6 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, multi-byte match, then look in the log for a state from which to restart matching. */ static re_dfastate_t * -internal_function find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) { re_dfastate_t *cur_state; @@ -2454,7 +2353,6 @@ find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) corresponding back references. */ static reg_errcode_t -internal_function check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, Idx str_idx) { @@ -2476,7 +2374,7 @@ check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) { err = match_ctx_add_subtop (mctx, node, str_idx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } } @@ -2485,7 +2383,7 @@ check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, #if 0 /* Return the next state to which the current state STATE will transit by - accepting the current input byte. */ + accepting the current input byte. Return NULL on failure. */ static re_dfastate_t * transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, @@ -2498,7 +2396,7 @@ transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, unsigned int context; *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) return NULL; for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt) { @@ -2507,7 +2405,7 @@ transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, { *err = re_node_set_merge (&next_nodes, dfa->eclosures + dfa->nexts[cur_node]); - if (BE (*err != REG_NOERROR, 0)) + if (__glibc_unlikely (*err != REG_NOERROR)) { re_node_set_free (&next_nodes); return NULL; @@ -2525,9 +2423,7 @@ transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, } #endif -#ifdef RE_ENABLE_I18N static reg_errcode_t -internal_function transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) { const re_dfa_t *const dfa = mctx->dfa; @@ -2567,11 +2463,9 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted : mctx->max_mb_elem_len); err = clean_state_log_if_needed (mctx, dest_idx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; -#ifdef DEBUG - assert (dfa->nexts[cur_node_idx] != REG_MISSING); -#endif + DEBUG_ASSERT (dfa->nexts[cur_node_idx] != -1); new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx]; dest_state = mctx->state_log[dest_idx]; @@ -2581,7 +2475,7 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) { err = re_node_set_init_union (&dest_nodes, dest_state->entrance_nodes, new_nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } context = re_string_context_at (&mctx->input, dest_idx - 1, @@ -2590,15 +2484,14 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) = re_acquire_state_context (&err, dfa, &dest_nodes, context); if (dest_state != NULL) re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0)) + if (__glibc_unlikely (mctx->state_log[dest_idx] == NULL + && err != REG_NOERROR)) return err; } return REG_NOERROR; } -#endif /* RE_ENABLE_I18N */ static reg_errcode_t -internal_function transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) { const re_dfa_t *const dfa = mctx->dfa; @@ -2630,14 +2523,12 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) Check the substring which the substring matched. */ bkc_idx = mctx->nbkref_ents; err = get_subexp (mctx, node_idx, cur_str_idx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; /* And add the epsilon closures (which is 'new_dest_nodes') of the backreference to appropriate state_log. */ -#ifdef DEBUG - assert (dfa->nexts[node_idx] != REG_MISSING); -#endif + DEBUG_ASSERT (dfa->nexts[node_idx] != -1); for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) { Idx subexp_len; @@ -2663,8 +2554,8 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) mctx->state_log[dest_str_idx] = re_acquire_state_context (&err, dfa, new_dest_nodes, context); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) + if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR)) goto free_return; } else @@ -2673,7 +2564,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) err = re_node_set_init_union (&dest_nodes, dest_state->entrance_nodes, new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&dest_nodes); goto free_return; @@ -2681,8 +2572,8 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) mctx->state_log[dest_str_idx] = re_acquire_state_context (&err, dfa, &dest_nodes, context); re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) + if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR)) goto free_return; } /* We need to check recursively if the backreference can epsilon @@ -2692,10 +2583,10 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) { err = check_subexp_matching_top (mctx, new_dest_nodes, cur_str_idx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; err = transit_state_bkref (mctx, new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto free_return; } } @@ -2712,7 +2603,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) delay these checking for prune_impossible_nodes(). */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) { const re_dfa_t *const dfa = mctx->dfa; @@ -2720,7 +2611,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) const char *buf = (const char *) re_string_get_buffer (&mctx->input); /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */ Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx); - if (cache_idx != REG_MISSING) + if (cache_idx != -1) { const struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx; @@ -2756,7 +2647,8 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) at the back reference? */ if (sl_str_diff > 0) { - if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0)) + if (__glibc_unlikely (bkref_str_off + sl_str_diff + > mctx->input.valid_len)) { /* Not enough chars for a successful match. */ if (bkref_str_off + sl_str_diff > mctx->input.len) @@ -2765,7 +2657,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) err = clean_state_log_if_needed (mctx, bkref_str_off + sl_str_diff); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; buf = (const char *) re_string_get_buffer (&mctx->input); } @@ -2784,7 +2676,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) if (err == REG_NOMATCH) continue; - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } @@ -2803,14 +2695,14 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) at the back reference? */ if (sl_str_off > 0) { - if (BE (bkref_str_off >= mctx->input.valid_len, 0)) + if (__glibc_unlikely (bkref_str_off >= mctx->input.valid_len)) { /* If we are at the end of the input, we cannot match. */ if (bkref_str_off >= mctx->input.len) break; err = extend_buffers (mctx, bkref_str_off + 1); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; buf = (const char *) re_string_get_buffer (&mctx->input); @@ -2825,7 +2717,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) nodes = &mctx->state_log[sl_str]->nodes; cls_node = find_subexp_node (dfa, nodes, subexp_num, OP_CLOSE_SUBEXP); - if (cls_node == REG_MISSING) + if (cls_node == -1) continue; /* No. */ if (sub_top->path == NULL) { @@ -2841,15 +2733,18 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) OP_CLOSE_SUBEXP); if (err == REG_NOMATCH) continue; - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); - if (BE (sub_last == NULL, 0)) + if (__glibc_unlikely (sub_last == NULL)) return REG_ESPACE; err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, bkref_str_idx); + buf = (const char *) re_string_get_buffer (&mctx->input); if (err == REG_NOMATCH) continue; + if (__glibc_unlikely (err != REG_NOERROR)) + return err; } } return REG_NOERROR; @@ -2862,7 +2757,6 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) and SUB_LAST. */ static reg_errcode_t -internal_function get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str) { @@ -2876,7 +2770,7 @@ get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, return err; err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx, sub_last->str_idx); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx; return clean_state_log_if_needed (mctx, to_idx); @@ -2891,7 +2785,6 @@ get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, E.g. RE: (a){2} */ static Idx -internal_function find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, Idx subexp_idx, int type) { @@ -2904,16 +2797,17 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, && node->opr.idx == subexp_idx) return cls_node; } - return REG_MISSING; + return -1; } /* Check whether the node TOP_NODE at TOP_STR can arrive to the node LAST_NODE at LAST_STR. We record the path onto PATH since it will be heavily reused. - Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ + Return REG_NOERROR if it can arrive, REG_NOMATCH if it cannot, + REG_ESPACE if memory is exhausted. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, Idx top_str, Idx last_node, Idx last_str, int type) { @@ -2927,19 +2821,19 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, subexp_num = dfa->nodes[top_node].opr.idx; /* Extend the buffer if we need. */ - if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0)) + if (__glibc_unlikely (path->alloc < last_str + mctx->max_mb_elem_len + 1)) { re_dfastate_t **new_array; Idx old_alloc = path->alloc; Idx incr_alloc = last_str + mctx->max_mb_elem_len + 1; Idx new_alloc; - if (BE (IDX_MAX - old_alloc < incr_alloc, 0)) + if (__glibc_unlikely (IDX_MAX - old_alloc < incr_alloc)) return REG_ESPACE; new_alloc = old_alloc + incr_alloc; - if (BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0)) + if (__glibc_unlikely (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc)) return REG_ESPACE; new_array = re_realloc (path->array, re_dfastate_t *, new_alloc); - if (BE (new_array == NULL, 0)) + if (__glibc_unlikely (new_array == NULL)) return REG_ESPACE; path->array = new_array; path->alloc = new_alloc; @@ -2960,10 +2854,10 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, if (str_idx == top_str) { err = re_node_set_init_1 (&next_nodes, top_node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; @@ -2975,7 +2869,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, if (cur_state && cur_state->has_backref) { err = re_node_set_init_copy (&next_nodes, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } else @@ -2987,14 +2881,14 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, { err = expand_bkref_cache (mctx, &next_nodes, str_idx, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; } } cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) + if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; @@ -3009,7 +2903,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, { err = re_node_set_merge (&next_nodes, &mctx->state_log[str_idx + 1]->nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; @@ -3020,7 +2914,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, err = check_arrival_add_next_nodes (mctx, str_idx, &cur_state->non_eps_nodes, &next_nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; @@ -3030,14 +2924,14 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, if (next_nodes.nelem) { err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; } err = expand_bkref_cache (mctx, &next_nodes, str_idx, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; @@ -3045,7 +2939,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, } context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) + if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR)) { re_node_set_free (&next_nodes); return err; @@ -3078,27 +2972,22 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, Can't we unify them? */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, re_node_set *cur_nodes, re_node_set *next_nodes) { const re_dfa_t *const dfa = mctx->dfa; bool ok; Idx cur_idx; -#ifdef RE_ENABLE_I18N reg_errcode_t err = REG_NOERROR; -#endif re_node_set union_set; re_node_set_init_empty (&union_set); for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) { int naccepted = 0; Idx cur_node = cur_nodes->elems[cur_idx]; -#ifdef DEBUG - re_token_type_t type = dfa->nodes[cur_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N + DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[cur_node].type)); + /* If the node may accept "multi byte". */ if (dfa->nodes[cur_node].accept_mb) { @@ -3114,34 +3003,34 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, if (dest_state) { err = re_node_set_merge (&union_set, &dest_state->nodes); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&union_set); return err; } } ok = re_node_set_insert (&union_set, next_node); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) { re_node_set_free (&union_set); return REG_ESPACE; } mctx->state_log[next_idx] = re_acquire_state (&err, dfa, &union_set); - if (BE (mctx->state_log[next_idx] == NULL - && err != REG_NOERROR, 0)) + if (__glibc_unlikely (mctx->state_log[next_idx] == NULL + && err != REG_NOERROR)) { re_node_set_free (&union_set); return err; } } } -#endif /* RE_ENABLE_I18N */ + if (naccepted || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) { ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) { re_node_set_free (&union_set); return REG_ESPACE; @@ -3159,18 +3048,15 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, */ static reg_errcode_t -internal_function check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, Idx ex_subexp, int type) { reg_errcode_t err; Idx idx, outside_node; re_node_set new_nodes; -#ifdef DEBUG - assert (cur_nodes->nelem); -#endif + DEBUG_ASSERT (cur_nodes->nelem); err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; /* Create a new node set NEW_NODES with the nodes which are epsilon closures of the node in CUR_NODES. */ @@ -3180,11 +3066,11 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, Idx cur_node = cur_nodes->elems[idx]; const re_node_set *eclosure = dfa->eclosures + cur_node; outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type); - if (outside_node == REG_MISSING) + if (outside_node == -1) { /* There are no problematic nodes, just merge them. */ err = re_node_set_merge (&new_nodes, eclosure); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&new_nodes); return err; @@ -3195,7 +3081,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, /* There are problematic nodes, re-calculate incrementally. */ err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node, ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) { re_node_set_free (&new_nodes); return err; @@ -3212,7 +3098,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, problematic append it to DST_NODES. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, Idx target, Idx ex_subexp, int type) { @@ -3227,13 +3113,13 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, if (type == OP_CLOSE_SUBEXP) { ok = re_node_set_insert (dst_nodes, cur_node); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; } break; } ok = re_node_set_insert (dst_nodes, cur_node); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) return REG_ESPACE; if (dfa->edests[cur_node].nelem == 0) break; @@ -3243,7 +3129,7 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, err = check_arrival_expand_ecl_sub (dfa, dst_nodes, dfa->edests[cur_node].elems[1], ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } cur_node = dfa->edests[cur_node].elems[0]; @@ -3257,7 +3143,7 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, in MCTX->BKREF_ENTS. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, Idx cur_str, Idx subexp_num, int type) { @@ -3266,7 +3152,7 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str); struct re_backref_cache_entry *ent; - if (cache_idx_start == REG_MISSING) + if (cache_idx_start == -1) return REG_NOERROR; restart: @@ -3295,8 +3181,8 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type); err3 = re_node_set_merge (cur_nodes, &new_dests); re_node_set_free (&new_dests); - if (BE (err != REG_NOERROR || err2 != REG_NOERROR - || err3 != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR || err2 != REG_NOERROR + || err3 != REG_NOERROR)) { err = (err != REG_NOERROR ? err : (err2 != REG_NOERROR ? err2 : err3)); @@ -3318,7 +3204,7 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, err = re_node_set_init_copy (&union_set, &mctx->state_log[to_idx]->nodes); ok = re_node_set_insert (&union_set, next_node); - if (BE (err != REG_NOERROR || ! ok, 0)) + if (__glibc_unlikely (err != REG_NOERROR || ! ok)) { re_node_set_free (&union_set); err = err != REG_NOERROR ? err : REG_ESPACE; @@ -3328,13 +3214,13 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, else { err = re_node_set_init_1 (&union_set, next_node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) return err; } mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set); re_node_set_free (&union_set); - if (BE (mctx->state_log[to_idx] == NULL - && err != REG_NOERROR, 0)) + if (__glibc_unlikely (mctx->state_log[to_idx] == NULL + && err != REG_NOERROR)) return err; } } @@ -3345,8 +3231,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 -internal_function +static bool __attribute_noinline__ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) { reg_errcode_t err; @@ -3354,36 +3239,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 (BE (dests_alloc == NULL, 0)) - 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; @@ -3391,16 +3260,14 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) /* At first, group all nodes belonging to 'state' into several destinations. */ ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); - if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0)) + if (__glibc_unlikely (ndests <= 0)) { - if (dests_node_malloced) - free (dests_alloc); /* Return false in case of an error, true otherwise. */ if (ndests == 0) { state->trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (state->trtable == NULL, 0)) + if (__glibc_unlikely (state->trtable == NULL)) return false; return true; } @@ -3408,40 +3275,15 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) } err = re_node_set_alloc (&follows, ndests + 1); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - - /* Avoid arithmetic overflow in size calculation. */ - if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) - / (3 * sizeof (re_dfastate_t *))) - < ndests), - 0)) - 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 + if (__glibc_unlikely (err != REG_NOERROR)) { - dest_states = (re_dfastate_t **) - malloc (ndests * 3 * sizeof (re_dfastate_t *)); - if (BE (dest_states == NULL, 0)) - { -out_free: - if (dest_states_malloced) - 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) - 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. */ @@ -3453,15 +3295,15 @@ out_free: for (j = 0; j < dests_node[i].nelem; ++j) { next_node = dfa->nexts[dests_node[i].elems[j]]; - if (next_node != REG_MISSING) + if (next_node != -1) { err = re_node_set_merge (&follows, dfa->eclosures + next_node); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto out_free; } } dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); - if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) + if (__glibc_unlikely (dest_states[i] == NULL && err != REG_NOERROR)) goto out_free; /* If the new state has context constraint, build appropriate states for these contexts. */ @@ -3469,7 +3311,8 @@ out_free: { dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, CONTEXT_WORD); - if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) + if (__glibc_unlikely (dest_states_word[i] == NULL + && err != REG_NOERROR)) goto out_free; if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1) @@ -3477,7 +3320,7 @@ out_free: dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, CONTEXT_NEWLINE); - if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) + if (__glibc_unlikely (dest_states_nl[i] == NULL && err != REG_NOERROR)) goto out_free; } else @@ -3488,7 +3331,7 @@ out_free: bitset_merge (acceptable, dests_ch[i]); } - if (!BE (need_word_trtable, 0)) + if (!__glibc_unlikely (need_word_trtable)) { /* We don't care about whether the following character is a word character, or we are in a single-byte character set so we can @@ -3496,7 +3339,7 @@ out_free: 256-entry transition table. */ trtable = state->trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (trtable == NULL, 0)) + if (__glibc_unlikely (trtable == NULL)) goto out_free; /* For all characters ch...: */ @@ -3504,7 +3347,7 @@ out_free: for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; elem; mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) + if (__glibc_unlikely (elem & 1)) { /* There must be exactly one destination which accepts character ch. See group_nodes_into_DFAstates. */ @@ -3527,7 +3370,7 @@ out_free: starting at trtable[SBC_MAX]. */ trtable = state->word_trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); - if (BE (trtable == NULL, 0)) + if (__glibc_unlikely (trtable == NULL)) goto out_free; /* For all characters ch...: */ @@ -3535,7 +3378,7 @@ out_free: for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; elem; mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) + if (__glibc_unlikely (elem & 1)) { /* There must be exactly one destination which accepts character ch. See group_nodes_into_DFAstates. */ @@ -3565,26 +3408,19 @@ out_free: } } - if (dest_states_malloced) - 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) - free (dests_alloc); - return true; } /* Group all nodes belonging to STATE into several destinations. Then for all destinations, set the nodes belonging to the destination to DESTS_NODE[i] and set the characters accepted by the destination - to DEST_CH[i]. This function return the number of destinations. */ + to DEST_CH[i]. Return the number of destinations if successful, + -1 on internal error. */ static Idx -internal_function group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, re_node_set *dests_node, bitset_t *dests_ch) { @@ -3613,18 +3449,15 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, } else if (type == OP_PERIOD) { -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) bitset_merge (accepts, dfa->sb_char); else -#endif bitset_set_all (accepts); if (!(dfa->syntax & RE_DOT_NEWLINE)) bitset_clear (accepts, '\n'); if (dfa->syntax & RE_DOT_NOT_NULL) bitset_clear (accepts, '\0'); } -#ifdef RE_ENABLE_I18N else if (type == OP_UTF8_PERIOD) { if (ASCII_CHARS % BITSET_WORD_BITS == 0) @@ -3636,7 +3469,6 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, if (dfa->syntax & RE_DOT_NOT_NULL) bitset_clear (accepts, '\0'); } -#endif else continue; @@ -3667,12 +3499,10 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, bitset_empty (accepts); continue; } -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) for (j = 0; j < BITSET_WORDS; ++j) any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); else -#endif for (j = 0; j < BITSET_WORDS; ++j) any_set |= (accepts[j] &= dfa->word_char[j]); if (!any_set) @@ -3686,12 +3516,10 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, bitset_empty (accepts); continue; } -#ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) for (j = 0; j < BITSET_WORDS; ++j) any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); else -#endif for (j = 0; j < BITSET_WORDS; ++j) any_set |= (accepts[j] &= ~dfa->word_char[j]); if (!any_set) @@ -3735,14 +3563,14 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, bitset_copy (dests_ch[ndests], remains); bitset_copy (dests_ch[j], intersec); err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto error_return; ++ndests; } /* Put the position in the current group. */ ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]); - if (BE (! ok, 0)) + if (__glibc_unlikely (! ok)) goto error_return; /* If all characters are consumed, go to next node. */ @@ -3754,20 +3582,20 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, { bitset_copy (dests_ch[ndests], accepts); err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) + if (__glibc_unlikely (err != REG_NOERROR)) goto error_return; ++ndests; bitset_empty (accepts); } } + assume (ndests <= SBC_MAX); return ndests; error_return: for (j = 0; j < ndests; ++j) re_node_set_free (dests_node + j); - return REG_MISSING; + return -1; } -#ifdef RE_ENABLE_I18N /* Check how many bytes the node 'dfa->nodes[node_idx]' accepts. Return the number of the bytes the node accepts. STR_IDX is the current index of the input string. @@ -3776,8 +3604,11 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, one collating element like '.', '[a-z]', opposite to the other nodes can only accept one byte. */ +#ifdef _LIBC +# include +#endif + static int -internal_function check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, const re_string_t *input, Idx str_idx) { @@ -3785,10 +3616,10 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, int char_len, elem_len; Idx i; - if (BE (node->type == OP_UTF8_PERIOD, 0)) + if (__glibc_unlikely (node->type == OP_UTF8_PERIOD)) { unsigned char c = re_string_byte_at (input, str_idx), d; - if (BE (c < 0xc2, 1)) + if (__glibc_likely (c < 0xc2)) return 0; if (str_idx + 2 > input->len) @@ -3844,10 +3675,10 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, /* FIXME: I don't think this if is needed, as both '\n' and '\0' are char_len == 1. */ /* '.' accepts any one character except the following two cases. */ - if ((!(dfa->syntax & RE_DOT_NEWLINE) && - re_string_byte_at (input, str_idx) == '\n') || - ((dfa->syntax & RE_DOT_NOT_NULL) && - re_string_byte_at (input, str_idx) == '\0')) + if ((!(dfa->syntax & RE_DOT_NEWLINE) + && re_string_byte_at (input, str_idx) == '\n') + || ((dfa->syntax & RE_DOT_NOT_NULL) + && re_string_byte_at (input, str_idx) == '\0')) return 0; return char_len; } @@ -3859,12 +3690,12 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, if (node->type == COMPLEX_BRACKET) { const re_charset_t *cset = node->opr.mbcset; -# ifdef _LIBC +#ifdef _LIBC const unsigned char *pin = ((const unsigned char *) re_string_get_buffer (input) + str_idx); Idx j; uint32_t nrules; -# endif /* _LIBC */ +#endif int match_len = 0; wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) ? re_string_wchar_at (input, str_idx) : 0); @@ -3887,7 +3718,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, } } -# ifdef _LIBC +#ifdef _LIBC nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); if (nrules != 0) { @@ -3895,8 +3726,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, const int32_t *table, *indirect; const unsigned char *weights, *extra; const char *collseqwc; - /* This #include defines a local function! */ -# include /* match with collating_symbol? */ if (cset->ncoll_syms) @@ -3953,35 +3782,32 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - int32_t idx = findidx (&cp, elem_len); + int32_t idx = findidx (table, indirect, extra, &cp, elem_len); + int32_t rule = idx >> 24; + idx &= 0xffffff; if (idx > 0) - for (i = 0; i < cset->nequiv_classes; ++i) - { - int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx & 0xffffff]; - if (weight_len == weights[equiv_class_idx & 0xffffff] - && (idx >> 24) == (equiv_class_idx >> 24)) - { - Idx cnt = 0; - - idx &= 0xffffff; - equiv_class_idx &= 0xffffff; - - while (cnt <= weight_len - && (weights[equiv_class_idx + 1 + cnt] - == weights[idx + 1 + cnt])) - ++cnt; - if (cnt > weight_len) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - } - } + { + size_t weight_len = weights[idx]; + for (i = 0; i < cset->nequiv_classes; ++i) + { + int32_t equiv_class_idx = cset->equiv_classes[i]; + int32_t equiv_class_rule = equiv_class_idx >> 24; + equiv_class_idx &= 0xffffff; + if (weights[equiv_class_idx] == weight_len + && equiv_class_rule == rule + && memcmp (weights + idx + 1, + weights + equiv_class_idx + 1, + weight_len) == 0) + { + match_len = elem_len; + goto check_node_accept_bytes_match; + } + } + } } } else -# endif /* _LIBC */ +#endif /* _LIBC */ { /* match with range expression? */ for (i = 0; i < cset->nranges; ++i) @@ -4007,9 +3833,8 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, return 0; } -# ifdef _LIBC +#ifdef _LIBC static unsigned int -internal_function find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); @@ -4066,14 +3891,12 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) return UINT_MAX; } } -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ +#endif /* _LIBC */ /* Check whether the node accepts the byte which is IDX-th byte of the INPUT. */ static bool -internal_function check_node_accept (const re_match_context_t *mctx, const re_token_t *node, Idx idx) { @@ -4091,12 +3914,10 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node, return false; break; -#ifdef RE_ENABLE_I18N case OP_UTF8_PERIOD: if (ch >= ASCII_CHARS) return false; - /* FALLTHROUGH */ -#endif + FALLTHROUGH; case OP_PERIOD: if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE)) || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL))) @@ -4123,22 +3944,22 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node, /* Extend the buffers, if the buffers have run out. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ extend_buffers (re_match_context_t *mctx, int min_len) { reg_errcode_t ret; re_string_t *pstr = &mctx->input; /* Avoid overflow. */ - if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2 - <= pstr->bufs_len, 0)) + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2 + <= pstr->bufs_len)) return REG_ESPACE; /* Double the lengths of the buffers, but allocate at least MIN_LEN. */ ret = re_string_realloc_buffers (pstr, MAX (min_len, MIN (pstr->len, pstr->bufs_len * 2))); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; if (mctx->state_log != NULL) @@ -4149,7 +3970,7 @@ extend_buffers (re_match_context_t *mctx, int min_len) does not have the right size. */ re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *, pstr->bufs_len + 1); - if (BE (new_array == NULL, 0)) + if (__glibc_unlikely (new_array == NULL)) return REG_ESPACE; mctx->state_log = new_array; } @@ -4157,24 +3978,20 @@ extend_buffers (re_match_context_t *mctx, int min_len) /* Then reconstruct the buffers. */ if (pstr->icase) { -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) { ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) + if (__glibc_unlikely (ret != REG_NOERROR)) return ret; } else -#endif /* RE_ENABLE_I18N */ build_upper_buffer (pstr); } else { -#ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) build_wcs_buffer (pstr); else -#endif /* RE_ENABLE_I18N */ { if (pstr->trans != NULL) re_string_translate_buffer (pstr); @@ -4189,23 +4006,23 @@ extend_buffers (re_match_context_t *mctx, int min_len) /* Initialize MCTX. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) { mctx->eflags = eflags; - mctx->match_last = REG_MISSING; + mctx->match_last = -1; if (n > 0) { /* Avoid overflow. */ size_t max_object_size = MAX (sizeof (struct re_backref_cache_entry), sizeof (re_sub_match_top_t *)); - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n, 0)) + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n)) return REG_ESPACE; mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); mctx->sub_tops = re_malloc (re_sub_match_top_t *, n); - if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0)) + if (__glibc_unlikely (mctx->bkref_ents == NULL || mctx->sub_tops == NULL)) return REG_ESPACE; } /* Already zero-ed by the caller. @@ -4224,7 +4041,6 @@ match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) of the input, or changes the input string. */ static void -internal_function match_ctx_clean (re_match_context_t *mctx) { Idx st_idx; @@ -4244,7 +4060,7 @@ match_ctx_clean (re_match_context_t *mctx) re_free (top->path->array); re_free (top->path); } - free (top); + re_free (top); } mctx->nsub_tops = 0; @@ -4254,7 +4070,6 @@ match_ctx_clean (re_match_context_t *mctx) /* Free all the memory associated with MCTX. */ static void -internal_function match_ctx_free (re_match_context_t *mctx) { /* First, free all the memory associated with MCTX->SUB_TOPS. */ @@ -4269,7 +4084,7 @@ match_ctx_free (re_match_context_t *mctx) */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, Idx to) { @@ -4278,7 +4093,7 @@ match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, struct re_backref_cache_entry* new_entry; new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry, mctx->abkref_ents * 2); - if (BE (new_entry == NULL, 0)) + if (__glibc_unlikely (new_entry == NULL)) { re_free (mctx->bkref_ents); return REG_ESPACE; @@ -4314,11 +4129,10 @@ match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, return REG_NOERROR; } -/* Return the first entry with the same str_idx, or REG_MISSING if none is +/* Return the first entry with the same str_idx, or -1 if none is found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */ static Idx -internal_function search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) { Idx left, right, mid, last; @@ -4334,33 +4148,31 @@ search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) if (left < last && mctx->bkref_ents[left].str_idx == str_idx) return left; else - return REG_MISSING; + return -1; } /* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches at STR_IDX. */ static reg_errcode_t -internal_function __attribute_warn_unused_result__ +__attribute_warn_unused_result__ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) { -#ifdef DEBUG - assert (mctx->sub_tops != NULL); - assert (mctx->asub_tops > 0); -#endif - if (BE (mctx->nsub_tops == mctx->asub_tops, 0)) + DEBUG_ASSERT (mctx->sub_tops != NULL); + DEBUG_ASSERT (mctx->asub_tops > 0); + if (__glibc_unlikely (mctx->nsub_tops == mctx->asub_tops)) { Idx new_asub_tops = mctx->asub_tops * 2; re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops, re_sub_match_top_t *, new_asub_tops); - if (BE (new_array == NULL, 0)) + if (__glibc_unlikely (new_array == NULL)) return REG_ESPACE; mctx->sub_tops = new_array; mctx->asub_tops = new_asub_tops; } mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t)); - if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0)) + if (__glibc_unlikely (mctx->sub_tops[mctx->nsub_tops] == NULL)) return REG_ESPACE; mctx->sub_tops[mctx->nsub_tops]->node = node; mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx; @@ -4368,26 +4180,26 @@ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) } /* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches - at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ + at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. + Return the new entry if successful, NULL if memory is exhausted. */ static re_sub_match_last_t * -internal_function match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) { re_sub_match_last_t *new_entry; - if (BE (subtop->nlasts == subtop->alasts, 0)) + if (__glibc_unlikely (subtop->nlasts == subtop->alasts)) { Idx new_alasts = 2 * subtop->alasts + 1; re_sub_match_last_t **new_array = re_realloc (subtop->lasts, re_sub_match_last_t *, new_alasts); - if (BE (new_array == NULL, 0)) + if (__glibc_unlikely (new_array == NULL)) return NULL; subtop->lasts = new_array; subtop->alasts = new_alasts; } new_entry = calloc (1, sizeof (re_sub_match_last_t)); - if (BE (new_entry != NULL, 1)) + if (__glibc_likely (new_entry != NULL)) { subtop->lasts[subtop->nlasts] = new_entry; new_entry->node = node; @@ -4398,7 +4210,6 @@ match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) } static void -internal_function sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx) { diff --git a/gl/safe-read.c b/gl/safe-read.c deleted file mode 100644 index 6a48c0cc..00000000 --- a/gl/safe-read.c +++ /dev/null @@ -1,77 +0,0 @@ -/* An interface to read and write that retries after interrupts. - - Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2013 Free Software - Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#ifdef SAFE_WRITE -# include "safe-write.h" -#else -# include "safe-read.h" -#endif - -/* Get ssize_t. */ -#include -#include - -#include - -#ifdef EINTR -# define IS_EINTR(x) ((x) == EINTR) -#else -# define IS_EINTR(x) 0 -#endif - -#include - -#ifdef SAFE_WRITE -# define safe_rw safe_write -# define rw write -#else -# define safe_rw safe_read -# define rw read -# undef const -# define const /* empty */ -#endif - -/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if - interrupted. Return the actual number of bytes read(written), zero for EOF, - or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ -size_t -safe_rw (int fd, void const *buf, size_t count) -{ - /* Work around a bug in Tru64 5.1. Attempting to read more than - INT_MAX bytes fails with errno == EINVAL. See - . - When decreasing COUNT, keep it block-aligned. */ - enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 }; - - for (;;) - { - ssize_t result = rw (fd, buf, count); - - if (0 <= result) - return result; - else if (IS_EINTR (errno)) - continue; - else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count) - count = BUGGY_READ_MAXIMUM; - else - return result; - } -} diff --git a/gl/safe-read.h b/gl/safe-read.h deleted file mode 100644 index 992b7a6a..00000000 --- a/gl/safe-read.h +++ /dev/null @@ -1,47 +0,0 @@ -/* An interface to read() that retries after interrupts. - Copyright (C) 2002, 2006, 2009-2013 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 . */ - -/* Some system calls may be interrupted and fail with errno = EINTR in the - following situations: - - The process is stopped and restarted (signal SIGSTOP and SIGCONT, user - types Ctrl-Z) on some platforms: Mac OS X. - - The process receives a signal for which a signal handler was installed - with sigaction() with an sa_flags field that does not contain - SA_RESTART. - - The process receives a signal for which a signal handler was installed - with signal() and for which no call to siginterrupt(sig,0) was done, - on some platforms: AIX, HP-UX, IRIX, OSF/1, Solaris. - - This module provides a wrapper around read() that handles EINTR. */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SAFE_READ_ERROR ((size_t) -1) - -/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. - Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR - upon error. */ -extern size_t safe_read (int fd, void *buf, size_t count); - - -#ifdef __cplusplus -} -#endif diff --git a/gl/setenv.c b/gl/setenv.c index 995a0f26..ebfd4e55 100644 --- a/gl/setenv.c +++ b/gl/setenv.c @@ -1,18 +1,18 @@ -/* Copyright (C) 1992, 1995-2003, 2005-2013 Free Software Foundation, Inc. +/* Copyright (C) 1992, 1995-2003, 2005-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if !_LIBC /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc @@ -72,7 +72,7 @@ __libc_lock_define_initialized (static, envlock) values are from a small set. Outside glibc this will eat up all memory after a while. */ #if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ - && defined __GNUC__) + && (defined __GNUC__ || defined __clang__)) # define USE_TSEARCH 1 # include typedef int (*compar_fn_t) (const void *, const void *); diff --git a/gl/setlocale-lock.c b/gl/setlocale-lock.c new file mode 100644 index 00000000..4e7540e1 --- /dev/null +++ b/gl/setlocale-lock.c @@ -0,0 +1,150 @@ +/* Return the internal lock used by setlocale_null_r. + Copyright (C) 2019-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019. */ + +#include + +/* When it is known that the gl_get_setlocale_null_lock function is defined + by a dependency library, it should not be defined here. */ +#if OMIT_SETLOCALE_LOCK + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#else + +/* This file defines the internal lock used by setlocale_null_r. + It is a separate compilation unit, so that only one copy of it is + present when linking statically. */ + +/* Prohibit renaming this symbol. */ +# undef gl_get_setlocale_null_lock + +/* Macro for exporting a symbol (function, not variable) defined in this file, + when compiled into a shared library. */ +# ifndef DLL_EXPORTED +# if HAVE_VISIBILITY + /* Override the effect of the compiler option '-fvisibility=hidden'. */ +# define DLL_EXPORTED __attribute__((__visibility__("default"))) +# elif defined _WIN32 || defined __CYGWIN__ +# define DLL_EXPORTED __declspec(dllexport) +# else +# define DLL_EXPORTED +# endif +# endif + +# if defined _WIN32 && !defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# include "windows-initguard.h" + +/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *', + because the latter is not guaranteed to be a stable ABI in the future. */ + +/* Make sure the function gets exported from DLLs. */ +DLL_EXPORTED CRITICAL_SECTION *gl_get_setlocale_null_lock (void); + +static glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT; +static CRITICAL_SECTION lock; + +/* Returns the internal lock used by setlocale_null_r. */ +CRITICAL_SECTION * +gl_get_setlocale_null_lock (void) +{ + if (!guard.done) + { + if (InterlockedIncrement (&guard.started) == 0) + { + /* This thread is the first one to need the lock. Initialize it. */ + InitializeCriticalSection (&lock); + guard.done = 1; + } + else + { + /* Don't let guard.started grow and wrap around. */ + InterlockedDecrement (&guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!guard.done) + Sleep (0); + } + } + return &lock; +} + +# elif HAVE_PTHREAD_API + +# include + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Make sure the function gets exported from shared libraries. */ +DLL_EXPORTED pthread_mutex_t *gl_get_setlocale_null_lock (void); + +/* Returns the internal lock used by setlocale_null_r. */ +pthread_mutex_t * +gl_get_setlocale_null_lock (void) +{ + return &mutex; +} + +# elif HAVE_THREADS_H + +# include +# include + +static int volatile init_needed = 1; +static once_flag init_once = ONCE_FLAG_INIT; +static mtx_t mutex; + +static void +atomic_init (void) +{ + if (mtx_init (&mutex, mtx_plain) != thrd_success) + abort (); + init_needed = 0; +} + +/* Make sure the function gets exported from shared libraries. */ +DLL_EXPORTED mtx_t *gl_get_setlocale_null_lock (void); + +/* Returns the internal lock used by setlocale_null_r. */ +mtx_t * +gl_get_setlocale_null_lock (void) +{ + if (init_needed) + call_once (&init_once, atomic_init); + return &mutex; +} + +# endif + +# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER +/* Make sure the '__declspec(dllimport)' in setlocale_null.c does not cause + a link failure when no DLLs are involved. */ +# if defined _WIN64 || defined _LP64 +# define IMP(x) __imp_##x +# else +# define IMP(x) _imp__##x +# endif +void * IMP(gl_get_setlocale_null_lock) = &gl_get_setlocale_null_lock; +# endif + +#endif diff --git a/gl/setlocale_null.c b/gl/setlocale_null.c new file mode 100644 index 00000000..778429b9 --- /dev/null +++ b/gl/setlocale_null.c @@ -0,0 +1,411 @@ +/* Query the name of the current global locale. + Copyright (C) 2019-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019. */ + +#include + +/* Specification. */ +#include "setlocale_null.h" + +#include +#include +#include +#include +#if defined _WIN32 && !defined __CYGWIN__ +# include +#endif + +#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) +# if defined _WIN32 && !defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# elif HAVE_PTHREAD_API + +# include +# if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS +# include +# pragma weak thrd_exit +# define c11_threads_in_use() (thrd_exit != NULL) +# else +# define c11_threads_in_use() 0 +# endif + +# elif HAVE_THREADS_H + +# include + +# endif +#endif + +/* Use the system's setlocale() function, not the gnulib override, here. */ +#undef setlocale + +static const char * +setlocale_null_androidfix (int category) +{ + const char *result = setlocale (category, NULL); + +#ifdef __ANDROID__ + if (result == NULL) + switch (category) + { + case LC_CTYPE: + case LC_NUMERIC: + case LC_TIME: + case LC_COLLATE: + case LC_MONETARY: + case LC_MESSAGES: + case LC_ALL: + case LC_PAPER: + case LC_NAME: + case LC_ADDRESS: + case LC_TELEPHONE: + case LC_MEASUREMENT: + result = "C"; + break; + default: + break; + } +#endif + + return result; +} + +static int +setlocale_null_unlocked (int category, char *buf, size_t bufsize) +{ +#if defined _WIN32 && !defined __CYGWIN__ && defined _MSC_VER + /* On native Windows, nowadays, the setlocale() implementation is based + on _wsetlocale() and uses malloc() for the result. We are better off + using _wsetlocale() directly. */ + const wchar_t *result = _wsetlocale (category, NULL); + + if (result == NULL) + { + /* CATEGORY is invalid. */ + if (bufsize > 0) + /* Return an empty string in BUF. + This is a convenience for callers that don't want to write explicit + code for handling EINVAL. */ + buf[0] = '\0'; + return EINVAL; + } + else + { + size_t length = wcslen (result); + if (length < bufsize) + { + size_t i; + + /* Convert wchar_t[] -> char[], assuming plain ASCII. */ + for (i = 0; i <= length; i++) + buf[i] = result[i]; + + return 0; + } + else + { + if (bufsize > 0) + { + /* Return a truncated result in BUF. + This is a convenience for callers that don't want to write + explicit code for handling ERANGE. */ + size_t i; + + /* Convert wchar_t[] -> char[], assuming plain ASCII. */ + for (i = 0; i < bufsize; i++) + buf[i] = result[i]; + buf[bufsize - 1] = '\0'; + } + return ERANGE; + } + } +#else + const char *result = setlocale_null_androidfix (category); + + if (result == NULL) + { + /* CATEGORY is invalid. */ + if (bufsize > 0) + /* Return an empty string in BUF. + This is a convenience for callers that don't want to write explicit + code for handling EINVAL. */ + buf[0] = '\0'; + return EINVAL; + } + else + { + size_t length = strlen (result); + if (length < bufsize) + { + memcpy (buf, result, length + 1); + return 0; + } + else + { + if (bufsize > 0) + { + /* Return a truncated result in BUF. + This is a convenience for callers that don't want to write + explicit code for handling ERANGE. */ + memcpy (buf, result, bufsize - 1); + buf[bufsize - 1] = '\0'; + } + return ERANGE; + } + } +#endif +} + +#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */ + +/* Use a lock, so that no two threads can invoke setlocale_null_unlocked + at the same time. */ + +/* Prohibit renaming this symbol. */ +# undef gl_get_setlocale_null_lock + +# if defined _WIN32 && !defined __CYGWIN__ + +extern __declspec(dllimport) CRITICAL_SECTION *gl_get_setlocale_null_lock (void); + +static int +setlocale_null_with_lock (int category, char *buf, size_t bufsize) +{ + CRITICAL_SECTION *lock = gl_get_setlocale_null_lock (); + int ret; + + EnterCriticalSection (lock); + ret = setlocale_null_unlocked (category, buf, bufsize); + LeaveCriticalSection (lock); + + return ret; +} + +# elif HAVE_PTHREAD_API /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */ + +extern +# if defined _WIN32 || defined __CYGWIN__ + __declspec(dllimport) +# endif + pthread_mutex_t *gl_get_setlocale_null_lock (void); + +# if HAVE_WEAK_SYMBOLS /* musl libc, FreeBSD, NetBSD, OpenBSD, Haiku */ + + /* Avoid the need to link with '-lpthread'. */ +# pragma weak pthread_mutex_lock +# pragma weak pthread_mutex_unlock + + /* Determine whether libpthread is in use. */ +# pragma weak pthread_mutexattr_gettype + /* See the comments in lock.h. */ +# define pthread_in_use() \ + (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) + +# else +# define pthread_in_use() 1 +# endif + +static int +setlocale_null_with_lock (int category, char *buf, size_t bufsize) +{ + if (pthread_in_use()) + { + pthread_mutex_t *lock = gl_get_setlocale_null_lock (); + int ret; + + if (pthread_mutex_lock (lock)) + abort (); + ret = setlocale_null_unlocked (category, buf, bufsize); + if (pthread_mutex_unlock (lock)) + abort (); + + return ret; + } + else + return setlocale_null_unlocked (category, buf, bufsize); +} + +# elif HAVE_THREADS_H + +extern mtx_t *gl_get_setlocale_null_lock (void); + +static int +setlocale_null_with_lock (int category, char *buf, size_t bufsize) +{ + mtx_t *lock = gl_get_setlocale_null_lock (); + int ret; + + if (mtx_lock (lock) != thrd_success) + abort (); + ret = setlocale_null_unlocked (category, buf, bufsize); + if (mtx_unlock (lock) != thrd_success) + abort (); + + return ret; +} + +# endif + +#endif + +int +setlocale_null_r (int category, char *buf, size_t bufsize) +{ +#if SETLOCALE_NULL_ALL_MTSAFE +# if SETLOCALE_NULL_ONE_MTSAFE + + return setlocale_null_unlocked (category, buf, bufsize); + +# else + + if (category == LC_ALL) + return setlocale_null_unlocked (category, buf, bufsize); + else + return setlocale_null_with_lock (category, buf, bufsize); + +# endif +#else +# if SETLOCALE_NULL_ONE_MTSAFE + + if (category == LC_ALL) + return setlocale_null_with_lock (category, buf, bufsize); + else + return setlocale_null_unlocked (category, buf, bufsize); + +# else + + return setlocale_null_with_lock (category, buf, bufsize); + +# endif +#endif +} + +const char * +setlocale_null (int category) +{ +#if SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE + return setlocale_null_androidfix (category); +#else + + /* This call must be multithread-safe. To achieve this without using + thread-local storage: + 1. We use a specific static buffer for each possible CATEGORY + argument. So that different threads can call setlocale_mtsafe + with different CATEGORY arguments, without interfering. + 2. We use a simple strcpy or memcpy to fill this static buffer. + Filling it through, for example, strcpy + strcat would not be + guaranteed to leave the buffer's contents intact if another thread + is currently accessing it. If necessary, the contents is first + assembled in a stack-allocated buffer. */ + if (category == LC_ALL) + { +# if SETLOCALE_NULL_ALL_MTSAFE + return setlocale_null_androidfix (LC_ALL); +# else + char buf[SETLOCALE_NULL_ALL_MAX]; + static char resultbuf[SETLOCALE_NULL_ALL_MAX]; + + if (setlocale_null_r (LC_ALL, buf, sizeof (buf))) + return "C"; + strcpy (resultbuf, buf); + return resultbuf; +# endif + } + else + { +# if SETLOCALE_NULL_ONE_MTSAFE + return setlocale_null_androidfix (category); +# else + enum + { + LC_CTYPE_INDEX, + LC_NUMERIC_INDEX, + LC_TIME_INDEX, + LC_COLLATE_INDEX, + LC_MONETARY_INDEX, + LC_MESSAGES_INDEX, +# ifdef LC_PAPER + LC_PAPER_INDEX, +# endif +# ifdef LC_NAME + LC_NAME_INDEX, +# endif +# ifdef LC_ADDRESS + LC_ADDRESS_INDEX, +# endif +# ifdef LC_TELEPHONE + LC_TELEPHONE_INDEX, +# endif +# ifdef LC_MEASUREMENT + LC_MEASUREMENT_INDEX, +# endif +# ifdef LC_IDENTIFICATION + LC_IDENTIFICATION_INDEX, +# endif + LC_INDICES_COUNT + } + i; + char buf[SETLOCALE_NULL_MAX]; + static char resultbuf[LC_INDICES_COUNT][SETLOCALE_NULL_MAX]; + int err; + + err = setlocale_null_r (category, buf, sizeof (buf)); + if (err == EINVAL) + return NULL; + if (err) + return "C"; + + switch (category) + { + case LC_CTYPE: i = LC_CTYPE_INDEX; break; + case LC_NUMERIC: i = LC_NUMERIC_INDEX; break; + case LC_TIME: i = LC_TIME_INDEX; break; + case LC_COLLATE: i = LC_COLLATE_INDEX; break; + case LC_MONETARY: i = LC_MONETARY_INDEX; break; + case LC_MESSAGES: i = LC_MESSAGES_INDEX; break; +# ifdef LC_PAPER + case LC_PAPER: i = LC_PAPER_INDEX; break; +# endif +# ifdef LC_NAME + case LC_NAME: i = LC_NAME_INDEX; break; +# endif +# ifdef LC_ADDRESS + case LC_ADDRESS: i = LC_ADDRESS_INDEX; break; +# endif +# ifdef LC_TELEPHONE + case LC_TELEPHONE: i = LC_TELEPHONE_INDEX; break; +# endif +# ifdef LC_MEASUREMENT + case LC_MEASUREMENT: i = LC_MEASUREMENT_INDEX; break; +# endif +# ifdef LC_IDENTIFICATION + case LC_IDENTIFICATION: i = LC_IDENTIFICATION_INDEX; break; +# endif + default: + /* If you get here, a #ifdef LC_xxx is missing. */ + abort (); + } + + strcpy (resultbuf[i], buf); + return resultbuf[i]; +# endif + } +#endif +} diff --git a/gl/setlocale_null.h b/gl/setlocale_null.h new file mode 100644 index 00000000..d1921b09 --- /dev/null +++ b/gl/setlocale_null.h @@ -0,0 +1,82 @@ +/* Query the name of the current global locale. + Copyright (C) 2019-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2019. */ + +#ifndef _SETLOCALE_NULL_H +#define _SETLOCALE_NULL_H + +#include + +#include "arg-nonnull.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Recommended size of a buffer for a locale name for a single category. + On glibc systems, you can have locale names that are relative file names; + assume a maximum length 256. + In native Windows, in 2018 the longest locale name was of length 58 + ("FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251"). */ +#define SETLOCALE_NULL_MAX (256+1) + +/* Recommended size of a buffer for a locale name with all categories. + On glibc systems, you can have locale names that are relative file names; + assume maximum length 256 for each. There are 12 categories; so, the + maximum total length is 148+12*256. + In native Windows, there are 5 categories, and the maximum total length is + 55+5*58. */ +#define SETLOCALE_NULL_ALL_MAX (148+12*256+1) + +/* setlocale_null_r (CATEGORY, BUF, BUFSIZE) is like setlocale (CATEGORY, NULL), + except that + - it is guaranteed to be multithread-safe, + - it returns the resulting locale category name or locale name in the + user-supplied buffer BUF, which must be BUFSIZE bytes long. + The recommended minimum buffer size is + - SETLOCALE_NULL_MAX for CATEGORY != LC_ALL, and + - SETLOCALE_NULL_ALL_MAX for CATEGORY == LC_ALL. + The return value is an error code: 0 if the call is successful, EINVAL if + CATEGORY is invalid, or ERANGE if BUFSIZE is smaller than the length needed + size (including the trailing NUL byte). In the latter case, a truncated + result is returned in BUF, but still NUL-terminated if BUFSIZE > 0. + For this call to be multithread-safe, *all* calls to + setlocale (CATEGORY, NULL) in all other threads must have been converted + to use setlocale_null_r or setlocale_null as well, and the other threads + must not make other setlocale invocations (since changing the global locale + has side effects on all threads). */ +extern int setlocale_null_r (int category, char *buf, size_t bufsize) + _GL_ARG_NONNULL ((2)); + +/* setlocale_null (CATEGORY) is like setlocale (CATEGORY, NULL), except that + it is guaranteed to be multithread-safe. + The return value is NULL if CATEGORY is invalid. + For this call to be multithread-safe, *all* calls to + setlocale (CATEGORY, NULL) in all other threads must have been converted + to use setlocale_null_r or setlocale_null as well, and the other threads + must not make other setlocale invocations (since changing the global locale + has side effects on all threads). */ +extern const char *setlocale_null (int category); + + +#ifdef __cplusplus +} +#endif + +#endif /* _SETLOCALE_NULL_H */ diff --git a/gl/sha1-stream.c b/gl/sha1-stream.c new file mode 100644 index 00000000..0ba04352 --- /dev/null +++ b/gl/sha1-stream.c @@ -0,0 +1,129 @@ +/* sha1.c - Functions to compute SHA1 message digest of files or + memory blocks according to the NIST specification FIPS-180-1. + + Copyright (C) 2000-2001, 2003-2006, 2008-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Scott G. Miller + Credits: + Robert Klep -- Expansion function fix +*/ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_SHA1 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "sha1.h" + +#include + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#include "af_alg.h" + +#define BLOCKSIZE 32768 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* Compute SHA1 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 20 bytes + beginning at RESBLOCK. */ +int +sha1_stream (FILE *stream, void *resblock) +{ + switch (afalg_stream (stream, "sha1", resblock, SHA1_DIGEST_SIZE)) + { + case 0: return 0; + case -EIO: return 1; + } + + char *buffer = malloc (BLOCKSIZE + 72); + if (!buffer) + return 1; + + struct sha1_ctx ctx; + sha1_init_ctx (&ctx); + size_t sum; + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + while (1) + { + /* Either process a partial fread() from this loop, + or the fread() in afalg_stream may have gotten EOF. + We need to avoid a subsequent fread() as EOF may + not be sticky. For details of such systems, see: + https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */ + if (feof (stream)) + goto process_partial_block; + + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + + if (sum == BLOCKSIZE) + break; + + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + { + free (buffer); + return 1; + } + goto process_partial_block; + } + } + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + sha1_process_block (buffer, BLOCKSIZE, &ctx); + } + + process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + sha1_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + sha1_finish_ctx (&ctx, resblock); + free (buffer); + return 0; +} + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/gl/sha1.c b/gl/sha1.c index 778389af..79e50ba0 100644 --- a/gl/sha1.c +++ b/gl/sha1.c @@ -1,20 +1,20 @@ /* sha1.c - Functions to compute SHA1 message digest of files or memory blocks according to the NIST specification FIPS-180-1. - Copyright (C) 2000-2001, 2003-2006, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2000-2001, 2003-2006, 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Scott G. Miller Credits: @@ -23,28 +23,24 @@ #include +/* Specification. */ +#if HAVE_OPENSSL_SHA1 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif #include "sha1.h" #include #include -#include #include -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - +#include #ifdef WORDS_BIGENDIAN # define SWAP(n) (n) #else -# define SWAP(n) \ - (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +# define SWAP(n) bswap_32 (n) #endif -#define BLOCKSIZE 32768 -#if BLOCKSIZE % 64 != 0 -# error "invalid BLOCKSIZE" -#endif +#if ! HAVE_OPENSSL_SHA1 /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ @@ -117,79 +113,6 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) return sha1_read_ctx (ctx, resbuf); } -/* Compute SHA1 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. */ -int -sha1_stream (FILE *stream, void *resblock) -{ - struct sha1_ctx ctx; - size_t sum; - - char *buffer = malloc (BLOCKSIZE + 72); - if (!buffer) - return 1; - - /* Initialize the computation context. */ - sha1_init_ctx (&ctx); - - /* Iterate over full file contents. */ - while (1) - { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the - computation function processes the whole buffer so that with the - next round of the loop another block can be read. */ - size_t n; - sum = 0; - - /* Read block. Take care for partial reads. */ - while (1) - { - n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); - - sum += n; - - if (sum == BLOCKSIZE) - break; - - if (n == 0) - { - /* Check for the error flag IFF N == 0, so that we don't - exit the loop after a partial read due to e.g., EAGAIN - or EWOULDBLOCK. */ - if (ferror (stream)) - { - free (buffer); - return 1; - } - goto process_partial_block; - } - - /* We've read at least one byte, so ignore errors. But always - check for EOF, since feof may be true even though N > 0. - Otherwise, we could end up calling fread after EOF. */ - if (feof (stream)) - goto process_partial_block; - } - - /* Process buffer with BLOCKSIZE bytes. Note that - BLOCKSIZE % 64 == 0 - */ - sha1_process_block (buffer, BLOCKSIZE, &ctx); - } - - process_partial_block:; - - /* Process any remaining bytes. */ - if (sum > 0) - sha1_process_bytes (buffer, sum, &ctx); - - /* Construct result in desired memory. */ - sha1_finish_ctx (&ctx, resblock); - free (buffer); - return 0; -} - /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message @@ -227,7 +150,8 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap. */ + /* The regions in the following copy operation cannot overlap, + because ctx->buflen < 64 ≤ (left_over + add) & ~63. */ memcpy (ctx->buffer, &((char *) ctx->buffer)[(left_over + add) & ~63], ctx->buflen); @@ -240,7 +164,7 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) /* Process available complete blocks. */ if (len >= 64) { -#if !_STRING_ARCH_unaligned +#if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned) # define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (uint32_t) != 0) if (UNALIGNED_P (buffer)) while (len > 64) @@ -269,6 +193,8 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) { sha1_process_block (ctx->buffer, 64, ctx); left_over -= 64; + /* The regions in the following copy operation cannot overlap, + because left_over ≤ 64. */ memcpy (ctx->buffer, &ctx->buffer[16], left_over); } ctx->buflen = left_over; @@ -424,3 +350,12 @@ sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) e = ctx->E += e; } } + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/gl/sha1.h b/gl/sha1.h index ddd386f9..bc3470a5 100644 --- a/gl/sha1.h +++ b/gl/sha1.h @@ -1,20 +1,20 @@ /* Declarations of functions and data types used for SHA1 sum library functions. - Copyright (C) 2000-2001, 2003, 2005-2006, 2008-2013 Free Software + Copyright (C) 2000-2001, 2003, 2005-2006, 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef SHA1_H # define SHA1_H 1 @@ -22,12 +22,23 @@ # include # include +# if HAVE_OPENSSL_SHA1 +# ifndef OPENSSL_API_COMPAT +# define OPENSSL_API_COMPAT 0x10101000L /* FIXME: Use OpenSSL 1.1+ API. */ +# endif +# include +# endif + # ifdef __cplusplus extern "C" { # endif -#define SHA1_DIGEST_SIZE 20 +# define SHA1_DIGEST_SIZE 20 +# if HAVE_OPENSSL_SHA1 +# define GL_OPENSSL_NAME 1 +# include "gl_openssl.h" +# else /* Structure to save state of computation between the single steps. */ struct sha1_ctx { @@ -38,11 +49,10 @@ struct sha1_ctx uint32_t E; uint32_t total[2]; - uint32_t buflen; - uint32_t buffer[32]; + uint32_t buflen; /* ≥ 0, ≤ 128 */ + uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */ }; - /* Initialize structure containing state of computation. */ extern void sha1_init_ctx (struct sha1_ctx *ctx); @@ -64,28 +74,42 @@ extern void sha1_process_bytes (const void *buffer, size_t len, in first 20 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf); +extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *restrict resbuf); /* Put result from CTX in first 20 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf); +extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *restrict resbuf); -/* Compute SHA1 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 20 bytes - beginning at RESBLOCK. */ -extern int sha1_stream (FILE *stream, void *resblock); - /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_buffer (const char *buffer, size_t len, void *resblock); +extern void *sha1_buffer (const char *buffer, size_t len, + void *restrict resblock); + +# endif + +/* Compute SHA1 message digest for bytes read from STREAM. + STREAM is an open file stream. Regular files are handled more efficiently. + The contents of STREAM from its current position to its end will be read. + The case that the last operation on STREAM was an 'ungetc' is not supported. + The resulting message digest number will be written into the 20 bytes + beginning at RESBLOCK. */ +extern int sha1_stream (FILE *stream, void *resblock); + # ifdef __cplusplus } # endif #endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/gl/size_max.h b/gl/size_max.h index 5f331240..dee2b8ee 100644 --- a/gl/size_max.h +++ b/gl/size_max.h @@ -1,19 +1,19 @@ /* size_max.h -- declare SIZE_MAX through system headers - Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2006, 2009-2022 Free Software Foundation, Inc. Written by Simon Josefsson. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef GNULIB_SIZE_MAX_H #define GNULIB_SIZE_MAX_H diff --git a/gl/snprintf.c b/gl/snprintf.c index 9c4ab3f2..3d87854e 100644 --- a/gl/snprintf.c +++ b/gl/snprintf.c @@ -1,19 +1,19 @@ /* Formatted output to strings. - Copyright (C) 2004, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 2004, 2006-2022 Free Software Foundation, Inc. Written by Simon Josefsson and Paul Eggert. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/sockets.c b/gl/sockets.c index ae961482..31b43029 100644 --- a/gl/sockets.c +++ b/gl/sockets.c @@ -1,19 +1,19 @@ /* sockets.c --- wrappers for Windows socket functions - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Simon Josefsson */ @@ -28,7 +28,11 @@ # include # include "fd-hook.h" -# include "msvc-nothrow.h" +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif /* Get set_winsock_errno, FD_TO_SOCKET etc. */ # include "w32sock.h" @@ -109,7 +113,7 @@ static int initialized_sockets_version /* = 0 */; #endif /* WINDOWS_SOCKETS */ int -gl_sockets_startup (int version _GL_UNUSED) +gl_sockets_startup (_GL_UNUSED int version) { #if WINDOWS_SOCKETS if (version > initialized_sockets_version) @@ -121,8 +125,11 @@ gl_sockets_startup (int version _GL_UNUSED) if (err != 0) return 1; - if (data.wVersion < version) - return 2; + if (data.wVersion != version) + { + WSACleanup (); + return 2; + } if (initialized_sockets_version == 0) register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket, diff --git a/gl/sockets.h b/gl/sockets.h index 1570ad84..75e49fce 100644 --- a/gl/sockets.h +++ b/gl/sockets.h @@ -1,39 +1,39 @@ /* sockets.h - wrappers for Windows socket functions - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Simon Josefsson */ #ifndef SOCKETS_H -# define SOCKETS_H 1 +#define SOCKETS_H 1 -#define SOCKETS_1_0 0x100 /* don't use - does not work on Windows XP */ -#define SOCKETS_1_1 0x101 -#define SOCKETS_2_0 0x200 /* don't use - does not work on Windows XP */ -#define SOCKETS_2_1 0x201 -#define SOCKETS_2_2 0x202 +#define SOCKETS_1_0 0x0001 +#define SOCKETS_1_1 0x0101 +#define SOCKETS_2_0 0x0002 +#define SOCKETS_2_1 0x0102 +#define SOCKETS_2_2 0x0202 int gl_sockets_startup (int version) -#if !WINDOWS_SOCKETS +#ifndef WINDOWS_SOCKETS _GL_ATTRIBUTE_CONST #endif ; int gl_sockets_cleanup (void) -#if !WINDOWS_SOCKETS +#ifndef WINDOWS_SOCKETS _GL_ATTRIBUTE_CONST #endif ; @@ -41,11 +41,15 @@ int gl_sockets_cleanup (void) /* This function is useful it you create a socket using gnulib's Winsock wrappers but needs to pass on the socket handle to some other library that only accepts sockets. */ -#if WINDOWS_SOCKETS +#ifdef WINDOWS_SOCKETS -#include +# include -#include "msvc-nothrow.h" +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif static inline SOCKET gl_fd_to_handle (int fd) @@ -55,7 +59,7 @@ gl_fd_to_handle (int fd) #else -#define gl_fd_to_handle(x) (x) +# define gl_fd_to_handle(x) (x) #endif /* WINDOWS_SOCKETS */ diff --git a/gl/stat-time.c b/gl/stat-time.c new file mode 100644 index 00000000..3d48a2b5 --- /dev/null +++ b/gl/stat-time.c @@ -0,0 +1,21 @@ +/* stat-related time functions. + + Copyright (C) 2012-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +#define _GL_STAT_TIME_INLINE _GL_EXTERN_INLINE +#include "stat-time.h" diff --git a/gl/stat-time.h b/gl/stat-time.h new file mode 100644 index 00000000..6b0088e3 --- /dev/null +++ b/gl/stat-time.h @@ -0,0 +1,252 @@ +/* stat-related time functions. + + Copyright (C) 2005, 2007, 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert. */ + +#ifndef STAT_TIME_H +#define STAT_TIME_H 1 + +#include "intprops.h" + +#include +#include +#include +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef _GL_STAT_TIME_INLINE +# define _GL_STAT_TIME_INLINE _GL_INLINE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type + struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST, + ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST, + if available. ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim + for access, status change, data modification, or birth (creation) + time respectively. + + These macros are private to stat-time.h. */ +#if _GL_WINDOWS_STAT_TIMESPEC || defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC +# if _GL_WINDOWS_STAT_TIMESPEC || defined TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC +# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim) +# else +# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec) +# endif +#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC +# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec) +#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC +# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec) +#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC +# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec) +#endif + +/* Return the nanosecond component of *ST's access time. */ +_GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE +get_stat_atime_ns (struct stat const *st) +{ +# if defined STAT_TIMESPEC + return STAT_TIMESPEC (st, st_atim).tv_nsec; +# elif defined STAT_TIMESPEC_NS + return STAT_TIMESPEC_NS (st, st_atim); +# else + return 0; +# endif +} + +/* Return the nanosecond component of *ST's status change time. */ +_GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE +get_stat_ctime_ns (struct stat const *st) +{ +# if defined STAT_TIMESPEC + return STAT_TIMESPEC (st, st_ctim).tv_nsec; +# elif defined STAT_TIMESPEC_NS + return STAT_TIMESPEC_NS (st, st_ctim); +# else + return 0; +# endif +} + +/* Return the nanosecond component of *ST's data modification time. */ +_GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE +get_stat_mtime_ns (struct stat const *st) +{ +# if defined STAT_TIMESPEC + return STAT_TIMESPEC (st, st_mtim).tv_nsec; +# elif defined STAT_TIMESPEC_NS + return STAT_TIMESPEC_NS (st, st_mtim); +# else + return 0; +# endif +} + +/* Return the nanosecond component of *ST's birth time. */ +_GL_STAT_TIME_INLINE long int _GL_ATTRIBUTE_PURE +get_stat_birthtime_ns (_GL_UNUSED struct stat const *st) +{ +# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC + return STAT_TIMESPEC (st, st_birthtim).tv_nsec; +# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC + return STAT_TIMESPEC_NS (st, st_birthtim); +# else + return 0; +# endif +} + +/* Return *ST's access time. */ +_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE +get_stat_atime (struct stat const *st) +{ +#ifdef STAT_TIMESPEC + return STAT_TIMESPEC (st, st_atim); +#else + struct timespec t; + t.tv_sec = st->st_atime; + t.tv_nsec = get_stat_atime_ns (st); + return t; +#endif +} + +/* Return *ST's status change time. */ +_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE +get_stat_ctime (struct stat const *st) +{ +#ifdef STAT_TIMESPEC + return STAT_TIMESPEC (st, st_ctim); +#else + struct timespec t; + t.tv_sec = st->st_ctime; + t.tv_nsec = get_stat_ctime_ns (st); + return t; +#endif +} + +/* Return *ST's data modification time. */ +_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE +get_stat_mtime (struct stat const *st) +{ +#ifdef STAT_TIMESPEC + return STAT_TIMESPEC (st, st_mtim); +#else + struct timespec t; + t.tv_sec = st->st_mtime; + t.tv_nsec = get_stat_mtime_ns (st); + return t; +#endif +} + +/* Return *ST's birth time, if available; otherwise return a value + with tv_sec and tv_nsec both equal to -1. */ +_GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE +get_stat_birthtime (_GL_UNUSED struct stat const *st) +{ + struct timespec t; + +#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ + || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) + t = STAT_TIMESPEC (st, st_birthtim); +#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC + t.tv_sec = st->st_birthtime; + t.tv_nsec = st->st_birthtimensec; +#elif defined _WIN32 && ! defined __CYGWIN__ + /* Native Windows platforms (but not Cygwin) put the "file creation + time" in st_ctime (!). See + . */ +# if _GL_WINDOWS_STAT_TIMESPEC + t = st->st_ctim; +# else + t.tv_sec = st->st_ctime; + t.tv_nsec = 0; +# endif +#else + /* Birth time is not supported. */ + t.tv_sec = -1; + t.tv_nsec = -1; +#endif + +#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ + || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \ + || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) + /* FreeBSD and NetBSD sometimes signal the absence of knowledge by + using zero. Attempt to work around this problem. Alas, this can + report failure even for valid timestamps. Also, NetBSD + sometimes returns junk in the birth time fields; work around this + bug if it is detected. */ + if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) + { + t.tv_sec = -1; + t.tv_nsec = -1; + } +#endif + + return t; +} + +/* If a stat-like function returned RESULT, normalize the timestamps + in *ST, in case this platform suffers from the Solaris 11 bug where + tv_nsec might be negative. Return the adjusted RESULT, setting + errno to EOVERFLOW if normalization overflowed. This function + is intended to be private to this .h file. */ +_GL_STAT_TIME_INLINE int +stat_time_normalize (int result, _GL_UNUSED struct stat *st) +{ +#if defined __sun && defined STAT_TIMESPEC + if (result == 0) + { + long int timespec_hz = 1000000000; + short int const ts_off[] = { offsetof (struct stat, st_atim), + offsetof (struct stat, st_mtim), + offsetof (struct stat, st_ctim) }; + int i; + for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++) + { + struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]); + long int q = ts->tv_nsec / timespec_hz; + long int r = ts->tv_nsec % timespec_hz; + if (r < 0) + { + r += timespec_hz; + q--; + } + ts->tv_nsec = r; + /* Overflow is possible, as Solaris 11 stat can yield + tv_sec == TYPE_MINIMUM (time_t) && tv_nsec == -1000000000. + INT_ADD_WRAPV is OK, since time_t is signed on Solaris. */ + if (INT_ADD_WRAPV (q, ts->tv_sec, &ts->tv_sec)) + { + errno = EOVERFLOW; + return -1; + } + } + } +#endif + return result; +} + +#ifdef __cplusplus +} +#endif + +_GL_INLINE_HEADER_END + +#endif diff --git a/gl/stat-w32.c b/gl/stat-w32.c new file mode 100644 index 00000000..c1a29239 --- /dev/null +++ b/gl/stat-w32.c @@ -0,0 +1,461 @@ +/* Core of implementation of fstat and stat for native Windows. + Copyright (C) 2017-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible. */ + +#include + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* Attempt to make define FILE_ID_INFO. + But ensure that the redefinition of _WIN32_WINNT does not make us assume + Windows Vista or newer when building for an older version of Windows. */ +#if HAVE_SDKDDKVER_H +# include +# if _WIN32_WINNT >= _WIN32_WINNT_VISTA +# define WIN32_ASSUME_VISTA 1 +# else +# define WIN32_ASSUME_VISTA 0 +# endif +# if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN8) +# undef _WIN32_WINNT +# define _WIN32_WINNT _WIN32_WINNT_WIN8 +# endif +#else +# define WIN32_ASSUME_VISTA (_WIN32_WINNT >= _WIN32_WINNT_VISTA) +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* Specification. */ +#include "stat-w32.h" + +#include "pathmax.h" +#include "verify.h" + +/* Don't assume that UNICODE is not defined. */ +#undef LoadLibrary +#define LoadLibrary LoadLibraryA +#undef GetFinalPathNameByHandle +#define GetFinalPathNameByHandle GetFinalPathNameByHandleA + +/* Older mingw headers do not define VOLUME_NAME_NONE. */ +#ifndef VOLUME_NAME_NONE +# define VOLUME_NAME_NONE 4 +#endif + +#if !WIN32_ASSUME_VISTA + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress + +# if _GL_WINDOWS_STAT_INODES == 2 +/* GetFileInformationByHandleEx was introduced only in Windows Vista. */ +typedef DWORD (WINAPI * GetFileInformationByHandleExFuncType) (HANDLE hFile, + FILE_INFO_BY_HANDLE_CLASS fiClass, + LPVOID lpBuffer, + DWORD dwBufferSize); +static GetFileInformationByHandleExFuncType GetFileInformationByHandleExFunc = NULL; +# endif +/* GetFinalPathNameByHandle was introduced only in Windows Vista. */ +typedef DWORD (WINAPI * GetFinalPathNameByHandleFuncType) (HANDLE hFile, + LPSTR lpFilePath, + DWORD lenFilePath, + DWORD dwFlags); +static GetFinalPathNameByHandleFuncType GetFinalPathNameByHandleFunc = NULL; +static BOOL initialized = FALSE; + +static void +initialize (void) +{ + HMODULE kernel32 = LoadLibrary ("kernel32.dll"); + if (kernel32 != NULL) + { +# if _GL_WINDOWS_STAT_INODES == 2 + GetFileInformationByHandleExFunc = + (GetFileInformationByHandleExFuncType) GetProcAddress (kernel32, "GetFileInformationByHandleEx"); +# endif + GetFinalPathNameByHandleFunc = + (GetFinalPathNameByHandleFuncType) GetProcAddress (kernel32, "GetFinalPathNameByHandleA"); + } + initialized = TRUE; +} + +#else + +# define GetFileInformationByHandleExFunc GetFileInformationByHandleEx +# define GetFinalPathNameByHandleFunc GetFinalPathNameByHandle + +#endif + +/* Converts a FILETIME to GMT time since 1970-01-01 00:00:00. */ +#if _GL_WINDOWS_STAT_TIMESPEC +struct timespec +_gl_convert_FILETIME_to_timespec (const FILETIME *ft) +{ + struct timespec result; + /* FILETIME: */ + unsigned long long since_1601 = + ((unsigned long long) ft->dwHighDateTime << 32) + | (unsigned long long) ft->dwLowDateTime; + if (since_1601 == 0) + { + result.tv_sec = 0; + result.tv_nsec = 0; + } + else + { + /* Between 1601-01-01 and 1970-01-01 there were 280 normal years and 89 + leap years, in total 134774 days. */ + unsigned long long since_1970 = + since_1601 - (unsigned long long) 134774 * (unsigned long long) 86400 * (unsigned long long) 10000000; + result.tv_sec = since_1970 / (unsigned long long) 10000000; + result.tv_nsec = (unsigned long) (since_1970 % (unsigned long long) 10000000) * 100; + } + return result; +} +#else +time_t +_gl_convert_FILETIME_to_POSIX (const FILETIME *ft) +{ + /* FILETIME: */ + unsigned long long since_1601 = + ((unsigned long long) ft->dwHighDateTime << 32) + | (unsigned long long) ft->dwLowDateTime; + if (since_1601 == 0) + return 0; + else + { + /* Between 1601-01-01 and 1970-01-01 there were 280 normal years and 89 + leap years, in total 134774 days. */ + unsigned long long since_1970 = + since_1601 - (unsigned long long) 134774 * (unsigned long long) 86400 * (unsigned long long) 10000000; + return since_1970 / (unsigned long long) 10000000; + } +} +#endif + +/* Fill *BUF with information about the file designated by H. + PATH is the file name, if known, otherwise NULL. + Return 0 if successful, or -1 with errno set upon failure. */ +int +_gl_fstat_by_handle (HANDLE h, const char *path, struct stat *buf) +{ + /* GetFileType + */ + DWORD type = GetFileType (h); + if (type == FILE_TYPE_DISK) + { +#if !WIN32_ASSUME_VISTA + if (!initialized) + initialize (); +#endif + + /* st_mode can be determined through + GetFileAttributesEx + + + or through + GetFileInformationByHandle + + + or through + GetFileInformationByHandleEx with argument FileBasicInfo + + + The latter requires -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher. */ + BY_HANDLE_FILE_INFORMATION info; + if (! GetFileInformationByHandle (h, &info)) + goto failed; + + /* Test for error conditions before starting to fill *buf. */ + if (sizeof (buf->st_size) <= 4 && info.nFileSizeHigh > 0) + { + errno = EOVERFLOW; + return -1; + } + +#if _GL_WINDOWS_STAT_INODES + /* st_ino can be determined through + GetFileInformationByHandle + + + as 64 bits, or through + GetFileInformationByHandleEx with argument FileIdInfo + + + as 128 bits. + The latter requires -D_WIN32_WINNT=_WIN32_WINNT_WIN8 or higher. */ + /* Experiments show that GetFileInformationByHandleEx does not provide + much more information than GetFileInformationByHandle: + * The dwVolumeSerialNumber from GetFileInformationByHandle is equal + to the low 32 bits of the 64-bit VolumeSerialNumber from + GetFileInformationByHandleEx, and is apparently sufficient for + identifying the device. + * The nFileIndex from GetFileInformationByHandle is equal to the low + 64 bits of the 128-bit FileId from GetFileInformationByHandleEx, + and the high 64 bits of this 128-bit FileId are zero. + * On a FAT file system, GetFileInformationByHandleEx fails with error + ERROR_INVALID_PARAMETER, whereas GetFileInformationByHandle + succeeds. + * On a CIFS/SMB file system, GetFileInformationByHandleEx fails with + error ERROR_INVALID_LEVEL, whereas GetFileInformationByHandle + succeeds. */ +# if _GL_WINDOWS_STAT_INODES == 2 + if (GetFileInformationByHandleExFunc != NULL) + { + FILE_ID_INFO id; + if (GetFileInformationByHandleExFunc (h, FileIdInfo, &id, sizeof (id))) + { + buf->st_dev = id.VolumeSerialNumber; + verify (sizeof (ino_t) == sizeof (id.FileId)); + memcpy (&buf->st_ino, &id.FileId, sizeof (ino_t)); + goto ino_done; + } + else + { + switch (GetLastError ()) + { + case ERROR_INVALID_PARAMETER: /* older Windows version, or FAT */ + case ERROR_INVALID_LEVEL: /* CIFS/SMB file system */ + goto fallback; + default: + goto failed; + } + } + } + fallback: ; + /* Fallback for older Windows versions. */ + buf->st_dev = info.dwVolumeSerialNumber; + buf->st_ino._gl_ino[0] = ((ULONGLONG) info.nFileIndexHigh << 32) | (ULONGLONG) info.nFileIndexLow; + buf->st_ino._gl_ino[1] = 0; + ino_done: ; +# else /* _GL_WINDOWS_STAT_INODES == 1 */ + buf->st_dev = info.dwVolumeSerialNumber; + buf->st_ino = ((ULONGLONG) info.nFileIndexHigh << 32) | (ULONGLONG) info.nFileIndexLow; +# endif +#else + /* st_ino is not wide enough for identifying a file on a device. + Without st_ino, st_dev is pointless. */ + buf->st_dev = 0; + buf->st_ino = 0; +#endif + + /* st_mode. */ + unsigned int mode = + /* XXX How to handle FILE_ATTRIBUTE_REPARSE_POINT ? */ + ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR | S_IEXEC_UGO : _S_IFREG) + | S_IREAD_UGO + | ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE_UGO); + if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + /* Determine whether the file is executable by looking at the file + name suffix. + If the file name is already known, use it. Otherwise, for + non-empty files, it can be determined through + GetFinalPathNameByHandle + + or through + GetFileInformationByHandleEx with argument FileNameInfo + + + Both require -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher. */ + if (info.nFileSizeHigh > 0 || info.nFileSizeLow > 0) + { + char fpath[PATH_MAX]; + if (path != NULL + || (GetFinalPathNameByHandleFunc != NULL + && GetFinalPathNameByHandleFunc (h, fpath, sizeof (fpath), VOLUME_NAME_NONE) + < sizeof (fpath) + && (path = fpath, 1))) + { + const char *last_dot = NULL; + const char *p; + for (p = path; *p != '\0'; p++) + if (*p == '.') + last_dot = p; + if (last_dot != NULL) + { + const char *suffix = last_dot + 1; + if (_stricmp (suffix, "exe") == 0 + || _stricmp (suffix, "bat") == 0 + || _stricmp (suffix, "cmd") == 0 + || _stricmp (suffix, "com") == 0) + mode |= S_IEXEC_UGO; + } + } + else + /* Cannot determine file name. Pretend that it is executable. */ + mode |= S_IEXEC_UGO; + } + } + buf->st_mode = mode; + + /* st_nlink can be determined through + GetFileInformationByHandle + + + or through + GetFileInformationByHandleEx with argument FileStandardInfo + + + The latter requires -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher. */ + buf->st_nlink = (info.nNumberOfLinks > SHRT_MAX ? SHRT_MAX : info.nNumberOfLinks); + + /* There's no easy way to map the Windows SID concept to an integer. */ + buf->st_uid = 0; + buf->st_gid = 0; + + /* st_rdev is irrelevant for normal files and directories. */ + buf->st_rdev = 0; + + /* st_size can be determined through + GetFileSizeEx + + or through + GetFileAttributesEx + + + or through + GetFileInformationByHandle + + + or through + GetFileInformationByHandleEx with argument FileStandardInfo + + + The latter requires -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher. */ + if (sizeof (buf->st_size) <= 4) + /* Range check already done above. */ + buf->st_size = info.nFileSizeLow; + else + buf->st_size = ((long long) info.nFileSizeHigh << 32) | (long long) info.nFileSizeLow; + + /* st_atime, st_mtime, st_ctime can be determined through + GetFileTime + + or through + GetFileAttributesEx + + + or through + GetFileInformationByHandle + + + or through + GetFileInformationByHandleEx with argument FileBasicInfo + + + The latter requires -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher. */ +#if _GL_WINDOWS_STAT_TIMESPEC + buf->st_atim = _gl_convert_FILETIME_to_timespec (&info.ftLastAccessTime); + buf->st_mtim = _gl_convert_FILETIME_to_timespec (&info.ftLastWriteTime); + buf->st_ctim = _gl_convert_FILETIME_to_timespec (&info.ftCreationTime); +#else + buf->st_atime = _gl_convert_FILETIME_to_POSIX (&info.ftLastAccessTime); + buf->st_mtime = _gl_convert_FILETIME_to_POSIX (&info.ftLastWriteTime); + buf->st_ctime = _gl_convert_FILETIME_to_POSIX (&info.ftCreationTime); +#endif + + return 0; + } + else if (type == FILE_TYPE_CHAR || type == FILE_TYPE_PIPE) + { + buf->st_dev = 0; +#if _GL_WINDOWS_STAT_INODES == 2 + buf->st_ino._gl_ino[0] = buf->st_ino._gl_ino[1] = 0; +#else + buf->st_ino = 0; +#endif + buf->st_mode = (type == FILE_TYPE_PIPE ? _S_IFIFO : _S_IFCHR); + buf->st_nlink = 1; + buf->st_uid = 0; + buf->st_gid = 0; + buf->st_rdev = 0; + if (type == FILE_TYPE_PIPE) + { + /* PeekNamedPipe + */ + DWORD bytes_available; + if (PeekNamedPipe (h, NULL, 0, NULL, &bytes_available, NULL)) + buf->st_size = bytes_available; + else + buf->st_size = 0; + } + else + buf->st_size = 0; +#if _GL_WINDOWS_STAT_TIMESPEC + buf->st_atim.tv_sec = 0; buf->st_atim.tv_nsec = 0; + buf->st_mtim.tv_sec = 0; buf->st_mtim.tv_nsec = 0; + buf->st_ctim.tv_sec = 0; buf->st_ctim.tv_nsec = 0; +#else + buf->st_atime = 0; + buf->st_mtime = 0; + buf->st_ctime = 0; +#endif + return 0; + } + else + { + errno = ENOENT; + return -1; + } + + failed: + { + DWORD error = GetLastError (); + #if 0 + fprintf (stderr, "_gl_fstat_by_handle error 0x%x\n", (unsigned int) error); + #endif + switch (error) + { + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + errno = EACCES; + break; + + case ERROR_OUTOFMEMORY: + errno = ENOMEM; + break; + + case ERROR_WRITE_FAULT: + case ERROR_READ_FAULT: + case ERROR_GEN_FAILURE: + errno = EIO; + break; + + default: + errno = EINVAL; + break; + } + return -1; + } +} + +#else + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; + +#endif diff --git a/gl/stat-w32.h b/gl/stat-w32.h new file mode 100644 index 00000000..0f79d614 --- /dev/null +++ b/gl/stat-w32.h @@ -0,0 +1,37 @@ +/* Core of implementation of fstat and stat for native Windows. + Copyright (C) 2017-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _STAT_W32_H +#define _STAT_W32_H 1 + +/* Converts a FILETIME to GMT time since 1970-01-01 00:00:00. */ +#if _GL_WINDOWS_STAT_TIMESPEC +extern struct timespec _gl_convert_FILETIME_to_timespec (const FILETIME *ft); +#else +extern time_t _gl_convert_FILETIME_to_POSIX (const FILETIME *ft); +#endif + +/* Fill *BUF with information about the file designated by H. + PATH is the file name, if known, otherwise NULL. + Return 0 if successful, or -1 with errno set upon failure. */ +extern int _gl_fstat_by_handle (HANDLE h, const char *path, struct stat *buf); + +/* Bitmasks for st_mode. */ +#define S_IREAD_UGO (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)) +#define S_IWRITE_UGO (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6)) +#define S_IEXEC_UGO (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6)) + +#endif /* _STAT_W32_H */ diff --git a/gl/stat.c b/gl/stat.c new file mode 100644 index 00000000..574489ac --- /dev/null +++ b/gl/stat.c @@ -0,0 +1,440 @@ +/* Work around platform bugs in stat. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Eric Blake and Bruno Haible. */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_stat doesn't recurse to + rpl_stat. */ +#define __need_system_sys_stat_h +#include + +/* Get the original definition of stat. It might be defined as a macro. */ +#include +#include +#undef __need_system_sys_stat_h + +#if defined _WIN32 && ! defined __CYGWIN__ +# define WINDOWS_NATIVE +#endif + +#if !defined WINDOWS_NATIVE + +static int +orig_stat (const char *filename, struct stat *buf) +{ + return stat (filename, buf); +} + +#endif + +/* Specification. */ +#ifdef __osf__ +/* Write "sys/stat.h" here, not , otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include + above. */ +# include "sys/stat.h" +#else +# include +#endif + +#include "stat-time.h" + +#include +#include +#include +#include +#include "filename.h" +#include "malloca.h" +#include "verify.h" + +#ifdef WINDOWS_NATIVE +# define WIN32_LEAN_AND_MEAN +# include +# include "stat-w32.h" +/* Don't assume that UNICODE is not defined. */ +# undef WIN32_FIND_DATA +# define WIN32_FIND_DATA WIN32_FIND_DATAA +# undef CreateFile +# define CreateFile CreateFileA +# undef FindFirstFile +# define FindFirstFile FindFirstFileA +#endif + +#ifdef WINDOWS_NATIVE +/* Return TRUE if the given file name denotes an UNC root. */ +static BOOL +is_unc_root (const char *rname) +{ + /* Test whether it has the syntax '\\server\share'. */ + if (ISSLASH (rname[0]) && ISSLASH (rname[1])) + { + /* It starts with two slashes. Find the next slash. */ + const char *p = rname + 2; + const char *q = p; + while (*q != '\0' && !ISSLASH (*q)) + q++; + if (q > p && *q != '\0') + { + /* Found the next slash at q. */ + q++; + const char *r = q; + while (*r != '\0' && !ISSLASH (*r)) + r++; + if (r > q && *r == '\0') + return TRUE; + } + } + return FALSE; +} +#endif + +/* Store information about NAME into ST. Work around bugs with + trailing slashes. Mingw has other bugs (such as st_ino always + being 0 on success) which this wrapper does not work around. But + at least this implementation provides the ability to emulate fchdir + correctly. */ + +int +rpl_stat (char const *name, struct stat *buf) +{ +#ifdef WINDOWS_NATIVE + /* Fill the fields ourselves, because the original stat function returns + values for st_atime, st_mtime, st_ctime that depend on the current time + zone. See + */ + /* XXX Should we convert to wchar_t* and prepend '\\?\', in order to work + around length limitations + ? */ + + /* POSIX + specifies: "More than two leading characters shall be treated as + a single character." */ + if (ISSLASH (name[0]) && ISSLASH (name[1]) && ISSLASH (name[2])) + { + name += 2; + while (ISSLASH (name[1])) + name++; + } + + size_t len = strlen (name); + size_t drive_prefix_len = (HAS_DEVICE (name) ? 2 : 0); + + /* Remove trailing slashes (except the very first one, at position + drive_prefix_len), but remember their presence. */ + size_t rlen; + bool check_dir = false; + + rlen = len; + while (rlen > drive_prefix_len && ISSLASH (name[rlen-1])) + { + check_dir = true; + if (rlen == drive_prefix_len + 1) + break; + rlen--; + } + + /* Handle '' and 'C:'. */ + if (!check_dir && rlen == drive_prefix_len) + { + errno = ENOENT; + return -1; + } + + /* Handle '\\'. */ + if (rlen == 1 && ISSLASH (name[0]) && len >= 2) + { + errno = ENOENT; + return -1; + } + + const char *rname; + char *malloca_rname; + if (rlen == len) + { + rname = name; + malloca_rname = NULL; + } + else + { + malloca_rname = malloca (rlen + 1); + if (malloca_rname == NULL) + { + errno = ENOMEM; + return -1; + } + memcpy (malloca_rname, name, rlen); + malloca_rname[rlen] = '\0'; + rname = malloca_rname; + } + + /* There are two ways to get at the requested information: + - by scanning the parent directory and examining the relevant + directory entry, + - by opening the file directly. + The first approach fails for root directories (e.g. 'C:\') and + UNC root directories (e.g. '\\server\share'). + The second approach fails for some system files (e.g. 'C:\pagefile.sys' + and 'C:\hiberfil.sys'): ERROR_SHARING_VIOLATION. + The second approach gives more information (in particular, correct + st_dev, st_ino, st_nlink fields). + So we use the second approach and, as a fallback except for root and + UNC root directories, also the first approach. */ + { + int ret; + + { + /* Approach based on the file. */ + + /* Open a handle to the file. + CreateFile + + */ + HANDLE h = + CreateFile (rname, + FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only + in case as different) makes sense only when applied to *all* + filesystem operations. */ + FILE_FLAG_BACKUP_SEMANTICS /* | FILE_FLAG_POSIX_SEMANTICS */, + NULL); + if (h != INVALID_HANDLE_VALUE) + { + ret = _gl_fstat_by_handle (h, rname, buf); + CloseHandle (h); + goto done; + } + } + + /* Test for root and UNC root directories. */ + if ((rlen == drive_prefix_len + 1 && ISSLASH (rname[drive_prefix_len])) + || is_unc_root (rname)) + goto failed; + + /* Fallback. */ + { + /* Approach based on the directory entry. */ + + if (strchr (rname, '?') != NULL || strchr (rname, '*') != NULL) + { + /* Other Windows API functions would fail with error + ERROR_INVALID_NAME. */ + if (malloca_rname != NULL) + freea (malloca_rname); + errno = ENOENT; + return -1; + } + + /* Get the details about the directory entry. This can be done through + FindFirstFile + + + or through + FindFirstFileEx with argument FindExInfoBasic + + + */ + WIN32_FIND_DATA info; + HANDLE h = FindFirstFile (rname, &info); + if (h == INVALID_HANDLE_VALUE) + goto failed; + + /* Test for error conditions before starting to fill *buf. */ + if (sizeof (buf->st_size) <= 4 && info.nFileSizeHigh > 0) + { + FindClose (h); + if (malloca_rname != NULL) + freea (malloca_rname); + errno = EOVERFLOW; + return -1; + } + +# if _GL_WINDOWS_STAT_INODES + buf->st_dev = 0; +# if _GL_WINDOWS_STAT_INODES == 2 + buf->st_ino._gl_ino[0] = buf->st_ino._gl_ino[1] = 0; +# else /* _GL_WINDOWS_STAT_INODES == 1 */ + buf->st_ino = 0; +# endif +# else + /* st_ino is not wide enough for identifying a file on a device. + Without st_ino, st_dev is pointless. */ + buf->st_dev = 0; + buf->st_ino = 0; +# endif + + /* st_mode. */ + unsigned int mode = + /* XXX How to handle FILE_ATTRIBUTE_REPARSE_POINT ? */ + ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR | S_IEXEC_UGO : _S_IFREG) + | S_IREAD_UGO + | ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE_UGO); + if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + /* Determine whether the file is executable by looking at the file + name suffix. */ + if (info.nFileSizeHigh > 0 || info.nFileSizeLow > 0) + { + const char *last_dot = NULL; + const char *p; + for (p = info.cFileName; *p != '\0'; p++) + if (*p == '.') + last_dot = p; + if (last_dot != NULL) + { + const char *suffix = last_dot + 1; + if (_stricmp (suffix, "exe") == 0 + || _stricmp (suffix, "bat") == 0 + || _stricmp (suffix, "cmd") == 0 + || _stricmp (suffix, "com") == 0) + mode |= S_IEXEC_UGO; + } + } + } + buf->st_mode = mode; + + /* st_nlink. Ignore hard links here. */ + buf->st_nlink = 1; + + /* There's no easy way to map the Windows SID concept to an integer. */ + buf->st_uid = 0; + buf->st_gid = 0; + + /* st_rdev is irrelevant for normal files and directories. */ + buf->st_rdev = 0; + + /* st_size. */ + if (sizeof (buf->st_size) <= 4) + /* Range check already done above. */ + buf->st_size = info.nFileSizeLow; + else + buf->st_size = ((long long) info.nFileSizeHigh << 32) | (long long) info.nFileSizeLow; + + /* st_atime, st_mtime, st_ctime. */ +# if _GL_WINDOWS_STAT_TIMESPEC + buf->st_atim = _gl_convert_FILETIME_to_timespec (&info.ftLastAccessTime); + buf->st_mtim = _gl_convert_FILETIME_to_timespec (&info.ftLastWriteTime); + buf->st_ctim = _gl_convert_FILETIME_to_timespec (&info.ftCreationTime); +# else + buf->st_atime = _gl_convert_FILETIME_to_POSIX (&info.ftLastAccessTime); + buf->st_mtime = _gl_convert_FILETIME_to_POSIX (&info.ftLastWriteTime); + buf->st_ctime = _gl_convert_FILETIME_to_POSIX (&info.ftCreationTime); +# endif + + FindClose (h); + + ret = 0; + } + + done: + if (ret >= 0 && check_dir && !S_ISDIR (buf->st_mode)) + { + errno = ENOTDIR; + ret = -1; + } + if (malloca_rname != NULL) + { + int saved_errno = errno; + freea (malloca_rname); + errno = saved_errno; + } + return ret; + } + + failed: + { + DWORD error = GetLastError (); + #if 0 + fprintf (stderr, "rpl_stat error 0x%x\n", (unsigned int) error); + #endif + + if (malloca_rname != NULL) + freea (malloca_rname); + + switch (error) + { + /* Some of these errors probably cannot happen with the specific flags + that we pass to CreateFile. But who knows... */ + case ERROR_FILE_NOT_FOUND: /* The last component of rname does not exist. */ + case ERROR_PATH_NOT_FOUND: /* Some directory component in rname does not exist. */ + case ERROR_BAD_PATHNAME: /* rname is such as '\\server'. */ + case ERROR_BAD_NET_NAME: /* rname is such as '\\server\nonexistentshare'. */ + case ERROR_INVALID_NAME: /* rname contains wildcards, misplaced colon, etc. */ + case ERROR_DIRECTORY: + errno = ENOENT; + break; + + case ERROR_ACCESS_DENIED: /* rname is such as 'C:\System Volume Information\foo'. */ + case ERROR_SHARING_VIOLATION: /* rname is such as 'C:\pagefile.sys' (second approach only). */ + /* XXX map to EACCES or EPERM? */ + errno = EACCES; + break; + + case ERROR_OUTOFMEMORY: + errno = ENOMEM; + break; + + case ERROR_WRITE_PROTECT: + errno = EROFS; + break; + + case ERROR_WRITE_FAULT: + case ERROR_READ_FAULT: + case ERROR_GEN_FAILURE: + errno = EIO; + break; + + case ERROR_BUFFER_OVERFLOW: + case ERROR_FILENAME_EXCED_RANGE: + errno = ENAMETOOLONG; + break; + + case ERROR_DELETE_PENDING: /* XXX map to EACCES or EPERM? */ + errno = EPERM; + break; + + default: + errno = EINVAL; + break; + } + + return -1; + } +#else + int result = orig_stat (name, buf); + if (result == 0) + { +# if REPLACE_FUNC_STAT_FILE + /* Solaris 9 mistakenly succeeds when given a non-directory with a + trailing slash. */ + if (!S_ISDIR (buf->st_mode)) + { + size_t len = strlen (name); + if (ISSLASH (name[len - 1])) + { + errno = ENOTDIR; + return -1; + } + } +# endif /* REPLACE_FUNC_STAT_FILE */ + result = stat_time_normalize (result, buf); + } + return result; +#endif +} diff --git a/gl/stdalign.in.h b/gl/stdalign.in.h index 7254a3de..3b117df1 100644 --- a/gl/stdalign.in.h +++ b/gl/stdalign.in.h @@ -1,19 +1,19 @@ /* A substitute for ISO C11 . - Copyright 2011-2013 Free Software Foundation, Inc. + Copyright 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Paul Eggert and Bruno Haible. */ @@ -34,11 +34,12 @@ requirement of a structure member (i.e., slot or field) that is of type TYPE, as an integer constant expression. - This differs from GCC's __alignof__ operator, which can yield a - better-performing alignment for an object of that type. For - example, on x86 with GCC, __alignof__ (double) and __alignof__ - (long long) are 8, whereas alignof (double) and alignof (long long) - are 4 unless the option '-malign-double' is used. + This differs from GCC's and clang's __alignof__ operator, which can + yield a better-performing alignment for an object of that type. For + example, on x86 with GCC and on Linux/x86 with clang, + __alignof__ (double) and __alignof__ (long long) are 8, whereas + alignof (double) and alignof (long long) are 4 unless the option + '-malign-double' is used. The result cannot be used as a value for an 'enum' constant, if you want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. @@ -52,7 +53,13 @@ #undef _Alignas #undef _Alignof -#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 +/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 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__ && __clang_major__ < 8)) # ifdef __cplusplus # if 201103 <= __cplusplus # define _Alignof(type) alignof (type) @@ -64,7 +71,9 @@ # define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) # endif #endif -#define alignof _Alignof +#if ! (defined __cplusplus && 201103 <= __cplusplus) +# define alignof _Alignof +#endif #define __alignof_is_defined 1 /* alignas (A), also known as _Alignas (A), aligns a variable or type @@ -95,14 +104,23 @@ #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 # if defined __cplusplus && 201103 <= __cplusplus # define _Alignas(a) alignas (a) -# elif __GNUC__ || __IBMC__ || __IBMCPP__ || __ICC || 0x5110 <= __SUNPRO_C +# elif (!defined __attribute__ \ + && ((defined __APPLE__ && defined __MACH__ \ + ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \ + : __GNUC__ && !defined __ibmxl__) \ + || (4 <= __clang_major__) \ + || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \ + || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__)) # define _Alignas(a) __attribute__ ((__aligned__ (a))) # elif 1300 <= _MSC_VER # define _Alignas(a) __declspec (align (a)) # endif #endif -#if defined _Alignas || (defined __STDC_VERSION && 201112 <= __STDC_VERSION__) +#if ((defined _Alignas && ! (defined __cplusplus && 201103 <= __cplusplus)) \ + || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) # define alignas _Alignas +#endif +#if defined alignas || (defined __cplusplus && 201103 <= __cplusplus) # define __alignas_is_defined 1 #endif diff --git a/gl/stdbool.in.h b/gl/stdbool.in.h index 7c157727..2fa46724 100644 --- a/gl/stdbool.in.h +++ b/gl/stdbool.in.h @@ -1,18 +1,18 @@ -/* Copyright (C) 2001-2003, 2006-2013 Free Software Foundation, Inc. +/* Copyright (C) 2001-2003, 2006-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2001. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _GL_STDBOOL_H #define _GL_STDBOOL_H @@ -58,33 +58,17 @@ /* 7.16. Boolean type and values */ -/* BeOS already #defines false 0, true 1. We use the same - definitions below, but temporarily we have to #undef them. */ -#if defined __BEOS__ && !defined __HAIKU__ -# include /* defines bool but not _Bool */ -# undef false -# undef true -#endif - #ifdef __cplusplus # define _Bool bool # define bool bool #else -# if defined __BEOS__ && !defined __HAIKU__ - /* A compiler known to have 'bool'. */ - /* If the compiler already has both 'bool' and '_Bool', we can assume they - are the same types. */ -# if !@HAVE__BOOL@ -typedef bool _Bool; -# endif -# else -# if !defined __GNUC__ +# if !defined __GNUC__ /* If @HAVE__BOOL@: Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when the built-in _Bool type is used. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html + https://lists.gnu.org/r/bug-coreutils/2005-10/msg00086.html Similar bugs are likely with other compilers as well; this file wouldn't be used if was working. So we override the _Bool type. @@ -98,10 +82,10 @@ typedef bool _Bool; "Invalid enumerator. (badenum)" with HP-UX cc on Tru64. The only benefit of the enum, debuggability, is not important with these compilers. So use 'signed char' and no enum. */ -# define _Bool signed char -# else +# define _Bool signed char +# else /* With this compiler, trust the _Bool type if the compiler has it. */ -# if !@HAVE__BOOL@ +# if !@HAVE__BOOL@ /* For the sake of symbolic names in gdb, define true and false as enum constants, not only as macros. It is tempting to write @@ -112,7 +96,6 @@ typedef bool _Bool; (see ISO C 99 6.3.1.1.(2)). So add a negative value to the enum; this ensures that '_Bool' promotes to 'int'. */ typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; -# endif # endif # endif # define bool _Bool diff --git a/gl/stdckdint.in.h b/gl/stdckdint.in.h new file mode 100644 index 00000000..90fa62e5 --- /dev/null +++ b/gl/stdckdint.in.h @@ -0,0 +1,37 @@ +/* stdckdint.h -- checked integer arithmetic + + Copyright 2022 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_STDCKDINT_H +#define _GL_STDCKDINT_H + +#include "intprops-internal.h" + +#include + +/* Store into *R the low-order bits of A + B, A - B, A * B, respectively. + Return 1 if the result overflows, 0 otherwise. + A, B, and *R can have any integer type other than char, bool, a + bit-precise integer type, or an enumeration type. + + These are like the standard macros introduced in C23, except that + arguments should not have side effects. */ + +#define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r)) +#define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r)) +#define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r)) + +#endif /* _GL_STDCKDINT_H */ diff --git a/gl/stddef.in.h b/gl/stddef.in.h index 40f0536a..5c9a747d 100644 --- a/gl/stddef.in.h +++ b/gl/stddef.in.h @@ -1,25 +1,25 @@ /* A substitute for POSIX 2008 , for platforms that have issues. - Copyright (C) 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Eric Blake. */ /* * POSIX 2008 for platforms that have issues. - * + * */ #if __GNUC__ >= 3 @@ -39,10 +39,16 @@ # if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T) # ifdef __need_wint_t -# undef _@GUARD_PREFIX@_STDDEF_H # define _GL_STDDEF_WINT_T # endif # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ + /* On TinyCC, make sure that the macros that indicate the special invocation + convention get undefined. */ +# undef __need_wchar_t +# undef __need_size_t +# undef __need_ptrdiff_t +# undef __need_NULL +# undef __need_wint_t # endif #else @@ -50,37 +56,92 @@ # ifndef _@GUARD_PREFIX@_STDDEF_H +/* On AIX 7.2, with xlc in 64-bit mode, defines max_align_t to a + type with alignment 4, but 'long' has alignment 8. */ +# if defined _AIX && defined __LP64__ +# 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@ -# ifndef _@GUARD_PREFIX@_STDDEF_H -# define _@GUARD_PREFIX@_STDDEF_H - /* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ -#if @REPLACE_NULL@ -# undef NULL -# ifdef __cplusplus +# if (@REPLACE_NULL@ \ + && (!defined _@GUARD_PREFIX@_STDDEF_H || defined _GL_STDDEF_WINT_T)) +# undef NULL +# ifdef __cplusplus /* ISO C++ says that the macro NULL must expand to an integer constant expression, hence '((void *) 0)' is not allowed in C++. */ -# if __GNUG__ >= 3 +# if __GNUG__ >= 3 /* GNU C++ has a __null macro that behaves like an integer ('int' or 'long') but has the same size as a pointer. Use that, to avoid warnings. */ -# define NULL __null -# else -# define NULL 0L +# define NULL __null +# else +# define NULL 0L +# endif +# else +# define NULL ((void *) 0) +# endif # endif -# else -# define NULL ((void *) 0) -# endif -#endif + +# ifndef _@GUARD_PREFIX@_STDDEF_H +# define _@GUARD_PREFIX@_STDDEF_H /* Some platforms lack wchar_t. */ #if !@HAVE_WCHAR_T@ # define wchar_t int #endif +/* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is + a hack in case the configure-time test was done with g++ even though + we are currently compiling with gcc. + On MSVC, max_align_t is defined only in C++ mode, after was + included. Its definition is good since it has an alignment of 8 (on x86 + and x86_64). + Similarly on OS/2 kLIBC. */ +#if (defined _MSC_VER || (defined __KLIBC__ && !defined __LIBCN__)) \ + && defined __cplusplus +# include +#else +# if ! (@HAVE_MAX_ALIGN_T@ || (defined _GCC_MAX_ALIGN_T && !defined __clang__)) +# if !GNULIB_defined_max_align_t +/* On the x86, the maximum storage alignment of double, long, etc. is 4, + but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8, + and the C11 standard allows this. Work around this problem by + using __alignof__ (which returns 8 for double) rather than _Alignof + (which returns 4), and align each union member accordingly. */ +# if defined __GNUC__ || (__clang_major__ >= 4) +# define _GL_STDDEF_ALIGNAS(type) \ + __attribute__ ((__aligned__ (__alignof__ (type)))) +# else +# define _GL_STDDEF_ALIGNAS(type) /* */ +# endif +typedef union +{ + char *__p _GL_STDDEF_ALIGNAS (char *); + double __d _GL_STDDEF_ALIGNAS (double); + long double __ld _GL_STDDEF_ALIGNAS (long double); + long int __i _GL_STDDEF_ALIGNAS (long int); +} rpl_max_align_t; +# define max_align_t rpl_max_align_t +# define GNULIB_defined_max_align_t 1 +# endif +# endif +#endif + # endif /* _@GUARD_PREFIX@_STDDEF_H */ # endif /* _@GUARD_PREFIX@_STDDEF_H */ #endif /* __need_XXX */ diff --git a/gl/stdint.in.h b/gl/stdint.in.h index 2db8b2e3..eaa7874f 100644 --- a/gl/stdint.in.h +++ b/gl/stdint.in.h @@ -1,23 +1,23 @@ -/* Copyright (C) 2001-2002, 2004-2013 Free Software Foundation, Inc. +/* Copyright (C) 2001-2002, 2004-2022 Free Software Foundation, Inc. Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. This file is part of gnulib. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* * ISO C 99 for platforms that lack it. - * + * */ #ifndef _@GUARD_PREFIX@_STDINT_H @@ -38,8 +38,7 @@ other system header files; just include the system's . Ideally we should test __BIONIC__ here, but it is only defined after has been included; hence test __ANDROID__ instead. */ -#if defined __ANDROID__ \ - && defined _SYS_TYPES_H_ && !defined __need_size_t +#if defined __ANDROID__ && defined _GL_INCLUDING_SYS_TYPES_H # @INCLUDE_NEXT@ @NEXT_STDINT_H@ #else @@ -80,54 +79,65 @@ #if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H #define _@GUARD_PREFIX@_STDINT_H +/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, + LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH. */ +#include + +/* Override WINT_MIN and WINT_MAX if gnulib's or overrides + wint_t. */ +#if @GNULIBHEADERS_OVERRIDE_WINT_T@ +# undef WINT_MIN +# undef WINT_MAX +# define WINT_MIN 0x0U +# define WINT_MAX 0xffffffffU +#endif + +#if ! @HAVE_C99_STDINT_H@ + /* defines some of the stdint.h types as well, on glibc, IRIX 6.5, and OpenBSD 3.8 (via ). AIX 5.2 isn't needed and causes troubles. Mac OS X 10.4.6 includes (which is us), but relies on the system definitions, so include after @NEXT_STDINT_H@. */ -#if @HAVE_SYS_TYPES_H@ && ! defined _AIX -# include -#endif - -/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, - LONG_MIN, LONG_MAX, ULONG_MAX. */ -#include +# if @HAVE_SYS_TYPES_H@ && ! defined _AIX +# include +# endif -#if @HAVE_INTTYPES_H@ +# if @HAVE_INTTYPES_H@ /* In OpenBSD 3.8, includes , which defines int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. also defines intptr_t and uintptr_t. */ -# include -#elif @HAVE_SYS_INTTYPES_H@ +# include +# elif @HAVE_SYS_INTTYPES_H@ /* Solaris 7 has the types except the *_fast*_t types, and the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ -# include -#endif +# include +# endif -#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ +# if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ /* Linux libc4 >= 4.6.7 and libc5 have a that defines int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is included by . */ -# include -#endif +# include +# endif -#undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +# undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H /* Minimum and maximum values for an integer type under the usual assumption. Return an unspecified value if BITS == 0, adding a check to pacify picky compilers. */ -#define _STDINT_MIN(signed, bits, zero) \ - ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) +/* These are separate macros, because if you try to merge these macros into + a single one, HP-UX cc rejects the resulting expression in constant + expressions. */ +# define _STDINT_UNSIGNED_MIN(bits, zero) \ + (zero) +# define _STDINT_SIGNED_MIN(bits, zero) \ + (~ _STDINT_MAX (1, bits, zero)) -#define _STDINT_MAX(signed, bits, zero) \ - ((signed) \ - ? ~ _STDINT_MIN (signed, bits, zero) \ - : /* The expression for the unsigned case. The subtraction of (signed) \ - is a nop in the unsigned case and avoids "signed integer overflow" \ - warnings in the signed case. */ \ - ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) +# define _STDINT_MAX(signed, bits, zero) \ + (((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) #if !GNULIB_defined_stdint_types @@ -136,26 +146,26 @@ /* Here we assume a standard architecture where the hardware integer types have 8, 16, 32, optionally 64 bits. */ -#undef int8_t -#undef uint8_t +# undef int8_t +# undef uint8_t typedef signed char gl_int8_t; typedef unsigned char gl_uint8_t; -#define int8_t gl_int8_t -#define uint8_t gl_uint8_t +# define int8_t gl_int8_t +# define uint8_t gl_uint8_t -#undef int16_t -#undef uint16_t +# undef int16_t +# undef uint16_t typedef short int gl_int16_t; typedef unsigned short int gl_uint16_t; -#define int16_t gl_int16_t -#define uint16_t gl_uint16_t +# define int16_t gl_int16_t +# define uint16_t gl_uint16_t -#undef int32_t -#undef uint32_t +# undef int32_t +# undef uint32_t typedef int gl_int32_t; typedef unsigned int gl_uint32_t; -#define int32_t gl_int32_t -#define uint32_t gl_uint32_t +# define int32_t gl_int32_t +# define uint32_t gl_uint32_t /* If the system defines INT64_MAX, assume int64_t works. That way, if the underlying platform defines int64_t to be a 64-bit long long @@ -163,54 +173,54 @@ typedef unsigned int gl_uint32_t; int, which would mess up C++ name mangling. We must use #ifdef rather than #if, to avoid an error with HP-UX 10.20 cc. */ -#ifdef INT64_MAX -# define GL_INT64_T -#else +# ifdef INT64_MAX +# define GL_INT64_T +# else /* Do not undefine int64_t if gnulib is not being used with 64-bit types, since otherwise it breaks platforms like Tandem/NSK. */ -# if LONG_MAX >> 31 >> 31 == 1 -# undef int64_t +# if LONG_MAX >> 31 >> 31 == 1 +# undef int64_t typedef long int gl_int64_t; -# define int64_t gl_int64_t -# define GL_INT64_T -# elif defined _MSC_VER -# undef int64_t +# define int64_t gl_int64_t +# define GL_INT64_T +# elif defined _MSC_VER +# undef int64_t typedef __int64 gl_int64_t; -# define int64_t gl_int64_t -# define GL_INT64_T -# elif @HAVE_LONG_LONG_INT@ -# undef int64_t +# define int64_t gl_int64_t +# define GL_INT64_T +# else +# undef int64_t typedef long long int gl_int64_t; -# define int64_t gl_int64_t -# define GL_INT64_T +# define int64_t gl_int64_t +# define GL_INT64_T +# endif # endif -#endif -#ifdef UINT64_MAX -# define GL_UINT64_T -#else -# if ULONG_MAX >> 31 >> 31 >> 1 == 1 -# undef uint64_t -typedef unsigned long int gl_uint64_t; -# define uint64_t gl_uint64_t +# ifdef UINT64_MAX # define GL_UINT64_T -# elif defined _MSC_VER -# undef uint64_t +# else +# if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# undef uint64_t +typedef unsigned long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# elif defined _MSC_VER +# undef uint64_t typedef unsigned __int64 gl_uint64_t; -# define uint64_t gl_uint64_t -# define GL_UINT64_T -# elif @HAVE_UNSIGNED_LONG_LONG_INT@ -# undef uint64_t +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# else +# undef uint64_t typedef unsigned long long int gl_uint64_t; -# define uint64_t gl_uint64_t -# define GL_UINT64_T +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# endif # endif -#endif /* Avoid collision with Solaris 2.5.1 etc. */ -#define _UINT8_T -#define _UINT32_T -#define _UINT64_T +# define _UINT8_T +# define _UINT32_T +# define _UINT64_T /* 7.18.1.2. Minimum-width integer types */ @@ -219,26 +229,26 @@ typedef unsigned long long int gl_uint64_t; types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types are the same as the corresponding N_t types. */ -#undef int_least8_t -#undef uint_least8_t -#undef int_least16_t -#undef uint_least16_t -#undef int_least32_t -#undef uint_least32_t -#undef int_least64_t -#undef uint_least64_t -#define int_least8_t int8_t -#define uint_least8_t uint8_t -#define int_least16_t int16_t -#define uint_least16_t uint16_t -#define int_least32_t int32_t -#define uint_least32_t uint32_t -#ifdef GL_INT64_T -# define int_least64_t int64_t -#endif -#ifdef GL_UINT64_T -# define uint_least64_t uint64_t -#endif +# undef int_least8_t +# undef uint_least8_t +# undef int_least16_t +# undef uint_least16_t +# undef int_least32_t +# undef uint_least32_t +# undef int_least64_t +# undef uint_least64_t +# define int_least8_t int8_t +# define uint_least8_t uint8_t +# define int_least16_t int16_t +# define uint_least16_t uint16_t +# define int_least32_t int32_t +# define uint_least32_t uint32_t +# ifdef GL_INT64_T +# define int_least64_t int64_t +# endif +# ifdef GL_UINT64_T +# define uint_least64_t uint64_t +# endif /* 7.18.1.3. Fastest minimum-width integer types */ @@ -251,50 +261,64 @@ typedef unsigned long long int gl_uint64_t; uses types consistent with glibc, as that lessens the chance of incompatibility with older GNU hosts. */ -#undef int_fast8_t -#undef uint_fast8_t -#undef int_fast16_t -#undef uint_fast16_t -#undef int_fast32_t -#undef uint_fast32_t -#undef int_fast64_t -#undef uint_fast64_t +# undef int_fast8_t +# undef uint_fast8_t +# undef int_fast16_t +# undef uint_fast16_t +# undef int_fast32_t +# undef uint_fast32_t +# undef int_fast64_t +# undef uint_fast64_t typedef signed char gl_int_fast8_t; typedef unsigned char gl_uint_fast8_t; -#ifdef __sun +# ifdef __sun /* Define types compatible with SunOS 5.10, so that code compiled under earlier SunOS versions works with code compiled under SunOS 5.10. */ typedef int gl_int_fast32_t; typedef unsigned int gl_uint_fast32_t; -#else +# else typedef long int gl_int_fast32_t; typedef unsigned long int gl_uint_fast32_t; -#endif +# endif typedef gl_int_fast32_t gl_int_fast16_t; typedef gl_uint_fast32_t gl_uint_fast16_t; -#define int_fast8_t gl_int_fast8_t -#define uint_fast8_t gl_uint_fast8_t -#define int_fast16_t gl_int_fast16_t -#define uint_fast16_t gl_uint_fast16_t -#define int_fast32_t gl_int_fast32_t -#define uint_fast32_t gl_uint_fast32_t -#ifdef GL_INT64_T -# define int_fast64_t int64_t -#endif -#ifdef GL_UINT64_T -# define uint_fast64_t uint64_t -#endif +# define int_fast8_t gl_int_fast8_t +# define uint_fast8_t gl_uint_fast8_t +# define int_fast16_t gl_int_fast16_t +# define uint_fast16_t gl_uint_fast16_t +# define int_fast32_t gl_int_fast32_t +# define uint_fast32_t gl_uint_fast32_t +# ifdef GL_INT64_T +# define int_fast64_t int64_t +# endif +# ifdef GL_UINT64_T +# define uint_fast64_t uint64_t +# endif /* 7.18.1.4. Integer types capable of holding object pointers */ -#undef intptr_t -#undef uintptr_t +/* kLIBC's defines _INTPTR_T_DECLARED and needs its own + definitions of intptr_t and uintptr_t (which use int and unsigned) + to avoid clashes with declarations of system functions like sbrk. + Similarly, MinGW WSL-5.4.1 needs its own intptr_t and + uintptr_t to avoid conflicting declarations of system functions like + _findclose in . */ +# if !((defined __KLIBC__ && defined _INTPTR_T_DECLARED) \ + || defined __MINGW32__) +# undef intptr_t +# undef uintptr_t +# ifdef _WIN64 +typedef long long int gl_intptr_t; +typedef unsigned long long int gl_uintptr_t; +# else typedef long int gl_intptr_t; typedef unsigned long int gl_uintptr_t; -#define intptr_t gl_intptr_t -#define uintptr_t gl_uintptr_t +# endif +# define intptr_t gl_intptr_t +# define uintptr_t gl_uintptr_t +# endif /* 7.18.1.5. Greatest-width integer types */ @@ -305,33 +329,33 @@ typedef unsigned long int gl_uintptr_t; similarly for UINTMAX_MAX and uintmax_t. This avoids problems with assuming one type where another is used by the system. */ -#ifndef INTMAX_MAX -# undef INTMAX_C -# undef intmax_t -# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# ifndef INTMAX_MAX +# undef INTMAX_C +# undef intmax_t +# if LONG_MAX >> 30 == 1 typedef long long int gl_intmax_t; -# define intmax_t gl_intmax_t -# elif defined GL_INT64_T -# define intmax_t int64_t -# else +# define intmax_t gl_intmax_t +# elif defined GL_INT64_T +# define intmax_t int64_t +# else typedef long int gl_intmax_t; -# define intmax_t gl_intmax_t +# define intmax_t gl_intmax_t +# endif # endif -#endif -#ifndef UINTMAX_MAX -# undef UINTMAX_C -# undef uintmax_t -# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# ifndef UINTMAX_MAX +# undef UINTMAX_C +# undef uintmax_t +# if ULONG_MAX >> 31 == 1 typedef unsigned long long int gl_uintmax_t; -# define uintmax_t gl_uintmax_t -# elif defined GL_UINT64_T -# define uintmax_t uint64_t -# else +# define uintmax_t gl_uintmax_t +# elif defined GL_UINT64_T +# define uintmax_t uint64_t +# else typedef unsigned long int gl_uintmax_t; -# define uintmax_t gl_uintmax_t +# define uintmax_t gl_uintmax_t +# endif # endif -#endif /* Verify that intmax_t and uintmax_t have the same size. Too much code breaks if this is not the case. If this check fails, the reason is likely @@ -339,8 +363,8 @@ typedef unsigned long int gl_uintmax_t; typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) ? 1 : -1]; -#define GNULIB_defined_stdint_types 1 -#endif /* !GNULIB_defined_stdint_types */ +# define GNULIB_defined_stdint_types 1 +# endif /* !GNULIB_defined_stdint_types */ /* 7.18.2. Limits of specified-width integer types */ @@ -349,37 +373,37 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) /* Here we assume a standard architecture where the hardware integer types have 8, 16, 32, optionally 64 bits. */ -#undef INT8_MIN -#undef INT8_MAX -#undef UINT8_MAX -#define INT8_MIN (~ INT8_MAX) -#define INT8_MAX 127 -#define UINT8_MAX 255 - -#undef INT16_MIN -#undef INT16_MAX -#undef UINT16_MAX -#define INT16_MIN (~ INT16_MAX) -#define INT16_MAX 32767 -#define UINT16_MAX 65535 - -#undef INT32_MIN -#undef INT32_MAX -#undef UINT32_MAX -#define INT32_MIN (~ INT32_MAX) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U - -#if defined GL_INT64_T && ! defined INT64_MAX +# undef INT8_MIN +# undef INT8_MAX +# undef UINT8_MAX +# define INT8_MIN (~ INT8_MAX) +# define INT8_MAX 127 +# define UINT8_MAX 255 + +# undef INT16_MIN +# undef INT16_MAX +# undef UINT16_MAX +# define INT16_MIN (~ INT16_MAX) +# define INT16_MAX 32767 +# define UINT16_MAX 65535 + +# undef INT32_MIN +# undef INT32_MAX +# undef UINT32_MAX +# define INT32_MIN (~ INT32_MAX) +# define INT32_MAX 2147483647 +# define UINT32_MAX 4294967295U + +# if defined GL_INT64_T && ! defined INT64_MAX /* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 evaluates the latter incorrectly in preprocessor expressions. */ -# define INT64_MIN (- INTMAX_C (1) << 63) -# define INT64_MAX INTMAX_C (9223372036854775807) -#endif +# define INT64_MIN (- INTMAX_C (1) << 63) +# define INT64_MAX INTMAX_C (9223372036854775807) +# endif -#if defined GL_UINT64_T && ! defined UINT64_MAX -# define UINT64_MAX UINTMAX_C (18446744073709551615) -#endif +# if defined GL_UINT64_T && ! defined UINT64_MAX +# define UINT64_MAX UINTMAX_C (18446744073709551615) +# endif /* 7.18.2.2. Limits of minimum-width integer types */ @@ -387,38 +411,38 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types are the same as the corresponding N_t types. */ -#undef INT_LEAST8_MIN -#undef INT_LEAST8_MAX -#undef UINT_LEAST8_MAX -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define UINT_LEAST8_MAX UINT8_MAX - -#undef INT_LEAST16_MIN -#undef INT_LEAST16_MAX -#undef UINT_LEAST16_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define UINT_LEAST16_MAX UINT16_MAX - -#undef INT_LEAST32_MIN -#undef INT_LEAST32_MAX -#undef UINT_LEAST32_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define UINT_LEAST32_MAX UINT32_MAX - -#undef INT_LEAST64_MIN -#undef INT_LEAST64_MAX -#ifdef GL_INT64_T -# define INT_LEAST64_MIN INT64_MIN -# define INT_LEAST64_MAX INT64_MAX -#endif +# undef INT_LEAST8_MIN +# undef INT_LEAST8_MAX +# undef UINT_LEAST8_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST8_MAX UINT8_MAX + +# undef INT_LEAST16_MIN +# undef INT_LEAST16_MAX +# undef UINT_LEAST16_MAX +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST16_MAX UINT16_MAX + +# undef INT_LEAST32_MIN +# undef INT_LEAST32_MAX +# undef UINT_LEAST32_MAX +# define INT_LEAST32_MIN INT32_MIN +# define INT_LEAST32_MAX INT32_MAX +# define UINT_LEAST32_MAX UINT32_MAX + +# undef INT_LEAST64_MIN +# undef INT_LEAST64_MAX +# ifdef GL_INT64_T +# define INT_LEAST64_MIN INT64_MIN +# define INT_LEAST64_MAX INT64_MAX +# endif -#undef UINT_LEAST64_MAX -#ifdef GL_UINT64_T -# define UINT_LEAST64_MAX UINT64_MAX -#endif +# undef UINT_LEAST64_MAX +# ifdef GL_UINT64_T +# define UINT_LEAST64_MAX UINT64_MAX +# endif /* 7.18.2.3. Limits of fastest minimum-width integer types */ @@ -426,117 +450,127 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types are taken from the same list of types. */ -#undef INT_FAST8_MIN -#undef INT_FAST8_MAX -#undef UINT_FAST8_MAX -#define INT_FAST8_MIN SCHAR_MIN -#define INT_FAST8_MAX SCHAR_MAX -#define UINT_FAST8_MAX UCHAR_MAX - -#undef INT_FAST16_MIN -#undef INT_FAST16_MAX -#undef UINT_FAST16_MAX -#define INT_FAST16_MIN INT_FAST32_MIN -#define INT_FAST16_MAX INT_FAST32_MAX -#define UINT_FAST16_MAX UINT_FAST32_MAX - -#undef INT_FAST32_MIN -#undef INT_FAST32_MAX -#undef UINT_FAST32_MAX -#ifdef __sun -# define INT_FAST32_MIN INT_MIN -# define INT_FAST32_MAX INT_MAX -# define UINT_FAST32_MAX UINT_MAX -#else -# define INT_FAST32_MIN LONG_MIN -# define INT_FAST32_MAX LONG_MAX -# define UINT_FAST32_MAX ULONG_MAX -#endif +# undef INT_FAST8_MIN +# undef INT_FAST8_MAX +# undef UINT_FAST8_MAX +# define INT_FAST8_MIN SCHAR_MIN +# define INT_FAST8_MAX SCHAR_MAX +# define UINT_FAST8_MAX UCHAR_MAX + +# undef INT_FAST16_MIN +# undef INT_FAST16_MAX +# undef UINT_FAST16_MAX +# define INT_FAST16_MIN INT_FAST32_MIN +# define INT_FAST16_MAX INT_FAST32_MAX +# define UINT_FAST16_MAX UINT_FAST32_MAX + +# undef INT_FAST32_MIN +# undef INT_FAST32_MAX +# undef UINT_FAST32_MAX +# ifdef __sun +# define INT_FAST32_MIN INT_MIN +# define INT_FAST32_MAX INT_MAX +# define UINT_FAST32_MAX UINT_MAX +# else +# define INT_FAST32_MIN LONG_MIN +# define INT_FAST32_MAX LONG_MAX +# define UINT_FAST32_MAX ULONG_MAX +# endif -#undef INT_FAST64_MIN -#undef INT_FAST64_MAX -#ifdef GL_INT64_T -# define INT_FAST64_MIN INT64_MIN -# define INT_FAST64_MAX INT64_MAX -#endif +# undef INT_FAST64_MIN +# undef INT_FAST64_MAX +# ifdef GL_INT64_T +# define INT_FAST64_MIN INT64_MIN +# define INT_FAST64_MAX INT64_MAX +# endif -#undef UINT_FAST64_MAX -#ifdef GL_UINT64_T -# define UINT_FAST64_MAX UINT64_MAX -#endif +# undef UINT_FAST64_MAX +# ifdef GL_UINT64_T +# define UINT_FAST64_MAX UINT64_MAX +# endif /* 7.18.2.4. Limits of integer types capable of holding object pointers */ -#undef INTPTR_MIN -#undef INTPTR_MAX -#undef UINTPTR_MAX -#define INTPTR_MIN LONG_MIN -#define INTPTR_MAX LONG_MAX -#define UINTPTR_MAX ULONG_MAX +# undef INTPTR_MIN +# undef INTPTR_MAX +# undef UINTPTR_MAX +# ifdef _WIN64 +# define INTPTR_MIN LLONG_MIN +# define INTPTR_MAX LLONG_MAX +# define UINTPTR_MAX ULLONG_MAX +# else +# define INTPTR_MIN LONG_MIN +# define INTPTR_MAX LONG_MAX +# define UINTPTR_MAX ULONG_MAX +# endif /* 7.18.2.5. Limits of greatest-width integer types */ -#ifndef INTMAX_MAX -# undef INTMAX_MIN -# ifdef INT64_MAX -# define INTMAX_MIN INT64_MIN -# define INTMAX_MAX INT64_MAX -# else -# define INTMAX_MIN INT32_MIN -# define INTMAX_MAX INT32_MAX +# ifndef INTMAX_MAX +# undef INTMAX_MIN +# ifdef INT64_MAX +# define INTMAX_MIN INT64_MIN +# define INTMAX_MAX INT64_MAX +# else +# define INTMAX_MIN INT32_MIN +# define INTMAX_MAX INT32_MAX +# endif # endif -#endif -#ifndef UINTMAX_MAX -# ifdef UINT64_MAX -# define UINTMAX_MAX UINT64_MAX -# else -# define UINTMAX_MAX UINT32_MAX +# ifndef UINTMAX_MAX +# ifdef UINT64_MAX +# define UINTMAX_MAX UINT64_MAX +# else +# define UINTMAX_MAX UINT32_MAX +# endif # endif -#endif /* 7.18.3. Limits of other integer types */ /* ptrdiff_t limits */ -#undef PTRDIFF_MIN -#undef PTRDIFF_MAX -#if @APPLE_UNIVERSAL_BUILD@ -# ifdef _LP64 -# define PTRDIFF_MIN _STDINT_MIN (1, 64, 0l) -# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +# undef PTRDIFF_MIN +# undef PTRDIFF_MAX +# if @APPLE_UNIVERSAL_BUILD@ +# ifdef _LP64 +# define PTRDIFF_MIN _STDINT_SIGNED_MIN (64, 0l) +# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +# else +# define PTRDIFF_MIN _STDINT_SIGNED_MIN (32, 0) +# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) +# endif # else -# define PTRDIFF_MIN _STDINT_MIN (1, 32, 0) -# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) -# endif -#else -# define PTRDIFF_MIN \ - _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) -# define PTRDIFF_MAX \ +# define PTRDIFF_MIN \ + _STDINT_SIGNED_MIN (@BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +# define PTRDIFF_MAX \ _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) -#endif +# endif /* sig_atomic_t limits */ -#undef SIG_ATOMIC_MIN -#undef SIG_ATOMIC_MAX -#define SIG_ATOMIC_MIN \ - _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ - 0@SIG_ATOMIC_T_SUFFIX@) -#define SIG_ATOMIC_MAX \ +# undef SIG_ATOMIC_MIN +# undef SIG_ATOMIC_MAX +# if @HAVE_SIGNED_SIG_ATOMIC_T@ +# define SIG_ATOMIC_MIN \ + _STDINT_SIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@) +# else +# define SIG_ATOMIC_MIN \ + _STDINT_UNSIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@) +# endif +# define SIG_ATOMIC_MAX \ _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ 0@SIG_ATOMIC_T_SUFFIX@) /* size_t limit */ -#undef SIZE_MAX -#if @APPLE_UNIVERSAL_BUILD@ -# ifdef _LP64 -# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# undef SIZE_MAX +# if @APPLE_UNIVERSAL_BUILD@ +# ifdef _LP64 +# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# endif # else -# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) # endif -#else -# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) -#endif /* wchar_t limits */ /* Get WCHAR_MIN, WCHAR_MAX. @@ -544,30 +578,39 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) sequence of nested includes -> -> -> , and the latter includes and assumes its types are already defined. */ -#if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) - /* BSD/OS 4.0.1 has a bug: , and must be - included before . */ -# include -# include -# include -# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H -# include -# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H -#endif -#undef WCHAR_MIN -#undef WCHAR_MAX -#define WCHAR_MIN \ - _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) -#define WCHAR_MAX \ +# if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) +# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# include +# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# endif +# undef WCHAR_MIN +# undef WCHAR_MAX +# if @HAVE_SIGNED_WCHAR_T@ +# define WCHAR_MIN \ + _STDINT_SIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +# else +# define WCHAR_MIN \ + _STDINT_UNSIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +# endif +# define WCHAR_MAX \ _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) /* wint_t limits */ -#undef WINT_MIN -#undef WINT_MAX -#define WINT_MIN \ - _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) -#define WINT_MAX \ - _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +/* If gnulib's or overrides wint_t, @WINT_T_SUFFIX@ is not + accurate, therefore use the definitions from above. */ +# if !@GNULIBHEADERS_OVERRIDE_WINT_T@ +# undef WINT_MIN +# undef WINT_MAX +# if @HAVE_SIGNED_WINT_T@ +# define WINT_MIN \ + _STDINT_SIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +# else +# define WINT_MIN \ + _STDINT_UNSIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +# endif +# define WINT_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +# endif /* 7.18.4. Macros for integer constants */ @@ -577,59 +620,120 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) /* Here we assume a standard architecture where the hardware integer types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ -#undef INT8_C -#undef UINT8_C -#define INT8_C(x) x -#define UINT8_C(x) x - -#undef INT16_C -#undef UINT16_C -#define INT16_C(x) x -#define UINT16_C(x) x - -#undef INT32_C -#undef UINT32_C -#define INT32_C(x) x -#define UINT32_C(x) x ## U - -#undef INT64_C -#undef UINT64_C -#if LONG_MAX >> 31 >> 31 == 1 -# define INT64_C(x) x##L -#elif defined _MSC_VER -# define INT64_C(x) x##i64 -#elif @HAVE_LONG_LONG_INT@ -# define INT64_C(x) x##LL -#endif -#if ULONG_MAX >> 31 >> 31 >> 1 == 1 -# define UINT64_C(x) x##UL -#elif defined _MSC_VER -# define UINT64_C(x) x##ui64 -#elif @HAVE_UNSIGNED_LONG_LONG_INT@ -# define UINT64_C(x) x##ULL -#endif +# undef INT8_C +# undef UINT8_C +# define INT8_C(x) x +# define UINT8_C(x) x -/* 7.18.4.2. Macros for greatest-width integer constants */ +# undef INT16_C +# undef UINT16_C +# define INT16_C(x) x +# define UINT16_C(x) x + +# undef INT32_C +# undef UINT32_C +# define INT32_C(x) x +# define UINT32_C(x) x ## U -#ifndef INTMAX_C -# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -# define INTMAX_C(x) x##LL -# elif defined GL_INT64_T -# define INTMAX_C(x) INT64_C(x) +# undef INT64_C +# undef UINT64_C +# if LONG_MAX >> 31 >> 31 == 1 +# define INT64_C(x) x##L +# elif defined _MSC_VER +# define INT64_C(x) x##i64 # else -# define INTMAX_C(x) x##L +# define INT64_C(x) x##LL # endif -#endif - -#ifndef UINTMAX_C -# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -# define UINTMAX_C(x) x##ULL -# elif defined GL_UINT64_T -# define UINTMAX_C(x) UINT64_C(x) +# if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define UINT64_C(x) x##UL +# elif defined _MSC_VER +# define UINT64_C(x) x##ui64 # else -# define UINTMAX_C(x) x##UL +# define UINT64_C(x) x##ULL # endif -#endif + +/* 7.18.4.2. Macros for greatest-width integer constants */ + +# ifndef INTMAX_C +# if LONG_MAX >> 30 == 1 +# define INTMAX_C(x) x##LL +# elif defined GL_INT64_T +# define INTMAX_C(x) INT64_C(x) +# else +# define INTMAX_C(x) x##L +# endif +# endif + +# ifndef UINTMAX_C +# if ULONG_MAX >> 31 == 1 +# define UINTMAX_C(x) x##ULL +# elif defined GL_UINT64_T +# define UINTMAX_C(x) UINT64_C(x) +# else +# define UINTMAX_C(x) x##UL +# endif +# endif + +#endif /* !@HAVE_C99_STDINT_H@ */ + +/* Macros specified by ISO/IEC TS 18661-1:2014. */ + +#if (!defined UINTMAX_WIDTH \ + && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__)) +# ifdef INT8_MAX +# define INT8_WIDTH _GL_INTEGER_WIDTH (INT8_MIN, INT8_MAX) +# endif +# ifdef UINT8_MAX +# define UINT8_WIDTH _GL_INTEGER_WIDTH (0, UINT8_MAX) +# endif +# ifdef INT16_MAX +# define INT16_WIDTH _GL_INTEGER_WIDTH (INT16_MIN, INT16_MAX) +# endif +# ifdef UINT16_MAX +# define UINT16_WIDTH _GL_INTEGER_WIDTH (0, UINT16_MAX) +# endif +# ifdef INT32_MAX +# define INT32_WIDTH _GL_INTEGER_WIDTH (INT32_MIN, INT32_MAX) +# endif +# ifdef UINT32_MAX +# define UINT32_WIDTH _GL_INTEGER_WIDTH (0, UINT32_MAX) +# endif +# ifdef INT64_MAX +# define INT64_WIDTH _GL_INTEGER_WIDTH (INT64_MIN, INT64_MAX) +# endif +# ifdef UINT64_MAX +# define UINT64_WIDTH _GL_INTEGER_WIDTH (0, UINT64_MAX) +# endif +# define INT_LEAST8_WIDTH _GL_INTEGER_WIDTH (INT_LEAST8_MIN, INT_LEAST8_MAX) +# define UINT_LEAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST8_MAX) +# define INT_LEAST16_WIDTH _GL_INTEGER_WIDTH (INT_LEAST16_MIN, INT_LEAST16_MAX) +# define UINT_LEAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST16_MAX) +# define INT_LEAST32_WIDTH _GL_INTEGER_WIDTH (INT_LEAST32_MIN, INT_LEAST32_MAX) +# define UINT_LEAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST32_MAX) +# define INT_LEAST64_WIDTH _GL_INTEGER_WIDTH (INT_LEAST64_MIN, INT_LEAST64_MAX) +# define UINT_LEAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST64_MAX) +# define INT_FAST8_WIDTH _GL_INTEGER_WIDTH (INT_FAST8_MIN, INT_FAST8_MAX) +# define UINT_FAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST8_MAX) +# define INT_FAST16_WIDTH _GL_INTEGER_WIDTH (INT_FAST16_MIN, INT_FAST16_MAX) +# define UINT_FAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST16_MAX) +# define INT_FAST32_WIDTH _GL_INTEGER_WIDTH (INT_FAST32_MIN, INT_FAST32_MAX) +# define UINT_FAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST32_MAX) +# define INT_FAST64_WIDTH _GL_INTEGER_WIDTH (INT_FAST64_MIN, INT_FAST64_MAX) +# define UINT_FAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST64_MAX) +# define INTPTR_WIDTH _GL_INTEGER_WIDTH (INTPTR_MIN, INTPTR_MAX) +# define UINTPTR_WIDTH _GL_INTEGER_WIDTH (0, UINTPTR_MAX) +# define INTMAX_WIDTH _GL_INTEGER_WIDTH (INTMAX_MIN, INTMAX_MAX) +# define UINTMAX_WIDTH _GL_INTEGER_WIDTH (0, UINTMAX_MAX) +# define PTRDIFF_WIDTH _GL_INTEGER_WIDTH (PTRDIFF_MIN, PTRDIFF_MAX) +# define SIZE_WIDTH _GL_INTEGER_WIDTH (0, SIZE_MAX) +# define WCHAR_WIDTH _GL_INTEGER_WIDTH (WCHAR_MIN, WCHAR_MAX) +# ifdef WINT_MAX +# define WINT_WIDTH _GL_INTEGER_WIDTH (WINT_MIN, WINT_MAX) +# endif +# ifdef SIG_ATOMIC_MAX +# define SIG_ATOMIC_WIDTH _GL_INTEGER_WIDTH (SIG_ATOMIC_MIN, SIG_ATOMIC_MAX) +# endif +#endif /* !WINT_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */ #endif /* _@GUARD_PREFIX@_STDINT_H */ #endif /* !(defined __ANDROID__ && ...) */ diff --git a/gl/stdio-impl.h b/gl/stdio-impl.h new file mode 100644 index 00000000..ed32e698 --- /dev/null +++ b/gl/stdio-impl.h @@ -0,0 +1,212 @@ +/* Implementation details of FILE streams. + Copyright (C) 2007-2008, 2010-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Many stdio implementations have the same logic and therefore can share + the same implementation of stdio extension API, except that some fields + have different naming conventions, or their access requires some casts. */ + +/* Glibc 2.28 made _IO_UNBUFFERED and _IO_IN_BACKUP private. For now, work + around this problem by defining them ourselves. FIXME: Do not rely on glibc + internals. */ +#if defined _IO_EOF_SEEN +# if !defined _IO_UNBUFFERED +# define _IO_UNBUFFERED 0x2 +# endif +# if !defined _IO_IN_BACKUP +# define _IO_IN_BACKUP 0x100 +# endif +#endif + +/* BSD stdio derived implementations. */ + +#if defined __NetBSD__ /* NetBSD */ +/* Get __NetBSD_Version__. */ +# include +#endif + +#include /* For detecting Plan9. */ + +#if defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ + +# if defined __DragonFly__ /* DragonFly */ + /* See . */ +# define fp_ ((struct { struct __FILE_public pub; \ + struct { unsigned char *_base; int _size; } _bf; \ + void *cookie; \ + void *_close; \ + void *_read; \ + void *_seek; \ + void *_write; \ + struct { unsigned char *_base; int _size; } _ub; \ + int _ur; \ + unsigned char _ubuf[3]; \ + unsigned char _nbuf[1]; \ + struct { unsigned char *_base; int _size; } _lb; \ + int _blksize; \ + fpos_t _offset; \ + /* More fields, not relevant here. */ \ + } *) fp) + /* See . */ +# define _p pub._p +# define _flags pub._flags +# define _r pub._r +# define _w pub._w +# elif defined __ANDROID__ /* Android */ +# ifdef __LP64__ +# define _gl_flags_file_t int +# else +# define _gl_flags_file_t short +# endif + /* Up to this commit from 2015-10-12 + + the innards of FILE were public, and fp_ub could be defined like for OpenBSD, + see + and . + After this commit, the innards of FILE are hidden. */ +# define fp_ ((struct { unsigned char *_p; \ + int _r; \ + int _w; \ + _gl_flags_file_t _flags; \ + _gl_flags_file_t _file; \ + struct { unsigned char *_base; size_t _size; } _bf; \ + int _lbfsize; \ + void *_cookie; \ + void *_close; \ + void *_read; \ + void *_seek; \ + void *_write; \ + struct { unsigned char *_base; size_t _size; } _ext; \ + unsigned char *_up; \ + int _ur; \ + unsigned char _ubuf[3]; \ + unsigned char _nbuf[1]; \ + struct { unsigned char *_base; size_t _size; } _lb; \ + int _blksize; \ + fpos_t _offset; \ + /* More fields, not relevant here. */ \ + } *) fp) +# else +# define fp_ fp +# endif + +# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */ + /* See + and + and */ + struct __sfileext + { + struct __sbuf _ub; /* ungetc buffer */ + /* More fields, not relevant here. */ + }; +# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub +# elif defined __ANDROID__ /* Android */ + struct __sfileext + { + struct { unsigned char *_base; size_t _size; } _ub; /* ungetc buffer */ + /* More fields, not relevant here. */ + }; +# define fp_ub ((struct __sfileext *) fp_->_ext._base)->_ub +# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, Mac OS X, Cygwin */ +# define fp_ub fp_->_ub +# endif + +# define HASUB(fp) (fp_ub._base != NULL) + +# if defined __ANDROID__ /* Android */ + /* Needed after this commit from 2016-01-25 + */ +# ifndef __SEOF +# define __SLBF 1 +# define __SNBF 2 +# define __SRD 4 +# define __SWR 8 +# define __SRW 0x10 +# define __SEOF 0x20 +# define __SERR 0x40 +# endif +# ifndef __SOFF +# define __SOFF 0x1000 +# endif +# endif + +#endif + + +/* SystemV derived implementations. */ + +#ifdef __TANDEM /* NonStop Kernel */ +# ifndef _IOERR +/* These values were determined by the program 'stdioext-flags' at + . */ +# define _IOERR 0x40 +# define _IOREAD 0x80 +# define _IOWRT 0x4 +# define _IORW 0x100 +# endif +#endif + +#if defined _IOERR + +# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ +# define fp_ ((struct { unsigned char *_ptr; \ + unsigned char *_base; \ + unsigned char *_end; \ + long _cnt; \ + int _file; \ + unsigned int _flag; \ + } *) fp) +# elif defined __VMS /* OpenVMS */ +# define fp_ ((struct _iobuf *) fp) +# else +# define fp_ fp +# endif + +# if defined _SCO_DS || (defined __SCO_VERSION__ || defined __sysv5__) /* OpenServer 5, OpenServer 6, UnixWare 7 */ +# define _cnt __cnt +# define _ptr __ptr +# define _base __base +# define _flag __flag +# endif + +#elif defined _WIN32 && ! defined __CYGWIN__ /* newer Windows with MSVC */ + +/* does not define the innards of FILE any more. */ +# define WINDOWS_OPAQUE_FILE + +struct _gl_real_FILE +{ + /* Note: Compared to older Windows and to mingw, it has the fields + _base and _cnt swapped. */ + unsigned char *_ptr; + unsigned char *_base; + int _cnt; + int _flag; + int _file; + int _charbuf; + int _bufsiz; +}; +# define fp_ ((struct _gl_real_FILE *) fp) + +/* These values were determined by a program similar to the one at + . */ +# define _IOREAD 0x1 +# define _IOWRT 0x2 +# define _IORW 0x4 +# define _IOEOF 0x8 +# define _IOERR 0x10 + +#endif diff --git a/gl/stdio-read.c b/gl/stdio-read.c new file mode 100644 index 00000000..85efa0d4 --- /dev/null +++ b/gl/stdio-read.c @@ -0,0 +1,168 @@ +/* POSIX compatible FILE stream read function. + Copyright (C) 2008-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2011. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Replace these functions only if module 'nonblocking' is requested. */ +#if GNULIB_NONBLOCKING + +/* On native Windows platforms, when read() is called on a non-blocking pipe + with an empty buffer, ReadFile() fails with error GetLastError() = + ERROR_NO_DATA, and read() in consequence fails with error EINVAL. This + read() function is at the basis of the function which fills the buffer of + a FILE stream. */ + +# if defined _WIN32 && ! defined __CYGWIN__ + +# include +# include + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +/* Don't assume that UNICODE is not defined. */ +# undef GetNamedPipeHandleState +# define GetNamedPipeHandleState GetNamedPipeHandleStateA + +# define CALL_WITH_ERRNO_FIX(RETTYPE, EXPRESSION, FAILED) \ + if (ferror (stream)) \ + return (EXPRESSION); \ + else \ + { \ + RETTYPE ret; \ + SetLastError (0); \ + ret = (EXPRESSION); \ + if (FAILED) \ + { \ + if (GetLastError () == ERROR_NO_DATA && ferror (stream)) \ + { \ + int fd = fileno (stream); \ + if (fd >= 0) \ + { \ + HANDLE h = (HANDLE) _get_osfhandle (fd); \ + if (GetFileType (h) == FILE_TYPE_PIPE) \ + { \ + /* h is a pipe or socket. */ \ + DWORD state; \ + if (GetNamedPipeHandleState (h, &state, NULL, NULL, \ + NULL, NULL, 0) \ + && (state & PIPE_NOWAIT) != 0) \ + /* h is a pipe in non-blocking mode. \ + Change errno from EINVAL to EAGAIN. */ \ + errno = EAGAIN; \ + } \ + } \ + } \ + } \ + return ret; \ + } + +/* Enable this function definition only if gnulib's has prepared it. + Otherwise we get a function definition conflict with mingw64's . */ +# if GNULIB_SCANF +int +scanf (const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfscanf (stdin, format, args); + va_end (args); + + return retval; +} +# endif + +/* Enable this function definition only if gnulib's has prepared it. + Otherwise we get a function definition conflict with mingw64's . */ +# if GNULIB_FSCANF +int +fscanf (FILE *stream, const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfscanf (stream, format, args); + va_end (args); + + return retval; +} +# endif + +/* Enable this function definition only if gnulib's has prepared it. + Otherwise we get a function definition conflict with mingw64's . */ +# if GNULIB_VSCANF +int +vscanf (const char *format, va_list args) +{ + return vfscanf (stdin, format, args); +} +# endif + +/* Enable this function definition only if gnulib's has prepared it. + Otherwise we get a function definition conflict with mingw64's . */ +# if GNULIB_VFSCANF +int +vfscanf (FILE *stream, const char *format, va_list args) +#undef vfscanf +{ + CALL_WITH_ERRNO_FIX (int, vfscanf (stream, format, args), ret == EOF) +} +# endif + +int +getchar (void) +{ + return fgetc (stdin); +} + +int +fgetc (FILE *stream) +#undef fgetc +{ + CALL_WITH_ERRNO_FIX (int, fgetc (stream), ret == EOF) +} + +char * +fgets (char *s, int n, FILE *stream) +#undef fgets +{ + CALL_WITH_ERRNO_FIX (char *, fgets (s, n, stream), ret == NULL) +} + +/* We intentionally don't bother to fix gets. */ + +size_t +fread (void *ptr, size_t s, size_t n, FILE *stream) +#undef fread +{ + CALL_WITH_ERRNO_FIX (size_t, fread (ptr, s, n, stream), ret < n) +} + +# endif +#endif diff --git a/gl/stdio-write.c b/gl/stdio-write.c new file mode 100644 index 00000000..82facf54 --- /dev/null +++ b/gl/stdio-write.c @@ -0,0 +1,206 @@ +/* POSIX compatible FILE stream write function. + Copyright (C) 2008-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Replace these functions only if module 'nonblocking' or module 'sigpipe' is + requested. */ +#if GNULIB_NONBLOCKING || GNULIB_SIGPIPE + +/* On native Windows platforms, SIGPIPE does not exist. When write() is + called on a pipe with no readers, WriteFile() fails with error + GetLastError() = ERROR_NO_DATA, and write() in consequence fails with + error EINVAL. This write() function is at the basis of the function + which flushes the buffer of a FILE stream. */ + +# if defined _WIN32 && ! defined __CYGWIN__ + +# include +# include +# include + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +/* Don't assume that UNICODE is not defined. */ +# undef GetNamedPipeHandleState +# define GetNamedPipeHandleState GetNamedPipeHandleStateA + +# if GNULIB_NONBLOCKING +# define CLEAR_ERRNO \ + errno = 0; +# define HANDLE_ENOSPC \ + if (errno == ENOSPC && ferror (stream)) \ + { \ + int fd = fileno (stream); \ + if (fd >= 0) \ + { \ + HANDLE h = (HANDLE) _get_osfhandle (fd); \ + if (GetFileType (h) == FILE_TYPE_PIPE) \ + { \ + /* h is a pipe or socket. */ \ + DWORD state; \ + if (GetNamedPipeHandleState (h, &state, NULL, NULL, \ + NULL, NULL, 0) \ + && (state & PIPE_NOWAIT) != 0) \ + /* h is a pipe in non-blocking mode. \ + Change errno from ENOSPC to EAGAIN. */ \ + errno = EAGAIN; \ + } \ + } \ + } \ + else +# else +# define CLEAR_ERRNO +# define HANDLE_ENOSPC +# endif + +# if GNULIB_SIGPIPE +# define CLEAR_LastError \ + SetLastError (0); +# define HANDLE_ERROR_NO_DATA \ + if (GetLastError () == ERROR_NO_DATA && ferror (stream)) \ + { \ + int fd = fileno (stream); \ + if (fd >= 0 \ + && GetFileType ((HANDLE) _get_osfhandle (fd)) \ + == FILE_TYPE_PIPE) \ + { \ + /* Try to raise signal SIGPIPE. */ \ + raise (SIGPIPE); \ + /* If it is currently blocked or ignored, change errno from \ + EINVAL to EPIPE. */ \ + errno = EPIPE; \ + } \ + } \ + else +# else +# define CLEAR_LastError +# define HANDLE_ERROR_NO_DATA +# endif + +# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \ + if (ferror (stream)) \ + return (EXPRESSION); \ + else \ + { \ + RETTYPE ret; \ + CLEAR_ERRNO \ + CLEAR_LastError \ + ret = (EXPRESSION); \ + if (FAILED) \ + { \ + HANDLE_ENOSPC \ + HANDLE_ERROR_NO_DATA \ + ; \ + } \ + return ret; \ + } + +# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */ +int +printf (const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfprintf (stdout, format, args); + va_end (args); + + return retval; +} +# endif + +# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */ +int +fprintf (FILE *stream, const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfprintf (stream, format, args); + va_end (args); + + return retval; +} +# endif + +# if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */ +int +vprintf (const char *format, va_list args) +{ + return vfprintf (stdout, format, args); +} +# endif + +# if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */ +int +vfprintf (FILE *stream, const char *format, va_list args) +#undef vfprintf +{ + CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF) +} +# endif + +int +putchar (int c) +{ + return fputc (c, stdout); +} + +int +fputc (int c, FILE *stream) +#undef fputc +{ + CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF) +} + +int +fputs (const char *string, FILE *stream) +#undef fputs +{ + CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF) +} + +int +puts (const char *string) +#undef puts +{ + FILE *stream = stdout; + CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF) +} + +size_t +fwrite (const void *ptr, size_t s, size_t n, FILE *stream) +#undef fwrite +{ + CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n) +} + +# endif +#endif diff --git a/gl/stdio.in.h b/gl/stdio.in.h index 06cbad00..7b36dac2 100644 --- a/gl/stdio.in.h +++ b/gl/stdio.in.h @@ -1,19 +1,19 @@ /* A GNU-like . - Copyright (C) 2004, 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2004, 2007-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ @@ -56,36 +56,103 @@ May also define off_t to a 64-bit type on native Windows. */ #include +/* Solaris 10 and NetBSD 7.0 declare renameat in , not in . */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && (defined __sun || defined __NetBSD__) \ + && ! defined __GLIBC__ +# include +#endif + +/* Android 4.3 declares renameat in , not in . */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \ + && ! defined __GLIBC__ +# include +#endif + +/* MSVC declares 'perror' in , not in . We must include + it before we #define perror rpl_perror. */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_PERROR@ || defined GNULIB_POSIXCHECK) \ + && (defined _WIN32 && ! defined __CYGWIN__) \ + && ! defined __GLIBC__ +# include +#endif + +/* MSVC declares 'remove' in , not in . We must include + it before we #define remove rpl_remove. */ +/* MSVC declares 'rename' in , not in . We must include + it before we #define rename rpl_rename. */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_REMOVE@ || @GNULIB_RENAME@ || defined GNULIB_POSIXCHECK) \ + && (defined _WIN32 && ! defined __CYGWIN__) \ + && ! defined __GLIBC__ +# include +#endif + + +/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers + that can be freed by passing them as the Ith argument to the + function F. */ +#ifndef _GL_ATTRIBUTE_DEALLOC +# if __GNUC__ >= 11 +# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) +# else +# define _GL_ATTRIBUTE_DEALLOC(f, i) +# endif +#endif + /* The __attribute__ feature is available in gcc versions 2.5 and later. The __-protected variants of the attributes 'format' and 'printf' are accepted by gcc versions 2.6.4 (effectively 2.7) and later. We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because gnulib and libintl do '#define printf __printf__' when they override the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +#ifndef _GL_ATTRIBUTE_FORMAT +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || defined __clang__ +# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) +# else +# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +# endif +#endif + +/* An __attribute__ __format__ specifier for a function that takes a format + string and arguments, where the format string directives are the ones + standardized by ISO C99 and POSIX. + _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD */ +/* __gnu_printf__ is supported in GCC >= 4.4. */ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +# define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __gnu_printf__ #else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ +# define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __printf__ #endif -/* _GL_ATTRIBUTE_FORMAT_PRINTF +/* An __attribute__ __format__ specifier for a function that takes a format + string and arguments, where the format string directives are the ones of the + system printf(), rather than the ones standardized by ISO C99 and POSIX. + _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM */ +/* On mingw, Gnulib sets __USE_MINGW_ANSI_STDIO in order to get closer to + the standards. The macro GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU indicates + whether this change is effective. On older mingw, it is not. */ +#if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU +# define _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD +#else +# define _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM __printf__ +#endif + +/* _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD indicates to GCC that the function takes a format string and arguments, where the format string directives are the ones standardized by ISO C99 and POSIX. */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__gnu_printf__, formatstring_parameter, first_argument)) -#else -# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) -#endif +#define _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, formatstring_parameter, first_argument)) -/* _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_PRINTF, +/* _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD, except that it indicates to GCC that the supported format string directives are the ones of the system printf(), rather than the ones standardized by ISO C99 and POSIX. */ #define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM, formatstring_parameter, first_argument)) /* _GL_ATTRIBUTE_FORMAT_SCANF indicates to GCC that the function takes a format string and arguments, @@ -106,14 +173,6 @@ #define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \ _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) -/* Solaris 10 declares renameat in , not in . */ -/* But in any case avoid namespace pollution on glibc systems. */ -#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \ - && ! defined __GLIBC__ -# include -#endif - - /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ /* The definition of _GL_ARG_NONNULL is copied here. */ @@ -124,23 +183,32 @@ #define _GL_STDIO_STRINGIZE(token) #token #define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token) +/* When also using extern inline, suppress the use of static inline in + standard headers of problematic Apple configurations, as Libc at + least through Libc-825.26 (2013-04-09) mishandles it; see, e.g., + . + Perhaps Apple will fix this some day. */ +#if (defined _GL_EXTERN_INLINE_IN_USE && defined __APPLE__ \ + && defined __GNUC__ && defined __STDC__) +# undef putc_unlocked +#endif #if @GNULIB_DPRINTF@ # if @REPLACE_DPRINTF@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define dprintf rpl_dprintf # endif -_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) +_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *format, ...)); +_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *restrict format, ...)); # else # if !@HAVE_DPRINTF@ -_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) +_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((2))); # endif -_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *format, ...)); +_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *restrict format, ...)); # endif _GL_CXXALIASWARN (dprintf); #elif defined GNULIB_POSIXCHECK @@ -162,7 +230,9 @@ _GL_CXXALIAS_RPL (fclose, int, (FILE *stream)); # else _GL_CXXALIAS_SYS (fclose, int, (FILE *stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fclose); +# endif #elif defined GNULIB_POSIXCHECK # undef fclose /* Assume fclose is always declared. */ @@ -170,24 +240,84 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " "use gnulib module fclose for portable POSIX compliance"); #endif +#if @GNULIB_MDA_FCLOSEALL@ +/* On native Windows, map 'fcloseall' to '_fcloseall', so that -loldnames is + not required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::fcloseall on all platforms that have + it. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fcloseall +# define fcloseall _fcloseall +# endif +_GL_CXXALIAS_MDA (fcloseall, int, (void)); +# else +# if @HAVE_DECL_FCLOSEALL@ +# if defined __FreeBSD__ || defined __DragonFly__ +_GL_CXXALIAS_SYS (fcloseall, void, (void)); +# else +_GL_CXXALIAS_SYS (fcloseall, int, (void)); +# endif +# endif +# endif +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCLOSEALL@ +_GL_CXXALIASWARN (fcloseall); +# endif +#endif + #if @GNULIB_FDOPEN@ # if @REPLACE_FDOPEN@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fdopen # define fdopen rpl_fdopen # endif -_GL_FUNCDECL_RPL (fdopen, FILE *, (int fd, const char *mode) - _GL_ARG_NONNULL ((2))); +_GL_FUNCDECL_RPL (fdopen, FILE *, + (int fd, const char *mode) + _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); _GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fdopen +# define fdopen _fdopen +# endif +_GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode)); # else +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */ +_GL_FUNCDECL_SYS (fdopen, FILE *, + (int fd, const char *mode) + _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +# endif _GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); # endif _GL_CXXALIASWARN (fdopen); -#elif defined GNULIB_POSIXCHECK -# undef fdopen +#else +# if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined fdopen +/* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */ +_GL_FUNCDECL_SYS (fdopen, FILE *, + (int fd, const char *mode) + _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +# endif +# if defined GNULIB_POSIXCHECK +# undef fdopen /* Assume fdopen is always declared. */ _GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - " "use gnulib module fdopen for portability"); +# elif @GNULIB_MDA_FDOPEN@ +/* On native Windows, map 'fdopen' to '_fdopen', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::fdopen always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fdopen +# define fdopen _fdopen +# endif +_GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode)); +# else +_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); +# endif +_GL_CXXALIASWARN (fdopen); +# endif #endif #if @GNULIB_FFLUSH@ @@ -206,7 +336,9 @@ _GL_CXXALIAS_RPL (fflush, int, (FILE *gl_stream)); # else _GL_CXXALIAS_SYS (fflush, int, (FILE *gl_stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fflush); +# endif #elif defined GNULIB_POSIXCHECK # undef fflush /* Assume fflush is always declared. */ @@ -225,7 +357,9 @@ _GL_CXXALIAS_RPL (fgetc, int, (FILE *stream)); # else _GL_CXXALIAS_SYS (fgetc, int, (FILE *stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fgetc); +# endif #endif #if @GNULIB_FGETS@ @@ -234,33 +368,74 @@ _GL_CXXALIASWARN (fgetc); # undef fgets # define fgets rpl_fgets # endif -_GL_FUNCDECL_RPL (fgets, char *, (char *s, int n, FILE *stream) - _GL_ARG_NONNULL ((1, 3))); -_GL_CXXALIAS_RPL (fgets, char *, (char *s, int n, FILE *stream)); +_GL_FUNCDECL_RPL (fgets, char *, + (char *restrict s, int n, FILE *restrict stream) + _GL_ARG_NONNULL ((1, 3))); +_GL_CXXALIAS_RPL (fgets, char *, + (char *restrict s, int n, FILE *restrict stream)); # else -_GL_CXXALIAS_SYS (fgets, char *, (char *s, int n, FILE *stream)); +_GL_CXXALIAS_SYS (fgets, char *, + (char *restrict s, int n, FILE *restrict stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fgets); +# endif +#endif + +#if @GNULIB_MDA_FILENO@ +/* On native Windows, map 'fileno' to '_fileno', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::fileno always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fileno +# define fileno _fileno +# endif +_GL_CXXALIAS_MDA (fileno, int, (FILE *restrict stream)); +# else +_GL_CXXALIAS_SYS (fileno, int, (FILE *restrict stream)); +# endif +_GL_CXXALIASWARN (fileno); #endif #if @GNULIB_FOPEN@ -# if @REPLACE_FOPEN@ +# if (@GNULIB_FOPEN@ && @REPLACE_FOPEN@) \ + || (@GNULIB_FOPEN_GNU@ && @REPLACE_FOPEN_FOR_FOPEN_GNU@) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef fopen # define fopen rpl_fopen # endif -_GL_FUNCDECL_RPL (fopen, FILE *, (const char *filename, const char *mode) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (fopen, FILE *, (const char *filename, const char *mode)); +_GL_FUNCDECL_RPL (fopen, FILE *, + (const char *restrict filename, const char *restrict mode) + _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +_GL_CXXALIAS_RPL (fopen, FILE *, + (const char *restrict filename, const char *restrict mode)); # else -_GL_CXXALIAS_SYS (fopen, FILE *, (const char *filename, const char *mode)); +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */ +_GL_FUNCDECL_SYS (fopen, FILE *, + (const char *restrict filename, const char *restrict mode) + _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +# endif +_GL_CXXALIAS_SYS (fopen, FILE *, + (const char *restrict filename, const char *restrict mode)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fopen); -#elif defined GNULIB_POSIXCHECK -# undef fopen +# endif +#else +# if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined fopen +/* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */ +_GL_FUNCDECL_SYS (fopen, FILE *, + (const char *restrict filename, const char *restrict mode) + _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +# endif +# if defined GNULIB_POSIXCHECK +# undef fopen /* Assume fopen is always declared. */ _GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX compliant - " "use gnulib module fopen for portability"); +# endif #endif #if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@ @@ -271,19 +446,25 @@ _GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX complian # endif # define GNULIB_overrides_fprintf 1 # if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_RPL (fprintf, int, + (FILE *restrict fp, const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); # else -_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) - _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_RPL (fprintf, int, + (FILE *restrict fp, const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) + _GL_ARG_NONNULL ((1, 2))); # endif -_GL_CXXALIAS_RPL (fprintf, int, (FILE *fp, const char *format, ...)); +_GL_CXXALIAS_RPL (fprintf, int, + (FILE *restrict fp, const char *restrict format, ...)); # else -_GL_CXXALIAS_SYS (fprintf, int, (FILE *fp, const char *format, ...)); +_GL_CXXALIAS_SYS (fprintf, int, + (FILE *restrict fp, const char *restrict format, ...)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fprintf); +# endif #endif #if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_fprintf @@ -334,7 +515,9 @@ _GL_CXXALIAS_RPL (fputc, int, (int c, FILE *stream)); # else _GL_CXXALIAS_SYS (fputc, int, (int c, FILE *stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fputc); +# endif #endif #if @GNULIB_FPUTS@ @@ -343,13 +526,18 @@ _GL_CXXALIASWARN (fputc); # undef fputs # define fputs rpl_fputs # endif -_GL_FUNCDECL_RPL (fputs, int, (const char *string, FILE *stream) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (fputs, int, (const char *string, FILE *stream)); +_GL_FUNCDECL_RPL (fputs, int, + (const char *restrict string, FILE *restrict stream) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fputs, int, + (const char *restrict string, FILE *restrict stream)); # else -_GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream)); +_GL_CXXALIAS_SYS (fputs, int, + (const char *restrict string, FILE *restrict stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fputs); +# endif #endif #if @GNULIB_FREAD@ @@ -358,13 +546,21 @@ _GL_CXXALIASWARN (fputs); # undef fread # define fread rpl_fread # endif -_GL_FUNCDECL_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream) - _GL_ARG_NONNULL ((4))); -_GL_CXXALIAS_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); +_GL_FUNCDECL_RPL (fread, size_t, + (void *restrict ptr, size_t s, size_t n, + FILE *restrict stream) + _GL_ARG_NONNULL ((4))); +_GL_CXXALIAS_RPL (fread, size_t, + (void *restrict ptr, size_t s, size_t n, + FILE *restrict stream)); # else -_GL_CXXALIAS_SYS (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); +_GL_CXXALIAS_SYS (fread, size_t, + (void *restrict ptr, size_t s, size_t n, + FILE *restrict stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fread); +# endif #endif #if @GNULIB_FREOPEN@ @@ -374,15 +570,20 @@ _GL_CXXALIASWARN (fread); # define freopen rpl_freopen # endif _GL_FUNCDECL_RPL (freopen, FILE *, - (const char *filename, const char *mode, FILE *stream) + (const char *restrict filename, const char *restrict mode, + FILE *restrict stream) _GL_ARG_NONNULL ((2, 3))); _GL_CXXALIAS_RPL (freopen, FILE *, - (const char *filename, const char *mode, FILE *stream)); + (const char *restrict filename, const char *restrict mode, + FILE *restrict stream)); # else _GL_CXXALIAS_SYS (freopen, FILE *, - (const char *filename, const char *mode, FILE *stream)); + (const char *restrict filename, const char *restrict mode, + FILE *restrict stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (freopen); +# endif #elif defined GNULIB_POSIXCHECK # undef freopen /* Assume freopen is always declared. */ @@ -397,14 +598,19 @@ _GL_WARN_ON_USE (freopen, # undef fscanf # define fscanf rpl_fscanf # endif -_GL_FUNCDECL_RPL (fscanf, int, (FILE *stream, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (fscanf, int, (FILE *stream, const char *format, ...)); +_GL_FUNCDECL_RPL (fscanf, int, + (FILE *restrict stream, const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fscanf, int, + (FILE *restrict stream, const char *restrict format, ...)); # else -_GL_CXXALIAS_SYS (fscanf, int, (FILE *stream, const char *format, ...)); +_GL_CXXALIAS_SYS (fscanf, int, + (FILE *restrict stream, const char *restrict format, ...)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fscanf); +# endif #endif @@ -455,7 +661,9 @@ _GL_CXXALIAS_RPL (fseek, int, (FILE *fp, long offset, int whence)); # else _GL_CXXALIAS_SYS (fseek, int, (FILE *fp, long offset, int whence)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fseek); +# endif #endif #if @GNULIB_FSEEKO@ @@ -518,7 +726,9 @@ _GL_CXXALIAS_RPL (ftell, long, (FILE *fp)); # else _GL_CXXALIAS_SYS (ftell, long, (FILE *fp)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (ftell); +# endif #endif #if @GNULIB_FTELLO@ @@ -567,16 +777,19 @@ _GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " # define fwrite rpl_fwrite # endif _GL_FUNCDECL_RPL (fwrite, size_t, - (const void *ptr, size_t s, size_t n, FILE *stream) + (const void *restrict ptr, size_t s, size_t n, + FILE *restrict stream) _GL_ARG_NONNULL ((1, 4))); _GL_CXXALIAS_RPL (fwrite, size_t, - (const void *ptr, size_t s, size_t n, FILE *stream)); + (const void *restrict ptr, size_t s, size_t n, + FILE *restrict stream)); # else _GL_CXXALIAS_SYS (fwrite, size_t, - (const void *ptr, size_t s, size_t n, FILE *stream)); + (const void *restrict ptr, size_t s, size_t n, + FILE *restrict stream)); /* Work around bug 11959 when fortifying glibc 2.4 through 2.15 - , + , which sometimes causes an unwanted diagnostic for fwrite calls. This affects only function declaration attributes under certain versions of gcc and clang, and is not needed for C++. */ @@ -598,7 +811,9 @@ extern size_t __REDIRECT (rpl_fwrite_unlocked, # define fwrite_unlocked rpl_fwrite_unlocked # endif # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (fwrite); +# endif #endif #if @GNULIB_GETC@ @@ -612,7 +827,9 @@ _GL_CXXALIAS_RPL_1 (getc, rpl_fgetc, int, (FILE *stream)); # else _GL_CXXALIAS_SYS (getc, int, (FILE *stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (getc); +# endif #endif #if @GNULIB_GETCHAR@ @@ -626,7 +843,9 @@ _GL_CXXALIAS_RPL (getchar, int, (void)); # else _GL_CXXALIAS_SYS (getchar, int, (void)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (getchar); +# endif #endif #if @GNULIB_GETDELIM@ @@ -642,22 +861,26 @@ _GL_CXXALIASWARN (getchar); # define getdelim rpl_getdelim # endif _GL_FUNCDECL_RPL (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream) + (char **restrict lineptr, size_t *restrict linesize, + int delimiter, + FILE *restrict stream) _GL_ARG_NONNULL ((1, 2, 4))); _GL_CXXALIAS_RPL (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream)); + (char **restrict lineptr, size_t *restrict linesize, + int delimiter, + FILE *restrict stream)); # else # if !@HAVE_DECL_GETDELIM@ _GL_FUNCDECL_SYS (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream) + (char **restrict lineptr, size_t *restrict linesize, + int delimiter, + FILE *restrict stream) _GL_ARG_NONNULL ((1, 2, 4))); # endif _GL_CXXALIAS_SYS (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream)); + (char **restrict lineptr, size_t *restrict linesize, + int delimiter, + FILE *restrict stream)); # endif _GL_CXXALIASWARN (getdelim); #elif defined GNULIB_POSIXCHECK @@ -681,18 +904,22 @@ _GL_WARN_ON_USE (getdelim, "getdelim is unportable - " # define getline rpl_getline # endif _GL_FUNCDECL_RPL (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream) + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream) _GL_ARG_NONNULL ((1, 2, 3))); _GL_CXXALIAS_RPL (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream)); + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream)); # else # if !@HAVE_DECL_GETLINE@ _GL_FUNCDECL_SYS (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream) + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream) _GL_ARG_NONNULL ((1, 2, 3))); # endif _GL_CXXALIAS_SYS (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream)); + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream)); # endif # if @HAVE_DECL_GETLINE@ _GL_CXXALIASWARN (getline); @@ -709,10 +936,25 @@ _GL_WARN_ON_USE (getline, "getline is unportable - " so any use of gets warrants an unconditional warning; besides, C11 removed it. */ #undef gets -#if HAVE_RAW_DECL_GETS +#if HAVE_RAW_DECL_GETS && !defined __cplusplus _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); #endif +#if @GNULIB_MDA_GETW@ +/* On native Windows, map 'getw' to '_getw', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::getw always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getw +# define getw _getw +# endif +_GL_CXXALIAS_MDA (getw, int, (FILE *restrict stream)); +# else +_GL_CXXALIAS_SYS (getw, int, (FILE *restrict stream)); +# endif +_GL_CXXALIASWARN (getw); +#endif #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ struct obstack; @@ -727,7 +969,7 @@ struct obstack; # endif _GL_FUNCDECL_RPL (obstack_printf, int, (struct obstack *obs, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (obstack_printf, int, (struct obstack *obs, const char *format, ...)); @@ -735,7 +977,7 @@ _GL_CXXALIAS_RPL (obstack_printf, int, # if !@HAVE_DECL_OBSTACK_PRINTF@ _GL_FUNCDECL_SYS (obstack_printf, int, (struct obstack *obs, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((1, 2))); # endif _GL_CXXALIAS_SYS (obstack_printf, int, @@ -748,7 +990,7 @@ _GL_CXXALIASWARN (obstack_printf); # endif _GL_FUNCDECL_RPL (obstack_vprintf, int, (struct obstack *obs, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (obstack_vprintf, int, (struct obstack *obs, const char *format, va_list args)); @@ -756,7 +998,7 @@ _GL_CXXALIAS_RPL (obstack_vprintf, int, # if !@HAVE_DECL_OBSTACK_PRINTF@ _GL_FUNCDECL_SYS (obstack_vprintf, int, (struct obstack *obs, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) _GL_ARG_NONNULL ((1, 2))); # endif _GL_CXXALIAS_SYS (obstack_vprintf, int, @@ -792,7 +1034,9 @@ _GL_CXXALIAS_RPL (perror, void, (const char *string)); # else _GL_CXXALIAS_SYS (perror, void, (const char *string)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (perror); +# endif #elif defined GNULIB_POSIXCHECK # undef perror /* Assume perror is always declared. */ @@ -806,43 +1050,53 @@ _GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - " # undef popen # define popen rpl_popen # endif -_GL_FUNCDECL_RPL (popen, FILE *, (const char *cmd, const char *mode) - _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_RPL (popen, FILE *, + (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1)); _GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); # else -# if !@HAVE_POPEN@ -_GL_FUNCDECL_SYS (popen, FILE *, (const char *cmd, const char *mode) - _GL_ARG_NONNULL ((1, 2))); +# if !@HAVE_POPEN@ || __GNUC__ >= 11 +_GL_FUNCDECL_SYS (popen, FILE *, + (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1)); # endif _GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); # endif _GL_CXXALIASWARN (popen); -#elif defined GNULIB_POSIXCHECK -# undef popen -# if HAVE_RAW_DECL_POPEN +#else +# if @GNULIB_PCLOSE@ && __GNUC__ >= 11 && !defined popen +/* For -Wmismatched-dealloc: Associate popen with pclose or rpl_pclose. */ +_GL_FUNCDECL_SYS (popen, FILE *, + (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1)); +# endif +# if defined GNULIB_POSIXCHECK +# undef popen +# if HAVE_RAW_DECL_POPEN _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " "use gnulib module popen or pipe for more portability"); +# endif # endif #endif #if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ # if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) -# if defined __GNUC__ +# if defined __GNUC__ || defined __clang__ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) /* Don't break __attribute__((format(printf,M,N))). */ # define printf __printf__ # endif # if @GNULIB_PRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ _GL_FUNCDECL_RPL_1 (__printf__, int, - (const char *format, ...) + (const char *restrict format, ...) __asm__ (@ASM_SYMBOL_PREFIX@ _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) - _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) _GL_ARG_NONNULL ((1))); # else _GL_FUNCDECL_RPL_1 (__printf__, int, - (const char *format, ...) + (const char *restrict format, ...) __asm__ (@ASM_SYMBOL_PREFIX@ _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2) @@ -854,16 +1108,18 @@ _GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...)); # define printf rpl_printf # endif _GL_FUNCDECL_RPL (printf, int, - (const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) + (const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (printf, int, (const char *format, ...)); +_GL_CXXALIAS_RPL (printf, int, (const char *restrict format, ...)); # endif # define GNULIB_overrides_printf 1 # else -_GL_CXXALIAS_SYS (printf, int, (const char *format, ...)); +_GL_CXXALIAS_SYS (printf, int, (const char *restrict format, ...)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (printf); +# endif #endif #if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_printf @@ -886,7 +1142,9 @@ _GL_CXXALIAS_RPL_1 (putc, rpl_fputc, int, (int c, FILE *stream)); # else _GL_CXXALIAS_SYS (putc, int, (int c, FILE *stream)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (putc); +# endif #endif #if @GNULIB_PUTCHAR@ @@ -900,7 +1158,9 @@ _GL_CXXALIAS_RPL (putchar, int, (int c)); # else _GL_CXXALIAS_SYS (putchar, int, (int c)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (putchar); +# endif #endif #if @GNULIB_PUTS@ @@ -914,7 +1174,25 @@ _GL_CXXALIAS_RPL (puts, int, (const char *string)); # else _GL_CXXALIAS_SYS (puts, int, (const char *string)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (puts); +# endif +#endif + +#if @GNULIB_MDA_PUTW@ +/* On native Windows, map 'putw' to '_putw', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::putw always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putw +# define putw _putw +# endif +_GL_CXXALIAS_MDA (putw, int, (int w, FILE *restrict stream)); +# else +_GL_CXXALIAS_SYS (putw, int, (int w, FILE *restrict stream)); +# endif +_GL_CXXALIASWARN (putw); #endif #if @GNULIB_REMOVE@ @@ -928,7 +1206,9 @@ _GL_CXXALIAS_RPL (remove, int, (const char *name)); # else _GL_CXXALIAS_SYS (remove, int, (const char *name)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (remove); +# endif #elif defined GNULIB_POSIXCHECK # undef remove /* Assume remove is always declared. */ @@ -951,7 +1231,9 @@ _GL_CXXALIAS_RPL (rename, int, _GL_CXXALIAS_SYS (rename, int, (const char *old_filename, const char *new_filename)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (rename); +# endif #elif defined GNULIB_POSIXCHECK # undef rename /* Assume rename is always declared. */ @@ -990,33 +1272,35 @@ _GL_WARN_ON_USE (renameat, "renameat is not portable - " #if @GNULIB_SCANF@ # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if defined __GNUC__ +# if defined __GNUC__ || defined __clang__ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef scanf /* Don't break __attribute__((format(scanf,M,N))). */ # define scanf __scanf__ # endif _GL_FUNCDECL_RPL_1 (__scanf__, int, - (const char *format, ...) + (const char *restrict format, ...) __asm__ (@ASM_SYMBOL_PREFIX@ _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf)) _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *format, ...)); +_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *restrict format, ...)); # else # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef scanf # define scanf rpl_scanf # endif -_GL_FUNCDECL_RPL (scanf, int, (const char *format, ...) +_GL_FUNCDECL_RPL (scanf, int, (const char *restrict format, ...) _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (scanf, int, (const char *format, ...)); +_GL_CXXALIAS_RPL (scanf, int, (const char *restrict format, ...)); # endif # else -_GL_CXXALIAS_SYS (scanf, int, (const char *format, ...)); +_GL_CXXALIAS_SYS (scanf, int, (const char *restrict format, ...)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (scanf); +# endif #endif #if @GNULIB_SNPRINTF@ @@ -1024,23 +1308,30 @@ _GL_CXXALIASWARN (scanf); # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define snprintf rpl_snprintf # endif +# define GNULIB_overrides_snprintf 1 _GL_FUNCDECL_RPL (snprintf, int, - (char *str, size_t size, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) + (char *restrict str, size_t size, + const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) _GL_ARG_NONNULL ((3))); _GL_CXXALIAS_RPL (snprintf, int, - (char *str, size_t size, const char *format, ...)); + (char *restrict str, size_t size, + const char *restrict format, ...)); # else # if !@HAVE_DECL_SNPRINTF@ _GL_FUNCDECL_SYS (snprintf, int, - (char *str, size_t size, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) + (char *restrict str, size_t size, + const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) _GL_ARG_NONNULL ((3))); # endif _GL_CXXALIAS_SYS (snprintf, int, - (char *str, size_t size, const char *format, ...)); + (char *restrict str, size_t size, + const char *restrict format, ...)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (snprintf); +# endif #elif defined GNULIB_POSIXCHECK # undef snprintf # if HAVE_RAW_DECL_SNPRINTF @@ -1063,14 +1354,20 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define sprintf rpl_sprintf # endif -_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...)); +# define GNULIB_overrides_sprintf 1 +_GL_FUNCDECL_RPL (sprintf, int, + (char *restrict str, const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (sprintf, int, + (char *restrict str, const char *restrict format, ...)); # else -_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...)); +_GL_CXXALIAS_SYS (sprintf, int, + (char *restrict str, const char *restrict format, ...)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (sprintf); +# endif #elif defined GNULIB_POSIXCHECK # undef sprintf /* Assume sprintf is always declared. */ @@ -1079,22 +1376,53 @@ _GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - " "POSIX compliance"); #endif +#if @GNULIB_MDA_TEMPNAM@ +/* On native Windows, map 'tempnam' to '_tempnam', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::tempnam always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tempnam +# define tempnam _tempnam +# endif +_GL_CXXALIAS_MDA (tempnam, char *, (const char *dir, const char *prefix)); +# else +_GL_CXXALIAS_SYS (tempnam, char *, (const char *dir, const char *prefix)); +# endif +_GL_CXXALIASWARN (tempnam); +#endif + #if @GNULIB_TMPFILE@ # if @REPLACE_TMPFILE@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define tmpfile rpl_tmpfile # endif -_GL_FUNCDECL_RPL (tmpfile, FILE *, (void)); +_GL_FUNCDECL_RPL (tmpfile, FILE *, (void) + _GL_ATTRIBUTE_DEALLOC (fclose, 1)); _GL_CXXALIAS_RPL (tmpfile, FILE *, (void)); # else +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */ +_GL_FUNCDECL_SYS (tmpfile, FILE *, (void) + _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +# endif _GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (tmpfile); -#elif defined GNULIB_POSIXCHECK -# undef tmpfile -# if HAVE_RAW_DECL_TMPFILE +# endif +#else +# if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined tmpfile +/* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */ +_GL_FUNCDECL_SYS (tmpfile, FILE *, (void) + _GL_ATTRIBUTE_DEALLOC (fclose, 1)); +# endif +# if defined GNULIB_POSIXCHECK +# undef tmpfile +# if HAVE_RAW_DECL_TMPFILE _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " "use gnulib module tmpfile for portability"); +# endif # endif #endif @@ -1107,9 +1435,10 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define asprintf rpl_asprintf # endif +# define GNULIB_overrides_asprintf _GL_FUNCDECL_RPL (asprintf, int, (char **result, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (asprintf, int, (char **result, const char *format, ...)); @@ -1117,7 +1446,7 @@ _GL_CXXALIAS_RPL (asprintf, int, # if !@HAVE_VASPRINTF@ _GL_FUNCDECL_SYS (asprintf, int, (char **result, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) _GL_ARG_NONNULL ((1, 2))); # endif _GL_CXXALIAS_SYS (asprintf, int, @@ -1128,9 +1457,10 @@ _GL_CXXALIASWARN (asprintf); # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define vasprintf rpl_vasprintf # endif +# define GNULIB_overrides_vasprintf 1 _GL_FUNCDECL_RPL (vasprintf, int, (char **result, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (vasprintf, int, (char **result, const char *format, va_list args)); @@ -1138,7 +1468,7 @@ _GL_CXXALIAS_RPL (vasprintf, int, # if !@HAVE_VASPRINTF@ _GL_FUNCDECL_SYS (vasprintf, int, (char **result, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) _GL_ARG_NONNULL ((1, 2))); # endif _GL_CXXALIAS_SYS (vasprintf, int, @@ -1152,22 +1482,27 @@ _GL_CXXALIASWARN (vasprintf); # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define vdprintf rpl_vdprintf # endif -_GL_FUNCDECL_RPL (vdprintf, int, (int fd, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (vdprintf, int, (int fd, const char *format, va_list args)); +_GL_FUNCDECL_RPL (vdprintf, int, + (int fd, const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (vdprintf, int, + (int fd, const char *restrict format, va_list args)); # else # if !@HAVE_VDPRINTF@ -_GL_FUNCDECL_SYS (vdprintf, int, (int fd, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((2))); +_GL_FUNCDECL_SYS (vdprintf, int, + (int fd, const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((2))); # endif /* Need to cast, because on Solaris, the third parameter will likely be __va_list args. */ _GL_CXXALIAS_SYS_CAST (vdprintf, int, - (int fd, const char *format, va_list args)); + (int fd, const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vdprintf); +# endif #elif defined GNULIB_POSIXCHECK # undef vdprintf # if HAVE_RAW_DECL_VDPRINTF @@ -1184,23 +1519,32 @@ _GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " # endif # define GNULIB_overrides_vfprintf 1 # if @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_RPL (vfprintf, int, + (FILE *restrict fp, + const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((1, 2))); # else -_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) - _GL_ARG_NONNULL ((1, 2))); +_GL_FUNCDECL_RPL (vfprintf, int, + (FILE *restrict fp, + const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) + _GL_ARG_NONNULL ((1, 2))); # endif -_GL_CXXALIAS_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)); +_GL_CXXALIAS_RPL (vfprintf, int, + (FILE *restrict fp, + const char *restrict format, va_list args)); # else /* Need to cast, because on Solaris, the third parameter is __va_list args and GCC's fixincludes did not change this to __gnuc_va_list. */ _GL_CXXALIAS_SYS_CAST (vfprintf, int, - (FILE *fp, const char *format, va_list args)); + (FILE *restrict fp, + const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vfprintf); +# endif #endif #if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_vfprintf @@ -1219,16 +1563,21 @@ _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " # define vfscanf rpl_vfscanf # endif _GL_FUNCDECL_RPL (vfscanf, int, - (FILE *stream, const char *format, va_list args) + (FILE *restrict stream, + const char *restrict format, va_list args) _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (vfscanf, int, - (FILE *stream, const char *format, va_list args)); + (FILE *restrict stream, + const char *restrict format, va_list args)); # else _GL_CXXALIAS_SYS (vfscanf, int, - (FILE *stream, const char *format, va_list args)); + (FILE *restrict stream, + const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vfscanf); +# endif #endif #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ @@ -1239,22 +1588,25 @@ _GL_CXXALIASWARN (vfscanf); # endif # define GNULIB_overrides_vprintf 1 # if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (1, 0) +_GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) _GL_ARG_NONNULL ((1))); # else -_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) +_GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args) _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) _GL_ARG_NONNULL ((1))); # endif -_GL_CXXALIAS_RPL (vprintf, int, (const char *format, va_list args)); +_GL_CXXALIAS_RPL (vprintf, int, (const char *restrict format, va_list args)); # else /* Need to cast, because on Solaris, the second parameter is __va_list args and GCC's fixincludes did not change this to __gnuc_va_list. */ -_GL_CXXALIAS_SYS_CAST (vprintf, int, (const char *format, va_list args)); +_GL_CXXALIAS_SYS_CAST (vprintf, int, + (const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vprintf); +# endif #endif #if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK # if !GNULIB_overrides_vprintf @@ -1272,14 +1624,16 @@ _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " # undef vscanf # define vscanf rpl_vscanf # endif -_GL_FUNCDECL_RPL (vscanf, int, (const char *format, va_list args) +_GL_FUNCDECL_RPL (vscanf, int, (const char *restrict format, va_list args) _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (vscanf, int, (const char *format, va_list args)); +_GL_CXXALIAS_RPL (vscanf, int, (const char *restrict format, va_list args)); # else -_GL_CXXALIAS_SYS (vscanf, int, (const char *format, va_list args)); +_GL_CXXALIAS_SYS (vscanf, int, (const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vscanf); +# endif #endif #if @GNULIB_VSNPRINTF@ @@ -1287,23 +1641,30 @@ _GL_CXXALIASWARN (vscanf); # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define vsnprintf rpl_vsnprintf # endif +# define GNULIB_overrides_vsnprintf 1 _GL_FUNCDECL_RPL (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) + (char *restrict str, size_t size, + const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3))); _GL_CXXALIAS_RPL (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args)); + (char *restrict str, size_t size, + const char *restrict format, va_list args)); # else # if !@HAVE_DECL_VSNPRINTF@ _GL_FUNCDECL_SYS (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) + (char *restrict str, size_t size, + const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3))); # endif _GL_CXXALIAS_SYS (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args)); + (char *restrict str, size_t size, + const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vsnprintf); +# endif #elif defined GNULIB_POSIXCHECK # undef vsnprintf # if HAVE_RAW_DECL_VSNPRINTF @@ -1317,20 +1678,26 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define vsprintf rpl_vsprintf # endif +# define GNULIB_overrides_vsprintf 1 _GL_FUNCDECL_RPL (vsprintf, int, - (char *str, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + (char *restrict str, + const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (vsprintf, int, - (char *str, const char *format, va_list args)); + (char *restrict str, + const char *restrict format, va_list args)); # else /* Need to cast, because on Solaris, the third parameter is __va_list args and GCC's fixincludes did not change this to __gnuc_va_list. */ _GL_CXXALIAS_SYS_CAST (vsprintf, int, - (char *str, const char *format, va_list args)); + (char *restrict str, + const char *restrict format, va_list args)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (vsprintf); +# endif #elif defined GNULIB_POSIXCHECK # undef vsprintf /* Assume vsprintf is always declared. */ diff --git a/gl/stdlib.in.h b/gl/stdlib.in.h index c9552480..a86643c3 100644 --- a/gl/stdlib.in.h +++ b/gl/stdlib.in.h @@ -1,19 +1,19 @@ /* A GNU-like . - Copyright (C) 1995, 2001-2004, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 1995, 2001-2004, 2006-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ @@ -47,11 +47,14 @@ /* Solaris declares getloadavg() in . */ #if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@ +/* OpenIndiana has a bug: must be included before + . */ +# include # include #endif -/* Native Windows platforms declare mktemp() in . */ -#if 0 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +/* Native Windows platforms declare _mktemp() in . */ +#if defined _WIN32 && !defined __CYGWIN__ # include #endif @@ -87,20 +90,52 @@ struct random_data # endif #endif -#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_MKOSTEMP@ || @GNULIB_MKOSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !(defined _WIN32 && ! defined __CYGWIN__) /* On Mac OS X 10.3, only declares mkstemp. */ /* On Mac OS X 10.5, only declares mkstemps. */ +/* On Mac OS X 10.13, only declares mkostemp and mkostemps. */ /* On Cygwin 1.7.1, only declares getsubopt. */ /* But avoid namespace pollution on glibc systems and native Windows. */ # include #endif +/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers + that can be freed by passing them as the Ith argument to the + function F. */ +#ifndef _GL_ATTRIBUTE_DEALLOC +# if __GNUC__ >= 11 +# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) +# else +# define _GL_ATTRIBUTE_DEALLOC(f, i) +# endif +#endif + +/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that + can be freed via 'free'; it can be used only after declaring 'free'. */ +/* Applies to: functions. Cannot be used on inline functions. */ +#ifndef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1) +#endif + +/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly + allocated memory. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_MALLOC +# if __GNUC__ >= 3 || defined __clang__ +# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define _GL_ATTRIBUTE_MALLOC +# endif +#endif + /* The __attribute__ feature is available in gcc versions 2.5 and later. The attribute __pure__ was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ +#ifndef _GL_ATTRIBUTE_PURE +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define _GL_ATTRIBUTE_PURE /* empty */ +# endif #endif /* The definition of _Noreturn is copied here. */ @@ -143,6 +178,73 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " #endif +#if @GNULIB_FREE_POSIX@ +# if @REPLACE_FREE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef free +# define free rpl_free +# endif +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_FUNCDECL_RPL (free, void, (void *ptr) throw ()); +# else +_GL_FUNCDECL_RPL (free, void, (void *ptr)); +# endif +_GL_CXXALIAS_RPL (free, void, (void *ptr)); +# else +_GL_CXXALIAS_SYS (free, void, (void *ptr)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (free); +# endif +#elif defined GNULIB_POSIXCHECK +# undef free +/* Assume free is always declared. */ +_GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " + "use gnulib module free for portability"); +#endif + + +/* Allocate memory with indefinite extent and specified alignment. */ +#if @GNULIB_ALIGNED_ALLOC@ +# if @REPLACE_ALIGNED_ALLOC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef aligned_alloc +# define aligned_alloc rpl_aligned_alloc +# endif +_GL_FUNCDECL_RPL (aligned_alloc, void *, + (size_t alignment, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +_GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); +# else +# if @HAVE_ALIGNED_ALLOC@ +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (aligned_alloc, void *, + (size_t alignment, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +_GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size)); +# endif +# endif +# if @HAVE_ALIGNED_ALLOC@ +_GL_CXXALIASWARN (aligned_alloc); +# endif +#else +# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined aligned_alloc +/* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (aligned_alloc, void *, + (size_t alignment, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK +# undef aligned_alloc +# if HAVE_RAW_DECL_ALIGNED_ALLOC +_GL_WARN_ON_USE (aligned_alloc, "aligned_alloc is not portable - " + "use gnulib module aligned_alloc for portability"); +# endif +# endif +#endif + #if @GNULIB_ATOLL@ /* Parse a signed decimal integer. Returns the value of the integer. Errors are not detected. */ @@ -162,22 +264,41 @@ _GL_WARN_ON_USE (atoll, "atoll is unportable - " #endif #if @GNULIB_CALLOC_POSIX@ -# if @REPLACE_CALLOC@ +# if (@GNULIB_CALLOC_POSIX@ && @REPLACE_CALLOC_FOR_CALLOC_POSIX@) \ + || (@GNULIB_CALLOC_GNU@ && @REPLACE_CALLOC_FOR_CALLOC_GNU@) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef calloc # define calloc rpl_calloc # endif -_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size)); +_GL_FUNCDECL_RPL (calloc, void *, + (size_t nmemb, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); # else +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (calloc, void *, + (size_t nmemb, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (calloc); -#elif defined GNULIB_POSIXCHECK -# undef calloc +# endif +#else +# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined calloc +/* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (calloc, void *, + (size_t nmemb, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK +# undef calloc /* Assume calloc is always declared. */ _GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - " "use gnulib module calloc-posix for portability"); +# endif #endif #if @GNULIB_CANONICALIZE_FILE_NAME@ @@ -185,23 +306,108 @@ _GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define canonicalize_file_name rpl_canonicalize_file_name # endif -_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name) - _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_RPL (canonicalize_file_name, char *, + (const char *name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); # else -# if !@HAVE_CANONICALIZE_FILE_NAME@ -_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name) - _GL_ARG_NONNULL ((1))); +# if !@HAVE_CANONICALIZE_FILE_NAME@ || __GNUC__ >= 11 +_GL_FUNCDECL_SYS (canonicalize_file_name, char *, + (const char *name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); # endif +# ifndef GNULIB_defined_canonicalize_file_name +# define GNULIB_defined_canonicalize_file_name \ + (!@HAVE_CANONICALIZE_FILE_NAME@ || @REPLACE_CANONICALIZE_FILE_NAME@) +# endif _GL_CXXALIASWARN (canonicalize_file_name); -#elif defined GNULIB_POSIXCHECK -# undef canonicalize_file_name -# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME +#else +# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined canonicalize_file_name +/* For -Wmismatched-dealloc: Associate canonicalize_file_name with free or + rpl_free. */ +_GL_FUNCDECL_SYS (canonicalize_file_name, char *, + (const char *name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK +# undef canonicalize_file_name +# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME _GL_WARN_ON_USE (canonicalize_file_name, "canonicalize_file_name is unportable - " "use gnulib module canonicalize-lgpl for portability"); +# endif +# endif +#endif + +#if @GNULIB_MDA_ECVT@ +/* On native Windows, map 'ecvt' to '_ecvt', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::ecvt on all platforms that have + it. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ecvt +# define ecvt _ecvt +# endif +_GL_CXXALIAS_MDA (ecvt, char *, + (double number, int ndigits, int *decptp, int *signp)); +# else +# if @HAVE_DECL_ECVT@ +_GL_CXXALIAS_SYS (ecvt, char *, + (double number, int ndigits, int *decptp, int *signp)); +# endif +# endif +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_ECVT@ +_GL_CXXALIASWARN (ecvt); +# endif +#endif + +#if @GNULIB_MDA_FCVT@ +/* On native Windows, map 'fcvt' to '_fcvt', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::fcvt on all platforms that have + it. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fcvt +# define fcvt _fcvt +# endif +_GL_CXXALIAS_MDA (fcvt, char *, + (double number, int ndigits, int *decptp, int *signp)); +# else +# if @HAVE_DECL_FCVT@ +_GL_CXXALIAS_SYS (fcvt, char *, + (double number, int ndigits, int *decptp, int *signp)); +# endif +# endif +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCVT@ +_GL_CXXALIASWARN (fcvt); +# endif +#endif + +#if @GNULIB_MDA_GCVT@ +/* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::gcvt on all platforms that have + it. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gcvt +# define gcvt _gcvt +# endif +_GL_CXXALIAS_MDA (gcvt, char *, (double number, int ndigits, char *buf)); +# else +# if @HAVE_DECL_GCVT@ +_GL_CXXALIAS_SYS (gcvt, char *, (double number, int ndigits, char *buf)); +# endif +# endif +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_GCVT@ +_GL_CXXALIASWARN (gcvt); # endif #endif @@ -234,8 +440,8 @@ _GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - " element (or NULL if it doesn't contain an "=" sign), - It returns the index of the "token" in the given array of tokens. Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined. - For more details see the POSIX:2001 specification. - http://www.opengroup.org/susv3xsh/getsubopt.html */ + For more details see the POSIX specification. + https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsubopt.html */ # if !@HAVE_GETSUBOPT@ _GL_FUNCDECL_SYS (getsubopt, int, (char **optionp, char *const *tokens, char **valuep) @@ -273,23 +479,42 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - " by never specifying a zero size), so it does not need malloc or realloc to be redefined. */ #if @GNULIB_MALLOC_POSIX@ -# if @REPLACE_MALLOC@ +# if (@GNULIB_MALLOC_POSIX@ && @REPLACE_MALLOC_FOR_MALLOC_POSIX@) \ + || (@GNULIB_MALLOC_GNU@ && @REPLACE_MALLOC_FOR_MALLOC_GNU@) # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ || _GL_USE_STDLIB_ALLOC) # undef malloc # define malloc rpl_malloc # endif -_GL_FUNCDECL_RPL (malloc, void *, (size_t size)); +_GL_FUNCDECL_RPL (malloc, void *, + (size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (malloc, void *, (size_t size)); # else +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (malloc, void *, + (size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (malloc, void *, (size_t size)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (malloc); -#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC -# undef malloc +# endif +#else +# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined malloc +/* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (malloc, void *, + (size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC +# undef malloc /* Assume malloc is always declared. */ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " "use gnulib module malloc-posix for portability"); +# endif #endif /* Convert a multibyte character to a wide character. */ @@ -299,12 +524,27 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " # undef mbtowc # define mbtowc rpl_mbtowc # endif -_GL_FUNCDECL_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); -_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); +_GL_FUNCDECL_RPL (mbtowc, int, + (wchar_t *restrict pwc, const char *restrict s, size_t n)); +_GL_CXXALIAS_RPL (mbtowc, int, + (wchar_t *restrict pwc, const char *restrict s, size_t n)); # else -_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); +# if !@HAVE_MBTOWC@ +_GL_FUNCDECL_SYS (mbtowc, int, + (wchar_t *restrict pwc, const char *restrict s, size_t n)); +# endif +_GL_CXXALIAS_SYS (mbtowc, int, + (wchar_t *restrict pwc, const char *restrict s, size_t n)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (mbtowc); +# endif +#elif defined GNULIB_POSIXCHECK +# undef mbtowc +# if HAVE_RAW_DECL_MBTOWC +_GL_WARN_ON_USE (mbtowc, "mbtowc is not portable - " + "use gnulib module mbtowc for portability"); +# endif #endif #if @GNULIB_MKDTEMP@ @@ -439,6 +679,51 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - " # endif #endif +#if @GNULIB_MDA_MKTEMP@ +/* On native Windows, map 'mktemp' to '_mktemp', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::mktemp always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mktemp +# define mktemp _mktemp +# endif +_GL_CXXALIAS_MDA (mktemp, char *, (char * /*template*/)); +# else +_GL_CXXALIAS_SYS (mktemp, char *, (char * /*template*/)); +# endif +_GL_CXXALIASWARN (mktemp); +#endif + +/* Allocate memory with indefinite extent and specified alignment. */ +#if @GNULIB_POSIX_MEMALIGN@ +# if @REPLACE_POSIX_MEMALIGN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef posix_memalign +# define posix_memalign rpl_posix_memalign +# endif +_GL_FUNCDECL_RPL (posix_memalign, int, + (void **memptr, size_t alignment, size_t size) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_memalign, int, + (void **memptr, size_t alignment, size_t size)); +# else +# if @HAVE_POSIX_MEMALIGN@ +_GL_CXXALIAS_SYS (posix_memalign, int, + (void **memptr, size_t alignment, size_t size)); +# endif +# endif +# if @HAVE_POSIX_MEMALIGN@ +_GL_CXXALIASWARN (posix_memalign); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_memalign +# if HAVE_RAW_DECL_POSIX_MEMALIGN +_GL_WARN_ON_USE (posix_memalign, "posix_memalign is not portable - " + "use gnulib module posix_memalign for portability"); +# endif +#endif + #if @GNULIB_POSIX_OPENPT@ /* Return an FD open to the master side of a pseudo-terminal. Flags should include O_RDWR, and may also include O_NOCTTY. */ @@ -497,6 +782,9 @@ _GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); # endif _GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); # endif +# ifndef GNULIB_defined_ptsname_r +# define GNULIB_defined_ptsname_r (!@HAVE_PTSNAME_R@ || @REPLACE_PTSNAME_R@) +# endif _GL_CXXALIASWARN (ptsname_r); #elif defined GNULIB_POSIXCHECK # undef ptsname_r @@ -514,12 +802,78 @@ _GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - " # endif _GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (putenv, int, (char *string)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putenv +# define putenv _putenv +# endif +_GL_CXXALIAS_MDA (putenv, int, (char *string)); +# else +_GL_CXXALIAS_SYS (putenv, int, (char *string)); +# endif +_GL_CXXALIASWARN (putenv); +#elif @GNULIB_MDA_PUTENV@ +/* On native Windows, map 'putenv' to '_putenv', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::putenv always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putenv +# define putenv _putenv +# endif +/* Need to cast, because on mingw, the parameter is either + 'const char *string' or 'char *string'. */ +_GL_CXXALIAS_MDA_CAST (putenv, int, (char *string)); # else _GL_CXXALIAS_SYS (putenv, int, (char *string)); # endif _GL_CXXALIASWARN (putenv); #endif +#if @GNULIB_QSORT_R@ +/* Sort an array of NMEMB elements, starting at address BASE, each element + occupying SIZE bytes, in ascending order according to the comparison + function COMPARE. */ +# ifdef __cplusplus +extern "C" { +# endif +# if !GNULIB_defined_qsort_r_fn_types +typedef int (*_gl_qsort_r_compar_fn) (void const *, void const *, void *); +# define GNULIB_defined_qsort_r_fn_types 1 +# endif +# ifdef __cplusplus +} +# endif +# if @REPLACE_QSORT_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef qsort_r +# define qsort_r rpl_qsort_r +# endif +_GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, + _gl_qsort_r_compar_fn compare, + void *arg) _GL_ARG_NONNULL ((1, 4))); +_GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, + _gl_qsort_r_compar_fn compare, + void *arg)); +# else +# if !@HAVE_QSORT_R@ +_GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, + _gl_qsort_r_compar_fn compare, + void *arg) _GL_ARG_NONNULL ((1, 4))); +# endif +_GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, + _gl_qsort_r_compar_fn compare, + void *arg)); +# endif +_GL_CXXALIASWARN (qsort_r); +#elif defined GNULIB_POSIXCHECK +# undef qsort_r +# if HAVE_RAW_DECL_QSORT_R +_GL_WARN_ON_USE (qsort_r, "qsort_r is not portable - " + "use gnulib module qsort_r for portability"); +# endif +#endif + #if @GNULIB_RANDOM_R@ # if !@HAVE_RANDOM_R@ @@ -531,10 +885,21 @@ _GL_CXXALIASWARN (putenv); #if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ +# if @REPLACE_RANDOM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef random +# define random rpl_random +# endif +_GL_FUNCDECL_RPL (random, long, (void)); +_GL_CXXALIAS_RPL (random, long, (void)); +# else +# if !@HAVE_RANDOM@ _GL_FUNCDECL_SYS (random, long, (void)); +# endif +/* Need to cast, because on Haiku, the return type is + int. */ +_GL_CXXALIAS_SYS_CAST (random, long, (void)); # endif -_GL_CXXALIAS_SYS (random, long, (void)); _GL_CXXALIASWARN (random); #elif defined GNULIB_POSIXCHECK # undef random @@ -545,10 +910,21 @@ _GL_WARN_ON_USE (random, "random is unportable - " #endif #if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ +# if @REPLACE_RANDOM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef srandom +# define srandom rpl_srandom +# endif +_GL_FUNCDECL_RPL (srandom, void, (unsigned int seed)); +_GL_CXXALIAS_RPL (srandom, void, (unsigned int seed)); +# else +# if !@HAVE_RANDOM@ _GL_FUNCDECL_SYS (srandom, void, (unsigned int seed)); +# endif +/* Need to cast, because on FreeBSD, the first parameter is + unsigned long seed. */ +_GL_CXXALIAS_SYS_CAST (srandom, void, (unsigned int seed)); # endif -_GL_CXXALIAS_SYS (srandom, void, (unsigned int seed)); _GL_CXXALIASWARN (srandom); #elif defined GNULIB_POSIXCHECK # undef srandom @@ -559,31 +935,56 @@ _GL_WARN_ON_USE (srandom, "srandom is unportable - " #endif #if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ +# if @REPLACE_INITSTATE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef initstate +# define initstate rpl_initstate +# endif +_GL_FUNCDECL_RPL (initstate, char *, + (unsigned int seed, char *buf, size_t buf_size) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (initstate, char *, + (unsigned int seed, char *buf, size_t buf_size)); +# else +# if !@HAVE_INITSTATE@ || !@HAVE_DECL_INITSTATE@ _GL_FUNCDECL_SYS (initstate, char *, (unsigned int seed, char *buf, size_t buf_size) _GL_ARG_NONNULL ((2))); +# endif +/* Need to cast, because on FreeBSD, the first parameter is + unsigned long seed. */ +_GL_CXXALIAS_SYS_CAST (initstate, char *, + (unsigned int seed, char *buf, size_t buf_size)); # endif -_GL_CXXALIAS_SYS (initstate, char *, - (unsigned int seed, char *buf, size_t buf_size)); _GL_CXXALIASWARN (initstate); #elif defined GNULIB_POSIXCHECK # undef initstate -# if HAVE_RAW_DECL_INITSTATE_R +# if HAVE_RAW_DECL_INITSTATE _GL_WARN_ON_USE (initstate, "initstate is unportable - " "use gnulib module random for portability"); # endif #endif #if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ +# if @REPLACE_SETSTATE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setstate +# define setstate rpl_setstate +# endif +_GL_FUNCDECL_RPL (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (setstate, char *, (char *arg_state)); +# else +# if !@HAVE_SETSTATE@ || !@HAVE_DECL_SETSTATE@ _GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on Mac OS X 10.13, HP-UX, Solaris the first parameter + is const char *arg_state. */ +_GL_CXXALIAS_SYS_CAST (setstate, char *, (char *arg_state)); # endif -_GL_CXXALIAS_SYS (setstate, char *, (char *arg_state)); _GL_CXXALIASWARN (setstate); #elif defined GNULIB_POSIXCHECK # undef setstate -# if HAVE_RAW_DECL_SETSTATE_R +# if HAVE_RAW_DECL_SETSTATE _GL_WARN_ON_USE (setstate, "setstate is unportable - " "use gnulib module random for portability"); # endif @@ -664,9 +1065,11 @@ _GL_FUNCDECL_SYS (initstate_r, int, struct random_data *rand_state) _GL_ARG_NONNULL ((2, 4))); # endif -_GL_CXXALIAS_SYS (initstate_r, int, - (unsigned int seed, char *buf, size_t buf_size, - struct random_data *rand_state)); +/* Need to cast, because on Haiku, the third parameter is + unsigned long buf_size. */ +_GL_CXXALIAS_SYS_CAST (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state)); # endif _GL_CXXALIASWARN (initstate_r); #elif defined GNULIB_POSIXCHECK @@ -694,8 +1097,10 @@ _GL_FUNCDECL_SYS (setstate_r, int, (char *arg_state, struct random_data *rand_state) _GL_ARG_NONNULL ((1, 2))); # endif -_GL_CXXALIAS_SYS (setstate_r, int, - (char *arg_state, struct random_data *rand_state)); +/* Need to cast, because on Haiku, the first parameter is + void *arg_state. */ +_GL_CXXALIAS_SYS_CAST (setstate_r, int, + (char *arg_state, struct random_data *rand_state)); # endif _GL_CXXALIASWARN (setstate_r); #elif defined GNULIB_POSIXCHECK @@ -708,23 +1113,67 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " #if @GNULIB_REALLOC_POSIX@ -# if @REPLACE_REALLOC@ +# if (@GNULIB_REALLOC_POSIX@ && @REPLACE_REALLOC_FOR_REALLOC_POSIX@) \ + || (@GNULIB_REALLOC_GNU@ && @REPLACE_REALLOC_FOR_REALLOC_GNU@) # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ || _GL_USE_STDLIB_ALLOC) # undef realloc # define realloc rpl_realloc # endif -_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size)); +_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size) + _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); # else +# if __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size) + _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (realloc); -#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC -# undef realloc +# endif +#else +# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined realloc +/* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */ +_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size) + _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC +# undef realloc /* Assume realloc is always declared. */ _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " "use gnulib module realloc-posix for portability"); +# endif +#endif + + +#if @GNULIB_REALLOCARRAY@ +# if @REPLACE_REALLOCARRAY@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef reallocarray +# define reallocarray rpl_reallocarray +# endif +_GL_FUNCDECL_RPL (reallocarray, void *, + (void *ptr, size_t nmemb, size_t size)); +_GL_CXXALIAS_RPL (reallocarray, void *, + (void *ptr, size_t nmemb, size_t size)); +# else +# if ! @HAVE_REALLOCARRAY@ +_GL_FUNCDECL_SYS (reallocarray, void *, + (void *ptr, size_t nmemb, size_t size)); +# endif +_GL_CXXALIAS_SYS (reallocarray, void *, + (void *ptr, size_t nmemb, size_t size)); +# endif +_GL_CXXALIASWARN (reallocarray); +#elif defined GNULIB_POSIXCHECK +# undef reallocarray +# if HAVE_RAW_DECL_REALLOCARRAY +_GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - " + "use gnulib module reallocarray for portability"); +# endif #endif #if @GNULIB_REALPATH@ @@ -732,15 +1181,19 @@ _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define realpath rpl_realpath # endif -_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved)); +_GL_FUNCDECL_RPL (realpath, char *, + (const char *restrict name, char *restrict resolved) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (realpath, char *, + (const char *restrict name, char *restrict resolved)); # else # if !@HAVE_REALPATH@ -_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved) - _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_SYS (realpath, char *, + (const char *restrict name, char *restrict resolved) + _GL_ARG_NONNULL ((1))); # endif -_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved)); +_GL_CXXALIAS_SYS (realpath, char *, + (const char *restrict name, char *restrict resolved)); # endif _GL_CXXALIASWARN (realpath); #elif defined GNULIB_POSIXCHECK @@ -822,17 +1275,24 @@ _GL_WARN_ON_USE (setenv, "setenv is unportable - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define strtod rpl_strtod # endif -_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp)); +# define GNULIB_defined_strtod_function 1 +_GL_FUNCDECL_RPL (strtod, double, + (const char *restrict str, char **restrict endp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtod, double, + (const char *restrict str, char **restrict endp)); # else # if !@HAVE_STRTOD@ -_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp) - _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_SYS (strtod, double, + (const char *restrict str, char **restrict endp) + _GL_ARG_NONNULL ((1))); # endif -_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp)); +_GL_CXXALIAS_SYS (strtod, double, + (const char *restrict str, char **restrict endp)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (strtod); +# endif #elif defined GNULIB_POSIXCHECK # undef strtod # if HAVE_RAW_DECL_STRTOD @@ -841,6 +1301,77 @@ _GL_WARN_ON_USE (strtod, "strtod is unportable - " # endif #endif +#if @GNULIB_STRTOLD@ + /* Parse a 'long double' from STRING, updating ENDP if appropriate. */ +# if @REPLACE_STRTOLD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtold rpl_strtold +# endif +# define GNULIB_defined_strtold_function 1 +_GL_FUNCDECL_RPL (strtold, long double, + (const char *restrict str, char **restrict endp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtold, long double, + (const char *restrict str, char **restrict endp)); +# else +# if !@HAVE_STRTOLD@ +_GL_FUNCDECL_SYS (strtold, long double, + (const char *restrict str, char **restrict endp) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtold, long double, + (const char *restrict str, char **restrict endp)); +# endif +_GL_CXXALIASWARN (strtold); +#elif defined GNULIB_POSIXCHECK +# undef strtold +# if HAVE_RAW_DECL_STRTOLD +_GL_WARN_ON_USE (strtold, "strtold is unportable - " + "use gnulib module strtold for portability"); +# endif +#endif + +#if @GNULIB_STRTOL@ +/* Parse a signed integer whose textual representation starts at STRING. + The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, + it may be decimal or octal (with prefix "0") or hexadecimal (with prefix + "0x"). + If ENDPTR is not NULL, the address of the first byte after the integer is + stored in *ENDPTR. + Upon overflow, the return value is LONG_MAX or LONG_MIN, and errno is set + to ERANGE. */ +# if @REPLACE_STRTOL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtol rpl_strtol +# endif +# define GNULIB_defined_strtol_function 1 +_GL_FUNCDECL_RPL (strtol, long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtol, long, + (const char *restrict string, char **restrict endptr, + int base)); +# else +# if !@HAVE_STRTOL@ +_GL_FUNCDECL_SYS (strtol, long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtol, long, + (const char *restrict string, char **restrict endptr, + int base)); +# endif +_GL_CXXALIASWARN (strtol); +#elif defined GNULIB_POSIXCHECK +# undef strtol +# if HAVE_RAW_DECL_STRTOL +_GL_WARN_ON_USE (strtol, "strtol is unportable - " + "use gnulib module strtol for portability"); +# endif +#endif + #if @GNULIB_STRTOLL@ /* Parse a signed integer whose textual representation starts at STRING. The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, @@ -850,13 +1381,29 @@ _GL_WARN_ON_USE (strtod, "strtod is unportable - " stored in *ENDPTR. Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set to ERANGE. */ -# if !@HAVE_STRTOLL@ +# if @REPLACE_STRTOLL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtoll rpl_strtoll +# endif +# define GNULIB_defined_strtoll_function 1 +_GL_FUNCDECL_RPL (strtoll, long long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoll, long long, + (const char *restrict string, char **restrict endptr, + int base)); +# else +# if !@HAVE_STRTOLL@ _GL_FUNCDECL_SYS (strtoll, long long, - (const char *string, char **endptr, int base) + (const char *restrict string, char **restrict endptr, + int base) _GL_ARG_NONNULL ((1))); -# endif +# endif _GL_CXXALIAS_SYS (strtoll, long long, - (const char *string, char **endptr, int base)); + (const char *restrict string, char **restrict endptr, + int base)); +# endif _GL_CXXALIASWARN (strtoll); #elif defined GNULIB_POSIXCHECK # undef strtoll @@ -866,6 +1413,46 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - " # endif #endif +#if @GNULIB_STRTOUL@ +/* Parse an unsigned integer whose textual representation starts at STRING. + The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, + it may be decimal or octal (with prefix "0") or hexadecimal (with prefix + "0x"). + If ENDPTR is not NULL, the address of the first byte after the integer is + stored in *ENDPTR. + Upon overflow, the return value is ULONG_MAX, and errno is set to ERANGE. */ +# if @REPLACE_STRTOUL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtoul rpl_strtoul +# endif +# define GNULIB_defined_strtoul_function 1 +_GL_FUNCDECL_RPL (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base)); +# else +# if !@HAVE_STRTOUL@ +_GL_FUNCDECL_SYS (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoul, unsigned long, + (const char *restrict string, char **restrict endptr, + int base)); +# endif +_GL_CXXALIASWARN (strtoul); +#elif defined GNULIB_POSIXCHECK +# undef strtoul +# if HAVE_RAW_DECL_STRTOUL +_GL_WARN_ON_USE (strtoul, "strtoul is unportable - " + "use gnulib module strtoul for portability"); +# endif +#endif + #if @GNULIB_STRTOULL@ /* Parse an unsigned integer whose textual representation starts at STRING. The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, @@ -875,13 +1462,29 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - " stored in *ENDPTR. Upon overflow, the return value is ULLONG_MAX, and errno is set to ERANGE. */ -# if !@HAVE_STRTOULL@ +# if @REPLACE_STRTOULL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtoull rpl_strtoull +# endif +# define GNULIB_defined_strtoull_function 1 +_GL_FUNCDECL_RPL (strtoull, unsigned long long, + (const char *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtoull, unsigned long long, + (const char *restrict string, char **restrict endptr, + int base)); +# else +# if !@HAVE_STRTOULL@ _GL_FUNCDECL_SYS (strtoull, unsigned long long, - (const char *string, char **endptr, int base) + (const char *restrict string, char **restrict endptr, + int base) _GL_ARG_NONNULL ((1))); -# endif +# endif _GL_CXXALIAS_SYS (strtoull, unsigned long long, - (const char *string, char **endptr, int base)); + (const char *restrict string, char **restrict endptr, + int base)); +# endif _GL_CXXALIASWARN (strtoull); #elif defined GNULIB_POSIXCHECK # undef strtoull @@ -945,7 +1548,9 @@ _GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc)); # else _GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wctomb); +# endif #endif diff --git a/gl/str-two-way.h b/gl/str-two-way.h index 707145db..b00017c0 100644 --- a/gl/str-two-way.h +++ b/gl/str-two-way.h @@ -1,24 +1,24 @@ /* Byte-wise substring search, using the Two-Way algorithm. - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Eric Blake , 2008. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Before including this file, you need to include and , and define: - RESULT_TYPE A macro that expands to the return type. + RETURN_TYPE A macro that expands to the return type. AVAILABLE(h, h_l, j, n_l) A macro that returns nonzero if there are at least N_L bytes left starting at H[J]. @@ -49,9 +49,9 @@ character shift table similar to the Boyer-Moore algorithm to achieve improved (potentially sub-linear) performance. - See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260, - http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm, - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.6641&rep=rep1&type=pdf + See https://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260, + https://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm, + https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.6641&rep=rep1&type=pdf */ /* Point at which computing a bad-byte shift table is likely to be @@ -231,7 +231,7 @@ critical_factorization (const unsigned char *needle, size_t needle_len, most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */ -static RETURN_TYPE +static RETURN_TYPE _GL_ATTRIBUTE_PURE two_way_short_needle (const unsigned char *haystack, size_t haystack_len, const unsigned char *needle, size_t needle_len) { @@ -325,7 +325,7 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and sublinear performance is not possible. */ -static RETURN_TYPE +static RETURN_TYPE _GL_ATTRIBUTE_PURE two_way_long_needle (const unsigned char *haystack, size_t haystack_len, const unsigned char *needle, size_t needle_len) { diff --git a/gl/strcasecmp.c b/gl/strcasecmp.c index 0f0a742f..a85a2b10 100644 --- a/gl/strcasecmp.c +++ b/gl/strcasecmp.c @@ -1,18 +1,18 @@ /* Case-insensitive string comparison function. - Copyright (C) 1998-1999, 2005-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1998-1999, 2005-2007, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -58,5 +58,5 @@ strcasecmp (const char *s1, const char *s2) /* On machines where 'char' and 'int' are types of the same size, the difference of two 'unsigned char' values - including the sign bit - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); + return _GL_CMP (c1, c2); } diff --git a/gl/strcasestr.c b/gl/strcasestr.c index 53474a45..b36f4091 100644 --- a/gl/strcasestr.c +++ b/gl/strcasestr.c @@ -1,19 +1,19 @@ /* Case-insensitive searching in a string. - Copyright (C) 2005-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2005. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/streq.h b/gl/streq.h index 12c1867c..49f73c1b 100644 --- a/gl/streq.h +++ b/gl/streq.h @@ -1,18 +1,18 @@ /* Optimized string comparison. - Copyright (C) 2001-2002, 2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2001-2002, 2007, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible . */ @@ -29,7 +29,7 @@ /* Help GCC to generate good code for string comparisons with immediate strings. */ -#if defined (__GNUC__) && defined (__OPTIMIZE__) +#if (defined __GNUC__ || defined __clang__) && defined __OPTIMIZE__ static inline int streq9 (const char *s1, const char *s2) diff --git a/gl/strerror-override.c b/gl/strerror-override.c index d0ed2fb8..6be1afdc 100644 --- a/gl/strerror-override.c +++ b/gl/strerror-override.c @@ -1,19 +1,19 @@ /* strerror-override.c --- POSIX compatible system error routine - Copyright (C) 2010-2013 Free Software Foundation, Inc. + Copyright (C) 2010-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible , 2010. */ @@ -29,6 +29,8 @@ # endif #endif +#if !GNULIB_defined_strerror_override_macro + /* If ERRNUM maps to an errno value defined by gnulib, return a string describing the error. Otherwise return NULL. */ const char * @@ -37,12 +39,12 @@ strerror_override (int errnum) /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ switch (errnum) { -#if REPLACE_STRERROR_0 +# if REPLACE_STRERROR_0 case 0: return "Success"; -#endif +# endif -#if GNULIB_defined_ESOCK /* native Windows platforms with older */ +# if GNULIB_defined_ESOCK /* native Windows platforms with older */ case EINPROGRESS: return "Operation now in progress"; case EALREADY: @@ -89,8 +91,8 @@ strerror_override (int errnum) return "No route to host"; case EWOULDBLOCK: return "Operation would block"; -#endif -#if GNULIB_defined_ESTREAMS /* native Windows platforms with older */ +# endif +# if GNULIB_defined_ESTREAMS /* native Windows platforms with older */ case ETXTBSY: return "Text file busy"; case ENODATA: @@ -103,8 +105,8 @@ strerror_override (int errnum) return "Timer expired"; case EOTHER: return "Other error"; -#endif -#if GNULIB_defined_EWINSOCK /* native Windows platforms */ +# endif +# if GNULIB_defined_EWINSOCK /* native Windows platforms */ case ESOCKTNOSUPPORT: return "Socket type not supported"; case EPFNOSUPPORT: @@ -125,7 +127,7 @@ strerror_override (int errnum) return "Stale NFS file handle"; case EREMOTE: return "Object is remote"; -# if HAVE_WINSOCK2_H +# if HAVE_WINSOCK2_H /* WSA_INVALID_HANDLE maps to EBADF */ /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ /* WSA_INVALID_PARAMETER maps to EINVAL */ @@ -213,90 +215,92 @@ strerror_override (int errnum) case WSANO_DATA: return "Valid name, no data record of requested type"; /* WSA_QOS_* omitted */ +# endif # endif -#endif -#if GNULIB_defined_ENOMSG +# if GNULIB_defined_ENOMSG case ENOMSG: return "No message of desired type"; -#endif +# endif -#if GNULIB_defined_EIDRM +# if GNULIB_defined_EIDRM case EIDRM: return "Identifier removed"; -#endif +# endif -#if GNULIB_defined_ENOLINK +# if GNULIB_defined_ENOLINK case ENOLINK: return "Link has been severed"; -#endif +# endif -#if GNULIB_defined_EPROTO +# if GNULIB_defined_EPROTO case EPROTO: return "Protocol error"; -#endif +# endif -#if GNULIB_defined_EMULTIHOP +# if GNULIB_defined_EMULTIHOP case EMULTIHOP: return "Multihop attempted"; -#endif +# endif -#if GNULIB_defined_EBADMSG +# if GNULIB_defined_EBADMSG case EBADMSG: return "Bad message"; -#endif +# endif -#if GNULIB_defined_EOVERFLOW +# if GNULIB_defined_EOVERFLOW case EOVERFLOW: return "Value too large for defined data type"; -#endif +# endif -#if GNULIB_defined_ENOTSUP +# if GNULIB_defined_ENOTSUP case ENOTSUP: return "Not supported"; -#endif +# endif -#if GNULIB_defined_ENETRESET +# if GNULIB_defined_ENETRESET case ENETRESET: return "Network dropped connection on reset"; -#endif +# endif -#if GNULIB_defined_ECONNABORTED +# if GNULIB_defined_ECONNABORTED case ECONNABORTED: return "Software caused connection abort"; -#endif +# endif -#if GNULIB_defined_ESTALE +# if GNULIB_defined_ESTALE case ESTALE: return "Stale NFS file handle"; -#endif +# endif -#if GNULIB_defined_EDQUOT +# if GNULIB_defined_EDQUOT case EDQUOT: return "Disk quota exceeded"; -#endif +# endif -#if GNULIB_defined_ECANCELED +# if GNULIB_defined_ECANCELED case ECANCELED: return "Operation canceled"; -#endif +# endif -#if GNULIB_defined_EOWNERDEAD +# if GNULIB_defined_EOWNERDEAD case EOWNERDEAD: return "Owner died"; -#endif +# endif -#if GNULIB_defined_ENOTRECOVERABLE +# if GNULIB_defined_ENOTRECOVERABLE case ENOTRECOVERABLE: return "State not recoverable"; -#endif +# endif -#if GNULIB_defined_EILSEQ +# if GNULIB_defined_EILSEQ case EILSEQ: return "Invalid or incomplete multibyte or wide character"; -#endif +# endif default: return NULL; } } + +#endif diff --git a/gl/strerror-override.h b/gl/strerror-override.h index 3b8f24b9..d010d27c 100644 --- a/gl/strerror-override.h +++ b/gl/strerror-override.h @@ -1,19 +1,19 @@ /* strerror-override.h --- POSIX compatible system error routine - Copyright (C) 2010-2013 Free Software Foundation, Inc. + Copyright (C) 2010-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _GL_STRERROR_OVERRIDE_H # define _GL_STRERROR_OVERRIDE_H @@ -48,9 +48,10 @@ || GNULIB_defined_EOWNERDEAD \ || GNULIB_defined_ENOTRECOVERABLE \ || GNULIB_defined_EILSEQ -extern const char *strerror_override (int errnum); +extern const char *strerror_override (int errnum) _GL_ATTRIBUTE_CONST; # else # define strerror_override(ignored) NULL +# define GNULIB_defined_strerror_override_macro 1 # endif #endif /* _GL_STRERROR_OVERRIDE_H */ diff --git a/gl/strerror.c b/gl/strerror.c index 80a2f2ee..67c5216e 100644 --- a/gl/strerror.c +++ b/gl/strerror.c @@ -1,19 +1,19 @@ /* strerror.c --- POSIX compatible system error routine - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -66,5 +66,6 @@ strerror (int n) if (sizeof buf <= len) abort (); - return memcpy (buf, msg, len + 1); + memcpy (buf, msg, len + 1); + return buf; } diff --git a/gl/string.in.h b/gl/string.in.h index d7a6c9c9..3996da9f 100644 --- a/gl/string.in.h +++ b/gl/string.in.h @@ -1,30 +1,46 @@ /* A GNU-like . - Copyright (C) 1995-1996, 2001-2013 Free Software Foundation, Inc. + Copyright (C) 1995-1996, 2001-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ - -#ifndef _@GUARD_PREFIX@_STRING_H + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ +#if defined _GL_ALREADY_INCLUDING_STRING_H +/* Special invocation convention: + - On OS X/NetBSD we have a sequence of nested includes + -> -> "string.h" + In this situation system _chk variants due to -D_FORTIFY_SOURCE + might be used after any replacements defined here. */ + +#@INCLUDE_NEXT@ @NEXT_STRING_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_STRING_H + +#define _GL_ALREADY_INCLUDING_STRING_H + /* The include_next requires a split double-inclusion guard. */ #@INCLUDE_NEXT@ @NEXT_STRING_H@ +#undef _GL_ALREADY_INCLUDING_STRING_H + #ifndef _@GUARD_PREFIX@_STRING_H #define _@GUARD_PREFIX@_STRING_H @@ -36,14 +52,6 @@ # include #endif -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The attribute __pure__ was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ -#endif - /* NetBSD 5.0 declares strsignal in , not in . */ /* But in any case avoid namespace pollution on glibc systems. */ #if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \ @@ -51,12 +59,115 @@ # include #endif +/* AIX 7.2 declares ffsl and ffsll in , not in . */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if ((@GNULIB_FFSL@ || @GNULIB_FFSLL@ || defined GNULIB_POSIXCHECK) \ + && defined _AIX) \ + && ! defined __GLIBC__ +# include +#endif + +/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers + that can be freed by passing them as the Ith argument to the + function F. */ +#ifndef _GL_ATTRIBUTE_DEALLOC +# if __GNUC__ >= 11 +# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) +# else +# define _GL_ATTRIBUTE_DEALLOC(f, i) +# endif +#endif + +/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that + can be freed via 'free'; it can be used only after declaring 'free'. */ +/* Applies to: functions. Cannot be used on inline functions. */ +#ifndef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1) +#endif + +/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly + allocated memory. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_MALLOC +# if __GNUC__ >= 3 || defined __clang__ +# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define _GL_ATTRIBUTE_MALLOC +# endif +#endif + +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The attribute __pure__ was added in gcc 2.96. */ +#ifndef _GL_ATTRIBUTE_PURE +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define _GL_ATTRIBUTE_PURE /* empty */ +# endif +#endif + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ /* The definition of _GL_ARG_NONNULL is copied here. */ /* The definition of _GL_WARN_ON_USE is copied here. */ +/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though may not have + been included yet. */ +#if @GNULIB_FREE_POSIX@ +# if (@REPLACE_FREE@ && !defined free \ + && !(defined __cplusplus && defined GNULIB_NAMESPACE)) +/* We can't do '#define free rpl_free' here. */ +_GL_EXTERN_C void rpl_free (void *); +# undef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1) +# else +# if defined _MSC_VER && !defined free +_GL_EXTERN_C +# if defined _DLL + __declspec (dllimport) +# endif + void __cdecl free (void *); +# else +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void free (void *) throw (); +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +# endif +#else +# if defined _MSC_VER && !defined free +_GL_EXTERN_C +# if defined _DLL + __declspec (dllimport) +# endif + void __cdecl free (void *); +# else +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void free (void *) throw (); +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +#endif + +/* Clear a block of memory. The compiler will not delete a call to + this function, even if the block is dead after the call. */ +#if @GNULIB_EXPLICIT_BZERO@ +# if ! @HAVE_EXPLICIT_BZERO@ +_GL_FUNCDECL_SYS (explicit_bzero, void, + (void *__dest, size_t __n) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n)); +_GL_CXXALIASWARN (explicit_bzero); +#elif defined GNULIB_POSIXCHECK +# undef explicit_bzero +# if HAVE_RAW_DECL_EXPLICIT_BZERO +_GL_WARN_ON_USE (explicit_bzero, "explicit_bzero is unportable - " + "use gnulib module explicit_bzero for portability"); +# endif +#endif /* Find the index of the least-significant set bit. */ #if @GNULIB_FFSL@ @@ -75,10 +186,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 @@ -88,10 +207,30 @@ _GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module"); #endif +#if @GNULIB_MDA_MEMCCPY@ +/* On native Windows, map 'memccpy' to '_memccpy', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::memccpy always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef memccpy +# define memccpy _memccpy +# endif +_GL_CXXALIAS_MDA (memccpy, void *, + (void *dest, const void *src, int c, size_t n)); +# else +_GL_CXXALIAS_SYS (memccpy, void *, + (void *dest, const void *src, int c, size_t n)); +# endif +_GL_CXXALIASWARN (memccpy); +#endif + + /* Return the first instance of C within N bytes of S, or NULL. */ #if @GNULIB_MEMCHR@ # if @REPLACE_MEMCHR@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef memchr # define memchr rpl_memchr # endif _GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n) @@ -99,11 +238,6 @@ _GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); # else -# if ! @HAVE_MEMCHR@ -_GL_FUNCDECL_SYS (memchr, void *, (void const *__s, int __c, size_t __n) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif /* On some systems, this function is defined as an overloaded function: extern "C" { const void * std::memchr (const void *, int, size_t); } extern "C++" { void * std::memchr (void *, int, size_t); } */ @@ -112,11 +246,12 @@ _GL_CXXALIAS_SYS_CAST2 (memchr, void const *, (void const *__s, int __c, size_t __n)); # endif # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n) throw ()); _GL_CXXALIASWARN1 (memchr, void const *, - (void const *__s, int __c, size_t __n)); -# else + (void const *__s, int __c, size_t __n) throw ()); +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (memchr); # endif #elif defined GNULIB_POSIXCHECK @@ -197,9 +332,10 @@ _GL_CXXALIAS_SYS_CAST2 (memrchr, void *, (void const *, int, size_t), void const *, (void const *, int, size_t)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t)); -_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t) throw ()); +_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t) throw ()); # else _GL_CXXALIASWARN (memrchr); # endif @@ -227,9 +363,11 @@ _GL_CXXALIAS_SYS_CAST2 (rawmemchr, void *, (void const *__s, int __c_in), void const *, (void const *__s, int __c_in)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in)); -_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in) throw ()); +_GL_CXXALIASWARN1 (rawmemchr, void const *, + (void const *__s, int __c_in) throw ()); # else _GL_CXXALIASWARN (rawmemchr); # endif @@ -299,9 +437,11 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " GB18030 and the character to be searched is a digit. */ # undef strchr /* Assume strchr is always declared. */ -_GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings " - "in some multibyte locales - " - "use mbschr if you care about internationalization"); +_GL_WARN_ON_USE_CXX (strchr, + const char *, char *, (const char *, int), + "strchr cannot work correctly on character strings " + "in some multibyte locales - " + "use mbschr if you care about internationalization"); #endif /* Find the first occurrence of C in S or the final NUL byte. */ @@ -329,9 +469,11 @@ _GL_CXXALIAS_SYS_CAST2 (strchrnul, char const *, (char const *__s, int __c_in)); # endif # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in)); -_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in) throw ()); +_GL_CXXALIASWARN1 (strchrnul, char const *, + (char const *__s, int __c_in) throw ()); # else _GL_CXXALIASWARN (strchrnul); # endif @@ -350,24 +492,62 @@ _GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - " # undef strdup # define strdup rpl_strdup # endif -_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_RPL (strdup, char *, + (char const *__s) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (strdup, char *, (char const *__s)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strdup +# define strdup _strdup +# endif +_GL_CXXALIAS_MDA (strdup, char *, (char const *__s)); # else # if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup /* strdup exists as a function and as a macro. Get rid of the macro. */ # undef strdup # endif -# if !(@HAVE_DECL_STRDUP@ || defined strdup) -_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +# if (!@HAVE_DECL_STRDUP@ || __GNUC__ >= 11) && !defined strdup +_GL_FUNCDECL_SYS (strdup, char *, + (char const *__s) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif _GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); # endif _GL_CXXALIASWARN (strdup); -#elif defined GNULIB_POSIXCHECK -# undef strdup -# if HAVE_RAW_DECL_STRDUP +#else +# if __GNUC__ >= 11 && !defined strdup +/* For -Wmismatched-dealloc: Associate strdup with free or rpl_free. */ +_GL_FUNCDECL_SYS (strdup, char *, + (char const *__s) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK +# undef strdup +# if HAVE_RAW_DECL_STRDUP _GL_WARN_ON_USE (strdup, "strdup is unportable - " "use gnulib module strdup for portability"); +# endif +# elif @GNULIB_MDA_STRDUP@ +/* On native Windows, map 'creat' to '_creat', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::strdup always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strdup +# define strdup _strdup +# endif +_GL_CXXALIAS_MDA (strdup, char *, (char const *__s)); +# else +# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup +# undef strdup +# endif +_GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); +# endif +_GL_CXXALIASWARN (strdup); # endif #endif @@ -378,13 +558,18 @@ _GL_WARN_ON_USE (strdup, "strdup is unportable - " # undef strncat # define strncat rpl_strncat # endif -_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n)); +_GL_FUNCDECL_RPL (strncat, char *, + (char *restrict dest, const char *restrict src, size_t n) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strncat, char *, + (char *restrict dest, const char *restrict src, size_t n)); # else -_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n)); +_GL_CXXALIAS_SYS (strncat, char *, + (char *restrict dest, const char *restrict src, size_t n)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (strncat); +# endif #elif defined GNULIB_POSIXCHECK # undef strncat # if HAVE_RAW_DECL_STRNCAT @@ -400,22 +585,35 @@ _GL_WARN_ON_USE (strncat, "strncat is unportable - " # undef strndup # define strndup rpl_strndup # endif -_GL_FUNCDECL_RPL (strndup, char *, (char const *__string, size_t __n) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strndup, char *, (char const *__string, size_t __n)); +_GL_FUNCDECL_RPL (strndup, char *, + (char const *__s, size_t __n) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +_GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n)); # else -# if ! @HAVE_DECL_STRNDUP@ -_GL_FUNCDECL_SYS (strndup, char *, (char const *__string, size_t __n) - _GL_ARG_NONNULL ((1))); +# if !@HAVE_DECL_STRNDUP@ || (__GNUC__ >= 11 && !defined strndup) +_GL_FUNCDECL_SYS (strndup, char *, + (char const *__s, size_t __n) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif -_GL_CXXALIAS_SYS (strndup, char *, (char const *__string, size_t __n)); +_GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t __n)); # endif _GL_CXXALIASWARN (strndup); -#elif defined GNULIB_POSIXCHECK -# undef strndup -# if HAVE_RAW_DECL_STRNDUP +#else +# if __GNUC__ >= 11 && !defined strndup +/* For -Wmismatched-dealloc: Associate strndup with free or rpl_free. */ +_GL_FUNCDECL_SYS (strndup, char *, + (char const *__s, size_t __n) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK +# undef strndup +# if HAVE_RAW_DECL_STRNDUP _GL_WARN_ON_USE (strndup, "strndup is unportable - " "use gnulib module strndup for portability"); +# endif # endif #endif @@ -428,17 +626,17 @@ _GL_WARN_ON_USE (strndup, "strndup is unportable - " # undef strnlen # define strnlen rpl_strnlen # endif -_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__string, size_t __maxlen) +_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__s, size_t __maxlen) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__string, size_t __maxlen)); +_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__s, size_t __maxlen)); # else # if ! @HAVE_DECL_STRNLEN@ -_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__string, size_t __maxlen) +_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__s, size_t __maxlen) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1))); # endif -_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__string, size_t __maxlen)); +_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__s, size_t __maxlen)); # endif _GL_CXXALIASWARN (strnlen); #elif defined GNULIB_POSIXCHECK @@ -475,11 +673,12 @@ _GL_CXXALIAS_SYS_CAST2 (strpbrk, char *, (char const *__s, char const *__accept), const char *, (char const *__s, char const *__accept)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept) throw ()); _GL_CXXALIASWARN1 (strpbrk, char const *, - (char const *__s, char const *__accept)); -# else + (char const *__s, char const *__accept) throw ()); +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (strpbrk); # endif # if defined GNULIB_POSIXCHECK @@ -488,15 +687,19 @@ _GL_CXXALIASWARN (strpbrk); locale encoding is GB18030 and one of the characters to be searched is a digit. */ # undef strpbrk -_GL_WARN_ON_USE (strpbrk, "strpbrk cannot work correctly on character strings " - "in multibyte locales - " - "use mbspbrk if you care about internationalization"); +_GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), + "strpbrk cannot work correctly on character strings " + "in multibyte locales - " + "use mbspbrk if you care about internationalization"); # endif #elif defined GNULIB_POSIXCHECK # undef strpbrk # if HAVE_RAW_DECL_STRPBRK -_GL_WARN_ON_USE (strpbrk, "strpbrk is unportable - " - "use gnulib module strpbrk for portability"); +_GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), + "strpbrk is unportable - " + "use gnulib module strpbrk for portability"); # endif #endif @@ -515,9 +718,11 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " GB18030 and the character to be searched is a digit. */ # undef strrchr /* Assume strrchr is always declared. */ -_GL_WARN_ON_USE (strrchr, "strrchr cannot work correctly on character strings " - "in some multibyte locales - " - "use mbsrchr if you care about internationalization"); +_GL_WARN_ON_USE_CXX (strrchr, + const char *, char *, (const char *, int), + "strrchr cannot work correctly on character strings " + "in some multibyte locales - " + "use mbsrchr if you care about internationalization"); #endif /* Search the next delimiter (char listed in DELIM) starting at *STRINGP. @@ -577,11 +782,13 @@ _GL_CXXALIAS_SYS_CAST2 (strstr, const char *, (const char *haystack, const char *needle)); # endif # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (strstr, char *, + (char *haystack, const char *needle) throw ()); _GL_CXXALIASWARN1 (strstr, const char *, - (const char *haystack, const char *needle)); -# else + (const char *haystack, const char *needle) throw ()); +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (strstr); # endif #elif defined GNULIB_POSIXCHECK @@ -626,10 +833,12 @@ _GL_CXXALIAS_SYS_CAST2 (strcasestr, const char *, (const char *haystack, const char *needle)); # endif # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle)); + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \ + || defined __clang__) +_GL_CXXALIASWARN1 (strcasestr, char *, + (char *haystack, const char *needle) throw ()); _GL_CXXALIASWARN1 (strcasestr, const char *, - (const char *haystack, const char *needle)); + (const char *haystack, const char *needle) throw ()); # else _GL_CXXALIASWARN (strcasestr); # endif @@ -660,7 +869,7 @@ _GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character " This is a variant of strtok() that is multithread-safe. For the POSIX documentation for this function, see: - http://www.opengroup.org/susv3xsh/strtok.html + https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html Caveat: It modifies the original string. Caveat: These functions cannot be used on constant strings. @@ -931,7 +1140,8 @@ _GL_EXTERN_C char * mbssep (char **stringp, const char *delim) Caveat: The identity of the delimiting character is lost. See also mbssep(). */ -_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr) +_GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim, + char **save_ptr) _GL_ARG_NONNULL ((2, 3)); #endif @@ -947,7 +1157,9 @@ _GL_CXXALIAS_RPL (strerror, char *, (int)); # else _GL_CXXALIAS_SYS (strerror, char *, (int)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (strerror); +# endif #elif defined GNULIB_POSIXCHECK # undef strerror /* Assume strerror is always declared. */ @@ -984,6 +1196,60 @@ _GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " # endif #endif +/* Return the name of the system error code ERRNUM. */ +#if @GNULIB_STRERRORNAME_NP@ +# if @REPLACE_STRERRORNAME_NP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strerrorname_np +# define strerrorname_np rpl_strerrorname_np +# endif +_GL_FUNCDECL_RPL (strerrorname_np, const char *, (int errnum)); +_GL_CXXALIAS_RPL (strerrorname_np, const char *, (int errnum)); +# else +# if !@HAVE_STRERRORNAME_NP@ +_GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum)); +# endif +_GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum)); +# endif +_GL_CXXALIASWARN (strerrorname_np); +#elif defined GNULIB_POSIXCHECK +# undef strerrorname_np +# if HAVE_RAW_DECL_STRERRORNAME_NP +_GL_WARN_ON_USE (strerrorname_np, "strerrorname_np is unportable - " + "use gnulib module strerrorname_np for portability"); +# 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 + +/* Return an English description string for the signal number SIG. */ +#if @GNULIB_SIGDESCR_NP@ +# if ! @HAVE_SIGDESCR_NP@ +_GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig)); +# endif +_GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig)); +_GL_CXXALIASWARN (sigdescr_np); +#elif defined GNULIB_POSIXCHECK +# undef sigdescr_np +# if HAVE_RAW_DECL_SIGDESCR_NP +_GL_WARN_ON_USE (sigdescr_np, "sigdescr_np is unportable - " + "use gnulib module sigdescr_np for portability"); +# endif +#endif + #if @GNULIB_STRSIGNAL@ # if @REPLACE_STRSIGNAL@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) @@ -1027,3 +1293,4 @@ _GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " #endif /* _@GUARD_PREFIX@_STRING_H */ #endif /* _@GUARD_PREFIX@_STRING_H */ +#endif diff --git a/gl/strings.in.h b/gl/strings.in.h index 4469f86c..2c31d2e1 100644 --- a/gl/strings.in.h +++ b/gl/strings.in.h @@ -1,19 +1,19 @@ /* A substitute . - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_STRINGS_H diff --git a/gl/stripslash.c b/gl/stripslash.c index 0e452a95..aee89b78 100644 --- a/gl/stripslash.c +++ b/gl/stripslash.c @@ -1,20 +1,20 @@ /* stripslash.c -- remove redundant trailing slashes from a file name - Copyright (C) 1990, 2001, 2003-2006, 2009-2013 Free Software Foundation, + Copyright (C) 1990, 2001, 2003-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/strncasecmp.c b/gl/strncasecmp.c index 35840bc0..35d215b9 100644 --- a/gl/strncasecmp.c +++ b/gl/strncasecmp.c @@ -1,18 +1,18 @@ /* strncasecmp.c -- case insensitive string comparator - Copyright (C) 1998-1999, 2005-2007, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 1998-1999, 2005-2007, 2009-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -58,5 +58,5 @@ strncasecmp (const char *s1, const char *s2, size_t n) /* On machines where 'char' and 'int' are types of the same size, the difference of two 'unsigned char' values - including the sign bit - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); + return _GL_CMP (c1, c2); } diff --git a/gl/strndup.c b/gl/strndup.c deleted file mode 100644 index e60268b8..00000000 --- a/gl/strndup.c +++ /dev/null @@ -1,36 +0,0 @@ -/* A replacement function, for systems that lack strndup. - - Copyright (C) 1996-1998, 2001-2003, 2005-2007, 2009-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#include - -#include - -#include - -char * -strndup (char const *s, size_t n) -{ - size_t len = strnlen (s, n); - char *new = malloc (len + 1); - - if (new == NULL) - return NULL; - - new[len] = '\0'; - return memcpy (new, s, len); -} diff --git a/gl/strnlen.c b/gl/strnlen.c deleted file mode 100644 index 57fdfe77..00000000 --- a/gl/strnlen.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Find the length of STRING, but scan at most MAXLEN characters. - Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. - Written by Simon Josefsson. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#include - -#include - -/* Find the length of STRING, but scan at most MAXLEN characters. - If no '\0' terminator is found in that many characters, return MAXLEN. */ - -size_t -strnlen (const char *string, size_t maxlen) -{ - const char *end = memchr (string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} diff --git a/gl/strsep.c b/gl/strsep.c index c51ac0d4..c05d7ebe 100644 --- a/gl/strsep.c +++ b/gl/strsep.c @@ -1,19 +1,19 @@ -/* Copyright (C) 2004, 2007, 2009-2013 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2007, 2009-2022 Free Software Foundation, Inc. Written by Yoann Vandoorselaere . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include diff --git a/gl/strstr.c b/gl/strstr.c index b91acec7..62369159 100644 --- a/gl/strstr.c +++ b/gl/strstr.c @@ -1,19 +1,19 @@ -/* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2013 Free Software +/* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This particular implementation was written by Eric Blake, 2008. */ @@ -26,10 +26,6 @@ #include -#ifndef _LIBC -# define __builtin_expect(expr, val) (expr) -#endif - #define RETURN_TYPE char * #define AVAILABLE(h, h_l, j, n_l) \ (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ diff --git a/gl/sys-limits.h b/gl/sys-limits.h new file mode 100644 index 00000000..d154f0b2 --- /dev/null +++ b/gl/sys-limits.h @@ -0,0 +1,42 @@ +/* System call limits + + Copyright 2018-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_SYS_LIMITS_H +#define _GL_SYS_LIMITS_H + +#include + +/* Maximum number of bytes to read or write in a single system call. + This can be useful for system calls like sendfile on GNU/Linux, + which do not handle more than MAX_RW_COUNT bytes correctly. + The Linux kernel MAX_RW_COUNT is at least INT_MAX >> 20 << 20, + where the 20 comes from the Hexagon port with 1 MiB pages; use that + as an approximation, as the exact value may not be available to us. + + Using this also works around a serious Linux bug before 2.6.16; see + . + + Using this also works around a Tru64 5.1 bug, where attempting + to read INT_MAX bytes fails with errno == EINVAL. See + . + + Using this is likely to work around similar bugs in other operating + systems. */ + +enum { SYS_BUFSIZE_MAX = INT_MAX >> 20 << 20 }; + +#endif diff --git a/gl/sys_socket.c b/gl/sys_socket.c index 3f017f8f..0bfd60f2 100644 --- a/gl/sys_socket.c +++ b/gl/sys_socket.c @@ -1,3 +1,22 @@ +/* Inline functions for . + + Copyright (C) 2012-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + #include + #define _GL_SYS_SOCKET_INLINE _GL_EXTERN_INLINE #include "sys/socket.h" +typedef int dummy; diff --git a/gl/sys_socket.in.h b/gl/sys_socket.in.h index b4cf0c39..acdf7eee 100644 --- a/gl/sys_socket.in.h +++ b/gl/sys_socket.in.h @@ -1,20 +1,20 @@ /* Provide a sys/socket header file for systems lacking it (read: MinGW) and for systems where it is incomplete. - Copyright (C) 2005-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2022 Free Software Foundation, Inc. Written by Simon Josefsson. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This file is supposed to be used on platforms that lack , on platforms where cannot be included standalone, and on @@ -63,6 +63,9 @@ #ifndef _@GUARD_PREFIX@_SYS_SOCKET_H #define _@GUARD_PREFIX@_SYS_SOCKET_H +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif _GL_INLINE_HEADER_BEGIN #ifndef _GL_SYS_SOCKET_INLINE # define _GL_SYS_SOCKET_INLINE _GL_INLINE @@ -76,7 +79,12 @@ _GL_INLINE_HEADER_BEGIN #if !@HAVE_SA_FAMILY_T@ # if !GNULIB_defined_sa_family_t +/* On OS/2 kLIBC, sa_family_t is unsigned char unless TCPV40HDRS is defined. */ +# if !defined __KLIBC__ || defined TCPV40HDRS typedef unsigned short sa_family_t; +# else +typedef unsigned char sa_family_t; +# endif # define GNULIB_defined_sa_family_t 1 # endif #endif @@ -133,6 +141,15 @@ struct sockaddr_storage # define SHUT_RDWR 2 # endif +# ifdef __VMS /* OpenVMS */ +# ifndef CMSG_SPACE +# define CMSG_SPACE(length) _CMSG_SPACE(length) +# endif +# ifndef CMSG_LEN +# define CMSG_LEN(length) _CMSG_LEN(length) +# endif +# endif + #else # ifdef __CYGWIN__ @@ -152,7 +169,7 @@ struct sockaddr_storage code may not run on older Windows releases then. My Windows 2000 box was not able to run the code, for example. The situation is slightly confusing because - + suggests that getaddrinfo should be available on all Windows releases. */ @@ -178,12 +195,7 @@ struct sockaddr_storage /* Include headers needed by the emulation code. */ # include # include - -# if !GNULIB_defined_socklen_t -typedef int socklen_t; -# define GNULIB_defined_socklen_t 1 -# endif - +/* If these headers don't define socklen_t, does. */ # endif /* Rudimentary 'struct msghdr'; this works as long as you don't try to @@ -198,6 +210,15 @@ struct msghdr { #endif +/* Ensure SO_REUSEPORT is defined. */ +/* For the subtle differences between SO_REUSEPORT and SO_REUSEADDR, see + https://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t + and https://lwn.net/Articles/542629/ + */ +#ifndef SO_REUSEPORT +# define SO_REUSEPORT SO_REUSEADDR +#endif + /* Fix some definitions from . */ #if @HAVE_WINSOCK2_H@ @@ -235,7 +256,7 @@ rpl_fd_isset (SOCKET fd, fd_set * set) # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef close # define close close_used_without_including_unistd_h -# else +# elif !defined __clang__ _GL_WARN_ON_USE (close, "close() used without including "); # endif @@ -320,14 +341,20 @@ _GL_WARN_ON_USE (connect, "connect is not always POSIX compliant - " # define accept rpl_accept # endif _GL_FUNCDECL_RPL (accept, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, + struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); _GL_CXXALIAS_RPL (accept, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, + struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); # else /* Need to cast, because on Solaris 10 systems, the third parameter is - void *addrlen. */ + void *addrlen. */ _GL_CXXALIAS_SYS_CAST (accept, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, + struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); # endif _GL_CXXALIASWARN (accept); #elif @HAVE_WINSOCK2_H@ @@ -378,15 +405,18 @@ _GL_WARN_ON_USE (bind, "bind is not always POSIX compliant - " # define getpeername rpl_getpeername # endif _GL_FUNCDECL_RPL (getpeername, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen) + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen) _GL_ARG_NONNULL ((2, 3))); _GL_CXXALIAS_RPL (getpeername, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); # else /* Need to cast, because on Solaris 10 systems, the third parameter is - void *addrlen. */ + void *addrlen. */ _GL_CXXALIAS_SYS_CAST (getpeername, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); # endif _GL_CXXALIASWARN (getpeername); #elif @HAVE_WINSOCK2_H@ @@ -407,15 +437,18 @@ _GL_WARN_ON_USE (getpeername, "getpeername is not always POSIX compliant - " # define getsockname rpl_getsockname # endif _GL_FUNCDECL_RPL (getsockname, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen) + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen) _GL_ARG_NONNULL ((2, 3))); _GL_CXXALIAS_RPL (getsockname, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); # else /* Need to cast, because on Solaris 10 systems, the third parameter is - void *addrlen. */ + void *addrlen. */ _GL_CXXALIAS_SYS_CAST (getsockname, int, - (int fd, struct sockaddr *addr, socklen_t *addrlen)); + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); # endif _GL_CXXALIASWARN (getsockname); #elif @HAVE_WINSOCK2_H@ @@ -435,16 +468,19 @@ _GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - " # undef getsockopt # define getsockopt rpl_getsockopt # endif -_GL_FUNCDECL_RPL (getsockopt, int, (int fd, int level, int optname, - void *optval, socklen_t *optlen) - _GL_ARG_NONNULL ((4, 5))); -_GL_CXXALIAS_RPL (getsockopt, int, (int fd, int level, int optname, - void *optval, socklen_t *optlen)); +_GL_FUNCDECL_RPL (getsockopt, int, + (int fd, int level, int optname, + void *restrict optval, socklen_t *restrict optlen) + _GL_ARG_NONNULL ((4, 5))); +_GL_CXXALIAS_RPL (getsockopt, int, + (int fd, int level, int optname, + void *restrict optval, socklen_t *restrict optlen)); # else /* Need to cast, because on Solaris 10 systems, the fifth parameter is void *optlen. */ -_GL_CXXALIAS_SYS_CAST (getsockopt, int, (int fd, int level, int optname, - void *optval, socklen_t *optlen)); +_GL_CXXALIAS_SYS_CAST (getsockopt, int, + (int fd, int level, int optname, + void *restrict optval, socklen_t *restrict optlen)); # endif _GL_CXXALIASWARN (getsockopt); #elif @HAVE_WINSOCK2_H@ @@ -491,7 +527,10 @@ _GL_FUNCDECL_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags)); # else -_GL_CXXALIAS_SYS (recv, ssize_t, (int fd, void *buf, size_t len, int flags)); +/* Need to cast, because on HP-UX 11.31 the return type may be + int, + depending on compiler options. */ +_GL_CXXALIAS_SYS_CAST (recv, ssize_t, (int fd, void *buf, size_t len, int flags)); # endif _GL_CXXALIASWARN (recv); #elif @HAVE_WINSOCK2_H@ @@ -517,8 +556,11 @@ _GL_FUNCDECL_RPL (send, ssize_t, _GL_CXXALIAS_RPL (send, ssize_t, (int fd, const void *buf, size_t len, int flags)); # else -_GL_CXXALIAS_SYS (send, ssize_t, - (int fd, const void *buf, size_t len, int flags)); +/* Need to cast, because on HP-UX 11.31 the return type may be + int, + depending on compiler options. */ +_GL_CXXALIAS_SYS_CAST (send, ssize_t, + (int fd, const void *buf, size_t len, int flags)); # endif _GL_CXXALIASWARN (send); #elif @HAVE_WINSOCK2_H@ @@ -539,18 +581,21 @@ _GL_WARN_ON_USE (send, "send is not always POSIX compliant - " # define recvfrom rpl_recvfrom # endif _GL_FUNCDECL_RPL (recvfrom, ssize_t, - (int fd, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) + (int fd, void *restrict buf, size_t len, int flags, + struct sockaddr *restrict from, + socklen_t *restrict fromlen) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (recvfrom, ssize_t, - (int fd, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen)); + (int fd, void *restrict buf, size_t len, int flags, + struct sockaddr *restrict from, + socklen_t *restrict fromlen)); # else /* Need to cast, because on Solaris 10 systems, the sixth parameter is void *fromlen. */ _GL_CXXALIAS_SYS_CAST (recvfrom, ssize_t, - (int fd, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen)); + (int fd, void *restrict buf, size_t len, int flags, + struct sockaddr *restrict from, + socklen_t *restrict fromlen)); # endif _GL_CXXALIASWARN (recvfrom); #elif @HAVE_WINSOCK2_H@ @@ -654,7 +699,7 @@ _GL_WARN_ON_USE (shutdown, "shutdown is not always POSIX compliant - " The flags are a bitmask, possibly including O_CLOEXEC (defined in ) and O_TEXT, O_BINARY (defined in "binary-io.h"). See also the Linux man page at - . */ + . */ # if @HAVE_ACCEPT4@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define accept4 rpl_accept4 diff --git a/gl/sys_stat.in.h b/gl/sys_stat.in.h new file mode 100644 index 00000000..714c3cb1 --- /dev/null +++ b/gl/sys_stat.in.h @@ -0,0 +1,954 @@ +/* Provide a more complete sys/stat.h header file. + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Eric Blake, Paul Eggert, and Jim Meyering. */ + +/* This file is supposed to be used on platforms where is + incomplete. It is intended to provide definitions and prototypes + needed by an application. Start with what the system provides. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_system_sys_stat_h +/* Special invocation convention. */ + +#@INCLUDE_NEXT@ @NEXT_SYS_STAT_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_SYS_STAT_H + +/* Get nlink_t. + May also define off_t to a 64-bit type on native Windows. */ +#include + +/* Get struct timespec. */ +#include + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_SYS_STAT_H@ + +#ifndef _@GUARD_PREFIX@_SYS_STAT_H +#define _@GUARD_PREFIX@_SYS_STAT_H + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Before doing "#define mknod rpl_mknod" below, we need to include all + headers that may declare mknod(). OS/2 kLIBC declares mknod() in + , not in . */ +#ifdef __KLIBC__ +# include +#endif + +/* Before doing "#define mkdir rpl_mkdir" below, we need to include all + headers that may declare mkdir(). Native Windows platforms declare mkdir + in and/or , not in . */ +#if defined _WIN32 && ! defined __CYGWIN__ +# include /* mingw32, mingw64 */ +# include /* mingw64, MSVC 9 */ +#endif + +/* Native Windows platforms declare umask() in . */ +#if 0 && (defined _WIN32 && ! defined __CYGWIN__) +# include +#endif + +/* Large File Support on native Windows. */ +#if @WINDOWS_64_BIT_ST_SIZE@ +# define stat _stati64 +#endif + +/* Optionally, override 'struct stat' on native Windows. */ +#if @GNULIB_OVERRIDES_STRUCT_STAT@ + +# undef stat +# if @GNULIB_STAT@ +# define stat rpl_stat +# else + /* Provoke a clear link error if stat() is used as a function and + module 'stat' is not in use. */ +# define stat stat_used_without_requesting_gnulib_module_stat +# endif + +# if !GNULIB_defined_struct_stat +struct stat +{ + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; +# if 0 + uid_t st_uid; +# else /* uid_t is not defined by default on native Windows. */ + short st_uid; +# endif +# if 0 + gid_t st_gid; +# else /* gid_t is not defined by default on native Windows. */ + short st_gid; +# endif + dev_t st_rdev; + off_t st_size; +# if 0 + blksize_t st_blksize; + blkcnt_t st_blocks; +# endif + +# if @WINDOWS_STAT_TIMESPEC@ + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; +# else + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +# endif +}; +# if @WINDOWS_STAT_TIMESPEC@ +# define st_atime st_atim.tv_sec +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec + /* Indicator, for gnulib internal purposes. */ +# define _GL_WINDOWS_STAT_TIMESPEC 1 +# endif +# define GNULIB_defined_struct_stat 1 +# endif + +/* Other possible values of st_mode. */ +# if 0 +# define _S_IFBLK 0x6000 +# endif +# if 0 +# define _S_IFLNK 0xA000 +# endif +# if 0 +# define _S_IFSOCK 0xC000 +# endif + +#endif + +#ifndef S_IFIFO +# ifdef _S_IFIFO +# define S_IFIFO _S_IFIFO +# endif +#endif + +#ifndef S_IFMT +# define S_IFMT 0170000 +#endif + +#if STAT_MACROS_BROKEN +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISLNK +# undef S_ISNAM +# undef S_ISMPB +# undef S_ISMPC +# undef S_ISNWK +# undef S_ISREG +# undef S_ISSOCK +#endif + +#ifndef S_ISBLK +# ifdef S_IFBLK +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# else +# define S_ISBLK(m) 0 +# endif +#endif + +#ifndef S_ISCHR +# ifdef S_IFCHR +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# else +# define S_ISCHR(m) 0 +# endif +#endif + +#ifndef S_ISDIR +# ifdef S_IFDIR +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# else +# define S_ISDIR(m) 0 +# endif +#endif + +#ifndef S_ISDOOR /* Solaris 2.5 and up */ +# define S_ISDOOR(m) 0 +#endif + +#ifndef S_ISFIFO +# ifdef S_IFIFO +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# else +# define S_ISFIFO(m) 0 +# endif +#endif + +#ifndef S_ISLNK +# ifdef S_IFLNK +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +# else +# define S_ISLNK(m) 0 +# endif +#endif + +#ifndef S_ISMPB /* V7 */ +# ifdef S_IFMPB +# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) +# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) +# else +# define S_ISMPB(m) 0 +# define S_ISMPC(m) 0 +# endif +#endif + +#ifndef S_ISMPX /* AIX */ +# define S_ISMPX(m) 0 +#endif + +#ifndef S_ISNAM /* Xenix */ +# ifdef S_IFNAM +# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) +# else +# define S_ISNAM(m) 0 +# endif +#endif + +#ifndef S_ISNWK /* HP/UX */ +# ifdef S_IFNWK +# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) +# else +# define S_ISNWK(m) 0 +# endif +#endif + +#ifndef S_ISPORT /* Solaris 10 and up */ +# define S_ISPORT(m) 0 +#endif + +#ifndef S_ISREG +# ifdef S_IFREG +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +# else +# define S_ISREG(m) 0 +# endif +#endif + +#ifndef S_ISSOCK +# ifdef S_IFSOCK +# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) +# else +# define S_ISSOCK(m) 0 +# endif +#endif + + +#ifndef S_TYPEISMQ +# define S_TYPEISMQ(p) 0 +#endif + +#ifndef S_TYPEISTMO +# define S_TYPEISTMO(p) 0 +#endif + + +#ifndef S_TYPEISSEM +# ifdef S_INSEM +# define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM) +# else +# define S_TYPEISSEM(p) 0 +# endif +#endif + +#ifndef S_TYPEISSHM +# ifdef S_INSHD +# define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD) +# else +# define S_TYPEISSHM(p) 0 +# endif +#endif + +/* high performance ("contiguous data") */ +#ifndef S_ISCTG +# define S_ISCTG(p) 0 +#endif + +/* Cray DMF (data migration facility): off line, with data */ +#ifndef S_ISOFD +# define S_ISOFD(p) 0 +#endif + +/* Cray DMF (data migration facility): off line, with no data */ +#ifndef S_ISOFL +# define S_ISOFL(p) 0 +#endif + +/* 4.4BSD whiteout */ +#ifndef S_ISWHT +# define S_ISWHT(m) 0 +#endif + +/* If any of the following are undefined, + define them to their de facto standard values. */ +#if !S_ISUID +# define S_ISUID 04000 +#endif +#if !S_ISGID +# define S_ISGID 02000 +#endif + +/* S_ISVTX is a common extension to POSIX. */ +#ifndef S_ISVTX +# define S_ISVTX 01000 +#endif + +#if !S_IRUSR && S_IREAD +# define S_IRUSR S_IREAD +#endif +#if !S_IRUSR +# define S_IRUSR 00400 +#endif +#if !S_IRGRP +# define S_IRGRP (S_IRUSR >> 3) +#endif +#if !S_IROTH +# define S_IROTH (S_IRUSR >> 6) +#endif + +#if !S_IWUSR && S_IWRITE +# define S_IWUSR S_IWRITE +#endif +#if !S_IWUSR +# define S_IWUSR 00200 +#endif +#if !S_IWGRP +# define S_IWGRP (S_IWUSR >> 3) +#endif +#if !S_IWOTH +# define S_IWOTH (S_IWUSR >> 6) +#endif + +#if !S_IXUSR && S_IEXEC +# define S_IXUSR S_IEXEC +#endif +#if !S_IXUSR +# define S_IXUSR 00100 +#endif +#if !S_IXGRP +# define S_IXGRP (S_IXUSR >> 3) +#endif +#if !S_IXOTH +# define S_IXOTH (S_IXUSR >> 6) +#endif + +#if !S_IRWXU +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +#endif +#if !S_IRWXG +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +#endif +#if !S_IRWXO +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#endif + +/* Although S_IXUGO and S_IRWXUGO are not specified by POSIX and are + not implemented in GNU/Linux, some Gnulib-using apps use the macros. */ +#if !S_IXUGO +# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) +#endif +#ifndef S_IRWXUGO +# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) +#endif + +/* Macros for futimens and utimensat. */ +#ifndef UTIME_NOW +# define UTIME_NOW (-1) +# define UTIME_OMIT (-2) +#endif + + +#if @GNULIB_CHMOD@ +# if @REPLACE_CHMOD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chmod +# define chmod rpl_chmod +# endif +_GL_FUNCDECL_RPL (chmod, int, (const char *filename, mode_t mode) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (chmod, int, (const char *filename, mode_t mode)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chmod +# define chmod _chmod +# endif +/* Need to cast, because in mingw the last argument is 'int mode'. */ +_GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode)); +# else +_GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode)); +# endif +_GL_CXXALIASWARN (chmod); +#elif defined GNULIB_POSIXCHECK +# undef chmod +# if HAVE_RAW_DECL_CHMOD +_GL_WARN_ON_USE (chmod, "chmod has portability problems - " + "use gnulib module chmod for portability"); +# endif +#elif @GNULIB_MDA_CHMOD@ +/* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::chmod always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chmod +# define chmod _chmod +# endif +/* Need to cast, because in mingw the last argument is 'int mode'. */ +_GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode)); +# else +_GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode)); +# endif +_GL_CXXALIASWARN (chmod); +#endif + + +#if @GNULIB_FCHMODAT@ +# if @REPLACE_FCHMODAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fchmodat +# define fchmodat rpl_fchmodat +# endif +_GL_FUNCDECL_RPL (fchmodat, int, + (int fd, char const *file, mode_t mode, int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (fchmodat, int, + (int fd, char const *file, mode_t mode, int flag)); +# else +# if !@HAVE_FCHMODAT@ +_GL_FUNCDECL_SYS (fchmodat, int, + (int fd, char const *file, mode_t mode, int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (fchmodat, int, + (int fd, char const *file, mode_t mode, int flag)); +# endif +_GL_CXXALIASWARN (fchmodat); +#elif defined GNULIB_POSIXCHECK +# undef fchmodat +# if HAVE_RAW_DECL_FCHMODAT +_GL_WARN_ON_USE (fchmodat, "fchmodat is not portable - " + "use gnulib module openat for portability"); +# endif +#endif + + +#if @GNULIB_FSTAT@ +# if @REPLACE_FSTAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fstat +# define fstat rpl_fstat +# endif +_GL_FUNCDECL_RPL (fstat, int, (int fd, struct stat *buf) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (fstat, int, (int fd, struct stat *buf)); +# else +_GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (fstat); +# endif +#elif @GNULIB_OVERRIDES_STRUCT_STAT@ +# undef fstat +# define fstat fstat_used_without_requesting_gnulib_module_fstat +#elif @WINDOWS_64_BIT_ST_SIZE@ +/* Above, we define stat to _stati64. */ +# define fstat _fstati64 +#elif defined GNULIB_POSIXCHECK +# undef fstat +# if HAVE_RAW_DECL_FSTAT +_GL_WARN_ON_USE (fstat, "fstat has portability problems - " + "use gnulib module fstat for portability"); +# endif +#endif + + +#if @GNULIB_FSTATAT@ +# if @REPLACE_FSTATAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fstatat +# define fstatat rpl_fstatat +# endif +_GL_FUNCDECL_RPL (fstatat, int, + (int fd, char const *restrict name, struct stat *restrict st, + int flags) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (fstatat, int, + (int fd, char const *restrict name, struct stat *restrict st, + int flags)); +# else +# if !@HAVE_FSTATAT@ +_GL_FUNCDECL_SYS (fstatat, int, + (int fd, char const *restrict name, struct stat *restrict st, + int flags) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (fstatat, int, + (int fd, char const *restrict name, struct stat *restrict st, + int flags)); +# endif +_GL_CXXALIASWARN (fstatat); +#elif @GNULIB_OVERRIDES_STRUCT_STAT@ +# undef fstatat +# define fstatat fstatat_used_without_requesting_gnulib_module_fstatat +#elif defined GNULIB_POSIXCHECK +# undef fstatat +# if HAVE_RAW_DECL_FSTATAT +_GL_WARN_ON_USE (fstatat, "fstatat is not portable - " + "use gnulib module openat for portability"); +# endif +#endif + + +#if @GNULIB_FUTIMENS@ +/* Use the rpl_ prefix also on Solaris <= 9, because on Solaris 9 our futimens + implementation relies on futimesat, which on Solaris 10 makes an invocation + to futimens that is meant to invoke the libc's futimens(), not gnulib's + futimens(). */ +# if @REPLACE_FUTIMENS@ || (!@HAVE_FUTIMENS@ && defined __sun) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef futimens +# define futimens rpl_futimens +# endif +_GL_FUNCDECL_RPL (futimens, int, (int fd, struct timespec const times[2])); +_GL_CXXALIAS_RPL (futimens, int, (int fd, struct timespec const times[2])); +# else +# if !@HAVE_FUTIMENS@ +_GL_FUNCDECL_SYS (futimens, int, (int fd, struct timespec const times[2])); +# endif +_GL_CXXALIAS_SYS (futimens, int, (int fd, struct timespec const times[2])); +# endif +# if @HAVE_FUTIMENS@ +_GL_CXXALIASWARN (futimens); +# endif +#elif defined GNULIB_POSIXCHECK +# undef futimens +# if HAVE_RAW_DECL_FUTIMENS +_GL_WARN_ON_USE (futimens, "futimens is not portable - " + "use gnulib module futimens for portability"); +# endif +#endif + + +#if @GNULIB_GETUMASK@ +# if !@HAVE_GETUMASK@ +_GL_FUNCDECL_SYS (getumask, mode_t, (void)); +# endif +_GL_CXXALIAS_SYS (getumask, mode_t, (void)); +# if @HAVE_GETUMASK@ +_GL_CXXALIASWARN (getumask); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getumask +# if HAVE_RAW_DECL_GETUMASK +_GL_WARN_ON_USE (getumask, "getumask is not portable - " + "use gnulib module getumask for portability"); +# endif +#endif + + +#if @GNULIB_LCHMOD@ +/* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME + denotes a symbolic link. */ +# if !@HAVE_LCHMOD@ || defined __hpux +_GL_FUNCDECL_SYS (lchmod, int, (const char *filename, mode_t mode) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (lchmod, int, (const char *filename, mode_t mode)); +_GL_CXXALIASWARN (lchmod); +#elif defined GNULIB_POSIXCHECK +# undef lchmod +# if HAVE_RAW_DECL_LCHMOD +_GL_WARN_ON_USE (lchmod, "lchmod is unportable - " + "use gnulib module lchmod for portability"); +# endif +#endif + + +#if @GNULIB_LSTAT@ +# if ! @HAVE_LSTAT@ +/* mingw does not support symlinks, therefore it does not have lstat. But + without links, stat does just fine. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define lstat stat +# endif +_GL_CXXALIAS_RPL_1 (lstat, stat, int, + (const char *restrict name, struct stat *restrict buf)); +# elif @REPLACE_LSTAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef lstat +# define lstat rpl_lstat +# endif +_GL_FUNCDECL_RPL (lstat, int, + (const char *restrict name, struct stat *restrict buf) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (lstat, int, + (const char *restrict name, struct stat *restrict buf)); +# else +_GL_CXXALIAS_SYS (lstat, int, + (const char *restrict name, struct stat *restrict buf)); +# endif +# if @HAVE_LSTAT@ +_GL_CXXALIASWARN (lstat); +# endif +#elif @GNULIB_OVERRIDES_STRUCT_STAT@ +# undef lstat +# define lstat lstat_used_without_requesting_gnulib_module_lstat +#elif defined GNULIB_POSIXCHECK +# undef lstat +# if HAVE_RAW_DECL_LSTAT +_GL_WARN_ON_USE (lstat, "lstat is unportable - " + "use gnulib module lstat for portability"); +# endif +#endif + + +#if @GNULIB_MKDIR@ +# if @REPLACE_MKDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif +_GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); +# elif defined _WIN32 && !defined __CYGWIN__ +/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. + Additionally, it declares _mkdir (and depending on compile flags, an + alias mkdir), only in the nonstandard includes and , + which are included above. */ +# if !GNULIB_defined_rpl_mkdir +static int +rpl_mkdir (char const *name, mode_t mode) +{ + return _mkdir (name); +} +# define GNULIB_defined_rpl_mkdir 1 +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif +_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); +# else +_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); +# endif +_GL_CXXALIASWARN (mkdir); +#elif defined GNULIB_POSIXCHECK +# undef mkdir +# if HAVE_RAW_DECL_MKDIR +_GL_WARN_ON_USE (mkdir, "mkdir does not always support two parameters - " + "use gnulib module mkdir for portability"); +# endif +#elif @GNULIB_MDA_MKDIR@ +/* On native Windows, map 'mkdir' to '_mkdir', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::mkdir always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !GNULIB_defined_rpl_mkdir +static int +rpl_mkdir (char const *name, mode_t mode) +{ + return _mkdir (name); +} +# define GNULIB_defined_rpl_mkdir 1 +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkdir +# define mkdir rpl_mkdir +# endif +_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); +# else +_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); +# endif +_GL_CXXALIASWARN (mkdir); +#endif + + +#if @GNULIB_MKDIRAT@ +# if !@HAVE_MKDIRAT@ +_GL_FUNCDECL_SYS (mkdirat, int, (int fd, char const *file, mode_t mode) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (mkdirat, int, (int fd, char const *file, mode_t mode)); +_GL_CXXALIASWARN (mkdirat); +#elif defined GNULIB_POSIXCHECK +# undef mkdirat +# if HAVE_RAW_DECL_MKDIRAT +_GL_WARN_ON_USE (mkdirat, "mkdirat is not portable - " + "use gnulib module openat for portability"); +# endif +#endif + + +#if @GNULIB_MKFIFO@ +# if @REPLACE_MKFIFO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mkfifo +# define mkfifo rpl_mkfifo +# endif +_GL_FUNCDECL_RPL (mkfifo, int, (char const *file, mode_t mode) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mkfifo, int, (char const *file, mode_t mode)); +# else +# if !@HAVE_MKFIFO@ +_GL_FUNCDECL_SYS (mkfifo, int, (char const *file, mode_t mode) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkfifo, int, (char const *file, mode_t mode)); +# endif +_GL_CXXALIASWARN (mkfifo); +#elif defined GNULIB_POSIXCHECK +# undef mkfifo +# if HAVE_RAW_DECL_MKFIFO +_GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - " + "use gnulib module mkfifo for portability"); +# endif +#endif + + +#if @GNULIB_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 +_GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)); +# endif +_GL_CXXALIASWARN (mkfifoat); +#elif defined GNULIB_POSIXCHECK +# undef mkfifoat +# if HAVE_RAW_DECL_MKFIFOAT +_GL_WARN_ON_USE (mkfifoat, "mkfifoat is not portable - " + "use gnulib module mkfifoat for portability"); +# endif +#endif + + +#if @GNULIB_MKNOD@ +# if @REPLACE_MKNOD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mknod +# define mknod rpl_mknod +# endif +_GL_FUNCDECL_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev)); +# else +# if !@HAVE_MKNOD@ +_GL_FUNCDECL_SYS (mknod, int, (char const *file, mode_t mode, dev_t dev) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on OSF/1 5.1, the third parameter is '...'. */ +_GL_CXXALIAS_SYS_CAST (mknod, int, (char const *file, mode_t mode, dev_t dev)); +# endif +_GL_CXXALIASWARN (mknod); +#elif defined GNULIB_POSIXCHECK +# undef mknod +# if HAVE_RAW_DECL_MKNOD +_GL_WARN_ON_USE (mknod, "mknod is not portable - " + "use gnulib module mknod for portability"); +# endif +#endif + + +#if @GNULIB_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 +_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 +# if HAVE_RAW_DECL_MKNODAT +_GL_WARN_ON_USE (mknodat, "mknodat is not portable - " + "use gnulib module mkfifoat for portability"); +# endif +#endif + + +#if @GNULIB_STAT@ +# if @REPLACE_STAT@ +# if !@GNULIB_OVERRIDES_STRUCT_STAT@ + /* We can't use the object-like #define stat rpl_stat, because of + struct stat. This means that rpl_stat will not be used if the user + does (stat)(a,b). Oh well. */ +# if defined _AIX && defined stat && defined _LARGE_FILES + /* With _LARGE_FILES defined, AIX (only) defines stat to stat64, + so we have to replace stat64() instead of stat(). */ +# undef stat64 +# define stat64(name, st) rpl_stat (name, st) +# elif @WINDOWS_64_BIT_ST_SIZE@ + /* Above, we define stat to _stati64. */ +# if defined __MINGW32__ && defined _stati64 +# ifndef _USE_32BIT_TIME_T + /* The system headers define _stati64 to _stat64. */ +# undef _stat64 +# define _stat64(name, st) rpl_stat (name, st) +# endif +# elif defined _MSC_VER && defined _stati64 +# ifdef _USE_32BIT_TIME_T + /* The system headers define _stati64 to _stat32i64. */ +# undef _stat32i64 +# define _stat32i64(name, st) rpl_stat (name, st) +# else + /* The system headers define _stati64 to _stat64. */ +# undef _stat64 +# define _stat64(name, st) rpl_stat (name, st) +# endif +# else +# undef _stati64 +# define _stati64(name, st) rpl_stat (name, st) +# endif +# elif defined __MINGW32__ && defined stat +# ifdef _USE_32BIT_TIME_T + /* The system headers define stat to _stat32i64. */ +# undef _stat32i64 +# define _stat32i64(name, st) rpl_stat (name, st) +# else + /* The system headers define stat to _stat64. */ +# undef _stat64 +# define _stat64(name, st) rpl_stat (name, st) +# endif +# elif defined _MSC_VER && defined stat +# ifdef _USE_32BIT_TIME_T + /* The system headers define stat to _stat32. */ +# undef _stat32 +# define _stat32(name, st) rpl_stat (name, st) +# else + /* The system headers define stat to _stat64i32. */ +# undef _stat64i32 +# define _stat64i32(name, st) rpl_stat (name, st) +# endif +# else /* !(_AIX || __MINGW32__ || _MSC_VER) */ +# undef stat +# define stat(name, st) rpl_stat (name, st) +# endif /* !_LARGE_FILES */ +# endif /* !@GNULIB_OVERRIDES_STRUCT_STAT@ */ +_GL_EXTERN_C int stat (const char *restrict name, struct stat *restrict buf) + _GL_ARG_NONNULL ((1, 2)); +# endif +#elif @GNULIB_OVERRIDES_STRUCT_STAT@ +/* see above: + #define stat stat_used_without_requesting_gnulib_module_stat + */ +#elif defined GNULIB_POSIXCHECK +# undef stat +# if HAVE_RAW_DECL_STAT +_GL_WARN_ON_USE (stat, "stat is unportable - " + "use gnulib module stat for portability"); +# endif +#endif + + +#if @GNULIB_MDA_UMASK@ +/* On native Windows, map 'umask' to '_umask', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::umask always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef umask +# define umask _umask +# endif +/* Need to cast, because in mingw the last argument is 'int mode'. */ +_GL_CXXALIAS_MDA_CAST (umask, mode_t, (mode_t mask)); +# else +_GL_CXXALIAS_SYS (umask, mode_t, (mode_t mask)); +# endif +_GL_CXXALIASWARN (umask); +#endif + + +#if @GNULIB_UTIMENSAT@ +/* Use the rpl_ prefix also on Solaris <= 9, because on Solaris 9 our utimensat + implementation relies on futimesat, which on Solaris 10 makes an invocation + to utimensat that is meant to invoke the libc's utimensat(), not gnulib's + utimensat(). */ +# if @REPLACE_UTIMENSAT@ || (!@HAVE_UTIMENSAT@ && defined __sun) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef utimensat +# define utimensat rpl_utimensat +# endif +_GL_FUNCDECL_RPL (utimensat, int, (int fd, char const *name, + struct timespec const times[2], int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (utimensat, int, (int fd, char const *name, + struct timespec const times[2], int flag)); +# else +# if !@HAVE_UTIMENSAT@ +_GL_FUNCDECL_SYS (utimensat, int, (int fd, char const *name, + struct timespec const times[2], int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (utimensat, int, (int fd, char const *name, + struct timespec const times[2], int flag)); +# endif +# if @HAVE_UTIMENSAT@ +_GL_CXXALIASWARN (utimensat); +# endif +#elif defined GNULIB_POSIXCHECK +# undef utimensat +# if HAVE_RAW_DECL_UTIMENSAT +_GL_WARN_ON_USE (utimensat, "utimensat is not portable - " + "use gnulib module utimensat for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_STAT_H */ +#endif /* _@GUARD_PREFIX@_SYS_STAT_H */ +#endif diff --git a/gl/sys_types.in.h b/gl/sys_types.in.h index d7da3562..698e88d6 100644 --- a/gl/sys_types.in.h +++ b/gl/sys_types.in.h @@ -1,29 +1,42 @@ /* Provide a more complete sys/types.h. - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ +#if defined _WIN32 && !defined __CYGWIN__ \ + && (defined __need_off_t || defined __need___off64_t \ + || defined __need_ssize_t || defined __need_time_t) + +/* Special invocation convention inside mingw header files. */ + +#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@ + +#else +/* Normal invocation convention. */ + #ifndef _@GUARD_PREFIX@_SYS_TYPES_H /* The include_next requires a split double-inclusion guard. */ +# define _GL_INCLUDING_SYS_TYPES_H #@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@ +# undef _GL_INCLUDING_SYS_TYPES_H #ifndef _@GUARD_PREFIX@_SYS_TYPES_H #define _@GUARD_PREFIX@_SYS_TYPES_H @@ -40,12 +53,54 @@ # define _GL_WINDOWS_64_BIT_OFF_T 1 #endif +/* Override dev_t and ino_t if distinguishable inodes support is requested + on native Windows. */ +#if @WINDOWS_STAT_INODES@ + +# if @WINDOWS_STAT_INODES@ == 2 +/* Experimental, not useful in Windows 10. */ + +/* Define dev_t to a 64-bit type. */ +# if !defined GNULIB_defined_dev_t +typedef unsigned long long int rpl_dev_t; +# undef dev_t +# define dev_t rpl_dev_t +# define GNULIB_defined_dev_t 1 +# endif + +/* Define ino_t to a 128-bit type. */ +# if !defined GNULIB_defined_ino_t +/* MSVC does not have a 128-bit integer type. + GCC has a 128-bit integer type __int128, but only on 64-bit targets. */ +typedef struct { unsigned long long int _gl_ino[2]; } rpl_ino_t; +# undef ino_t +# define ino_t rpl_ino_t +# define GNULIB_defined_ino_t 1 +# endif + +# else /* @WINDOWS_STAT_INODES@ == 1 */ + +/* Define ino_t to a 64-bit type. */ +# if !defined GNULIB_defined_ino_t +typedef unsigned long long int rpl_ino_t; +# undef ino_t +# define ino_t rpl_ino_t +# define GNULIB_defined_ino_t 1 +# endif + +# endif + +/* Indicator, for gnulib internal purposes. */ +# define _GL_WINDOWS_STAT_INODES @WINDOWS_STAT_INODES@ + +#endif + /* MSVC 9 defines size_t in , not in . */ /* But avoid namespace pollution on glibc systems. */ -#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ - && ! defined __GLIBC__ +#if (defined _WIN32 && ! defined __CYGWIN__) && ! defined __GLIBC__ # include #endif #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ +#endif /* __need_XXX */ diff --git a/gl/sys_uio.in.h b/gl/sys_uio.in.h index fef19dc3..788d461f 100644 --- a/gl/sys_uio.in.h +++ b/gl/sys_uio.in.h @@ -1,18 +1,18 @@ /* Substitute for . - Copyright (C) 2011-2013 Free Software Foundation, Inc. + Copyright (C) 2011-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ # if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ diff --git a/gl/time.in.h b/gl/time.in.h index 8ced7947..6d4c7719 100644 --- a/gl/time.in.h +++ b/gl/time.in.h @@ -1,19 +1,19 @@ /* A more-standard . - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ @@ -22,11 +22,13 @@ /* Don't get in the way of glibc when it includes time.h merely to declare a few standard symbols, rather than to declare all the - symbols. Also, Solaris 8 eventually includes itself + symbols. (However, skip this for MinGW as it treats __need_time_t + incompatibly.) Also, Solaris 8 eventually includes itself recursively; if that is happening, just include the system without adding our own declarations. */ -#if (defined __need_time_t || defined __need_clock_t \ - || defined __need_timespec \ +#if (((defined __need_time_t || defined __need_clock_t \ + || defined __need_timespec) \ + && !defined __MINGW32__) \ || defined _@GUARD_PREFIX@_TIME_H) # @INCLUDE_NEXT@ @NEXT_TIME_H@ @@ -35,6 +37,12 @@ # define _@GUARD_PREFIX@_TIME_H +/* mingw's provides the functions asctime_r, ctime_r, gmtime_r, + localtime_r only if or has been included before. */ +# if defined __MINGW32__ +# include +# endif + # @INCLUDE_NEXT@ @NEXT_TIME_H@ /* NetBSD 5.0 mis-defines NULL. */ @@ -46,22 +54,17 @@ /* The definition of _GL_WARN_ON_USE is copied here. */ -/* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3). +/* Some systems don't define struct timespec (e.g., AIX 4.1). Or they define it with the wrong member names or define it in - (e.g., FreeBSD circa 1997). Stock Mingw does not define it, but the - pthreads-win32 library defines it in . */ + (e.g., FreeBSD circa 1997). Stock Mingw prior to 3.0 does not define it, + but the pthreads-win32 library defines it in . */ # if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@ # if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ # include # elif @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ # include -/* The pthreads-win32 also defines a couple of broken macros. */ -# undef asctime_r -# undef ctime_r -# undef gmtime_r -# undef localtime_r -# undef rand_r -# undef strtok_r +# elif @UNISTD_H_DEFINES_STRUCT_TIMESPEC@ +# include # else # ifdef __cplusplus @@ -87,8 +90,8 @@ struct timespec # endif # if !GNULIB_defined_struct_time_t_must_be_integral -/* Per http://austingroupbugs.net/view.php?id=327, POSIX requires - time_t to be an integer type, even though C99 permits floating +/* https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html + requires time_t to be an integer type, even though C99 permits floating point. We don't know of any implementation that uses floating point, and it is much easier to write code that doesn't have to worry about that corner case, so we force the issue. */ @@ -98,9 +101,39 @@ 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 + +/* Set *TS to the current time resolution, and return BASE. + Upon failure, return 0. */ +# if @GNULIB_TIMESPEC_GETRES@ +# if ! @HAVE_TIMESPEC_GETRES@ +_GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base)); +_GL_CXXALIASWARN (timespec_getres); +# endif + /* Sleep for at least RQTP seconds unless interrupted, If interrupted, return -1 and store the remaining time into RMTP. See - . */ + . */ # if @GNULIB_NANOSLEEP@ # if @REPLACE_NANOSLEEP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) @@ -123,6 +156,41 @@ _GL_CXXALIAS_SYS (nanosleep, int, _GL_CXXALIASWARN (nanosleep); # endif +/* Initialize time conversion information. */ +# if @GNULIB_TZSET@ +# if @REPLACE_TZSET@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tzset +# define tzset rpl_tzset +# endif +_GL_FUNCDECL_RPL (tzset, void, (void)); +_GL_CXXALIAS_RPL (tzset, void, (void)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tzset +# define tzset _tzset +# endif +_GL_CXXALIAS_MDA (tzset, void, (void)); +# else +_GL_CXXALIAS_SYS (tzset, void, (void)); +# endif +_GL_CXXALIASWARN (tzset); +# elif @GNULIB_MDA_TZSET@ +/* On native Windows, map 'tzset' to '_tzset', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::tzset always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef tzset +# define tzset _tzset +# endif +_GL_CXXALIAS_MDA (tzset, void, (void)); +# else +_GL_CXXALIAS_SYS (tzset, void, (void)); +# endif +_GL_CXXALIASWARN (tzset); +# endif + /* Return the 'time_t' representation of TP and normalize TP. */ # if @GNULIB_MKTIME@ # if @REPLACE_MKTIME@ @@ -134,12 +202,14 @@ _GL_CXXALIAS_RPL (mktime, time_t, (struct tm *__tp)); # else _GL_CXXALIAS_SYS (mktime, time_t, (struct tm *__tp)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (mktime); +# endif # endif /* Convert TIMER to RESULT, assuming local time and UTC respectively. See - and - . */ + and + . */ # if @GNULIB_TIME_R@ # if @REPLACE_LOCALTIME_R@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) @@ -187,9 +257,44 @@ _GL_CXXALIASWARN (gmtime_r); # endif # endif -/* Parse BUF as a time stamp, assuming FORMAT specifies its layout, and store +/* Convert TIMER to RESULT, assuming local time and UTC respectively. See + and + . */ +# if @GNULIB_LOCALTIME@ || @REPLACE_LOCALTIME@ +# if @REPLACE_LOCALTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef localtime +# define localtime rpl_localtime +# endif +_GL_FUNCDECL_RPL (localtime, struct tm *, (time_t const *__timer) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (localtime, struct tm *, (time_t const *__timer)); +# else +_GL_CXXALIAS_SYS (localtime, struct tm *, (time_t const *__timer)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (localtime); +# endif +# endif + +# if 0 || @REPLACE_GMTIME@ +# if @REPLACE_GMTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gmtime +# define gmtime rpl_gmtime +# endif +_GL_FUNCDECL_RPL (gmtime, struct tm *, (time_t const *__timer) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (gmtime, struct tm *, (time_t const *__timer)); +# else +_GL_CXXALIAS_SYS (gmtime, struct tm *, (time_t const *__timer)); +# endif +_GL_CXXALIASWARN (gmtime); +# endif + +/* Parse BUF as a timestamp, assuming FORMAT specifies its layout, and store the resulting broken-down time into TM. See - . */ + . */ # if @GNULIB_STRPTIME@ # if ! @HAVE_STRPTIME@ _GL_FUNCDECL_SYS (strptime, char *, (char const *restrict __buf, @@ -203,6 +308,105 @@ _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf, _GL_CXXALIASWARN (strptime); # endif +/* Convert *TP to a date and time string. See + . */ +# if @GNULIB_CTIME@ +# if @REPLACE_CTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define ctime rpl_ctime +# endif +_GL_FUNCDECL_RPL (ctime, char *, (time_t const *__tp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (ctime, char *, (time_t const *__tp)); +# else +_GL_CXXALIAS_SYS (ctime, char *, (time_t const *__tp)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (ctime); +# endif +# endif + +/* Convert *TP to a date and time string. See + . */ +# if @GNULIB_STRFTIME@ +# if @REPLACE_STRFTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strftime rpl_strftime +# endif +_GL_FUNCDECL_RPL (strftime, size_t, + (char *restrict __buf, size_t __bufsize, + const char *restrict __fmt, const struct tm *restrict __tp) + _GL_ARG_NONNULL ((1, 3, 4))); +_GL_CXXALIAS_RPL (strftime, size_t, + (char *restrict __buf, size_t __bufsize, + const char *restrict __fmt, const struct tm *restrict __tp)); +# else +_GL_CXXALIAS_SYS (strftime, size_t, + (char *restrict __buf, size_t __bufsize, + const char *restrict __fmt, const struct tm *restrict __tp)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (strftime); +# endif +# endif + +# if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@ +/* Functions that use a first-class time zone data type, instead of + relying on an implicit global time zone. + Inspired by NetBSD. */ + +/* Represents a time zone. + (timezone_t) NULL stands for UTC. */ +typedef struct tm_zone *timezone_t; + +/* tzalloc (name) + Returns a time zone object for the given time zone NAME. This object + represents the time zone that other functions would use it the TZ + environment variable was set to NAME. + If NAME is NULL, the result represents the time zone that other functions + would use it the TZ environment variable was unset. + May return NULL if NAME is invalid (this is platform dependent) or + upon memory allocation failure. */ +_GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name)); +_GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name)); + +/* tzfree (tz) + Frees a time zone object. + The argument must have been returned by tzalloc(). */ +_GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz)); +_GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz)); + +/* localtime_rz (tz, &t, &result) + Converts an absolute time T to a broken-down time RESULT, assuming the + time zone TZ. + This function is like 'localtime_r', but relies on the argument TZ instead + of an implicit global time zone. */ +_GL_FUNCDECL_SYS (localtime_rz, struct tm *, + (timezone_t __tz, time_t const *restrict __timer, + struct tm *restrict __result) _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_SYS (localtime_rz, struct tm *, + (timezone_t __tz, time_t const *restrict __timer, + struct tm *restrict __result)); + +/* mktime_z (tz, &tm) + Normalizes the broken-down time TM and converts it to an absolute time, + assuming the time zone TZ. Returns the absolute time. + This function is like 'mktime', but relies on the argument TZ instead + of an implicit global time zone. */ +_GL_FUNCDECL_SYS (mktime_z, time_t, + (timezone_t __tz, struct tm *restrict __tm) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_SYS (mktime_z, time_t, + (timezone_t __tz, struct tm *restrict __tm)); + +/* Time zone abbreviation strings (returned by 'localtime_rz' or 'mktime_z' + in the 'tm_zone' member of 'struct tm') are valid as long as + - the 'struct tm' argument is not destroyed or overwritten, + and + - the 'timezone_t' argument is not freed through tzfree(). */ + +# endif + /* Convert TM to a time_t value, assuming UTC. */ # if @GNULIB_TIMEGM@ # if @REPLACE_TIMEGM@ @@ -231,17 +435,17 @@ _GL_WARN_ON_USE (asctime, "asctime can overrun buffers in some cases - " # endif # if defined GNULIB_POSIXCHECK # undef asctime_r -_GL_WARN_ON_USE (asctime, "asctime_r can overrun buffers in some cases - " +_GL_WARN_ON_USE (asctime_r, "asctime_r can overrun buffers in some cases - " "better use strftime (or even sprintf) instead"); # endif # if defined GNULIB_POSIXCHECK # undef ctime -_GL_WARN_ON_USE (asctime, "ctime can overrun buffers in some cases - " +_GL_WARN_ON_USE (ctime, "ctime can overrun buffers in some cases - " "better use strftime (or even sprintf) instead"); # endif # if defined GNULIB_POSIXCHECK # undef ctime_r -_GL_WARN_ON_USE (asctime, "ctime_r can overrun buffers in some cases - " +_GL_WARN_ON_USE (ctime_r, "ctime_r can overrun buffers in some cases - " "better use strftime (or even sprintf) instead"); # endif diff --git a/gl/time_r.c b/gl/time_r.c index 98662998..d4b22755 100644 --- a/gl/time_r.c +++ b/gl/time_r.c @@ -1,19 +1,19 @@ /* Reentrant time functions like localtime_r. - Copyright (C) 2003, 2006-2007, 2010-2013 Free Software Foundation, Inc. + Copyright (C) 2003, 2006-2007, 2010-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Paul Eggert. */ diff --git a/gl/timegm.c b/gl/timegm.c index 6338baa3..a1b19efc 100644 --- a/gl/timegm.c +++ b/gl/timegm.c @@ -1,38 +1,58 @@ /* Convert UTC calendar time to simple time. Like mktime but assumes UTC. - Copyright (C) 1994, 1997, 2003-2004, 2006-2007, 2009-2013 Free Software - Foundation, Inc. This file is part of the GNU C Library. + Copyright (C) 1994-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ #ifndef _LIBC -# include +# include #endif #include +#include -#ifndef _LIBC -# undef __gmtime_r -# define __gmtime_r gmtime_r -# define __mktime_internal mktime_internal -# include "mktime-internal.h" -#endif +#include "mktime-internal.h" + +__time64_t +__timegm64 (struct tm *tmp) +{ + static mktime_offset_t gmtime_offset; + tmp->tm_isdst = 0; + return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset); +} + +#if defined _LIBC && __TIMESIZE != 64 + +libc_hidden_def (__timegm64) time_t timegm (struct tm *tmp) { - static time_t gmtime_offset; - tmp->tm_isdst = 0; - return __mktime_internal (tmp, __gmtime_r, &gmtime_offset); + struct tm tm = *tmp; + __time64_t t = __timegm64 (&tm); + if (in_time_t_range (t)) + { + *tmp = tm; + return t; + } + else + { + __set_errno (EOVERFLOW); + return -1; + } } + +#endif diff --git a/gl/unistd.c b/gl/unistd.c index 6c6a8e26..95978e6a 100644 --- a/gl/unistd.c +++ b/gl/unistd.c @@ -1,3 +1,22 @@ +/* Inline functions for . + + Copyright (C) 2012-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + #include + #define _GL_UNISTD_INLINE _GL_EXTERN_INLINE #include "unistd.h" +typedef int dummy; diff --git a/gl/unistd.in.h b/gl/unistd.in.h index 2ea9af43..57df09ec 100644 --- a/gl/unistd.in.h +++ b/gl/unistd.in.h @@ -1,18 +1,18 @@ /* Substitute for and wrapper around . - Copyright (C) 2003-2013 Free Software Foundation, Inc. + Copyright (C) 2003-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _@GUARD_PREFIX@_UNISTD_H @@ -21,9 +21,23 @@ #endif @PRAGMA_COLUMNS@ +#if @HAVE_UNISTD_H@ && defined _GL_INCLUDING_UNISTD_H +/* Special invocation convention: + - On Mac OS X 10.3.9 we have a sequence of nested includes + -> -> -> + In this situation, the functions are not yet declared, therefore we cannot + provide the C++ aliases. */ + +#@INCLUDE_NEXT@ @NEXT_UNISTD_H@ + +#else +/* Normal invocation convention. */ + /* The include_next requires a split double-inclusion guard. */ #if @HAVE_UNISTD_H@ +# define _GL_INCLUDING_UNISTD_H # @INCLUDE_NEXT@ @NEXT_UNISTD_H@ +# undef _GL_INCLUDING_UNISTD_H #endif /* Get all possible declarations of gethostname(). */ @@ -38,21 +52,30 @@ #define _@GUARD_PREFIX@_UNISTD_H /* NetBSD 5.0 mis-defines NULL. Also get size_t. */ -#include +/* But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include +#endif /* mingw doesn't define the SEEK_* or *_FILENO macros in . */ +/* MSVC declares 'unlink' in , not in . We must include + it before we #define unlink rpl_unlink. */ /* Cygwin 1.7.1 declares symlinkat in , not in . */ /* But avoid namespace pollution on glibc systems. */ #if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \ + || ((@GNULIB_UNLINK@ || defined GNULIB_POSIXCHECK) \ + && (defined _WIN32 && ! defined __CYGWIN__)) \ || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \ && defined __CYGWIN__)) \ && ! defined __GLIBC__ # include #endif -/* Cygwin 1.7.1 declares unlinkat in , not in . */ +/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in , not in + . */ /* But avoid namespace pollution on glibc systems. */ -#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && defined __CYGWIN__ \ +#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ + && (defined __CYGWIN__ || defined __ANDROID__) \ && ! defined __GLIBC__ # include #endif @@ -70,20 +93,18 @@ # undef __need_system_stdlib_h #endif -/* Native Windows platforms declare chdir, getcwd, rmdir in +/* Native Windows platforms declare _chdir, _getcwd, _rmdir in and/or , not in . - They also declare access(), chmod(), close(), dup(), dup2(), isatty(), - lseek(), read(), unlink(), write() in . */ -#if ((@GNULIB_CHDIR@ || @GNULIB_GETCWD@ || @GNULIB_RMDIR@ \ - || defined GNULIB_POSIXCHECK) \ - && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) -# include /* mingw32, mingw64 */ -# include /* mingw64, MSVC 9 */ -#elif (@GNULIB_CLOSE@ || @GNULIB_DUP@ || @GNULIB_DUP2@ || @GNULIB_ISATTY@ \ - || @GNULIB_LSEEK@ || @GNULIB_READ@ || @GNULIB_UNLINK@ || @GNULIB_WRITE@ \ - || defined GNULIB_POSIXCHECK) \ - && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) + They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(), + _lseek(), _read(), _unlink(), _write() in . */ +#if defined _WIN32 && !defined __CYGWIN__ # include +# include +#endif + +/* Native Windows platforms declare _execl*, _execv* in . */ +#if defined _WIN32 && !defined __CYGWIN__ +# include #endif /* AIX and OSF/1 5.1 declare getdomainname in , not in . @@ -95,31 +116,28 @@ # include #endif -/* MSVC defines off_t in . - May also define off_t to a 64-bit type on native Windows. */ -#if !@HAVE_UNISTD_H@ || @WINDOWS_64_BIT_OFF_T@ -/* Get off_t. */ -# include -#endif - -#if (@GNULIB_READ@ || @GNULIB_WRITE@ \ - || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \ - || @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK) -/* Get ssize_t. */ -# include +/* Mac OS X 10.13, Solaris 11.4, and Android 9.0 declare getentropy in + , not in . */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_GETENTROPY@ || defined GNULIB_POSIXCHECK) \ + && ((defined __APPLE__ && defined __MACH__) || defined __sun \ + || defined __ANDROID__) \ + && @UNISTD_H_HAVE_SYS_RANDOM_H@ \ + && !defined __GLIBC__ +# include #endif -/* Get getopt(), optarg, optind, opterr, optopt. - But avoid namespace pollution on glibc systems. */ -#if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT -# define __need_getopt -# include +/* Android 4.3 declares fchownat in , not in . */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_FCHOWNAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \ + && !defined __GLIBC__ +# include #endif -_GL_INLINE_HEADER_BEGIN -#ifndef _GL_UNISTD_INLINE -# define _GL_UNISTD_INLINE _GL_INLINE -#endif +/* MSVC defines off_t in . + May also define off_t to a 64-bit type on native Windows. */ +/* Get off_t, ssize_t, mode_t. */ +#include /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ @@ -128,6 +146,20 @@ _GL_INLINE_HEADER_BEGIN /* The definition of _GL_WARN_ON_USE is copied here. */ +/* Get getopt(), optarg, optind, opterr, optopt. */ +#if @GNULIB_GETOPT_POSIX@ && @GNULIB_UNISTD_H_GETOPT@ && !defined _GL_SYSTEM_GETOPT +# include +# include +#endif + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef _GL_UNISTD_INLINE +# define _GL_UNISTD_INLINE _GL_INLINE +#endif + /* Hide some function declarations from . */ #if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ @@ -227,15 +259,61 @@ _GL_INLINE_HEADER_BEGIN /* Declare overridden functions. */ -#if defined GNULIB_POSIXCHECK +#if @GNULIB_ACCESS@ +# if @REPLACE_ACCESS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef access +# define access rpl_access +# endif +_GL_FUNCDECL_RPL (access, int, (const char *file, int mode) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (access, int, (const char *file, int mode)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef access +# define access _access +# endif +_GL_CXXALIAS_MDA (access, int, (const char *file, int mode)); +# else +_GL_CXXALIAS_SYS (access, int, (const char *file, int mode)); +# endif +_GL_CXXALIASWARN (access); +#elif defined GNULIB_POSIXCHECK +# undef access +# if HAVE_RAW_DECL_ACCESS /* The access() function is a security risk. */ -_GL_WARN_ON_USE (access, "the access function is a security risk - " +_GL_WARN_ON_USE (access, "access does not always support X_OK - " + "use gnulib module access for portability; " + "also, this function is a security risk - " "use the gnulib module faccessat instead"); +# endif +#elif @GNULIB_MDA_ACCESS@ +/* On native Windows, map 'access' to '_access', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::access always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef access +# define access _access +# endif +_GL_CXXALIAS_MDA (access, int, (const char *file, int mode)); +# else +_GL_CXXALIAS_SYS (access, int, (const char *file, int mode)); +# endif +_GL_CXXALIASWARN (access); #endif #if @GNULIB_CHDIR@ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chdir +# define chdir _chdir +# endif +_GL_CXXALIAS_MDA (chdir, int, (const char *file)); +# else _GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1))); +# endif _GL_CXXALIASWARN (chdir); #elif defined GNULIB_POSIXCHECK # undef chdir @@ -243,6 +321,20 @@ _GL_CXXALIASWARN (chdir); _GL_WARN_ON_USE (chown, "chdir is not always in - " "use gnulib module chdir for portability"); # endif +#elif @GNULIB_MDA_CHDIR@ +/* On native Windows, map 'chdir' to '_chdir', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::chdir always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chdir +# define chdir _chdir +# endif +_GL_CXXALIAS_MDA (chdir, int, (const char *file)); +# else +_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIASWARN (chdir); #endif @@ -251,7 +343,7 @@ _GL_WARN_ON_USE (chown, "chdir is not always in - " to GID (if GID is not -1). Follow symbolic links. Return 0 if successful, otherwise -1 and errno set. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_DUP2@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define dup2 rpl_dup2 # endif _GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd)); _GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); -# else -# if !@HAVE_DUP2@ -_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef dup2 +# define dup2 _dup2 # endif +_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd)); +# else _GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd)); # endif _GL_CXXALIASWARN (dup2); @@ -347,6 +515,20 @@ _GL_CXXALIASWARN (dup2); _GL_WARN_ON_USE (dup2, "dup2 is unportable - " "use gnulib module dup2 for portability"); # endif +#elif @GNULIB_MDA_DUP2@ +/* On native Windows, map 'dup2' to '_dup2', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::dup2 always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef dup2 +# define dup2 _dup2 +# endif +_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd)); +# else +_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd)); +# endif +_GL_CXXALIASWARN (dup2); #endif @@ -358,7 +540,7 @@ _GL_WARN_ON_USE (dup2, "dup2 is unportable - " Close NEWFD first if it is open. Return newfd if successful, otherwise -1 and errno set. See the Linux man page at - . */ + . */ # if @HAVE_DUP3@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define dup3 rpl_dup3 @@ -380,10 +562,23 @@ _GL_WARN_ON_USE (dup3, "dup3 is unportable - " #if @GNULIB_ENVIRON@ +# if defined __CYGWIN__ && !defined __i386__ +/* The 'environ' variable is defined in a DLL. Therefore its declaration needs + the '__declspec(dllimport)' attribute, but the system's lacks it. + This leads to a link error on 64-bit Cygwin when the option + -Wl,--disable-auto-import is in use. */ +_GL_EXTERN_C __declspec(dllimport) char **environ; +# endif # if !@HAVE_DECL_ENVIRON@ /* Set of environment variables and values. An array of strings of the form "VARIABLE=VALUE", terminated with a NULL. */ # if defined __APPLE__ && defined __MACH__ +# include +# if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +# define _GL_USE_CRT_EXTERNS +# endif +# endif +# ifdef _GL_USE_CRT_EXTERNS # include # define environ (*_NSGetEnviron ()) # else @@ -399,12 +594,12 @@ extern char **environ; #elif defined GNULIB_POSIXCHECK # if HAVE_RAW_DECL_ENVIRON _GL_UNISTD_INLINE char *** +_GL_WARN_ON_USE_ATTRIBUTE ("environ is unportable - " + "use gnulib module environ for portability") rpl_environ (void) { return &environ; } -_GL_WARN_ON_USE (rpl_environ, "environ is unportable - " - "use gnulib module environ for portability"); # undef environ # define environ (*rpl_environ ()) # endif @@ -434,14 +629,302 @@ _GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - " #endif +#if @GNULIB_EXECL@ +# if @REPLACE_EXECL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execl +# define execl rpl_execl +# endif +_GL_FUNCDECL_RPL (execl, int, (const char *program, const char *arg, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (execl, int, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execl); +#elif defined GNULIB_POSIXCHECK +# undef execl +# if HAVE_RAW_DECL_EXECL +_GL_WARN_ON_USE (execl, "execl behaves very differently on mingw - " + "use gnulib module execl for portability"); +# endif +#elif @GNULIB_MDA_EXECL@ +/* On native Windows, map 'execl' to '_execl', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execl always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execl +# define execl _execl +# endif +_GL_CXXALIAS_MDA (execl, intptr_t, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execl); +#endif + +#if @GNULIB_EXECLE@ +# if @REPLACE_EXECLE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execle +# define execle rpl_execle +# endif +_GL_FUNCDECL_RPL (execle, int, (const char *program, const char *arg, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (execle, int, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execle); +#elif defined GNULIB_POSIXCHECK +# undef execle +# if HAVE_RAW_DECL_EXECLE +_GL_WARN_ON_USE (execle, "execle behaves very differently on mingw - " + "use gnulib module execle for portability"); +# endif +#elif @GNULIB_MDA_EXECLE@ +/* On native Windows, map 'execle' to '_execle', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execle always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execle +# define execle _execle +# endif +_GL_CXXALIAS_MDA (execle, intptr_t, + (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execle); +#endif + +#if @GNULIB_EXECLP@ +# if @REPLACE_EXECLP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execlp +# define execlp rpl_execlp +# endif +_GL_FUNCDECL_RPL (execlp, int, (const char *program, const char *arg, ...) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (execlp, int, (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execlp); +#elif defined GNULIB_POSIXCHECK +# undef execlp +# if HAVE_RAW_DECL_EXECLP +_GL_WARN_ON_USE (execlp, "execlp behaves very differently on mingw - " + "use gnulib module execlp for portability"); +# endif +#elif @GNULIB_MDA_EXECLP@ +/* On native Windows, map 'execlp' to '_execlp', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execlp always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execlp +# define execlp _execlp +# endif +_GL_CXXALIAS_MDA (execlp, intptr_t, + (const char *program, const char *arg, ...)); +# else +_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...)); +# endif +_GL_CXXALIASWARN (execlp); +#endif + + +#if @GNULIB_EXECV@ +# if @REPLACE_EXECV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execv +# define execv rpl_execv +# endif +_GL_FUNCDECL_RPL (execv, int, (const char *program, char * const *argv) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execv, int, (const char *program, char * const *argv)); +# else +_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv)); +# endif +_GL_CXXALIASWARN (execv); +#elif defined GNULIB_POSIXCHECK +# undef execv +# if HAVE_RAW_DECL_EXECV +_GL_WARN_ON_USE (execv, "execv behaves very differently on mingw - " + "use gnulib module execv for portability"); +# endif +#elif @GNULIB_MDA_EXECV@ +/* On native Windows, map 'execv' to '_execv', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execv always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execv +# define execv _execv +# endif +_GL_CXXALIAS_MDA_CAST (execv, intptr_t, + (const char *program, char * const *argv)); +# else +_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv)); +# endif +_GL_CXXALIASWARN (execv); +#endif + +#if @GNULIB_EXECVE@ +# if @REPLACE_EXECVE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execve +# define execve rpl_execve +# endif +_GL_FUNCDECL_RPL (execve, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execve, int, + (const char *program, char * const *argv, char * const *env)); +# else +_GL_CXXALIAS_SYS (execve, int, + (const char *program, char * const *argv, char * const *env)); +# endif +_GL_CXXALIASWARN (execve); +#elif defined GNULIB_POSIXCHECK +# undef execve +# if HAVE_RAW_DECL_EXECVE +_GL_WARN_ON_USE (execve, "execve behaves very differently on mingw - " + "use gnulib module execve for portability"); +# endif +#elif @GNULIB_MDA_EXECVE@ +/* On native Windows, map 'execve' to '_execve', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execve always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execve +# define execve _execve +# endif +_GL_CXXALIAS_MDA_CAST (execve, intptr_t, + (const char *program, char * const *argv, + char * const *env)); +# else +_GL_CXXALIAS_SYS (execve, int, + (const char *program, char * const *argv, char * const *env)); +# endif +_GL_CXXALIASWARN (execve); +#endif + +#if @GNULIB_EXECVP@ +# if @REPLACE_EXECVP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvp +# define execvp rpl_execvp +# endif +_GL_FUNCDECL_RPL (execvp, int, (const char *program, char * const *argv) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execvp, int, (const char *program, char * const *argv)); +# else +_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv)); +# endif +_GL_CXXALIASWARN (execvp); +#elif defined GNULIB_POSIXCHECK +# undef execvp +# if HAVE_RAW_DECL_EXECVP +_GL_WARN_ON_USE (execvp, "execvp behaves very differently on mingw - " + "use gnulib module execvp for portability"); +# endif +#elif @GNULIB_MDA_EXECVP@ +/* On native Windows, map 'execvp' to '_execvp', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execvp always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvp +# define execvp _execvp +# endif +_GL_CXXALIAS_MDA_CAST (execvp, intptr_t, + (const char *program, char * const *argv)); +# else +_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv)); +# endif +_GL_CXXALIASWARN (execvp); +#endif + +#if @GNULIB_EXECVPE@ +# if @REPLACE_EXECVPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvpe +# define execvpe rpl_execvpe +# endif +_GL_FUNCDECL_RPL (execvpe, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (execvpe, int, + (const char *program, char * const *argv, char * const *env)); +# else +# if !@HAVE_DECL_EXECVPE@ +_GL_FUNCDECL_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env)); +# endif +_GL_CXXALIASWARN (execvpe); +#elif defined GNULIB_POSIXCHECK +# undef execvpe +# if HAVE_RAW_DECL_EXECVPE +_GL_WARN_ON_USE (execvpe, "execvpe behaves very differently on mingw - " + "use gnulib module execvpe for portability"); +# endif +#elif @GNULIB_MDA_EXECVPE@ +/* On native Windows, map 'execvpe' to '_execvpe', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::execvpe on all platforms that have + it. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef execvpe +# define execvpe _execvpe +# endif +_GL_CXXALIAS_MDA_CAST (execvpe, intptr_t, + (const char *program, char * const *argv, + char * const *env)); +# elif @HAVE_EXECVPE@ +# if !@HAVE_DECL_EXECVPE@ +_GL_FUNCDECL_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (execvpe, int, + (const char *program, char * const *argv, char * const *env)); +# endif +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_EXECVPE@ +_GL_CXXALIASWARN (execvpe); +# endif +#endif + + #if @GNULIB_FACCESSAT@ -# if !@HAVE_FACCESSAT@ +# if @REPLACE_FACCESSAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef faccessat +# define faccessat rpl_faccessat +# endif +_GL_FUNCDECL_RPL (faccessat, int, + (int fd, char const *name, int mode, int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (faccessat, int, + (int fd, char const *name, int mode, int flag)); +# else +# if !@HAVE_FACCESSAT@ _GL_FUNCDECL_SYS (faccessat, int, (int fd, char const *file, int mode, int flag) _GL_ARG_NONNULL ((2))); -# endif +# endif _GL_CXXALIAS_SYS (faccessat, int, (int fd, char const *file, int mode, int flag)); +# endif _GL_CXXALIASWARN (faccessat); #elif defined GNULIB_POSIXCHECK # undef faccessat @@ -457,7 +940,7 @@ _GL_WARN_ON_USE (faccessat, "faccessat is not portable - " the given file descriptor is open. Return 0 if successful, otherwise -1 and errno set. See the POSIX:2008 specification - . */ + . */ # if ! @HAVE_FCHDIR@ _GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); @@ -509,7 +992,7 @@ _GL_CXXALIASWARN (fchownat); # undef fchownat # if HAVE_RAW_DECL_FCHOWNAT _GL_WARN_ON_USE (fchownat, "fchownat is not portable - " - "use gnulib module openat for portability"); + "use gnulib module fchownat for portability"); # endif #endif @@ -518,7 +1001,7 @@ _GL_WARN_ON_USE (fchownat, "fchownat is not portable - " /* Synchronize changes to a file. Return 0 if successful, otherwise -1 and errno set. See POSIX:2008 specification - . */ + . */ # if !@HAVE_FDATASYNC@ || !@HAVE_DECL_FDATASYNC@ _GL_FUNCDECL_SYS (fdatasync, int, (int fd)); # endif @@ -537,7 +1020,7 @@ _GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - " /* Synchronize changes, including metadata, to a file. Return 0 if successful, otherwise -1 and errno set. See POSIX:2008 specification - . */ + . */ # if !@HAVE_FSYNC@ _GL_FUNCDECL_SYS (fsync, int, (int fd)); # endif @@ -556,7 +1039,7 @@ _GL_WARN_ON_USE (fsync, "fsync is unportable - " /* Change the size of the file to which FD is opened to become equal to LENGTH. Return 0 if successful, otherwise -1 and errno set. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_FTRUNCATE@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef ftruncate @@ -586,7 +1069,7 @@ _GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " Return BUF if successful, or NULL if the directory couldn't be determined or SIZE was too small. See the POSIX:2008 specification - . + . Additionally, the gnulib module 'getcwd' guarantees the following GNU extension: If BUF is NULL, an array is allocated with 'malloc'; the array is SIZE bytes long, unless SIZE == 0, in which case it is as big as @@ -597,6 +1080,12 @@ _GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " # endif _GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size)); _GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getcwd +# define getcwd _getcwd +# endif +_GL_CXXALIAS_MDA (getcwd, char *, (char *buf, size_t size)); # else /* Need to cast, because on mingw, the second parameter is int size. */ @@ -609,6 +1098,22 @@ _GL_CXXALIASWARN (getcwd); _GL_WARN_ON_USE (getcwd, "getcwd is unportable - " "use gnulib module getcwd for portability"); # endif +#elif @GNULIB_MDA_GETCWD@ +/* On native Windows, map 'getcwd' to '_getcwd', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::getcwd always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getcwd +# define getcwd _getcwd +# endif +/* Need to cast, because on mingw, the second parameter is either + 'int size' or 'size_t size'. */ +_GL_CXXALIAS_MDA_CAST (getcwd, char *, (char *buf, size_t size)); +# else +_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size)); +# endif +_GL_CXXALIASWARN (getcwd); #endif @@ -651,10 +1156,21 @@ _GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - " #if @GNULIB_GETDTABLESIZE@ /* Return the maximum number of file descriptors in the current process. In POSIX, this is same as sysconf (_SC_OPEN_MAX). */ -# if !@HAVE_GETDTABLESIZE@ +# if @REPLACE_GETDTABLESIZE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getdtablesize +# define getdtablesize rpl_getdtablesize +# endif +_GL_FUNCDECL_RPL (getdtablesize, int, (void)); +_GL_CXXALIAS_RPL (getdtablesize, int, (void)); +# else +# if !@HAVE_GETDTABLESIZE@ _GL_FUNCDECL_SYS (getdtablesize, int, (void)); +# endif +/* Need to cast, because on AIX, the parameter list is + (...). */ +_GL_CXXALIAS_SYS_CAST (getdtablesize, int, (void)); # endif -_GL_CXXALIAS_SYS (getdtablesize, int, (void)); _GL_CXXALIASWARN (getdtablesize); #elif defined GNULIB_POSIXCHECK # undef getdtablesize @@ -665,6 +1181,22 @@ _GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - " #endif +#if @GNULIB_GETENTROPY@ +/* Fill a buffer with random bytes. */ +# if !@HAVE_GETENTROPY@ +_GL_FUNCDECL_SYS (getentropy, int, (void *buffer, size_t length)); +# endif +_GL_CXXALIAS_SYS (getentropy, int, (void *buffer, size_t length)); +_GL_CXXALIASWARN (getentropy); +#elif defined GNULIB_POSIXCHECK +# undef getentropy +# if HAVE_RAW_DECL_GETENTROPY +_GL_WARN_ON_USE (getentropy, "getentropy is unportable - " + "use gnulib module getentropy for portability"); +# endif +#endif + + #if @GNULIB_GETGROUPS@ /* Return the supplemental groups that the current process belongs to. It is unspecified whether the effective group id is in the list. @@ -737,14 +1269,14 @@ _GL_WARN_ON_USE (gethostname, "gethostname is unportable - " /* Returns the user's login name, or NULL if it cannot be found. Upon error, returns NULL with errno set. - See . + See . Most programs don't need to use this function, because the information is available through environment variables: ${LOGNAME-$USER} on Unix platforms, $USERNAME on native Windows platforms. */ -# if !@HAVE_GETLOGIN@ +# if !@HAVE_DECL_GETLOGIN@ _GL_FUNCDECL_SYS (getlogin, char *, (void)); # endif _GL_CXXALIAS_SYS (getlogin, char *, (void)); @@ -766,7 +1298,7 @@ _GL_WARN_ON_USE (getlogin, "getlogin is unportable - " the case that the login name cannot be found but no specific error is provided (this case is hopefully rare but is left open by the POSIX spec). - See . + See . Most programs don't need to use this function, because the information is available through environment variables: @@ -807,6 +1339,11 @@ _GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - " _GL_FUNCDECL_RPL (getpagesize, int, (void)); _GL_CXXALIAS_RPL (getpagesize, int, (void)); # else +/* On HP-UX, getpagesize exists, but it is not declared in even if + the compiler options -D_HPUX_SOURCE -D_XOPEN_SOURCE=600 are used. */ +# if defined __hpux +_GL_FUNCDECL_SYS (getpagesize, int, (void)); +# endif # if !@HAVE_GETPAGESIZE@ # if !defined getpagesize /* This is for POSIX systems. */ @@ -881,6 +1418,54 @@ _GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - " #endif +#if @GNULIB_GETPASS@ +/* Function getpass() from module 'getpass': + Read a password from /dev/tty or stdin. + Function getpass() from module 'getpass-gnu': + Read a password of arbitrary length from /dev/tty or stdin. */ +# if (@GNULIB_GETPASS@ && @REPLACE_GETPASS@) \ + || (@GNULIB_GETPASS_GNU@ && @REPLACE_GETPASS_FOR_GETPASS_GNU@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getpass +# define getpass rpl_getpass +# endif +_GL_FUNCDECL_RPL (getpass, char *, (const char *prompt) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (getpass, char *, (const char *prompt)); +# else +# if !@HAVE_GETPASS@ +_GL_FUNCDECL_SYS (getpass, char *, (const char *prompt) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (getpass, char *, (const char *prompt)); +# endif +_GL_CXXALIASWARN (getpass); +#elif defined GNULIB_POSIXCHECK +# undef getpass +# if HAVE_RAW_DECL_GETPASS +_GL_WARN_ON_USE (getpass, "getpass is unportable - " + "use gnulib module getpass or getpass-gnu for portability"); +# endif +#endif + + +#if @GNULIB_MDA_GETPID@ +/* On native Windows, map 'getpid' to '_getpid', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::getpid always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getpid +# define getpid _getpid +# endif +_GL_CXXALIAS_MDA (getpid, int, (void)); +# else +_GL_CXXALIAS_SYS (getpid, pid_t, (void)); +# endif +_GL_CXXALIASWARN (getpid); +#endif + + #if @GNULIB_GETUSERSHELL@ /* Return the next valid login shell on the system, or NULL when the end of the list has been reached. */ @@ -951,8 +1536,15 @@ _GL_WARN_ON_USE (group_member, "group_member is unportable - " # undef isatty # define isatty rpl_isatty # endif +# define GNULIB_defined_isatty 1 _GL_FUNCDECL_RPL (isatty, int, (int fd)); _GL_CXXALIAS_RPL (isatty, int, (int fd)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef isatty +# define isatty _isatty +# endif +_GL_CXXALIAS_MDA (isatty, int, (int fd)); # else _GL_CXXALIAS_SYS (isatty, int, (int fd)); # endif @@ -963,6 +1555,20 @@ _GL_CXXALIASWARN (isatty); _GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - " "use gnulib module isatty for portability"); # endif +#elif @GNULIB_MDA_ISATTY@ +/* On native Windows, map 'isatty' to '_isatty', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::isatty always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef isatty +# define isatty _isatty +# endif +_GL_CXXALIAS_MDA (isatty, int, (int fd)); +# else +_GL_CXXALIAS_SYS (isatty, int, (int fd)); +# endif +_GL_CXXALIASWARN (isatty); #endif @@ -971,7 +1577,7 @@ _GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - " to GID (if GID is not -1). Do not follow symbolic links. Return 0 if successful, otherwise -1 and errno set. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_LCHOWN@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef lchown @@ -1001,7 +1607,7 @@ _GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - " /* Create a new hard link for an existing file. Return 0 if successful, otherwise -1 and errno set. See POSIX:2008 specification - . */ + . */ # if @REPLACE_LINK@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define link rpl_link @@ -1067,13 +1673,19 @@ _GL_WARN_ON_USE (linkat, "linkat is unportable - " /* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END. Return the new offset if successful, otherwise -1 and errno set. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_LSEEK@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define lseek rpl_lseek # endif _GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence)); _GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef lseek +# define lseek _lseek +# endif +_GL_CXXALIAS_MDA (lseek, off_t, (int fd, off_t offset, int whence)); # else _GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence)); # endif @@ -1084,6 +1696,20 @@ _GL_CXXALIASWARN (lseek); _GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some " "systems - use gnulib module lseek for portability"); # endif +#elif @GNULIB_MDA_LSEEK@ +/* On native Windows, map 'lseek' to '_lseek', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::lseek always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef lseek +# define lseek _lseek +# endif +_GL_CXXALIAS_MDA (lseek, long, (int fd, long offset, int whence)); +# else +_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence)); +# endif +_GL_CXXALIASWARN (lseek); #endif @@ -1113,7 +1739,7 @@ _GL_WARN_ON_USE (pipe, "pipe is unportable - " Store the read-end as fd[0] and the write-end as fd[1]. Return 0 upon success, or -1 with errno set upon failure. See also the Linux man page at - . */ + . */ # if @HAVE_PIPE2@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define pipe2 rpl_pipe2 @@ -1139,7 +1765,7 @@ _GL_WARN_ON_USE (pipe2, "pipe2 is unportable - " Return the number of bytes placed into BUF if successful, otherwise set errno and return -1. 0 indicates EOF. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_PREAD@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef pread @@ -1174,7 +1800,7 @@ _GL_WARN_ON_USE (pread, "pread is unportable - " Return the number of bytes written if successful, otherwise set errno and return -1. 0 indicates nothing written. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_PWRITE@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef pwrite @@ -1207,7 +1833,7 @@ _GL_WARN_ON_USE (pwrite, "pwrite is unportable - " #if @GNULIB_READ@ /* Read up to COUNT bytes from file descriptor FD into the buffer starting at BUF. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_READ@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef read @@ -1216,11 +1842,32 @@ _GL_WARN_ON_USE (pwrite, "pwrite is unportable - " _GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef read +# define read _read +# endif +_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, size_t count)); +# else +_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); +# endif +_GL_CXXALIASWARN (read); +#elif @GNULIB_MDA_READ@ +/* On native Windows, map 'read' to '_read', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::read always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef read +# define read _read +# endif +# ifdef __MINGW32__ +_GL_CXXALIAS_MDA (read, int, (int fd, void *buf, unsigned int count)); +# else +_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, unsigned int count)); +# endif # else -/* Need to cast, because on mingw, the third parameter is - unsigned int count - and the return type is 'int'. */ -_GL_CXXALIAS_SYS_CAST (read, ssize_t, (int fd, void *buf, size_t count)); +_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); # endif _GL_CXXALIASWARN (read); #endif @@ -1231,24 +1878,28 @@ _GL_CXXALIASWARN (read); bytes of it into BUF. Return the number of bytes placed into BUF if successful, otherwise -1 and errno set. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_READLINK@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define readlink rpl_readlink # endif _GL_FUNCDECL_RPL (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize) + (const char *restrict file, + char *restrict buf, size_t bufsize) _GL_ARG_NONNULL ((1, 2))); _GL_CXXALIAS_RPL (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize)); + (const char *restrict file, + char *restrict buf, size_t bufsize)); # else # if !@HAVE_READLINK@ _GL_FUNCDECL_SYS (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize) + (const char *restrict file, + char *restrict buf, size_t bufsize) _GL_ARG_NONNULL ((1, 2))); # endif _GL_CXXALIAS_SYS (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize)); + (const char *restrict file, + char *restrict buf, size_t bufsize)); # endif _GL_CXXALIASWARN (readlink); #elif defined GNULIB_POSIXCHECK @@ -1261,13 +1912,28 @@ _GL_WARN_ON_USE (readlink, "readlink is unportable - " #if @GNULIB_READLINKAT@ -# if !@HAVE_READLINKAT@ +# if @REPLACE_READLINKAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define readlinkat rpl_readlinkat +# endif +_GL_FUNCDECL_RPL (readlinkat, ssize_t, + (int fd, char const *restrict file, + char *restrict buf, size_t len) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (readlinkat, ssize_t, + (int fd, char const *restrict file, + char *restrict buf, size_t len)); +# else +# if !@HAVE_READLINKAT@ _GL_FUNCDECL_SYS (readlinkat, ssize_t, - (int fd, char const *file, char *buf, size_t len) + (int fd, char const *restrict file, + char *restrict buf, size_t len) _GL_ARG_NONNULL ((2, 3))); -# endif +# endif _GL_CXXALIAS_SYS (readlinkat, ssize_t, - (int fd, char const *file, char *buf, size_t len)); + (int fd, char const *restrict file, + char *restrict buf, size_t len)); +# endif _GL_CXXALIASWARN (readlinkat); #elif defined GNULIB_POSIXCHECK # undef readlinkat @@ -1286,6 +1952,12 @@ _GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - " # endif _GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (rmdir, int, (char const *name)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef rmdir +# define rmdir _rmdir +# endif +_GL_CXXALIAS_MDA (rmdir, int, (char const *name)); # else _GL_CXXALIAS_SYS (rmdir, int, (char const *name)); # endif @@ -1296,6 +1968,20 @@ _GL_CXXALIASWARN (rmdir); _GL_WARN_ON_USE (rmdir, "rmdir is unportable - " "use gnulib module rmdir for portability"); # endif +#elif @GNULIB_MDA_RMDIR@ +/* On native Windows, map 'rmdir' to '_rmdir', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::rmdir always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef rmdir +# define rmdir _rmdir +# endif +_GL_CXXALIAS_MDA (rmdir, int, (char const *name)); +# else +_GL_CXXALIAS_SYS (rmdir, int, (char const *name)); +# endif +_GL_CXXALIASWARN (rmdir); #endif @@ -1330,7 +2016,7 @@ _GL_WARN_ON_USE (sethostname, "sethostname is unportable - " /* Pause the execution of the current thread for N seconds. Returns the number of seconds left to sleep. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_SLEEP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef sleep @@ -1354,6 +2040,31 @@ _GL_WARN_ON_USE (sleep, "sleep is unportable - " #endif +#if @GNULIB_MDA_SWAB@ +/* On native Windows, map 'swab' to '_swab', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::swab always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef swab +# define swab _swab +# endif +/* Need to cast, because in old mingw the arguments are + (const char *from, char *to, size_t n). */ +_GL_CXXALIAS_MDA_CAST (swab, void, (char *from, char *to, int n)); +# else +# if defined __hpux /* HP-UX */ +_GL_CXXALIAS_SYS (swab, void, (const char *from, char *to, int n)); +# elif defined __sun && !defined _XPG4 /* Solaris */ +_GL_CXXALIAS_SYS (swab, void, (const char *from, char *to, ssize_t n)); +# else +_GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n)); +# endif +# endif +_GL_CXXALIASWARN (swab); +#endif + + #if @GNULIB_SYMLINK@ # if @REPLACE_SYMLINK@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) @@ -1381,13 +2092,25 @@ _GL_WARN_ON_USE (symlink, "symlink is not portable - " #if @GNULIB_SYMLINKAT@ -# if !@HAVE_SYMLINKAT@ +# if @REPLACE_SYMLINKAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef symlinkat +# define symlinkat rpl_symlinkat +# endif +_GL_FUNCDECL_RPL (symlinkat, int, + (char const *contents, int fd, char const *file) + _GL_ARG_NONNULL ((1, 3))); +_GL_CXXALIAS_RPL (symlinkat, int, + (char const *contents, int fd, char const *file)); +# else +# if !@HAVE_SYMLINKAT@ _GL_FUNCDECL_SYS (symlinkat, int, (char const *contents, int fd, char const *file) _GL_ARG_NONNULL ((1, 3))); -# endif +# endif _GL_CXXALIAS_SYS (symlinkat, int, (char const *contents, int fd, char const *file)); +# endif _GL_CXXALIASWARN (symlinkat); #elif defined GNULIB_POSIXCHECK # undef symlinkat @@ -1398,6 +2121,36 @@ _GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " #endif +#if @GNULIB_TRUNCATE@ +/* Change the size of the file designated by FILENAME to become equal to LENGTH. + Return 0 if successful, otherwise -1 and errno set. + See the POSIX:2008 specification + . */ +# if @REPLACE_TRUNCATE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef truncate +# define truncate rpl_truncate +# endif +_GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length)); +# else +# if !@HAVE_DECL_TRUNCATE@ +_GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length)); +# endif +_GL_CXXALIASWARN (truncate); +#elif defined GNULIB_POSIXCHECK +# undef truncate +# if HAVE_RAW_DECL_TRUNCATE +_GL_WARN_ON_USE (truncate, "truncate is unportable - " + "use gnulib module truncate for portability"); +# endif +#endif + + #if @GNULIB_TTYNAME_R@ /* Store at most BUFLEN characters of the pathname of the terminal FD is open on in BUF. Return 0 on success, otherwise an error number. */ @@ -1436,6 +2189,12 @@ _GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - " # endif _GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (unlink, int, (char const *file)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unlink +# define unlink _unlink +# endif +_GL_CXXALIAS_MDA (unlink, int, (char const *file)); # else _GL_CXXALIAS_SYS (unlink, int, (char const *file)); # endif @@ -1446,6 +2205,20 @@ _GL_CXXALIASWARN (unlink); _GL_WARN_ON_USE (unlink, "unlink is not portable - " "use gnulib module unlink for portability"); # endif +#elif @GNULIB_MDA_UNLINK@ +/* On native Windows, map 'unlink' to '_unlink', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::unlink always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unlink +# define unlink _unlink +# endif +_GL_CXXALIAS_MDA (unlink, int, (char const *file)); +# else +_GL_CXXALIAS_SYS (unlink, int, (char const *file)); +# endif +_GL_CXXALIASWARN (unlink); #endif @@ -1470,7 +2243,7 @@ _GL_CXXALIASWARN (unlinkat); # undef unlinkat # if HAVE_RAW_DECL_UNLINKAT _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " - "use gnulib module openat for portability"); + "use gnulib module unlinkat for portability"); # endif #endif @@ -1479,7 +2252,7 @@ _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " /* Pause the execution of the current thread for N microseconds. Returns 0 on completion, or -1 on range error. See the POSIX:2001 specification - . */ + . */ # if @REPLACE_USLEEP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef usleep @@ -1491,7 +2264,9 @@ _GL_CXXALIAS_RPL (usleep, int, (useconds_t n)); # if !@HAVE_USLEEP@ _GL_FUNCDECL_SYS (usleep, int, (useconds_t n)); # endif -_GL_CXXALIAS_SYS (usleep, int, (useconds_t n)); +/* Need to cast, because on Haiku, the first parameter is + unsigned int n. */ +_GL_CXXALIAS_SYS_CAST (usleep, int, (useconds_t n)); # endif _GL_CXXALIASWARN (usleep); #elif defined GNULIB_POSIXCHECK @@ -1506,7 +2281,7 @@ _GL_WARN_ON_USE (usleep, "usleep is unportable - " #if @GNULIB_WRITE@ /* Write up to COUNT bytes starting at BUF to file descriptor FD. See the POSIX:2008 specification - . */ + . */ # if @REPLACE_WRITE@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # undef write @@ -1515,11 +2290,32 @@ _GL_WARN_ON_USE (usleep, "usleep is unportable - " _GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef write +# define write _write +# endif +_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count)); +# else +_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); +# endif +_GL_CXXALIASWARN (write); +#elif @GNULIB_MDA_WRITE@ +/* On native Windows, map 'write' to '_write', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::write always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef write +# define write _write +# endif +# ifdef __MINGW32__ +_GL_CXXALIAS_MDA (write, int, (int fd, const void *buf, unsigned int count)); +# else +_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, unsigned int count)); +# endif # else -/* Need to cast, because on mingw, the third parameter is - unsigned int count - and the return type is 'int'. */ -_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count)); +_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); # endif _GL_CXXALIASWARN (write); #endif @@ -1527,4 +2323,5 @@ _GL_CXXALIASWARN (write); _GL_INLINE_HEADER_END #endif /* _@GUARD_PREFIX@_UNISTD_H */ +#endif /* _GL_INCLUDING_UNISTD_H */ #endif /* _@GUARD_PREFIX@_UNISTD_H */ diff --git a/gl/unlocked-io.h b/gl/unlocked-io.h new file mode 100644 index 00000000..7461d740 --- /dev/null +++ b/gl/unlocked-io.h @@ -0,0 +1,136 @@ +/* Prefer faster, non-thread-safe stdio functions if available. + + Copyright (C) 2001-2004, 2009-2022 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 . */ + +/* Written by Jim Meyering. */ + +#ifndef UNLOCKED_IO_H +# define UNLOCKED_IO_H 1 + +/* These are wrappers for functions/macros from the GNU C library, and + from other C libraries supporting POSIX's optional thread-safe functions. + + The standard I/O functions are thread-safe. These *_unlocked ones are + more efficient but not thread-safe. That they're not thread-safe is + fine since all of the applications in this package are single threaded. + + Also, some code that is shared with the GNU C library may invoke + the *_unlocked functions directly. On hosts that lack those + functions, invoke the non-thread-safe versions instead. */ + +# include + +# if HAVE_DECL_CLEARERR_UNLOCKED || defined clearerr_unlocked +# undef clearerr +# define clearerr(x) clearerr_unlocked (x) +# else +# define clearerr_unlocked(x) clearerr (x) +# endif + +# if HAVE_DECL_FEOF_UNLOCKED || defined feof_unlocked +# undef feof +# define feof(x) feof_unlocked (x) +# else +# define feof_unlocked(x) feof (x) +# endif + +# if HAVE_DECL_FERROR_UNLOCKED || defined ferror_unlocked +# undef ferror +# define ferror(x) ferror_unlocked (x) +# else +# define ferror_unlocked(x) ferror (x) +# endif + +# if HAVE_DECL_FFLUSH_UNLOCKED || defined fflush_unlocked +# undef fflush +# define fflush(x) fflush_unlocked (x) +# else +# define fflush_unlocked(x) fflush (x) +# endif + +# if HAVE_DECL_FGETS_UNLOCKED || defined fgets_unlocked +# undef fgets +# define fgets(x,y,z) fgets_unlocked (x,y,z) +# else +# define fgets_unlocked(x,y,z) fgets (x,y,z) +# endif + +# if HAVE_DECL_FPUTC_UNLOCKED || defined fputc_unlocked +# undef fputc +# define fputc(x,y) fputc_unlocked (x,y) +# else +# define fputc_unlocked(x,y) fputc (x,y) +# endif + +# if HAVE_DECL_FPUTS_UNLOCKED || defined fputs_unlocked +# undef fputs +# define fputs(x,y) fputs_unlocked (x,y) +# else +# define fputs_unlocked(x,y) fputs (x,y) +# endif + +# if HAVE_DECL_FREAD_UNLOCKED || defined fread_unlocked +# undef fread +# define fread(w,x,y,z) fread_unlocked (w,x,y,z) +# else +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +# endif + +# if HAVE_DECL_FWRITE_UNLOCKED || defined fwrite_unlocked +# undef fwrite +# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z) +# else +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +# endif + +# if HAVE_DECL_GETC_UNLOCKED || defined get_unlocked +# undef getc +# define getc(x) getc_unlocked (x) +# else +# define getc_unlocked(x) getc (x) +# endif + +# if HAVE_DECL_GETCHAR_UNLOCKED || defined getchar_unlocked +# undef getchar +# define getchar() getchar_unlocked () +# else +# define getchar_unlocked() getchar () +# endif + +# if HAVE_DECL_PUTC_UNLOCKED || defined putc_unlocked +# undef putc +# define putc(x,y) putc_unlocked (x,y) +# else +# define putc_unlocked(x,y) putc (x,y) +# endif + +# if HAVE_DECL_PUTCHAR_UNLOCKED || defined putchar_unlocked +# undef putchar +# define putchar(x) putchar_unlocked (x) +# else +# define putchar_unlocked(x) putchar (x) +# endif + +# undef flockfile +# define flockfile(x) ((void) 0) + +# undef ftrylockfile +# define ftrylockfile(x) 0 + +# undef funlockfile +# define funlockfile(x) ((void) 0) + +#endif /* UNLOCKED_IO_H */ diff --git a/gl/unsetenv.c b/gl/unsetenv.c index c58c82f4..07eac6fd 100644 --- a/gl/unsetenv.c +++ b/gl/unsetenv.c @@ -1,18 +1,18 @@ -/* Copyright (C) 1992, 1995-2002, 2005-2013 Free Software Foundation, Inc. +/* Copyright (C) 1992, 1995-2002, 2005-2022 Free Software Foundation, Inc. This file is part of the GNU C Library. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc optimizes away the name == NULL test below. */ diff --git a/gl/vasnprintf.c b/gl/vasnprintf.c index 5267b1bb..285c674b 100644 --- a/gl/vasnprintf.c +++ b/gl/vasnprintf.c @@ -1,18 +1,18 @@ /* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2013 Free Software Foundation, Inc. + Copyright (C) 1999, 2002-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* This file can be parametrized with the following macros: VASNPRINTF The name of the function being defined. @@ -41,7 +41,14 @@ DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[]. DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t. DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t. - DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */ + DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + ENABLE_WCHAR_FALLBACK Set to 1 to avoid EILSEQ during conversion of wide + characters (wchar_t) and wide character strings + (wchar_t[]) to multibyte sequences. The fallback is the + hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or, + if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn. + */ /* Tell glibc's to provide a prototype for snprintf(). This must come before because may include @@ -53,10 +60,16 @@ #ifndef VASNPRINTF # include #endif -#ifndef IN_LIBINTL -# include + +/* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's + use of CHECK macros expands to code that is too complicated for gcc + -fanalyzer. Suppress the resulting bogus warnings. */ +#if 10 <= __GNUC__ +# pragma GCC diagnostic ignored "-Wanalyzer-null-argument" #endif +#include + /* Specification. */ #ifndef VASNPRINTF # if WIDE_CHAR_VERSION @@ -87,6 +100,7 @@ /* Checked size_t computations. */ #include "xsize.h" +#include "attribute.h" #include "verify.h" #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL @@ -156,6 +170,7 @@ # define SNPRINTF snwprintf # else # define SNPRINTF _snwprintf +# define USE_MSVC__SNPRINTF 1 # endif # else /* Unix. */ @@ -181,7 +196,9 @@ /* Here we need to call the native snprintf, not rpl_snprintf. */ # undef snprintf # else + /* MSVC versions < 14 did not have snprintf, only _snprintf. */ # define SNPRINTF _snprintf +# define USE_MSVC__SNPRINTF 1 # endif # else /* Unix. */ @@ -195,7 +212,7 @@ /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" warnings in this file. Use -Dlint to suppress them. */ -#ifdef lint +#if defined GCC_LINT || defined lint # define IF_LINT(Code) Code #else # define IF_LINT(Code) /* empty */ @@ -208,7 +225,7 @@ #undef remainder #define remainder rem -#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION # if (HAVE_STRNLEN && !defined _AIX) # define local_strnlen strnlen # else @@ -224,7 +241,7 @@ local_strnlen (const char *string, size_t maxlen) # endif #endif -#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T +#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T # if HAVE_WCSLEN # define local_wcslen wcslen # else @@ -247,7 +264,7 @@ local_wcslen (const wchar_t *s) # endif #endif -#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION # if HAVE_WCSNLEN # define local_wcsnlen wcsnlen # else @@ -266,6 +283,74 @@ local_wcsnlen (const wchar_t *s, size_t maxlen) # endif #endif +#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || (ENABLE_WCHAR_FALLBACK && HAVE_WINT_T)) && !WIDE_CHAR_VERSION +# if ENABLE_WCHAR_FALLBACK +static size_t +wctomb_fallback (char *s, wchar_t wc) +{ + static char hex[16] = "0123456789ABCDEF"; + + s[0] = '\\'; + if (sizeof (wchar_t) > 2 && wc > 0xffff) + { +# if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__) + s[1] = 'U'; +# else + s[1] = 'W'; +# endif + s[2] = hex[(wc & 0xf0000000U) >> 28]; + s[3] = hex[(wc & 0xf000000U) >> 24]; + s[4] = hex[(wc & 0xf00000U) >> 20]; + s[5] = hex[(wc & 0xf0000U) >> 16]; + s[6] = hex[(wc & 0xf000U) >> 12]; + s[7] = hex[(wc & 0xf00U) >> 8]; + s[8] = hex[(wc & 0xf0U) >> 4]; + s[9] = hex[wc & 0xfU]; + return 10; + } + else + { +# if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__) + s[1] = 'u'; +# else + s[1] = 'w'; +# endif + s[2] = hex[(wc & 0xf000U) >> 12]; + s[3] = hex[(wc & 0xf00U) >> 8]; + s[4] = hex[(wc & 0xf0U) >> 4]; + s[5] = hex[wc & 0xfU]; + return 6; + } +} +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t +static size_t +local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps) +{ + size_t count = wcrtomb (s, wc, ps); + if (count == (size_t)(-1)) + count = wctomb_fallback (s, wc); + return count; +} +# else +static int +local_wctomb (char *s, wchar_t wc) +{ + int count = wctomb (s, wc); + if (count < 0) + count = wctomb_fallback (s, wc); + return count; +} +# define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC)) +# endif +# else +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t +# define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS)) +# else +# define local_wcrtomb(S, WC, PS) wctomb ((S), (WC)) +# endif +# endif +#endif + #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL /* Determine the decimal-point character according to the current locale. */ # ifndef decimal_point_char_defined @@ -554,7 +639,8 @@ divide (mpn_t a, mpn_t b, mpn_t *q) mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ /* Determine s = GMP_LIMB_BITS - integer_length (msd). Code copied from gnulib's integer_length.c. */ -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \ + || (__clang_major__ >= 4) s = __builtin_clz (msd); # else # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT @@ -829,8 +915,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q) q_ptr[q_len++] = 1; } keep_q: - if (tmp_roomptr != NULL) - free (tmp_roomptr); + free (tmp_roomptr); q->limbs = q_ptr; q->nlimbs = q_len; return roomptr; @@ -849,7 +934,9 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes) size_t a_len = a.nlimbs; /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); - char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); + /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the + digits of a, followed by 1 byte for the terminating NUL. */ + char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1)); if (c_ptr != NULL) { char *d_ptr = c_ptr; @@ -1517,7 +1604,7 @@ is_borderline (const char *digits, size_t precision) #endif -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF /* Use a different function name, to make it possible that the 'wchar_t' parametrization and the 'char' parametrization get compiled in the same @@ -1540,16 +1627,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, switch (conversion) { case 'd': case 'i': case 'u': -# if HAVE_LONG_LONG_INT if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.30103 /* binary -> decimal */ ) + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + else if (type == TYPE_LONGINT || type == TYPE_ULONGINT) tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.30103 /* binary -> decimal */ @@ -1570,16 +1654,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, break; case 'o': -# if HAVE_LONG_LONG_INT if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.333334 /* binary -> octal */ ) + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + else if (type == TYPE_LONGINT || type == TYPE_ULONGINT) tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.333334 /* binary -> octal */ @@ -1598,16 +1679,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, break; case 'x': case 'X': -# if HAVE_LONG_LONG_INT if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */ ) + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + else if (type == TYPE_LONGINT || type == TYPE_ULONGINT) tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */ @@ -1673,7 +1751,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, case 'c': # if HAVE_WINT_T && !WIDE_CHAR_VERSION if (type == TYPE_WIDE_CHAR) - tmp_length = MB_CUR_MAX; + { + tmp_length = MB_CUR_MAX; +# if ENABLE_WCHAR_FALLBACK + if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6)) + tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6); +# endif + } else # endif tmp_length = 1; @@ -1780,6 +1864,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* errno is already set. */ return NULL; + /* Frees the memory allocated by this function. Preserves errno. */ #define CLEANUP() \ if (d.dir != d.direct_alloc_dir) \ free (d.dir); \ @@ -1787,11 +1872,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, free (a.arg); if (PRINTF_FETCHARGS (args, &a) < 0) - { - CLEANUP (); - errno = EINVAL; - return NULL; - } + goto fail_1_with_EINVAL; { size_t buf_neededlength; @@ -1827,24 +1908,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, buf_malloced = buf; } - if (resultbuf != NULL) - { - result = resultbuf; - allocated = *lengthp; - } - else - { - result = NULL; - allocated = 0; - } + result = resultbuf; + allocated = (resultbuf != NULL ? *lengthp : 0); length = 0; /* Invariants: - result is either == resultbuf or == NULL or malloc-allocated. + result is either == resultbuf or malloc-allocated. + If result == NULL, resultbuf is == NULL as well. If length > 0, then result != NULL. */ /* Ensures that allocated >= needed. Aborts through a jump to out_of_memory if needed is SIZE_MAX or otherwise too big. */ -#define ENSURE_ALLOCATION(needed) \ +#define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \ if ((needed) > allocated) \ { \ size_t memory_size; \ @@ -1855,17 +1929,19 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, allocated = (needed); \ memory_size = xtimes (allocated, sizeof (DCHAR_T)); \ if (size_overflow_p (memory_size)) \ - goto out_of_memory; \ - if (result == resultbuf || result == NULL) \ + oom_statement \ + if (result == resultbuf) \ memory = (DCHAR_T *) malloc (memory_size); \ else \ memory = (DCHAR_T *) realloc (result, memory_size); \ if (memory == NULL) \ - goto out_of_memory; \ + oom_statement \ if (result == resultbuf && length > 0) \ DCHAR_CPY (memory, result, length); \ result = memory; \ } +#define ENSURE_ALLOCATION(needed) \ + ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; ) for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) { @@ -1886,7 +1962,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, else { do - result[length++] = (unsigned char) *cp++; + result[length++] = *cp++; while (--n > 0); } } @@ -1926,11 +2002,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, case TYPE_COUNT_LONGINT_POINTER: *a.arg[dp->arg_index].a.a_count_longint_pointer = length; break; -#if HAVE_LONG_LONG_INT case TYPE_COUNT_LONGLONGINT_POINTER: *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; break; -#endif default: abort (); } @@ -1957,15 +2031,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; + width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = (unsigned int) (-arg); + width = -width; } - else - width = arg; } else { @@ -2027,15 +2100,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (count == 0) break; if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2052,15 +2117,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (count == 0) break; if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2073,8 +2130,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) + if (characters < width && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2107,19 +2163,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, converted, &converted_len); # endif if (converted == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } + goto fail_with_errno; if (converted != result + length) { - ENSURE_ALLOCATION (xsum (length, converted_len)); + ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), + { free (converted); goto out_of_memory; }); DCHAR_CPY (result + length, converted, converted_len); free (converted); } @@ -2127,8 +2175,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } # endif - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) + if (characters < width && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2155,15 +2202,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (count == 0) break; if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2180,15 +2219,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (count == 0) break; if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2201,8 +2232,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) + if (characters < width && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2235,19 +2265,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, converted, &converted_len); # endif if (converted == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } + goto fail_with_errno; if (converted != result + length) { - ENSURE_ALLOCATION (xsum (length, converted_len)); + ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), + { free (converted); goto out_of_memory; }); DCHAR_CPY (result + length, converted, converted_len); free (converted); } @@ -2255,8 +2277,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } # endif - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) + if (characters < width && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2283,15 +2304,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (count == 0) break; if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2308,15 +2321,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (count == 0) break; if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2329,8 +2334,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) + if (characters < width && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2363,19 +2367,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, converted, &converted_len); # endif if (converted == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } + goto fail_with_errno; if (converted != result + length) { - ENSURE_ALLOCATION (xsum (length, converted_len)); + ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), + { free (converted); goto out_of_memory; }); DCHAR_CPY (result + length, converted, converted_len); free (converted); } @@ -2383,8 +2379,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } # endif - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) + if (characters < width && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2399,7 +2394,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } } #endif -#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T else if (dp->conversion == 's' # if WIDE_CHAR_VERSION && a.arg[dp->arg_index].type != TYPE_WIDE_STRING @@ -2435,15 +2430,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; + width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = (unsigned int) (-arg); + width = -width; } - else - width = arg; } else { @@ -2515,16 +2509,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* Found the terminating NUL. */ break; if (count < 0) - { - /* Invalid or incomplete multibyte character. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + /* Invalid or incomplete multibyte character. */ + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2551,16 +2537,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* Found the terminating NUL. */ break; if (count < 0) - { - /* Invalid or incomplete multibyte character. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + /* Invalid or incomplete multibyte character. */ + goto fail_with_EILSEQ; arg_end += count; characters++; } @@ -2573,8 +2551,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) + if (characters < width && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2635,8 +2612,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } } - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) + if (characters < width && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2677,23 +2653,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (*arg_end == 0) /* Found the terminating null wide character. */ break; -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg_end, &state); -# else - count = wctomb (cbuf, *arg_end); -# endif + count = local_wcrtomb (cbuf, *arg_end, &state); if (count < 0) - { - /* Cannot convert. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - if (precision < count) + /* Cannot convert. */ + goto fail_with_EILSEQ; + if (precision < (unsigned int) count) break; arg_end++; characters += count; @@ -2722,22 +2686,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (*arg_end == 0) /* Found the terminating null wide character. */ break; -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg_end, &state); -# else - count = wctomb (cbuf, *arg_end); -# endif + count = local_wcrtomb (cbuf, *arg_end, &state); if (count < 0) - { - /* Cannot convert. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + /* Cannot convert. */ + goto fail_with_EILSEQ; arg_end++; characters += count; } @@ -2771,11 +2723,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (*arg == 0) abort (); -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg, &state); -# else - count = wctomb (cbuf, *arg); -# endif + count = local_wcrtomb (cbuf, *arg, &state); if (count <= 0) /* Inconsistency. */ abort (); @@ -2797,15 +2745,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, NULL, &tmpdst_len); if (tmpdst == NULL) { - int saved_errno = errno; free (tmpsrc); - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; + goto fail_with_errno; } free (tmpsrc); # endif @@ -2827,8 +2768,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* w doesn't matter. */ w = 0; - if (has_width && width > w - && !(dp->flags & FLAG_LEFT)) + if (w < width && !(dp->flags & FLAG_LEFT)) { size_t n = width - w; ENSURE_ALLOCATION (xsum (length, n)); @@ -2853,11 +2793,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (*arg == 0) abort (); -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg, &state); -# else - count = wctomb (cbuf, *arg); -# endif + count = local_wcrtomb (cbuf, *arg, &state); if (count <= 0) /* Inconsistency. */ abort (); @@ -2882,22 +2818,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (*arg == 0) abort (); -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg, &state); -# else - count = wctomb (cbuf, *arg); -# endif + count = local_wcrtomb (cbuf, *arg, &state); if (count <= 0) - { - /* Cannot convert. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } + /* Cannot convert. */ + goto fail_with_EILSEQ; ENSURE_ALLOCATION (xsum (length, count)); memcpy (result + length, cbuf, count); length += count; @@ -2905,14 +2829,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } } # else - ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), + { free (tmpdst); goto out_of_memory; }); DCHAR_CPY (result + length, tmpdst, tmpdst_len); free (tmpdst); length += tmpdst_len; # endif - if (has_width && width > w - && (dp->flags & FLAG_LEFT)) + if (w < width && (dp->flags & FLAG_LEFT)) { size_t n = width - w; ENSURE_ALLOCATION (xsum (length, n)); @@ -2923,6 +2847,202 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, # endif } #endif +#if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION + else if (dp->conversion == 'c' + && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR) + { + /* Implement the 'lc' directive ourselves, in order to provide + the fallback that avoids EILSEQ. */ + int flags = dp->flags; + int has_width; + size_t width; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + width = arg; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = -width; + } + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + /* %lc in vasnprintf. See the specification of fprintf. */ + { + wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char; + size_t characters; +# if !DCHAR_IS_TCHAR + /* This code assumes that TCHAR_T is 'char'. */ + verify (sizeof (TCHAR_T) == 1); + TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */ + DCHAR_T *tmpdst; + size_t tmpdst_len; +# endif + size_t w; + +# if DCHAR_IS_TCHAR + if (has_width) +# endif + { + /* Count the number of bytes. */ + characters = 0; + if (arg != 0) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + + count = local_wcrtomb (cbuf, arg, &state); + if (count < 0) + /* Inconsistency. */ + abort (); + characters = count; + } + } +# if DCHAR_IS_TCHAR + else + { + /* The number of bytes doesn't matter. */ + characters = 0; + } +# endif + +# if !DCHAR_IS_TCHAR + /* Convert the string into a piece of temporary memory. */ + if (characters > 0) /* implies arg != 0 */ + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + + count = local_wcrtomb (cbuf, arg, &state); + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (tmpsrc, cbuf, count); + } + + /* Convert from TCHAR_T[] to DCHAR_T[]. */ + tmpdst = + DCHAR_CONV_FROM_ENCODING (locale_charset (), + iconveh_question_mark, + tmpsrc, characters, + NULL, + NULL, &tmpdst_len); + if (tmpdst == NULL) + goto fail_with_errno; +# endif + + if (has_width) + { +# if ENABLE_UNISTDIO + /* Outside POSIX, it's preferable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, characters); +# else + /* The width is compared against the number of _bytes_ + of the converted value, says POSIX. */ + w = characters; +# endif + } + else + /* w doesn't matter. */ + w = 0; + + if (w < width && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_TCHAR + if (has_width) + { + /* We know the number of bytes in advance. */ + ENSURE_ALLOCATION (xsum (length, characters)); + if (characters > 0) /* implies arg != 0 */ + { + int count; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + + count = local_wcrtomb (result + length, arg, &state); + if (count <= 0) + /* Inconsistency. */ + abort (); + length += count; + } + } + else + { + if (arg != 0) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + + count = local_wcrtomb (cbuf, arg, &state); + if (count <= 0) + /* Inconsistency. */ + abort (); + ENSURE_ALLOCATION (xsum (length, count)); + memcpy (result + length, cbuf, count); + length += count; + } + } +# else + ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), + { free (tmpdst); goto out_of_memory; }); + DCHAR_CPY (result + length, tmpdst, tmpdst_len); + free (tmpdst); + length += tmpdst_len; +# endif + + if (w < width && (dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + } +#endif #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL else if ((dp->conversion == 'a' || dp->conversion == 'A') # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE)) @@ -2939,17 +3059,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { arg_type type = a.arg[dp->arg_index].type; int flags = dp->flags; - int has_width; size_t width; int has_precision; size_t precision; size_t tmp_length; + size_t count; DCHAR_T tmpbuf[700]; DCHAR_T *tmp; DCHAR_T *pad_ptr; DCHAR_T *p; - has_width = 0; width = 0; if (dp->width_start != dp->width_end) { @@ -2960,15 +3079,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; + width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = (unsigned int) (-arg); + width = -width; } - else - width = arg; } else { @@ -2978,7 +3096,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, width = xsum (xtimes (width, 10), *digitp++ - '0'); while (digitp != dp->width_end); } - has_width = 1; } has_precision = 0; @@ -3354,11 +3471,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, abort (); # endif } + /* The generated string now extends from tmp to p, with the zero padding insertion point being at pad_ptr. */ - if (has_width && p - tmp < width) + count = p - tmp; + + if (count < width) { - size_t pad = width - (p - tmp); + size_t pad = width - count; DCHAR_T *end = p + pad; if (flags & FLAG_LEFT) @@ -3391,28 +3511,26 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, p = end; } - { - size_t count = p - tmp; + count = p - tmp; - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); - ENSURE_ALLOCATION (n); - } + ENSURE_ALLOCATION (n); + } - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; - } + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; } #endif #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL @@ -3446,8 +3564,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, arg_type type = a.arg[dp->arg_index].type; # endif int flags = dp->flags; - int has_width; size_t width; + size_t count; int has_precision; size_t precision; size_t tmp_length; @@ -3456,7 +3574,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, DCHAR_T *pad_ptr; DCHAR_T *p; - has_width = 0; width = 0; if (dp->width_start != dp->width_end) { @@ -3467,15 +3584,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; + width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = (unsigned int) (-arg); + width = -width; } - else - width = arg; } else { @@ -3485,7 +3601,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, width = xsum (xtimes (width, 10), *digitp++ - '0'); while (digitp != dp->width_end); } - has_width = 1; } has_precision = 0; @@ -3925,9 +4040,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, digits without trailing zeroes. */ if (exponent >= 0) { - size_t count = exponent + 1; + size_t ecount = exponent + 1; /* Note: count <= precision = ndigits. */ - for (; count > 0; count--) + for (; ecount > 0; ecount--) *p++ = digits[--ndigits]; if ((flags & FLAG_ALT) || ndigits > nzeroes) { @@ -3941,10 +4056,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } else { - size_t count = -exponent - 1; + size_t ecount = -exponent - 1; *p++ = '0'; *p++ = decimal_point_char (); - for (; count > 0; count--) + for (; ecount > 0; ecount--) *p++ = '0'; while (ndigits > nzeroes) { @@ -4249,7 +4364,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, static const wchar_t decimal_format[] = /* Produce the same number of exponent digits as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ { '%', '+', '.', '3', 'd', '\0' }; # else { '%', '+', '.', '2', 'd', '\0' }; @@ -4263,7 +4378,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, static const char decimal_format[] = /* Produce the same number of exponent digits as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ "%+.3d"; # else "%+.2d"; @@ -4395,9 +4510,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, digits without trailing zeroes. */ if (exponent >= 0) { - size_t count = exponent + 1; - /* Note: count <= precision = ndigits. */ - for (; count > 0; count--) + size_t ecount = exponent + 1; + /* Note: ecount <= precision = ndigits. */ + for (; ecount > 0; ecount--) *p++ = digits[--ndigits]; if ((flags & FLAG_ALT) || ndigits > nzeroes) { @@ -4411,10 +4526,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } else { - size_t count = -exponent - 1; + size_t ecount = -exponent - 1; *p++ = '0'; *p++ = decimal_point_char (); - for (; count > 0; count--) + for (; ecount > 0; ecount--) *p++ = '0'; while (ndigits > nzeroes) { @@ -4442,7 +4557,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, static const wchar_t decimal_format[] = /* Produce the same number of exponent digits as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ { '%', '+', '.', '3', 'd', '\0' }; # else { '%', '+', '.', '2', 'd', '\0' }; @@ -4456,7 +4571,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, static const char decimal_format[] = /* Produce the same number of exponent digits as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ "%+.3d"; # else "%+.2d"; @@ -4514,7 +4629,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, *p++ = '+'; /* Produce the same number of exponent digits as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if defined _WIN32 && ! defined __CYGWIN__ *p++ = '0'; # endif *p++ = '0'; @@ -4542,9 +4657,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* The generated string now extends from tmp to p, with the zero padding insertion point being at pad_ptr. */ - if (has_width && p - tmp < width) + count = p - tmp; + + if (count < width) { - size_t pad = width - (p - tmp); + size_t pad = width - count; DCHAR_T *end = p + pad; if (flags & FLAG_LEFT) @@ -4577,39 +4694,39 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, p = end; } - { - size_t count = p - tmp; + count = p - tmp; - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); - ENSURE_ALLOCATION (n); - } + ENSURE_ALLOCATION (n); + } - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; - } + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; } #endif else { arg_type type = a.arg[dp->arg_index].type; int flags = dp->flags; -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION int has_width; +#endif +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION size_t width; #endif -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION int has_precision; size_t precision; #endif @@ -4635,8 +4752,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, TCHAR_T *tmp; #endif -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION has_width = 0; +#endif +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION width = 0; if (dp->width_start != dp->width_end) { @@ -4647,15 +4766,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; + width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = (unsigned int) (-arg); + width = -width; } - else - width = arg; } else { @@ -4665,11 +4783,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, width = xsum (xtimes (width, 10), *digitp++ - '0'); while (digitp != dp->width_end); } +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION has_width = 1; +#endif } #endif -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION has_precision = 0; precision = 6; if (dp->precision_start != dp->precision_end) @@ -4805,7 +4925,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { const FCHAR_T *mp = dp->width_start; do - *fbp++ = (unsigned char) *mp++; + *fbp++ = *mp++; while (--n > 0); } } @@ -4826,7 +4946,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { const FCHAR_T *mp = dp->precision_start; do - *fbp++ = (unsigned char) *mp++; + *fbp++ = *mp++; while (--n > 0); } } @@ -4834,19 +4954,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, switch (type) { -#if HAVE_LONG_LONG_INT case TYPE_LONGLONGINT: case TYPE_ULONGLONGINT: -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +#if defined _WIN32 && ! defined __CYGWIN__ *fbp++ = 'I'; *fbp++ = '6'; *fbp++ = '4'; break; -# else +#else *fbp++ = 'l'; - /*FALLTHROUGH*/ -# endif #endif + FALLTHROUGH; case TYPE_LONGINT: case TYPE_ULONGINT: #if HAVE_WINT_T @@ -4870,20 +4988,32 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, #endif *fbp = dp->conversion; #if USE_SNPRINTF -# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) - fbp[1] = '%'; - fbp[2] = 'n'; - fbp[3] = '\0'; -# else - /* On glibc2 systems from glibc >= 2.3 - probably also older - ones - we know that snprintf's return value conforms to - ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and - gl_SNPRINTF_TRUNCATION_C99 pass. - Therefore we can avoid using %n in this situation. - On glibc2 systems from 2004-10-18 or newer, the use of %n - in format strings in writable memory may crash the program - (if compiled with _FORTIFY_SOURCE=2), so we should avoid it - in this situation. */ +# if ((HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99) \ + || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \ + && !defined __UCLIBC__) \ + || (defined __APPLE__ && defined __MACH__) \ + || defined __ANDROID__ \ + || (defined _WIN32 && ! defined __CYGWIN__)) + /* On systems where we know that snprintf's return value + conforms to ISO C 99 (HAVE_SNPRINTF_RETVAL_C99) and that + snprintf always produces NUL-terminated strings + (HAVE_SNPRINTF_TRUNCATION_C99), it is possible to avoid + using %n. And it is desirable to do so, because more and + more platforms no longer support %n, for "security reasons". + In particular, the following platforms: + - On glibc2 systems from 2004-10-18 or newer, the use of + %n in format strings in writable memory may crash the + program (if compiled with _FORTIFY_SOURCE=2). + - On Mac OS X 10.13 or newer, the use of %n in format + strings in writable memory by default crashes the + program. + - On Android, starting on 2018-03-07, the use of %n in + format strings produces a fatal error (see + ). + On these platforms, HAVE_SNPRINTF_RETVAL_C99 and + HAVE_SNPRINTF_TRUNCATION_C99 are 1. We have listed them + explicitly in the condition above, in case of cross- + compilation (just to be sure). */ /* On native Windows systems (such as mingw), we can avoid using %n because: - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, @@ -4896,10 +5026,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, On native Windows systems (such as mingw) where the OS is Windows Vista, the use of %n in format strings by default crashes the program. See - and - + and + So we should avoid %n in this situation. */ fbp[1] = '\0'; +# else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */ + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; # endif #else fbp[1] = '\0'; @@ -5043,7 +5177,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, SNPRINTF_BUF (arg); } break; -#if HAVE_LONG_LONG_INT case TYPE_LONGLONGINT: { long long int arg = a.arg[dp->arg_index].a.a_longlongint; @@ -5056,7 +5189,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, SNPRINTF_BUF (arg); } break; -#endif case TYPE_DOUBLE: { double arg = a.arg[dp->arg_index].a.a_double; @@ -5116,7 +5248,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { /* Verify that snprintf() has NUL-terminated its result. */ - if (count < maxlen + if ((unsigned int) count < maxlen && ((TCHAR_T *) (result + length)) [count] != '\0') abort (); /* Portability hack. */ @@ -5139,7 +5271,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* Look at the snprintf() return value. */ if (retcount < 0) { -# if !HAVE_SNPRINTF_RETVAL_C99 +# if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF /* HP-UX 10.20 snprintf() is doubly deficient: It doesn't understand the '%n' directive, *and* it returns -1 (rather than the length @@ -5153,7 +5285,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, size_t tmp_length = MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type, flags, - has_width ? width : 0, + width, has_precision, precision, pad_ourselves); @@ -5188,22 +5320,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* Attempt to handle failure. */ if (count < 0) { - /* SNPRINTF or sprintf failed. Save and use the errno - that it has set, if any. */ - int saved_errno = errno; - - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = - (saved_errno != 0 - ? saved_errno - : (dp->conversion == 'c' || dp->conversion == 's' - ? EILSEQ - : EINVAL)); - return NULL; + /* SNPRINTF or sprintf failed. Use the errno that it + has set, if any. */ + if (errno == 0) + { + if (dp->conversion == 'c' || dp->conversion == 's') + errno = EILSEQ; + else + errno = EINVAL; + } + + goto fail_with_errno; } #if USE_SNPRINTF @@ -5337,17 +5464,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, NULL, NULL, &tmpdst_len); if (tmpdst == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + goto fail_with_errno; + ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), + { free (tmpdst); goto out_of_memory; }); DCHAR_CPY (result + length, tmpdst, tmpdst_len); free (tmpdst); count = tmpdst_len; @@ -5391,7 +5510,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, tmpsrc += count; tmpdst += count; for (n = count; n > 0; n--) - *--tmpdst = (unsigned char) *--tmpsrc; + *--tmpdst = *--tmpsrc; } } #endif @@ -5570,25 +5689,40 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, #if USE_SNPRINTF overflow: - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); errno = EOVERFLOW; - return NULL; + goto fail_with_errno; #endif out_of_memory: - if (!(result == resultbuf || result == NULL)) + errno = ENOMEM; + goto fail_with_errno; + +#if ENABLE_UNISTDIO || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) + fail_with_EILSEQ: + errno = EILSEQ; + goto fail_with_errno; +#endif + + fail_with_errno: + if (result != resultbuf) free (result); if (buf_malloced != NULL) free (buf_malloced); - out_of_memory_1: CLEANUP (); - errno = ENOMEM; return NULL; } + + out_of_memory_1: + errno = ENOMEM; + goto fail_1_with_errno; + + fail_1_with_EINVAL: + errno = EINVAL; + goto fail_1_with_errno; + + fail_1_with_errno: + CLEANUP (); + return NULL; } #undef MAX_ROOM_NEEDED diff --git a/gl/vasnprintf.h b/gl/vasnprintf.h index 7658f505..27cf54c5 100644 --- a/gl/vasnprintf.h +++ b/gl/vasnprintf.h @@ -1,18 +1,18 @@ /* vsprintf with automatic memory allocation. - Copyright (C) 2002-2004, 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2002-2004, 2007-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _VASNPRINTF_H #define _VASNPRINTF_H @@ -23,17 +23,8 @@ /* Get size_t. */ #include -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif +/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD. */ +#include #ifdef __cplusplus extern "C" { @@ -67,10 +58,12 @@ extern "C" { # define asnprintf rpl_asnprintf # define vasnprintf rpl_vasnprintf #endif -extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); -extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0)); +extern char * asnprintf (char *restrict resultbuf, size_t *lengthp, + const char *format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)); +extern char * vasnprintf (char *restrict resultbuf, size_t *lengthp, + const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0)); #ifdef __cplusplus } diff --git a/gl/vasprintf.c b/gl/vasprintf.c index d0d4a11b..218275f2 100644 --- a/gl/vasprintf.c +++ b/gl/vasprintf.c @@ -1,18 +1,18 @@ /* Formatted output to strings. - Copyright (C) 1999, 2002, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2006-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include diff --git a/gl/verify.h b/gl/verify.h index d42d0750..47b6ee66 100644 --- a/gl/verify.h +++ b/gl/verify.h @@ -1,19 +1,19 @@ /* Compile-time assert-like macros. - Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2006, 2009-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ @@ -21,31 +21,32 @@ #define _GL_VERIFY_H -/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. - This is supported by GCC 4.6.0 and later, in C mode, and its use - here generates easier-to-read diagnostics when verify (R) fails. +/* 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 by clang 4+. - Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. - This will likely be supported by future GCC versions, in C++ mode. + Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as + per C2x. This is supported by GCC 9.1+. - Use this only with GCC. If we were willing to slow 'configure' - down we could also use it with other compilers, but since this - affects only the quality of diagnostics, why bother? */ -#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \ - && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \ - && !defined __cplusplus) -# define _GL_HAVE__STATIC_ASSERT 1 -#endif -/* The condition (99 < __GNUC__) is temporary, until we know about the - first G++ release that supports static_assert. */ -#if (99 < __GNUC__) && defined __cplusplus -# define _GL_HAVE_STATIC_ASSERT 1 + Support compilers claiming conformance to the relevant standard, + and also support GCC when not pedantic. If we were willing to slow + 'configure' down we could also use it with other compilers, but + since this affects only the quality of diagnostics, why bother? */ +#ifndef __cplusplus +# if (201112L <= __STDC_VERSION__ \ + || (!defined __STRICT_ANSI__ \ + && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 5 <= __clang_major__))) +# define _GL_HAVE__STATIC_ASSERT 1 +# endif +# if (202000L <= __STDC_VERSION__ \ + || (!defined __STRICT_ANSI__ && 9 <= __GNUC__)) +# define _GL_HAVE__STATIC_ASSERT1 1 +# endif #endif /* FreeBSD 9.1 , included by and lots of other system headers, defines a conflicting _Static_assert that is no better than ours; override it. */ -#ifndef _GL_HAVE_STATIC_ASSERT +#ifndef _GL_HAVE__STATIC_ASSERT # include # undef _Static_assert #endif @@ -143,9 +144,9 @@ which do not support _Static_assert, also do not warn about the last declaration mentioned above. - * GCC warns if -Wnested-externs is enabled and verify() is used + * GCC warns if -Wnested-externs is enabled and 'verify' is used within a function body; but inside a function, you can always - arrange to use verify_expr() instead. + arrange to use verify_expr instead. * In C++, any struct definition inside sizeof is invalid. Use a template type to work around the problem. */ @@ -197,48 +198,66 @@ template #endif /* Verify requirement R at compile-time, as a declaration without a - trailing ';'. If R is false, fail at compile-time, preferably - with a diagnostic that includes the string-literal DIAGNOSTIC. + trailing ';'. If R is false, fail at compile-time. + + This macro requires three or more arguments but uses at most the first + two, so that the _Static_assert macro optionally defined below supports + both the C11 two-argument syntax and the C2x one-argument syntax. Unfortunately, unlike C11, this implementation must appear as an ordinary declaration, and cannot appear inside struct { ... }. */ -#ifdef _GL_HAVE__STATIC_ASSERT -# define _GL_VERIFY _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) \ +# define _GL_VERIFY(R, DIAGNOSTIC, ...) \ extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] +# if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic ignored "-Wnested-externs" +# endif #endif /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ #ifdef _GL_STATIC_ASSERT_H -# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert -# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) +# if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert +# define _Static_assert(...) \ + _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) # endif -# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert +# if __cpp_static_assert < 201411 && !defined static_assert # define static_assert _Static_assert /* C11 requires this #define. */ # endif #endif /* @assert.h omit start@ */ +#if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)) +# define _GL_HAS_BUILTIN_TRAP 1 +#elif defined __has_builtin +# define _GL_HAS_BUILTIN_TRAP __has_builtin (__builtin_trap) +#else +# define _GL_HAS_BUILTIN_TRAP 0 +#endif + +#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) +# define _GL_HAS_BUILTIN_UNREACHABLE 1 +#elif defined __has_builtin +# define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) +#else +# define _GL_HAS_BUILTIN_UNREACHABLE 0 +#endif + /* Each of these macros verifies that its argument R is nonzero. To be portable, R should be an integer constant expression. Unlike assert (R), there is no run-time overhead. There are two macros, since no single macro can be used in all - contexts in C. verify_true (R) is for scalar contexts, including + contexts in C. verify_expr (R, E) is for scalar contexts, including integer constant expression contexts. verify (R) is for declaration contexts, e.g., the top level. */ -/* Verify requirement R at compile-time, as an integer constant expression. - Return 1. This is equivalent to verify_expr (R, 1). - - verify_true is obsolescent; please use verify_expr instead. */ - -#define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") - /* Verify requirement R at compile-time. Return the value of the expression E. */ @@ -246,9 +265,56 @@ template (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) /* Verify requirement R at compile-time, as a declaration without a - trailing ';'. */ + trailing ';'. verify (R) acts like static_assert (R) except that + it is portable to C11/C++14 and earlier, it can issue better + diagnostics, and its name is shorter and may be more convenient. */ + +#ifdef __PGI +/* PGI barfs if R is long. */ +# define verify(R) _GL_VERIFY (R, "verify (...)", -) +#else +# define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) +#endif -#define verify(R) _GL_VERIFY (R, "verify (" #R ")") +/* Assume that R always holds. Behavior is undefined if R is false, + fails to evaluate, or has side effects. + + 'assume (R)' is a directive from the programmer telling the + compiler that R is true so the compiler needn't generate code to + test R. This is why 'assume' is in verify.h: it's related to + static checking (in this case, static checking done by the + programmer), not dynamic checking. + + 'assume (R)' can affect compilation of all the code, not just code + that happens to be executed after the assume (R) is "executed". + For example, if the code mistakenly does 'assert (R); assume (R);' + the compiler is entitled to optimize away the 'assert (R)'. + + Although assuming R can help a compiler generate better code or + diagnostics, performance can suffer if R uses hard-to-optimize + features such as function calls not inlined by the compiler. + + Avoid Clang's __builtin_assume, as it breaks GNU Emacs master + as of 2020-08-23T21:09:49Z!eggert@cs.ucla.edu; see + . It's not known whether this breakage + is a Clang bug or an Emacs bug; play it safe for now. */ + +#if _GL_HAS_BUILTIN_UNREACHABLE +# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) +#elif 1200 <= _MSC_VER +# define assume(R) __assume (R) +#elif 202311L <= __STDC_VERSION__ +# include +# define assume(R) ((R) ? (void) 0 : unreachable ()) +#elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP + /* Doing it this way helps various packages when configured with + --enable-gcc-warnings, which compiles with -Dlint. It's nicer + if 'assume' silences warnings with GCC 3.4 through GCC 4.4.7 (2012). */ +# define assume(R) ((R) ? (void) 0 : __builtin_trap ()) +#else + /* Some older tools grok NOTREACHED, e.g., Oracle Studio 12.6 (2017). */ +# define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) +#endif /* @assert.h omit end@ */ diff --git a/gl/vsnprintf.c b/gl/vsnprintf.c index 7d4dfbed..80999e9b 100644 --- a/gl/vsnprintf.c +++ b/gl/vsnprintf.c @@ -1,19 +1,19 @@ /* Formatted output to strings. - Copyright (C) 2004, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 2004, 2006-2022 Free Software Foundation, Inc. Written by Simon Josefsson and Yoann Vandoorselaere . - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include diff --git a/gl/w32sock.h b/gl/w32sock.h index 44f3a1a0..17db3f12 100644 --- a/gl/w32sock.h +++ b/gl/w32sock.h @@ -1,19 +1,19 @@ /* w32sock.h --- internal auxiliary functions for Windows socket functions - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Paolo Bonzini */ @@ -26,7 +26,11 @@ #include /* Get _get_osfhandle(). */ -#include "msvc-nothrow.h" +#if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +#else +# include +#endif #define FD_TO_SOCKET(fd) ((SOCKET) _get_osfhandle ((fd))) #define SOCKET_TO_FD(fh) (_open_osfhandle ((intptr_t) (fh), O_RDWR | O_BINARY)) diff --git a/gl/wchar.in.h b/gl/wchar.in.h index b6e43627..835ddbe6 100644 --- a/gl/wchar.in.h +++ b/gl/wchar.in.h @@ -1,25 +1,25 @@ /* A substitute for ISO C99 , for platforms that have issues. - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Eric Blake. */ /* * ISO C 99 for platforms that have issues. - * + * * * For now, this just ensures proper prerequisite inclusion order and * the declaration of wcwidth(). @@ -30,15 +30,24 @@ #endif @PRAGMA_COLUMNS@ -#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +#if (((defined __need_mbstate_t || defined __need_wint_t) \ + && !defined __MINGW32__) \ + || (defined __hpux \ + && ((defined _INTTYPES_INCLUDED \ + && !defined _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H) \ + || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) \ + || (defined __MINGW32__ && defined __STRING_H_SOURCED__) \ + || defined _GL_ALREADY_INCLUDING_WCHAR_H) /* Special invocation convention: - - Inside glibc and uClibc header files. + - Inside glibc and uClibc header files, but not MinGW. - On HP-UX 11.00 we have a sequence of nested includes -> -> , and the latter includes , once indirectly -> -> -> and once directly. In both situations 'wint_t' is not yet defined, therefore we cannot provide the function overrides; instead include only the system's . + - With MinGW 3.22, when includes , only some part of + is actually processed, and that doesn't include 'mbstate_t'. - On IRIX 6.5, similarly, we have an include -> , and the latter includes . But here, we have no way to detect whether is completely included or is still being included. */ @@ -56,20 +65,12 @@ # include /* for __GLIBC__ */ #endif -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . - In some builds of uClibc, is nonexistent and wchar_t is defined +/* In some builds of uClibc, is nonexistent and wchar_t is defined by . But avoid namespace pollution on glibc systems. */ #if !(defined __GLIBC__ && !defined __UCLIBC__) # include #endif -#ifndef __GLIBC__ -# include -# include -#endif /* Include the original if it exists. Some builds of uClibc lack it. */ @@ -83,12 +84,43 @@ #ifndef _@GUARD_PREFIX@_WCHAR_H #define _@GUARD_PREFIX@_WCHAR_H +/* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers + that can be freed by passing them as the Ith argument to the + function F. */ +#ifndef _GL_ATTRIBUTE_DEALLOC +# if __GNUC__ >= 11 +# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) +# else +# define _GL_ATTRIBUTE_DEALLOC(f, i) +# endif +#endif + +/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that + can be freed via 'free'; it can be used only after declaring 'free'. */ +/* Applies to: functions. Cannot be used on inline functions. */ +#ifndef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1) +#endif + +/* _GL_ATTRIBUTE_MALLOC declares that the function returns a pointer to freshly + allocated memory. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_MALLOC +# if __GNUC__ >= 3 || defined __clang__ +# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define _GL_ATTRIBUTE_MALLOC +# endif +#endif + /* The __attribute__ feature is available in gcc versions 2.5 and later. The attribute __pure__ was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ +#ifndef _GL_ATTRIBUTE_PURE +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define _GL_ATTRIBUTE_PURE /* empty */ +# endif #endif /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ @@ -105,12 +137,16 @@ # define WEOF -1 # endif #else -/* MSVC defines wint_t as 'unsigned short' in . - This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be - "unchanged by default argument promotions". Override it. */ -# if defined _MSC_VER +/* mingw and MSVC define wint_t as 'unsigned short' in or + . This is too small: ISO C 99 section 7.24.1.(2) says that + wint_t must be "unchanged by default argument promotions". Override it. */ +# if @GNULIBHEADERS_OVERRIDE_WINT_T@ # if !GNULIB_defined_wint_t -# include +# if @HAVE_CRTDEFS_H@ +# include +# else +# include +# endif typedef unsigned int rpl_wint_t; # undef wint_t # define wint_t rpl_wint_t @@ -125,16 +161,59 @@ typedef unsigned int rpl_wint_t; /* Override mbstate_t if it is too small. On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for - implementing mbrtowc for encodings like UTF-8. */ -#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ + implementing mbrtowc for encodings like UTF-8. + On AIX and MSVC, mbrtowc needs to be overridden, but mbstate_t exists and is + large enough and overriding it would cause problems in C++ mode. */ +#if !(((defined _WIN32 && !defined __CYGWIN__) || @HAVE_MBSINIT@) && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ # if !GNULIB_defined_mbstate_t +# if !(defined _AIX || defined _MSC_VER) typedef int rpl_mbstate_t; -# undef mbstate_t -# define mbstate_t rpl_mbstate_t +# undef mbstate_t +# define mbstate_t rpl_mbstate_t +# endif # define GNULIB_defined_mbstate_t 1 # endif #endif +/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though may not have + been included yet. */ +#if @GNULIB_FREE_POSIX@ +# if (@REPLACE_FREE@ && !defined free \ + && !(defined __cplusplus && defined GNULIB_NAMESPACE)) +/* We can't do '#define free rpl_free' here. */ +_GL_EXTERN_C void rpl_free (void *); +# undef _GL_ATTRIBUTE_DEALLOC_FREE +# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1) +# else +# if defined _MSC_VER && !defined free +_GL_EXTERN_C +# if defined _DLL + __declspec (dllimport) +# endif + void __cdecl free (void *); +# else +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void free (void *) throw (); +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +# endif +#else +# if defined _MSC_VER && !defined free +_GL_EXTERN_C +# if defined _DLL + __declspec (dllimport) +# endif + void __cdecl free (void *); +# else +# if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) +_GL_EXTERN_C void free (void *) throw (); +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +#endif /* Convert a single-byte character to a wide character. */ #if @GNULIB_BTOWC@ @@ -149,9 +228,12 @@ _GL_CXXALIAS_RPL (btowc, wint_t, (int c)); # if !@HAVE_BTOWC@ _GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); # endif -_GL_CXXALIAS_SYS (btowc, wint_t, (int c)); +/* Need to cast, because on mingw, the return type is 'unsigned short'. */ +_GL_CXXALIAS_SYS_CAST (btowc, wint_t, (int c)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (btowc); +# endif #elif defined GNULIB_POSIXCHECK # undef btowc # if HAVE_RAW_DECL_BTOWC @@ -177,7 +259,9 @@ _GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); # endif _GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wctob); +# endif #elif defined GNULIB_POSIXCHECK # undef wctob # if HAVE_RAW_DECL_WCTOB @@ -202,7 +286,9 @@ _GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps)); # endif _GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (mbsinit); +# endif #elif defined GNULIB_POSIXCHECK # undef mbsinit # if HAVE_RAW_DECL_MBSINIT @@ -220,18 +306,24 @@ _GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - " # define mbrtowc rpl_mbrtowc # endif _GL_FUNCDECL_RPL (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); + (wchar_t *restrict pwc, const char *restrict s, size_t n, + mbstate_t *restrict ps)); _GL_CXXALIAS_RPL (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); + (wchar_t *restrict pwc, const char *restrict s, size_t n, + mbstate_t *restrict ps)); # else # if !@HAVE_MBRTOWC@ _GL_FUNCDECL_SYS (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); + (wchar_t *restrict pwc, const char *restrict s, size_t n, + mbstate_t *restrict ps)); # endif _GL_CXXALIAS_SYS (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); + (wchar_t *restrict pwc, const char *restrict s, size_t n, + mbstate_t *restrict ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (mbrtowc); +# endif #elif defined GNULIB_POSIXCHECK # undef mbrtowc # if HAVE_RAW_DECL_MBRTOWC @@ -248,15 +340,21 @@ _GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - " # undef mbrlen # define mbrlen rpl_mbrlen # endif -_GL_FUNCDECL_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); -_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +_GL_FUNCDECL_RPL (mbrlen, size_t, + (const char *restrict s, size_t n, mbstate_t *restrict ps)); +_GL_CXXALIAS_RPL (mbrlen, size_t, + (const char *restrict s, size_t n, mbstate_t *restrict ps)); # else # if !@HAVE_MBRLEN@ -_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +_GL_FUNCDECL_SYS (mbrlen, size_t, + (const char *restrict s, size_t n, mbstate_t *restrict ps)); # endif -_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +_GL_CXXALIAS_SYS (mbrlen, size_t, + (const char *restrict s, size_t n, mbstate_t *restrict ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (mbrlen); +# endif #elif defined GNULIB_POSIXCHECK # undef mbrlen # if HAVE_RAW_DECL_MBRLEN @@ -274,22 +372,30 @@ _GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - " # define mbsrtowcs rpl_mbsrtowcs # endif _GL_FUNCDECL_RPL (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) + (wchar_t *restrict dest, + const char **restrict srcp, size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, - mbstate_t *ps)); + (wchar_t *restrict dest, + const char **restrict srcp, size_t len, + mbstate_t *restrict ps)); # else # if !@HAVE_MBSRTOWCS@ _GL_FUNCDECL_SYS (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) + (wchar_t *restrict dest, + const char **restrict srcp, size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); # endif _GL_CXXALIAS_SYS (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, - mbstate_t *ps)); + (wchar_t *restrict dest, + const char **restrict srcp, size_t len, + mbstate_t *restrict ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (mbsrtowcs); +# endif #elif defined GNULIB_POSIXCHECK # undef mbsrtowcs # if HAVE_RAW_DECL_MBSRTOWCS @@ -307,22 +413,26 @@ _GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - " # define mbsnrtowcs rpl_mbsnrtowcs # endif _GL_FUNCDECL_RPL (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps) + (wchar_t *restrict dest, + const char **restrict srcp, size_t srclen, size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps)); + (wchar_t *restrict dest, + const char **restrict srcp, size_t srclen, size_t len, + mbstate_t *restrict ps)); # else # if !@HAVE_MBSNRTOWCS@ _GL_FUNCDECL_SYS (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps) + (wchar_t *restrict dest, + const char **restrict srcp, size_t srclen, size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); # endif _GL_CXXALIAS_SYS (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps)); + (wchar_t *restrict dest, + const char **restrict srcp, size_t srclen, size_t len, + mbstate_t *restrict ps)); # endif _GL_CXXALIASWARN (mbsnrtowcs); #elif defined GNULIB_POSIXCHECK @@ -341,15 +451,21 @@ _GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - " # undef wcrtomb # define wcrtomb rpl_wcrtomb # endif -_GL_FUNCDECL_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); -_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +_GL_FUNCDECL_RPL (wcrtomb, size_t, + (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); +_GL_CXXALIAS_RPL (wcrtomb, size_t, + (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); # else # if !@HAVE_WCRTOMB@ -_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +_GL_FUNCDECL_SYS (wcrtomb, size_t, + (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); # endif -_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +_GL_CXXALIAS_SYS (wcrtomb, size_t, + (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcrtomb); +# endif #elif defined GNULIB_POSIXCHECK # undef wcrtomb # if HAVE_RAW_DECL_WCRTOMB @@ -367,22 +483,30 @@ _GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - " # define wcsrtombs rpl_wcsrtombs # endif _GL_FUNCDECL_RPL (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) + (char *restrict dest, const wchar_t **restrict srcp, + size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, - mbstate_t *ps)); + (char *restrict dest, const wchar_t **restrict srcp, + size_t len, + mbstate_t *restrict ps)); # else # if !@HAVE_WCSRTOMBS@ _GL_FUNCDECL_SYS (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) + (char *restrict dest, const wchar_t **restrict srcp, + size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); # endif _GL_CXXALIAS_SYS (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, - mbstate_t *ps)); + (char *restrict dest, const wchar_t **restrict srcp, + size_t len, + mbstate_t *restrict ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsrtombs); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsrtombs # if HAVE_RAW_DECL_WCSRTOMBS @@ -400,24 +524,34 @@ _GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - " # define wcsnrtombs rpl_wcsnrtombs # endif _GL_FUNCDECL_RPL (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps) + (char *restrict dest, + const wchar_t **restrict srcp, size_t srclen, + size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); _GL_CXXALIAS_RPL (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps)); + (char *restrict dest, + const wchar_t **restrict srcp, size_t srclen, + size_t len, + mbstate_t *restrict ps)); # else -# if !@HAVE_WCSNRTOMBS@ +# if !@HAVE_WCSNRTOMBS@ || (defined __cplusplus && defined __sun) _GL_FUNCDECL_SYS (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps) + (char *restrict dest, + const wchar_t **restrict srcp, size_t srclen, + size_t len, + mbstate_t *restrict ps) _GL_ARG_NONNULL ((2))); # endif _GL_CXXALIAS_SYS (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps)); + (char *restrict dest, + const wchar_t **restrict srcp, size_t srclen, + size_t len, + mbstate_t *restrict ps)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsnrtombs); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsnrtombs # if HAVE_RAW_DECL_WCSNRTOMBS @@ -443,7 +577,9 @@ _GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); # endif _GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcwidth); +# endif #elif defined GNULIB_POSIXCHECK # undef wcwidth # if HAVE_RAW_DECL_WCWIDTH @@ -472,7 +608,7 @@ _GL_CXXALIAS_SYS_CAST2 (wmemchr, _GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); _GL_CXXALIASWARN1 (wmemchr, const wchar_t *, (const wchar_t *s, wchar_t c, size_t n)); -# else +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (wmemchr); # endif #elif defined GNULIB_POSIXCHECK @@ -493,7 +629,9 @@ _GL_FUNCDECL_SYS (wmemcmp, int, # endif _GL_CXXALIAS_SYS (wmemcmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wmemcmp); +# endif #elif defined GNULIB_POSIXCHECK # undef wmemcmp # if HAVE_RAW_DECL_WMEMCMP @@ -507,11 +645,15 @@ _GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " #if @GNULIB_WMEMCPY@ # if !@HAVE_WMEMCPY@ _GL_FUNCDECL_SYS (wmemcpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); # endif _GL_CXXALIAS_SYS (wmemcpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wmemcpy); +# endif #elif defined GNULIB_POSIXCHECK # undef wmemcpy # if HAVE_RAW_DECL_WMEMCPY @@ -530,7 +672,9 @@ _GL_FUNCDECL_SYS (wmemmove, wchar_t *, # endif _GL_CXXALIAS_SYS (wmemmove, wchar_t *, (wchar_t *dest, const wchar_t *src, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wmemmove); +# endif #elif defined GNULIB_POSIXCHECK # undef wmemmove # if HAVE_RAW_DECL_WMEMMOVE @@ -540,13 +684,38 @@ _GL_WARN_ON_USE (wmemmove, "wmemmove is unportable - " #endif +/* Copy N wide characters of SRC to DEST. + Return pointer to wide characters after the last written wide character. */ +#if @GNULIB_WMEMPCPY@ +# if !@HAVE_WMEMPCPY@ +_GL_FUNCDECL_SYS (wmempcpy, wchar_t *, + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wmempcpy, wchar_t *, + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (wmempcpy); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wmempcpy +# if HAVE_RAW_DECL_WMEMPCPY +_GL_WARN_ON_USE (wmempcpy, "wmempcpy is unportable - " + "use gnulib module wmempcpy for portability"); +# endif +#endif + + /* Set N wide characters of S to C. */ #if @GNULIB_WMEMSET@ # if !@HAVE_WMEMSET@ _GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); # endif _GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wmemset); +# endif #elif defined GNULIB_POSIXCHECK # undef wmemset # if HAVE_RAW_DECL_WMEMSET @@ -562,7 +731,9 @@ _GL_WARN_ON_USE (wmemset, "wmemset is unportable - " _GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE); # endif _GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcslen); +# endif #elif defined GNULIB_POSIXCHECK # undef wcslen # if HAVE_RAW_DECL_WCSLEN @@ -592,10 +763,14 @@ _GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - " /* Copy SRC to DEST. */ #if @GNULIB_WCSCPY@ # if !@HAVE_WCSCPY@ -_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_FUNCDECL_SYS (wcscpy, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); # endif -_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_CXXALIAS_SYS (wcscpy, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcscpy); +# endif #elif defined GNULIB_POSIXCHECK # undef wcscpy # if HAVE_RAW_DECL_WCSCPY @@ -608,9 +783,11 @@ _GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - " /* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST. */ #if @GNULIB_WCPCPY@ # if !@HAVE_WCPCPY@ -_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); # endif -_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); _GL_CXXALIASWARN (wcpcpy); #elif defined GNULIB_POSIXCHECK # undef wcpcpy @@ -625,11 +802,15 @@ _GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " #if @GNULIB_WCSNCPY@ # if !@HAVE_WCSNCPY@ _GL_FUNCDECL_SYS (wcsncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); # endif _GL_CXXALIAS_SYS (wcsncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsncpy); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsncpy # if HAVE_RAW_DECL_WCSNCPY @@ -644,10 +825,12 @@ _GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - " #if @GNULIB_WCPNCPY@ # if !@HAVE_WCPNCPY@ _GL_FUNCDECL_SYS (wcpncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); # endif _GL_CXXALIAS_SYS (wcpncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); _GL_CXXALIASWARN (wcpncpy); #elif defined GNULIB_POSIXCHECK # undef wcpncpy @@ -661,10 +844,14 @@ _GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - " /* Append SRC onto DEST. */ #if @GNULIB_WCSCAT@ # if !@HAVE_WCSCAT@ -_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_FUNCDECL_SYS (wcscat, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); # endif -_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); +_GL_CXXALIAS_SYS (wcscat, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcscat); +# endif #elif defined GNULIB_POSIXCHECK # undef wcscat # if HAVE_RAW_DECL_WCSCAT @@ -678,11 +865,15 @@ _GL_WARN_ON_USE (wcscat, "wcscat is unportable - " #if @GNULIB_WCSNCAT@ # if !@HAVE_WCSNCAT@ _GL_FUNCDECL_SYS (wcsncat, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, const wchar_t *restrict src, + size_t n)); # endif _GL_CXXALIAS_SYS (wcsncat, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); + (wchar_t *restrict dest, const wchar_t *restrict src, + size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsncat); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsncat # if HAVE_RAW_DECL_WCSNCAT @@ -699,7 +890,9 @@ _GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2) _GL_ATTRIBUTE_PURE); # endif _GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcscmp); +# endif #elif defined GNULIB_POSIXCHECK # undef wcscmp # if HAVE_RAW_DECL_WCSCMP @@ -718,7 +911,9 @@ _GL_FUNCDECL_SYS (wcsncmp, int, # endif _GL_CXXALIAS_SYS (wcsncmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsncmp); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsncmp # if HAVE_RAW_DECL_WCSNCMP @@ -771,7 +966,9 @@ _GL_WARN_ON_USE (wcsncasecmp, "wcsncasecmp is unportable - " _GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); # endif _GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcscoll); +# endif #elif defined GNULIB_POSIXCHECK # undef wcscoll # if HAVE_RAW_DECL_WCSCOLL @@ -786,10 +983,14 @@ _GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - " original strings. */ #if @GNULIB_WCSXFRM@ # if !@HAVE_WCSXFRM@ -_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); +_GL_FUNCDECL_SYS (wcsxfrm, size_t, + (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n)); # endif -_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); +_GL_CXXALIAS_SYS (wcsxfrm, size_t, + (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsxfrm); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsxfrm # if HAVE_RAW_DECL_WCSXFRM @@ -801,16 +1002,55 @@ _GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - " /* Duplicate S, returning an identical malloc'd string. */ #if @GNULIB_WCSDUP@ -# if !@HAVE_WCSDUP@ -_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s)); -# endif +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsdup +# define wcsdup _wcsdup +# endif +_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s)); +# else +# if !@HAVE_WCSDUP@ || __GNUC__ >= 11 +_GL_FUNCDECL_SYS (wcsdup, wchar_t *, + (const wchar_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +# endif _GL_CXXALIASWARN (wcsdup); -#elif defined GNULIB_POSIXCHECK -# undef wcsdup -# if HAVE_RAW_DECL_WCSDUP +#else +# if __GNUC__ >= 11 && !defined wcsdup +/* For -Wmismatched-dealloc: Associate wcsdup with free or rpl_free. */ +_GL_FUNCDECL_SYS (wcsdup, wchar_t *, + (const wchar_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif +# if defined GNULIB_POSIXCHECK +# undef wcsdup +# if HAVE_RAW_DECL_WCSDUP _GL_WARN_ON_USE (wcsdup, "wcsdup is unportable - " "use gnulib module wcsdup for portability"); +# endif +# elif @GNULIB_MDA_WCSDUP@ +/* On native Windows, map 'wcsdup' to '_wcsdup', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::wcsdup always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsdup +# define wcsdup _wcsdup +# endif +_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s)); +# else +_GL_FUNCDECL_SYS (wcsdup, wchar_t *, + (const wchar_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# if @HAVE_DECL_WCSDUP@ +_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +# endif +# endif +# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_WCSDUP@ +_GL_CXXALIASWARN (wcsdup); +# endif # endif #endif @@ -833,7 +1073,7 @@ _GL_CXXALIAS_SYS_CAST2 (wcschr, && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) _GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); _GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); -# else +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (wcschr); # endif #elif defined GNULIB_POSIXCHECK @@ -863,7 +1103,7 @@ _GL_CXXALIAS_SYS_CAST2 (wcsrchr, && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) _GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); _GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); -# else +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsrchr); # endif #elif defined GNULIB_POSIXCHECK @@ -883,7 +1123,9 @@ _GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject) _GL_ATTRIBUTE_PURE); # endif _GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcscspn); +# endif #elif defined GNULIB_POSIXCHECK # undef wcscspn # if HAVE_RAW_DECL_WCSCSPN @@ -901,7 +1143,9 @@ _GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept) _GL_ATTRIBUTE_PURE); # endif _GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsspn); +# endif #elif defined GNULIB_POSIXCHECK # undef wcsspn # if HAVE_RAW_DECL_WCSSPN @@ -932,7 +1176,7 @@ _GL_CXXALIASWARN1 (wcspbrk, wchar_t *, (wchar_t *wcs, const wchar_t *accept)); _GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, (const wchar_t *wcs, const wchar_t *accept)); -# else +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (wcspbrk); # endif #elif defined GNULIB_POSIXCHECK @@ -948,7 +1192,8 @@ _GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - " #if @GNULIB_WCSSTR@ # if !@HAVE_WCSSTR@ _GL_FUNCDECL_SYS (wcsstr, wchar_t *, - (const wchar_t *haystack, const wchar_t *needle) + (const wchar_t *restrict haystack, + const wchar_t *restrict needle) _GL_ATTRIBUTE_PURE); # endif /* On some systems, this function is defined as an overloaded function: @@ -957,15 +1202,19 @@ _GL_FUNCDECL_SYS (wcsstr, wchar_t *, wchar_t * std::wcsstr (wchar_t *, const wchar_t *); } */ _GL_CXXALIAS_SYS_CAST2 (wcsstr, - wchar_t *, (const wchar_t *, const wchar_t *), - const wchar_t *, (const wchar_t *, const wchar_t *)); + wchar_t *, + (const wchar_t *restrict, const wchar_t *restrict), + const wchar_t *, + (const wchar_t *restrict, const wchar_t *restrict)); # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) _GL_CXXALIASWARN1 (wcsstr, wchar_t *, - (wchar_t *haystack, const wchar_t *needle)); + (wchar_t *restrict haystack, + const wchar_t *restrict needle)); _GL_CXXALIASWARN1 (wcsstr, const wchar_t *, - (const wchar_t *haystack, const wchar_t *needle)); -# else + (const wchar_t *restrict haystack, + const wchar_t *restrict needle)); +# elif __GLIBC__ >= 2 _GL_CXXALIASWARN (wcsstr); # endif #elif defined GNULIB_POSIXCHECK @@ -979,13 +1228,30 @@ _GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - " /* Divide WCS into tokens separated by characters in DELIM. */ #if @GNULIB_WCSTOK@ -# if !@HAVE_WCSTOK@ +# if @REPLACE_WCSTOK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcstok +# define wcstok rpl_wcstok +# endif +_GL_FUNCDECL_RPL (wcstok, wchar_t *, + (wchar_t *restrict wcs, const wchar_t *restrict delim, + wchar_t **restrict ptr)); +_GL_CXXALIAS_RPL (wcstok, wchar_t *, + (wchar_t *restrict wcs, const wchar_t *restrict delim, + wchar_t **restrict ptr)); +# else +# if !@HAVE_WCSTOK@ _GL_FUNCDECL_SYS (wcstok, wchar_t *, - (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); -# endif + (wchar_t *restrict wcs, const wchar_t *restrict delim, + wchar_t **restrict ptr)); +# endif _GL_CXXALIAS_SYS (wcstok, wchar_t *, - (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); + (wchar_t *restrict wcs, const wchar_t *restrict delim, + wchar_t **restrict ptr)); +# endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcstok); +# endif #elif defined GNULIB_POSIXCHECK # undef wcstok # if HAVE_RAW_DECL_WCSTOK @@ -1013,7 +1279,9 @@ _GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n) # endif _GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wcswidth); +# endif #elif defined GNULIB_POSIXCHECK # undef wcswidth # if HAVE_RAW_DECL_WCSWIDTH @@ -1023,6 +1291,48 @@ _GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - " #endif +/* Convert *TP to a date and time wide string. See + . */ +#if @GNULIB_WCSFTIME@ +# if @REPLACE_WCSFTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsftime +# define wcsftime rpl_wcsftime +# endif +_GL_FUNCDECL_RPL (wcsftime, size_t, + (wchar_t *restrict __buf, size_t __bufsize, + const wchar_t *restrict __fmt, + const struct tm *restrict __tp) + _GL_ARG_NONNULL ((1, 3, 4))); +_GL_CXXALIAS_RPL (wcsftime, size_t, + (wchar_t *restrict __buf, size_t __bufsize, + const wchar_t *restrict __fmt, + const struct tm *restrict __tp)); +# else +# if !@HAVE_WCSFTIME@ +_GL_FUNCDECL_SYS (wcsftime, size_t, + (wchar_t *restrict __buf, size_t __bufsize, + const wchar_t *restrict __fmt, + const struct tm *restrict __tp) + _GL_ARG_NONNULL ((1, 3, 4))); +# endif +_GL_CXXALIAS_SYS (wcsftime, size_t, + (wchar_t *restrict __buf, size_t __bufsize, + const wchar_t *restrict __fmt, + const struct tm *restrict __tp)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (wcsftime); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wcsftime +# if HAVE_RAW_DECL_WCSFTIME +_GL_WARN_ON_USE (wcsftime, "wcsftime is unportable - " + "use gnulib module wcsftime for portability"); +# endif +#endif + + #endif /* _@GUARD_PREFIX@_WCHAR_H */ #endif /* _@GUARD_PREFIX@_WCHAR_H */ #endif diff --git a/gl/wcrtomb.c b/gl/wcrtomb.c index da42809b..e14d8022 100644 --- a/gl/wcrtomb.c +++ b/gl/wcrtomb.c @@ -1,19 +1,19 @@ /* Convert wide character to multibyte character. - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2022 Free Software Foundation, Inc. Written by Bruno Haible , 2008. - 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #include @@ -26,20 +26,46 @@ size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps) +#undef wcrtomb { - /* This implementation of wcrtomb on top of wctomb() supports only - stateless encodings. ps must be in the initial state. */ + /* This implementation of wcrtomb supports only stateless encodings. + ps must be in the initial state. */ if (ps != NULL && !mbsinit (ps)) { errno = EINVAL; return (size_t)(-1); } +#if !HAVE_WCRTOMB /* IRIX 6.5 */ \ + || WCRTOMB_RETVAL_BUG /* Solaris 11.3, MSVC */ \ + || WCRTOMB_C_LOCALE_BUG /* Android */ if (s == NULL) /* We know the NUL wide character corresponds to the NUL character. */ return 1; else +#endif { +#if HAVE_WCRTOMB +# if WCRTOMB_C_LOCALE_BUG /* Android */ + /* Implement consistently with mbrtowc(): through a 1:1 correspondence, + as in ISO-8859-1. */ + if (wc >= 0 && wc <= 0xff) + { + *s = (unsigned char) wc; + return 1; + } + else + { + errno = EILSEQ; + return (size_t)(-1); + } +# else + return wcrtomb (s, wc, ps); +# endif +#else /* IRIX 6.5 */ + /* Fallback for platforms that don't have wcrtomb(). + Implement on top of wctomb(). + This code is not multithread-safe. */ int ret = wctomb (s, wc); if (ret >= 0) @@ -49,5 +75,6 @@ wcrtomb (char *s, wchar_t wc, mbstate_t *ps) errno = EILSEQ; return (size_t)(-1); } +#endif } } diff --git a/gl/wctype-h.c b/gl/wctype-h.c index bb5f847e..12781433 100644 --- a/gl/wctype-h.c +++ b/gl/wctype-h.c @@ -1,4 +1,23 @@ +/* Inline functions for . + + Copyright (C) 2012-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + /* Normally this would be wctype.c, but that name's already taken. */ + #include + #define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE #include "wctype.h" diff --git a/gl/wctype.in.h b/gl/wctype.in.h index a7c07d1e..98cafee7 100644 --- a/gl/wctype.in.h +++ b/gl/wctype.in.h @@ -1,54 +1,61 @@ /* A substitute for ISO C99 , for platforms that lack it. - Copyright (C) 2006-2013 Free Software Foundation, Inc. + Copyright (C) 2006-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ /* Written by Bruno Haible and Paul Eggert. */ /* * ISO C 99 for platforms that lack it. - * + * * * iswctype, towctrans, towlower, towupper, wctrans, wctype, * wctrans_t, and wctype_t are not yet implemented. */ -#ifndef _@GUARD_PREFIX@_WCTYPE_H - #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ +#if (defined __MINGW32__ && defined __CTYPE_H_SOURCED__) + +/* Special invocation convention: + - With MinGW 3.22, when includes , only some part of + is being processed, which doesn't include the idempotency + guard. */ + +#@INCLUDE_NEXT@ @NEXT_WCTYPE_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_WCTYPE_H + #if @HAVE_WINT_T@ -/* Solaris 2.5 has a bug: must be included before . - Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -# include -# include -# include +/* Solaris 2.5 has a bug: must be included before . */ # include #endif -/* mingw has declarations of towupper and towlower in as - well . Include in advance to avoid rpl_ prefix - being added to the declarations. */ -#ifdef __MINGW32__ +/* Native Windows (mingw, MSVC) have declarations of towupper, towlower, and + isw* functions in , as well as in . Include + , in advance to avoid rpl_ prefix being added to the + declarations. */ +#if defined _WIN32 && ! defined __CYGWIN__ # include +# include #endif /* Include the original if it exists. @@ -61,6 +68,9 @@ #ifndef _@GUARD_PREFIX@_WCTYPE_H #define _@GUARD_PREFIX@_WCTYPE_H +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif _GL_INLINE_HEADER_BEGIN #ifndef _GL_WCTYPE_INLINE # define _GL_WCTYPE_INLINE _GL_INLINE @@ -90,12 +100,16 @@ _GL_INLINE_HEADER_BEGIN # define WEOF -1 # endif #else -/* MSVC defines wint_t as 'unsigned short' in . - This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be - "unchanged by default argument promotions". Override it. */ -# if defined _MSC_VER +/* mingw and MSVC define wint_t as 'unsigned short' in or + . This is too small: ISO C 99 section 7.24.1.(2) says that + wint_t must be "unchanged by default argument promotions". Override it. */ +# if @GNULIBHEADERS_OVERRIDE_WINT_T@ # if !GNULIB_defined_wint_t -# include +# if @HAVE_CRTDEFS_H@ +# include +# else +# include +# endif typedef unsigned int rpl_wint_t; # undef wint_t # define wint_t rpl_wint_t @@ -112,33 +126,116 @@ typedef unsigned int rpl_wint_t; /* FreeBSD 4.4 to 4.11 has but lacks the functions. Linux libc5 has and the functions but they are broken. + mingw and MSVC have and the functions but they take a wchar_t + as argument, not an rpl_wint_t. Assume all 11 functions (all isw* except iswblank) are implemented the same way, or not at all. */ # if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ -/* IRIX 5.3 has macros but no functions, its isw* macros refer to an - undefined variable _ctmp_ and to macros like _P, and they - refer to system functions like _iswctype that are not in the - standard C library. Rather than try to get ancient buggy - implementations like this to work, just disable them. */ -# undef iswalnum -# undef iswalpha -# undef iswblank -# undef iswcntrl -# undef iswdigit -# undef iswgraph -# undef iswlower -# undef iswprint -# undef iswpunct -# undef iswspace -# undef iswupper -# undef iswxdigit -# undef towlower -# undef towupper +# if @GNULIBHEADERS_OVERRIDE_WINT_T@ /* implies @REPLACE_ISWCNTRL@ */ + +_GL_WCTYPE_INLINE int +rpl_iswalnum (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswalnum ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswalpha (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswalpha ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswblank (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswblank ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswcntrl (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswcntrl ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswdigit (wint_t wc) +{ + return ((wchar_t) wc == wc ? wc >= '0' && wc <= '9' : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswgraph (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswgraph ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswlower (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswlower ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswprint (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswprint ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswpunct (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswpunct ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswspace (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswspace ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswupper (wint_t wc) +{ + return ((wchar_t) wc == wc ? iswupper ((wchar_t) wc) : 0); +} + +_GL_WCTYPE_INLINE int +rpl_iswxdigit (wint_t wc) +{ + return ((wchar_t) wc == wc + ? (wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F') + : 0); +} + +_GL_WCTYPE_INLINE wint_t +rpl_towlower (wint_t wc) +{ + return ((wchar_t) wc == wc ? (wchar_t) towlower ((wchar_t) wc) : wc); +} + +_GL_WCTYPE_INLINE wint_t +rpl_towupper (wint_t wc) +{ + return ((wchar_t) wc == wc ? (wchar_t) towupper ((wchar_t) wc) : wc); +} -/* Linux libc5 has and the functions but they are broken. */ -# if @REPLACE_ISWCNTRL@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef iswalnum +# undef iswalpha +# undef iswblank +# undef iswcntrl +# undef iswdigit +# undef iswgraph +# undef iswlower +# undef iswprint +# undef iswpunct +# undef iswspace +# undef iswupper +# undef iswxdigit +# undef towlower +# undef towupper # define iswalnum rpl_iswalnum # define iswalpha rpl_iswalpha # define iswblank rpl_iswblank @@ -151,21 +248,62 @@ typedef unsigned int rpl_wint_t; # define iswspace rpl_iswspace # define iswupper rpl_iswupper # define iswxdigit rpl_iswxdigit -# endif -# endif -# if @REPLACE_TOWLOWER@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define towlower rpl_towlower # define towupper rpl_towupper # endif -# endif + +# else + +/* IRIX 5.3 has macros but no functions, its isw* macros refer to an + undefined variable _ctmp_ and to macros like _P, and they + refer to system functions like _iswctype that are not in the + standard C library. Rather than try to get ancient buggy + implementations like this to work, just disable them. */ +# undef iswalnum +# undef iswalpha +# undef iswblank +# undef iswcntrl +# undef iswdigit +# undef iswgraph +# undef iswlower +# undef iswprint +# undef iswpunct +# undef iswspace +# undef iswupper +# undef iswxdigit +# undef towlower +# undef towupper + +/* Linux libc5 has and the functions but they are broken. */ +# if @REPLACE_ISWCNTRL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iswalnum rpl_iswalnum +# define iswalpha rpl_iswalpha +# define iswblank rpl_iswblank +# define iswcntrl rpl_iswcntrl +# define iswdigit rpl_iswdigit +# define iswgraph rpl_iswgraph +# define iswlower rpl_iswlower +# define iswprint rpl_iswprint +# define iswpunct rpl_iswpunct +# define iswspace rpl_iswspace +# define iswupper rpl_iswupper +# define iswxdigit rpl_iswxdigit +# endif +# endif +# if @REPLACE_TOWLOWER@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define towlower rpl_towlower +# define towupper rpl_towupper +# endif +# endif _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswalnum -# else +# else iswalnum -# endif +# endif (wint_t wc) { return ((wc >= '0' && wc <= '9') @@ -173,88 +311,88 @@ iswalnum } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswalpha -# else +# else iswalpha -# endif +# endif (wint_t wc) { return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswblank -# else +# else iswblank -# endif +# endif (wint_t wc) { return wc == ' ' || wc == '\t'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswcntrl -# else +# else iswcntrl -# endif +# endif (wint_t wc) { return (wc & ~0x1f) == 0 || wc == 0x7f; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWDIGIT@ rpl_iswdigit -# else +# else iswdigit -# endif +# endif (wint_t wc) { return wc >= '0' && wc <= '9'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswgraph -# else +# else iswgraph -# endif +# endif (wint_t wc) { return wc >= '!' && wc <= '~'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswlower -# else +# else iswlower -# endif +# endif (wint_t wc) { return wc >= 'a' && wc <= 'z'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswprint -# else +# else iswprint -# endif +# endif (wint_t wc) { return wc >= ' ' && wc <= '~'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswpunct -# else +# else iswpunct -# endif +# endif (wint_t wc) { return (wc >= '!' && wc <= '~' @@ -263,11 +401,11 @@ iswpunct } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswspace -# else +# else iswspace -# endif +# endif (wint_t wc) { return (wc == ' ' || wc == '\t' @@ -275,22 +413,22 @@ iswspace } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWCNTRL@ rpl_iswupper -# else +# else iswupper -# endif +# endif (wint_t wc) { return wc >= 'A' && wc <= 'Z'; } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWXDIGIT@ rpl_iswxdigit -# else +# else iswxdigit -# endif +# endif (wint_t wc) { return ((wc >= '0' && wc <= '9') @@ -298,42 +436,67 @@ iswxdigit } _GL_WCTYPE_INLINE wint_t -# if @REPLACE_TOWLOWER@ +# if @REPLACE_TOWLOWER@ rpl_towlower -# else +# else towlower -# endif +# endif (wint_t wc) { return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); } _GL_WCTYPE_INLINE wint_t -# if @REPLACE_TOWLOWER@ +# if @REPLACE_TOWLOWER@ rpl_towupper -# else +# else towupper -# endif +# endif (wint_t wc) { return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); } -# elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) -/* Only the iswblank function is missing. */ +# endif -# if @REPLACE_ISWBLANK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define iswblank rpl_iswblank -# endif +# else +/* Only some of the functions are missing or broken. */ + +# if @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) +/* Only the iswblank function is missing. */ +# if @REPLACE_ISWBLANK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iswblank rpl_iswblank +# endif _GL_FUNCDECL_RPL (iswblank, int, (wint_t wc)); -# else +# else _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); +# endif +# endif + +# if @GNULIB_ISWDIGIT@ +# if @REPLACE_ISWDIGIT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef iswdigit +# define iswdigit rpl_iswdigit +# endif +_GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc)); +# endif +# endif + +# if @GNULIB_ISWXDIGIT@ +# if @REPLACE_ISWXDIGIT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef iswxdigit +# define iswxdigit rpl_iswxdigit +# endif +_GL_FUNCDECL_RPL (iswxdigit, int, (wint_t wc)); +# endif # endif # endif -# if defined __MINGW32__ +# if defined __MINGW32__ && !@GNULIBHEADERS_OVERRIDE_WINT_T@ /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t. The functions towlower and towupper are implemented in the MSVCRT library @@ -366,36 +529,71 @@ rpl_towupper (wint_t wc) # define towupper rpl_towupper # endif -# endif /* __MINGW32__ */ +# endif /* __MINGW32__ && !@GNULIBHEADERS_OVERRIDE_WINT_T@ */ # define GNULIB_defined_wctype_functions 1 #endif #if @REPLACE_ISWCNTRL@ _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); #else _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); +#endif +#if @GNULIB_ISWDIGIT@ +# if @REPLACE_ISWDIGIT@ +_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); +# else _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); +# endif +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); +#endif +#if @GNULIB_ISWXDIGIT@ +# if @REPLACE_ISWXDIGIT@ +_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); +# else _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); +# endif #endif +#if __GLIBC__ >= 2 _GL_CXXALIASWARN (iswalnum); _GL_CXXALIASWARN (iswalpha); _GL_CXXALIASWARN (iswcntrl); @@ -407,6 +605,7 @@ _GL_CXXALIASWARN (iswpunct); _GL_CXXALIASWARN (iswspace); _GL_CXXALIASWARN (iswupper); _GL_CXXALIASWARN (iswxdigit); +#endif #if @GNULIB_ISWBLANK@ # if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@ @@ -414,7 +613,9 @@ _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); # else _GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (iswblank); +# endif #endif #if !@HAVE_WCTYPE_T@ @@ -430,7 +631,9 @@ typedef void * wctype_t; _GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name)); # endif _GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wctype); +# endif #elif defined GNULIB_POSIXCHECK # undef wctype # if HAVE_RAW_DECL_WCTYPE @@ -443,11 +646,22 @@ _GL_WARN_ON_USE (wctype, "wctype is unportable - " The argument WC must be either a wchar_t value or WEOF. The argument DESC must have been returned by the wctype() function. */ #if @GNULIB_ISWCTYPE@ -# if !@HAVE_WCTYPE_T@ +# if @GNULIBHEADERS_OVERRIDE_WINT_T@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef iswctype +# define iswctype rpl_iswctype +# endif +_GL_FUNCDECL_RPL (iswctype, int, (wint_t wc, wctype_t desc)); +_GL_CXXALIAS_RPL (iswctype, int, (wint_t wc, wctype_t desc)); +# else +# if !@HAVE_WCTYPE_T@ _GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc)); -# endif +# endif _GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc)); +# endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (iswctype); +# endif #elif defined GNULIB_POSIXCHECK # undef iswctype # if HAVE_RAW_DECL_ISWCTYPE @@ -463,8 +677,10 @@ _GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); _GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc)); _GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc)); #endif +#if __GLIBC__ >= 2 _GL_CXXALIASWARN (towlower); _GL_CXXALIASWARN (towupper); +#endif #if !@HAVE_WCTRANS_T@ # if !GNULIB_defined_wctrans_t @@ -479,7 +695,9 @@ typedef void * wctrans_t; _GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name)); # endif _GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (wctrans); +# endif #elif defined GNULIB_POSIXCHECK # undef wctrans # if HAVE_RAW_DECL_WCTRANS @@ -496,7 +714,9 @@ _GL_WARN_ON_USE (wctrans, "wctrans is unportable - " _GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); # endif _GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (towctrans); +# endif #elif defined GNULIB_POSIXCHECK # undef towctrans # if HAVE_RAW_DECL_TOWCTRANS @@ -509,3 +729,4 @@ _GL_INLINE_HEADER_END #endif /* _@GUARD_PREFIX@_WCTYPE_H */ #endif /* _@GUARD_PREFIX@_WCTYPE_H */ +#endif diff --git a/gl/windows-initguard.h b/gl/windows-initguard.h new file mode 100644 index 00000000..a29d7e97 --- /dev/null +++ b/gl/windows-initguard.h @@ -0,0 +1,35 @@ +/* Init guards, somewhat like spinlocks (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#ifndef _WINDOWS_INITGUARD_H +#define _WINDOWS_INITGUARD_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +typedef struct + { + volatile int done; + volatile LONG started; + } + glwthread_initguard_t; + +#define GLWTHREAD_INITGUARD_INIT { 0, -1 } + +#endif /* _WINDOWS_INITGUARD_H */ diff --git a/gl/windows-mutex.c b/gl/windows-mutex.c new file mode 100644 index 00000000..28e429c1 --- /dev/null +++ b/gl/windows-mutex.c @@ -0,0 +1,95 @@ +/* Plain mutexes (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#include + +/* Specification. */ +#include "windows-mutex.h" + +#include + +void +glwthread_mutex_init (glwthread_mutex_t *mutex) +{ + InitializeCriticalSection (&mutex->lock); + mutex->guard.done = 1; +} + +int +glwthread_mutex_lock (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_mutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!mutex->guard.done) + Sleep (0); + } + } + EnterCriticalSection (&mutex->lock); + return 0; +} + +int +glwthread_mutex_trylock (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_mutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Let another thread finish initializing this mutex, and let it also + lock this mutex. */ + return EBUSY; + } + } + if (!TryEnterCriticalSection (&mutex->lock)) + return EBUSY; + return 0; +} + +int +glwthread_mutex_unlock (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + return EINVAL; + LeaveCriticalSection (&mutex->lock); + return 0; +} + +int +glwthread_mutex_destroy (glwthread_mutex_t *mutex) +{ + if (!mutex->guard.done) + return EINVAL; + DeleteCriticalSection (&mutex->lock); + mutex->guard.done = 0; + return 0; +} diff --git a/gl/windows-mutex.h b/gl/windows-mutex.h new file mode 100644 index 00000000..7aedfdf6 --- /dev/null +++ b/gl/windows-mutex.h @@ -0,0 +1,51 @@ +/* Plain mutexes (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#ifndef _WINDOWS_MUTEX_H +#define _WINDOWS_MUTEX_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +#include "windows-initguard.h" + +typedef struct + { + glwthread_initguard_t guard; /* protects the initialization */ + CRITICAL_SECTION lock; + } + glwthread_mutex_t; + +#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_INITGUARD_INIT } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_mutex_init (glwthread_mutex_t *mutex); +extern int glwthread_mutex_lock (glwthread_mutex_t *mutex); +extern int glwthread_mutex_trylock (glwthread_mutex_t *mutex); +extern int glwthread_mutex_unlock (glwthread_mutex_t *mutex); +extern int glwthread_mutex_destroy (glwthread_mutex_t *mutex); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_MUTEX_H */ diff --git a/gl/windows-once.c b/gl/windows-once.c new file mode 100644 index 00000000..deea5487 --- /dev/null +++ b/gl/windows-once.c @@ -0,0 +1,62 @@ +/* Once-only control (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#include + +/* Specification. */ +#include "windows-once.h" + +#include + +void +glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) +{ + if (once_control->inited <= 0) + { + if (InterlockedIncrement (&once_control->started) == 0) + { + /* This thread is the first one to come to this once_control. */ + InitializeCriticalSection (&once_control->lock); + EnterCriticalSection (&once_control->lock); + once_control->inited = 0; + initfunction (); + once_control->inited = 1; + LeaveCriticalSection (&once_control->lock); + } + else + { + /* Don't let once_control->started grow and wrap around. */ + InterlockedDecrement (&once_control->started); + /* Some other thread has already started the initialization. + Yield the CPU while waiting for the other thread to finish + initializing and taking the lock. */ + while (once_control->inited < 0) + Sleep (0); + if (once_control->inited <= 0) + { + /* Take the lock. This blocks until the other thread has + finished calling the initfunction. */ + EnterCriticalSection (&once_control->lock); + LeaveCriticalSection (&once_control->lock); + if (!(once_control->inited > 0)) + abort (); + } + } + } +} diff --git a/gl/windows-once.h b/gl/windows-once.h new file mode 100644 index 00000000..85534c99 --- /dev/null +++ b/gl/windows-once.h @@ -0,0 +1,47 @@ +/* Once-only control (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#ifndef _WINDOWS_ONCE_H +#define _WINDOWS_ONCE_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +typedef struct + { + volatile int inited; + volatile LONG started; + CRITICAL_SECTION lock; + } + glwthread_once_t; + +#define GLWTHREAD_ONCE_INIT { -1, -1 } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_once (glwthread_once_t *once_control, + void (*initfunction) (void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_ONCE_H */ diff --git a/gl/windows-recmutex.c b/gl/windows-recmutex.c new file mode 100644 index 00000000..d8087ac1 --- /dev/null +++ b/gl/windows-recmutex.c @@ -0,0 +1,127 @@ +/* Plain recursive mutexes (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#include + +/* Specification. */ +#include "windows-recmutex.h" + +#include + +void +glwthread_recmutex_init (glwthread_recmutex_t *mutex) +{ + mutex->owner = 0; + mutex->depth = 0; + InitializeCriticalSection (&mutex->lock); + mutex->guard.done = 1; +} + +int +glwthread_recmutex_lock (glwthread_recmutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_recmutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this mutex. */ + while (!mutex->guard.done) + Sleep (0); + } + } + { + DWORD self = GetCurrentThreadId (); + if (mutex->owner != self) + { + EnterCriticalSection (&mutex->lock); + mutex->owner = self; + } + if (++(mutex->depth) == 0) /* wraparound? */ + { + mutex->depth--; + return EAGAIN; + } + } + return 0; +} + +int +glwthread_recmutex_trylock (glwthread_recmutex_t *mutex) +{ + if (!mutex->guard.done) + { + if (InterlockedIncrement (&mutex->guard.started) == 0) + /* This thread is the first one to need this mutex. Initialize it. */ + glwthread_recmutex_init (mutex); + else + { + /* Don't let mutex->guard.started grow and wrap around. */ + InterlockedDecrement (&mutex->guard.started); + /* Let another thread finish initializing this mutex, and let it also + lock this mutex. */ + return EBUSY; + } + } + { + DWORD self = GetCurrentThreadId (); + if (mutex->owner != self) + { + if (!TryEnterCriticalSection (&mutex->lock)) + return EBUSY; + mutex->owner = self; + } + if (++(mutex->depth) == 0) /* wraparound? */ + { + mutex->depth--; + return EAGAIN; + } + } + return 0; +} + +int +glwthread_recmutex_unlock (glwthread_recmutex_t *mutex) +{ + if (mutex->owner != GetCurrentThreadId ()) + return EPERM; + if (mutex->depth == 0) + return EINVAL; + if (--(mutex->depth) == 0) + { + mutex->owner = 0; + LeaveCriticalSection (&mutex->lock); + } + return 0; +} + +int +glwthread_recmutex_destroy (glwthread_recmutex_t *mutex) +{ + if (mutex->owner != 0) + return EBUSY; + DeleteCriticalSection (&mutex->lock); + mutex->guard.done = 0; + return 0; +} diff --git a/gl/windows-recmutex.h b/gl/windows-recmutex.h new file mode 100644 index 00000000..746e75c0 --- /dev/null +++ b/gl/windows-recmutex.h @@ -0,0 +1,57 @@ +/* Plain recursive mutexes (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#ifndef _WINDOWS_RECMUTEX_H +#define _WINDOWS_RECMUTEX_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +#include "windows-initguard.h" + +/* The native Windows documentation says that CRITICAL_SECTION already + implements a recursive lock. But we need not rely on it: It's easy to + implement a recursive lock without this assumption. */ + +typedef struct + { + glwthread_initguard_t guard; /* protects the initialization */ + DWORD owner; + unsigned long depth; + CRITICAL_SECTION lock; + } + glwthread_recmutex_t; + +#define GLWTHREAD_RECMUTEX_INIT { GLWTHREAD_INITGUARD_INIT, 0, 0 } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_recmutex_init (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_lock (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_trylock (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_unlock (glwthread_recmutex_t *mutex); +extern int glwthread_recmutex_destroy (glwthread_recmutex_t *mutex); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_RECMUTEX_H */ diff --git a/gl/windows-rwlock.c b/gl/windows-rwlock.c new file mode 100644 index 00000000..d186e037 --- /dev/null +++ b/gl/windows-rwlock.c @@ -0,0 +1,377 @@ +/* Read-write locks (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#include + +/* Specification. */ +#include "windows-rwlock.h" + +#include +#include + +/* Don't assume that UNICODE is not defined. */ +#undef CreateEvent +#define CreateEvent CreateEventA + +/* In this file, the waitqueues are implemented as circular arrays. */ +#define glwthread_waitqueue_t glwthread_carray_waitqueue_t + +static void +glwthread_waitqueue_init (glwthread_waitqueue_t *wq) +{ + wq->array = NULL; + wq->count = 0; + wq->alloc = 0; + wq->offset = 0; +} + +/* Enqueues the current thread, represented by an event, in a wait queue. + Returns INVALID_HANDLE_VALUE if an allocation failure occurs. */ +static HANDLE +glwthread_waitqueue_add (glwthread_waitqueue_t *wq) +{ + HANDLE event; + unsigned int index; + + if (wq->count == wq->alloc) + { + unsigned int new_alloc = 2 * wq->alloc + 1; + HANDLE *new_array = + (HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE)); + if (new_array == NULL) + /* No more memory. */ + return INVALID_HANDLE_VALUE; + /* Now is a good opportunity to rotate the array so that its contents + starts at offset 0. */ + if (wq->offset > 0) + { + unsigned int old_count = wq->count; + unsigned int old_alloc = wq->alloc; + unsigned int old_offset = wq->offset; + unsigned int i; + if (old_offset + old_count > old_alloc) + { + unsigned int limit = old_offset + old_count - old_alloc; + for (i = 0; i < limit; i++) + new_array[old_alloc + i] = new_array[i]; + } + for (i = 0; i < old_count; i++) + new_array[i] = new_array[old_offset + i]; + wq->offset = 0; + } + wq->array = new_array; + wq->alloc = new_alloc; + } + /* Whether the created event is a manual-reset one or an auto-reset one, + does not matter, since we will wait on it only once. */ + event = CreateEvent (NULL, TRUE, FALSE, NULL); + if (event == INVALID_HANDLE_VALUE) + /* No way to allocate an event. */ + return INVALID_HANDLE_VALUE; + index = wq->offset + wq->count; + if (index >= wq->alloc) + index -= wq->alloc; + wq->array[index] = event; + wq->count++; + return event; +} + +/* Notifies the first thread from a wait queue and dequeues it. */ +static void +glwthread_waitqueue_notify_first (glwthread_waitqueue_t *wq) +{ + SetEvent (wq->array[wq->offset + 0]); + wq->offset++; + wq->count--; + if (wq->count == 0 || wq->offset == wq->alloc) + wq->offset = 0; +} + +/* Notifies all threads from a wait queue and dequeues them all. */ +static void +glwthread_waitqueue_notify_all (glwthread_waitqueue_t *wq) +{ + unsigned int i; + + for (i = 0; i < wq->count; i++) + { + unsigned int index = wq->offset + i; + if (index >= wq->alloc) + index -= wq->alloc; + SetEvent (wq->array[index]); + } + wq->count = 0; + wq->offset = 0; +} + +void +glwthread_rwlock_init (glwthread_rwlock_t *lock) +{ + InitializeCriticalSection (&lock->lock); + glwthread_waitqueue_init (&lock->waiting_readers); + glwthread_waitqueue_init (&lock->waiting_writers); + lock->runcount = 0; + lock->guard.done = 1; +} + +int +glwthread_rwlock_rdlock (glwthread_rwlock_t *lock) +{ + if (!lock->guard.done) + { + if (InterlockedIncrement (&lock->guard.started) == 0) + /* This thread is the first one to need this lock. Initialize it. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this lock. */ + while (!lock->guard.done) + Sleep (0); + } + } + EnterCriticalSection (&lock->lock); + /* Test whether only readers are currently running, and whether the runcount + field will not overflow, and whether no writer is waiting. The latter + condition is because POSIX recommends that "write locks shall take + precedence over read locks", to avoid "writer starvation". */ + if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0)) + { + /* This thread has to wait for a while. Enqueue it among the + waiting_readers. */ + HANDLE event = glwthread_waitqueue_add (&lock->waiting_readers); + if (event != INVALID_HANDLE_VALUE) + { + DWORD result; + LeaveCriticalSection (&lock->lock); + /* Wait until another thread signals this event. */ + result = WaitForSingleObject (event, INFINITE); + if (result == WAIT_FAILED || result == WAIT_TIMEOUT) + abort (); + CloseHandle (event); + /* The thread which signalled the event already did the bookkeeping: + removed us from the waiting_readers, incremented lock->runcount. */ + if (!(lock->runcount > 0)) + abort (); + return 0; + } + else + { + /* Allocation failure. Weird. */ + do + { + LeaveCriticalSection (&lock->lock); + Sleep (1); + EnterCriticalSection (&lock->lock); + } + while (!(lock->runcount + 1 > 0)); + } + } + lock->runcount++; + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_wrlock (glwthread_rwlock_t *lock) +{ + if (!lock->guard.done) + { + if (InterlockedIncrement (&lock->guard.started) == 0) + /* This thread is the first one to need this lock. Initialize it. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this lock. */ + while (!lock->guard.done) + Sleep (0); + } + } + EnterCriticalSection (&lock->lock); + /* Test whether no readers or writers are currently running. */ + if (!(lock->runcount == 0)) + { + /* This thread has to wait for a while. Enqueue it among the + waiting_writers. */ + HANDLE event = glwthread_waitqueue_add (&lock->waiting_writers); + if (event != INVALID_HANDLE_VALUE) + { + DWORD result; + LeaveCriticalSection (&lock->lock); + /* Wait until another thread signals this event. */ + result = WaitForSingleObject (event, INFINITE); + if (result == WAIT_FAILED || result == WAIT_TIMEOUT) + abort (); + CloseHandle (event); + /* The thread which signalled the event already did the bookkeeping: + removed us from the waiting_writers, set lock->runcount = -1. */ + if (!(lock->runcount == -1)) + abort (); + return 0; + } + else + { + /* Allocation failure. Weird. */ + do + { + LeaveCriticalSection (&lock->lock); + Sleep (1); + EnterCriticalSection (&lock->lock); + } + while (!(lock->runcount == 0)); + } + } + lock->runcount--; /* runcount becomes -1 */ + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_tryrdlock (glwthread_rwlock_t *lock) +{ + if (!lock->guard.done) + { + if (InterlockedIncrement (&lock->guard.started) == 0) + /* This thread is the first one to need this lock. Initialize it. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this lock. */ + while (!lock->guard.done) + Sleep (0); + } + } + /* It's OK to wait for this critical section, because it is never taken for a + long time. */ + EnterCriticalSection (&lock->lock); + /* Test whether only readers are currently running, and whether the runcount + field will not overflow, and whether no writer is waiting. The latter + condition is because POSIX recommends that "write locks shall take + precedence over read locks", to avoid "writer starvation". */ + if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0)) + { + /* This thread would have to wait for a while. Return instead. */ + LeaveCriticalSection (&lock->lock); + return EBUSY; + } + lock->runcount++; + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_trywrlock (glwthread_rwlock_t *lock) +{ + if (!lock->guard.done) + { + if (InterlockedIncrement (&lock->guard.started) == 0) + /* This thread is the first one to need this lock. Initialize it. */ + glwthread_rwlock_init (lock); + else + { + /* Don't let lock->guard.started grow and wrap around. */ + InterlockedDecrement (&lock->guard.started); + /* Yield the CPU while waiting for another thread to finish + initializing this lock. */ + while (!lock->guard.done) + Sleep (0); + } + } + /* It's OK to wait for this critical section, because it is never taken for a + long time. */ + EnterCriticalSection (&lock->lock); + /* Test whether no readers or writers are currently running. */ + if (!(lock->runcount == 0)) + { + /* This thread would have to wait for a while. Return instead. */ + LeaveCriticalSection (&lock->lock); + return EBUSY; + } + lock->runcount--; /* runcount becomes -1 */ + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_unlock (glwthread_rwlock_t *lock) +{ + if (!lock->guard.done) + return EINVAL; + EnterCriticalSection (&lock->lock); + if (lock->runcount < 0) + { + /* Drop a writer lock. */ + if (!(lock->runcount == -1)) + abort (); + lock->runcount = 0; + } + else + { + /* Drop a reader lock. */ + if (!(lock->runcount > 0)) + { + LeaveCriticalSection (&lock->lock); + return EPERM; + } + lock->runcount--; + } + if (lock->runcount == 0) + { + /* POSIX recommends that "write locks shall take precedence over read + locks", to avoid "writer starvation". */ + if (lock->waiting_writers.count > 0) + { + /* Wake up one of the waiting writers. */ + lock->runcount--; + glwthread_waitqueue_notify_first (&lock->waiting_writers); + } + else + { + /* Wake up all waiting readers. */ + lock->runcount += lock->waiting_readers.count; + glwthread_waitqueue_notify_all (&lock->waiting_readers); + } + } + LeaveCriticalSection (&lock->lock); + return 0; +} + +int +glwthread_rwlock_destroy (glwthread_rwlock_t *lock) +{ + if (!lock->guard.done) + return EINVAL; + if (lock->runcount != 0) + return EBUSY; + DeleteCriticalSection (&lock->lock); + if (lock->waiting_readers.array != NULL) + free (lock->waiting_readers.array); + if (lock->waiting_writers.array != NULL) + free (lock->waiting_writers.array); + lock->guard.done = 0; + return 0; +} diff --git a/gl/windows-rwlock.h b/gl/windows-rwlock.h new file mode 100644 index 00000000..65c5ab49 --- /dev/null +++ b/gl/windows-rwlock.h @@ -0,0 +1,68 @@ +/* Read-write locks (native Windows implementation). + Copyright (C) 2005-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2005. + Based on GCC's gthr-win32.h. */ + +#ifndef _WINDOWS_RWLOCK_H +#define _WINDOWS_RWLOCK_H + +#define WIN32_LEAN_AND_MEAN /* avoid including junk */ +#include + +#include "windows-initguard.h" + +/* It is impossible to implement read-write locks using plain locks, without + introducing an extra thread dedicated to managing read-write locks. + Therefore here we need to use the low-level Event type. */ + +typedef struct + { + HANDLE *array; /* array of waiting threads, each represented by an event */ + unsigned int count; /* number of waiting threads */ + unsigned int alloc; /* length of allocated array */ + unsigned int offset; /* index of first waiting thread in array */ + } + glwthread_carray_waitqueue_t; +typedef struct + { + glwthread_initguard_t guard; /* protects the initialization */ + CRITICAL_SECTION lock; /* protects the remaining fields */ + glwthread_carray_waitqueue_t waiting_readers; /* waiting readers */ + glwthread_carray_waitqueue_t waiting_writers; /* waiting writers */ + int runcount; /* number of readers running, or -1 when a writer runs */ + } + glwthread_rwlock_t; + +#define GLWTHREAD_RWLOCK_INIT { GLWTHREAD_INITGUARD_INIT } + +#ifdef __cplusplus +extern "C" { +#endif + +extern void glwthread_rwlock_init (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_rdlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_wrlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_tryrdlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_trywrlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_unlock (glwthread_rwlock_t *lock); +extern int glwthread_rwlock_destroy (glwthread_rwlock_t *lock); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_RWLOCK_H */ diff --git a/gl/xalloc-die.c b/gl/xalloc-die.c index daa403b9..5b947f10 100644 --- a/gl/xalloc-die.c +++ b/gl/xalloc-die.c @@ -1,11 +1,11 @@ /* Report a memory allocation failure and exit. - Copyright (C) 1997-2000, 2002-2004, 2006, 2009-2013 Free Software + Copyright (C) 1997-2000, 2002-2004, 2006, 2009-2022 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 + 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, @@ -14,7 +14,7 @@ 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 . */ + along with this program. If not, see . */ #include diff --git a/gl/xalloc-oversized.h b/gl/xalloc-oversized.h index a971c78a..aefa6fd8 100644 --- a/gl/xalloc-oversized.h +++ b/gl/xalloc-oversized.h @@ -1,38 +1,65 @@ /* xalloc-oversized.h -- memory allocation size checking - Copyright (C) 1990-2000, 2003-2004, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 1990-2000, 2003-2004, 2006-2022 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 file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef XALLOC_OVERSIZED_H_ -# define XALLOC_OVERSIZED_H_ - -# include - -/* Return 1 if an array of N objects, each of size S, cannot exist due - to size arithmetic overflow. S must be positive and N must be - nonnegative. This is a macro, not a function, so that it - works correctly even when SIZE_MAX < N. - - By gnulib convention, SIZE_MAX represents overflow in size - calculations, so the conservative dividend to use here is - SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. - However, malloc (SIZE_MAX) fails on all known hosts where - sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for - exactly-SIZE_MAX allocations on such hosts; this avoids a test and - branch when S is known to be 1. */ +#define XALLOC_OVERSIZED_H_ + +#include +#include + +/* True if N * S does not fit into both ptrdiff_t and size_t. + N and S should be nonnegative and free of side effects. + This expands to a constant expression if N and S are both constants. + By gnulib convention, SIZE_MAX represents overflow in size_t + calculations, so the conservative size_t-based dividend to use here + is SIZE_MAX - 1. */ +#define __xalloc_oversized(n, s) \ + ((s) != 0 \ + && ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) \ + < (n))) + +/* Return 1 if and only if an array of N objects, each of size S, + cannot exist reliably because its total size in bytes would exceed + MIN (PTRDIFF_MAX, SIZE_MAX - 1). + + N and S should be nonnegative and free of side effects. + + Warning: (xalloc_oversized (N, S) ? NULL : malloc (N * S)) can + misbehave if N and S are both narrower than ptrdiff_t and size_t, + and can be rewritten as (xalloc_oversized (N, S) ? NULL + : malloc (N * (size_t) S)). + + This is a macro, not a function, so that it works even if an + argument exceeds MAX (PTRDIFF_MAX, SIZE_MAX). */ +#if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX # define xalloc_oversized(n, s) \ - ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) + __builtin_mul_overflow_p (n, s, (ptrdiff_t) 1) +#elif (5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__ \ + && PTRDIFF_MAX < SIZE_MAX) +# define xalloc_oversized(n, s) \ + (__builtin_constant_p (n) && __builtin_constant_p (s) \ + ? __xalloc_oversized (n, s) \ + : ({ ptrdiff_t __xalloc_count; \ + __builtin_mul_overflow (n, s, &__xalloc_count); })) + +/* Other compilers use integer division; this may be slower but is + more portable. */ +#else +# define xalloc_oversized(n, s) __xalloc_oversized (n, s) +#endif #endif /* !XALLOC_OVERSIZED_H_ */ diff --git a/gl/xalloc.h b/gl/xalloc.h index da7c4b6b..9f4bf8d4 100644 --- a/gl/xalloc.h +++ b/gl/xalloc.h @@ -1,10 +1,10 @@ /* xalloc.h -- malloc with out-of-memory checking - Copyright (C) 1990-2000, 2003-2004, 2006-2013 Free Software Foundation, Inc. + Copyright (C) 1990-2000, 2003-2004, 2006-2022 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 + 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, @@ -13,57 +13,94 @@ 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 . */ + along with this program. If not, see . */ #ifndef XALLOC_H_ #define XALLOC_H_ #include +#include +#include -#include "xalloc-oversized.h" +#if GNULIB_XALLOC +# include "idx.h" +# include "intprops.h" +#endif +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif _GL_INLINE_HEADER_BEGIN #ifndef XALLOC_INLINE # define XALLOC_INLINE _GL_INLINE #endif + #ifdef __cplusplus extern "C" { #endif -#if __GNUC__ >= 3 -# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) -#else -# define _GL_ATTRIBUTE_MALLOC -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) -#else -# define _GL_ATTRIBUTE_ALLOC_SIZE(args) -#endif +#if GNULIB_XALLOC_DIE /* This function is always triggered when memory is exhausted. It must be defined by the application, either explicitly or by using gnulib's xalloc-die module. This is the function to call when one wants the program to die because of a memory allocation failure. */ -extern _Noreturn void xalloc_die (void); +/*extern*/ _Noreturn void xalloc_die (void); + +#endif /* GNULIB_XALLOC_DIE */ + +#if GNULIB_XALLOC void *xmalloc (size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *ximalloc (idx_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *xinmalloc (idx_t n, idx_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; void *xzalloc (size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *xizalloc (idx_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; void *xcalloc (size_t n, size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *xicalloc (idx_t n, idx_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; void *xrealloc (void *p, size_t s) - _GL_ATTRIBUTE_ALLOC_SIZE ((2)); -void *x2realloc (void *p, size_t *pn); + _GL_ATTRIBUTE_ALLOC_SIZE ((2)); +void *xirealloc (void *p, idx_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *xreallocarray (void *p, size_t n, size_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); +void *xireallocarray (void *p, idx_t n, idx_t s) + _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *x2realloc (void *p, size_t *ps) /* superseded by xpalloc */ + _GL_ATTRIBUTE_RETURNS_NONNULL; +void *x2nrealloc (void *p, size_t *pn, size_t s) /* superseded by xpalloc */ + _GL_ATTRIBUTE_RETURNS_NONNULL; +void *xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s) + _GL_ATTRIBUTE_RETURNS_NONNULL; void *xmemdup (void const *p, size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2)); + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; +void *ximemdup (void const *p, idx_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL; +char *ximemdup0 (void const *p, idx_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; char *xstrdup (char const *str) - _GL_ATTRIBUTE_MALLOC; + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; /* In the following macros, T must be an elementary or structure/union or typedef'ed type, or a pointer to such a type. To apply one of the @@ -72,153 +109,60 @@ char *xstrdup (char const *str) /* Allocate an object of type T dynamically, with error checking. */ /* extern t *XMALLOC (typename t); */ -#define XMALLOC(t) ((t *) xmalloc (sizeof (t))) +# define XMALLOC(t) ((t *) xmalloc (sizeof (t))) /* Allocate memory for N elements of type T, with error checking. */ /* extern t *XNMALLOC (size_t n, typename t); */ -#define XNMALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) +# define XNMALLOC(n, t) \ + ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) /* Allocate an object of type T dynamically, with error checking, and zero it. */ /* extern t *XZALLOC (typename t); */ -#define XZALLOC(t) ((t *) xzalloc (sizeof (t))) +# define XZALLOC(t) ((t *) xzalloc (sizeof (t))) /* Allocate memory for N elements of type T, with error checking, and zero it. */ /* extern t *XCALLOC (size_t n, typename t); */ -#define XCALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) +# define XCALLOC(n, t) \ + ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) /* Allocate an array of N objects, each with S bytes of memory, dynamically, with error checking. S must be nonzero. */ -XALLOC_INLINE void *xnmalloc (size_t n, size_t s) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)); -XALLOC_INLINE void * -xnmalloc (size_t n, size_t s) -{ - if (xalloc_oversized (n, s)) - xalloc_die (); - return xmalloc (n * s); -} +void *xnmalloc (size_t n, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2)) _GL_ATTRIBUTE_RETURNS_NONNULL; +/* FIXME: Deprecate this in favor of xreallocarray? */ /* Change the size of an allocated block of memory P to an array of N objects each of S bytes, with error checking. S must be nonzero. */ XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s) - _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); + _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)); XALLOC_INLINE void * xnrealloc (void *p, size_t n, size_t s) { - if (xalloc_oversized (n, s)) - xalloc_die (); - return xrealloc (p, n * s); -} - -/* If P is null, allocate a block of at least *PN such objects; - otherwise, reallocate P so that it contains more than *PN objects - each of S bytes. *PN must be nonzero unless P is null, and S must - be nonzero. Set *PN to the new number of objects, and return the - pointer to the new block. *PN is never set to zero, and the - returned pointer is never null. - - Repeated reallocations are guaranteed to make progress, either by - allocating an initial block with a nonzero size, or by allocating a - larger block. - - In the following implementation, nonzero sizes are increased by a - factor of approximately 1.5 so that repeated reallocations have - O(N) overall cost rather than O(N**2) cost, but the - specification for this function does not guarantee that rate. - - Here is an example of use: - - int *p = NULL; - size_t used = 0; - size_t allocated = 0; - - void - append_int (int value) - { - if (used == allocated) - p = x2nrealloc (p, &allocated, sizeof *p); - p[used++] = value; - } - - This causes x2nrealloc to allocate a block of some nonzero size the - first time it is called. - - To have finer-grained control over the initial size, set *PN to a - nonzero value before calling this function with P == NULL. For - example: - - int *p = NULL; - size_t used = 0; - size_t allocated = 0; - size_t allocated1 = 1000; - - void - append_int (int value) - { - if (used == allocated) - { - p = x2nrealloc (p, &allocated1, sizeof *p); - allocated = allocated1; - } - p[used++] = value; - } - - */ - -XALLOC_INLINE void * -x2nrealloc (void *p, size_t *pn, size_t s) -{ - size_t n = *pn; - - if (! p) - { - if (! n) - { - /* The approximate size to use for initial small allocation - requests, when the invoking code specifies an old size of - zero. This is the largest "small" request for the GNU C - library malloc. */ - enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; - - n = DEFAULT_MXFAST / s; - n += !n; - } - } - else - { - /* Set N = ceil (1.5 * N) so that progress is made if N == 1. - Check for overflow, so that N * S stays in size_t range. - The check is slightly conservative, but an exact check isn't - worth the trouble. */ - if ((size_t) -1 / 3 * 2 / s <= n) - xalloc_die (); - n += (n + 1) / 2; - } - - *pn = n; - return xrealloc (p, n * s); + return xreallocarray (p, n, s); } /* Return a pointer to a new buffer of N bytes. This is like xmalloc, except it returns char *. */ -XALLOC_INLINE char *xcharalloc (size_t n) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); -XALLOC_INLINE char * -xcharalloc (size_t n) -{ - return XNMALLOC (n, char); -} +char *xcharalloc (size_t n) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL; + +#endif /* GNULIB_XALLOC */ + #ifdef __cplusplus } +#endif + + +#if GNULIB_XALLOC && defined __cplusplus /* C++ does not allow conversions from void * to other pointer types without a cast. Use templates to work around the problem when @@ -230,10 +174,17 @@ xrealloc (T *p, size_t s) return (T *) xrealloc ((void *) p, s); } +template inline T * +xreallocarray (T *p, size_t n, size_t s) +{ + return (T *) xreallocarray ((void *) p, n, s); +} + +/* FIXME: Deprecate this in favor of xreallocarray? */ template inline T * xnrealloc (T *p, size_t n, size_t s) { - return (T *) xnrealloc ((void *) p, n, s); + return xreallocarray (p, n, s); } template inline T * @@ -254,7 +205,9 @@ xmemdup (T const *p, size_t s) return (T *) xmemdup ((void const *) p, s); } -#endif +#endif /* GNULIB_XALLOC && C++ */ + +_GL_INLINE_HEADER_END #endif /* !XALLOC_H_ */ diff --git a/gl/xmalloc.c b/gl/xmalloc.c index 57e34b7c..3c3cb207 100644 --- a/gl/xmalloc.c +++ b/gl/xmalloc.c @@ -1,10 +1,10 @@ /* xmalloc.c -- malloc with out of memory checking - Copyright (C) 1990-2000, 2002-2006, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 1990-2000, 2002-2006, 2008-2022 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 + 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, @@ -13,7 +13,7 @@ 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 . */ + along with this program. If not, see . */ #include @@ -21,59 +21,255 @@ #include "xalloc.h" +#include "ialloc.h" +#include "minmax.h" + +#include #include #include -/* 1 if calloc is known to be compatible with GNU calloc. This - matters if we are not also using the calloc module, which defines - HAVE_CALLOC_GNU and supports the GNU API even on non-GNU platforms. */ -#if defined HAVE_CALLOC_GNU || (defined __GLIBC__ && !defined __UCLIBC__) -enum { HAVE_GNU_CALLOC = 1 }; -#else -enum { HAVE_GNU_CALLOC = 0 }; -#endif +static void * _GL_ATTRIBUTE_PURE +nonnull (void *p) +{ + if (!p) + xalloc_die (); + return p; +} -/* Allocate N bytes of memory dynamically, with error checking. */ +/* Allocate S bytes of memory dynamically, with error checking. */ void * -xmalloc (size_t n) +xmalloc (size_t s) { - void *p = malloc (n); - if (!p && n != 0) - xalloc_die (); - return p; + return nonnull (malloc (s)); +} + +void * +ximalloc (idx_t s) +{ + return nonnull (imalloc (s)); } -/* Change the size of an allocated block of memory P to N bytes, +char * +xcharalloc (size_t n) +{ + return XNMALLOC (n, char); +} + +/* Change the size of an allocated block of memory P to S bytes, with error checking. */ void * -xrealloc (void *p, size_t n) +xrealloc (void *p, size_t s) +{ + void *r = realloc (p, s); + if (!r && (!p || s)) + xalloc_die (); + return r; +} + +void * +xirealloc (void *p, idx_t s) +{ + return nonnull (irealloc (p, s)); +} + +/* Change the size of an allocated block of memory P to an array of N + objects each of S bytes, with error checking. */ + +void * +xreallocarray (void *p, size_t n, size_t s) +{ + void *r = reallocarray (p, n, s); + if (!r && (!p || (n && s))) + xalloc_die (); + return r; +} + +void * +xireallocarray (void *p, idx_t n, idx_t s) +{ + return nonnull (ireallocarray (p, n, s)); +} + +/* Allocate an array of N objects, each with S bytes of memory, + dynamically, with error checking. S must be nonzero. */ + +void * +xnmalloc (size_t n, size_t s) +{ + return xreallocarray (NULL, n, s); +} + +void * +xinmalloc (idx_t n, idx_t s) +{ + return xireallocarray (NULL, n, s); +} + +/* If P is null, allocate a block of at least *PS bytes; otherwise, + reallocate P so that it contains more than *PS bytes. *PS must be + nonzero unless P is null. Set *PS to the new block's size, and + return the pointer to the new block. *PS is never set to zero, and + the returned pointer is never null. */ + +void * +x2realloc (void *p, size_t *ps) +{ + return x2nrealloc (p, ps, 1); +} + +/* If P is null, allocate a block of at least *PN such objects; + otherwise, reallocate P so that it contains more than *PN objects + each of S bytes. S must be nonzero. Set *PN to the new number of + objects, and return the pointer to the new block. *PN is never set + to zero, and the returned pointer is never null. + + Repeated reallocations are guaranteed to make progress, either by + allocating an initial block with a nonzero size, or by allocating a + larger block. + + In the following implementation, nonzero sizes are increased by a + factor of approximately 1.5 so that repeated reallocations have + O(N) overall cost rather than O(N**2) cost, but the + specification for this function does not guarantee that rate. + + Here is an example of use: + + int *p = NULL; + size_t used = 0; + size_t allocated = 0; + + void + append_int (int value) + { + if (used == allocated) + p = x2nrealloc (p, &allocated, sizeof *p); + p[used++] = value; + } + + This causes x2nrealloc to allocate a block of some nonzero size the + first time it is called. + + To have finer-grained control over the initial size, set *PN to a + nonzero value before calling this function with P == NULL. For + example: + + int *p = NULL; + size_t used = 0; + size_t allocated = 0; + size_t allocated1 = 1000; + + void + append_int (int value) + { + if (used == allocated) + { + p = x2nrealloc (p, &allocated1, sizeof *p); + allocated = allocated1; + } + p[used++] = value; + } + + */ + +void * +x2nrealloc (void *p, size_t *pn, size_t s) { - if (!n && p) + size_t n = *pn; + + if (! p) { - /* The GNU and C99 realloc behaviors disagree here. Act like - GNU, even if the underlying realloc is C99. */ - free (p); - return NULL; + if (! n) + { + /* The approximate size to use for initial small allocation + requests, when the invoking code specifies an old size of + zero. This is the largest "small" request for the GNU C + library malloc. */ + enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; + + n = DEFAULT_MXFAST / s; + n += !n; + } + } + else + { + /* Set N = floor (1.5 * N) + 1 to make progress even if N == 0. */ + if (ckd_add (&n, n, (n >> 1) + 1)) + xalloc_die (); } - p = realloc (p, n); - if (!p && n) - xalloc_die (); + p = xreallocarray (p, n, s); + *pn = n; return p; } -/* If P is null, allocate a block of at least *PN bytes; otherwise, - reallocate P so that it contains more than *PN bytes. *PN must be - nonzero unless P is null. Set *PN to the new block's size, and - return the pointer to the new block. *PN is never set to zero, and - the returned pointer is never null. */ +/* Grow PA, which points to an array of *PN items, and return the + location of the reallocated array, updating *PN to reflect its + new size. The new array will contain at least N_INCR_MIN more + items, but will not contain more than N_MAX items total. + S is the size of each item, in bytes. + + S and N_INCR_MIN must be positive. *PN must be + nonnegative. If N_MAX is -1, it is treated as if it were + infinity. + + If PA is null, then allocate a new array instead of reallocating + the old one. + + Thus, to grow an array A without saving its old contents, do + { free (A); A = xpalloc (NULL, &AITEMS, ...); }. */ void * -x2realloc (void *p, size_t *pn) +xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s) { - return x2nrealloc (p, pn, 1); + idx_t n0 = *pn; + + /* The approximate size to use for initial small allocation + requests. This is the largest "small" request for the GNU C + library malloc. */ + enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; + + /* If the array is tiny, grow it to about (but no greater than) + DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. + Adjust the growth according to three constraints: N_INCR_MIN, + N_MAX, and what the C language can represent safely. */ + + idx_t n; + if (ckd_add (&n, n0, n0 >> 1)) + n = IDX_MAX; + if (0 <= n_max && n_max < n) + n = n_max; + + /* NBYTES is of a type suitable for holding the count of bytes in an object. + This is typically idx_t, but it should be size_t on (theoretical?) + platforms where SIZE_MAX < IDX_MAX so xpalloc does not pass + values greater than SIZE_MAX to xrealloc. */ +#if IDX_MAX <= SIZE_MAX + idx_t nbytes; +#else + size_t nbytes; +#endif + idx_t adjusted_nbytes + = (ckd_mul (&nbytes, n, s) + ? MIN (IDX_MAX, SIZE_MAX) + : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0); + if (adjusted_nbytes) + { + n = adjusted_nbytes / s; + nbytes = adjusted_nbytes - adjusted_nbytes % s; + } + + if (! pa) + *pn = 0; + if (n - n0 < n_incr_min + && (ckd_add (&n, n0, n_incr_min) + || (0 <= n_max && n_max < n) + || ckd_mul (&nbytes, n, s))) + xalloc_die (); + pa = xrealloc (pa, nbytes); + *pn = n; + return pa; } /* Allocate S bytes of zeroed memory dynamically, with error checking. @@ -83,7 +279,13 @@ x2realloc (void *p, size_t *pn) void * xzalloc (size_t s) { - return memset (xmalloc (s), 0, s); + return xcalloc (s, 1); +} + +void * +xizalloc (idx_t s) +{ + return xicalloc (s, 1); } /* Allocate zeroed memory for N elements of S bytes, with error @@ -92,15 +294,13 @@ xzalloc (size_t s) void * xcalloc (size_t n, size_t s) { - void *p; - /* Test for overflow, since some calloc implementations don't have - proper overflow checks. But omit overflow and size-zero tests if - HAVE_GNU_CALLOC, since GNU calloc catches overflow and never - returns NULL if successful. */ - if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s)) - || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0))) - xalloc_die (); - return p; + return nonnull (calloc (n, s)); +} + +void * +xicalloc (idx_t n, idx_t s) +{ + return nonnull (icalloc (n, s)); } /* Clone an object P of size S, with error checking. There's no need @@ -113,6 +313,23 @@ xmemdup (void const *p, size_t s) return memcpy (xmalloc (s), p, s); } +void * +ximemdup (void const *p, idx_t s) +{ + return memcpy (ximalloc (s), p, s); +} + +/* Clone an object P of size S, with error checking. Append + a terminating NUL byte. */ + +char * +ximemdup0 (void const *p, idx_t s) +{ + char *result = ximalloc (s + 1); + result[s] = 0; + return memcpy (result, p, s); +} + /* Clone STRING. */ char * diff --git a/gl/xsize.c b/gl/xsize.c index 4b4914c2..761e3434 100644 --- a/gl/xsize.c +++ b/gl/xsize.c @@ -1,3 +1,21 @@ +/* Checked size_t computations. + + Copyright (C) 2012-2022 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + #include + #define XSIZE_INLINE _GL_EXTERN_INLINE #include "xsize.h" diff --git a/gl/xsize.h b/gl/xsize.h index 2922f353..0bfa4c88 100644 --- a/gl/xsize.h +++ b/gl/xsize.h @@ -1,19 +1,19 @@ /* xsize.h -- Checked size_t computations. - Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2003, 2008-2022 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This file 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. + GNU Lesser 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 . */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ #ifndef _XSIZE_H #define _XSIZE_H @@ -27,6 +27,12 @@ # include #endif +/* Get ATTRIBUTE_PURE. */ +#include "attribute.h" + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif _GL_INLINE_HEADER_BEGIN #ifndef XSIZE_INLINE # define XSIZE_INLINE _GL_INLINE @@ -53,10 +59,7 @@ _GL_INLINE_HEADER_BEGIN ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) /* Sum of two sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif +XSIZE_INLINE size_t ATTRIBUTE_PURE xsum (size_t size1, size_t size2) { size_t sum = size1 + size2; @@ -64,30 +67,21 @@ xsum (size_t size1, size_t size2) } /* Sum of three sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif +XSIZE_INLINE size_t ATTRIBUTE_PURE xsum3 (size_t size1, size_t size2, size_t size3) { return xsum (xsum (size1, size2), size3); } /* Sum of four sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif +XSIZE_INLINE size_t ATTRIBUTE_PURE xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) { return xsum (xsum (xsum (size1, size2), size3), size4); } /* Maximum of two sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif +XSIZE_INLINE size_t ATTRIBUTE_PURE xmax (size_t size1, size_t size2) { /* No explicit check is needed here, because for any n: diff --git a/gl/xstrndup.c b/gl/xstrndup.c deleted file mode 100644 index eae92d03..00000000 --- a/gl/xstrndup.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Duplicate a bounded initial segment of a string, with out-of-memory - checking. - Copyright (C) 2003, 2006-2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include "xstrndup.h" - -#include -#include "xalloc.h" - -/* Return a newly allocated copy of at most N bytes of STRING. - In other words, return a copy of the initial segment of length N of - STRING. */ -char * -xstrndup (const char *string, size_t n) -{ - char *s = strndup (string, n); - if (! s) - xalloc_die (); - return s; -} diff --git a/gl/xstrndup.h b/gl/xstrndup.h deleted file mode 100644 index 59673b04..00000000 --- a/gl/xstrndup.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Duplicate a bounded initial segment of a string, with out-of-memory - checking. - Copyright (C) 2003, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Return a newly allocated copy of at most N bytes of STRING. - In other words, return a copy of the initial segment of length N of - STRING. */ -extern char *xstrndup (const char *string, size_t n); -- cgit v1.2.3-74-g34f1