From 5e03c718f4e7ff13cb6834eda737c269ebed02ad Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:04:52 +0200 Subject: Adding upstream version 1.21.3. Signed-off-by: Daniel Baumann --- lib/Makefile.am | 14 + lib/Makefile.in | 9569 ++++++++++++++++++++++++++++ lib/_Noreturn.h | 45 + lib/accept.c | 52 + lib/access.c | 31 + lib/af_alg.c | 213 + lib/af_alg.h | 115 + lib/alloca.c | 202 + lib/alloca.in.h | 72 + lib/arg-nonnull.h | 26 + lib/arpa_inet.in.h | 150 + lib/array-mergesort.h | 281 + lib/asnprintf.c | 34 + lib/asprintf.c | 39 + lib/assure.h | 57 + lib/at-func.c | 146 + lib/attribute.h | 226 + lib/base32.c | 586 ++ lib/base32.h | 60 + lib/basename-lgpl.c | 71 + lib/basename-lgpl.h | 78 + lib/basename.c | 64 + lib/binary-io.c | 39 + lib/binary-io.h | 77 + lib/bind.c | 49 + lib/bitrotate.c | 21 + lib/bitrotate.h | 138 + lib/btowc.c | 39 + lib/byteswap.in.h | 44 + lib/c++defs.h | 331 + lib/c-ctype.c | 21 + lib/c-ctype.h | 366 ++ lib/c-strcase.h | 56 + lib/c-strcasecmp.c | 56 + lib/c-strcaseeq.h | 181 + lib/c-strcasestr.c | 77 + lib/c-strcasestr.h | 36 + lib/c-strncasecmp.c | 56 + lib/calloc.c | 55 + lib/canonicalize-lgpl.c | 472 ++ lib/canonicalize.c | 489 ++ lib/canonicalize.h | 58 + lib/cdefs.h | 707 ++ lib/chdir-long.c | 264 + lib/chdir-long.h | 30 + lib/cloexec.c | 83 + lib/cloexec.h | 36 + lib/close.c | 75 + lib/closedir.c | 71 + lib/concat-filename.c | 73 + lib/concat-filename.h | 46 + lib/connect.c | 56 + lib/ctype.in.h | 57 + lib/dirent-private.h | 44 + lib/dirent.in.h | 321 + lib/dirfd.c | 98 + lib/dirname-lgpl.c | 86 + lib/dirname.c | 38 + lib/dirname.h | 54 + lib/dup-safer-flag.c | 38 + lib/dup-safer.c | 34 + lib/dup.c | 92 + lib/dup2.c | 189 + lib/dynarray.h | 284 + lib/eloop-threshold.h | 83 + lib/errno.in.h | 279 + lib/error.c | 411 ++ lib/error.h | 66 + lib/exitfail.c | 24 + lib/exitfail.h | 18 + lib/fatal-signal.c | 372 ++ lib/fatal-signal.h | 96 + lib/fchdir.c | 206 + lib/fcntl.c | 629 ++ lib/fcntl.in.h | 441 ++ lib/fd-hook.c | 116 + lib/fd-hook.h | 119 + lib/fd-safer-flag.c | 52 + lib/fd-safer.c | 49 + lib/fdopendir.c | 249 + lib/fflush.c | 233 + lib/file-set.c | 74 + lib/file-set.h | 33 + lib/filename.h | 112 + lib/filenamecat-lgpl.c | 90 + lib/filenamecat.h | 32 + lib/findprog-in.c | 399 ++ lib/findprog.h | 77 + lib/flexmember.h | 60 + lib/float+.h | 147 + lib/float.c | 33 + lib/float.in.h | 194 + lib/flock.c | 224 + lib/fnmatch.c | 361 ++ lib/fnmatch.in.h | 110 + lib/fnmatch_loop.c | 1211 ++++ lib/fopen.c | 230 + lib/fpurge.c | 150 + lib/freading.c | 76 + lib/freading.h | 55 + lib/free.c | 53 + lib/fseek.c | 30 + lib/fseeko.c | 164 + lib/fstat.c | 94 + lib/fstatat.c | 148 + lib/ftell.c | 37 + lib/ftello.c | 157 + lib/futimens.c | 37 + lib/gai_strerror.c | 92 + lib/getaddrinfo.c | 505 ++ lib/getcwd-lgpl.c | 127 + lib/getcwd.c | 495 ++ lib/getdelim.c | 147 + lib/getdtablesize.c | 124 + lib/getgroups.c | 125 + lib/getline.c | 27 + lib/getopt-cdefs.in.h | 66 + lib/getopt-core.h | 96 + lib/getopt-ext.h | 77 + lib/getopt-pfx-core.h | 66 + lib/getopt-pfx-ext.h | 70 + lib/getopt.c | 811 +++ lib/getopt.in.h | 61 + lib/getopt1.c | 159 + lib/getopt_int.h | 118 + lib/getpass.c | 237 + lib/getpass.h | 21 + lib/getpeername.c | 49 + lib/getprogname.c | 302 + lib/getprogname.h | 40 + lib/getrandom.c | 191 + lib/getsockname.c | 49 + lib/gettext.h | 300 + lib/gettime.c | 51 + lib/gettimeofday.c | 153 + lib/gl_openssl.h | 116 + lib/glthread/lock.c | 749 +++ lib/glthread/lock.h | 791 +++ lib/glthread/threadlib.c | 108 + lib/gnulib.mk | 4711 ++++++++++++++ lib/group-member.c | 115 + lib/hard-locale.c | 35 + lib/hard-locale.h | 28 + lib/hash-pjw.c | 40 + lib/hash-pjw.h | 23 + lib/hash-triple-simple.c | 59 + lib/hash-triple.h | 46 + lib/hash.c | 1106 ++++ lib/hash.h | 264 + lib/ialloc.c | 21 + lib/ialloc.h | 100 + lib/iconv.in.h | 127 + lib/idx.h | 134 + lib/inet_ntop.c | 260 + lib/intprops.h | 642 ++ lib/inttypes.in.h | 1002 +++ lib/ioctl.c | 92 + lib/isblank.c | 33 + lib/iswblank.c | 26 + lib/iswdigit.c | 26 + lib/iswxdigit.c | 33 + lib/itold.c | 28 + lib/langinfo.in.h | 222 + lib/lc-charset-dispatch.c | 82 + lib/lc-charset-dispatch.h | 40 + lib/libc-config.h | 191 + lib/libunistring.valgrind | 32 + lib/limits.in.h | 131 + lib/link.c | 237 + lib/listen.c | 49 + lib/localcharset.c | 1159 ++++ lib/localcharset.h | 137 + lib/locale.in.h | 305 + lib/localeconv.c | 103 + lib/lseek.c | 89 + lib/lstat.c | 104 + lib/malloc.c | 51 + lib/malloc/dynarray-skeleton.c | 528 ++ lib/malloc/dynarray.h | 178 + lib/malloc/dynarray_at_failure.c | 40 + lib/malloc/dynarray_emplace_enlarge.c | 77 + lib/malloc/dynarray_finalize.c | 66 + lib/malloc/dynarray_resize.c | 68 + lib/malloc/dynarray_resize_clear.c | 39 + lib/malloc/scratch_buffer.h | 151 + lib/malloc/scratch_buffer_dupfree.c | 41 + lib/malloc/scratch_buffer_grow.c | 56 + lib/malloc/scratch_buffer_grow_preserve.c | 67 + lib/malloc/scratch_buffer_set_array_size.c | 64 + lib/malloca.c | 113 + lib/malloca.h | 126 + lib/mbchar.c | 37 + lib/mbchar.h | 353 + lib/mbiter.c | 21 + lib/mbiter.h | 218 + lib/mbrtowc-impl-utf8.h | 138 + lib/mbrtowc-impl.h | 262 + lib/mbrtowc.c | 158 + lib/mbsinit.c | 70 + lib/mbsrtowcs-impl.h | 122 + lib/mbsrtowcs-state.c | 37 + lib/mbsrtowcs.c | 36 + lib/mbtowc-impl.h | 44 + lib/mbtowc-lock.c | 150 + lib/mbtowc-lock.h | 125 + lib/mbtowc.c | 26 + lib/md2-stream.c | 109 + lib/md2.c | 192 + lib/md2.h | 87 + lib/md4-stream.c | 109 + lib/md4.c | 300 + lib/md4.h | 93 + lib/md5-stream.c | 141 + lib/md5.c | 395 ++ lib/md5.h | 148 + lib/memchr.c | 172 + lib/memchr.valgrind | 30 + lib/mempcpy.c | 33 + lib/memrchr.c | 161 + lib/minmax.h | 60 + lib/mkdir.c | 93 + lib/mkostemp.c | 46 + lib/mkstemp.c | 50 + lib/mktime-internal.h | 79 + lib/mktime.c | 578 ++ lib/msvc-inval.c | 129 + lib/msvc-inval.h | 222 + lib/msvc-nothrow.c | 51 + lib/msvc-nothrow.h | 43 + lib/nanosleep.c | 195 + lib/netdb.in.h | 295 + lib/netinet_in.in.h | 47 + lib/nl_langinfo-lock.c | 150 + lib/nl_langinfo.c | 572 ++ lib/open.c | 209 + lib/openat-die.c | 62 + lib/openat-priv.h | 64 + lib/openat-proc.c | 135 + lib/openat.c | 312 + lib/openat.h | 123 + lib/opendir.c | 179 + lib/os2-spawn.c | 155 + lib/os2-spawn.h | 33 + lib/pathmax.h | 83 + lib/pipe-safer.c | 52 + lib/pipe.c | 50 + lib/pipe2-safer.c | 52 + lib/pipe2.c | 167 + lib/printf-args.c | 183 + lib/printf-args.h | 150 + lib/printf-parse.c | 623 ++ lib/printf-parse.h | 193 + lib/pselect.c | 110 + lib/pthread_sigmask.c | 92 + lib/quote.h | 46 + lib/quotearg.c | 1081 ++++ lib/quotearg.h | 431 ++ lib/raise.c | 83 + lib/rawmemchr.c | 125 + lib/rawmemchr.valgrind | 28 + lib/readdir.c | 102 + lib/readlink.c | 104 + lib/realloc.c | 63 + lib/reallocarray.c | 39 + lib/recv.c | 49 + lib/regcomp.c | 3778 +++++++++++ lib/regex.c | 84 + lib/regex.h | 699 ++ lib/regex_internal.c | 1713 +++++ lib/regex_internal.h | 835 +++ lib/regexec.c | 4220 ++++++++++++ lib/rename.c | 477 ++ lib/rewinddir.c | 53 + lib/rmdir.c | 56 + lib/same-inode.h | 47 + lib/save-cwd.c | 97 + lib/save-cwd.h | 34 + lib/sched.in.h | 99 + lib/scratch_buffer.h | 127 + lib/secure_getenv.c | 54 + lib/select.c | 598 ++ lib/send.c | 49 + lib/setlocale-lock.c | 150 + lib/setlocale_null.c | 411 ++ lib/setlocale_null.h | 82 + lib/setsockopt.c | 65 + lib/sha1-stream.c | 129 + lib/sha1.c | 361 ++ lib/sha1.h | 112 + lib/sha256-stream.c | 145 + lib/sha256.c | 433 ++ lib/sha256.h | 118 + lib/sha512-stream.c | 145 + lib/sha512.c | 478 ++ lib/sha512.h | 121 + lib/sig-handler.c | 21 + lib/sig-handler.h | 51 + lib/sigaction.c | 204 + lib/signal.in.h | 487 ++ lib/sigprocmask.c | 349 + lib/size_max.h | 30 + lib/snprintf.c | 71 + lib/socket.c | 53 + lib/sockets.c | 161 + lib/sockets.h | 66 + lib/spawn-pipe.c | 673 ++ lib/spawn-pipe.h | 166 + lib/spawn.c | 34 + lib/spawn.in.h | 992 +++ lib/spawn_faction_addchdir.c | 70 + lib/spawn_faction_addclose.c | 69 + lib/spawn_faction_adddup2.c | 70 + lib/spawn_faction_addopen.c | 86 + lib/spawn_faction_destroy.c | 61 + lib/spawn_faction_init.c | 56 + lib/spawn_int.h | 72 + lib/spawnattr_destroy.c | 28 + lib/spawnattr_init.c | 33 + lib/spawnattr_setflags.c | 45 + lib/spawnattr_setpgroup.c | 32 + lib/spawnattr_setsigmask.c | 33 + lib/spawni.c | 965 +++ lib/spawnp.c | 34 + lib/stat-time.c | 21 + lib/stat-time.h | 252 + lib/stat-w32.c | 461 ++ lib/stat-w32.h | 37 + lib/stat.c | 440 ++ lib/stdalign.in.h | 127 + lib/stdbool.in.h | 132 + lib/stddef.in.h | 147 + lib/stdint.in.h | 740 +++ lib/stdio-impl.h | 212 + lib/stdio-read.c | 168 + lib/stdio-write.c | 206 + lib/stdio.in.h | 1711 +++++ lib/stdlib.in.h | 1555 +++++ lib/stpcpy.c | 49 + lib/str-two-way.h | 452 ++ lib/strcasecmp.c | 62 + lib/strchrnul.c | 142 + lib/strchrnul.valgrind | 28 + lib/strdup.c | 54 + lib/streq.h | 176 + lib/strerror-override.c | 306 + lib/strerror-override.h | 57 + lib/strerror.c | 71 + lib/strerror_r.c | 451 ++ lib/string.in.h | 1269 ++++ lib/strings.in.h | 122 + lib/stripslash.c | 45 + lib/strncasecmp.c | 62 + lib/strndup.c | 36 + lib/strnlen.c | 30 + lib/strnlen1.c | 35 + lib/strnlen1.h | 40 + lib/strpbrk.c | 43 + lib/strptime.c | 1163 ++++ lib/strtok_r.c | 76 + lib/strtol.c | 408 ++ lib/strtoll.c | 33 + lib/symlink.c | 57 + lib/sys-limits.h | 42 + lib/sys_file.in.h | 63 + lib/sys_ioctl.in.h | 79 + lib/sys_random.in.h | 98 + lib/sys_select.in.h | 331 + lib/sys_socket.c | 22 + lib/sys_socket.in.h | 734 +++ lib/sys_stat.in.h | 928 +++ lib/sys_time.in.h | 224 + lib/sys_types.in.h | 106 + lib/sys_uio.in.h | 63 + lib/sys_wait.in.h | 131 + lib/tempname.c | 345 + lib/tempname.h | 72 + lib/thread-optim.h | 60 + lib/time.in.h | 452 ++ lib/time_r.c | 44 + lib/timegm.c | 58 + lib/timespec.c | 21 + lib/timespec.h | 102 + lib/tmpdir.c | 165 + lib/tmpdir.h | 26 + lib/u64.c | 22 + lib/u64.h | 179 + lib/unicase.in.h | 473 ++ lib/unicase/cased.c | 61 + lib/unicase/cased.h | 403 ++ lib/unicase/caseprop.h | 42 + lib/unicase/context.h | 73 + lib/unicase/empty-prefix-context.c | 35 + lib/unicase/empty-suffix-context.c | 35 + lib/unicase/ignorable.c | 79 + lib/unicase/ignorable.h | 664 ++ lib/unicase/simple-mapping.h | 47 + lib/unicase/special-casing-table.gperf | 160 + lib/unicase/special-casing-table.h | 333 + lib/unicase/special-casing.c | 33 + lib/unicase/special-casing.in.h | 69 + lib/unicase/tolower.c | 35 + lib/unicase/tolower.h | 735 +++ lib/unicase/u-casemap.h | 424 ++ lib/unicase/u8-casemap.c | 48 + lib/unicase/u8-tolower.c | 128 + lib/unicase/unicasemap.h | 60 + lib/unictype.in.h | 1090 ++++ lib/unictype/bitmap.h | 48 + lib/unictype/combiningclass.c | 47 + lib/unictype/combiningclass.h | 1591 +++++ lib/unictype/pr_soft_dotted.c | 43 + lib/unictype/pr_soft_dotted.h | 347 + lib/uninorm.in.h | 249 + lib/uninorm/decompose-internal.c | 29 + lib/uninorm/decompose-internal.h | 36 + lib/uninorm/normalize-internal.h | 35 + lib/uninorm/u-normalize-internal.h | 380 ++ lib/uninorm/u8-normalize.c | 46 + lib/unistd--.h | 32 + lib/unistd-safer.h | 31 + lib/unistd.c | 22 + lib/unistd.in.h | 2327 +++++++ lib/unistr.in.h | 753 +++ lib/unistr/u-cpy.h | 33 + lib/unistr/u8-cpy.c | 33 + lib/unistr/u8-mbtouc-unsafe-aux.c | 139 + lib/unistr/u8-mbtouc-unsafe.c | 150 + lib/unistr/u8-strlen.c | 29 + lib/unistr/u8-uctomb-aux.c | 60 + lib/unistr/u8-uctomb.c | 79 + lib/unitypes.in.h | 61 + lib/uniwidth.in.h | 72 + lib/uniwidth/cjk.h | 37 + lib/uniwidth/width.c | 95 + lib/uniwidth/width0.h | 485 ++ lib/uniwidth/width2.h | 549 ++ lib/unlink.c | 98 + lib/unlocked-io.h | 136 + lib/utime.c | 288 + lib/utime.in.h | 112 + lib/utimens.c | 647 ++ lib/utimens.h | 49 + lib/vasnprintf.c | 5872 +++++++++++++++++ lib/vasnprintf.h | 72 + lib/vasprintf.c | 50 + lib/verify.h | 315 + lib/vsnprintf.c | 70 + lib/w32sock.h | 140 + lib/wait-process.c | 370 ++ lib/wait-process.h | 74 + lib/waitpid.c | 30 + lib/warn-on-use.h | 149 + lib/wchar.in.h | 1322 ++++ lib/wcrtomb.c | 80 + lib/wctype-h.c | 23 + lib/wctype.in.h | 732 +++ lib/wcwidth.c | 73 + lib/windows-initguard.h | 35 + lib/windows-mutex.c | 95 + lib/windows-mutex.h | 51 + lib/windows-once.c | 62 + lib/windows-once.h | 47 + lib/windows-recmutex.c | 127 + lib/windows-recmutex.h | 57 + lib/windows-rwlock.c | 377 ++ lib/windows-rwlock.h | 68 + lib/windows-spawn.c | 727 +++ lib/windows-spawn.h | 157 + lib/wmemchr-impl.h | 27 + lib/wmemchr.c | 23 + lib/wmempcpy.c | 28 + lib/write.c | 155 + lib/xalloc-die.c | 41 + lib/xalloc-oversized.h | 65 + lib/xalloc.h | 213 + lib/xmalloc.c | 339 + lib/xmemdup0.c | 45 + lib/xmemdup0.h | 36 + lib/xsize.c | 21 + lib/xsize.h | 108 + lib/xstrndup.c | 36 + lib/xstrndup.h | 25 + 482 files changed, 119931 insertions(+) create mode 100644 lib/Makefile.am create mode 100644 lib/Makefile.in create mode 100644 lib/_Noreturn.h create mode 100644 lib/accept.c create mode 100644 lib/access.c create mode 100644 lib/af_alg.c create mode 100644 lib/af_alg.h create mode 100644 lib/alloca.c create mode 100644 lib/alloca.in.h create mode 100644 lib/arg-nonnull.h create mode 100644 lib/arpa_inet.in.h create mode 100644 lib/array-mergesort.h create mode 100644 lib/asnprintf.c create mode 100644 lib/asprintf.c create mode 100644 lib/assure.h create mode 100644 lib/at-func.c create mode 100644 lib/attribute.h create mode 100644 lib/base32.c create mode 100644 lib/base32.h create mode 100644 lib/basename-lgpl.c create mode 100644 lib/basename-lgpl.h create mode 100644 lib/basename.c create mode 100644 lib/binary-io.c create mode 100644 lib/binary-io.h create mode 100644 lib/bind.c create mode 100644 lib/bitrotate.c create mode 100644 lib/bitrotate.h create mode 100644 lib/btowc.c create mode 100644 lib/byteswap.in.h create mode 100644 lib/c++defs.h create mode 100644 lib/c-ctype.c create mode 100644 lib/c-ctype.h create mode 100644 lib/c-strcase.h create mode 100644 lib/c-strcasecmp.c create mode 100644 lib/c-strcaseeq.h create mode 100644 lib/c-strcasestr.c create mode 100644 lib/c-strcasestr.h create mode 100644 lib/c-strncasecmp.c create mode 100644 lib/calloc.c create mode 100644 lib/canonicalize-lgpl.c create mode 100644 lib/canonicalize.c create mode 100644 lib/canonicalize.h create mode 100644 lib/cdefs.h create mode 100644 lib/chdir-long.c create mode 100644 lib/chdir-long.h create mode 100644 lib/cloexec.c create mode 100644 lib/cloexec.h create mode 100644 lib/close.c create mode 100644 lib/closedir.c create mode 100644 lib/concat-filename.c create mode 100644 lib/concat-filename.h create mode 100644 lib/connect.c create mode 100644 lib/ctype.in.h create mode 100644 lib/dirent-private.h create mode 100644 lib/dirent.in.h create mode 100644 lib/dirfd.c create mode 100644 lib/dirname-lgpl.c create mode 100644 lib/dirname.c create mode 100644 lib/dirname.h create mode 100644 lib/dup-safer-flag.c create mode 100644 lib/dup-safer.c create mode 100644 lib/dup.c create mode 100644 lib/dup2.c create mode 100644 lib/dynarray.h create mode 100644 lib/eloop-threshold.h create mode 100644 lib/errno.in.h create mode 100644 lib/error.c create mode 100644 lib/error.h create mode 100644 lib/exitfail.c create mode 100644 lib/exitfail.h create mode 100644 lib/fatal-signal.c create mode 100644 lib/fatal-signal.h create mode 100644 lib/fchdir.c create mode 100644 lib/fcntl.c create mode 100644 lib/fcntl.in.h create mode 100644 lib/fd-hook.c create mode 100644 lib/fd-hook.h create mode 100644 lib/fd-safer-flag.c create mode 100644 lib/fd-safer.c create mode 100644 lib/fdopendir.c create mode 100644 lib/fflush.c create mode 100644 lib/file-set.c create mode 100644 lib/file-set.h create mode 100644 lib/filename.h create mode 100644 lib/filenamecat-lgpl.c create mode 100644 lib/filenamecat.h create mode 100644 lib/findprog-in.c create mode 100644 lib/findprog.h create mode 100644 lib/flexmember.h create mode 100644 lib/float+.h create mode 100644 lib/float.c create mode 100644 lib/float.in.h create mode 100644 lib/flock.c create mode 100644 lib/fnmatch.c create mode 100644 lib/fnmatch.in.h create mode 100644 lib/fnmatch_loop.c create mode 100644 lib/fopen.c create mode 100644 lib/fpurge.c create mode 100644 lib/freading.c create mode 100644 lib/freading.h create mode 100644 lib/free.c create mode 100644 lib/fseek.c create mode 100644 lib/fseeko.c create mode 100644 lib/fstat.c create mode 100644 lib/fstatat.c create mode 100644 lib/ftell.c create mode 100644 lib/ftello.c create mode 100644 lib/futimens.c create mode 100644 lib/gai_strerror.c create mode 100644 lib/getaddrinfo.c create mode 100644 lib/getcwd-lgpl.c create mode 100644 lib/getcwd.c create mode 100644 lib/getdelim.c create mode 100644 lib/getdtablesize.c create mode 100644 lib/getgroups.c create mode 100644 lib/getline.c create mode 100644 lib/getopt-cdefs.in.h create mode 100644 lib/getopt-core.h create mode 100644 lib/getopt-ext.h create mode 100644 lib/getopt-pfx-core.h create mode 100644 lib/getopt-pfx-ext.h create mode 100644 lib/getopt.c create mode 100644 lib/getopt.in.h create mode 100644 lib/getopt1.c create mode 100644 lib/getopt_int.h create mode 100644 lib/getpass.c create mode 100644 lib/getpass.h create mode 100644 lib/getpeername.c create mode 100644 lib/getprogname.c create mode 100644 lib/getprogname.h create mode 100644 lib/getrandom.c create mode 100644 lib/getsockname.c create mode 100644 lib/gettext.h create mode 100644 lib/gettime.c create mode 100644 lib/gettimeofday.c create mode 100644 lib/gl_openssl.h create mode 100644 lib/glthread/lock.c create mode 100644 lib/glthread/lock.h create mode 100644 lib/glthread/threadlib.c create mode 100644 lib/gnulib.mk create mode 100644 lib/group-member.c create mode 100644 lib/hard-locale.c create mode 100644 lib/hard-locale.h create mode 100644 lib/hash-pjw.c create mode 100644 lib/hash-pjw.h create mode 100644 lib/hash-triple-simple.c create mode 100644 lib/hash-triple.h create mode 100644 lib/hash.c create mode 100644 lib/hash.h create mode 100644 lib/ialloc.c create mode 100644 lib/ialloc.h create mode 100644 lib/iconv.in.h create mode 100644 lib/idx.h create mode 100644 lib/inet_ntop.c create mode 100644 lib/intprops.h create mode 100644 lib/inttypes.in.h create mode 100644 lib/ioctl.c create mode 100644 lib/isblank.c create mode 100644 lib/iswblank.c create mode 100644 lib/iswdigit.c create mode 100644 lib/iswxdigit.c create mode 100644 lib/itold.c create mode 100644 lib/langinfo.in.h create mode 100644 lib/lc-charset-dispatch.c create mode 100644 lib/lc-charset-dispatch.h create mode 100644 lib/libc-config.h create mode 100644 lib/libunistring.valgrind create mode 100644 lib/limits.in.h create mode 100644 lib/link.c create mode 100644 lib/listen.c create mode 100644 lib/localcharset.c create mode 100644 lib/localcharset.h create mode 100644 lib/locale.in.h create mode 100644 lib/localeconv.c create mode 100644 lib/lseek.c create mode 100644 lib/lstat.c create mode 100644 lib/malloc.c create mode 100644 lib/malloc/dynarray-skeleton.c create mode 100644 lib/malloc/dynarray.h create mode 100644 lib/malloc/dynarray_at_failure.c create mode 100644 lib/malloc/dynarray_emplace_enlarge.c create mode 100644 lib/malloc/dynarray_finalize.c create mode 100644 lib/malloc/dynarray_resize.c create mode 100644 lib/malloc/dynarray_resize_clear.c create mode 100644 lib/malloc/scratch_buffer.h create mode 100644 lib/malloc/scratch_buffer_dupfree.c create mode 100644 lib/malloc/scratch_buffer_grow.c create mode 100644 lib/malloc/scratch_buffer_grow_preserve.c create mode 100644 lib/malloc/scratch_buffer_set_array_size.c create mode 100644 lib/malloca.c create mode 100644 lib/malloca.h create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbiter.c create mode 100644 lib/mbiter.h create mode 100644 lib/mbrtowc-impl-utf8.h create mode 100644 lib/mbrtowc-impl.h create mode 100644 lib/mbrtowc.c create mode 100644 lib/mbsinit.c create mode 100644 lib/mbsrtowcs-impl.h create mode 100644 lib/mbsrtowcs-state.c create mode 100644 lib/mbsrtowcs.c create mode 100644 lib/mbtowc-impl.h create mode 100644 lib/mbtowc-lock.c create mode 100644 lib/mbtowc-lock.h create mode 100644 lib/mbtowc.c create mode 100644 lib/md2-stream.c create mode 100644 lib/md2.c create mode 100644 lib/md2.h create mode 100644 lib/md4-stream.c create mode 100644 lib/md4.c create mode 100644 lib/md4.h create mode 100644 lib/md5-stream.c create mode 100644 lib/md5.c create mode 100644 lib/md5.h create mode 100644 lib/memchr.c create mode 100644 lib/memchr.valgrind create mode 100644 lib/mempcpy.c create mode 100644 lib/memrchr.c create mode 100644 lib/minmax.h create mode 100644 lib/mkdir.c create mode 100644 lib/mkostemp.c create mode 100644 lib/mkstemp.c create mode 100644 lib/mktime-internal.h create mode 100644 lib/mktime.c create mode 100644 lib/msvc-inval.c create mode 100644 lib/msvc-inval.h create mode 100644 lib/msvc-nothrow.c create mode 100644 lib/msvc-nothrow.h create mode 100644 lib/nanosleep.c create mode 100644 lib/netdb.in.h create mode 100644 lib/netinet_in.in.h create mode 100644 lib/nl_langinfo-lock.c create mode 100644 lib/nl_langinfo.c create mode 100644 lib/open.c create mode 100644 lib/openat-die.c create mode 100644 lib/openat-priv.h create mode 100644 lib/openat-proc.c create mode 100644 lib/openat.c create mode 100644 lib/openat.h create mode 100644 lib/opendir.c create mode 100644 lib/os2-spawn.c create mode 100644 lib/os2-spawn.h create mode 100644 lib/pathmax.h create mode 100644 lib/pipe-safer.c create mode 100644 lib/pipe.c create mode 100644 lib/pipe2-safer.c create mode 100644 lib/pipe2.c create mode 100644 lib/printf-args.c create mode 100644 lib/printf-args.h create mode 100644 lib/printf-parse.c create mode 100644 lib/printf-parse.h create mode 100644 lib/pselect.c create mode 100644 lib/pthread_sigmask.c create mode 100644 lib/quote.h create mode 100644 lib/quotearg.c create mode 100644 lib/quotearg.h create mode 100644 lib/raise.c create mode 100644 lib/rawmemchr.c create mode 100644 lib/rawmemchr.valgrind create mode 100644 lib/readdir.c create mode 100644 lib/readlink.c create mode 100644 lib/realloc.c create mode 100644 lib/reallocarray.c create mode 100644 lib/recv.c create mode 100644 lib/regcomp.c create mode 100644 lib/regex.c create mode 100644 lib/regex.h create mode 100644 lib/regex_internal.c create mode 100644 lib/regex_internal.h create mode 100644 lib/regexec.c create mode 100644 lib/rename.c create mode 100644 lib/rewinddir.c create mode 100644 lib/rmdir.c create mode 100644 lib/same-inode.h create mode 100644 lib/save-cwd.c create mode 100644 lib/save-cwd.h create mode 100644 lib/sched.in.h create mode 100644 lib/scratch_buffer.h create mode 100644 lib/secure_getenv.c create mode 100644 lib/select.c create mode 100644 lib/send.c create mode 100644 lib/setlocale-lock.c create mode 100644 lib/setlocale_null.c create mode 100644 lib/setlocale_null.h create mode 100644 lib/setsockopt.c create mode 100644 lib/sha1-stream.c create mode 100644 lib/sha1.c create mode 100644 lib/sha1.h create mode 100644 lib/sha256-stream.c create mode 100644 lib/sha256.c create mode 100644 lib/sha256.h create mode 100644 lib/sha512-stream.c create mode 100644 lib/sha512.c create mode 100644 lib/sha512.h create mode 100644 lib/sig-handler.c create mode 100644 lib/sig-handler.h create mode 100644 lib/sigaction.c create mode 100644 lib/signal.in.h create mode 100644 lib/sigprocmask.c create mode 100644 lib/size_max.h create mode 100644 lib/snprintf.c create mode 100644 lib/socket.c create mode 100644 lib/sockets.c create mode 100644 lib/sockets.h create mode 100644 lib/spawn-pipe.c create mode 100644 lib/spawn-pipe.h create mode 100644 lib/spawn.c create mode 100644 lib/spawn.in.h create mode 100644 lib/spawn_faction_addchdir.c create mode 100644 lib/spawn_faction_addclose.c create mode 100644 lib/spawn_faction_adddup2.c create mode 100644 lib/spawn_faction_addopen.c create mode 100644 lib/spawn_faction_destroy.c create mode 100644 lib/spawn_faction_init.c create mode 100644 lib/spawn_int.h create mode 100644 lib/spawnattr_destroy.c create mode 100644 lib/spawnattr_init.c create mode 100644 lib/spawnattr_setflags.c create mode 100644 lib/spawnattr_setpgroup.c create mode 100644 lib/spawnattr_setsigmask.c create mode 100644 lib/spawni.c create mode 100644 lib/spawnp.c create mode 100644 lib/stat-time.c create mode 100644 lib/stat-time.h create mode 100644 lib/stat-w32.c create mode 100644 lib/stat-w32.h create mode 100644 lib/stat.c create mode 100644 lib/stdalign.in.h create mode 100644 lib/stdbool.in.h create mode 100644 lib/stddef.in.h create mode 100644 lib/stdint.in.h create mode 100644 lib/stdio-impl.h create mode 100644 lib/stdio-read.c create mode 100644 lib/stdio-write.c create mode 100644 lib/stdio.in.h create mode 100644 lib/stdlib.in.h create mode 100644 lib/stpcpy.c create mode 100644 lib/str-two-way.h create mode 100644 lib/strcasecmp.c create mode 100644 lib/strchrnul.c create mode 100644 lib/strchrnul.valgrind create mode 100644 lib/strdup.c create mode 100644 lib/streq.h create mode 100644 lib/strerror-override.c create mode 100644 lib/strerror-override.h create mode 100644 lib/strerror.c create mode 100644 lib/strerror_r.c create mode 100644 lib/string.in.h create mode 100644 lib/strings.in.h create mode 100644 lib/stripslash.c create mode 100644 lib/strncasecmp.c create mode 100644 lib/strndup.c create mode 100644 lib/strnlen.c create mode 100644 lib/strnlen1.c create mode 100644 lib/strnlen1.h create mode 100644 lib/strpbrk.c create mode 100644 lib/strptime.c create mode 100644 lib/strtok_r.c create mode 100644 lib/strtol.c create mode 100644 lib/strtoll.c create mode 100644 lib/symlink.c create mode 100644 lib/sys-limits.h create mode 100644 lib/sys_file.in.h create mode 100644 lib/sys_ioctl.in.h create mode 100644 lib/sys_random.in.h create mode 100644 lib/sys_select.in.h create mode 100644 lib/sys_socket.c create mode 100644 lib/sys_socket.in.h create mode 100644 lib/sys_stat.in.h create mode 100644 lib/sys_time.in.h create mode 100644 lib/sys_types.in.h create mode 100644 lib/sys_uio.in.h create mode 100644 lib/sys_wait.in.h create mode 100644 lib/tempname.c create mode 100644 lib/tempname.h create mode 100644 lib/thread-optim.h create mode 100644 lib/time.in.h create mode 100644 lib/time_r.c create mode 100644 lib/timegm.c create mode 100644 lib/timespec.c create mode 100644 lib/timespec.h create mode 100644 lib/tmpdir.c create mode 100644 lib/tmpdir.h create mode 100644 lib/u64.c create mode 100644 lib/u64.h create mode 100644 lib/unicase.in.h create mode 100644 lib/unicase/cased.c create mode 100644 lib/unicase/cased.h create mode 100644 lib/unicase/caseprop.h create mode 100644 lib/unicase/context.h create mode 100644 lib/unicase/empty-prefix-context.c create mode 100644 lib/unicase/empty-suffix-context.c create mode 100644 lib/unicase/ignorable.c create mode 100644 lib/unicase/ignorable.h create mode 100644 lib/unicase/simple-mapping.h create mode 100644 lib/unicase/special-casing-table.gperf create mode 100644 lib/unicase/special-casing-table.h create mode 100644 lib/unicase/special-casing.c create mode 100644 lib/unicase/special-casing.in.h create mode 100644 lib/unicase/tolower.c create mode 100644 lib/unicase/tolower.h create mode 100644 lib/unicase/u-casemap.h create mode 100644 lib/unicase/u8-casemap.c create mode 100644 lib/unicase/u8-tolower.c create mode 100644 lib/unicase/unicasemap.h create mode 100644 lib/unictype.in.h create mode 100644 lib/unictype/bitmap.h create mode 100644 lib/unictype/combiningclass.c create mode 100644 lib/unictype/combiningclass.h create mode 100644 lib/unictype/pr_soft_dotted.c create mode 100644 lib/unictype/pr_soft_dotted.h create mode 100644 lib/uninorm.in.h create mode 100644 lib/uninorm/decompose-internal.c create mode 100644 lib/uninorm/decompose-internal.h create mode 100644 lib/uninorm/normalize-internal.h create mode 100644 lib/uninorm/u-normalize-internal.h create mode 100644 lib/uninorm/u8-normalize.c create mode 100644 lib/unistd--.h create mode 100644 lib/unistd-safer.h create mode 100644 lib/unistd.c create mode 100644 lib/unistd.in.h create mode 100644 lib/unistr.in.h create mode 100644 lib/unistr/u-cpy.h create mode 100644 lib/unistr/u8-cpy.c create mode 100644 lib/unistr/u8-mbtouc-unsafe-aux.c create mode 100644 lib/unistr/u8-mbtouc-unsafe.c create mode 100644 lib/unistr/u8-strlen.c create mode 100644 lib/unistr/u8-uctomb-aux.c create mode 100644 lib/unistr/u8-uctomb.c create mode 100644 lib/unitypes.in.h create mode 100644 lib/uniwidth.in.h create mode 100644 lib/uniwidth/cjk.h create mode 100644 lib/uniwidth/width.c create mode 100644 lib/uniwidth/width0.h create mode 100644 lib/uniwidth/width2.h create mode 100644 lib/unlink.c create mode 100644 lib/unlocked-io.h create mode 100644 lib/utime.c create mode 100644 lib/utime.in.h create mode 100644 lib/utimens.c create mode 100644 lib/utimens.h create mode 100644 lib/vasnprintf.c create mode 100644 lib/vasnprintf.h create mode 100644 lib/vasprintf.c create mode 100644 lib/verify.h create mode 100644 lib/vsnprintf.c create mode 100644 lib/w32sock.h create mode 100644 lib/wait-process.c create mode 100644 lib/wait-process.h create mode 100644 lib/waitpid.c create mode 100644 lib/warn-on-use.h create mode 100644 lib/wchar.in.h create mode 100644 lib/wcrtomb.c create mode 100644 lib/wctype-h.c create mode 100644 lib/wctype.in.h create mode 100644 lib/wcwidth.c create mode 100644 lib/windows-initguard.h create mode 100644 lib/windows-mutex.c create mode 100644 lib/windows-mutex.h create mode 100644 lib/windows-once.c create mode 100644 lib/windows-once.h create mode 100644 lib/windows-recmutex.c create mode 100644 lib/windows-recmutex.h create mode 100644 lib/windows-rwlock.c create mode 100644 lib/windows-rwlock.h create mode 100644 lib/windows-spawn.c create mode 100644 lib/windows-spawn.h create mode 100644 lib/wmemchr-impl.h create mode 100644 lib/wmemchr.c create mode 100644 lib/wmempcpy.c create mode 100644 lib/write.c create mode 100644 lib/xalloc-die.c create mode 100644 lib/xalloc-oversized.h create mode 100644 lib/xalloc.h create mode 100644 lib/xmalloc.c create mode 100644 lib/xmemdup0.c create mode 100644 lib/xmemdup0.h create mode 100644 lib/xsize.c create mode 100644 lib/xsize.h create mode 100644 lib/xstrndup.c create mode 100644 lib/xstrndup.h (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..e58fa28 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,14 @@ +MOSTLYCLEANFILES = +noinst_LTLIBRARIES = +EXTRA_DIST = +BUILT_SOURCES = +MOSTLYCLEANDIRS = +CLEANFILES = +SUFFIXES = +noinst_LIBRARIES = +MAINTAINERCLEANFILES = + +AM_CFLAGS = $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) +AM_CPPFLAGS = + +include gnulib.mk diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 0000000..d1881d7 --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,9569 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# 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 +# (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. +# +# You should have received a copy of the GNU General Public License +# 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 +# contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# Reproduce by: +# gnulib-tool --import --local-dir=gl \ +# --lib=libgnu \ +# --source-base=lib \ +# --m4-base=m4 \ +# --po-base=gnulib_po \ +# --doc-base=doc \ +# --tests-base=lib/tests \ +# --aux-dir=build-aux \ +# --makefile-name=gnulib.mk \ +# --no-conditional-dependencies \ +# --no-libtool \ +# --macro-prefix=gl \ +# --po-domain=wget \ +# accept \ +# announce-gen \ +# base32 \ +# bind \ +# c-ctype \ +# c-strcase \ +# c-strcasestr \ +# clock-time \ +# close \ +# connect \ +# crypto/md2 \ +# crypto/md4 \ +# crypto/md5 \ +# crypto/sha1 \ +# crypto/sha256 \ +# crypto/sha512 \ +# dirname \ +# fcntl \ +# flock \ +# fnmatch-gnu \ +# fopen \ +# ftello \ +# futimens \ +# gendocs \ +# getaddrinfo \ +# getline \ +# getopt-gnu \ +# getpass-gnu \ +# getpeername \ +# getsockname \ +# gettext-h \ +# git-version-gen \ +# gitlog-to-changelog \ +# gnu-web-doc-update \ +# gnupload \ +# group-member \ +# hostent \ +# iconv \ +# iconv-h \ +# inet_ntop \ +# intprops \ +# inttypes \ +# ioctl \ +# langinfo \ +# libunistring-optional \ +# limits-h \ +# link \ +# listen \ +# maintainer-makefile \ +# mbiter \ +# mbtowc \ +# memrchr \ +# mkdir \ +# mkostemp \ +# mkstemp \ +# nanosleep \ +# open \ +# pipe-posix \ +# posix_spawn \ +# quote \ +# quotearg \ +# recv \ +# regex \ +# rename \ +# select \ +# send \ +# setsockopt \ +# signal-h \ +# sigpipe \ +# sigprocmask \ +# snprintf \ +# socket \ +# spawn-pipe \ +# stat \ +# stdbool \ +# stdint \ +# strcase \ +# strerror_r-posix \ +# strpbrk \ +# strptime \ +# strtok_r \ +# strtol \ +# strtoll \ +# symlink \ +# sys_types \ +# timegm \ +# tmpdir \ +# unicase/u8-tolower \ +# unistr/u8-strlen \ +# unlink \ +# unlocked-io \ +# update-copyright \ +# utime \ +# utimens \ +# vasprintf \ +# vsnprintf \ +# warnings \ +# wcwidth \ +# write \ +# xmemdup0 \ +# xstrndup + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@GL_COND_OBJ_ACCEPT_TRUE@am__append_1 = accept.c +@GL_COND_OBJ_ACCESS_TRUE@am__append_2 = access.c +@GL_COND_OBJ_BIND_TRUE@am__append_3 = bind.c +@GL_COND_OBJ_BTOWC_TRUE@am__append_4 = btowc.c +@GL_COND_OBJ_CANONICALIZE_LGPL_TRUE@am__append_5 = canonicalize-lgpl.c +@GL_COND_OBJ_CHDIR_LONG_TRUE@am__append_6 = chdir-long.c +@GL_COND_OBJ_CLOSE_TRUE@am__append_7 = close.c +@GL_COND_OBJ_CLOSEDIR_TRUE@am__append_8 = closedir.c +@GL_COND_OBJ_CONNECT_TRUE@am__append_9 = connect.c +@GL_COND_OBJ_DIRFD_TRUE@am__append_10 = dirfd.c +@GL_COND_OBJ_DUP_TRUE@am__append_11 = dup.c +@GL_COND_OBJ_DUP2_TRUE@am__append_12 = dup2.c +@GL_COND_OBJ_ERROR_TRUE@am__append_13 = error.c +@GL_COND_OBJ_FCHDIR_TRUE@am__append_14 = fchdir.c +@GL_COND_OBJ_FCNTL_TRUE@am__append_15 = fcntl.c +@GL_COND_OBJ_FDOPENDIR_TRUE@am__append_16 = fdopendir.c +@GL_COND_OBJ_FFLUSH_TRUE@am__append_17 = fflush.c +@GL_COND_OBJ_FLOAT_TRUE@am__append_18 = float.c +@GL_COND_OBJ_ITOLD_TRUE@am__append_19 = itold.c +@GL_COND_OBJ_FLOCK_TRUE@am__append_20 = flock.c +@GL_COND_OBJ_FPURGE_TRUE@am__append_21 = fpurge.c +@GL_COND_OBJ_FREE_TRUE@am__append_22 = free.c +@GL_COND_OBJ_FSEEK_TRUE@am__append_23 = fseek.c +@GL_COND_OBJ_FSEEKO_TRUE@am__append_24 = fseeko.c +@GL_COND_OBJ_FSTAT_TRUE@am__append_25 = fstat.c +@GL_COND_OBJ_FSTATAT_TRUE@am__append_26 = fstatat.c +@GL_COND_OBJ_FTELL_TRUE@am__append_27 = ftell.c +@GL_COND_OBJ_FTELLO_TRUE@am__append_28 = ftello.c +@GL_COND_OBJ_FUTIMENS_TRUE@am__append_29 = futimens.c +@GL_COND_OBJ_GETADDRINFO_TRUE@am__append_30 = getaddrinfo.c +@GL_COND_OBJ_GAI_STRERROR_TRUE@am__append_31 = gai_strerror.c +@GL_COND_OBJ_GETCWD_TRUE@am__append_32 = getcwd.c +@GL_COND_OBJ_GETCWD_LGPL_TRUE@am__append_33 = getcwd-lgpl.c +@GL_COND_OBJ_GETDELIM_TRUE@am__append_34 = getdelim.c +@GL_COND_OBJ_GETDTABLESIZE_TRUE@am__append_35 = getdtablesize.c +@GL_COND_OBJ_GETGROUPS_TRUE@am__append_36 = getgroups.c +@GL_COND_OBJ_GETLINE_TRUE@am__append_37 = getline.c +@GL_COND_OBJ_GETOPT_TRUE@am__append_38 = getopt.c getopt1.c +@GL_COND_OBJ_GETPEERNAME_TRUE@am__append_39 = getpeername.c +@GL_COND_OBJ_GETRANDOM_TRUE@am__append_40 = getrandom.c +@GL_COND_OBJ_GETSOCKNAME_TRUE@am__append_41 = getsockname.c +@GL_COND_OBJ_GETTIMEOFDAY_TRUE@am__append_42 = gettimeofday.c +@GL_COND_OBJ_GROUP_MEMBER_TRUE@am__append_43 = group-member.c +@GL_COND_OBJ_INET_NTOP_TRUE@am__append_44 = inet_ntop.c +@GL_COND_OBJ_IOCTL_TRUE@am__append_45 = ioctl.c +@GL_COND_OBJ_ISBLANK_TRUE@am__append_46 = isblank.c +@GL_COND_OBJ_ISWBLANK_TRUE@am__append_47 = iswblank.c +@GL_COND_OBJ_ISWDIGIT_TRUE@am__append_48 = iswdigit.c +@GL_COND_OBJ_ISWXDIGIT_TRUE@am__append_49 = iswxdigit.c +@GL_COND_OBJ_LINK_TRUE@am__append_50 = link.c +@GL_COND_OBJ_LISTEN_TRUE@am__append_51 = listen.c +@GL_COND_OBJ_LOCALECONV_TRUE@am__append_52 = localeconv.c +@GL_COND_OBJ_LSEEK_TRUE@am__append_53 = lseek.c +@GL_COND_OBJ_LSTAT_TRUE@am__append_54 = lstat.c +@GL_COND_OBJ_MBRTOWC_TRUE@am__append_55 = mbrtowc.c +@GL_COND_OBJ_MBSINIT_TRUE@am__append_56 = mbsinit.c +@GL_COND_OBJ_MBSRTOWCS_TRUE@am__append_57 = mbsrtowcs.c +@GL_COND_OBJ_MBTOWC_TRUE@am__append_58 = mbtowc.c +@GL_COND_OBJ_MEMCHR_TRUE@am__append_59 = memchr.c +@GL_COND_OBJ_MEMPCPY_TRUE@am__append_60 = mempcpy.c +@GL_COND_OBJ_MEMRCHR_TRUE@am__append_61 = memrchr.c +@GL_COND_OBJ_MKDIR_TRUE@am__append_62 = mkdir.c +@GL_COND_OBJ_MKOSTEMP_TRUE@am__append_63 = mkostemp.c +@GL_COND_OBJ_MKSTEMP_TRUE@am__append_64 = mkstemp.c +@GL_COND_OBJ_MSVC_INVAL_TRUE@am__append_65 = msvc-inval.c +@GL_COND_OBJ_MSVC_NOTHROW_TRUE@am__append_66 = msvc-nothrow.c +@GL_COND_OBJ_NANOSLEEP_TRUE@am__append_67 = nanosleep.c +@GL_COND_OBJ_NL_LANGINFO_TRUE@am__append_68 = nl_langinfo.c +@GL_COND_OBJ_NL_LANGINFO_LOCK_TRUE@am__append_69 = nl_langinfo-lock.c +@GL_COND_OBJ_OPEN_TRUE@am__append_70 = open.c +@GL_COND_OBJ_OPENAT_TRUE@am__append_71 = openat.c +@GL_COND_OBJ_OPENDIR_TRUE@am__append_72 = opendir.c +@GL_COND_OBJ_PIPE_TRUE@am__append_73 = pipe.c +@GL_COND_OBJ_SPAWN_TRUE@am__append_74 = spawn.c +@GL_COND_OBJ_SPAWNI_TRUE@am__append_75 = spawni.c +@GL_COND_OBJ_SPAWN_FACTION_ADDCHDIR_TRUE@am__append_76 = spawn_faction_addchdir.c +@GL_COND_OBJ_SPAWN_FACTION_ADDCLOSE_TRUE@am__append_77 = spawn_faction_addclose.c +@GL_COND_OBJ_SPAWN_FACTION_ADDDUP2_TRUE@am__append_78 = spawn_faction_adddup2.c +@GL_COND_OBJ_SPAWN_FACTION_ADDOPEN_TRUE@am__append_79 = spawn_faction_addopen.c +@GL_COND_OBJ_SPAWN_FACTION_DESTROY_TRUE@am__append_80 = spawn_faction_destroy.c +@GL_COND_OBJ_SPAWN_FACTION_INIT_TRUE@am__append_81 = spawn_faction_init.c +@GL_COND_OBJ_SPAWNATTR_DESTROY_TRUE@am__append_82 = spawnattr_destroy.c +@GL_COND_OBJ_SPAWNATTR_INIT_TRUE@am__append_83 = spawnattr_init.c +@GL_COND_OBJ_SPAWNATTR_SETFLAGS_TRUE@am__append_84 = spawnattr_setflags.c +@GL_COND_OBJ_SPAWNATTR_SETPGROUP_TRUE@am__append_85 = spawnattr_setpgroup.c +@GL_COND_OBJ_SPAWNATTR_SETSIGMASK_TRUE@am__append_86 = spawnattr_setsigmask.c +@GL_COND_OBJ_SPAWNP_TRUE@am__append_87 = spawnp.c +@GL_COND_OBJ_PSELECT_TRUE@am__append_88 = pselect.c +@GL_COND_OBJ_PTHREAD_SIGMASK_TRUE@am__append_89 = pthread_sigmask.c +@GL_COND_OBJ_RAISE_TRUE@am__append_90 = raise.c +@GL_COND_OBJ_RAWMEMCHR_TRUE@am__append_91 = rawmemchr.c +@GL_COND_OBJ_READDIR_TRUE@am__append_92 = readdir.c +@GL_COND_OBJ_READLINK_TRUE@am__append_93 = readlink.c +@GL_COND_OBJ_REALLOCARRAY_TRUE@am__append_94 = reallocarray.c +@GL_COND_OBJ_RECV_TRUE@am__append_95 = recv.c +@GL_COND_OBJ_REGEX_TRUE@am__append_96 = regex.c +@GL_COND_OBJ_RENAME_TRUE@am__append_97 = rename.c +@GL_COND_OBJ_REWINDDIR_TRUE@am__append_98 = rewinddir.c +@GL_COND_OBJ_RMDIR_TRUE@am__append_99 = rmdir.c +@GL_COND_OBJ_SECURE_GETENV_TRUE@am__append_100 = secure_getenv.c +@GL_COND_OBJ_SELECT_TRUE@am__append_101 = select.c +@GL_COND_OBJ_SEND_TRUE@am__append_102 = send.c +@GL_COND_OBJ_SETLOCALE_LOCK_TRUE@am__append_103 = setlocale-lock.c +@GL_COND_OBJ_SETSOCKOPT_TRUE@am__append_104 = setsockopt.c +@GL_COND_OBJ_SIGACTION_TRUE@am__append_105 = sigaction.c +@GL_COND_OBJ_SIGPROCMASK_TRUE@am__append_106 = sigprocmask.c +@GL_COND_OBJ_SOCKET_TRUE@am__append_107 = socket.c +@GL_COND_OBJ_OS2_SPAWN_TRUE@am__append_108 = os2-spawn.c +@GL_COND_OBJ_STAT_TRUE@am__append_109 = stat.c +@GL_COND_OBJ_STDIO_READ_TRUE@am__append_110 = stdio-read.c +@GL_COND_OBJ_STDIO_WRITE_TRUE@am__append_111 = stdio-write.c +@GL_COND_OBJ_STPCPY_TRUE@am__append_112 = stpcpy.c +@GL_COND_OBJ_STRCASECMP_TRUE@am__append_113 = strcasecmp.c +@GL_COND_OBJ_STRNCASECMP_TRUE@am__append_114 = strncasecmp.c +@GL_COND_OBJ_STRCHRNUL_TRUE@am__append_115 = strchrnul.c +@GL_COND_OBJ_STRDUP_TRUE@am__append_116 = strdup.c +@GL_COND_OBJ_STRERROR_TRUE@am__append_117 = strerror.c +@GL_COND_OBJ_STRERROR_OVERRIDE_TRUE@am__append_118 = strerror-override.c +@GL_COND_OBJ_STRNDUP_TRUE@am__append_119 = strndup.c +@GL_COND_OBJ_STRNLEN_TRUE@am__append_120 = strnlen.c +@GL_COND_OBJ_STRPBRK_TRUE@am__append_121 = strpbrk.c +@GL_COND_OBJ_STRPTIME_TRUE@am__append_122 = strptime.c +@GL_COND_OBJ_STRTOK_R_TRUE@am__append_123 = strtok_r.c +@GL_COND_OBJ_STRTOL_TRUE@am__append_124 = strtol.c +@GL_COND_OBJ_STRTOLL_TRUE@am__append_125 = strtoll.c +@GL_COND_OBJ_SYMLINK_TRUE@am__append_126 = symlink.c +@GL_COND_OBJ_TIME_R_TRUE@am__append_127 = time_r.c +@GL_COND_OBJ_TIMEGM_TRUE@am__append_128 = timegm.c +@LIBUNISTRING_COMPILE_UNICASE_EMPTY_PREFIX_CONTEXT_TRUE@am__append_129 = unicase/empty-prefix-context.c +@LIBUNISTRING_COMPILE_UNICASE_EMPTY_SUFFIX_CONTEXT_TRUE@am__append_130 = unicase/empty-suffix-context.c +@LIBUNISTRING_COMPILE_UNICASE_TOLOWER_TRUE@am__append_131 = unicase/tolower.c +@LIBUNISTRING_COMPILE_UNICASE_U8_TOLOWER_TRUE@am__append_132 = unicase/u8-tolower.c +@LIBUNISTRING_COMPILE_UNICTYPE_COMBINING_CLASS_TRUE@am__append_133 = unictype/combiningclass.c +@LIBUNISTRING_COMPILE_UNICTYPE_PROPERTY_SOFT_DOTTED_TRUE@am__append_134 = unictype/pr_soft_dotted.c +@LIBUNISTRING_COMPILE_UNINORM_U8_NORMALIZE_TRUE@am__append_135 = uninorm/u8-normalize.c +@LIBUNISTRING_COMPILE_UNISTR_U8_CPY_TRUE@am__append_136 = unistr/u8-cpy.c +@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUC_UNSAFE_TRUE@am__append_137 = unistr/u8-mbtouc-unsafe.c unistr/u8-mbtouc-unsafe-aux.c +@LIBUNISTRING_COMPILE_UNISTR_U8_STRLEN_TRUE@am__append_138 = unistr/u8-strlen.c +@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@am__append_139 = unistr/u8-uctomb.c unistr/u8-uctomb-aux.c +@LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE@am__append_140 = uniwidth/width.c +@GL_COND_OBJ_UNLINK_TRUE@am__append_141 = unlink.c +@GL_COND_OBJ_UTIME_TRUE@am__append_142 = utime.c +@GL_COND_OBJ_WAITPID_TRUE@am__append_143 = waitpid.c +@GL_COND_OBJ_WCRTOMB_TRUE@am__append_144 = wcrtomb.c +@GL_COND_OBJ_WCWIDTH_TRUE@am__append_145 = wcwidth.c +@GL_COND_OBJ_WINDOWS_MUTEX_TRUE@am__append_146 = windows-mutex.c +@GL_COND_OBJ_WINDOWS_ONCE_TRUE@am__append_147 = windows-once.c +@GL_COND_OBJ_WINDOWS_RECMUTEX_TRUE@am__append_148 = windows-recmutex.c +@GL_COND_OBJ_WINDOWS_RWLOCK_TRUE@am__append_149 = windows-rwlock.c +@GL_COND_OBJ_WINDOWS_SPAWN_TRUE@am__append_150 = windows-spawn.c +@GL_COND_OBJ_WMEMCHR_TRUE@am__append_151 = wmemchr.c +@GL_COND_OBJ_WMEMPCPY_TRUE@am__append_152 = wmempcpy.c +@GL_COND_OBJ_WRITE_TRUE@am__append_153 = write.c +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ + $(top_srcdir)/m4/__inline.m4 \ + $(top_srcdir)/m4/absolute-header.m4 $(top_srcdir)/m4/access.m4 \ + $(top_srcdir)/m4/af_alg.m4 $(top_srcdir)/m4/alloca.m4 \ + $(top_srcdir)/m4/arpa_inet_h.m4 \ + $(top_srcdir)/m4/asm-underscore.m4 $(top_srcdir)/m4/base32.m4 \ + $(top_srcdir)/m4/btowc.m4 $(top_srcdir)/m4/builtin-expect.m4 \ + $(top_srcdir)/m4/byteswap.m4 $(top_srcdir)/m4/calloc.m4 \ + $(top_srcdir)/m4/canonicalize.m4 \ + $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/clock_time.m4 \ + $(top_srcdir)/m4/close.m4 $(top_srcdir)/m4/closedir.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/ctype_h.m4 \ + $(top_srcdir)/m4/d-ino.m4 $(top_srcdir)/m4/dirent_h.m4 \ + $(top_srcdir)/m4/dirfd.m4 \ + $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup.m4 \ + $(top_srcdir)/m4/dup2.m4 $(top_srcdir)/m4/eaccess.m4 \ + $(top_srcdir)/m4/eealloc.m4 $(top_srcdir)/m4/environ.m4 \ + $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/error.m4 \ + $(top_srcdir)/m4/exponentd.m4 $(top_srcdir)/m4/extensions.m4 \ + $(top_srcdir)/m4/extern-inline.m4 \ + $(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fchdir.m4 \ + $(top_srcdir)/m4/fcntl-o.m4 $(top_srcdir)/m4/fcntl.m4 \ + $(top_srcdir)/m4/fcntl_h.m4 $(top_srcdir)/m4/fdopendir.m4 \ + $(top_srcdir)/m4/fflush.m4 $(top_srcdir)/m4/filenamecat.m4 \ + $(top_srcdir)/m4/findprog-in.m4 $(top_srcdir)/m4/flexmember.m4 \ + $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/flock.m4 \ + $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fnmatch_h.m4 \ + $(top_srcdir)/m4/fopen.m4 $(top_srcdir)/m4/fpurge.m4 \ + $(top_srcdir)/m4/freading.m4 $(top_srcdir)/m4/free.m4 \ + $(top_srcdir)/m4/fseek.m4 $(top_srcdir)/m4/fseeko.m4 \ + $(top_srcdir)/m4/fstat.m4 $(top_srcdir)/m4/fstatat.m4 \ + $(top_srcdir)/m4/ftell.m4 $(top_srcdir)/m4/ftello.m4 \ + $(top_srcdir)/m4/futimens.m4 $(top_srcdir)/m4/getaddrinfo.m4 \ + $(top_srcdir)/m4/getcwd-abort-bug.m4 \ + $(top_srcdir)/m4/getcwd-path-max.m4 $(top_srcdir)/m4/getcwd.m4 \ + $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \ + $(top_srcdir)/m4/getgroups.m4 $(top_srcdir)/m4/getline.m4 \ + $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpagesize.m4 \ + $(top_srcdir)/m4/getpass.m4 $(top_srcdir)/m4/getprogname.m4 \ + $(top_srcdir)/m4/getrandom.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/gl-openssl.m4 \ + $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 \ + $(top_srcdir)/m4/group-member.m4 \ + $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/hostent.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/iconv_h.m4 \ + $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inet_ntop.m4 \ + $(top_srcdir)/m4/inline.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes.m4 \ + $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/ioctl.m4 \ + $(top_srcdir)/m4/isblank.m4 $(top_srcdir)/m4/iswblank.m4 \ + $(top_srcdir)/m4/iswdigit.m4 $(top_srcdir)/m4/iswxdigit.m4 \ + $(top_srcdir)/m4/langinfo_h.m4 $(top_srcdir)/m4/largefile.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libunistring-base.m4 \ + $(top_srcdir)/m4/libunistring-optional.m4 \ + $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/limits-h.m4 \ + $(top_srcdir)/m4/link.m4 $(top_srcdir)/m4/localcharset.m4 \ + $(top_srcdir)/m4/locale-fr.m4 $(top_srcdir)/m4/locale-ja.m4 \ + $(top_srcdir)/m4/locale-zh.m4 $(top_srcdir)/m4/locale_h.m4 \ + $(top_srcdir)/m4/localeconv.m4 $(top_srcdir)/m4/lock.m4 \ + $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \ + $(top_srcdir)/m4/malloc.m4 $(top_srcdir)/m4/malloca.m4 \ + $(top_srcdir)/m4/mbchar.m4 $(top_srcdir)/m4/mbiter.m4 \ + $(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbsinit.m4 \ + $(top_srcdir)/m4/mbsrtowcs.m4 $(top_srcdir)/m4/mbstate_t.m4 \ + $(top_srcdir)/m4/mbtowc.m4 $(top_srcdir)/m4/md4.m4 \ + $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/memchr.m4 \ + $(top_srcdir)/m4/mempcpy.m4 $(top_srcdir)/m4/memrchr.m4 \ + $(top_srcdir)/m4/minmax.m4 $(top_srcdir)/m4/mkdir.m4 \ + $(top_srcdir)/m4/mkostemp.m4 $(top_srcdir)/m4/mkstemp.m4 \ + $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/mmap-anon.m4 \ + $(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/msvc-inval.m4 \ + $(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \ + $(top_srcdir)/m4/nanosleep.m4 $(top_srcdir)/m4/netdb_h.m4 \ + $(top_srcdir)/m4/netinet_in_h.m4 \ + $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/off_t.m4 \ + $(top_srcdir)/m4/open-cloexec.m4 \ + $(top_srcdir)/m4/open-slash.m4 $(top_srcdir)/m4/open.m4 \ + $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/opendir.m4 \ + $(top_srcdir)/m4/pathmax.m4 $(top_srcdir)/m4/pipe.m4 \ + $(top_srcdir)/m4/pipe2.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/posix_spawn.m4 \ + $(top_srcdir)/m4/posix_spawn_faction_addchdir.m4 \ + $(top_srcdir)/m4/printf.m4 $(top_srcdir)/m4/pselect.m4 \ + $(top_srcdir)/m4/pthread_rwlock_rdlock.m4 \ + $(top_srcdir)/m4/pthread_sigmask.m4 $(top_srcdir)/m4/quote.m4 \ + $(top_srcdir)/m4/quotearg.m4 $(top_srcdir)/m4/raise.m4 \ + $(top_srcdir)/m4/rawmemchr.m4 $(top_srcdir)/m4/readdir.m4 \ + $(top_srcdir)/m4/readlink.m4 $(top_srcdir)/m4/realloc.m4 \ + $(top_srcdir)/m4/reallocarray.m4 $(top_srcdir)/m4/regex.m4 \ + $(top_srcdir)/m4/rename.m4 $(top_srcdir)/m4/rewinddir.m4 \ + $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/save-cwd.m4 \ + $(top_srcdir)/m4/sched_h.m4 $(top_srcdir)/m4/secure_getenv.m4 \ + $(top_srcdir)/m4/select.m4 $(top_srcdir)/m4/servent.m4 \ + $(top_srcdir)/m4/setlocale_null.m4 \ + $(top_srcdir)/m4/sh-filename.m4 $(top_srcdir)/m4/sha1.m4 \ + $(top_srcdir)/m4/sha256.m4 $(top_srcdir)/m4/sha512.m4 \ + $(top_srcdir)/m4/sig_atomic_t.m4 $(top_srcdir)/m4/sigaction.m4 \ + $(top_srcdir)/m4/signal_h.m4 \ + $(top_srcdir)/m4/signalblocking.m4 $(top_srcdir)/m4/sigpipe.m4 \ + $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/snprintf.m4 \ + $(top_srcdir)/m4/socketlib.m4 $(top_srcdir)/m4/sockets.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sockpfaf.m4 \ + $(top_srcdir)/m4/spawn-pipe.m4 $(top_srcdir)/m4/spawn_h.m4 \ + $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat-time.m4 \ + $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdalign.m4 \ + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ + $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \ + $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \ + $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcase.m4 \ + $(top_srcdir)/m4/strchrnul.m4 $(top_srcdir)/m4/strdup.m4 \ + $(top_srcdir)/m4/strerror.m4 $(top_srcdir)/m4/strerror_r.m4 \ + $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strings_h.m4 \ + $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \ + $(top_srcdir)/m4/strpbrk.m4 $(top_srcdir)/m4/strptime.m4 \ + $(top_srcdir)/m4/strtok_r.m4 $(top_srcdir)/m4/strtol.m4 \ + $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/symlink.m4 \ + $(top_srcdir)/m4/sys_file_h.m4 $(top_srcdir)/m4/sys_ioctl_h.m4 \ + $(top_srcdir)/m4/sys_random_h.m4 \ + $(top_srcdir)/m4/sys_select_h.m4 \ + $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \ + $(top_srcdir)/m4/sys_types_h.m4 $(top_srcdir)/m4/sys_uio_h.m4 \ + $(top_srcdir)/m4/sys_wait_h.m4 $(top_srcdir)/m4/tempname.m4 \ + $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/time_h.m4 \ + $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/timegm.m4 \ + $(top_srcdir)/m4/timespec.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \ + $(top_srcdir)/m4/tmpdir.m4 $(top_srcdir)/m4/ungetc.m4 \ + $(top_srcdir)/m4/unistd-safer.m4 $(top_srcdir)/m4/unistd_h.m4 \ + $(top_srcdir)/m4/unlink.m4 $(top_srcdir)/m4/unlocked-io.m4 \ + $(top_srcdir)/m4/utime.m4 $(top_srcdir)/m4/utime_h.m4 \ + $(top_srcdir)/m4/utimens.m4 $(top_srcdir)/m4/utimes.m4 \ + $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vasprintf.m4 \ + $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/m4/vsnprintf.m4 \ + $(top_srcdir)/m4/wait-process.m4 $(top_srcdir)/m4/waitpid.m4 \ + $(top_srcdir)/m4/warn-on-use.m4 $(top_srcdir)/m4/warnings.m4 \ + $(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \ + $(top_srcdir)/m4/wcrtomb.m4 $(top_srcdir)/m4/wctype_h.m4 \ + $(top_srcdir)/m4/wcwidth.m4 $(top_srcdir)/m4/wget.m4 \ + $(top_srcdir)/m4/wget_manywarnings.m4 \ + $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/wmemchr.m4 \ + $(top_srcdir)/m4/wmempcpy.m4 $(top_srcdir)/m4/write.m4 \ + $(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xsize.m4 \ + $(top_srcdir)/m4/xstrndup.m4 $(top_srcdir)/m4/year2038.m4 \ + $(top_srcdir)/m4/zzgnulib.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +LTLIBRARIES = $(noinst_LTLIBRARIES) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libgnu_a_AR = $(AR) $(ARFLAGS) +am__DEPENDENCIES_1 = +am__libgnu_a_SOURCES_DIST = accept.c access.c openat-priv.h \ + openat-proc.c base32.h base32.c basename-lgpl.c binary-io.h \ + binary-io.c bind.c bitrotate.h bitrotate.c btowc.c c-ctype.h \ + c-ctype.c c-strcase.h c-strcasecmp.c c-strncasecmp.c \ + c-strcasestr.h c-strcasestr.c canonicalize.c \ + canonicalize-lgpl.c chdir-long.c cloexec.c close.c closedir.c \ + concat-filename.c connect.c af_alg.c md2-stream.c md2.c \ + md4-stream.c md4.c md5-stream.c md5.c sha1-stream.c sha1.c \ + sha256-stream.c sha256.c sha512-stream.c sha512.c dirfd.c \ + dirname.c basename.c dirname-lgpl.c stripslash.c dup.c dup2.c \ + malloc/dynarray_at_failure.c malloc/dynarray_emplace_enlarge.c \ + malloc/dynarray_finalize.c malloc/dynarray_resize.c \ + malloc/dynarray_resize_clear.c error.c exitfail.c \ + fatal-signal.h fatal-signal.c fchdir.c fcntl.c fd-hook.c \ + fd-safer-flag.c dup-safer-flag.c fdopendir.c fflush.c \ + file-set.c filenamecat-lgpl.c findprog.h findprog-in.c float.c \ + itold.c flock.c fpurge.c freading.c free.c fseek.c fseeko.c \ + fstat.c fstatat.c ftell.c ftello.c futimens.c getaddrinfo.c \ + gai_strerror.c getcwd.c getcwd-lgpl.c getdelim.c \ + getdtablesize.c getgroups.c getline.c getopt.c getopt1.c \ + getpeername.c getprogname.h getprogname.c getrandom.c \ + getsockname.c gettext.h gettime.c gettimeofday.c \ + group-member.c hard-locale.c hash.c hash-pjw.h hash-pjw.c \ + hash-triple-simple.c ialloc.c idx.h inet_ntop.c ioctl.c \ + isblank.c iswblank.c iswdigit.c iswxdigit.c link.c listen.c \ + localcharset.c localeconv.c glthread/lock.h glthread/lock.c \ + lseek.c lstat.c malloca.c mbchar.c mbiter.h mbiter.c mbrtowc.c \ + mbsinit.c mbsrtowcs.c mbtowc.c memchr.c mempcpy.c memrchr.c \ + minmax.h mkdir.c mkostemp.c mkstemp.c msvc-inval.c \ + msvc-nothrow.c nanosleep.c nl_langinfo.c nl_langinfo-lock.c \ + open.c openat.c openat-die.c opendir.c pipe.c pipe2.c \ + pipe2-safer.c spawn.c spawni.c spawn_faction_addchdir.c \ + spawn_faction_addclose.c spawn_faction_adddup2.c \ + spawn_faction_addopen.c spawn_faction_destroy.c \ + spawn_faction_init.c spawnattr_destroy.c spawnattr_init.c \ + spawnattr_setflags.c spawnattr_setpgroup.c \ + spawnattr_setsigmask.c spawnp.c pselect.c pthread_sigmask.c \ + quotearg.c raise.c rawmemchr.c readdir.c readlink.c \ + reallocarray.c recv.c regex.c rename.c rewinddir.c rmdir.c \ + save-cwd.c malloc/scratch_buffer_dupfree.c \ + malloc/scratch_buffer_grow.c \ + malloc/scratch_buffer_grow_preserve.c \ + malloc/scratch_buffer_set_array_size.c secure_getenv.c \ + select.c send.c setlocale_null.c setlocale-lock.c setsockopt.c \ + sigaction.c sig-handler.c sigprocmask.c size_max.h socket.c \ + sockets.h sockets.c spawn-pipe.h spawn-pipe.c os2-spawn.c \ + stat.c stat-time.c stdio-read.c stdio-write.c stpcpy.c \ + strcasecmp.c strncasecmp.c strchrnul.c strdup.c strerror.c \ + strerror-override.c strndup.c strnlen.c strnlen1.h strnlen1.c \ + strpbrk.c strptime.c strtok_r.c strtol.c strtoll.c symlink.c \ + sys_socket.c tempname.c glthread/threadlib.c time_r.c timegm.c \ + timespec.c tmpdir.h tmpdir.c u64.c unicase/cased.c \ + unicase/empty-prefix-context.c unicase/empty-suffix-context.c \ + unicase/ignorable.c unicase/special-casing.c unicase/tolower.c \ + unicase/u8-casemap.c unicase/u8-tolower.c \ + unictype/combiningclass.c unictype/pr_soft_dotted.c \ + uninorm/decompose-internal.c uninorm/u8-normalize.c unistd.c \ + dup-safer.c fd-safer.c pipe-safer.c unistr/u8-cpy.c \ + unistr/u8-mbtouc-unsafe.c unistr/u8-mbtouc-unsafe-aux.c \ + unistr/u8-strlen.c unistr/u8-uctomb.c unistr/u8-uctomb-aux.c \ + uniwidth/width.c unlink.c utime.c utimens.c wait-process.h \ + wait-process.c waitpid.c wcrtomb.c wctype-h.c wcwidth.c \ + windows-mutex.c windows-once.c windows-recmutex.c \ + windows-rwlock.c windows-spawn.c wmemchr.c wmempcpy.c write.c \ + xmalloc.c xalloc-die.c xmemdup0.h xmemdup0.c xsize.h xsize.c \ + xstrndup.h xstrndup.c +@GL_COND_OBJ_ACCEPT_TRUE@am__objects_1 = libgnu_a-accept.$(OBJEXT) +@GL_COND_OBJ_ACCESS_TRUE@am__objects_2 = libgnu_a-access.$(OBJEXT) +@GL_COND_OBJ_BIND_TRUE@am__objects_3 = libgnu_a-bind.$(OBJEXT) +@GL_COND_OBJ_BTOWC_TRUE@am__objects_4 = libgnu_a-btowc.$(OBJEXT) +@GL_COND_OBJ_CANONICALIZE_LGPL_TRUE@am__objects_5 = libgnu_a-canonicalize-lgpl.$(OBJEXT) +@GL_COND_OBJ_CHDIR_LONG_TRUE@am__objects_6 = \ +@GL_COND_OBJ_CHDIR_LONG_TRUE@ libgnu_a-chdir-long.$(OBJEXT) +@GL_COND_OBJ_CLOSE_TRUE@am__objects_7 = libgnu_a-close.$(OBJEXT) +@GL_COND_OBJ_CLOSEDIR_TRUE@am__objects_8 = \ +@GL_COND_OBJ_CLOSEDIR_TRUE@ libgnu_a-closedir.$(OBJEXT) +@GL_COND_OBJ_CONNECT_TRUE@am__objects_9 = libgnu_a-connect.$(OBJEXT) +@GL_COND_OBJ_DIRFD_TRUE@am__objects_10 = libgnu_a-dirfd.$(OBJEXT) +@GL_COND_OBJ_DUP_TRUE@am__objects_11 = libgnu_a-dup.$(OBJEXT) +@GL_COND_OBJ_DUP2_TRUE@am__objects_12 = libgnu_a-dup2.$(OBJEXT) +am__dirstamp = $(am__leading_dot)dirstamp +@GL_COND_OBJ_ERROR_TRUE@am__objects_13 = libgnu_a-error.$(OBJEXT) +@GL_COND_OBJ_FCHDIR_TRUE@am__objects_14 = libgnu_a-fchdir.$(OBJEXT) +@GL_COND_OBJ_FCNTL_TRUE@am__objects_15 = libgnu_a-fcntl.$(OBJEXT) +@GL_COND_OBJ_FDOPENDIR_TRUE@am__objects_16 = \ +@GL_COND_OBJ_FDOPENDIR_TRUE@ libgnu_a-fdopendir.$(OBJEXT) +@GL_COND_OBJ_FFLUSH_TRUE@am__objects_17 = libgnu_a-fflush.$(OBJEXT) +@GL_COND_OBJ_FLOAT_TRUE@am__objects_18 = libgnu_a-float.$(OBJEXT) +@GL_COND_OBJ_ITOLD_TRUE@am__objects_19 = libgnu_a-itold.$(OBJEXT) +@GL_COND_OBJ_FLOCK_TRUE@am__objects_20 = libgnu_a-flock.$(OBJEXT) +@GL_COND_OBJ_FPURGE_TRUE@am__objects_21 = libgnu_a-fpurge.$(OBJEXT) +@GL_COND_OBJ_FREE_TRUE@am__objects_22 = libgnu_a-free.$(OBJEXT) +@GL_COND_OBJ_FSEEK_TRUE@am__objects_23 = libgnu_a-fseek.$(OBJEXT) +@GL_COND_OBJ_FSEEKO_TRUE@am__objects_24 = libgnu_a-fseeko.$(OBJEXT) +@GL_COND_OBJ_FSTAT_TRUE@am__objects_25 = libgnu_a-fstat.$(OBJEXT) +@GL_COND_OBJ_FSTATAT_TRUE@am__objects_26 = libgnu_a-fstatat.$(OBJEXT) +@GL_COND_OBJ_FTELL_TRUE@am__objects_27 = libgnu_a-ftell.$(OBJEXT) +@GL_COND_OBJ_FTELLO_TRUE@am__objects_28 = libgnu_a-ftello.$(OBJEXT) +@GL_COND_OBJ_FUTIMENS_TRUE@am__objects_29 = \ +@GL_COND_OBJ_FUTIMENS_TRUE@ libgnu_a-futimens.$(OBJEXT) +@GL_COND_OBJ_GETADDRINFO_TRUE@am__objects_30 = \ +@GL_COND_OBJ_GETADDRINFO_TRUE@ libgnu_a-getaddrinfo.$(OBJEXT) +@GL_COND_OBJ_GAI_STRERROR_TRUE@am__objects_31 = libgnu_a-gai_strerror.$(OBJEXT) +@GL_COND_OBJ_GETCWD_TRUE@am__objects_32 = libgnu_a-getcwd.$(OBJEXT) +@GL_COND_OBJ_GETCWD_LGPL_TRUE@am__objects_33 = \ +@GL_COND_OBJ_GETCWD_LGPL_TRUE@ libgnu_a-getcwd-lgpl.$(OBJEXT) +@GL_COND_OBJ_GETDELIM_TRUE@am__objects_34 = \ +@GL_COND_OBJ_GETDELIM_TRUE@ libgnu_a-getdelim.$(OBJEXT) +@GL_COND_OBJ_GETDTABLESIZE_TRUE@am__objects_35 = libgnu_a-getdtablesize.$(OBJEXT) +@GL_COND_OBJ_GETGROUPS_TRUE@am__objects_36 = \ +@GL_COND_OBJ_GETGROUPS_TRUE@ libgnu_a-getgroups.$(OBJEXT) +@GL_COND_OBJ_GETLINE_TRUE@am__objects_37 = libgnu_a-getline.$(OBJEXT) +@GL_COND_OBJ_GETOPT_TRUE@am__objects_38 = libgnu_a-getopt.$(OBJEXT) \ +@GL_COND_OBJ_GETOPT_TRUE@ libgnu_a-getopt1.$(OBJEXT) +@GL_COND_OBJ_GETPEERNAME_TRUE@am__objects_39 = \ +@GL_COND_OBJ_GETPEERNAME_TRUE@ libgnu_a-getpeername.$(OBJEXT) +@GL_COND_OBJ_GETRANDOM_TRUE@am__objects_40 = \ +@GL_COND_OBJ_GETRANDOM_TRUE@ libgnu_a-getrandom.$(OBJEXT) +@GL_COND_OBJ_GETSOCKNAME_TRUE@am__objects_41 = \ +@GL_COND_OBJ_GETSOCKNAME_TRUE@ libgnu_a-getsockname.$(OBJEXT) +@GL_COND_OBJ_GETTIMEOFDAY_TRUE@am__objects_42 = libgnu_a-gettimeofday.$(OBJEXT) +@GL_COND_OBJ_GROUP_MEMBER_TRUE@am__objects_43 = libgnu_a-group-member.$(OBJEXT) +@GL_COND_OBJ_INET_NTOP_TRUE@am__objects_44 = \ +@GL_COND_OBJ_INET_NTOP_TRUE@ libgnu_a-inet_ntop.$(OBJEXT) +@GL_COND_OBJ_IOCTL_TRUE@am__objects_45 = libgnu_a-ioctl.$(OBJEXT) +@GL_COND_OBJ_ISBLANK_TRUE@am__objects_46 = libgnu_a-isblank.$(OBJEXT) +@GL_COND_OBJ_ISWBLANK_TRUE@am__objects_47 = \ +@GL_COND_OBJ_ISWBLANK_TRUE@ libgnu_a-iswblank.$(OBJEXT) +@GL_COND_OBJ_ISWDIGIT_TRUE@am__objects_48 = \ +@GL_COND_OBJ_ISWDIGIT_TRUE@ libgnu_a-iswdigit.$(OBJEXT) +@GL_COND_OBJ_ISWXDIGIT_TRUE@am__objects_49 = \ +@GL_COND_OBJ_ISWXDIGIT_TRUE@ libgnu_a-iswxdigit.$(OBJEXT) +@GL_COND_OBJ_LINK_TRUE@am__objects_50 = libgnu_a-link.$(OBJEXT) +@GL_COND_OBJ_LISTEN_TRUE@am__objects_51 = libgnu_a-listen.$(OBJEXT) +@GL_COND_OBJ_LOCALECONV_TRUE@am__objects_52 = \ +@GL_COND_OBJ_LOCALECONV_TRUE@ libgnu_a-localeconv.$(OBJEXT) +@GL_COND_OBJ_LSEEK_TRUE@am__objects_53 = libgnu_a-lseek.$(OBJEXT) +@GL_COND_OBJ_LSTAT_TRUE@am__objects_54 = libgnu_a-lstat.$(OBJEXT) +@GL_COND_OBJ_MBRTOWC_TRUE@am__objects_55 = libgnu_a-mbrtowc.$(OBJEXT) +@GL_COND_OBJ_MBSINIT_TRUE@am__objects_56 = libgnu_a-mbsinit.$(OBJEXT) +@GL_COND_OBJ_MBSRTOWCS_TRUE@am__objects_57 = \ +@GL_COND_OBJ_MBSRTOWCS_TRUE@ libgnu_a-mbsrtowcs.$(OBJEXT) +@GL_COND_OBJ_MBTOWC_TRUE@am__objects_58 = libgnu_a-mbtowc.$(OBJEXT) +@GL_COND_OBJ_MEMCHR_TRUE@am__objects_59 = libgnu_a-memchr.$(OBJEXT) +@GL_COND_OBJ_MEMPCPY_TRUE@am__objects_60 = libgnu_a-mempcpy.$(OBJEXT) +@GL_COND_OBJ_MEMRCHR_TRUE@am__objects_61 = libgnu_a-memrchr.$(OBJEXT) +@GL_COND_OBJ_MKDIR_TRUE@am__objects_62 = libgnu_a-mkdir.$(OBJEXT) +@GL_COND_OBJ_MKOSTEMP_TRUE@am__objects_63 = \ +@GL_COND_OBJ_MKOSTEMP_TRUE@ libgnu_a-mkostemp.$(OBJEXT) +@GL_COND_OBJ_MKSTEMP_TRUE@am__objects_64 = libgnu_a-mkstemp.$(OBJEXT) +@GL_COND_OBJ_MSVC_INVAL_TRUE@am__objects_65 = \ +@GL_COND_OBJ_MSVC_INVAL_TRUE@ libgnu_a-msvc-inval.$(OBJEXT) +@GL_COND_OBJ_MSVC_NOTHROW_TRUE@am__objects_66 = libgnu_a-msvc-nothrow.$(OBJEXT) +@GL_COND_OBJ_NANOSLEEP_TRUE@am__objects_67 = \ +@GL_COND_OBJ_NANOSLEEP_TRUE@ libgnu_a-nanosleep.$(OBJEXT) +@GL_COND_OBJ_NL_LANGINFO_TRUE@am__objects_68 = \ +@GL_COND_OBJ_NL_LANGINFO_TRUE@ libgnu_a-nl_langinfo.$(OBJEXT) +@GL_COND_OBJ_NL_LANGINFO_LOCK_TRUE@am__objects_69 = libgnu_a-nl_langinfo-lock.$(OBJEXT) +@GL_COND_OBJ_OPEN_TRUE@am__objects_70 = libgnu_a-open.$(OBJEXT) +@GL_COND_OBJ_OPENAT_TRUE@am__objects_71 = libgnu_a-openat.$(OBJEXT) +@GL_COND_OBJ_OPENDIR_TRUE@am__objects_72 = libgnu_a-opendir.$(OBJEXT) +@GL_COND_OBJ_PIPE_TRUE@am__objects_73 = libgnu_a-pipe.$(OBJEXT) +@GL_COND_OBJ_SPAWN_TRUE@am__objects_74 = libgnu_a-spawn.$(OBJEXT) +@GL_COND_OBJ_SPAWNI_TRUE@am__objects_75 = libgnu_a-spawni.$(OBJEXT) +@GL_COND_OBJ_SPAWN_FACTION_ADDCHDIR_TRUE@am__objects_76 = libgnu_a-spawn_faction_addchdir.$(OBJEXT) +@GL_COND_OBJ_SPAWN_FACTION_ADDCLOSE_TRUE@am__objects_77 = libgnu_a-spawn_faction_addclose.$(OBJEXT) +@GL_COND_OBJ_SPAWN_FACTION_ADDDUP2_TRUE@am__objects_78 = libgnu_a-spawn_faction_adddup2.$(OBJEXT) +@GL_COND_OBJ_SPAWN_FACTION_ADDOPEN_TRUE@am__objects_79 = libgnu_a-spawn_faction_addopen.$(OBJEXT) +@GL_COND_OBJ_SPAWN_FACTION_DESTROY_TRUE@am__objects_80 = libgnu_a-spawn_faction_destroy.$(OBJEXT) +@GL_COND_OBJ_SPAWN_FACTION_INIT_TRUE@am__objects_81 = libgnu_a-spawn_faction_init.$(OBJEXT) +@GL_COND_OBJ_SPAWNATTR_DESTROY_TRUE@am__objects_82 = libgnu_a-spawnattr_destroy.$(OBJEXT) +@GL_COND_OBJ_SPAWNATTR_INIT_TRUE@am__objects_83 = libgnu_a-spawnattr_init.$(OBJEXT) +@GL_COND_OBJ_SPAWNATTR_SETFLAGS_TRUE@am__objects_84 = libgnu_a-spawnattr_setflags.$(OBJEXT) +@GL_COND_OBJ_SPAWNATTR_SETPGROUP_TRUE@am__objects_85 = libgnu_a-spawnattr_setpgroup.$(OBJEXT) +@GL_COND_OBJ_SPAWNATTR_SETSIGMASK_TRUE@am__objects_86 = libgnu_a-spawnattr_setsigmask.$(OBJEXT) +@GL_COND_OBJ_SPAWNP_TRUE@am__objects_87 = libgnu_a-spawnp.$(OBJEXT) +@GL_COND_OBJ_PSELECT_TRUE@am__objects_88 = libgnu_a-pselect.$(OBJEXT) +@GL_COND_OBJ_PTHREAD_SIGMASK_TRUE@am__objects_89 = libgnu_a-pthread_sigmask.$(OBJEXT) +@GL_COND_OBJ_RAISE_TRUE@am__objects_90 = libgnu_a-raise.$(OBJEXT) +@GL_COND_OBJ_RAWMEMCHR_TRUE@am__objects_91 = \ +@GL_COND_OBJ_RAWMEMCHR_TRUE@ libgnu_a-rawmemchr.$(OBJEXT) +@GL_COND_OBJ_READDIR_TRUE@am__objects_92 = libgnu_a-readdir.$(OBJEXT) +@GL_COND_OBJ_READLINK_TRUE@am__objects_93 = \ +@GL_COND_OBJ_READLINK_TRUE@ libgnu_a-readlink.$(OBJEXT) +@GL_COND_OBJ_REALLOCARRAY_TRUE@am__objects_94 = libgnu_a-reallocarray.$(OBJEXT) +@GL_COND_OBJ_RECV_TRUE@am__objects_95 = libgnu_a-recv.$(OBJEXT) +@GL_COND_OBJ_REGEX_TRUE@am__objects_96 = libgnu_a-regex.$(OBJEXT) +@GL_COND_OBJ_RENAME_TRUE@am__objects_97 = libgnu_a-rename.$(OBJEXT) +@GL_COND_OBJ_REWINDDIR_TRUE@am__objects_98 = \ +@GL_COND_OBJ_REWINDDIR_TRUE@ libgnu_a-rewinddir.$(OBJEXT) +@GL_COND_OBJ_RMDIR_TRUE@am__objects_99 = libgnu_a-rmdir.$(OBJEXT) +@GL_COND_OBJ_SECURE_GETENV_TRUE@am__objects_100 = libgnu_a-secure_getenv.$(OBJEXT) +@GL_COND_OBJ_SELECT_TRUE@am__objects_101 = libgnu_a-select.$(OBJEXT) +@GL_COND_OBJ_SEND_TRUE@am__objects_102 = libgnu_a-send.$(OBJEXT) +@GL_COND_OBJ_SETLOCALE_LOCK_TRUE@am__objects_103 = libgnu_a-setlocale-lock.$(OBJEXT) +@GL_COND_OBJ_SETSOCKOPT_TRUE@am__objects_104 = \ +@GL_COND_OBJ_SETSOCKOPT_TRUE@ libgnu_a-setsockopt.$(OBJEXT) +@GL_COND_OBJ_SIGACTION_TRUE@am__objects_105 = \ +@GL_COND_OBJ_SIGACTION_TRUE@ libgnu_a-sigaction.$(OBJEXT) +@GL_COND_OBJ_SIGPROCMASK_TRUE@am__objects_106 = \ +@GL_COND_OBJ_SIGPROCMASK_TRUE@ libgnu_a-sigprocmask.$(OBJEXT) +@GL_COND_OBJ_SOCKET_TRUE@am__objects_107 = libgnu_a-socket.$(OBJEXT) +@GL_COND_OBJ_OS2_SPAWN_TRUE@am__objects_108 = \ +@GL_COND_OBJ_OS2_SPAWN_TRUE@ libgnu_a-os2-spawn.$(OBJEXT) +@GL_COND_OBJ_STAT_TRUE@am__objects_109 = libgnu_a-stat.$(OBJEXT) +@GL_COND_OBJ_STDIO_READ_TRUE@am__objects_110 = \ +@GL_COND_OBJ_STDIO_READ_TRUE@ libgnu_a-stdio-read.$(OBJEXT) +@GL_COND_OBJ_STDIO_WRITE_TRUE@am__objects_111 = \ +@GL_COND_OBJ_STDIO_WRITE_TRUE@ libgnu_a-stdio-write.$(OBJEXT) +@GL_COND_OBJ_STPCPY_TRUE@am__objects_112 = libgnu_a-stpcpy.$(OBJEXT) +@GL_COND_OBJ_STRCASECMP_TRUE@am__objects_113 = \ +@GL_COND_OBJ_STRCASECMP_TRUE@ libgnu_a-strcasecmp.$(OBJEXT) +@GL_COND_OBJ_STRNCASECMP_TRUE@am__objects_114 = \ +@GL_COND_OBJ_STRNCASECMP_TRUE@ libgnu_a-strncasecmp.$(OBJEXT) +@GL_COND_OBJ_STRCHRNUL_TRUE@am__objects_115 = \ +@GL_COND_OBJ_STRCHRNUL_TRUE@ libgnu_a-strchrnul.$(OBJEXT) +@GL_COND_OBJ_STRDUP_TRUE@am__objects_116 = libgnu_a-strdup.$(OBJEXT) +@GL_COND_OBJ_STRERROR_TRUE@am__objects_117 = \ +@GL_COND_OBJ_STRERROR_TRUE@ libgnu_a-strerror.$(OBJEXT) +@GL_COND_OBJ_STRERROR_OVERRIDE_TRUE@am__objects_118 = libgnu_a-strerror-override.$(OBJEXT) +@GL_COND_OBJ_STRNDUP_TRUE@am__objects_119 = \ +@GL_COND_OBJ_STRNDUP_TRUE@ libgnu_a-strndup.$(OBJEXT) +@GL_COND_OBJ_STRNLEN_TRUE@am__objects_120 = \ +@GL_COND_OBJ_STRNLEN_TRUE@ libgnu_a-strnlen.$(OBJEXT) +@GL_COND_OBJ_STRPBRK_TRUE@am__objects_121 = \ +@GL_COND_OBJ_STRPBRK_TRUE@ libgnu_a-strpbrk.$(OBJEXT) +@GL_COND_OBJ_STRPTIME_TRUE@am__objects_122 = \ +@GL_COND_OBJ_STRPTIME_TRUE@ libgnu_a-strptime.$(OBJEXT) +@GL_COND_OBJ_STRTOK_R_TRUE@am__objects_123 = \ +@GL_COND_OBJ_STRTOK_R_TRUE@ libgnu_a-strtok_r.$(OBJEXT) +@GL_COND_OBJ_STRTOL_TRUE@am__objects_124 = libgnu_a-strtol.$(OBJEXT) +@GL_COND_OBJ_STRTOLL_TRUE@am__objects_125 = \ +@GL_COND_OBJ_STRTOLL_TRUE@ libgnu_a-strtoll.$(OBJEXT) +@GL_COND_OBJ_SYMLINK_TRUE@am__objects_126 = \ +@GL_COND_OBJ_SYMLINK_TRUE@ libgnu_a-symlink.$(OBJEXT) +@GL_COND_OBJ_TIME_R_TRUE@am__objects_127 = libgnu_a-time_r.$(OBJEXT) +@GL_COND_OBJ_TIMEGM_TRUE@am__objects_128 = libgnu_a-timegm.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNICASE_EMPTY_PREFIX_CONTEXT_TRUE@am__objects_129 = unicase/libgnu_a-empty-prefix-context.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNICASE_EMPTY_SUFFIX_CONTEXT_TRUE@am__objects_130 = unicase/libgnu_a-empty-suffix-context.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNICASE_TOLOWER_TRUE@am__objects_131 = unicase/libgnu_a-tolower.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNICASE_U8_TOLOWER_TRUE@am__objects_132 = unicase/libgnu_a-u8-tolower.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNICTYPE_COMBINING_CLASS_TRUE@am__objects_133 = unictype/libgnu_a-combiningclass.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNICTYPE_PROPERTY_SOFT_DOTTED_TRUE@am__objects_134 = unictype/libgnu_a-pr_soft_dotted.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNINORM_U8_NORMALIZE_TRUE@am__objects_135 = uninorm/libgnu_a-u8-normalize.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNISTR_U8_CPY_TRUE@am__objects_136 = unistr/libgnu_a-u8-cpy.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUC_UNSAFE_TRUE@am__objects_137 = unistr/libgnu_a-u8-mbtouc-unsafe.$(OBJEXT) \ +@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUC_UNSAFE_TRUE@ unistr/libgnu_a-u8-mbtouc-unsafe-aux.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNISTR_U8_STRLEN_TRUE@am__objects_138 = unistr/libgnu_a-u8-strlen.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@am__objects_139 = unistr/libgnu_a-u8-uctomb.$(OBJEXT) \ +@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@ unistr/libgnu_a-u8-uctomb-aux.$(OBJEXT) +@LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE@am__objects_140 = uniwidth/libgnu_a-width.$(OBJEXT) +@GL_COND_OBJ_UNLINK_TRUE@am__objects_141 = libgnu_a-unlink.$(OBJEXT) +@GL_COND_OBJ_UTIME_TRUE@am__objects_142 = libgnu_a-utime.$(OBJEXT) +@GL_COND_OBJ_WAITPID_TRUE@am__objects_143 = \ +@GL_COND_OBJ_WAITPID_TRUE@ libgnu_a-waitpid.$(OBJEXT) +@GL_COND_OBJ_WCRTOMB_TRUE@am__objects_144 = \ +@GL_COND_OBJ_WCRTOMB_TRUE@ libgnu_a-wcrtomb.$(OBJEXT) +@GL_COND_OBJ_WCWIDTH_TRUE@am__objects_145 = \ +@GL_COND_OBJ_WCWIDTH_TRUE@ libgnu_a-wcwidth.$(OBJEXT) +@GL_COND_OBJ_WINDOWS_MUTEX_TRUE@am__objects_146 = libgnu_a-windows-mutex.$(OBJEXT) +@GL_COND_OBJ_WINDOWS_ONCE_TRUE@am__objects_147 = libgnu_a-windows-once.$(OBJEXT) +@GL_COND_OBJ_WINDOWS_RECMUTEX_TRUE@am__objects_148 = libgnu_a-windows-recmutex.$(OBJEXT) +@GL_COND_OBJ_WINDOWS_RWLOCK_TRUE@am__objects_149 = libgnu_a-windows-rwlock.$(OBJEXT) +@GL_COND_OBJ_WINDOWS_SPAWN_TRUE@am__objects_150 = libgnu_a-windows-spawn.$(OBJEXT) +@GL_COND_OBJ_WMEMCHR_TRUE@am__objects_151 = \ +@GL_COND_OBJ_WMEMCHR_TRUE@ libgnu_a-wmemchr.$(OBJEXT) +@GL_COND_OBJ_WMEMPCPY_TRUE@am__objects_152 = \ +@GL_COND_OBJ_WMEMPCPY_TRUE@ libgnu_a-wmempcpy.$(OBJEXT) +@GL_COND_OBJ_WRITE_TRUE@am__objects_153 = libgnu_a-write.$(OBJEXT) +am_libgnu_a_OBJECTS = $(am__objects_1) $(am__objects_2) \ + libgnu_a-openat-proc.$(OBJEXT) libgnu_a-base32.$(OBJEXT) \ + libgnu_a-basename-lgpl.$(OBJEXT) libgnu_a-binary-io.$(OBJEXT) \ + $(am__objects_3) libgnu_a-bitrotate.$(OBJEXT) $(am__objects_4) \ + libgnu_a-c-ctype.$(OBJEXT) libgnu_a-c-strcasecmp.$(OBJEXT) \ + libgnu_a-c-strncasecmp.$(OBJEXT) \ + libgnu_a-c-strcasestr.$(OBJEXT) \ + libgnu_a-canonicalize.$(OBJEXT) $(am__objects_5) \ + $(am__objects_6) libgnu_a-cloexec.$(OBJEXT) $(am__objects_7) \ + $(am__objects_8) libgnu_a-concat-filename.$(OBJEXT) \ + $(am__objects_9) libgnu_a-af_alg.$(OBJEXT) \ + libgnu_a-md2-stream.$(OBJEXT) libgnu_a-md2.$(OBJEXT) \ + libgnu_a-md4-stream.$(OBJEXT) libgnu_a-md4.$(OBJEXT) \ + libgnu_a-md5-stream.$(OBJEXT) libgnu_a-md5.$(OBJEXT) \ + libgnu_a-sha1-stream.$(OBJEXT) libgnu_a-sha1.$(OBJEXT) \ + libgnu_a-sha256-stream.$(OBJEXT) libgnu_a-sha256.$(OBJEXT) \ + libgnu_a-sha512-stream.$(OBJEXT) libgnu_a-sha512.$(OBJEXT) \ + $(am__objects_10) libgnu_a-dirname.$(OBJEXT) \ + libgnu_a-basename.$(OBJEXT) libgnu_a-dirname-lgpl.$(OBJEXT) \ + libgnu_a-stripslash.$(OBJEXT) $(am__objects_11) \ + $(am__objects_12) \ + malloc/libgnu_a-dynarray_at_failure.$(OBJEXT) \ + malloc/libgnu_a-dynarray_emplace_enlarge.$(OBJEXT) \ + malloc/libgnu_a-dynarray_finalize.$(OBJEXT) \ + malloc/libgnu_a-dynarray_resize.$(OBJEXT) \ + malloc/libgnu_a-dynarray_resize_clear.$(OBJEXT) \ + $(am__objects_13) libgnu_a-exitfail.$(OBJEXT) \ + libgnu_a-fatal-signal.$(OBJEXT) $(am__objects_14) \ + $(am__objects_15) libgnu_a-fd-hook.$(OBJEXT) \ + libgnu_a-fd-safer-flag.$(OBJEXT) \ + libgnu_a-dup-safer-flag.$(OBJEXT) $(am__objects_16) \ + $(am__objects_17) libgnu_a-file-set.$(OBJEXT) \ + libgnu_a-filenamecat-lgpl.$(OBJEXT) \ + libgnu_a-findprog-in.$(OBJEXT) $(am__objects_18) \ + $(am__objects_19) $(am__objects_20) $(am__objects_21) \ + libgnu_a-freading.$(OBJEXT) $(am__objects_22) \ + $(am__objects_23) $(am__objects_24) $(am__objects_25) \ + $(am__objects_26) $(am__objects_27) $(am__objects_28) \ + $(am__objects_29) $(am__objects_30) $(am__objects_31) \ + $(am__objects_32) $(am__objects_33) $(am__objects_34) \ + $(am__objects_35) $(am__objects_36) $(am__objects_37) \ + $(am__objects_38) $(am__objects_39) \ + libgnu_a-getprogname.$(OBJEXT) $(am__objects_40) \ + $(am__objects_41) libgnu_a-gettime.$(OBJEXT) $(am__objects_42) \ + $(am__objects_43) libgnu_a-hard-locale.$(OBJEXT) \ + libgnu_a-hash.$(OBJEXT) libgnu_a-hash-pjw.$(OBJEXT) \ + libgnu_a-hash-triple-simple.$(OBJEXT) \ + libgnu_a-ialloc.$(OBJEXT) $(am__objects_44) $(am__objects_45) \ + $(am__objects_46) $(am__objects_47) $(am__objects_48) \ + $(am__objects_49) $(am__objects_50) $(am__objects_51) \ + libgnu_a-localcharset.$(OBJEXT) $(am__objects_52) \ + glthread/libgnu_a-lock.$(OBJEXT) $(am__objects_53) \ + $(am__objects_54) libgnu_a-malloca.$(OBJEXT) \ + libgnu_a-mbchar.$(OBJEXT) libgnu_a-mbiter.$(OBJEXT) \ + $(am__objects_55) $(am__objects_56) $(am__objects_57) \ + $(am__objects_58) $(am__objects_59) $(am__objects_60) \ + $(am__objects_61) $(am__objects_62) $(am__objects_63) \ + $(am__objects_64) $(am__objects_65) $(am__objects_66) \ + $(am__objects_67) $(am__objects_68) $(am__objects_69) \ + $(am__objects_70) $(am__objects_71) \ + libgnu_a-openat-die.$(OBJEXT) $(am__objects_72) \ + $(am__objects_73) libgnu_a-pipe2.$(OBJEXT) \ + libgnu_a-pipe2-safer.$(OBJEXT) $(am__objects_74) \ + $(am__objects_75) $(am__objects_76) $(am__objects_77) \ + $(am__objects_78) $(am__objects_79) $(am__objects_80) \ + $(am__objects_81) $(am__objects_82) $(am__objects_83) \ + $(am__objects_84) $(am__objects_85) $(am__objects_86) \ + $(am__objects_87) $(am__objects_88) $(am__objects_89) \ + libgnu_a-quotearg.$(OBJEXT) $(am__objects_90) \ + $(am__objects_91) $(am__objects_92) $(am__objects_93) \ + $(am__objects_94) $(am__objects_95) $(am__objects_96) \ + $(am__objects_97) $(am__objects_98) $(am__objects_99) \ + libgnu_a-save-cwd.$(OBJEXT) \ + malloc/libgnu_a-scratch_buffer_dupfree.$(OBJEXT) \ + malloc/libgnu_a-scratch_buffer_grow.$(OBJEXT) \ + malloc/libgnu_a-scratch_buffer_grow_preserve.$(OBJEXT) \ + malloc/libgnu_a-scratch_buffer_set_array_size.$(OBJEXT) \ + $(am__objects_100) $(am__objects_101) $(am__objects_102) \ + libgnu_a-setlocale_null.$(OBJEXT) $(am__objects_103) \ + $(am__objects_104) $(am__objects_105) \ + libgnu_a-sig-handler.$(OBJEXT) $(am__objects_106) \ + $(am__objects_107) libgnu_a-sockets.$(OBJEXT) \ + libgnu_a-spawn-pipe.$(OBJEXT) $(am__objects_108) \ + $(am__objects_109) libgnu_a-stat-time.$(OBJEXT) \ + $(am__objects_110) $(am__objects_111) $(am__objects_112) \ + $(am__objects_113) $(am__objects_114) $(am__objects_115) \ + $(am__objects_116) $(am__objects_117) $(am__objects_118) \ + $(am__objects_119) $(am__objects_120) \ + libgnu_a-strnlen1.$(OBJEXT) $(am__objects_121) \ + $(am__objects_122) $(am__objects_123) $(am__objects_124) \ + $(am__objects_125) $(am__objects_126) \ + libgnu_a-sys_socket.$(OBJEXT) libgnu_a-tempname.$(OBJEXT) \ + glthread/libgnu_a-threadlib.$(OBJEXT) $(am__objects_127) \ + $(am__objects_128) libgnu_a-timespec.$(OBJEXT) \ + libgnu_a-tmpdir.$(OBJEXT) libgnu_a-u64.$(OBJEXT) \ + unicase/libgnu_a-cased.$(OBJEXT) $(am__objects_129) \ + $(am__objects_130) unicase/libgnu_a-ignorable.$(OBJEXT) \ + unicase/libgnu_a-special-casing.$(OBJEXT) $(am__objects_131) \ + unicase/libgnu_a-u8-casemap.$(OBJEXT) $(am__objects_132) \ + $(am__objects_133) $(am__objects_134) \ + uninorm/libgnu_a-decompose-internal.$(OBJEXT) \ + $(am__objects_135) libgnu_a-unistd.$(OBJEXT) \ + libgnu_a-dup-safer.$(OBJEXT) libgnu_a-fd-safer.$(OBJEXT) \ + libgnu_a-pipe-safer.$(OBJEXT) $(am__objects_136) \ + $(am__objects_137) $(am__objects_138) $(am__objects_139) \ + $(am__objects_140) $(am__objects_141) $(am__objects_142) \ + libgnu_a-utimens.$(OBJEXT) libgnu_a-wait-process.$(OBJEXT) \ + $(am__objects_143) $(am__objects_144) \ + libgnu_a-wctype-h.$(OBJEXT) $(am__objects_145) \ + $(am__objects_146) $(am__objects_147) $(am__objects_148) \ + $(am__objects_149) $(am__objects_150) $(am__objects_151) \ + $(am__objects_152) $(am__objects_153) \ + libgnu_a-xmalloc.$(OBJEXT) libgnu_a-xalloc-die.$(OBJEXT) \ + libgnu_a-xmemdup0.$(OBJEXT) libgnu_a-xsize.$(OBJEXT) \ + libgnu_a-xstrndup.$(OBJEXT) +libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/alloca.Po \ + ./$(DEPDIR)/libgnu_a-accept.Po ./$(DEPDIR)/libgnu_a-access.Po \ + ./$(DEPDIR)/libgnu_a-af_alg.Po ./$(DEPDIR)/libgnu_a-alloca.Po \ + ./$(DEPDIR)/libgnu_a-asnprintf.Po \ + ./$(DEPDIR)/libgnu_a-asprintf.Po \ + ./$(DEPDIR)/libgnu_a-at-func.Po ./$(DEPDIR)/libgnu_a-base32.Po \ + ./$(DEPDIR)/libgnu_a-basename-lgpl.Po \ + ./$(DEPDIR)/libgnu_a-basename.Po \ + ./$(DEPDIR)/libgnu_a-binary-io.Po ./$(DEPDIR)/libgnu_a-bind.Po \ + ./$(DEPDIR)/libgnu_a-bitrotate.Po \ + ./$(DEPDIR)/libgnu_a-btowc.Po ./$(DEPDIR)/libgnu_a-c-ctype.Po \ + ./$(DEPDIR)/libgnu_a-c-strcasecmp.Po \ + ./$(DEPDIR)/libgnu_a-c-strcasestr.Po \ + ./$(DEPDIR)/libgnu_a-c-strncasecmp.Po \ + ./$(DEPDIR)/libgnu_a-calloc.Po \ + ./$(DEPDIR)/libgnu_a-canonicalize-lgpl.Po \ + ./$(DEPDIR)/libgnu_a-canonicalize.Po \ + ./$(DEPDIR)/libgnu_a-chdir-long.Po \ + ./$(DEPDIR)/libgnu_a-cloexec.Po ./$(DEPDIR)/libgnu_a-close.Po \ + ./$(DEPDIR)/libgnu_a-closedir.Po \ + ./$(DEPDIR)/libgnu_a-concat-filename.Po \ + ./$(DEPDIR)/libgnu_a-connect.Po ./$(DEPDIR)/libgnu_a-dirfd.Po \ + ./$(DEPDIR)/libgnu_a-dirname-lgpl.Po \ + ./$(DEPDIR)/libgnu_a-dirname.Po \ + ./$(DEPDIR)/libgnu_a-dup-safer-flag.Po \ + ./$(DEPDIR)/libgnu_a-dup-safer.Po ./$(DEPDIR)/libgnu_a-dup.Po \ + ./$(DEPDIR)/libgnu_a-dup2.Po ./$(DEPDIR)/libgnu_a-error.Po \ + ./$(DEPDIR)/libgnu_a-exitfail.Po \ + ./$(DEPDIR)/libgnu_a-fatal-signal.Po \ + ./$(DEPDIR)/libgnu_a-fchdir.Po ./$(DEPDIR)/libgnu_a-fcntl.Po \ + ./$(DEPDIR)/libgnu_a-fd-hook.Po \ + ./$(DEPDIR)/libgnu_a-fd-safer-flag.Po \ + ./$(DEPDIR)/libgnu_a-fd-safer.Po \ + ./$(DEPDIR)/libgnu_a-fdopendir.Po \ + ./$(DEPDIR)/libgnu_a-fflush.Po \ + ./$(DEPDIR)/libgnu_a-file-set.Po \ + ./$(DEPDIR)/libgnu_a-filenamecat-lgpl.Po \ + ./$(DEPDIR)/libgnu_a-findprog-in.Po \ + ./$(DEPDIR)/libgnu_a-float.Po ./$(DEPDIR)/libgnu_a-flock.Po \ + ./$(DEPDIR)/libgnu_a-fnmatch.Po \ + ./$(DEPDIR)/libgnu_a-fnmatch_loop.Po \ + ./$(DEPDIR)/libgnu_a-fopen.Po ./$(DEPDIR)/libgnu_a-fpurge.Po \ + ./$(DEPDIR)/libgnu_a-freading.Po ./$(DEPDIR)/libgnu_a-free.Po \ + ./$(DEPDIR)/libgnu_a-fseek.Po ./$(DEPDIR)/libgnu_a-fseeko.Po \ + ./$(DEPDIR)/libgnu_a-fstat.Po ./$(DEPDIR)/libgnu_a-fstatat.Po \ + ./$(DEPDIR)/libgnu_a-ftell.Po ./$(DEPDIR)/libgnu_a-ftello.Po \ + ./$(DEPDIR)/libgnu_a-futimens.Po \ + ./$(DEPDIR)/libgnu_a-gai_strerror.Po \ + ./$(DEPDIR)/libgnu_a-getaddrinfo.Po \ + ./$(DEPDIR)/libgnu_a-getcwd-lgpl.Po \ + ./$(DEPDIR)/libgnu_a-getcwd.Po \ + ./$(DEPDIR)/libgnu_a-getdelim.Po \ + ./$(DEPDIR)/libgnu_a-getdtablesize.Po \ + ./$(DEPDIR)/libgnu_a-getgroups.Po \ + ./$(DEPDIR)/libgnu_a-getline.Po ./$(DEPDIR)/libgnu_a-getopt.Po \ + ./$(DEPDIR)/libgnu_a-getopt1.Po \ + ./$(DEPDIR)/libgnu_a-getpass.Po \ + ./$(DEPDIR)/libgnu_a-getpeername.Po \ + ./$(DEPDIR)/libgnu_a-getprogname.Po \ + ./$(DEPDIR)/libgnu_a-getrandom.Po \ + ./$(DEPDIR)/libgnu_a-getsockname.Po \ + ./$(DEPDIR)/libgnu_a-gettime.Po \ + ./$(DEPDIR)/libgnu_a-gettimeofday.Po \ + ./$(DEPDIR)/libgnu_a-group-member.Po \ + ./$(DEPDIR)/libgnu_a-hard-locale.Po \ + ./$(DEPDIR)/libgnu_a-hash-pjw.Po \ + ./$(DEPDIR)/libgnu_a-hash-triple-simple.Po \ + ./$(DEPDIR)/libgnu_a-hash.Po ./$(DEPDIR)/libgnu_a-ialloc.Po \ + ./$(DEPDIR)/libgnu_a-inet_ntop.Po \ + ./$(DEPDIR)/libgnu_a-ioctl.Po ./$(DEPDIR)/libgnu_a-isblank.Po \ + ./$(DEPDIR)/libgnu_a-iswblank.Po \ + ./$(DEPDIR)/libgnu_a-iswdigit.Po \ + ./$(DEPDIR)/libgnu_a-iswxdigit.Po \ + ./$(DEPDIR)/libgnu_a-itold.Po \ + ./$(DEPDIR)/libgnu_a-lc-charset-dispatch.Po \ + ./$(DEPDIR)/libgnu_a-link.Po ./$(DEPDIR)/libgnu_a-listen.Po \ + ./$(DEPDIR)/libgnu_a-localcharset.Po \ + ./$(DEPDIR)/libgnu_a-localeconv.Po \ + ./$(DEPDIR)/libgnu_a-lseek.Po ./$(DEPDIR)/libgnu_a-lstat.Po \ + ./$(DEPDIR)/libgnu_a-malloc.Po ./$(DEPDIR)/libgnu_a-malloca.Po \ + ./$(DEPDIR)/libgnu_a-mbchar.Po ./$(DEPDIR)/libgnu_a-mbiter.Po \ + ./$(DEPDIR)/libgnu_a-mbrtowc.Po \ + ./$(DEPDIR)/libgnu_a-mbsinit.Po \ + ./$(DEPDIR)/libgnu_a-mbsrtowcs-state.Po \ + ./$(DEPDIR)/libgnu_a-mbsrtowcs.Po \ + ./$(DEPDIR)/libgnu_a-mbtowc-lock.Po \ + ./$(DEPDIR)/libgnu_a-mbtowc.Po \ + ./$(DEPDIR)/libgnu_a-md2-stream.Po ./$(DEPDIR)/libgnu_a-md2.Po \ + ./$(DEPDIR)/libgnu_a-md4-stream.Po ./$(DEPDIR)/libgnu_a-md4.Po \ + ./$(DEPDIR)/libgnu_a-md5-stream.Po ./$(DEPDIR)/libgnu_a-md5.Po \ + ./$(DEPDIR)/libgnu_a-memchr.Po ./$(DEPDIR)/libgnu_a-mempcpy.Po \ + ./$(DEPDIR)/libgnu_a-memrchr.Po ./$(DEPDIR)/libgnu_a-mkdir.Po \ + ./$(DEPDIR)/libgnu_a-mkostemp.Po \ + ./$(DEPDIR)/libgnu_a-mkstemp.Po ./$(DEPDIR)/libgnu_a-mktime.Po \ + ./$(DEPDIR)/libgnu_a-msvc-inval.Po \ + ./$(DEPDIR)/libgnu_a-msvc-nothrow.Po \ + ./$(DEPDIR)/libgnu_a-nanosleep.Po \ + ./$(DEPDIR)/libgnu_a-nl_langinfo-lock.Po \ + ./$(DEPDIR)/libgnu_a-nl_langinfo.Po \ + ./$(DEPDIR)/libgnu_a-open.Po \ + ./$(DEPDIR)/libgnu_a-openat-die.Po \ + ./$(DEPDIR)/libgnu_a-openat-proc.Po \ + ./$(DEPDIR)/libgnu_a-openat.Po ./$(DEPDIR)/libgnu_a-opendir.Po \ + ./$(DEPDIR)/libgnu_a-os2-spawn.Po \ + ./$(DEPDIR)/libgnu_a-pipe-safer.Po \ + ./$(DEPDIR)/libgnu_a-pipe.Po \ + ./$(DEPDIR)/libgnu_a-pipe2-safer.Po \ + ./$(DEPDIR)/libgnu_a-pipe2.Po \ + ./$(DEPDIR)/libgnu_a-printf-args.Po \ + ./$(DEPDIR)/libgnu_a-printf-parse.Po \ + ./$(DEPDIR)/libgnu_a-pselect.Po \ + ./$(DEPDIR)/libgnu_a-pthread_sigmask.Po \ + ./$(DEPDIR)/libgnu_a-quotearg.Po ./$(DEPDIR)/libgnu_a-raise.Po \ + ./$(DEPDIR)/libgnu_a-rawmemchr.Po \ + ./$(DEPDIR)/libgnu_a-readdir.Po \ + ./$(DEPDIR)/libgnu_a-readlink.Po \ + ./$(DEPDIR)/libgnu_a-realloc.Po \ + ./$(DEPDIR)/libgnu_a-reallocarray.Po \ + ./$(DEPDIR)/libgnu_a-recv.Po ./$(DEPDIR)/libgnu_a-regcomp.Po \ + ./$(DEPDIR)/libgnu_a-regex.Po \ + ./$(DEPDIR)/libgnu_a-regex_internal.Po \ + ./$(DEPDIR)/libgnu_a-regexec.Po ./$(DEPDIR)/libgnu_a-rename.Po \ + ./$(DEPDIR)/libgnu_a-rewinddir.Po \ + ./$(DEPDIR)/libgnu_a-rmdir.Po ./$(DEPDIR)/libgnu_a-save-cwd.Po \ + ./$(DEPDIR)/libgnu_a-secure_getenv.Po \ + ./$(DEPDIR)/libgnu_a-select.Po ./$(DEPDIR)/libgnu_a-send.Po \ + ./$(DEPDIR)/libgnu_a-setlocale-lock.Po \ + ./$(DEPDIR)/libgnu_a-setlocale_null.Po \ + ./$(DEPDIR)/libgnu_a-setsockopt.Po \ + ./$(DEPDIR)/libgnu_a-sha1-stream.Po \ + ./$(DEPDIR)/libgnu_a-sha1.Po \ + ./$(DEPDIR)/libgnu_a-sha256-stream.Po \ + ./$(DEPDIR)/libgnu_a-sha256.Po \ + ./$(DEPDIR)/libgnu_a-sha512-stream.Po \ + ./$(DEPDIR)/libgnu_a-sha512.Po \ + ./$(DEPDIR)/libgnu_a-sig-handler.Po \ + ./$(DEPDIR)/libgnu_a-sigaction.Po \ + ./$(DEPDIR)/libgnu_a-sigprocmask.Po \ + ./$(DEPDIR)/libgnu_a-snprintf.Po \ + ./$(DEPDIR)/libgnu_a-socket.Po ./$(DEPDIR)/libgnu_a-sockets.Po \ + ./$(DEPDIR)/libgnu_a-spawn-pipe.Po \ + ./$(DEPDIR)/libgnu_a-spawn.Po \ + ./$(DEPDIR)/libgnu_a-spawn_faction_addchdir.Po \ + ./$(DEPDIR)/libgnu_a-spawn_faction_addclose.Po \ + ./$(DEPDIR)/libgnu_a-spawn_faction_adddup2.Po \ + ./$(DEPDIR)/libgnu_a-spawn_faction_addopen.Po \ + ./$(DEPDIR)/libgnu_a-spawn_faction_destroy.Po \ + ./$(DEPDIR)/libgnu_a-spawn_faction_init.Po \ + ./$(DEPDIR)/libgnu_a-spawnattr_destroy.Po \ + ./$(DEPDIR)/libgnu_a-spawnattr_init.Po \ + ./$(DEPDIR)/libgnu_a-spawnattr_setflags.Po \ + ./$(DEPDIR)/libgnu_a-spawnattr_setpgroup.Po \ + ./$(DEPDIR)/libgnu_a-spawnattr_setsigmask.Po \ + ./$(DEPDIR)/libgnu_a-spawni.Po ./$(DEPDIR)/libgnu_a-spawnp.Po \ + ./$(DEPDIR)/libgnu_a-stat-time.Po \ + ./$(DEPDIR)/libgnu_a-stat-w32.Po ./$(DEPDIR)/libgnu_a-stat.Po \ + ./$(DEPDIR)/libgnu_a-stdio-read.Po \ + ./$(DEPDIR)/libgnu_a-stdio-write.Po \ + ./$(DEPDIR)/libgnu_a-stpcpy.Po \ + ./$(DEPDIR)/libgnu_a-strcasecmp.Po \ + ./$(DEPDIR)/libgnu_a-strchrnul.Po \ + ./$(DEPDIR)/libgnu_a-strdup.Po \ + ./$(DEPDIR)/libgnu_a-strerror-override.Po \ + ./$(DEPDIR)/libgnu_a-strerror.Po \ + ./$(DEPDIR)/libgnu_a-strerror_r.Po \ + ./$(DEPDIR)/libgnu_a-stripslash.Po \ + ./$(DEPDIR)/libgnu_a-strncasecmp.Po \ + ./$(DEPDIR)/libgnu_a-strndup.Po \ + ./$(DEPDIR)/libgnu_a-strnlen.Po \ + ./$(DEPDIR)/libgnu_a-strnlen1.Po \ + ./$(DEPDIR)/libgnu_a-strpbrk.Po \ + ./$(DEPDIR)/libgnu_a-strptime.Po \ + ./$(DEPDIR)/libgnu_a-strtok_r.Po \ + ./$(DEPDIR)/libgnu_a-strtol.Po ./$(DEPDIR)/libgnu_a-strtoll.Po \ + ./$(DEPDIR)/libgnu_a-symlink.Po \ + ./$(DEPDIR)/libgnu_a-sys_socket.Po \ + ./$(DEPDIR)/libgnu_a-tempname.Po \ + ./$(DEPDIR)/libgnu_a-time_r.Po ./$(DEPDIR)/libgnu_a-timegm.Po \ + ./$(DEPDIR)/libgnu_a-timespec.Po \ + ./$(DEPDIR)/libgnu_a-tmpdir.Po ./$(DEPDIR)/libgnu_a-u64.Po \ + ./$(DEPDIR)/libgnu_a-unistd.Po ./$(DEPDIR)/libgnu_a-unlink.Po \ + ./$(DEPDIR)/libgnu_a-utime.Po ./$(DEPDIR)/libgnu_a-utimens.Po \ + ./$(DEPDIR)/libgnu_a-vasnprintf.Po \ + ./$(DEPDIR)/libgnu_a-vasprintf.Po \ + ./$(DEPDIR)/libgnu_a-vsnprintf.Po \ + ./$(DEPDIR)/libgnu_a-wait-process.Po \ + ./$(DEPDIR)/libgnu_a-waitpid.Po \ + ./$(DEPDIR)/libgnu_a-wcrtomb.Po \ + ./$(DEPDIR)/libgnu_a-wctype-h.Po \ + ./$(DEPDIR)/libgnu_a-wcwidth.Po \ + ./$(DEPDIR)/libgnu_a-windows-mutex.Po \ + ./$(DEPDIR)/libgnu_a-windows-once.Po \ + ./$(DEPDIR)/libgnu_a-windows-recmutex.Po \ + ./$(DEPDIR)/libgnu_a-windows-rwlock.Po \ + ./$(DEPDIR)/libgnu_a-windows-spawn.Po \ + ./$(DEPDIR)/libgnu_a-wmemchr.Po \ + ./$(DEPDIR)/libgnu_a-wmempcpy.Po ./$(DEPDIR)/libgnu_a-write.Po \ + ./$(DEPDIR)/libgnu_a-xalloc-die.Po \ + ./$(DEPDIR)/libgnu_a-xmalloc.Po \ + ./$(DEPDIR)/libgnu_a-xmemdup0.Po ./$(DEPDIR)/libgnu_a-xsize.Po \ + ./$(DEPDIR)/libgnu_a-xstrndup.Po \ + glthread/$(DEPDIR)/libgnu_a-lock.Po \ + glthread/$(DEPDIR)/libgnu_a-threadlib.Po \ + malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Po \ + malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Po \ + malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Po \ + malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Po \ + malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Po \ + malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Po \ + malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Po \ + malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Po \ + malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Po \ + malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Po \ + unicase/$(DEPDIR)/libgnu_a-cased.Po \ + unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Po \ + unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Po \ + unicase/$(DEPDIR)/libgnu_a-ignorable.Po \ + unicase/$(DEPDIR)/libgnu_a-special-casing.Po \ + unicase/$(DEPDIR)/libgnu_a-tolower.Po \ + unicase/$(DEPDIR)/libgnu_a-u8-casemap.Po \ + unicase/$(DEPDIR)/libgnu_a-u8-tolower.Po \ + unictype/$(DEPDIR)/libgnu_a-combiningclass.Po \ + unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Po \ + uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Po \ + uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Po \ + unistr/$(DEPDIR)/libgnu_a-u8-cpy.Po \ + unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Po \ + unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Po \ + unistr/$(DEPDIR)/libgnu_a-u8-strlen.Po \ + unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Po \ + unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Po \ + uniwidth/$(DEPDIR)/libgnu_a-width.Po +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libgnu_a_SOURCES) $(EXTRA_libgnu_a_SOURCES) +DIST_SOURCES = $(am__libgnu_a_SOURCES_DIST) $(EXTRA_libgnu_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/gnulib.mk \ + $(top_srcdir)/build-aux/depcomp alloca.c +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +BYTESWAP_H = @BYTESWAP_H@ +CARES_CFLAGS = @CARES_CFLAGS@ +CARES_LIBS = @CARES_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@ +CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@ +COMMENT_IF_NO_POD2MAN = @COMMENT_IF_NO_POD2MAN@ +CONFIG_INCLUDE = @CONFIG_INCLUDE@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ +EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ +ENOLINK_VALUE = @ENOLINK_VALUE@ +EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ +EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ +ERRNO_H = @ERRNO_H@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FLOAT_H = @FLOAT_H@ +FNMATCH_H = @FNMATCH_H@ +FUZZ_LIBS = @FUZZ_LIBS@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GETADDRINFO_LIB = @GETADDRINFO_LIB@ +GETOPT_CDEFS_H = @GETOPT_CDEFS_H@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GL_CFLAG_ALLOW_WARNINGS = @GL_CFLAG_ALLOW_WARNINGS@ +GL_CFLAG_GNULIB_WARNINGS = @GL_CFLAG_GNULIB_WARNINGS@ +GL_GNULIB_ACCEPT = @GL_GNULIB_ACCEPT@ +GL_GNULIB_ACCEPT4 = @GL_GNULIB_ACCEPT4@ +GL_GNULIB_ACCESS = @GL_GNULIB_ACCESS@ +GL_GNULIB_ALIGNED_ALLOC = @GL_GNULIB_ALIGNED_ALLOC@ +GL_GNULIB_ALPHASORT = @GL_GNULIB_ALPHASORT@ +GL_GNULIB_ATOLL = @GL_GNULIB_ATOLL@ +GL_GNULIB_BIND = @GL_GNULIB_BIND@ +GL_GNULIB_BTOWC = @GL_GNULIB_BTOWC@ +GL_GNULIB_CALLOC_GNU = @GL_GNULIB_CALLOC_GNU@ +GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@ +GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@ +GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@ +GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@ +GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@ +GL_GNULIB_CLOSEDIR = @GL_GNULIB_CLOSEDIR@ +GL_GNULIB_CONNECT = @GL_GNULIB_CONNECT@ +GL_GNULIB_COPY_FILE_RANGE = @GL_GNULIB_COPY_FILE_RANGE@ +GL_GNULIB_CREAT = @GL_GNULIB_CREAT@ +GL_GNULIB_CTIME = @GL_GNULIB_CTIME@ +GL_GNULIB_DIRFD = @GL_GNULIB_DIRFD@ +GL_GNULIB_DPRINTF = @GL_GNULIB_DPRINTF@ +GL_GNULIB_DUP = @GL_GNULIB_DUP@ +GL_GNULIB_DUP2 = @GL_GNULIB_DUP2@ +GL_GNULIB_DUP3 = @GL_GNULIB_DUP3@ +GL_GNULIB_DUPLOCALE = @GL_GNULIB_DUPLOCALE@ +GL_GNULIB_ENVIRON = @GL_GNULIB_ENVIRON@ +GL_GNULIB_EUIDACCESS = @GL_GNULIB_EUIDACCESS@ +GL_GNULIB_EXECL = @GL_GNULIB_EXECL@ +GL_GNULIB_EXECLE = @GL_GNULIB_EXECLE@ +GL_GNULIB_EXECLP = @GL_GNULIB_EXECLP@ +GL_GNULIB_EXECV = @GL_GNULIB_EXECV@ +GL_GNULIB_EXECVE = @GL_GNULIB_EXECVE@ +GL_GNULIB_EXECVP = @GL_GNULIB_EXECVP@ +GL_GNULIB_EXECVPE = @GL_GNULIB_EXECVPE@ +GL_GNULIB_EXPLICIT_BZERO = @GL_GNULIB_EXPLICIT_BZERO@ +GL_GNULIB_FACCESSAT = @GL_GNULIB_FACCESSAT@ +GL_GNULIB_FCHDIR = @GL_GNULIB_FCHDIR@ +GL_GNULIB_FCHMODAT = @GL_GNULIB_FCHMODAT@ +GL_GNULIB_FCHOWNAT = @GL_GNULIB_FCHOWNAT@ +GL_GNULIB_FCLOSE = @GL_GNULIB_FCLOSE@ +GL_GNULIB_FCNTL = @GL_GNULIB_FCNTL@ +GL_GNULIB_FDATASYNC = @GL_GNULIB_FDATASYNC@ +GL_GNULIB_FDOPEN = @GL_GNULIB_FDOPEN@ +GL_GNULIB_FDOPENDIR = @GL_GNULIB_FDOPENDIR@ +GL_GNULIB_FFLUSH = @GL_GNULIB_FFLUSH@ +GL_GNULIB_FFS = @GL_GNULIB_FFS@ +GL_GNULIB_FFSL = @GL_GNULIB_FFSL@ +GL_GNULIB_FFSLL = @GL_GNULIB_FFSLL@ +GL_GNULIB_FGETC = @GL_GNULIB_FGETC@ +GL_GNULIB_FGETS = @GL_GNULIB_FGETS@ +GL_GNULIB_FLOCK = @GL_GNULIB_FLOCK@ +GL_GNULIB_FNMATCH = @GL_GNULIB_FNMATCH@ +GL_GNULIB_FOPEN = @GL_GNULIB_FOPEN@ +GL_GNULIB_FOPEN_GNU = @GL_GNULIB_FOPEN_GNU@ +GL_GNULIB_FPRINTF = @GL_GNULIB_FPRINTF@ +GL_GNULIB_FPRINTF_POSIX = @GL_GNULIB_FPRINTF_POSIX@ +GL_GNULIB_FPURGE = @GL_GNULIB_FPURGE@ +GL_GNULIB_FPUTC = @GL_GNULIB_FPUTC@ +GL_GNULIB_FPUTS = @GL_GNULIB_FPUTS@ +GL_GNULIB_FREAD = @GL_GNULIB_FREAD@ +GL_GNULIB_FREE_POSIX = @GL_GNULIB_FREE_POSIX@ +GL_GNULIB_FREOPEN = @GL_GNULIB_FREOPEN@ +GL_GNULIB_FSCANF = @GL_GNULIB_FSCANF@ +GL_GNULIB_FSEEK = @GL_GNULIB_FSEEK@ +GL_GNULIB_FSEEKO = @GL_GNULIB_FSEEKO@ +GL_GNULIB_FSTAT = @GL_GNULIB_FSTAT@ +GL_GNULIB_FSTATAT = @GL_GNULIB_FSTATAT@ +GL_GNULIB_FSYNC = @GL_GNULIB_FSYNC@ +GL_GNULIB_FTELL = @GL_GNULIB_FTELL@ +GL_GNULIB_FTELLO = @GL_GNULIB_FTELLO@ +GL_GNULIB_FTRUNCATE = @GL_GNULIB_FTRUNCATE@ +GL_GNULIB_FUTIMENS = @GL_GNULIB_FUTIMENS@ +GL_GNULIB_FWRITE = @GL_GNULIB_FWRITE@ +GL_GNULIB_GETADDRINFO = @GL_GNULIB_GETADDRINFO@ +GL_GNULIB_GETC = @GL_GNULIB_GETC@ +GL_GNULIB_GETCHAR = @GL_GNULIB_GETCHAR@ +GL_GNULIB_GETCWD = @GL_GNULIB_GETCWD@ +GL_GNULIB_GETDELIM = @GL_GNULIB_GETDELIM@ +GL_GNULIB_GETDOMAINNAME = @GL_GNULIB_GETDOMAINNAME@ +GL_GNULIB_GETDTABLESIZE = @GL_GNULIB_GETDTABLESIZE@ +GL_GNULIB_GETENTROPY = @GL_GNULIB_GETENTROPY@ +GL_GNULIB_GETGROUPS = @GL_GNULIB_GETGROUPS@ +GL_GNULIB_GETHOSTNAME = @GL_GNULIB_GETHOSTNAME@ +GL_GNULIB_GETLINE = @GL_GNULIB_GETLINE@ +GL_GNULIB_GETLOADAVG = @GL_GNULIB_GETLOADAVG@ +GL_GNULIB_GETLOGIN = @GL_GNULIB_GETLOGIN@ +GL_GNULIB_GETLOGIN_R = @GL_GNULIB_GETLOGIN_R@ +GL_GNULIB_GETOPT_POSIX = @GL_GNULIB_GETOPT_POSIX@ +GL_GNULIB_GETPAGESIZE = @GL_GNULIB_GETPAGESIZE@ +GL_GNULIB_GETPASS = @GL_GNULIB_GETPASS@ +GL_GNULIB_GETPASS_GNU = @GL_GNULIB_GETPASS_GNU@ +GL_GNULIB_GETPEERNAME = @GL_GNULIB_GETPEERNAME@ +GL_GNULIB_GETRANDOM = @GL_GNULIB_GETRANDOM@ +GL_GNULIB_GETSOCKNAME = @GL_GNULIB_GETSOCKNAME@ +GL_GNULIB_GETSOCKOPT = @GL_GNULIB_GETSOCKOPT@ +GL_GNULIB_GETSUBOPT = @GL_GNULIB_GETSUBOPT@ +GL_GNULIB_GETTIMEOFDAY = @GL_GNULIB_GETTIMEOFDAY@ +GL_GNULIB_GETUMASK = @GL_GNULIB_GETUMASK@ +GL_GNULIB_GETUSERSHELL = @GL_GNULIB_GETUSERSHELL@ +GL_GNULIB_GRANTPT = @GL_GNULIB_GRANTPT@ +GL_GNULIB_GROUP_MEMBER = @GL_GNULIB_GROUP_MEMBER@ +GL_GNULIB_ICONV = @GL_GNULIB_ICONV@ +GL_GNULIB_IMAXABS = @GL_GNULIB_IMAXABS@ +GL_GNULIB_IMAXDIV = @GL_GNULIB_IMAXDIV@ +GL_GNULIB_INET_NTOP = @GL_GNULIB_INET_NTOP@ +GL_GNULIB_INET_PTON = @GL_GNULIB_INET_PTON@ +GL_GNULIB_IOCTL = @GL_GNULIB_IOCTL@ +GL_GNULIB_ISATTY = @GL_GNULIB_ISATTY@ +GL_GNULIB_ISBLANK = @GL_GNULIB_ISBLANK@ +GL_GNULIB_ISWBLANK = @GL_GNULIB_ISWBLANK@ +GL_GNULIB_ISWCTYPE = @GL_GNULIB_ISWCTYPE@ +GL_GNULIB_ISWDIGIT = @GL_GNULIB_ISWDIGIT@ +GL_GNULIB_ISWXDIGIT = @GL_GNULIB_ISWXDIGIT@ +GL_GNULIB_LCHMOD = @GL_GNULIB_LCHMOD@ +GL_GNULIB_LCHOWN = @GL_GNULIB_LCHOWN@ +GL_GNULIB_LINK = @GL_GNULIB_LINK@ +GL_GNULIB_LINKAT = @GL_GNULIB_LINKAT@ +GL_GNULIB_LISTEN = @GL_GNULIB_LISTEN@ +GL_GNULIB_LOCALECONV = @GL_GNULIB_LOCALECONV@ +GL_GNULIB_LOCALENAME = @GL_GNULIB_LOCALENAME@ +GL_GNULIB_LOCALTIME = @GL_GNULIB_LOCALTIME@ +GL_GNULIB_LSEEK = @GL_GNULIB_LSEEK@ +GL_GNULIB_LSTAT = @GL_GNULIB_LSTAT@ +GL_GNULIB_MALLOC_GNU = @GL_GNULIB_MALLOC_GNU@ +GL_GNULIB_MALLOC_POSIX = @GL_GNULIB_MALLOC_POSIX@ +GL_GNULIB_MBRLEN = @GL_GNULIB_MBRLEN@ +GL_GNULIB_MBRTOWC = @GL_GNULIB_MBRTOWC@ +GL_GNULIB_MBSCASECMP = @GL_GNULIB_MBSCASECMP@ +GL_GNULIB_MBSCASESTR = @GL_GNULIB_MBSCASESTR@ +GL_GNULIB_MBSCHR = @GL_GNULIB_MBSCHR@ +GL_GNULIB_MBSCSPN = @GL_GNULIB_MBSCSPN@ +GL_GNULIB_MBSINIT = @GL_GNULIB_MBSINIT@ +GL_GNULIB_MBSLEN = @GL_GNULIB_MBSLEN@ +GL_GNULIB_MBSNCASECMP = @GL_GNULIB_MBSNCASECMP@ +GL_GNULIB_MBSNLEN = @GL_GNULIB_MBSNLEN@ +GL_GNULIB_MBSNRTOWCS = @GL_GNULIB_MBSNRTOWCS@ +GL_GNULIB_MBSPBRK = @GL_GNULIB_MBSPBRK@ +GL_GNULIB_MBSPCASECMP = @GL_GNULIB_MBSPCASECMP@ +GL_GNULIB_MBSRCHR = @GL_GNULIB_MBSRCHR@ +GL_GNULIB_MBSRTOWCS = @GL_GNULIB_MBSRTOWCS@ +GL_GNULIB_MBSSEP = @GL_GNULIB_MBSSEP@ +GL_GNULIB_MBSSPN = @GL_GNULIB_MBSSPN@ +GL_GNULIB_MBSSTR = @GL_GNULIB_MBSSTR@ +GL_GNULIB_MBSTOK_R = @GL_GNULIB_MBSTOK_R@ +GL_GNULIB_MBTOWC = @GL_GNULIB_MBTOWC@ +GL_GNULIB_MDA_ACCESS = @GL_GNULIB_MDA_ACCESS@ +GL_GNULIB_MDA_CHDIR = @GL_GNULIB_MDA_CHDIR@ +GL_GNULIB_MDA_CHMOD = @GL_GNULIB_MDA_CHMOD@ +GL_GNULIB_MDA_CLOSE = @GL_GNULIB_MDA_CLOSE@ +GL_GNULIB_MDA_CREAT = @GL_GNULIB_MDA_CREAT@ +GL_GNULIB_MDA_DUP = @GL_GNULIB_MDA_DUP@ +GL_GNULIB_MDA_DUP2 = @GL_GNULIB_MDA_DUP2@ +GL_GNULIB_MDA_ECVT = @GL_GNULIB_MDA_ECVT@ +GL_GNULIB_MDA_EXECL = @GL_GNULIB_MDA_EXECL@ +GL_GNULIB_MDA_EXECLE = @GL_GNULIB_MDA_EXECLE@ +GL_GNULIB_MDA_EXECLP = @GL_GNULIB_MDA_EXECLP@ +GL_GNULIB_MDA_EXECV = @GL_GNULIB_MDA_EXECV@ +GL_GNULIB_MDA_EXECVE = @GL_GNULIB_MDA_EXECVE@ +GL_GNULIB_MDA_EXECVP = @GL_GNULIB_MDA_EXECVP@ +GL_GNULIB_MDA_EXECVPE = @GL_GNULIB_MDA_EXECVPE@ +GL_GNULIB_MDA_FCLOSEALL = @GL_GNULIB_MDA_FCLOSEALL@ +GL_GNULIB_MDA_FCVT = @GL_GNULIB_MDA_FCVT@ +GL_GNULIB_MDA_FDOPEN = @GL_GNULIB_MDA_FDOPEN@ +GL_GNULIB_MDA_FILENO = @GL_GNULIB_MDA_FILENO@ +GL_GNULIB_MDA_GCVT = @GL_GNULIB_MDA_GCVT@ +GL_GNULIB_MDA_GETCWD = @GL_GNULIB_MDA_GETCWD@ +GL_GNULIB_MDA_GETPID = @GL_GNULIB_MDA_GETPID@ +GL_GNULIB_MDA_GETW = @GL_GNULIB_MDA_GETW@ +GL_GNULIB_MDA_ISATTY = @GL_GNULIB_MDA_ISATTY@ +GL_GNULIB_MDA_LSEEK = @GL_GNULIB_MDA_LSEEK@ +GL_GNULIB_MDA_MEMCCPY = @GL_GNULIB_MDA_MEMCCPY@ +GL_GNULIB_MDA_MKDIR = @GL_GNULIB_MDA_MKDIR@ +GL_GNULIB_MDA_MKTEMP = @GL_GNULIB_MDA_MKTEMP@ +GL_GNULIB_MDA_OPEN = @GL_GNULIB_MDA_OPEN@ +GL_GNULIB_MDA_PUTENV = @GL_GNULIB_MDA_PUTENV@ +GL_GNULIB_MDA_PUTW = @GL_GNULIB_MDA_PUTW@ +GL_GNULIB_MDA_READ = @GL_GNULIB_MDA_READ@ +GL_GNULIB_MDA_RMDIR = @GL_GNULIB_MDA_RMDIR@ +GL_GNULIB_MDA_STRDUP = @GL_GNULIB_MDA_STRDUP@ +GL_GNULIB_MDA_SWAB = @GL_GNULIB_MDA_SWAB@ +GL_GNULIB_MDA_TEMPNAM = @GL_GNULIB_MDA_TEMPNAM@ +GL_GNULIB_MDA_TZSET = @GL_GNULIB_MDA_TZSET@ +GL_GNULIB_MDA_UMASK = @GL_GNULIB_MDA_UMASK@ +GL_GNULIB_MDA_UNLINK = @GL_GNULIB_MDA_UNLINK@ +GL_GNULIB_MDA_UTIME = @GL_GNULIB_MDA_UTIME@ +GL_GNULIB_MDA_WCSDUP = @GL_GNULIB_MDA_WCSDUP@ +GL_GNULIB_MDA_WRITE = @GL_GNULIB_MDA_WRITE@ +GL_GNULIB_MEMCHR = @GL_GNULIB_MEMCHR@ +GL_GNULIB_MEMMEM = @GL_GNULIB_MEMMEM@ +GL_GNULIB_MEMPCPY = @GL_GNULIB_MEMPCPY@ +GL_GNULIB_MEMRCHR = @GL_GNULIB_MEMRCHR@ +GL_GNULIB_MKDIR = @GL_GNULIB_MKDIR@ +GL_GNULIB_MKDIRAT = @GL_GNULIB_MKDIRAT@ +GL_GNULIB_MKDTEMP = @GL_GNULIB_MKDTEMP@ +GL_GNULIB_MKFIFO = @GL_GNULIB_MKFIFO@ +GL_GNULIB_MKFIFOAT = @GL_GNULIB_MKFIFOAT@ +GL_GNULIB_MKNOD = @GL_GNULIB_MKNOD@ +GL_GNULIB_MKNODAT = @GL_GNULIB_MKNODAT@ +GL_GNULIB_MKOSTEMP = @GL_GNULIB_MKOSTEMP@ +GL_GNULIB_MKOSTEMPS = @GL_GNULIB_MKOSTEMPS@ +GL_GNULIB_MKSTEMP = @GL_GNULIB_MKSTEMP@ +GL_GNULIB_MKSTEMPS = @GL_GNULIB_MKSTEMPS@ +GL_GNULIB_MKTIME = @GL_GNULIB_MKTIME@ +GL_GNULIB_NANOSLEEP = @GL_GNULIB_NANOSLEEP@ +GL_GNULIB_NL_LANGINFO = @GL_GNULIB_NL_LANGINFO@ +GL_GNULIB_NONBLOCKING = @GL_GNULIB_NONBLOCKING@ +GL_GNULIB_OBSTACK_PRINTF = @GL_GNULIB_OBSTACK_PRINTF@ +GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@ +GL_GNULIB_OPEN = @GL_GNULIB_OPEN@ +GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@ +GL_GNULIB_OPENDIR = @GL_GNULIB_OPENDIR@ +GL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GNULIB_OVERRIDES_STRUCT_STAT@ +GL_GNULIB_PCLOSE = @GL_GNULIB_PCLOSE@ +GL_GNULIB_PERROR = @GL_GNULIB_PERROR@ +GL_GNULIB_PIPE = @GL_GNULIB_PIPE@ +GL_GNULIB_PIPE2 = @GL_GNULIB_PIPE2@ +GL_GNULIB_POPEN = @GL_GNULIB_POPEN@ +GL_GNULIB_POSIX_MEMALIGN = @GL_GNULIB_POSIX_MEMALIGN@ +GL_GNULIB_POSIX_OPENPT = @GL_GNULIB_POSIX_OPENPT@ +GL_GNULIB_POSIX_SPAWN = @GL_GNULIB_POSIX_SPAWN@ +GL_GNULIB_POSIX_SPAWNATTR_DESTROY = @GL_GNULIB_POSIX_SPAWNATTR_DESTROY@ +GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS = @GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS@ +GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP = @GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP@ +GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM = @GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@ +GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY = @GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@ +GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT = @GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@ +GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK = @GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK@ +GL_GNULIB_POSIX_SPAWNATTR_INIT = @GL_GNULIB_POSIX_SPAWNATTR_INIT@ +GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS = @GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS@ +GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP = @GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP@ +GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM = @GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@ +GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY = @GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@ +GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT = @GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@ +GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK = @GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK@ +GL_GNULIB_POSIX_SPAWNP = @GL_GNULIB_POSIX_SPAWNP@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@ +GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@ +GL_GNULIB_PREAD = @GL_GNULIB_PREAD@ +GL_GNULIB_PRINTF = @GL_GNULIB_PRINTF@ +GL_GNULIB_PRINTF_POSIX = @GL_GNULIB_PRINTF_POSIX@ +GL_GNULIB_PSELECT = @GL_GNULIB_PSELECT@ +GL_GNULIB_PTHREAD_SIGMASK = @GL_GNULIB_PTHREAD_SIGMASK@ +GL_GNULIB_PTSNAME = @GL_GNULIB_PTSNAME@ +GL_GNULIB_PTSNAME_R = @GL_GNULIB_PTSNAME_R@ +GL_GNULIB_PUTC = @GL_GNULIB_PUTC@ +GL_GNULIB_PUTCHAR = @GL_GNULIB_PUTCHAR@ +GL_GNULIB_PUTENV = @GL_GNULIB_PUTENV@ +GL_GNULIB_PUTS = @GL_GNULIB_PUTS@ +GL_GNULIB_PWRITE = @GL_GNULIB_PWRITE@ +GL_GNULIB_QSORT_R = @GL_GNULIB_QSORT_R@ +GL_GNULIB_RAISE = @GL_GNULIB_RAISE@ +GL_GNULIB_RANDOM = @GL_GNULIB_RANDOM@ +GL_GNULIB_RANDOM_R = @GL_GNULIB_RANDOM_R@ +GL_GNULIB_RAWMEMCHR = @GL_GNULIB_RAWMEMCHR@ +GL_GNULIB_READ = @GL_GNULIB_READ@ +GL_GNULIB_READDIR = @GL_GNULIB_READDIR@ +GL_GNULIB_READLINK = @GL_GNULIB_READLINK@ +GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@ +GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@ +GL_GNULIB_REALLOC_GNU = @GL_GNULIB_REALLOC_GNU@ +GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@ +GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@ +GL_GNULIB_RECV = @GL_GNULIB_RECV@ +GL_GNULIB_RECVFROM = @GL_GNULIB_RECVFROM@ +GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@ +GL_GNULIB_RENAME = @GL_GNULIB_RENAME@ +GL_GNULIB_RENAMEAT = @GL_GNULIB_RENAMEAT@ +GL_GNULIB_REWINDDIR = @GL_GNULIB_REWINDDIR@ +GL_GNULIB_RMDIR = @GL_GNULIB_RMDIR@ +GL_GNULIB_RPMATCH = @GL_GNULIB_RPMATCH@ +GL_GNULIB_SCANDIR = @GL_GNULIB_SCANDIR@ +GL_GNULIB_SCANF = @GL_GNULIB_SCANF@ +GL_GNULIB_SCHED_YIELD = @GL_GNULIB_SCHED_YIELD@ +GL_GNULIB_SECURE_GETENV = @GL_GNULIB_SECURE_GETENV@ +GL_GNULIB_SELECT = @GL_GNULIB_SELECT@ +GL_GNULIB_SEND = @GL_GNULIB_SEND@ +GL_GNULIB_SENDTO = @GL_GNULIB_SENDTO@ +GL_GNULIB_SETENV = @GL_GNULIB_SETENV@ +GL_GNULIB_SETHOSTNAME = @GL_GNULIB_SETHOSTNAME@ +GL_GNULIB_SETLOCALE = @GL_GNULIB_SETLOCALE@ +GL_GNULIB_SETLOCALE_NULL = @GL_GNULIB_SETLOCALE_NULL@ +GL_GNULIB_SETSOCKOPT = @GL_GNULIB_SETSOCKOPT@ +GL_GNULIB_SHUTDOWN = @GL_GNULIB_SHUTDOWN@ +GL_GNULIB_SIGABBREV_NP = @GL_GNULIB_SIGABBREV_NP@ +GL_GNULIB_SIGACTION = @GL_GNULIB_SIGACTION@ +GL_GNULIB_SIGDESCR_NP = @GL_GNULIB_SIGDESCR_NP@ +GL_GNULIB_SIGNAL_H_SIGPIPE = @GL_GNULIB_SIGNAL_H_SIGPIPE@ +GL_GNULIB_SIGPROCMASK = @GL_GNULIB_SIGPROCMASK@ +GL_GNULIB_SLEEP = @GL_GNULIB_SLEEP@ +GL_GNULIB_SNPRINTF = @GL_GNULIB_SNPRINTF@ +GL_GNULIB_SOCKET = @GL_GNULIB_SOCKET@ +GL_GNULIB_SPRINTF_POSIX = @GL_GNULIB_SPRINTF_POSIX@ +GL_GNULIB_STAT = @GL_GNULIB_STAT@ +GL_GNULIB_STDIO_H_NONBLOCKING = @GL_GNULIB_STDIO_H_NONBLOCKING@ +GL_GNULIB_STDIO_H_SIGPIPE = @GL_GNULIB_STDIO_H_SIGPIPE@ +GL_GNULIB_STPCPY = @GL_GNULIB_STPCPY@ +GL_GNULIB_STPNCPY = @GL_GNULIB_STPNCPY@ +GL_GNULIB_STRCASESTR = @GL_GNULIB_STRCASESTR@ +GL_GNULIB_STRCHRNUL = @GL_GNULIB_STRCHRNUL@ +GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@ +GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@ +GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@ +GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@ +GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@ +GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@ +GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@ +GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@ +GL_GNULIB_STRPBRK = @GL_GNULIB_STRPBRK@ +GL_GNULIB_STRPTIME = @GL_GNULIB_STRPTIME@ +GL_GNULIB_STRSEP = @GL_GNULIB_STRSEP@ +GL_GNULIB_STRSIGNAL = @GL_GNULIB_STRSIGNAL@ +GL_GNULIB_STRSTR = @GL_GNULIB_STRSTR@ +GL_GNULIB_STRTOD = @GL_GNULIB_STRTOD@ +GL_GNULIB_STRTOIMAX = @GL_GNULIB_STRTOIMAX@ +GL_GNULIB_STRTOK_R = @GL_GNULIB_STRTOK_R@ +GL_GNULIB_STRTOL = @GL_GNULIB_STRTOL@ +GL_GNULIB_STRTOLD = @GL_GNULIB_STRTOLD@ +GL_GNULIB_STRTOLL = @GL_GNULIB_STRTOLL@ +GL_GNULIB_STRTOUL = @GL_GNULIB_STRTOUL@ +GL_GNULIB_STRTOULL = @GL_GNULIB_STRTOULL@ +GL_GNULIB_STRTOUMAX = @GL_GNULIB_STRTOUMAX@ +GL_GNULIB_STRVERSCMP = @GL_GNULIB_STRVERSCMP@ +GL_GNULIB_SYMLINK = @GL_GNULIB_SYMLINK@ +GL_GNULIB_SYMLINKAT = @GL_GNULIB_SYMLINKAT@ +GL_GNULIB_SYSTEM_POSIX = @GL_GNULIB_SYSTEM_POSIX@ +GL_GNULIB_TIMEGM = @GL_GNULIB_TIMEGM@ +GL_GNULIB_TIMESPEC_GET = @GL_GNULIB_TIMESPEC_GET@ +GL_GNULIB_TIMESPEC_GETRES = @GL_GNULIB_TIMESPEC_GETRES@ +GL_GNULIB_TIME_R = @GL_GNULIB_TIME_R@ +GL_GNULIB_TIME_RZ = @GL_GNULIB_TIME_RZ@ +GL_GNULIB_TMPFILE = @GL_GNULIB_TMPFILE@ +GL_GNULIB_TOWCTRANS = @GL_GNULIB_TOWCTRANS@ +GL_GNULIB_TRUNCATE = @GL_GNULIB_TRUNCATE@ +GL_GNULIB_TTYNAME_R = @GL_GNULIB_TTYNAME_R@ +GL_GNULIB_TZSET = @GL_GNULIB_TZSET@ +GL_GNULIB_UNISTD_H_GETOPT = @GL_GNULIB_UNISTD_H_GETOPT@ +GL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GNULIB_UNISTD_H_NONBLOCKING@ +GL_GNULIB_UNISTD_H_SIGPIPE = @GL_GNULIB_UNISTD_H_SIGPIPE@ +GL_GNULIB_UNLINK = @GL_GNULIB_UNLINK@ +GL_GNULIB_UNLINKAT = @GL_GNULIB_UNLINKAT@ +GL_GNULIB_UNLOCKPT = @GL_GNULIB_UNLOCKPT@ +GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@ +GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@ +GL_GNULIB_UTIME = @GL_GNULIB_UTIME@ +GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@ +GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@ +GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@ +GL_GNULIB_VFPRINTF = @GL_GNULIB_VFPRINTF@ +GL_GNULIB_VFPRINTF_POSIX = @GL_GNULIB_VFPRINTF_POSIX@ +GL_GNULIB_VFSCANF = @GL_GNULIB_VFSCANF@ +GL_GNULIB_VPRINTF = @GL_GNULIB_VPRINTF@ +GL_GNULIB_VPRINTF_POSIX = @GL_GNULIB_VPRINTF_POSIX@ +GL_GNULIB_VSCANF = @GL_GNULIB_VSCANF@ +GL_GNULIB_VSNPRINTF = @GL_GNULIB_VSNPRINTF@ +GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@ +GL_GNULIB_WAITPID = @GL_GNULIB_WAITPID@ +GL_GNULIB_WCPCPY = @GL_GNULIB_WCPCPY@ +GL_GNULIB_WCPNCPY = @GL_GNULIB_WCPNCPY@ +GL_GNULIB_WCRTOMB = @GL_GNULIB_WCRTOMB@ +GL_GNULIB_WCSCASECMP = @GL_GNULIB_WCSCASECMP@ +GL_GNULIB_WCSCAT = @GL_GNULIB_WCSCAT@ +GL_GNULIB_WCSCHR = @GL_GNULIB_WCSCHR@ +GL_GNULIB_WCSCMP = @GL_GNULIB_WCSCMP@ +GL_GNULIB_WCSCOLL = @GL_GNULIB_WCSCOLL@ +GL_GNULIB_WCSCPY = @GL_GNULIB_WCSCPY@ +GL_GNULIB_WCSCSPN = @GL_GNULIB_WCSCSPN@ +GL_GNULIB_WCSDUP = @GL_GNULIB_WCSDUP@ +GL_GNULIB_WCSFTIME = @GL_GNULIB_WCSFTIME@ +GL_GNULIB_WCSLEN = @GL_GNULIB_WCSLEN@ +GL_GNULIB_WCSNCASECMP = @GL_GNULIB_WCSNCASECMP@ +GL_GNULIB_WCSNCAT = @GL_GNULIB_WCSNCAT@ +GL_GNULIB_WCSNCMP = @GL_GNULIB_WCSNCMP@ +GL_GNULIB_WCSNCPY = @GL_GNULIB_WCSNCPY@ +GL_GNULIB_WCSNLEN = @GL_GNULIB_WCSNLEN@ +GL_GNULIB_WCSNRTOMBS = @GL_GNULIB_WCSNRTOMBS@ +GL_GNULIB_WCSPBRK = @GL_GNULIB_WCSPBRK@ +GL_GNULIB_WCSRCHR = @GL_GNULIB_WCSRCHR@ +GL_GNULIB_WCSRTOMBS = @GL_GNULIB_WCSRTOMBS@ +GL_GNULIB_WCSSPN = @GL_GNULIB_WCSSPN@ +GL_GNULIB_WCSSTR = @GL_GNULIB_WCSSTR@ +GL_GNULIB_WCSTOK = @GL_GNULIB_WCSTOK@ +GL_GNULIB_WCSWIDTH = @GL_GNULIB_WCSWIDTH@ +GL_GNULIB_WCSXFRM = @GL_GNULIB_WCSXFRM@ +GL_GNULIB_WCTOB = @GL_GNULIB_WCTOB@ +GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@ +GL_GNULIB_WCTRANS = @GL_GNULIB_WCTRANS@ +GL_GNULIB_WCTYPE = @GL_GNULIB_WCTYPE@ +GL_GNULIB_WCWIDTH = @GL_GNULIB_WCWIDTH@ +GL_GNULIB_WMEMCHR = @GL_GNULIB_WMEMCHR@ +GL_GNULIB_WMEMCMP = @GL_GNULIB_WMEMCMP@ +GL_GNULIB_WMEMCPY = @GL_GNULIB_WMEMCPY@ +GL_GNULIB_WMEMMOVE = @GL_GNULIB_WMEMMOVE@ +GL_GNULIB_WMEMPCPY = @GL_GNULIB_WMEMPCPY@ +GL_GNULIB_WMEMSET = @GL_GNULIB_WMEMSET@ +GL_GNULIB_WRITE = @GL_GNULIB_WRITE@ +GL_GNULIB__EXIT = @GL_GNULIB__EXIT@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@ +GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@ +GNULIB_WARN_CFLAGS = @GNULIB_WARN_CFLAGS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GPGME_CFLAGS = @GPGME_CFLAGS@ +GPGME_CONFIG = @GPGME_CONFIG@ +GPGME_LIBS = @GPGME_LIBS@ +GREP = @GREP@ +HAVE_ACCEPT4 = @HAVE_ACCEPT4@ +HAVE_ALIGNED_ALLOC = @HAVE_ALIGNED_ALLOC@ +HAVE_ALLOCA_H = @HAVE_ALLOCA_H@ +HAVE_ALPHASORT = @HAVE_ALPHASORT@ +HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@ +HAVE_ATOLL = @HAVE_ATOLL@ +HAVE_BTOWC = @HAVE_BTOWC@ +HAVE_C99_STDINT_H = @HAVE_C99_STDINT_H@ +HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@ +HAVE_CHOWN = @HAVE_CHOWN@ +HAVE_CLOSEDIR = @HAVE_CLOSEDIR@ +HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@ +HAVE_CRTDEFS_H = @HAVE_CRTDEFS_H@ +HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@ +HAVE_DECL_ECVT = @HAVE_DECL_ECVT@ +HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ +HAVE_DECL_EXECVPE = @HAVE_DECL_EXECVPE@ +HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@ +HAVE_DECL_FCLOSEALL = @HAVE_DECL_FCLOSEALL@ +HAVE_DECL_FCVT = @HAVE_DECL_FCVT@ +HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@ +HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@ +HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@ +HAVE_DECL_FREEADDRINFO = @HAVE_DECL_FREEADDRINFO@ +HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@ +HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@ +HAVE_DECL_GAI_STRERROR = @HAVE_DECL_GAI_STRERROR@ +HAVE_DECL_GCVT = @HAVE_DECL_GCVT@ +HAVE_DECL_GETADDRINFO = @HAVE_DECL_GETADDRINFO@ +HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@ +HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@ +HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@ +HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@ +HAVE_DECL_GETLOGIN = @HAVE_DECL_GETLOGIN@ +HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@ +HAVE_DECL_GETNAMEINFO = @HAVE_DECL_GETNAMEINFO@ +HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@ +HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@ +HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ +HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ +HAVE_DECL_INET_NTOP = @HAVE_DECL_INET_NTOP@ +HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@ +HAVE_DECL_INITSTATE = @HAVE_DECL_INITSTATE@ +HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@ +HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@ +HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@ +HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@ +HAVE_DECL_SETENV = @HAVE_DECL_SETENV@ +HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@ +HAVE_DECL_SETSTATE = @HAVE_DECL_SETSTATE@ +HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@ +HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@ +HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@ +HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@ +HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@ +HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@ +HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@ +HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ +HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@ +HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ +HAVE_DECL_TRUNCATE = @HAVE_DECL_TRUNCATE@ +HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@ +HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@ +HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ +HAVE_DECL_WCSDUP = @HAVE_DECL_WCSDUP@ +HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +HAVE_DIRENT_H = @HAVE_DIRENT_H@ +HAVE_DPRINTF = @HAVE_DPRINTF@ +HAVE_DUP3 = @HAVE_DUP3@ +HAVE_DUPLOCALE = @HAVE_DUPLOCALE@ +HAVE_EUIDACCESS = @HAVE_EUIDACCESS@ +HAVE_EXECVPE = @HAVE_EXECVPE@ +HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@ +HAVE_FACCESSAT = @HAVE_FACCESSAT@ +HAVE_FCHDIR = @HAVE_FCHDIR@ +HAVE_FCHMODAT = @HAVE_FCHMODAT@ +HAVE_FCHOWNAT = @HAVE_FCHOWNAT@ +HAVE_FCNTL = @HAVE_FCNTL@ +HAVE_FDATASYNC = @HAVE_FDATASYNC@ +HAVE_FDOPENDIR = @HAVE_FDOPENDIR@ +HAVE_FEATURES_H = @HAVE_FEATURES_H@ +HAVE_FFS = @HAVE_FFS@ +HAVE_FFSL = @HAVE_FFSL@ +HAVE_FFSLL = @HAVE_FFSLL@ +HAVE_FLOCK = @HAVE_FLOCK@ +HAVE_FNMATCH = @HAVE_FNMATCH@ +HAVE_FNMATCH_H = @HAVE_FNMATCH_H@ +HAVE_FREELOCALE = @HAVE_FREELOCALE@ +HAVE_FSEEKO = @HAVE_FSEEKO@ +HAVE_FSTATAT = @HAVE_FSTATAT@ +HAVE_FSYNC = @HAVE_FSYNC@ +HAVE_FTELLO = @HAVE_FTELLO@ +HAVE_FTRUNCATE = @HAVE_FTRUNCATE@ +HAVE_FUTIMENS = @HAVE_FUTIMENS@ +HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@ +HAVE_GETENTROPY = @HAVE_GETENTROPY@ +HAVE_GETGROUPS = @HAVE_GETGROUPS@ +HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@ +HAVE_GETLOGIN = @HAVE_GETLOGIN@ +HAVE_GETOPT_H = @HAVE_GETOPT_H@ +HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ +HAVE_GETPASS = @HAVE_GETPASS@ +HAVE_GETRANDOM = @HAVE_GETRANDOM@ +HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ +HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@ +HAVE_GETUMASK = @HAVE_GETUMASK@ +HAVE_GRANTPT = @HAVE_GRANTPT@ +HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@ +HAVE_IMAXDIV_T = @HAVE_IMAXDIV_T@ +HAVE_INITSTATE = @HAVE_INITSTATE@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_ISBLANK = @HAVE_ISBLANK@ +HAVE_ISWBLANK = @HAVE_ISWBLANK@ +HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +HAVE_LANGINFO_ALTMON = @HAVE_LANGINFO_ALTMON@ +HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@ +HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@ +HAVE_LANGINFO_H = @HAVE_LANGINFO_H@ +HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@ +HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@ +HAVE_LCHMOD = @HAVE_LCHMOD@ +HAVE_LCHOWN = @HAVE_LCHOWN@ +HAVE_LIBGNUTLS = @HAVE_LIBGNUTLS@ +HAVE_LIBSSL = @HAVE_LIBSSL@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +HAVE_LINK = @HAVE_LINK@ +HAVE_LINKAT = @HAVE_LINKAT@ +HAVE_LSTAT = @HAVE_LSTAT@ +HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@ +HAVE_MBRLEN = @HAVE_MBRLEN@ +HAVE_MBRTOWC = @HAVE_MBRTOWC@ +HAVE_MBSINIT = @HAVE_MBSINIT@ +HAVE_MBSLEN = @HAVE_MBSLEN@ +HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@ +HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@ +HAVE_MBTOWC = @HAVE_MBTOWC@ +HAVE_MEMPCPY = @HAVE_MEMPCPY@ +HAVE_MKDIRAT = @HAVE_MKDIRAT@ +HAVE_MKDTEMP = @HAVE_MKDTEMP@ +HAVE_MKFIFO = @HAVE_MKFIFO@ +HAVE_MKFIFOAT = @HAVE_MKFIFOAT@ +HAVE_MKNOD = @HAVE_MKNOD@ +HAVE_MKNODAT = @HAVE_MKNODAT@ +HAVE_MKOSTEMP = @HAVE_MKOSTEMP@ +HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@ +HAVE_MKSTEMP = @HAVE_MKSTEMP@ +HAVE_MKSTEMPS = @HAVE_MKSTEMPS@ +HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@ +HAVE_NANOSLEEP = @HAVE_NANOSLEEP@ +HAVE_NETDB_H = @HAVE_NETDB_H@ +HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@ +HAVE_NEWLOCALE = @HAVE_NEWLOCALE@ +HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@ +HAVE_OPENAT = @HAVE_OPENAT@ +HAVE_OPENDIR = @HAVE_OPENDIR@ +HAVE_OS_H = @HAVE_OS_H@ +HAVE_PCLOSE = @HAVE_PCLOSE@ +HAVE_PIPE = @HAVE_PIPE@ +HAVE_PIPE2 = @HAVE_PIPE2@ +HAVE_POPEN = @HAVE_POPEN@ +HAVE_POSIX_MEMALIGN = @HAVE_POSIX_MEMALIGN@ +HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@ +HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@ +HAVE_POSIX_SPAWN = @HAVE_POSIX_SPAWN@ +HAVE_POSIX_SPAWNATTR_T = @HAVE_POSIX_SPAWNATTR_T@ +HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +HAVE_POSIX_SPAWN_FILE_ACTIONS_T = @HAVE_POSIX_SPAWN_FILE_ACTIONS_T@ +HAVE_PREAD = @HAVE_PREAD@ +HAVE_PSELECT = @HAVE_PSELECT@ +HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@ +HAVE_PTSNAME = @HAVE_PTSNAME@ +HAVE_PTSNAME_R = @HAVE_PTSNAME_R@ +HAVE_PWRITE = @HAVE_PWRITE@ +HAVE_QSORT_R = @HAVE_QSORT_R@ +HAVE_RAISE = @HAVE_RAISE@ +HAVE_RANDOM = @HAVE_RANDOM@ +HAVE_RANDOM_H = @HAVE_RANDOM_H@ +HAVE_RANDOM_R = @HAVE_RANDOM_R@ +HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@ +HAVE_READDIR = @HAVE_READDIR@ +HAVE_READLINK = @HAVE_READLINK@ +HAVE_READLINKAT = @HAVE_READLINKAT@ +HAVE_REALLOCARRAY = @HAVE_REALLOCARRAY@ +HAVE_REALPATH = @HAVE_REALPATH@ +HAVE_RENAMEAT = @HAVE_RENAMEAT@ +HAVE_REWINDDIR = @HAVE_REWINDDIR@ +HAVE_RPMATCH = @HAVE_RPMATCH@ +HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@ +HAVE_SCANDIR = @HAVE_SCANDIR@ +HAVE_SCHED_H = @HAVE_SCHED_H@ +HAVE_SCHED_YIELD = @HAVE_SCHED_YIELD@ +HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@ +HAVE_SETENV = @HAVE_SETENV@ +HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@ +HAVE_SETSTATE = @HAVE_SETSTATE@ +HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@ +HAVE_SIGACTION = @HAVE_SIGACTION@ +HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@ +HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@ +HAVE_SIGINFO_T = @HAVE_SIGINFO_T@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_SIGSET_T = @HAVE_SIGSET_T@ +HAVE_SLEEP = @HAVE_SLEEP@ +HAVE_SPAWN_H = @HAVE_SPAWN_H@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_STPCPY = @HAVE_STPCPY@ +HAVE_STPNCPY = @HAVE_STPNCPY@ +HAVE_STRCASECMP = @HAVE_STRCASECMP@ +HAVE_STRCASESTR = @HAVE_STRCASESTR@ +HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ +HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@ +HAVE_STRINGS_H = @HAVE_STRINGS_H@ +HAVE_STRPBRK = @HAVE_STRPBRK@ +HAVE_STRPTIME = @HAVE_STRPTIME@ +HAVE_STRSEP = @HAVE_STRSEP@ +HAVE_STRTOD = @HAVE_STRTOD@ +HAVE_STRTOL = @HAVE_STRTOL@ +HAVE_STRTOLD = @HAVE_STRTOLD@ +HAVE_STRTOLL = @HAVE_STRTOLL@ +HAVE_STRTOUL = @HAVE_STRTOUL@ +HAVE_STRTOULL = @HAVE_STRTOULL@ +HAVE_STRUCT_ADDRINFO = @HAVE_STRUCT_ADDRINFO@ +HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@ +HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@ +HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@ +HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@ +HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = @HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_STRVERSCMP = @HAVE_STRVERSCMP@ +HAVE_SYMLINK = @HAVE_SYMLINK@ +HAVE_SYMLINKAT = @HAVE_SYMLINKAT@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_CDEFS_H = @HAVE_SYS_CDEFS_H@ +HAVE_SYS_FILE_H = @HAVE_SYS_FILE_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@ +HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@ +HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_RANDOM_H = @HAVE_SYS_RANDOM_H@ +HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@ +HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_SYS_UIO_H = @HAVE_SYS_UIO_H@ +HAVE_TIMEGM = @HAVE_TIMEGM@ +HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@ +HAVE_TIMESPEC_GETRES = @HAVE_TIMESPEC_GETRES@ +HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@ +HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ +HAVE_UNISTD_H = @HAVE_UNISTD_H@ +HAVE_UNLINKAT = @HAVE_UNLINKAT@ +HAVE_UNLOCKPT = @HAVE_UNLOCKPT@ +HAVE_USLEEP = @HAVE_USLEEP@ +HAVE_UTIME = @HAVE_UTIME@ +HAVE_UTIMENSAT = @HAVE_UTIMENSAT@ +HAVE_UTIME_H = @HAVE_UTIME_H@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +HAVE_VASPRINTF = @HAVE_VASPRINTF@ +HAVE_VDPRINTF = @HAVE_VDPRINTF@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +HAVE_WCHAR_T = @HAVE_WCHAR_T@ +HAVE_WCPCPY = @HAVE_WCPCPY@ +HAVE_WCPNCPY = @HAVE_WCPNCPY@ +HAVE_WCRTOMB = @HAVE_WCRTOMB@ +HAVE_WCSCASECMP = @HAVE_WCSCASECMP@ +HAVE_WCSCAT = @HAVE_WCSCAT@ +HAVE_WCSCHR = @HAVE_WCSCHR@ +HAVE_WCSCMP = @HAVE_WCSCMP@ +HAVE_WCSCOLL = @HAVE_WCSCOLL@ +HAVE_WCSCPY = @HAVE_WCSCPY@ +HAVE_WCSCSPN = @HAVE_WCSCSPN@ +HAVE_WCSDUP = @HAVE_WCSDUP@ +HAVE_WCSFTIME = @HAVE_WCSFTIME@ +HAVE_WCSLEN = @HAVE_WCSLEN@ +HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@ +HAVE_WCSNCAT = @HAVE_WCSNCAT@ +HAVE_WCSNCMP = @HAVE_WCSNCMP@ +HAVE_WCSNCPY = @HAVE_WCSNCPY@ +HAVE_WCSNLEN = @HAVE_WCSNLEN@ +HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@ +HAVE_WCSPBRK = @HAVE_WCSPBRK@ +HAVE_WCSRCHR = @HAVE_WCSRCHR@ +HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@ +HAVE_WCSSPN = @HAVE_WCSSPN@ +HAVE_WCSSTR = @HAVE_WCSSTR@ +HAVE_WCSTOK = @HAVE_WCSTOK@ +HAVE_WCSWIDTH = @HAVE_WCSWIDTH@ +HAVE_WCSXFRM = @HAVE_WCSXFRM@ +HAVE_WCTRANS_T = @HAVE_WCTRANS_T@ +HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +HAVE_WCTYPE_T = @HAVE_WCTYPE_T@ +HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@ +HAVE_WINT_T = @HAVE_WINT_T@ +HAVE_WMEMCHR = @HAVE_WMEMCHR@ +HAVE_WMEMCMP = @HAVE_WMEMCMP@ +HAVE_WMEMCPY = @HAVE_WMEMCPY@ +HAVE_WMEMMOVE = @HAVE_WMEMMOVE@ +HAVE_WMEMPCPY = @HAVE_WMEMPCPY@ +HAVE_WMEMSET = @HAVE_WMEMSET@ +HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@ +HAVE_XLOCALE_H = @HAVE_XLOCALE_H@ +HAVE__BOOL = @HAVE__BOOL@ +HAVE__EXIT = @HAVE__EXIT@ +HOSTENT_LIB = @HOSTENT_LIB@ +ICONV_CONST = @ICONV_CONST@ +ICONV_H = @ICONV_H@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +INET_NTOP_LIB = @INET_NTOP_LIB@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@ +INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBGNUTLS = @LIBGNUTLS@ +LIBGNUTLS_PREFIX = @LIBGNUTLS_PREFIX@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBIDN2_CFLAGS = @LIBIDN2_CFLAGS@ +LIBIDN2_LIBS = @LIBIDN2_LIBS@ +LIBINTL = @LIBINTL@ +LIBMULTITHREAD = @LIBMULTITHREAD@ +LIBOBJS = @LIBOBJS@ +LIBPMULTITHREAD = @LIBPMULTITHREAD@ +LIBPSL_CFLAGS = @LIBPSL_CFLAGS@ +LIBPSL_LIBS = @LIBPSL_LIBS@ +LIBPTHREAD = @LIBPTHREAD@ +LIBS = @LIBS@ +LIBSOCKET = @LIBSOCKET@ +LIBSSL = @LIBSSL@ +LIBSSL_PREFIX = @LIBSSL_PREFIX@ +LIBSTDTHREAD = @LIBSTDTHREAD@ +LIBTHREAD = @LIBTHREAD@ +LIBUNISTRING = @LIBUNISTRING@ +LIBUNISTRING_PREFIX = @LIBUNISTRING_PREFIX@ +LIBUNISTRING_UNICASE_H = @LIBUNISTRING_UNICASE_H@ +LIBUNISTRING_UNICTYPE_H = @LIBUNISTRING_UNICTYPE_H@ +LIBUNISTRING_UNINORM_H = @LIBUNISTRING_UNINORM_H@ +LIBUNISTRING_UNISTR_H = @LIBUNISTRING_UNISTR_H@ +LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ +LIB_CRYPTO = @LIB_CRYPTO@ +LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ +LIB_GETRANDOM = @LIB_GETRANDOM@ +LIB_HARD_LOCALE = @LIB_HARD_LOCALE@ +LIB_MBRTOWC = @LIB_MBRTOWC@ +LIB_NANOSLEEP = @LIB_NANOSLEEP@ +LIB_NL_LANGINFO = @LIB_NL_LANGINFO@ +LIB_POSIX_SPAWN = @LIB_POSIX_SPAWN@ +LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ +LIB_SCHED_YIELD = @LIB_SCHED_YIELD@ +LIB_SELECT = @LIB_SELECT@ +LIB_SETLOCALE_NULL = @LIB_SETLOCALE_NULL@ +LIMITS_H = @LIMITS_H@ +LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +LOCALENAME_ENHANCE_LOCALE_FUNCS = @LOCALENAME_ENHANCE_LOCALE_FUNCS@ +LOCALE_FR = @LOCALE_FR@ +LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@ +LOCALE_JA = @LOCALE_JA@ +LOCALE_ZH_CN = @LOCALE_ZH_CN@ +LTLIBGNUTLS = @LTLIBGNUTLS@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBSSL = @LTLIBSSL@ +LTLIBTHREAD = @LTLIBTHREAD@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +MAKEINFO = @MAKEINFO@ +METALINK_CFLAGS = @METALINK_CFLAGS@ +METALINK_LIBS = @METALINK_LIBS@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +NETINET_IN_H = @NETINET_IN_H@ +NETTLE_CFLAGS = @NETTLE_CFLAGS@ +NETTLE_LIBS = @NETTLE_LIBS@ +NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@ +NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@ +NEXT_AS_FIRST_DIRECTIVE_CTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_CTYPE_H@ +NEXT_AS_FIRST_DIRECTIVE_DIRENT_H = @NEXT_AS_FIRST_DIRECTIVE_DIRENT_H@ +NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@ +NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@ +NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@ +NEXT_AS_FIRST_DIRECTIVE_FNMATCH_H = @NEXT_AS_FIRST_DIRECTIVE_FNMATCH_H@ +NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ +NEXT_AS_FIRST_DIRECTIVE_ICONV_H = @NEXT_AS_FIRST_DIRECTIVE_ICONV_H@ +NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ +NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@ +NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@ +NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@ +NEXT_AS_FIRST_DIRECTIVE_NETDB_H = @NEXT_AS_FIRST_DIRECTIVE_NETDB_H@ +NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@ +NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@ +NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ +NEXT_AS_FIRST_DIRECTIVE_SPAWN_H = @NEXT_AS_FIRST_DIRECTIVE_SPAWN_H@ +NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ +NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ +NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@ +NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@ +NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@ +NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H@ +NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@ +NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@ +NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@ +NEXT_AS_FIRST_DIRECTIVE_UTIME_H = @NEXT_AS_FIRST_DIRECTIVE_UTIME_H@ +NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@ +NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@ +NEXT_CTYPE_H = @NEXT_CTYPE_H@ +NEXT_DIRENT_H = @NEXT_DIRENT_H@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_FCNTL_H = @NEXT_FCNTL_H@ +NEXT_FLOAT_H = @NEXT_FLOAT_H@ +NEXT_FNMATCH_H = @NEXT_FNMATCH_H@ +NEXT_GETOPT_H = @NEXT_GETOPT_H@ +NEXT_ICONV_H = @NEXT_ICONV_H@ +NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +NEXT_LANGINFO_H = @NEXT_LANGINFO_H@ +NEXT_LIMITS_H = @NEXT_LIMITS_H@ +NEXT_LOCALE_H = @NEXT_LOCALE_H@ +NEXT_NETDB_H = @NEXT_NETDB_H@ +NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@ +NEXT_SCHED_H = @NEXT_SCHED_H@ +NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ +NEXT_SPAWN_H = @NEXT_SPAWN_H@ +NEXT_STDDEF_H = @NEXT_STDDEF_H@ +NEXT_STDINT_H = @NEXT_STDINT_H@ +NEXT_STDIO_H = @NEXT_STDIO_H@ +NEXT_STDLIB_H = @NEXT_STDLIB_H@ +NEXT_STRINGS_H = @NEXT_STRINGS_H@ +NEXT_STRING_H = @NEXT_STRING_H@ +NEXT_SYS_FILE_H = @NEXT_SYS_FILE_H@ +NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@ +NEXT_SYS_RANDOM_H = @NEXT_SYS_RANDOM_H@ +NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@ +NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@ +NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@ +NEXT_SYS_UIO_H = @NEXT_SYS_UIO_H@ +NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@ +NEXT_TIME_H = @NEXT_TIME_H@ +NEXT_UNISTD_H = @NEXT_UNISTD_H@ +NEXT_UTIME_H = @NEXT_UTIME_H@ +NEXT_WCHAR_H = @NEXT_WCHAR_H@ +NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCRE2_CFLAGS = @PCRE2_CFLAGS@ +PCRE2_LIBS = @PCRE2_LIBS@ +PCRE_CFLAGS = @PCRE_CFLAGS@ +PCRE_LIBS = @PCRE_LIBS@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POD2MAN = @POD2MAN@ +POSUB = @POSUB@ +PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +PRIPTR_PREFIX = @PRIPTR_PREFIX@ +PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +REPLACE_ACCESS = @REPLACE_ACCESS@ +REPLACE_ALIGNED_ALLOC = @REPLACE_ALIGNED_ALLOC@ +REPLACE_BTOWC = @REPLACE_BTOWC@ +REPLACE_CALLOC_FOR_CALLOC_GNU = @REPLACE_CALLOC_FOR_CALLOC_GNU@ +REPLACE_CALLOC_FOR_CALLOC_POSIX = @REPLACE_CALLOC_FOR_CALLOC_POSIX@ +REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@ +REPLACE_CHOWN = @REPLACE_CHOWN@ +REPLACE_CLOSE = @REPLACE_CLOSE@ +REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@ +REPLACE_COPY_FILE_RANGE = @REPLACE_COPY_FILE_RANGE@ +REPLACE_CREAT = @REPLACE_CREAT@ +REPLACE_CTIME = @REPLACE_CTIME@ +REPLACE_DIRFD = @REPLACE_DIRFD@ +REPLACE_DPRINTF = @REPLACE_DPRINTF@ +REPLACE_DUP = @REPLACE_DUP@ +REPLACE_DUP2 = @REPLACE_DUP2@ +REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@ +REPLACE_EXECL = @REPLACE_EXECL@ +REPLACE_EXECLE = @REPLACE_EXECLE@ +REPLACE_EXECLP = @REPLACE_EXECLP@ +REPLACE_EXECV = @REPLACE_EXECV@ +REPLACE_EXECVE = @REPLACE_EXECVE@ +REPLACE_EXECVP = @REPLACE_EXECVP@ +REPLACE_EXECVPE = @REPLACE_EXECVPE@ +REPLACE_FACCESSAT = @REPLACE_FACCESSAT@ +REPLACE_FCHMODAT = @REPLACE_FCHMODAT@ +REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ +REPLACE_FCLOSE = @REPLACE_FCLOSE@ +REPLACE_FCNTL = @REPLACE_FCNTL@ +REPLACE_FDOPEN = @REPLACE_FDOPEN@ +REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@ +REPLACE_FFLUSH = @REPLACE_FFLUSH@ +REPLACE_FFSLL = @REPLACE_FFSLL@ +REPLACE_FNMATCH = @REPLACE_FNMATCH@ +REPLACE_FOPEN = @REPLACE_FOPEN@ +REPLACE_FOPEN_FOR_FOPEN_GNU = @REPLACE_FOPEN_FOR_FOPEN_GNU@ +REPLACE_FPRINTF = @REPLACE_FPRINTF@ +REPLACE_FPURGE = @REPLACE_FPURGE@ +REPLACE_FREE = @REPLACE_FREE@ +REPLACE_FREELOCALE = @REPLACE_FREELOCALE@ +REPLACE_FREOPEN = @REPLACE_FREOPEN@ +REPLACE_FSEEK = @REPLACE_FSEEK@ +REPLACE_FSEEKO = @REPLACE_FSEEKO@ +REPLACE_FSTAT = @REPLACE_FSTAT@ +REPLACE_FSTATAT = @REPLACE_FSTATAT@ +REPLACE_FTELL = @REPLACE_FTELL@ +REPLACE_FTELLO = @REPLACE_FTELLO@ +REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@ +REPLACE_FUTIMENS = @REPLACE_FUTIMENS@ +REPLACE_GAI_STRERROR = @REPLACE_GAI_STRERROR@ +REPLACE_GETADDRINFO = @REPLACE_GETADDRINFO@ +REPLACE_GETCWD = @REPLACE_GETCWD@ +REPLACE_GETDELIM = @REPLACE_GETDELIM@ +REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@ +REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@ +REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ +REPLACE_GETLINE = @REPLACE_GETLINE@ +REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ +REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ +REPLACE_GETPASS = @REPLACE_GETPASS@ +REPLACE_GETPASS_FOR_GETPASS_GNU = @REPLACE_GETPASS_FOR_GETPASS_GNU@ +REPLACE_GETRANDOM = @REPLACE_GETRANDOM@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_GMTIME = @REPLACE_GMTIME@ +REPLACE_ICONV = @REPLACE_ICONV@ +REPLACE_ICONV_OPEN = @REPLACE_ICONV_OPEN@ +REPLACE_ICONV_UTF = @REPLACE_ICONV_UTF@ +REPLACE_INET_NTOP = @REPLACE_INET_NTOP@ +REPLACE_INET_PTON = @REPLACE_INET_PTON@ +REPLACE_INITSTATE = @REPLACE_INITSTATE@ +REPLACE_IOCTL = @REPLACE_IOCTL@ +REPLACE_ISATTY = @REPLACE_ISATTY@ +REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +REPLACE_ISWDIGIT = @REPLACE_ISWDIGIT@ +REPLACE_ISWXDIGIT = @REPLACE_ISWXDIGIT@ +REPLACE_ITOLD = @REPLACE_ITOLD@ +REPLACE_LCHOWN = @REPLACE_LCHOWN@ +REPLACE_LINK = @REPLACE_LINK@ +REPLACE_LINKAT = @REPLACE_LINKAT@ +REPLACE_LOCALECONV = @REPLACE_LOCALECONV@ +REPLACE_LOCALTIME = @REPLACE_LOCALTIME@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_LSEEK = @REPLACE_LSEEK@ +REPLACE_LSTAT = @REPLACE_LSTAT@ +REPLACE_MALLOC_FOR_MALLOC_GNU = @REPLACE_MALLOC_FOR_MALLOC_GNU@ +REPLACE_MALLOC_FOR_MALLOC_POSIX = @REPLACE_MALLOC_FOR_MALLOC_POSIX@ +REPLACE_MBRLEN = @REPLACE_MBRLEN@ +REPLACE_MBRTOWC = @REPLACE_MBRTOWC@ +REPLACE_MBSINIT = @REPLACE_MBSINIT@ +REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@ +REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@ +REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@ +REPLACE_MBTOWC = @REPLACE_MBTOWC@ +REPLACE_MEMCHR = @REPLACE_MEMCHR@ +REPLACE_MEMMEM = @REPLACE_MEMMEM@ +REPLACE_MKDIR = @REPLACE_MKDIR@ +REPLACE_MKFIFO = @REPLACE_MKFIFO@ +REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@ +REPLACE_MKNOD = @REPLACE_MKNOD@ +REPLACE_MKNODAT = @REPLACE_MKNODAT@ +REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ +REPLACE_MKTIME = @REPLACE_MKTIME@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_NEWLOCALE = @REPLACE_NEWLOCALE@ +REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@ +REPLACE_NULL = @REPLACE_NULL@ +REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@ +REPLACE_OPEN = @REPLACE_OPEN@ +REPLACE_OPENAT = @REPLACE_OPENAT@ +REPLACE_OPENDIR = @REPLACE_OPENDIR@ +REPLACE_PERROR = @REPLACE_PERROR@ +REPLACE_POPEN = @REPLACE_POPEN@ +REPLACE_POSIX_MEMALIGN = @REPLACE_POSIX_MEMALIGN@ +REPLACE_POSIX_SPAWN = @REPLACE_POSIX_SPAWN@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@ +REPLACE_PREAD = @REPLACE_PREAD@ +REPLACE_PRINTF = @REPLACE_PRINTF@ +REPLACE_PSELECT = @REPLACE_PSELECT@ +REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@ +REPLACE_PTSNAME = @REPLACE_PTSNAME@ +REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@ +REPLACE_PUTENV = @REPLACE_PUTENV@ +REPLACE_PWRITE = @REPLACE_PWRITE@ +REPLACE_QSORT_R = @REPLACE_QSORT_R@ +REPLACE_RAISE = @REPLACE_RAISE@ +REPLACE_RANDOM = @REPLACE_RANDOM@ +REPLACE_RANDOM_R = @REPLACE_RANDOM_R@ +REPLACE_READ = @REPLACE_READ@ +REPLACE_READLINK = @REPLACE_READLINK@ +REPLACE_READLINKAT = @REPLACE_READLINKAT@ +REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@ +REPLACE_REALLOC_FOR_REALLOC_GNU = @REPLACE_REALLOC_FOR_REALLOC_GNU@ +REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@ +REPLACE_REALPATH = @REPLACE_REALPATH@ +REPLACE_REMOVE = @REPLACE_REMOVE@ +REPLACE_RENAME = @REPLACE_RENAME@ +REPLACE_RENAMEAT = @REPLACE_RENAMEAT@ +REPLACE_RMDIR = @REPLACE_RMDIR@ +REPLACE_SCHED_YIELD = @REPLACE_SCHED_YIELD@ +REPLACE_SELECT = @REPLACE_SELECT@ +REPLACE_SETENV = @REPLACE_SETENV@ +REPLACE_SETLOCALE = @REPLACE_SETLOCALE@ +REPLACE_SETSTATE = @REPLACE_SETSTATE@ +REPLACE_SLEEP = @REPLACE_SLEEP@ +REPLACE_SNPRINTF = @REPLACE_SNPRINTF@ +REPLACE_SPRINTF = @REPLACE_SPRINTF@ +REPLACE_STAT = @REPLACE_STAT@ +REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@ +REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@ +REPLACE_STPNCPY = @REPLACE_STPNCPY@ +REPLACE_STRCASESTR = @REPLACE_STRCASESTR@ +REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@ +REPLACE_STRDUP = @REPLACE_STRDUP@ +REPLACE_STRERROR = @REPLACE_STRERROR@ +REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@ +REPLACE_STRERROR_R = @REPLACE_STRERROR_R@ +REPLACE_STRFTIME = @REPLACE_STRFTIME@ +REPLACE_STRNCAT = @REPLACE_STRNCAT@ +REPLACE_STRNDUP = @REPLACE_STRNDUP@ +REPLACE_STRNLEN = @REPLACE_STRNLEN@ +REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@ +REPLACE_STRSTR = @REPLACE_STRSTR@ +REPLACE_STRTOD = @REPLACE_STRTOD@ +REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@ +REPLACE_STRTOK_R = @REPLACE_STRTOK_R@ +REPLACE_STRTOL = @REPLACE_STRTOL@ +REPLACE_STRTOLD = @REPLACE_STRTOLD@ +REPLACE_STRTOLL = @REPLACE_STRTOLL@ +REPLACE_STRTOUL = @REPLACE_STRTOUL@ +REPLACE_STRTOULL = @REPLACE_STRTOULL@ +REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@ +REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@ +REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@ +REPLACE_SYMLINK = @REPLACE_SYMLINK@ +REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ +REPLACE_TMPFILE = @REPLACE_TMPFILE@ +REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +REPLACE_TRUNCATE = @REPLACE_TRUNCATE@ +REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@ +REPLACE_TZSET = @REPLACE_TZSET@ +REPLACE_UNLINK = @REPLACE_UNLINK@ +REPLACE_UNLINKAT = @REPLACE_UNLINKAT@ +REPLACE_UNSETENV = @REPLACE_UNSETENV@ +REPLACE_USLEEP = @REPLACE_USLEEP@ +REPLACE_UTIME = @REPLACE_UTIME@ +REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@ +REPLACE_VASPRINTF = @REPLACE_VASPRINTF@ +REPLACE_VDPRINTF = @REPLACE_VDPRINTF@ +REPLACE_VFPRINTF = @REPLACE_VFPRINTF@ +REPLACE_VPRINTF = @REPLACE_VPRINTF@ +REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@ +REPLACE_VSPRINTF = @REPLACE_VSPRINTF@ +REPLACE_WCRTOMB = @REPLACE_WCRTOMB@ +REPLACE_WCSFTIME = @REPLACE_WCSFTIME@ +REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +REPLACE_WCSTOK = @REPLACE_WCSTOK@ +REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +REPLACE_WCTOB = @REPLACE_WCTOB@ +REPLACE_WCTOMB = @REPLACE_WCTOMB@ +REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +REPLACE_WRITE = @REPLACE_WRITE@ +SED = @SED@ +SERVENT_LIB = @SERVENT_LIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDALIGN_H = @STDALIGN_H@ +STDBOOL_H = @STDBOOL_H@ +STDDEF_H = @STDDEF_H@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYS_IOCTL_H_HAVE_WINSOCK2_H = @SYS_IOCTL_H_HAVE_WINSOCK2_H@ +SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@ +UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ +UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ +UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@ +UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@ +UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@ +UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@ +UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_TESTS = @VALGRIND_TESTS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@ +WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@ +WINDOWS_STAT_INODES = @WINDOWS_STAT_INODES@ +WINDOWS_STAT_TIMESPEC = @WINDOWS_STAT_TIMESPEC@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gl_LIBOBJDEPS = @gl_LIBOBJDEPS@ +gl_LIBOBJS = @gl_LIBOBJS@ +gl_LTLIBOBJS = @gl_LTLIBOBJS@ +gltests_LIBOBJDEPS = @gltests_LIBOBJDEPS@ +gltests_LIBOBJS = @gltests_LIBOBJS@ +gltests_LTLIBOBJS = @gltests_LTLIBOBJS@ +gltests_WITNESS = @gltests_WITNESS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +ifGNUmake = @ifGNUmake@ +ifnGNUmake = @ifnGNUmake@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t arpa/inet.h \ + arpa/inet.h-t byteswap.h byteswap.h-t ctype.h ctype.h-t \ + dirent.h dirent.h-t malloc/dynarray.gl.h \ + malloc/dynarray.gl.h-t malloc/dynarray-skeleton.gl.h \ + malloc/dynarray-skeleton.gl.h-t errno.h errno.h-t fcntl.h \ + fcntl.h-t float.h float.h-t fnmatch.h fnmatch.h-t getopt.h \ + getopt.h-t getopt-cdefs.h getopt-cdefs.h-t iconv.h iconv.h-t \ + inttypes.h inttypes.h-t langinfo.h langinfo.h-t limits.h \ + limits.h-t locale.h locale.h-t netdb.h netdb.h-t netinet/in.h \ + netinet/in.h-t sched.h sched.h-t malloc/scratch_buffer.gl.h \ + malloc/scratch_buffer.gl.h-t signal.h signal.h-t spawn.h \ + spawn.h-t stdalign.h stdalign.h-t stdbool.h stdbool.h-t \ + stddef.h stddef.h-t stdint.h stdint.h-t stdio.h stdio.h-t \ + stdlib.h stdlib.h-t string.h string.h-t strings.h strings.h-t \ + sys/file.h sys/file.h-t sys/ioctl.h sys/ioctl.h-t sys/random.h \ + sys/random.h-t sys/select.h sys/select.h-t sys/socket.h \ + sys/socket.h-t sys/stat.h sys/stat.h-t sys/time.h sys/time.h-t \ + sys/types.h sys/types.h-t sys/uio.h sys/uio.h-t sys/wait.h \ + sys/wait.h-t time.h time.h-t unicase.h unicase.h-t \ + unicase/special-casing-table.h-t unicase/special-casing.h \ + unicase/special-casing.h-t unictype.h unictype.h-t uninorm.h \ + uninorm.h-t unistd.h unistd.h-t unistr.h unistr.h-t unitypes.h \ + unitypes.h-t uniwidth.h uniwidth.h-t utime.h utime.h-t wchar.h \ + wchar.h-t wctype.h wctype.h-t +noinst_LTLIBRARIES = +EXTRA_DIST = w32sock.h alloca.c alloca.in.h \ + $(top_srcdir)/build-aux/announce-gen arpa_inet.in.h \ + array-mergesort.h assure.h attribute.h basename-lgpl.h \ + w32sock.h byteswap.in.h c-strcaseeq.h str-two-way.h calloc.c \ + calloc.c canonicalize.h chdir-long.h cloexec.h \ + dirent-private.h concat-filename.h w32sock.h af_alg.h \ + sys-limits.h md2.h md4.h gl_openssl.h md5.h gl_openssl.h \ + sha1.h gl_openssl.h sha256.h gl_openssl.h sha512.h ctype.in.h \ + dirent.in.h stripslash.c dirname.h dynarray.h \ + malloc/dynarray-skeleton.c malloc/dynarray.h eloop-threshold.h \ + errno.in.h error.h exitfail.h fcntl.in.h fd-hook.h \ + stdio-impl.h file-set.h filename.h filenamecat.h flexmember.h \ + float.in.h fnmatch.c fnmatch_loop.c fnmatch.c fnmatch.in.h \ + fopen.c fopen.c stdio-impl.h freading.h stdio-impl.h \ + stdio-impl.h stat-w32.c stat-w32.h at-func.c stdio-impl.h \ + $(top_srcdir)/build-aux/gendocs.sh getopt-cdefs.in.h \ + getopt-core.h getopt-ext.h getopt-pfx-core.h getopt-pfx-ext.h \ + getopt.in.h getopt_int.h getpass.c getpass.h getpass.c \ + getpass.h w32sock.h w32sock.h \ + $(top_srcdir)/build-aux/git-version-gen \ + $(top_srcdir)/build-aux/gitlog-to-changelog \ + $(top_srcdir)/build-aux/gnu-web-doc-update \ + $(top_srcdir)/GNUmakefile $(top_srcdir)/build-aux/gnupload \ + hard-locale.h hash.h hash-triple.h \ + $(top_srcdir)/build-aux/config.rpath ialloc.h iconv.in.h \ + intprops.h inttypes.in.h w32sock.h langinfo.in.h cdefs.h \ + libc-config.h libunistring.valgrind limits.in.h w32sock.h \ + localcharset.h locale.in.h $(top_srcdir)/maint.mk malloc.c \ + malloc.c malloca.h mbchar.h lc-charset-dispatch.c \ + lc-charset-dispatch.h mbrtowc-impl-utf8.h mbrtowc-impl.h \ + mbtowc-lock.c mbtowc-lock.h windows-initguard.h \ + mbsrtowcs-impl.h mbsrtowcs-state.c mbtowc-impl.h \ + memchr.valgrind mktime-internal.h mktime.c mktime-internal.h \ + mktime.c msvc-inval.h msvc-nothrow.h netdb.in.h \ + netinet_in.in.h windows-initguard.h openat.h dirent-private.h \ + pathmax.h spawn_int.h spawn_int.h spawn_int.h spawn_int.h \ + spawn_int.h spawn_int.h quote.h quote.h quotearg.h \ + rawmemchr.valgrind dirent-private.h realloc.c realloc.c \ + w32sock.h regcomp.c regex.h regex_internal.c regex_internal.h \ + regexec.c dirent-private.h same-inode.h save-cwd.h sched.in.h \ + malloc/scratch_buffer.h scratch_buffer.h w32sock.h \ + setlocale_null.h windows-initguard.h w32sock.h sig-handler.h \ + signal.in.h stdio-write.c _Noreturn.h arg-nonnull.h c++defs.h \ + warn-on-use.h snprintf.c w32sock.h w32sock.h spawn.in.h \ + os2-spawn.h stat-w32.c stat-w32.h stat-time.h stdalign.in.h \ + stdbool.in.h stddef.in.h stdint.in.h stdio.in.h stdlib.in.h \ + strchrnul.valgrind streq.h strerror-override.h strerror_r.c \ + string.in.h strings.in.h strtol.c sys_file.in.h sys_ioctl.in.h \ + sys_random.in.h sys_select.in.h sys_socket.in.h sys_stat.in.h \ + sys_time.in.h sys_types.in.h sys_uio.in.h sys_wait.in.h \ + tempname.h thread-optim.h time.in.h mktime-internal.h \ + timespec.h u64.h unicase.in.h unicase/cased.h \ + unicase/caseprop.h unictype/bitmap.h unicase/caseprop.h \ + unicase/ignorable.h unictype/bitmap.h \ + unicase/special-casing-table.h \ + unicase/special-casing-table.gperf unicase/special-casing.in.h \ + unicase/simple-mapping.h unicase/tolower.h unicase/context.h \ + unicase/u-casemap.h unicase/unicasemap.h unictype.in.h \ + unictype/combiningclass.h unictype/bitmap.h \ + unictype/pr_soft_dotted.h uninorm.in.h \ + uninorm/decompose-internal.h uninorm/normalize-internal.h \ + uninorm/u-normalize-internal.h unistd.in.h unistd--.h \ + unistd-safer.h unistr.in.h unistr/u-cpy.h unitypes.in.h \ + localcharset.h uniwidth.in.h unictype/bitmap.h uniwidth/cjk.h \ + uniwidth/width0.h uniwidth/width2.h unlocked-io.h \ + $(top_srcdir)/build-aux/update-copyright \ + $(top_srcdir)/build-aux/useless-if-before-free utime.in.h \ + utimens.h asnprintf.c float+.h printf-args.c printf-args.h \ + printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h \ + asprintf.c vasprintf.c $(top_srcdir)/build-aux/vc-list-files \ + verify.h vsnprintf.c wchar.in.h wctype.in.h \ + windows-initguard.h windows-mutex.h windows-once.h \ + windows-initguard.h windows-recmutex.h windows-initguard.h \ + windows-rwlock.h windows-spawn.h wmemchr-impl.h xalloc.h \ + xalloc.h xalloc-oversized.h +BUILT_SOURCES = $(ALLOCA_H) arpa/inet.h $(BYTESWAP_H) ctype.h dirent.h \ + malloc/dynarray.gl.h malloc/dynarray-skeleton.gl.h $(ERRNO_H) \ + fcntl.h $(FLOAT_H) $(FNMATCH_H) $(GETOPT_H) $(GETOPT_CDEFS_H) \ + $(ICONV_H) inttypes.h langinfo.h $(LIMITS_H) locale.h netdb.h \ + $(NETINET_IN_H) sched.h malloc/scratch_buffer.gl.h signal.h \ + spawn.h $(STDALIGN_H) $(STDBOOL_H) $(STDDEF_H) $(STDINT_H) \ + stdio.h stdlib.h string.h strings.h sys/file.h sys/ioctl.h \ + sys/random.h sys/select.h sys/socket.h sys/stat.h sys/time.h \ + sys/types.h sys/uio.h sys/wait.h time.h \ + $(LIBUNISTRING_UNICASE_H) unicase/special-casing-table.h \ + unicase/special-casing.h $(LIBUNISTRING_UNICTYPE_H) \ + $(LIBUNISTRING_UNINORM_H) unistd.h $(LIBUNISTRING_UNISTR_H) \ + $(LIBUNISTRING_UNITYPES_H) $(LIBUNISTRING_UNIWIDTH_H) utime.h \ + wchar.h wctype.h +MOSTLYCLEANDIRS = arpa netinet sys sys sys sys sys sys sys sys +CLEANFILES = +SUFFIXES = +# No GNU Make output. +noinst_LIBRARIES = libgnu.a +MAINTAINERCLEANFILES = unicase/special-casing-table.h +AM_CFLAGS = $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS) +AM_CPPFLAGS = -DDEFAULT_TEXT_DOMAIN=\"wget-gnulib\" +libgnu_a_SOURCES = $(am__append_1) $(am__append_2) openat-priv.h \ + openat-proc.c base32.h base32.c basename-lgpl.c binary-io.h \ + binary-io.c $(am__append_3) bitrotate.h bitrotate.c \ + $(am__append_4) c-ctype.h c-ctype.c c-strcase.h c-strcasecmp.c \ + c-strncasecmp.c c-strcasestr.h c-strcasestr.c canonicalize.c \ + $(am__append_5) $(am__append_6) cloexec.c $(am__append_7) \ + $(am__append_8) concat-filename.c $(am__append_9) af_alg.c \ + md2-stream.c md2.c md4-stream.c md4.c md5-stream.c md5.c \ + sha1-stream.c sha1.c sha256-stream.c sha256.c sha512-stream.c \ + sha512.c $(am__append_10) dirname.c basename.c dirname-lgpl.c \ + stripslash.c $(am__append_11) $(am__append_12) \ + malloc/dynarray_at_failure.c malloc/dynarray_emplace_enlarge.c \ + malloc/dynarray_finalize.c malloc/dynarray_resize.c \ + malloc/dynarray_resize_clear.c $(am__append_13) exitfail.c \ + fatal-signal.h fatal-signal.c $(am__append_14) \ + $(am__append_15) fd-hook.c fd-safer-flag.c dup-safer-flag.c \ + $(am__append_16) $(am__append_17) file-set.c \ + filenamecat-lgpl.c findprog.h findprog-in.c $(am__append_18) \ + $(am__append_19) $(am__append_20) $(am__append_21) freading.c \ + $(am__append_22) $(am__append_23) $(am__append_24) \ + $(am__append_25) $(am__append_26) $(am__append_27) \ + $(am__append_28) $(am__append_29) $(am__append_30) \ + $(am__append_31) $(am__append_32) $(am__append_33) \ + $(am__append_34) $(am__append_35) $(am__append_36) \ + $(am__append_37) $(am__append_38) $(am__append_39) \ + getprogname.h getprogname.c $(am__append_40) $(am__append_41) \ + gettext.h gettime.c $(am__append_42) $(am__append_43) \ + hard-locale.c hash.c hash-pjw.h hash-pjw.c \ + hash-triple-simple.c ialloc.c idx.h $(am__append_44) \ + $(am__append_45) $(am__append_46) $(am__append_47) \ + $(am__append_48) $(am__append_49) $(am__append_50) \ + $(am__append_51) localcharset.c $(am__append_52) \ + glthread/lock.h glthread/lock.c $(am__append_53) \ + $(am__append_54) malloca.c mbchar.c mbiter.h mbiter.c \ + $(am__append_55) $(am__append_56) $(am__append_57) \ + $(am__append_58) $(am__append_59) $(am__append_60) \ + $(am__append_61) minmax.h $(am__append_62) $(am__append_63) \ + $(am__append_64) $(am__append_65) $(am__append_66) \ + $(am__append_67) $(am__append_68) $(am__append_69) \ + $(am__append_70) $(am__append_71) openat-die.c \ + $(am__append_72) $(am__append_73) pipe2.c pipe2-safer.c \ + $(am__append_74) $(am__append_75) $(am__append_76) \ + $(am__append_77) $(am__append_78) $(am__append_79) \ + $(am__append_80) $(am__append_81) $(am__append_82) \ + $(am__append_83) $(am__append_84) $(am__append_85) \ + $(am__append_86) $(am__append_87) $(am__append_88) \ + $(am__append_89) quotearg.c $(am__append_90) $(am__append_91) \ + $(am__append_92) $(am__append_93) $(am__append_94) \ + $(am__append_95) $(am__append_96) $(am__append_97) \ + $(am__append_98) $(am__append_99) save-cwd.c \ + malloc/scratch_buffer_dupfree.c malloc/scratch_buffer_grow.c \ + malloc/scratch_buffer_grow_preserve.c \ + malloc/scratch_buffer_set_array_size.c $(am__append_100) \ + $(am__append_101) $(am__append_102) setlocale_null.c \ + $(am__append_103) $(am__append_104) $(am__append_105) \ + sig-handler.c $(am__append_106) size_max.h $(am__append_107) \ + sockets.h sockets.c spawn-pipe.h spawn-pipe.c \ + $(am__append_108) $(am__append_109) stat-time.c \ + $(am__append_110) $(am__append_111) $(am__append_112) \ + $(am__append_113) $(am__append_114) $(am__append_115) \ + $(am__append_116) $(am__append_117) $(am__append_118) \ + $(am__append_119) $(am__append_120) strnlen1.h strnlen1.c \ + $(am__append_121) $(am__append_122) $(am__append_123) \ + $(am__append_124) $(am__append_125) $(am__append_126) \ + sys_socket.c tempname.c glthread/threadlib.c $(am__append_127) \ + $(am__append_128) timespec.c tmpdir.h tmpdir.c u64.c \ + unicase/cased.c $(am__append_129) $(am__append_130) \ + unicase/ignorable.c unicase/special-casing.c $(am__append_131) \ + unicase/u8-casemap.c $(am__append_132) $(am__append_133) \ + $(am__append_134) uninorm/decompose-internal.c \ + $(am__append_135) unistd.c dup-safer.c fd-safer.c pipe-safer.c \ + $(am__append_136) $(am__append_137) $(am__append_138) \ + $(am__append_139) $(am__append_140) $(am__append_141) \ + $(am__append_142) utimens.c wait-process.h wait-process.c \ + $(am__append_143) $(am__append_144) wctype-h.c \ + $(am__append_145) $(am__append_146) $(am__append_147) \ + $(am__append_148) $(am__append_149) $(am__append_150) \ + $(am__append_151) $(am__append_152) $(am__append_153) \ + xmalloc.c xalloc-die.c xmemdup0.h xmemdup0.c xsize.h xsize.c \ + xstrndup.h xstrndup.c +libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS) +libgnu_a_LIBADD = $(gl_LIBOBJS) @ALLOCA@ +libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) @ALLOCA@ +EXTRA_libgnu_a_SOURCES = alloca.c calloc.c calloc.c stripslash.c \ + malloc/dynarray-skeleton.c fnmatch.c fnmatch_loop.c fnmatch.c \ + fopen.c fopen.c stat-w32.c at-func.c getpass.c getpass.c \ + malloc.c malloc.c lc-charset-dispatch.c mbtowc-lock.c \ + mbsrtowcs-state.c mktime.c mktime.c realloc.c realloc.c \ + regcomp.c regex_internal.c regexec.c stdio-write.c snprintf.c \ + stat-w32.c strerror_r.c strtol.c asnprintf.c printf-args.c \ + printf-parse.c vasnprintf.c asprintf.c vasprintf.c vsnprintf.c + +# 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) + +# 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 + +# '$(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' + +# Use $(gl_V_at) instead of $(AM_V_GEN) or $(AM_V_at) on a line that +gl_V_at = $(AM_V_GEN) +GPERF = gperf +V_GPERF = $(V_GPERF_@AM_V@) +V_GPERF_ = $(V_GPERF_@AM_DEFAULT_V@) +V_GPERF_0 = @echo " GPERF " $@; + +# 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. +_NORETURN_H = $(srcdir)/_Noreturn.h + +# 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 = $(srcdir)/arg-nonnull.h + +# 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 = $(srcdir)/c++defs.h + +# 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 = $(srcdir)/warn-on-use.h +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/gnulib.mk $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(srcdir)/gnulib.mk $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +malloc/$(am__dirstamp): + @$(MKDIR_P) malloc + @: > malloc/$(am__dirstamp) +malloc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) malloc/$(DEPDIR) + @: > malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-dynarray_at_failure.$(OBJEXT): malloc/$(am__dirstamp) \ + malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-dynarray_emplace_enlarge.$(OBJEXT): \ + malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-dynarray_finalize.$(OBJEXT): malloc/$(am__dirstamp) \ + malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-dynarray_resize.$(OBJEXT): malloc/$(am__dirstamp) \ + malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-dynarray_resize_clear.$(OBJEXT): \ + malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp) +glthread/$(am__dirstamp): + @$(MKDIR_P) glthread + @: > glthread/$(am__dirstamp) +glthread/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) glthread/$(DEPDIR) + @: > glthread/$(DEPDIR)/$(am__dirstamp) +glthread/libgnu_a-lock.$(OBJEXT): glthread/$(am__dirstamp) \ + glthread/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-scratch_buffer_dupfree.$(OBJEXT): \ + malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-scratch_buffer_grow.$(OBJEXT): malloc/$(am__dirstamp) \ + malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-scratch_buffer_grow_preserve.$(OBJEXT): \ + malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-scratch_buffer_set_array_size.$(OBJEXT): \ + malloc/$(am__dirstamp) malloc/$(DEPDIR)/$(am__dirstamp) +glthread/libgnu_a-threadlib.$(OBJEXT): glthread/$(am__dirstamp) \ + glthread/$(DEPDIR)/$(am__dirstamp) +unicase/$(am__dirstamp): + @$(MKDIR_P) unicase + @: > unicase/$(am__dirstamp) +unicase/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) unicase/$(DEPDIR) + @: > unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-cased.$(OBJEXT): unicase/$(am__dirstamp) \ + unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-empty-prefix-context.$(OBJEXT): \ + unicase/$(am__dirstamp) unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-empty-suffix-context.$(OBJEXT): \ + unicase/$(am__dirstamp) unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-ignorable.$(OBJEXT): unicase/$(am__dirstamp) \ + unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-special-casing.$(OBJEXT): unicase/$(am__dirstamp) \ + unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-tolower.$(OBJEXT): unicase/$(am__dirstamp) \ + unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-u8-casemap.$(OBJEXT): unicase/$(am__dirstamp) \ + unicase/$(DEPDIR)/$(am__dirstamp) +unicase/libgnu_a-u8-tolower.$(OBJEXT): unicase/$(am__dirstamp) \ + unicase/$(DEPDIR)/$(am__dirstamp) +unictype/$(am__dirstamp): + @$(MKDIR_P) unictype + @: > unictype/$(am__dirstamp) +unictype/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) unictype/$(DEPDIR) + @: > unictype/$(DEPDIR)/$(am__dirstamp) +unictype/libgnu_a-combiningclass.$(OBJEXT): unictype/$(am__dirstamp) \ + unictype/$(DEPDIR)/$(am__dirstamp) +unictype/libgnu_a-pr_soft_dotted.$(OBJEXT): unictype/$(am__dirstamp) \ + unictype/$(DEPDIR)/$(am__dirstamp) +uninorm/$(am__dirstamp): + @$(MKDIR_P) uninorm + @: > uninorm/$(am__dirstamp) +uninorm/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) uninorm/$(DEPDIR) + @: > uninorm/$(DEPDIR)/$(am__dirstamp) +uninorm/libgnu_a-decompose-internal.$(OBJEXT): \ + uninorm/$(am__dirstamp) uninorm/$(DEPDIR)/$(am__dirstamp) +uninorm/libgnu_a-u8-normalize.$(OBJEXT): uninorm/$(am__dirstamp) \ + uninorm/$(DEPDIR)/$(am__dirstamp) +unistr/$(am__dirstamp): + @$(MKDIR_P) unistr + @: > unistr/$(am__dirstamp) +unistr/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) unistr/$(DEPDIR) + @: > unistr/$(DEPDIR)/$(am__dirstamp) +unistr/libgnu_a-u8-cpy.$(OBJEXT): unistr/$(am__dirstamp) \ + unistr/$(DEPDIR)/$(am__dirstamp) +unistr/libgnu_a-u8-mbtouc-unsafe.$(OBJEXT): unistr/$(am__dirstamp) \ + unistr/$(DEPDIR)/$(am__dirstamp) +unistr/libgnu_a-u8-mbtouc-unsafe-aux.$(OBJEXT): \ + unistr/$(am__dirstamp) unistr/$(DEPDIR)/$(am__dirstamp) +unistr/libgnu_a-u8-strlen.$(OBJEXT): unistr/$(am__dirstamp) \ + unistr/$(DEPDIR)/$(am__dirstamp) +unistr/libgnu_a-u8-uctomb.$(OBJEXT): unistr/$(am__dirstamp) \ + unistr/$(DEPDIR)/$(am__dirstamp) +unistr/libgnu_a-u8-uctomb-aux.$(OBJEXT): unistr/$(am__dirstamp) \ + unistr/$(DEPDIR)/$(am__dirstamp) +uniwidth/$(am__dirstamp): + @$(MKDIR_P) uniwidth + @: > uniwidth/$(am__dirstamp) +uniwidth/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) uniwidth/$(DEPDIR) + @: > uniwidth/$(DEPDIR)/$(am__dirstamp) +uniwidth/libgnu_a-width.$(OBJEXT): uniwidth/$(am__dirstamp) \ + uniwidth/$(DEPDIR)/$(am__dirstamp) +malloc/libgnu_a-dynarray-skeleton.$(OBJEXT): malloc/$(am__dirstamp) \ + malloc/$(DEPDIR)/$(am__dirstamp) + +libgnu.a: $(libgnu_a_OBJECTS) $(libgnu_a_DEPENDENCIES) $(EXTRA_libgnu_a_DEPENDENCIES) + $(AM_V_at)-rm -f libgnu.a + $(AM_V_AR)$(libgnu_a_AR) libgnu.a $(libgnu_a_OBJECTS) $(libgnu_a_LIBADD) + $(AM_V_at)$(RANLIB) libgnu.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f glthread/*.$(OBJEXT) + -rm -f malloc/*.$(OBJEXT) + -rm -f unicase/*.$(OBJEXT) + -rm -f unictype/*.$(OBJEXT) + -rm -f uninorm/*.$(OBJEXT) + -rm -f unistr/*.$(OBJEXT) + -rm -f uniwidth/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-accept.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-access.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-af_alg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-alloca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-asnprintf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-asprintf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-at-func.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-base32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-basename-lgpl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-basename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-binary-io.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-bind.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-bitrotate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-btowc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-c-ctype.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-c-strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-c-strcasestr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-c-strncasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-calloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-canonicalize-lgpl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-canonicalize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-chdir-long.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-cloexec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-close.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-closedir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-concat-filename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-connect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dirfd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dirname-lgpl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dirname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dup-safer-flag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dup-safer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-dup2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-error.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-exitfail.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fatal-signal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fchdir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fcntl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fd-hook.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fd-safer-flag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fd-safer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fdopendir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fflush.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-file-set.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-filenamecat-lgpl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-findprog-in.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-float.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-flock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fnmatch.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fnmatch_loop.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fopen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fpurge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-freading.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-free.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fseek.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fseeko.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fstat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-fstatat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-ftell.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-ftello.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-futimens.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-gai_strerror.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getaddrinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getcwd-lgpl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getcwd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getdelim.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getdtablesize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getgroups.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getline.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getopt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getopt1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getpass.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getpeername.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getprogname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getrandom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-getsockname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-gettime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-gettimeofday.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-group-member.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-hard-locale.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-hash-pjw.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-hash-triple-simple.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-ialloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-inet_ntop.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-ioctl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-isblank.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-iswblank.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-iswdigit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-iswxdigit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-itold.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-lc-charset-dispatch.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-link.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-listen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-localcharset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-localeconv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-lseek.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-lstat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-malloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-malloca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbchar.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbiter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbrtowc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbsinit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbsrtowcs-state.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbsrtowcs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbtowc-lock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mbtowc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-md2-stream.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-md2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-md4-stream.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-md4.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-md5-stream.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-md5.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-memchr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mempcpy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-memrchr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mkdir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mkostemp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mkstemp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-mktime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-msvc-inval.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-msvc-nothrow.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-nanosleep.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-nl_langinfo-lock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-nl_langinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-open.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-openat-die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-openat-proc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-openat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-opendir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-os2-spawn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-pipe-safer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-pipe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-pipe2-safer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-pipe2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-printf-args.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-printf-parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-pselect.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-pthread_sigmask.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-quotearg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-raise.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-rawmemchr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-readdir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-readlink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-realloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-reallocarray.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-recv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-regcomp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-regex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-regex_internal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-regexec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-rename.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-rewinddir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-rmdir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-save-cwd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-secure_getenv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-select.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-send.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-setlocale-lock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-setlocale_null.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-setsockopt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sha1-stream.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sha1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sha256-stream.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sha256.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sha512-stream.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sha512.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sig-handler.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sigaction.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sigprocmask.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-snprintf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-socket.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sockets.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn-pipe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn_faction_addchdir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn_faction_addclose.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn_faction_adddup2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn_faction_addopen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn_faction_destroy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawn_faction_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawnattr_destroy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawnattr_init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawnattr_setflags.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawnattr_setpgroup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawnattr_setsigmask.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawni.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-spawnp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stat-time.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stat-w32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stdio-read.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stdio-write.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stpcpy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strchrnul.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strdup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strerror-override.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strerror.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strerror_r.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-stripslash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strncasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strndup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strnlen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strnlen1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strpbrk.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strptime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strtok_r.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strtol.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-strtoll.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-symlink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-sys_socket.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-tempname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-time_r.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-timegm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-timespec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-tmpdir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-u64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-unistd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-unlink.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-utime.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-utimens.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-vasnprintf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-vasprintf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-vsnprintf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-wait-process.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-waitpid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-wcrtomb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-wctype-h.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-wcwidth.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-windows-mutex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-windows-once.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-windows-recmutex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-windows-rwlock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-windows-spawn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-wmemchr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-wmempcpy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-write.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-xalloc-die.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-xmalloc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-xmemdup0.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-xsize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgnu_a-xstrndup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@glthread/$(DEPDIR)/libgnu_a-lock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@glthread/$(DEPDIR)/libgnu_a-threadlib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-cased.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-ignorable.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-special-casing.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-tolower.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-u8-casemap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unicase/$(DEPDIR)/libgnu_a-u8-tolower.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unictype/$(DEPDIR)/libgnu_a-combiningclass.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/libgnu_a-u8-cpy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/libgnu_a-u8-strlen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@uniwidth/$(DEPDIR)/libgnu_a-width.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +libgnu_a-accept.o: accept.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-accept.o -MD -MP -MF $(DEPDIR)/libgnu_a-accept.Tpo -c -o libgnu_a-accept.o `test -f 'accept.c' || echo '$(srcdir)/'`accept.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-accept.Tpo $(DEPDIR)/libgnu_a-accept.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='accept.c' object='libgnu_a-accept.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-accept.o `test -f 'accept.c' || echo '$(srcdir)/'`accept.c + +libgnu_a-accept.obj: accept.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-accept.obj -MD -MP -MF $(DEPDIR)/libgnu_a-accept.Tpo -c -o libgnu_a-accept.obj `if test -f 'accept.c'; then $(CYGPATH_W) 'accept.c'; else $(CYGPATH_W) '$(srcdir)/accept.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-accept.Tpo $(DEPDIR)/libgnu_a-accept.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='accept.c' object='libgnu_a-accept.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-accept.obj `if test -f 'accept.c'; then $(CYGPATH_W) 'accept.c'; else $(CYGPATH_W) '$(srcdir)/accept.c'; fi` + +libgnu_a-access.o: access.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-access.o -MD -MP -MF $(DEPDIR)/libgnu_a-access.Tpo -c -o libgnu_a-access.o `test -f 'access.c' || echo '$(srcdir)/'`access.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-access.Tpo $(DEPDIR)/libgnu_a-access.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='access.c' object='libgnu_a-access.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-access.o `test -f 'access.c' || echo '$(srcdir)/'`access.c + +libgnu_a-access.obj: access.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-access.obj -MD -MP -MF $(DEPDIR)/libgnu_a-access.Tpo -c -o libgnu_a-access.obj `if test -f 'access.c'; then $(CYGPATH_W) 'access.c'; else $(CYGPATH_W) '$(srcdir)/access.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-access.Tpo $(DEPDIR)/libgnu_a-access.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='access.c' object='libgnu_a-access.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-access.obj `if test -f 'access.c'; then $(CYGPATH_W) 'access.c'; else $(CYGPATH_W) '$(srcdir)/access.c'; fi` + +libgnu_a-openat-proc.o: openat-proc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-openat-proc.o -MD -MP -MF $(DEPDIR)/libgnu_a-openat-proc.Tpo -c -o libgnu_a-openat-proc.o `test -f 'openat-proc.c' || echo '$(srcdir)/'`openat-proc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-openat-proc.Tpo $(DEPDIR)/libgnu_a-openat-proc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openat-proc.c' object='libgnu_a-openat-proc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-openat-proc.o `test -f 'openat-proc.c' || echo '$(srcdir)/'`openat-proc.c + +libgnu_a-openat-proc.obj: openat-proc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-openat-proc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-openat-proc.Tpo -c -o libgnu_a-openat-proc.obj `if test -f 'openat-proc.c'; then $(CYGPATH_W) 'openat-proc.c'; else $(CYGPATH_W) '$(srcdir)/openat-proc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-openat-proc.Tpo $(DEPDIR)/libgnu_a-openat-proc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openat-proc.c' object='libgnu_a-openat-proc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-openat-proc.obj `if test -f 'openat-proc.c'; then $(CYGPATH_W) 'openat-proc.c'; else $(CYGPATH_W) '$(srcdir)/openat-proc.c'; fi` + +libgnu_a-base32.o: base32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-base32.o -MD -MP -MF $(DEPDIR)/libgnu_a-base32.Tpo -c -o libgnu_a-base32.o `test -f 'base32.c' || echo '$(srcdir)/'`base32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-base32.Tpo $(DEPDIR)/libgnu_a-base32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base32.c' object='libgnu_a-base32.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-base32.o `test -f 'base32.c' || echo '$(srcdir)/'`base32.c + +libgnu_a-base32.obj: base32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-base32.obj -MD -MP -MF $(DEPDIR)/libgnu_a-base32.Tpo -c -o libgnu_a-base32.obj `if test -f 'base32.c'; then $(CYGPATH_W) 'base32.c'; else $(CYGPATH_W) '$(srcdir)/base32.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-base32.Tpo $(DEPDIR)/libgnu_a-base32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base32.c' object='libgnu_a-base32.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-base32.obj `if test -f 'base32.c'; then $(CYGPATH_W) 'base32.c'; else $(CYGPATH_W) '$(srcdir)/base32.c'; fi` + +libgnu_a-basename-lgpl.o: basename-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-basename-lgpl.o -MD -MP -MF $(DEPDIR)/libgnu_a-basename-lgpl.Tpo -c -o libgnu_a-basename-lgpl.o `test -f 'basename-lgpl.c' || echo '$(srcdir)/'`basename-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-basename-lgpl.Tpo $(DEPDIR)/libgnu_a-basename-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='basename-lgpl.c' object='libgnu_a-basename-lgpl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-basename-lgpl.o `test -f 'basename-lgpl.c' || echo '$(srcdir)/'`basename-lgpl.c + +libgnu_a-basename-lgpl.obj: basename-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-basename-lgpl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-basename-lgpl.Tpo -c -o libgnu_a-basename-lgpl.obj `if test -f 'basename-lgpl.c'; then $(CYGPATH_W) 'basename-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/basename-lgpl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-basename-lgpl.Tpo $(DEPDIR)/libgnu_a-basename-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='basename-lgpl.c' object='libgnu_a-basename-lgpl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-basename-lgpl.obj `if test -f 'basename-lgpl.c'; then $(CYGPATH_W) 'basename-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/basename-lgpl.c'; fi` + +libgnu_a-binary-io.o: binary-io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-binary-io.o -MD -MP -MF $(DEPDIR)/libgnu_a-binary-io.Tpo -c -o libgnu_a-binary-io.o `test -f 'binary-io.c' || echo '$(srcdir)/'`binary-io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-binary-io.Tpo $(DEPDIR)/libgnu_a-binary-io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='binary-io.c' object='libgnu_a-binary-io.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-binary-io.o `test -f 'binary-io.c' || echo '$(srcdir)/'`binary-io.c + +libgnu_a-binary-io.obj: binary-io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-binary-io.obj -MD -MP -MF $(DEPDIR)/libgnu_a-binary-io.Tpo -c -o libgnu_a-binary-io.obj `if test -f 'binary-io.c'; then $(CYGPATH_W) 'binary-io.c'; else $(CYGPATH_W) '$(srcdir)/binary-io.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-binary-io.Tpo $(DEPDIR)/libgnu_a-binary-io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='binary-io.c' object='libgnu_a-binary-io.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-binary-io.obj `if test -f 'binary-io.c'; then $(CYGPATH_W) 'binary-io.c'; else $(CYGPATH_W) '$(srcdir)/binary-io.c'; fi` + +libgnu_a-bind.o: bind.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-bind.o -MD -MP -MF $(DEPDIR)/libgnu_a-bind.Tpo -c -o libgnu_a-bind.o `test -f 'bind.c' || echo '$(srcdir)/'`bind.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-bind.Tpo $(DEPDIR)/libgnu_a-bind.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bind.c' object='libgnu_a-bind.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-bind.o `test -f 'bind.c' || echo '$(srcdir)/'`bind.c + +libgnu_a-bind.obj: bind.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-bind.obj -MD -MP -MF $(DEPDIR)/libgnu_a-bind.Tpo -c -o libgnu_a-bind.obj `if test -f 'bind.c'; then $(CYGPATH_W) 'bind.c'; else $(CYGPATH_W) '$(srcdir)/bind.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-bind.Tpo $(DEPDIR)/libgnu_a-bind.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bind.c' object='libgnu_a-bind.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-bind.obj `if test -f 'bind.c'; then $(CYGPATH_W) 'bind.c'; else $(CYGPATH_W) '$(srcdir)/bind.c'; fi` + +libgnu_a-bitrotate.o: bitrotate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-bitrotate.o -MD -MP -MF $(DEPDIR)/libgnu_a-bitrotate.Tpo -c -o libgnu_a-bitrotate.o `test -f 'bitrotate.c' || echo '$(srcdir)/'`bitrotate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-bitrotate.Tpo $(DEPDIR)/libgnu_a-bitrotate.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bitrotate.c' object='libgnu_a-bitrotate.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-bitrotate.o `test -f 'bitrotate.c' || echo '$(srcdir)/'`bitrotate.c + +libgnu_a-bitrotate.obj: bitrotate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-bitrotate.obj -MD -MP -MF $(DEPDIR)/libgnu_a-bitrotate.Tpo -c -o libgnu_a-bitrotate.obj `if test -f 'bitrotate.c'; then $(CYGPATH_W) 'bitrotate.c'; else $(CYGPATH_W) '$(srcdir)/bitrotate.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-bitrotate.Tpo $(DEPDIR)/libgnu_a-bitrotate.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bitrotate.c' object='libgnu_a-bitrotate.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-bitrotate.obj `if test -f 'bitrotate.c'; then $(CYGPATH_W) 'bitrotate.c'; else $(CYGPATH_W) '$(srcdir)/bitrotate.c'; fi` + +libgnu_a-btowc.o: btowc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-btowc.o -MD -MP -MF $(DEPDIR)/libgnu_a-btowc.Tpo -c -o libgnu_a-btowc.o `test -f 'btowc.c' || echo '$(srcdir)/'`btowc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-btowc.Tpo $(DEPDIR)/libgnu_a-btowc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='btowc.c' object='libgnu_a-btowc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-btowc.o `test -f 'btowc.c' || echo '$(srcdir)/'`btowc.c + +libgnu_a-btowc.obj: btowc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-btowc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-btowc.Tpo -c -o libgnu_a-btowc.obj `if test -f 'btowc.c'; then $(CYGPATH_W) 'btowc.c'; else $(CYGPATH_W) '$(srcdir)/btowc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-btowc.Tpo $(DEPDIR)/libgnu_a-btowc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='btowc.c' object='libgnu_a-btowc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-btowc.obj `if test -f 'btowc.c'; then $(CYGPATH_W) 'btowc.c'; else $(CYGPATH_W) '$(srcdir)/btowc.c'; fi` + +libgnu_a-c-ctype.o: c-ctype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-ctype.o -MD -MP -MF $(DEPDIR)/libgnu_a-c-ctype.Tpo -c -o libgnu_a-c-ctype.o `test -f 'c-ctype.c' || echo '$(srcdir)/'`c-ctype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-ctype.Tpo $(DEPDIR)/libgnu_a-c-ctype.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-ctype.c' object='libgnu_a-c-ctype.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-ctype.o `test -f 'c-ctype.c' || echo '$(srcdir)/'`c-ctype.c + +libgnu_a-c-ctype.obj: c-ctype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-ctype.obj -MD -MP -MF $(DEPDIR)/libgnu_a-c-ctype.Tpo -c -o libgnu_a-c-ctype.obj `if test -f 'c-ctype.c'; then $(CYGPATH_W) 'c-ctype.c'; else $(CYGPATH_W) '$(srcdir)/c-ctype.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-ctype.Tpo $(DEPDIR)/libgnu_a-c-ctype.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-ctype.c' object='libgnu_a-c-ctype.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-ctype.obj `if test -f 'c-ctype.c'; then $(CYGPATH_W) 'c-ctype.c'; else $(CYGPATH_W) '$(srcdir)/c-ctype.c'; fi` + +libgnu_a-c-strcasecmp.o: c-strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-strcasecmp.o -MD -MP -MF $(DEPDIR)/libgnu_a-c-strcasecmp.Tpo -c -o libgnu_a-c-strcasecmp.o `test -f 'c-strcasecmp.c' || echo '$(srcdir)/'`c-strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-strcasecmp.Tpo $(DEPDIR)/libgnu_a-c-strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-strcasecmp.c' object='libgnu_a-c-strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-strcasecmp.o `test -f 'c-strcasecmp.c' || echo '$(srcdir)/'`c-strcasecmp.c + +libgnu_a-c-strcasecmp.obj: c-strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-strcasecmp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-c-strcasecmp.Tpo -c -o libgnu_a-c-strcasecmp.obj `if test -f 'c-strcasecmp.c'; then $(CYGPATH_W) 'c-strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/c-strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-strcasecmp.Tpo $(DEPDIR)/libgnu_a-c-strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-strcasecmp.c' object='libgnu_a-c-strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-strcasecmp.obj `if test -f 'c-strcasecmp.c'; then $(CYGPATH_W) 'c-strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/c-strcasecmp.c'; fi` + +libgnu_a-c-strncasecmp.o: c-strncasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-strncasecmp.o -MD -MP -MF $(DEPDIR)/libgnu_a-c-strncasecmp.Tpo -c -o libgnu_a-c-strncasecmp.o `test -f 'c-strncasecmp.c' || echo '$(srcdir)/'`c-strncasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-strncasecmp.Tpo $(DEPDIR)/libgnu_a-c-strncasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-strncasecmp.c' object='libgnu_a-c-strncasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-strncasecmp.o `test -f 'c-strncasecmp.c' || echo '$(srcdir)/'`c-strncasecmp.c + +libgnu_a-c-strncasecmp.obj: c-strncasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-strncasecmp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-c-strncasecmp.Tpo -c -o libgnu_a-c-strncasecmp.obj `if test -f 'c-strncasecmp.c'; then $(CYGPATH_W) 'c-strncasecmp.c'; else $(CYGPATH_W) '$(srcdir)/c-strncasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-strncasecmp.Tpo $(DEPDIR)/libgnu_a-c-strncasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-strncasecmp.c' object='libgnu_a-c-strncasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-strncasecmp.obj `if test -f 'c-strncasecmp.c'; then $(CYGPATH_W) 'c-strncasecmp.c'; else $(CYGPATH_W) '$(srcdir)/c-strncasecmp.c'; fi` + +libgnu_a-c-strcasestr.o: c-strcasestr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-strcasestr.o -MD -MP -MF $(DEPDIR)/libgnu_a-c-strcasestr.Tpo -c -o libgnu_a-c-strcasestr.o `test -f 'c-strcasestr.c' || echo '$(srcdir)/'`c-strcasestr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-strcasestr.Tpo $(DEPDIR)/libgnu_a-c-strcasestr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-strcasestr.c' object='libgnu_a-c-strcasestr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-strcasestr.o `test -f 'c-strcasestr.c' || echo '$(srcdir)/'`c-strcasestr.c + +libgnu_a-c-strcasestr.obj: c-strcasestr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-c-strcasestr.obj -MD -MP -MF $(DEPDIR)/libgnu_a-c-strcasestr.Tpo -c -o libgnu_a-c-strcasestr.obj `if test -f 'c-strcasestr.c'; then $(CYGPATH_W) 'c-strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/c-strcasestr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-c-strcasestr.Tpo $(DEPDIR)/libgnu_a-c-strcasestr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='c-strcasestr.c' object='libgnu_a-c-strcasestr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-c-strcasestr.obj `if test -f 'c-strcasestr.c'; then $(CYGPATH_W) 'c-strcasestr.c'; else $(CYGPATH_W) '$(srcdir)/c-strcasestr.c'; fi` + +libgnu_a-canonicalize.o: canonicalize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-canonicalize.o -MD -MP -MF $(DEPDIR)/libgnu_a-canonicalize.Tpo -c -o libgnu_a-canonicalize.o `test -f 'canonicalize.c' || echo '$(srcdir)/'`canonicalize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-canonicalize.Tpo $(DEPDIR)/libgnu_a-canonicalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='canonicalize.c' object='libgnu_a-canonicalize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-canonicalize.o `test -f 'canonicalize.c' || echo '$(srcdir)/'`canonicalize.c + +libgnu_a-canonicalize.obj: canonicalize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-canonicalize.obj -MD -MP -MF $(DEPDIR)/libgnu_a-canonicalize.Tpo -c -o libgnu_a-canonicalize.obj `if test -f 'canonicalize.c'; then $(CYGPATH_W) 'canonicalize.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-canonicalize.Tpo $(DEPDIR)/libgnu_a-canonicalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='canonicalize.c' object='libgnu_a-canonicalize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-canonicalize.obj `if test -f 'canonicalize.c'; then $(CYGPATH_W) 'canonicalize.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize.c'; fi` + +libgnu_a-canonicalize-lgpl.o: canonicalize-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-canonicalize-lgpl.o -MD -MP -MF $(DEPDIR)/libgnu_a-canonicalize-lgpl.Tpo -c -o libgnu_a-canonicalize-lgpl.o `test -f 'canonicalize-lgpl.c' || echo '$(srcdir)/'`canonicalize-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-canonicalize-lgpl.Tpo $(DEPDIR)/libgnu_a-canonicalize-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='canonicalize-lgpl.c' object='libgnu_a-canonicalize-lgpl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-canonicalize-lgpl.o `test -f 'canonicalize-lgpl.c' || echo '$(srcdir)/'`canonicalize-lgpl.c + +libgnu_a-canonicalize-lgpl.obj: canonicalize-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-canonicalize-lgpl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-canonicalize-lgpl.Tpo -c -o libgnu_a-canonicalize-lgpl.obj `if test -f 'canonicalize-lgpl.c'; then $(CYGPATH_W) 'canonicalize-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize-lgpl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-canonicalize-lgpl.Tpo $(DEPDIR)/libgnu_a-canonicalize-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='canonicalize-lgpl.c' object='libgnu_a-canonicalize-lgpl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-canonicalize-lgpl.obj `if test -f 'canonicalize-lgpl.c'; then $(CYGPATH_W) 'canonicalize-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize-lgpl.c'; fi` + +libgnu_a-chdir-long.o: chdir-long.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-chdir-long.o -MD -MP -MF $(DEPDIR)/libgnu_a-chdir-long.Tpo -c -o libgnu_a-chdir-long.o `test -f 'chdir-long.c' || echo '$(srcdir)/'`chdir-long.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-chdir-long.Tpo $(DEPDIR)/libgnu_a-chdir-long.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chdir-long.c' object='libgnu_a-chdir-long.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-chdir-long.o `test -f 'chdir-long.c' || echo '$(srcdir)/'`chdir-long.c + +libgnu_a-chdir-long.obj: chdir-long.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-chdir-long.obj -MD -MP -MF $(DEPDIR)/libgnu_a-chdir-long.Tpo -c -o libgnu_a-chdir-long.obj `if test -f 'chdir-long.c'; then $(CYGPATH_W) 'chdir-long.c'; else $(CYGPATH_W) '$(srcdir)/chdir-long.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-chdir-long.Tpo $(DEPDIR)/libgnu_a-chdir-long.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chdir-long.c' object='libgnu_a-chdir-long.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-chdir-long.obj `if test -f 'chdir-long.c'; then $(CYGPATH_W) 'chdir-long.c'; else $(CYGPATH_W) '$(srcdir)/chdir-long.c'; fi` + +libgnu_a-cloexec.o: cloexec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-cloexec.o -MD -MP -MF $(DEPDIR)/libgnu_a-cloexec.Tpo -c -o libgnu_a-cloexec.o `test -f 'cloexec.c' || echo '$(srcdir)/'`cloexec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-cloexec.Tpo $(DEPDIR)/libgnu_a-cloexec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cloexec.c' object='libgnu_a-cloexec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-cloexec.o `test -f 'cloexec.c' || echo '$(srcdir)/'`cloexec.c + +libgnu_a-cloexec.obj: cloexec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-cloexec.obj -MD -MP -MF $(DEPDIR)/libgnu_a-cloexec.Tpo -c -o libgnu_a-cloexec.obj `if test -f 'cloexec.c'; then $(CYGPATH_W) 'cloexec.c'; else $(CYGPATH_W) '$(srcdir)/cloexec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-cloexec.Tpo $(DEPDIR)/libgnu_a-cloexec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cloexec.c' object='libgnu_a-cloexec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-cloexec.obj `if test -f 'cloexec.c'; then $(CYGPATH_W) 'cloexec.c'; else $(CYGPATH_W) '$(srcdir)/cloexec.c'; fi` + +libgnu_a-close.o: close.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-close.o -MD -MP -MF $(DEPDIR)/libgnu_a-close.Tpo -c -o libgnu_a-close.o `test -f 'close.c' || echo '$(srcdir)/'`close.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-close.Tpo $(DEPDIR)/libgnu_a-close.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='close.c' object='libgnu_a-close.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-close.o `test -f 'close.c' || echo '$(srcdir)/'`close.c + +libgnu_a-close.obj: close.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-close.obj -MD -MP -MF $(DEPDIR)/libgnu_a-close.Tpo -c -o libgnu_a-close.obj `if test -f 'close.c'; then $(CYGPATH_W) 'close.c'; else $(CYGPATH_W) '$(srcdir)/close.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-close.Tpo $(DEPDIR)/libgnu_a-close.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='close.c' object='libgnu_a-close.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-close.obj `if test -f 'close.c'; then $(CYGPATH_W) 'close.c'; else $(CYGPATH_W) '$(srcdir)/close.c'; fi` + +libgnu_a-closedir.o: closedir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-closedir.o -MD -MP -MF $(DEPDIR)/libgnu_a-closedir.Tpo -c -o libgnu_a-closedir.o `test -f 'closedir.c' || echo '$(srcdir)/'`closedir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-closedir.Tpo $(DEPDIR)/libgnu_a-closedir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='closedir.c' object='libgnu_a-closedir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-closedir.o `test -f 'closedir.c' || echo '$(srcdir)/'`closedir.c + +libgnu_a-closedir.obj: closedir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-closedir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-closedir.Tpo -c -o libgnu_a-closedir.obj `if test -f 'closedir.c'; then $(CYGPATH_W) 'closedir.c'; else $(CYGPATH_W) '$(srcdir)/closedir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-closedir.Tpo $(DEPDIR)/libgnu_a-closedir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='closedir.c' object='libgnu_a-closedir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-closedir.obj `if test -f 'closedir.c'; then $(CYGPATH_W) 'closedir.c'; else $(CYGPATH_W) '$(srcdir)/closedir.c'; fi` + +libgnu_a-concat-filename.o: concat-filename.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-concat-filename.o -MD -MP -MF $(DEPDIR)/libgnu_a-concat-filename.Tpo -c -o libgnu_a-concat-filename.o `test -f 'concat-filename.c' || echo '$(srcdir)/'`concat-filename.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-concat-filename.Tpo $(DEPDIR)/libgnu_a-concat-filename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='concat-filename.c' object='libgnu_a-concat-filename.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-concat-filename.o `test -f 'concat-filename.c' || echo '$(srcdir)/'`concat-filename.c + +libgnu_a-concat-filename.obj: concat-filename.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-concat-filename.obj -MD -MP -MF $(DEPDIR)/libgnu_a-concat-filename.Tpo -c -o libgnu_a-concat-filename.obj `if test -f 'concat-filename.c'; then $(CYGPATH_W) 'concat-filename.c'; else $(CYGPATH_W) '$(srcdir)/concat-filename.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-concat-filename.Tpo $(DEPDIR)/libgnu_a-concat-filename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='concat-filename.c' object='libgnu_a-concat-filename.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-concat-filename.obj `if test -f 'concat-filename.c'; then $(CYGPATH_W) 'concat-filename.c'; else $(CYGPATH_W) '$(srcdir)/concat-filename.c'; fi` + +libgnu_a-connect.o: connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-connect.o -MD -MP -MF $(DEPDIR)/libgnu_a-connect.Tpo -c -o libgnu_a-connect.o `test -f 'connect.c' || echo '$(srcdir)/'`connect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-connect.Tpo $(DEPDIR)/libgnu_a-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='connect.c' object='libgnu_a-connect.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-connect.o `test -f 'connect.c' || echo '$(srcdir)/'`connect.c + +libgnu_a-connect.obj: connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-connect.obj -MD -MP -MF $(DEPDIR)/libgnu_a-connect.Tpo -c -o libgnu_a-connect.obj `if test -f 'connect.c'; then $(CYGPATH_W) 'connect.c'; else $(CYGPATH_W) '$(srcdir)/connect.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-connect.Tpo $(DEPDIR)/libgnu_a-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='connect.c' object='libgnu_a-connect.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-connect.obj `if test -f 'connect.c'; then $(CYGPATH_W) 'connect.c'; else $(CYGPATH_W) '$(srcdir)/connect.c'; fi` + +libgnu_a-af_alg.o: af_alg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-af_alg.o -MD -MP -MF $(DEPDIR)/libgnu_a-af_alg.Tpo -c -o libgnu_a-af_alg.o `test -f 'af_alg.c' || echo '$(srcdir)/'`af_alg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-af_alg.Tpo $(DEPDIR)/libgnu_a-af_alg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='af_alg.c' object='libgnu_a-af_alg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-af_alg.o `test -f 'af_alg.c' || echo '$(srcdir)/'`af_alg.c + +libgnu_a-af_alg.obj: af_alg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-af_alg.obj -MD -MP -MF $(DEPDIR)/libgnu_a-af_alg.Tpo -c -o libgnu_a-af_alg.obj `if test -f 'af_alg.c'; then $(CYGPATH_W) 'af_alg.c'; else $(CYGPATH_W) '$(srcdir)/af_alg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-af_alg.Tpo $(DEPDIR)/libgnu_a-af_alg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='af_alg.c' object='libgnu_a-af_alg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-af_alg.obj `if test -f 'af_alg.c'; then $(CYGPATH_W) 'af_alg.c'; else $(CYGPATH_W) '$(srcdir)/af_alg.c'; fi` + +libgnu_a-md2-stream.o: md2-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md2-stream.o -MD -MP -MF $(DEPDIR)/libgnu_a-md2-stream.Tpo -c -o libgnu_a-md2-stream.o `test -f 'md2-stream.c' || echo '$(srcdir)/'`md2-stream.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md2-stream.Tpo $(DEPDIR)/libgnu_a-md2-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md2-stream.c' object='libgnu_a-md2-stream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md2-stream.o `test -f 'md2-stream.c' || echo '$(srcdir)/'`md2-stream.c + +libgnu_a-md2-stream.obj: md2-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md2-stream.obj -MD -MP -MF $(DEPDIR)/libgnu_a-md2-stream.Tpo -c -o libgnu_a-md2-stream.obj `if test -f 'md2-stream.c'; then $(CYGPATH_W) 'md2-stream.c'; else $(CYGPATH_W) '$(srcdir)/md2-stream.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md2-stream.Tpo $(DEPDIR)/libgnu_a-md2-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md2-stream.c' object='libgnu_a-md2-stream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md2-stream.obj `if test -f 'md2-stream.c'; then $(CYGPATH_W) 'md2-stream.c'; else $(CYGPATH_W) '$(srcdir)/md2-stream.c'; fi` + +libgnu_a-md2.o: md2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md2.o -MD -MP -MF $(DEPDIR)/libgnu_a-md2.Tpo -c -o libgnu_a-md2.o `test -f 'md2.c' || echo '$(srcdir)/'`md2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md2.Tpo $(DEPDIR)/libgnu_a-md2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md2.c' object='libgnu_a-md2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md2.o `test -f 'md2.c' || echo '$(srcdir)/'`md2.c + +libgnu_a-md2.obj: md2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md2.obj -MD -MP -MF $(DEPDIR)/libgnu_a-md2.Tpo -c -o libgnu_a-md2.obj `if test -f 'md2.c'; then $(CYGPATH_W) 'md2.c'; else $(CYGPATH_W) '$(srcdir)/md2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md2.Tpo $(DEPDIR)/libgnu_a-md2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md2.c' object='libgnu_a-md2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md2.obj `if test -f 'md2.c'; then $(CYGPATH_W) 'md2.c'; else $(CYGPATH_W) '$(srcdir)/md2.c'; fi` + +libgnu_a-md4-stream.o: md4-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md4-stream.o -MD -MP -MF $(DEPDIR)/libgnu_a-md4-stream.Tpo -c -o libgnu_a-md4-stream.o `test -f 'md4-stream.c' || echo '$(srcdir)/'`md4-stream.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md4-stream.Tpo $(DEPDIR)/libgnu_a-md4-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md4-stream.c' object='libgnu_a-md4-stream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md4-stream.o `test -f 'md4-stream.c' || echo '$(srcdir)/'`md4-stream.c + +libgnu_a-md4-stream.obj: md4-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md4-stream.obj -MD -MP -MF $(DEPDIR)/libgnu_a-md4-stream.Tpo -c -o libgnu_a-md4-stream.obj `if test -f 'md4-stream.c'; then $(CYGPATH_W) 'md4-stream.c'; else $(CYGPATH_W) '$(srcdir)/md4-stream.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md4-stream.Tpo $(DEPDIR)/libgnu_a-md4-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md4-stream.c' object='libgnu_a-md4-stream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md4-stream.obj `if test -f 'md4-stream.c'; then $(CYGPATH_W) 'md4-stream.c'; else $(CYGPATH_W) '$(srcdir)/md4-stream.c'; fi` + +libgnu_a-md4.o: md4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md4.o -MD -MP -MF $(DEPDIR)/libgnu_a-md4.Tpo -c -o libgnu_a-md4.o `test -f 'md4.c' || echo '$(srcdir)/'`md4.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md4.Tpo $(DEPDIR)/libgnu_a-md4.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md4.c' object='libgnu_a-md4.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md4.o `test -f 'md4.c' || echo '$(srcdir)/'`md4.c + +libgnu_a-md4.obj: md4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md4.obj -MD -MP -MF $(DEPDIR)/libgnu_a-md4.Tpo -c -o libgnu_a-md4.obj `if test -f 'md4.c'; then $(CYGPATH_W) 'md4.c'; else $(CYGPATH_W) '$(srcdir)/md4.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md4.Tpo $(DEPDIR)/libgnu_a-md4.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md4.c' object='libgnu_a-md4.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md4.obj `if test -f 'md4.c'; then $(CYGPATH_W) 'md4.c'; else $(CYGPATH_W) '$(srcdir)/md4.c'; fi` + +libgnu_a-md5-stream.o: md5-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md5-stream.o -MD -MP -MF $(DEPDIR)/libgnu_a-md5-stream.Tpo -c -o libgnu_a-md5-stream.o `test -f 'md5-stream.c' || echo '$(srcdir)/'`md5-stream.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md5-stream.Tpo $(DEPDIR)/libgnu_a-md5-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5-stream.c' object='libgnu_a-md5-stream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md5-stream.o `test -f 'md5-stream.c' || echo '$(srcdir)/'`md5-stream.c + +libgnu_a-md5-stream.obj: md5-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md5-stream.obj -MD -MP -MF $(DEPDIR)/libgnu_a-md5-stream.Tpo -c -o libgnu_a-md5-stream.obj `if test -f 'md5-stream.c'; then $(CYGPATH_W) 'md5-stream.c'; else $(CYGPATH_W) '$(srcdir)/md5-stream.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md5-stream.Tpo $(DEPDIR)/libgnu_a-md5-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5-stream.c' object='libgnu_a-md5-stream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md5-stream.obj `if test -f 'md5-stream.c'; then $(CYGPATH_W) 'md5-stream.c'; else $(CYGPATH_W) '$(srcdir)/md5-stream.c'; fi` + +libgnu_a-md5.o: md5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md5.o -MD -MP -MF $(DEPDIR)/libgnu_a-md5.Tpo -c -o libgnu_a-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md5.Tpo $(DEPDIR)/libgnu_a-md5.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='libgnu_a-md5.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c + +libgnu_a-md5.obj: md5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-md5.obj -MD -MP -MF $(DEPDIR)/libgnu_a-md5.Tpo -c -o libgnu_a-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-md5.Tpo $(DEPDIR)/libgnu_a-md5.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='libgnu_a-md5.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi` + +libgnu_a-sha1-stream.o: sha1-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha1-stream.o -MD -MP -MF $(DEPDIR)/libgnu_a-sha1-stream.Tpo -c -o libgnu_a-sha1-stream.o `test -f 'sha1-stream.c' || echo '$(srcdir)/'`sha1-stream.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha1-stream.Tpo $(DEPDIR)/libgnu_a-sha1-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1-stream.c' object='libgnu_a-sha1-stream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha1-stream.o `test -f 'sha1-stream.c' || echo '$(srcdir)/'`sha1-stream.c + +libgnu_a-sha1-stream.obj: sha1-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha1-stream.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sha1-stream.Tpo -c -o libgnu_a-sha1-stream.obj `if test -f 'sha1-stream.c'; then $(CYGPATH_W) 'sha1-stream.c'; else $(CYGPATH_W) '$(srcdir)/sha1-stream.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha1-stream.Tpo $(DEPDIR)/libgnu_a-sha1-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1-stream.c' object='libgnu_a-sha1-stream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha1-stream.obj `if test -f 'sha1-stream.c'; then $(CYGPATH_W) 'sha1-stream.c'; else $(CYGPATH_W) '$(srcdir)/sha1-stream.c'; fi` + +libgnu_a-sha1.o: sha1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha1.o -MD -MP -MF $(DEPDIR)/libgnu_a-sha1.Tpo -c -o libgnu_a-sha1.o `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha1.Tpo $(DEPDIR)/libgnu_a-sha1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1.c' object='libgnu_a-sha1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha1.o `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c + +libgnu_a-sha1.obj: sha1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha1.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sha1.Tpo -c -o libgnu_a-sha1.obj `if test -f 'sha1.c'; then $(CYGPATH_W) 'sha1.c'; else $(CYGPATH_W) '$(srcdir)/sha1.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha1.Tpo $(DEPDIR)/libgnu_a-sha1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1.c' object='libgnu_a-sha1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha1.obj `if test -f 'sha1.c'; then $(CYGPATH_W) 'sha1.c'; else $(CYGPATH_W) '$(srcdir)/sha1.c'; fi` + +libgnu_a-sha256-stream.o: sha256-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha256-stream.o -MD -MP -MF $(DEPDIR)/libgnu_a-sha256-stream.Tpo -c -o libgnu_a-sha256-stream.o `test -f 'sha256-stream.c' || echo '$(srcdir)/'`sha256-stream.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha256-stream.Tpo $(DEPDIR)/libgnu_a-sha256-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha256-stream.c' object='libgnu_a-sha256-stream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha256-stream.o `test -f 'sha256-stream.c' || echo '$(srcdir)/'`sha256-stream.c + +libgnu_a-sha256-stream.obj: sha256-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha256-stream.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sha256-stream.Tpo -c -o libgnu_a-sha256-stream.obj `if test -f 'sha256-stream.c'; then $(CYGPATH_W) 'sha256-stream.c'; else $(CYGPATH_W) '$(srcdir)/sha256-stream.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha256-stream.Tpo $(DEPDIR)/libgnu_a-sha256-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha256-stream.c' object='libgnu_a-sha256-stream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha256-stream.obj `if test -f 'sha256-stream.c'; then $(CYGPATH_W) 'sha256-stream.c'; else $(CYGPATH_W) '$(srcdir)/sha256-stream.c'; fi` + +libgnu_a-sha256.o: sha256.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha256.o -MD -MP -MF $(DEPDIR)/libgnu_a-sha256.Tpo -c -o libgnu_a-sha256.o `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha256.Tpo $(DEPDIR)/libgnu_a-sha256.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha256.c' object='libgnu_a-sha256.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha256.o `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c + +libgnu_a-sha256.obj: sha256.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha256.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sha256.Tpo -c -o libgnu_a-sha256.obj `if test -f 'sha256.c'; then $(CYGPATH_W) 'sha256.c'; else $(CYGPATH_W) '$(srcdir)/sha256.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha256.Tpo $(DEPDIR)/libgnu_a-sha256.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha256.c' object='libgnu_a-sha256.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha256.obj `if test -f 'sha256.c'; then $(CYGPATH_W) 'sha256.c'; else $(CYGPATH_W) '$(srcdir)/sha256.c'; fi` + +libgnu_a-sha512-stream.o: sha512-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha512-stream.o -MD -MP -MF $(DEPDIR)/libgnu_a-sha512-stream.Tpo -c -o libgnu_a-sha512-stream.o `test -f 'sha512-stream.c' || echo '$(srcdir)/'`sha512-stream.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha512-stream.Tpo $(DEPDIR)/libgnu_a-sha512-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha512-stream.c' object='libgnu_a-sha512-stream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha512-stream.o `test -f 'sha512-stream.c' || echo '$(srcdir)/'`sha512-stream.c + +libgnu_a-sha512-stream.obj: sha512-stream.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha512-stream.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sha512-stream.Tpo -c -o libgnu_a-sha512-stream.obj `if test -f 'sha512-stream.c'; then $(CYGPATH_W) 'sha512-stream.c'; else $(CYGPATH_W) '$(srcdir)/sha512-stream.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha512-stream.Tpo $(DEPDIR)/libgnu_a-sha512-stream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha512-stream.c' object='libgnu_a-sha512-stream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha512-stream.obj `if test -f 'sha512-stream.c'; then $(CYGPATH_W) 'sha512-stream.c'; else $(CYGPATH_W) '$(srcdir)/sha512-stream.c'; fi` + +libgnu_a-sha512.o: sha512.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha512.o -MD -MP -MF $(DEPDIR)/libgnu_a-sha512.Tpo -c -o libgnu_a-sha512.o `test -f 'sha512.c' || echo '$(srcdir)/'`sha512.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha512.Tpo $(DEPDIR)/libgnu_a-sha512.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha512.c' object='libgnu_a-sha512.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha512.o `test -f 'sha512.c' || echo '$(srcdir)/'`sha512.c + +libgnu_a-sha512.obj: sha512.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sha512.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sha512.Tpo -c -o libgnu_a-sha512.obj `if test -f 'sha512.c'; then $(CYGPATH_W) 'sha512.c'; else $(CYGPATH_W) '$(srcdir)/sha512.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sha512.Tpo $(DEPDIR)/libgnu_a-sha512.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha512.c' object='libgnu_a-sha512.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sha512.obj `if test -f 'sha512.c'; then $(CYGPATH_W) 'sha512.c'; else $(CYGPATH_W) '$(srcdir)/sha512.c'; fi` + +libgnu_a-dirfd.o: dirfd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dirfd.o -MD -MP -MF $(DEPDIR)/libgnu_a-dirfd.Tpo -c -o libgnu_a-dirfd.o `test -f 'dirfd.c' || echo '$(srcdir)/'`dirfd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dirfd.Tpo $(DEPDIR)/libgnu_a-dirfd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dirfd.c' object='libgnu_a-dirfd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dirfd.o `test -f 'dirfd.c' || echo '$(srcdir)/'`dirfd.c + +libgnu_a-dirfd.obj: dirfd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dirfd.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dirfd.Tpo -c -o libgnu_a-dirfd.obj `if test -f 'dirfd.c'; then $(CYGPATH_W) 'dirfd.c'; else $(CYGPATH_W) '$(srcdir)/dirfd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dirfd.Tpo $(DEPDIR)/libgnu_a-dirfd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dirfd.c' object='libgnu_a-dirfd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dirfd.obj `if test -f 'dirfd.c'; then $(CYGPATH_W) 'dirfd.c'; else $(CYGPATH_W) '$(srcdir)/dirfd.c'; fi` + +libgnu_a-dirname.o: dirname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dirname.o -MD -MP -MF $(DEPDIR)/libgnu_a-dirname.Tpo -c -o libgnu_a-dirname.o `test -f 'dirname.c' || echo '$(srcdir)/'`dirname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dirname.Tpo $(DEPDIR)/libgnu_a-dirname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dirname.c' object='libgnu_a-dirname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dirname.o `test -f 'dirname.c' || echo '$(srcdir)/'`dirname.c + +libgnu_a-dirname.obj: dirname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dirname.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dirname.Tpo -c -o libgnu_a-dirname.obj `if test -f 'dirname.c'; then $(CYGPATH_W) 'dirname.c'; else $(CYGPATH_W) '$(srcdir)/dirname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dirname.Tpo $(DEPDIR)/libgnu_a-dirname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dirname.c' object='libgnu_a-dirname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dirname.obj `if test -f 'dirname.c'; then $(CYGPATH_W) 'dirname.c'; else $(CYGPATH_W) '$(srcdir)/dirname.c'; fi` + +libgnu_a-basename.o: basename.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-basename.o -MD -MP -MF $(DEPDIR)/libgnu_a-basename.Tpo -c -o libgnu_a-basename.o `test -f 'basename.c' || echo '$(srcdir)/'`basename.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-basename.Tpo $(DEPDIR)/libgnu_a-basename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='basename.c' object='libgnu_a-basename.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-basename.o `test -f 'basename.c' || echo '$(srcdir)/'`basename.c + +libgnu_a-basename.obj: basename.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-basename.obj -MD -MP -MF $(DEPDIR)/libgnu_a-basename.Tpo -c -o libgnu_a-basename.obj `if test -f 'basename.c'; then $(CYGPATH_W) 'basename.c'; else $(CYGPATH_W) '$(srcdir)/basename.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-basename.Tpo $(DEPDIR)/libgnu_a-basename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='basename.c' object='libgnu_a-basename.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-basename.obj `if test -f 'basename.c'; then $(CYGPATH_W) 'basename.c'; else $(CYGPATH_W) '$(srcdir)/basename.c'; fi` + +libgnu_a-dirname-lgpl.o: dirname-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dirname-lgpl.o -MD -MP -MF $(DEPDIR)/libgnu_a-dirname-lgpl.Tpo -c -o libgnu_a-dirname-lgpl.o `test -f 'dirname-lgpl.c' || echo '$(srcdir)/'`dirname-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dirname-lgpl.Tpo $(DEPDIR)/libgnu_a-dirname-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dirname-lgpl.c' object='libgnu_a-dirname-lgpl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dirname-lgpl.o `test -f 'dirname-lgpl.c' || echo '$(srcdir)/'`dirname-lgpl.c + +libgnu_a-dirname-lgpl.obj: dirname-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dirname-lgpl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dirname-lgpl.Tpo -c -o libgnu_a-dirname-lgpl.obj `if test -f 'dirname-lgpl.c'; then $(CYGPATH_W) 'dirname-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/dirname-lgpl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dirname-lgpl.Tpo $(DEPDIR)/libgnu_a-dirname-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dirname-lgpl.c' object='libgnu_a-dirname-lgpl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dirname-lgpl.obj `if test -f 'dirname-lgpl.c'; then $(CYGPATH_W) 'dirname-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/dirname-lgpl.c'; fi` + +libgnu_a-stripslash.o: stripslash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stripslash.o -MD -MP -MF $(DEPDIR)/libgnu_a-stripslash.Tpo -c -o libgnu_a-stripslash.o `test -f 'stripslash.c' || echo '$(srcdir)/'`stripslash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stripslash.Tpo $(DEPDIR)/libgnu_a-stripslash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stripslash.c' object='libgnu_a-stripslash.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stripslash.o `test -f 'stripslash.c' || echo '$(srcdir)/'`stripslash.c + +libgnu_a-stripslash.obj: stripslash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stripslash.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stripslash.Tpo -c -o libgnu_a-stripslash.obj `if test -f 'stripslash.c'; then $(CYGPATH_W) 'stripslash.c'; else $(CYGPATH_W) '$(srcdir)/stripslash.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stripslash.Tpo $(DEPDIR)/libgnu_a-stripslash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stripslash.c' object='libgnu_a-stripslash.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stripslash.obj `if test -f 'stripslash.c'; then $(CYGPATH_W) 'stripslash.c'; else $(CYGPATH_W) '$(srcdir)/stripslash.c'; fi` + +libgnu_a-dup.o: dup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup.o -MD -MP -MF $(DEPDIR)/libgnu_a-dup.Tpo -c -o libgnu_a-dup.o `test -f 'dup.c' || echo '$(srcdir)/'`dup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup.Tpo $(DEPDIR)/libgnu_a-dup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup.c' object='libgnu_a-dup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup.o `test -f 'dup.c' || echo '$(srcdir)/'`dup.c + +libgnu_a-dup.obj: dup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dup.Tpo -c -o libgnu_a-dup.obj `if test -f 'dup.c'; then $(CYGPATH_W) 'dup.c'; else $(CYGPATH_W) '$(srcdir)/dup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup.Tpo $(DEPDIR)/libgnu_a-dup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup.c' object='libgnu_a-dup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup.obj `if test -f 'dup.c'; then $(CYGPATH_W) 'dup.c'; else $(CYGPATH_W) '$(srcdir)/dup.c'; fi` + +libgnu_a-dup2.o: dup2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup2.o -MD -MP -MF $(DEPDIR)/libgnu_a-dup2.Tpo -c -o libgnu_a-dup2.o `test -f 'dup2.c' || echo '$(srcdir)/'`dup2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup2.Tpo $(DEPDIR)/libgnu_a-dup2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup2.c' object='libgnu_a-dup2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup2.o `test -f 'dup2.c' || echo '$(srcdir)/'`dup2.c + +libgnu_a-dup2.obj: dup2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup2.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dup2.Tpo -c -o libgnu_a-dup2.obj `if test -f 'dup2.c'; then $(CYGPATH_W) 'dup2.c'; else $(CYGPATH_W) '$(srcdir)/dup2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup2.Tpo $(DEPDIR)/libgnu_a-dup2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup2.c' object='libgnu_a-dup2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup2.obj `if test -f 'dup2.c'; then $(CYGPATH_W) 'dup2.c'; else $(CYGPATH_W) '$(srcdir)/dup2.c'; fi` + +malloc/libgnu_a-dynarray_at_failure.o: malloc/dynarray_at_failure.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_at_failure.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Tpo -c -o malloc/libgnu_a-dynarray_at_failure.o `test -f 'malloc/dynarray_at_failure.c' || echo '$(srcdir)/'`malloc/dynarray_at_failure.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_at_failure.c' object='malloc/libgnu_a-dynarray_at_failure.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_at_failure.o `test -f 'malloc/dynarray_at_failure.c' || echo '$(srcdir)/'`malloc/dynarray_at_failure.c + +malloc/libgnu_a-dynarray_at_failure.obj: malloc/dynarray_at_failure.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_at_failure.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Tpo -c -o malloc/libgnu_a-dynarray_at_failure.obj `if test -f 'malloc/dynarray_at_failure.c'; then $(CYGPATH_W) 'malloc/dynarray_at_failure.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_at_failure.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_at_failure.c' object='malloc/libgnu_a-dynarray_at_failure.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_at_failure.obj `if test -f 'malloc/dynarray_at_failure.c'; then $(CYGPATH_W) 'malloc/dynarray_at_failure.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_at_failure.c'; fi` + +malloc/libgnu_a-dynarray_emplace_enlarge.o: malloc/dynarray_emplace_enlarge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_emplace_enlarge.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Tpo -c -o malloc/libgnu_a-dynarray_emplace_enlarge.o `test -f 'malloc/dynarray_emplace_enlarge.c' || echo '$(srcdir)/'`malloc/dynarray_emplace_enlarge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_emplace_enlarge.c' object='malloc/libgnu_a-dynarray_emplace_enlarge.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_emplace_enlarge.o `test -f 'malloc/dynarray_emplace_enlarge.c' || echo '$(srcdir)/'`malloc/dynarray_emplace_enlarge.c + +malloc/libgnu_a-dynarray_emplace_enlarge.obj: malloc/dynarray_emplace_enlarge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_emplace_enlarge.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Tpo -c -o malloc/libgnu_a-dynarray_emplace_enlarge.obj `if test -f 'malloc/dynarray_emplace_enlarge.c'; then $(CYGPATH_W) 'malloc/dynarray_emplace_enlarge.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_emplace_enlarge.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_emplace_enlarge.c' object='malloc/libgnu_a-dynarray_emplace_enlarge.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_emplace_enlarge.obj `if test -f 'malloc/dynarray_emplace_enlarge.c'; then $(CYGPATH_W) 'malloc/dynarray_emplace_enlarge.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_emplace_enlarge.c'; fi` + +malloc/libgnu_a-dynarray_finalize.o: malloc/dynarray_finalize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_finalize.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Tpo -c -o malloc/libgnu_a-dynarray_finalize.o `test -f 'malloc/dynarray_finalize.c' || echo '$(srcdir)/'`malloc/dynarray_finalize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_finalize.c' object='malloc/libgnu_a-dynarray_finalize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_finalize.o `test -f 'malloc/dynarray_finalize.c' || echo '$(srcdir)/'`malloc/dynarray_finalize.c + +malloc/libgnu_a-dynarray_finalize.obj: malloc/dynarray_finalize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_finalize.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Tpo -c -o malloc/libgnu_a-dynarray_finalize.obj `if test -f 'malloc/dynarray_finalize.c'; then $(CYGPATH_W) 'malloc/dynarray_finalize.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_finalize.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_finalize.c' object='malloc/libgnu_a-dynarray_finalize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_finalize.obj `if test -f 'malloc/dynarray_finalize.c'; then $(CYGPATH_W) 'malloc/dynarray_finalize.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_finalize.c'; fi` + +malloc/libgnu_a-dynarray_resize.o: malloc/dynarray_resize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_resize.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Tpo -c -o malloc/libgnu_a-dynarray_resize.o `test -f 'malloc/dynarray_resize.c' || echo '$(srcdir)/'`malloc/dynarray_resize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_resize.c' object='malloc/libgnu_a-dynarray_resize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_resize.o `test -f 'malloc/dynarray_resize.c' || echo '$(srcdir)/'`malloc/dynarray_resize.c + +malloc/libgnu_a-dynarray_resize.obj: malloc/dynarray_resize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_resize.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Tpo -c -o malloc/libgnu_a-dynarray_resize.obj `if test -f 'malloc/dynarray_resize.c'; then $(CYGPATH_W) 'malloc/dynarray_resize.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_resize.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_resize.c' object='malloc/libgnu_a-dynarray_resize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_resize.obj `if test -f 'malloc/dynarray_resize.c'; then $(CYGPATH_W) 'malloc/dynarray_resize.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_resize.c'; fi` + +malloc/libgnu_a-dynarray_resize_clear.o: malloc/dynarray_resize_clear.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_resize_clear.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Tpo -c -o malloc/libgnu_a-dynarray_resize_clear.o `test -f 'malloc/dynarray_resize_clear.c' || echo '$(srcdir)/'`malloc/dynarray_resize_clear.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_resize_clear.c' object='malloc/libgnu_a-dynarray_resize_clear.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_resize_clear.o `test -f 'malloc/dynarray_resize_clear.c' || echo '$(srcdir)/'`malloc/dynarray_resize_clear.c + +malloc/libgnu_a-dynarray_resize_clear.obj: malloc/dynarray_resize_clear.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray_resize_clear.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Tpo -c -o malloc/libgnu_a-dynarray_resize_clear.obj `if test -f 'malloc/dynarray_resize_clear.c'; then $(CYGPATH_W) 'malloc/dynarray_resize_clear.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_resize_clear.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray_resize_clear.c' object='malloc/libgnu_a-dynarray_resize_clear.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray_resize_clear.obj `if test -f 'malloc/dynarray_resize_clear.c'; then $(CYGPATH_W) 'malloc/dynarray_resize_clear.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray_resize_clear.c'; fi` + +libgnu_a-error.o: error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-error.o -MD -MP -MF $(DEPDIR)/libgnu_a-error.Tpo -c -o libgnu_a-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-error.Tpo $(DEPDIR)/libgnu_a-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='error.c' object='libgnu_a-error.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c + +libgnu_a-error.obj: error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-error.obj -MD -MP -MF $(DEPDIR)/libgnu_a-error.Tpo -c -o libgnu_a-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-error.Tpo $(DEPDIR)/libgnu_a-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='error.c' object='libgnu_a-error.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` + +libgnu_a-exitfail.o: exitfail.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-exitfail.o -MD -MP -MF $(DEPDIR)/libgnu_a-exitfail.Tpo -c -o libgnu_a-exitfail.o `test -f 'exitfail.c' || echo '$(srcdir)/'`exitfail.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-exitfail.Tpo $(DEPDIR)/libgnu_a-exitfail.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exitfail.c' object='libgnu_a-exitfail.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-exitfail.o `test -f 'exitfail.c' || echo '$(srcdir)/'`exitfail.c + +libgnu_a-exitfail.obj: exitfail.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-exitfail.obj -MD -MP -MF $(DEPDIR)/libgnu_a-exitfail.Tpo -c -o libgnu_a-exitfail.obj `if test -f 'exitfail.c'; then $(CYGPATH_W) 'exitfail.c'; else $(CYGPATH_W) '$(srcdir)/exitfail.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-exitfail.Tpo $(DEPDIR)/libgnu_a-exitfail.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exitfail.c' object='libgnu_a-exitfail.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-exitfail.obj `if test -f 'exitfail.c'; then $(CYGPATH_W) 'exitfail.c'; else $(CYGPATH_W) '$(srcdir)/exitfail.c'; fi` + +libgnu_a-fatal-signal.o: fatal-signal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fatal-signal.o -MD -MP -MF $(DEPDIR)/libgnu_a-fatal-signal.Tpo -c -o libgnu_a-fatal-signal.o `test -f 'fatal-signal.c' || echo '$(srcdir)/'`fatal-signal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fatal-signal.Tpo $(DEPDIR)/libgnu_a-fatal-signal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fatal-signal.c' object='libgnu_a-fatal-signal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fatal-signal.o `test -f 'fatal-signal.c' || echo '$(srcdir)/'`fatal-signal.c + +libgnu_a-fatal-signal.obj: fatal-signal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fatal-signal.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fatal-signal.Tpo -c -o libgnu_a-fatal-signal.obj `if test -f 'fatal-signal.c'; then $(CYGPATH_W) 'fatal-signal.c'; else $(CYGPATH_W) '$(srcdir)/fatal-signal.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fatal-signal.Tpo $(DEPDIR)/libgnu_a-fatal-signal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fatal-signal.c' object='libgnu_a-fatal-signal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fatal-signal.obj `if test -f 'fatal-signal.c'; then $(CYGPATH_W) 'fatal-signal.c'; else $(CYGPATH_W) '$(srcdir)/fatal-signal.c'; fi` + +libgnu_a-fchdir.o: fchdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fchdir.o -MD -MP -MF $(DEPDIR)/libgnu_a-fchdir.Tpo -c -o libgnu_a-fchdir.o `test -f 'fchdir.c' || echo '$(srcdir)/'`fchdir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fchdir.Tpo $(DEPDIR)/libgnu_a-fchdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fchdir.c' object='libgnu_a-fchdir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fchdir.o `test -f 'fchdir.c' || echo '$(srcdir)/'`fchdir.c + +libgnu_a-fchdir.obj: fchdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fchdir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fchdir.Tpo -c -o libgnu_a-fchdir.obj `if test -f 'fchdir.c'; then $(CYGPATH_W) 'fchdir.c'; else $(CYGPATH_W) '$(srcdir)/fchdir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fchdir.Tpo $(DEPDIR)/libgnu_a-fchdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fchdir.c' object='libgnu_a-fchdir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fchdir.obj `if test -f 'fchdir.c'; then $(CYGPATH_W) 'fchdir.c'; else $(CYGPATH_W) '$(srcdir)/fchdir.c'; fi` + +libgnu_a-fcntl.o: fcntl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fcntl.o -MD -MP -MF $(DEPDIR)/libgnu_a-fcntl.Tpo -c -o libgnu_a-fcntl.o `test -f 'fcntl.c' || echo '$(srcdir)/'`fcntl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fcntl.Tpo $(DEPDIR)/libgnu_a-fcntl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fcntl.c' object='libgnu_a-fcntl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fcntl.o `test -f 'fcntl.c' || echo '$(srcdir)/'`fcntl.c + +libgnu_a-fcntl.obj: fcntl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fcntl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fcntl.Tpo -c -o libgnu_a-fcntl.obj `if test -f 'fcntl.c'; then $(CYGPATH_W) 'fcntl.c'; else $(CYGPATH_W) '$(srcdir)/fcntl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fcntl.Tpo $(DEPDIR)/libgnu_a-fcntl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fcntl.c' object='libgnu_a-fcntl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fcntl.obj `if test -f 'fcntl.c'; then $(CYGPATH_W) 'fcntl.c'; else $(CYGPATH_W) '$(srcdir)/fcntl.c'; fi` + +libgnu_a-fd-hook.o: fd-hook.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fd-hook.o -MD -MP -MF $(DEPDIR)/libgnu_a-fd-hook.Tpo -c -o libgnu_a-fd-hook.o `test -f 'fd-hook.c' || echo '$(srcdir)/'`fd-hook.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fd-hook.Tpo $(DEPDIR)/libgnu_a-fd-hook.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fd-hook.c' object='libgnu_a-fd-hook.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fd-hook.o `test -f 'fd-hook.c' || echo '$(srcdir)/'`fd-hook.c + +libgnu_a-fd-hook.obj: fd-hook.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fd-hook.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fd-hook.Tpo -c -o libgnu_a-fd-hook.obj `if test -f 'fd-hook.c'; then $(CYGPATH_W) 'fd-hook.c'; else $(CYGPATH_W) '$(srcdir)/fd-hook.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fd-hook.Tpo $(DEPDIR)/libgnu_a-fd-hook.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fd-hook.c' object='libgnu_a-fd-hook.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fd-hook.obj `if test -f 'fd-hook.c'; then $(CYGPATH_W) 'fd-hook.c'; else $(CYGPATH_W) '$(srcdir)/fd-hook.c'; fi` + +libgnu_a-fd-safer-flag.o: fd-safer-flag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fd-safer-flag.o -MD -MP -MF $(DEPDIR)/libgnu_a-fd-safer-flag.Tpo -c -o libgnu_a-fd-safer-flag.o `test -f 'fd-safer-flag.c' || echo '$(srcdir)/'`fd-safer-flag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fd-safer-flag.Tpo $(DEPDIR)/libgnu_a-fd-safer-flag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fd-safer-flag.c' object='libgnu_a-fd-safer-flag.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fd-safer-flag.o `test -f 'fd-safer-flag.c' || echo '$(srcdir)/'`fd-safer-flag.c + +libgnu_a-fd-safer-flag.obj: fd-safer-flag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fd-safer-flag.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fd-safer-flag.Tpo -c -o libgnu_a-fd-safer-flag.obj `if test -f 'fd-safer-flag.c'; then $(CYGPATH_W) 'fd-safer-flag.c'; else $(CYGPATH_W) '$(srcdir)/fd-safer-flag.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fd-safer-flag.Tpo $(DEPDIR)/libgnu_a-fd-safer-flag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fd-safer-flag.c' object='libgnu_a-fd-safer-flag.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fd-safer-flag.obj `if test -f 'fd-safer-flag.c'; then $(CYGPATH_W) 'fd-safer-flag.c'; else $(CYGPATH_W) '$(srcdir)/fd-safer-flag.c'; fi` + +libgnu_a-dup-safer-flag.o: dup-safer-flag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup-safer-flag.o -MD -MP -MF $(DEPDIR)/libgnu_a-dup-safer-flag.Tpo -c -o libgnu_a-dup-safer-flag.o `test -f 'dup-safer-flag.c' || echo '$(srcdir)/'`dup-safer-flag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup-safer-flag.Tpo $(DEPDIR)/libgnu_a-dup-safer-flag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup-safer-flag.c' object='libgnu_a-dup-safer-flag.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup-safer-flag.o `test -f 'dup-safer-flag.c' || echo '$(srcdir)/'`dup-safer-flag.c + +libgnu_a-dup-safer-flag.obj: dup-safer-flag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup-safer-flag.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dup-safer-flag.Tpo -c -o libgnu_a-dup-safer-flag.obj `if test -f 'dup-safer-flag.c'; then $(CYGPATH_W) 'dup-safer-flag.c'; else $(CYGPATH_W) '$(srcdir)/dup-safer-flag.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup-safer-flag.Tpo $(DEPDIR)/libgnu_a-dup-safer-flag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup-safer-flag.c' object='libgnu_a-dup-safer-flag.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup-safer-flag.obj `if test -f 'dup-safer-flag.c'; then $(CYGPATH_W) 'dup-safer-flag.c'; else $(CYGPATH_W) '$(srcdir)/dup-safer-flag.c'; fi` + +libgnu_a-fdopendir.o: fdopendir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fdopendir.o -MD -MP -MF $(DEPDIR)/libgnu_a-fdopendir.Tpo -c -o libgnu_a-fdopendir.o `test -f 'fdopendir.c' || echo '$(srcdir)/'`fdopendir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fdopendir.Tpo $(DEPDIR)/libgnu_a-fdopendir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fdopendir.c' object='libgnu_a-fdopendir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fdopendir.o `test -f 'fdopendir.c' || echo '$(srcdir)/'`fdopendir.c + +libgnu_a-fdopendir.obj: fdopendir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fdopendir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fdopendir.Tpo -c -o libgnu_a-fdopendir.obj `if test -f 'fdopendir.c'; then $(CYGPATH_W) 'fdopendir.c'; else $(CYGPATH_W) '$(srcdir)/fdopendir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fdopendir.Tpo $(DEPDIR)/libgnu_a-fdopendir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fdopendir.c' object='libgnu_a-fdopendir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fdopendir.obj `if test -f 'fdopendir.c'; then $(CYGPATH_W) 'fdopendir.c'; else $(CYGPATH_W) '$(srcdir)/fdopendir.c'; fi` + +libgnu_a-fflush.o: fflush.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fflush.o -MD -MP -MF $(DEPDIR)/libgnu_a-fflush.Tpo -c -o libgnu_a-fflush.o `test -f 'fflush.c' || echo '$(srcdir)/'`fflush.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fflush.Tpo $(DEPDIR)/libgnu_a-fflush.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fflush.c' object='libgnu_a-fflush.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fflush.o `test -f 'fflush.c' || echo '$(srcdir)/'`fflush.c + +libgnu_a-fflush.obj: fflush.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fflush.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fflush.Tpo -c -o libgnu_a-fflush.obj `if test -f 'fflush.c'; then $(CYGPATH_W) 'fflush.c'; else $(CYGPATH_W) '$(srcdir)/fflush.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fflush.Tpo $(DEPDIR)/libgnu_a-fflush.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fflush.c' object='libgnu_a-fflush.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fflush.obj `if test -f 'fflush.c'; then $(CYGPATH_W) 'fflush.c'; else $(CYGPATH_W) '$(srcdir)/fflush.c'; fi` + +libgnu_a-file-set.o: file-set.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-file-set.o -MD -MP -MF $(DEPDIR)/libgnu_a-file-set.Tpo -c -o libgnu_a-file-set.o `test -f 'file-set.c' || echo '$(srcdir)/'`file-set.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-file-set.Tpo $(DEPDIR)/libgnu_a-file-set.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file-set.c' object='libgnu_a-file-set.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-file-set.o `test -f 'file-set.c' || echo '$(srcdir)/'`file-set.c + +libgnu_a-file-set.obj: file-set.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-file-set.obj -MD -MP -MF $(DEPDIR)/libgnu_a-file-set.Tpo -c -o libgnu_a-file-set.obj `if test -f 'file-set.c'; then $(CYGPATH_W) 'file-set.c'; else $(CYGPATH_W) '$(srcdir)/file-set.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-file-set.Tpo $(DEPDIR)/libgnu_a-file-set.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file-set.c' object='libgnu_a-file-set.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-file-set.obj `if test -f 'file-set.c'; then $(CYGPATH_W) 'file-set.c'; else $(CYGPATH_W) '$(srcdir)/file-set.c'; fi` + +libgnu_a-filenamecat-lgpl.o: filenamecat-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-filenamecat-lgpl.o -MD -MP -MF $(DEPDIR)/libgnu_a-filenamecat-lgpl.Tpo -c -o libgnu_a-filenamecat-lgpl.o `test -f 'filenamecat-lgpl.c' || echo '$(srcdir)/'`filenamecat-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-filenamecat-lgpl.Tpo $(DEPDIR)/libgnu_a-filenamecat-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filenamecat-lgpl.c' object='libgnu_a-filenamecat-lgpl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-filenamecat-lgpl.o `test -f 'filenamecat-lgpl.c' || echo '$(srcdir)/'`filenamecat-lgpl.c + +libgnu_a-filenamecat-lgpl.obj: filenamecat-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-filenamecat-lgpl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-filenamecat-lgpl.Tpo -c -o libgnu_a-filenamecat-lgpl.obj `if test -f 'filenamecat-lgpl.c'; then $(CYGPATH_W) 'filenamecat-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/filenamecat-lgpl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-filenamecat-lgpl.Tpo $(DEPDIR)/libgnu_a-filenamecat-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filenamecat-lgpl.c' object='libgnu_a-filenamecat-lgpl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-filenamecat-lgpl.obj `if test -f 'filenamecat-lgpl.c'; then $(CYGPATH_W) 'filenamecat-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/filenamecat-lgpl.c'; fi` + +libgnu_a-findprog-in.o: findprog-in.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-findprog-in.o -MD -MP -MF $(DEPDIR)/libgnu_a-findprog-in.Tpo -c -o libgnu_a-findprog-in.o `test -f 'findprog-in.c' || echo '$(srcdir)/'`findprog-in.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-findprog-in.Tpo $(DEPDIR)/libgnu_a-findprog-in.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='findprog-in.c' object='libgnu_a-findprog-in.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-findprog-in.o `test -f 'findprog-in.c' || echo '$(srcdir)/'`findprog-in.c + +libgnu_a-findprog-in.obj: findprog-in.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-findprog-in.obj -MD -MP -MF $(DEPDIR)/libgnu_a-findprog-in.Tpo -c -o libgnu_a-findprog-in.obj `if test -f 'findprog-in.c'; then $(CYGPATH_W) 'findprog-in.c'; else $(CYGPATH_W) '$(srcdir)/findprog-in.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-findprog-in.Tpo $(DEPDIR)/libgnu_a-findprog-in.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='findprog-in.c' object='libgnu_a-findprog-in.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-findprog-in.obj `if test -f 'findprog-in.c'; then $(CYGPATH_W) 'findprog-in.c'; else $(CYGPATH_W) '$(srcdir)/findprog-in.c'; fi` + +libgnu_a-float.o: float.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-float.o -MD -MP -MF $(DEPDIR)/libgnu_a-float.Tpo -c -o libgnu_a-float.o `test -f 'float.c' || echo '$(srcdir)/'`float.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-float.Tpo $(DEPDIR)/libgnu_a-float.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='float.c' object='libgnu_a-float.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-float.o `test -f 'float.c' || echo '$(srcdir)/'`float.c + +libgnu_a-float.obj: float.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-float.obj -MD -MP -MF $(DEPDIR)/libgnu_a-float.Tpo -c -o libgnu_a-float.obj `if test -f 'float.c'; then $(CYGPATH_W) 'float.c'; else $(CYGPATH_W) '$(srcdir)/float.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-float.Tpo $(DEPDIR)/libgnu_a-float.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='float.c' object='libgnu_a-float.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-float.obj `if test -f 'float.c'; then $(CYGPATH_W) 'float.c'; else $(CYGPATH_W) '$(srcdir)/float.c'; fi` + +libgnu_a-itold.o: itold.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-itold.o -MD -MP -MF $(DEPDIR)/libgnu_a-itold.Tpo -c -o libgnu_a-itold.o `test -f 'itold.c' || echo '$(srcdir)/'`itold.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-itold.Tpo $(DEPDIR)/libgnu_a-itold.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='itold.c' object='libgnu_a-itold.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-itold.o `test -f 'itold.c' || echo '$(srcdir)/'`itold.c + +libgnu_a-itold.obj: itold.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-itold.obj -MD -MP -MF $(DEPDIR)/libgnu_a-itold.Tpo -c -o libgnu_a-itold.obj `if test -f 'itold.c'; then $(CYGPATH_W) 'itold.c'; else $(CYGPATH_W) '$(srcdir)/itold.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-itold.Tpo $(DEPDIR)/libgnu_a-itold.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='itold.c' object='libgnu_a-itold.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-itold.obj `if test -f 'itold.c'; then $(CYGPATH_W) 'itold.c'; else $(CYGPATH_W) '$(srcdir)/itold.c'; fi` + +libgnu_a-flock.o: flock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-flock.o -MD -MP -MF $(DEPDIR)/libgnu_a-flock.Tpo -c -o libgnu_a-flock.o `test -f 'flock.c' || echo '$(srcdir)/'`flock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-flock.Tpo $(DEPDIR)/libgnu_a-flock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='flock.c' object='libgnu_a-flock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-flock.o `test -f 'flock.c' || echo '$(srcdir)/'`flock.c + +libgnu_a-flock.obj: flock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-flock.obj -MD -MP -MF $(DEPDIR)/libgnu_a-flock.Tpo -c -o libgnu_a-flock.obj `if test -f 'flock.c'; then $(CYGPATH_W) 'flock.c'; else $(CYGPATH_W) '$(srcdir)/flock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-flock.Tpo $(DEPDIR)/libgnu_a-flock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='flock.c' object='libgnu_a-flock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-flock.obj `if test -f 'flock.c'; then $(CYGPATH_W) 'flock.c'; else $(CYGPATH_W) '$(srcdir)/flock.c'; fi` + +libgnu_a-fpurge.o: fpurge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fpurge.o -MD -MP -MF $(DEPDIR)/libgnu_a-fpurge.Tpo -c -o libgnu_a-fpurge.o `test -f 'fpurge.c' || echo '$(srcdir)/'`fpurge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fpurge.Tpo $(DEPDIR)/libgnu_a-fpurge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fpurge.c' object='libgnu_a-fpurge.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fpurge.o `test -f 'fpurge.c' || echo '$(srcdir)/'`fpurge.c + +libgnu_a-fpurge.obj: fpurge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fpurge.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fpurge.Tpo -c -o libgnu_a-fpurge.obj `if test -f 'fpurge.c'; then $(CYGPATH_W) 'fpurge.c'; else $(CYGPATH_W) '$(srcdir)/fpurge.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fpurge.Tpo $(DEPDIR)/libgnu_a-fpurge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fpurge.c' object='libgnu_a-fpurge.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fpurge.obj `if test -f 'fpurge.c'; then $(CYGPATH_W) 'fpurge.c'; else $(CYGPATH_W) '$(srcdir)/fpurge.c'; fi` + +libgnu_a-freading.o: freading.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-freading.o -MD -MP -MF $(DEPDIR)/libgnu_a-freading.Tpo -c -o libgnu_a-freading.o `test -f 'freading.c' || echo '$(srcdir)/'`freading.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-freading.Tpo $(DEPDIR)/libgnu_a-freading.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='freading.c' object='libgnu_a-freading.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-freading.o `test -f 'freading.c' || echo '$(srcdir)/'`freading.c + +libgnu_a-freading.obj: freading.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-freading.obj -MD -MP -MF $(DEPDIR)/libgnu_a-freading.Tpo -c -o libgnu_a-freading.obj `if test -f 'freading.c'; then $(CYGPATH_W) 'freading.c'; else $(CYGPATH_W) '$(srcdir)/freading.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-freading.Tpo $(DEPDIR)/libgnu_a-freading.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='freading.c' object='libgnu_a-freading.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-freading.obj `if test -f 'freading.c'; then $(CYGPATH_W) 'freading.c'; else $(CYGPATH_W) '$(srcdir)/freading.c'; fi` + +libgnu_a-free.o: free.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-free.o -MD -MP -MF $(DEPDIR)/libgnu_a-free.Tpo -c -o libgnu_a-free.o `test -f 'free.c' || echo '$(srcdir)/'`free.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-free.Tpo $(DEPDIR)/libgnu_a-free.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='free.c' object='libgnu_a-free.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-free.o `test -f 'free.c' || echo '$(srcdir)/'`free.c + +libgnu_a-free.obj: free.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-free.obj -MD -MP -MF $(DEPDIR)/libgnu_a-free.Tpo -c -o libgnu_a-free.obj `if test -f 'free.c'; then $(CYGPATH_W) 'free.c'; else $(CYGPATH_W) '$(srcdir)/free.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-free.Tpo $(DEPDIR)/libgnu_a-free.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='free.c' object='libgnu_a-free.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-free.obj `if test -f 'free.c'; then $(CYGPATH_W) 'free.c'; else $(CYGPATH_W) '$(srcdir)/free.c'; fi` + +libgnu_a-fseek.o: fseek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fseek.o -MD -MP -MF $(DEPDIR)/libgnu_a-fseek.Tpo -c -o libgnu_a-fseek.o `test -f 'fseek.c' || echo '$(srcdir)/'`fseek.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fseek.Tpo $(DEPDIR)/libgnu_a-fseek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fseek.c' object='libgnu_a-fseek.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fseek.o `test -f 'fseek.c' || echo '$(srcdir)/'`fseek.c + +libgnu_a-fseek.obj: fseek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fseek.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fseek.Tpo -c -o libgnu_a-fseek.obj `if test -f 'fseek.c'; then $(CYGPATH_W) 'fseek.c'; else $(CYGPATH_W) '$(srcdir)/fseek.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fseek.Tpo $(DEPDIR)/libgnu_a-fseek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fseek.c' object='libgnu_a-fseek.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fseek.obj `if test -f 'fseek.c'; then $(CYGPATH_W) 'fseek.c'; else $(CYGPATH_W) '$(srcdir)/fseek.c'; fi` + +libgnu_a-fseeko.o: fseeko.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fseeko.o -MD -MP -MF $(DEPDIR)/libgnu_a-fseeko.Tpo -c -o libgnu_a-fseeko.o `test -f 'fseeko.c' || echo '$(srcdir)/'`fseeko.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fseeko.Tpo $(DEPDIR)/libgnu_a-fseeko.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fseeko.c' object='libgnu_a-fseeko.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fseeko.o `test -f 'fseeko.c' || echo '$(srcdir)/'`fseeko.c + +libgnu_a-fseeko.obj: fseeko.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fseeko.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fseeko.Tpo -c -o libgnu_a-fseeko.obj `if test -f 'fseeko.c'; then $(CYGPATH_W) 'fseeko.c'; else $(CYGPATH_W) '$(srcdir)/fseeko.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fseeko.Tpo $(DEPDIR)/libgnu_a-fseeko.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fseeko.c' object='libgnu_a-fseeko.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fseeko.obj `if test -f 'fseeko.c'; then $(CYGPATH_W) 'fseeko.c'; else $(CYGPATH_W) '$(srcdir)/fseeko.c'; fi` + +libgnu_a-fstat.o: fstat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fstat.o -MD -MP -MF $(DEPDIR)/libgnu_a-fstat.Tpo -c -o libgnu_a-fstat.o `test -f 'fstat.c' || echo '$(srcdir)/'`fstat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fstat.Tpo $(DEPDIR)/libgnu_a-fstat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fstat.c' object='libgnu_a-fstat.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fstat.o `test -f 'fstat.c' || echo '$(srcdir)/'`fstat.c + +libgnu_a-fstat.obj: fstat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fstat.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fstat.Tpo -c -o libgnu_a-fstat.obj `if test -f 'fstat.c'; then $(CYGPATH_W) 'fstat.c'; else $(CYGPATH_W) '$(srcdir)/fstat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fstat.Tpo $(DEPDIR)/libgnu_a-fstat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fstat.c' object='libgnu_a-fstat.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fstat.obj `if test -f 'fstat.c'; then $(CYGPATH_W) 'fstat.c'; else $(CYGPATH_W) '$(srcdir)/fstat.c'; fi` + +libgnu_a-fstatat.o: fstatat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fstatat.o -MD -MP -MF $(DEPDIR)/libgnu_a-fstatat.Tpo -c -o libgnu_a-fstatat.o `test -f 'fstatat.c' || echo '$(srcdir)/'`fstatat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fstatat.Tpo $(DEPDIR)/libgnu_a-fstatat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fstatat.c' object='libgnu_a-fstatat.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fstatat.o `test -f 'fstatat.c' || echo '$(srcdir)/'`fstatat.c + +libgnu_a-fstatat.obj: fstatat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fstatat.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fstatat.Tpo -c -o libgnu_a-fstatat.obj `if test -f 'fstatat.c'; then $(CYGPATH_W) 'fstatat.c'; else $(CYGPATH_W) '$(srcdir)/fstatat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fstatat.Tpo $(DEPDIR)/libgnu_a-fstatat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fstatat.c' object='libgnu_a-fstatat.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fstatat.obj `if test -f 'fstatat.c'; then $(CYGPATH_W) 'fstatat.c'; else $(CYGPATH_W) '$(srcdir)/fstatat.c'; fi` + +libgnu_a-ftell.o: ftell.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ftell.o -MD -MP -MF $(DEPDIR)/libgnu_a-ftell.Tpo -c -o libgnu_a-ftell.o `test -f 'ftell.c' || echo '$(srcdir)/'`ftell.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ftell.Tpo $(DEPDIR)/libgnu_a-ftell.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftell.c' object='libgnu_a-ftell.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ftell.o `test -f 'ftell.c' || echo '$(srcdir)/'`ftell.c + +libgnu_a-ftell.obj: ftell.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ftell.obj -MD -MP -MF $(DEPDIR)/libgnu_a-ftell.Tpo -c -o libgnu_a-ftell.obj `if test -f 'ftell.c'; then $(CYGPATH_W) 'ftell.c'; else $(CYGPATH_W) '$(srcdir)/ftell.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ftell.Tpo $(DEPDIR)/libgnu_a-ftell.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftell.c' object='libgnu_a-ftell.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ftell.obj `if test -f 'ftell.c'; then $(CYGPATH_W) 'ftell.c'; else $(CYGPATH_W) '$(srcdir)/ftell.c'; fi` + +libgnu_a-ftello.o: ftello.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ftello.o -MD -MP -MF $(DEPDIR)/libgnu_a-ftello.Tpo -c -o libgnu_a-ftello.o `test -f 'ftello.c' || echo '$(srcdir)/'`ftello.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ftello.Tpo $(DEPDIR)/libgnu_a-ftello.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftello.c' object='libgnu_a-ftello.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ftello.o `test -f 'ftello.c' || echo '$(srcdir)/'`ftello.c + +libgnu_a-ftello.obj: ftello.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ftello.obj -MD -MP -MF $(DEPDIR)/libgnu_a-ftello.Tpo -c -o libgnu_a-ftello.obj `if test -f 'ftello.c'; then $(CYGPATH_W) 'ftello.c'; else $(CYGPATH_W) '$(srcdir)/ftello.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ftello.Tpo $(DEPDIR)/libgnu_a-ftello.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftello.c' object='libgnu_a-ftello.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ftello.obj `if test -f 'ftello.c'; then $(CYGPATH_W) 'ftello.c'; else $(CYGPATH_W) '$(srcdir)/ftello.c'; fi` + +libgnu_a-futimens.o: futimens.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-futimens.o -MD -MP -MF $(DEPDIR)/libgnu_a-futimens.Tpo -c -o libgnu_a-futimens.o `test -f 'futimens.c' || echo '$(srcdir)/'`futimens.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-futimens.Tpo $(DEPDIR)/libgnu_a-futimens.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='futimens.c' object='libgnu_a-futimens.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-futimens.o `test -f 'futimens.c' || echo '$(srcdir)/'`futimens.c + +libgnu_a-futimens.obj: futimens.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-futimens.obj -MD -MP -MF $(DEPDIR)/libgnu_a-futimens.Tpo -c -o libgnu_a-futimens.obj `if test -f 'futimens.c'; then $(CYGPATH_W) 'futimens.c'; else $(CYGPATH_W) '$(srcdir)/futimens.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-futimens.Tpo $(DEPDIR)/libgnu_a-futimens.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='futimens.c' object='libgnu_a-futimens.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-futimens.obj `if test -f 'futimens.c'; then $(CYGPATH_W) 'futimens.c'; else $(CYGPATH_W) '$(srcdir)/futimens.c'; fi` + +libgnu_a-getaddrinfo.o: getaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getaddrinfo.o -MD -MP -MF $(DEPDIR)/libgnu_a-getaddrinfo.Tpo -c -o libgnu_a-getaddrinfo.o `test -f 'getaddrinfo.c' || echo '$(srcdir)/'`getaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getaddrinfo.Tpo $(DEPDIR)/libgnu_a-getaddrinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getaddrinfo.c' object='libgnu_a-getaddrinfo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getaddrinfo.o `test -f 'getaddrinfo.c' || echo '$(srcdir)/'`getaddrinfo.c + +libgnu_a-getaddrinfo.obj: getaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getaddrinfo.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getaddrinfo.Tpo -c -o libgnu_a-getaddrinfo.obj `if test -f 'getaddrinfo.c'; then $(CYGPATH_W) 'getaddrinfo.c'; else $(CYGPATH_W) '$(srcdir)/getaddrinfo.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getaddrinfo.Tpo $(DEPDIR)/libgnu_a-getaddrinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getaddrinfo.c' object='libgnu_a-getaddrinfo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getaddrinfo.obj `if test -f 'getaddrinfo.c'; then $(CYGPATH_W) 'getaddrinfo.c'; else $(CYGPATH_W) '$(srcdir)/getaddrinfo.c'; fi` + +libgnu_a-gai_strerror.o: gai_strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-gai_strerror.o -MD -MP -MF $(DEPDIR)/libgnu_a-gai_strerror.Tpo -c -o libgnu_a-gai_strerror.o `test -f 'gai_strerror.c' || echo '$(srcdir)/'`gai_strerror.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-gai_strerror.Tpo $(DEPDIR)/libgnu_a-gai_strerror.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gai_strerror.c' object='libgnu_a-gai_strerror.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-gai_strerror.o `test -f 'gai_strerror.c' || echo '$(srcdir)/'`gai_strerror.c + +libgnu_a-gai_strerror.obj: gai_strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-gai_strerror.obj -MD -MP -MF $(DEPDIR)/libgnu_a-gai_strerror.Tpo -c -o libgnu_a-gai_strerror.obj `if test -f 'gai_strerror.c'; then $(CYGPATH_W) 'gai_strerror.c'; else $(CYGPATH_W) '$(srcdir)/gai_strerror.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-gai_strerror.Tpo $(DEPDIR)/libgnu_a-gai_strerror.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gai_strerror.c' object='libgnu_a-gai_strerror.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-gai_strerror.obj `if test -f 'gai_strerror.c'; then $(CYGPATH_W) 'gai_strerror.c'; else $(CYGPATH_W) '$(srcdir)/gai_strerror.c'; fi` + +libgnu_a-getcwd.o: getcwd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getcwd.o -MD -MP -MF $(DEPDIR)/libgnu_a-getcwd.Tpo -c -o libgnu_a-getcwd.o `test -f 'getcwd.c' || echo '$(srcdir)/'`getcwd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getcwd.Tpo $(DEPDIR)/libgnu_a-getcwd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getcwd.c' object='libgnu_a-getcwd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getcwd.o `test -f 'getcwd.c' || echo '$(srcdir)/'`getcwd.c + +libgnu_a-getcwd.obj: getcwd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getcwd.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getcwd.Tpo -c -o libgnu_a-getcwd.obj `if test -f 'getcwd.c'; then $(CYGPATH_W) 'getcwd.c'; else $(CYGPATH_W) '$(srcdir)/getcwd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getcwd.Tpo $(DEPDIR)/libgnu_a-getcwd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getcwd.c' object='libgnu_a-getcwd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getcwd.obj `if test -f 'getcwd.c'; then $(CYGPATH_W) 'getcwd.c'; else $(CYGPATH_W) '$(srcdir)/getcwd.c'; fi` + +libgnu_a-getcwd-lgpl.o: getcwd-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getcwd-lgpl.o -MD -MP -MF $(DEPDIR)/libgnu_a-getcwd-lgpl.Tpo -c -o libgnu_a-getcwd-lgpl.o `test -f 'getcwd-lgpl.c' || echo '$(srcdir)/'`getcwd-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getcwd-lgpl.Tpo $(DEPDIR)/libgnu_a-getcwd-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getcwd-lgpl.c' object='libgnu_a-getcwd-lgpl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getcwd-lgpl.o `test -f 'getcwd-lgpl.c' || echo '$(srcdir)/'`getcwd-lgpl.c + +libgnu_a-getcwd-lgpl.obj: getcwd-lgpl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getcwd-lgpl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getcwd-lgpl.Tpo -c -o libgnu_a-getcwd-lgpl.obj `if test -f 'getcwd-lgpl.c'; then $(CYGPATH_W) 'getcwd-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/getcwd-lgpl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getcwd-lgpl.Tpo $(DEPDIR)/libgnu_a-getcwd-lgpl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getcwd-lgpl.c' object='libgnu_a-getcwd-lgpl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getcwd-lgpl.obj `if test -f 'getcwd-lgpl.c'; then $(CYGPATH_W) 'getcwd-lgpl.c'; else $(CYGPATH_W) '$(srcdir)/getcwd-lgpl.c'; fi` + +libgnu_a-getdelim.o: getdelim.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getdelim.o -MD -MP -MF $(DEPDIR)/libgnu_a-getdelim.Tpo -c -o libgnu_a-getdelim.o `test -f 'getdelim.c' || echo '$(srcdir)/'`getdelim.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getdelim.Tpo $(DEPDIR)/libgnu_a-getdelim.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getdelim.c' object='libgnu_a-getdelim.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getdelim.o `test -f 'getdelim.c' || echo '$(srcdir)/'`getdelim.c + +libgnu_a-getdelim.obj: getdelim.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getdelim.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getdelim.Tpo -c -o libgnu_a-getdelim.obj `if test -f 'getdelim.c'; then $(CYGPATH_W) 'getdelim.c'; else $(CYGPATH_W) '$(srcdir)/getdelim.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getdelim.Tpo $(DEPDIR)/libgnu_a-getdelim.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getdelim.c' object='libgnu_a-getdelim.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getdelim.obj `if test -f 'getdelim.c'; then $(CYGPATH_W) 'getdelim.c'; else $(CYGPATH_W) '$(srcdir)/getdelim.c'; fi` + +libgnu_a-getdtablesize.o: getdtablesize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getdtablesize.o -MD -MP -MF $(DEPDIR)/libgnu_a-getdtablesize.Tpo -c -o libgnu_a-getdtablesize.o `test -f 'getdtablesize.c' || echo '$(srcdir)/'`getdtablesize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getdtablesize.Tpo $(DEPDIR)/libgnu_a-getdtablesize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getdtablesize.c' object='libgnu_a-getdtablesize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getdtablesize.o `test -f 'getdtablesize.c' || echo '$(srcdir)/'`getdtablesize.c + +libgnu_a-getdtablesize.obj: getdtablesize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getdtablesize.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getdtablesize.Tpo -c -o libgnu_a-getdtablesize.obj `if test -f 'getdtablesize.c'; then $(CYGPATH_W) 'getdtablesize.c'; else $(CYGPATH_W) '$(srcdir)/getdtablesize.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getdtablesize.Tpo $(DEPDIR)/libgnu_a-getdtablesize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getdtablesize.c' object='libgnu_a-getdtablesize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getdtablesize.obj `if test -f 'getdtablesize.c'; then $(CYGPATH_W) 'getdtablesize.c'; else $(CYGPATH_W) '$(srcdir)/getdtablesize.c'; fi` + +libgnu_a-getgroups.o: getgroups.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getgroups.o -MD -MP -MF $(DEPDIR)/libgnu_a-getgroups.Tpo -c -o libgnu_a-getgroups.o `test -f 'getgroups.c' || echo '$(srcdir)/'`getgroups.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getgroups.Tpo $(DEPDIR)/libgnu_a-getgroups.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getgroups.c' object='libgnu_a-getgroups.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getgroups.o `test -f 'getgroups.c' || echo '$(srcdir)/'`getgroups.c + +libgnu_a-getgroups.obj: getgroups.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getgroups.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getgroups.Tpo -c -o libgnu_a-getgroups.obj `if test -f 'getgroups.c'; then $(CYGPATH_W) 'getgroups.c'; else $(CYGPATH_W) '$(srcdir)/getgroups.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getgroups.Tpo $(DEPDIR)/libgnu_a-getgroups.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getgroups.c' object='libgnu_a-getgroups.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getgroups.obj `if test -f 'getgroups.c'; then $(CYGPATH_W) 'getgroups.c'; else $(CYGPATH_W) '$(srcdir)/getgroups.c'; fi` + +libgnu_a-getline.o: getline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getline.o -MD -MP -MF $(DEPDIR)/libgnu_a-getline.Tpo -c -o libgnu_a-getline.o `test -f 'getline.c' || echo '$(srcdir)/'`getline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getline.Tpo $(DEPDIR)/libgnu_a-getline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getline.c' object='libgnu_a-getline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getline.o `test -f 'getline.c' || echo '$(srcdir)/'`getline.c + +libgnu_a-getline.obj: getline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getline.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getline.Tpo -c -o libgnu_a-getline.obj `if test -f 'getline.c'; then $(CYGPATH_W) 'getline.c'; else $(CYGPATH_W) '$(srcdir)/getline.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getline.Tpo $(DEPDIR)/libgnu_a-getline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getline.c' object='libgnu_a-getline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getline.obj `if test -f 'getline.c'; then $(CYGPATH_W) 'getline.c'; else $(CYGPATH_W) '$(srcdir)/getline.c'; fi` + +libgnu_a-getopt.o: getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getopt.o -MD -MP -MF $(DEPDIR)/libgnu_a-getopt.Tpo -c -o libgnu_a-getopt.o `test -f 'getopt.c' || echo '$(srcdir)/'`getopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getopt.Tpo $(DEPDIR)/libgnu_a-getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getopt.c' object='libgnu_a-getopt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getopt.o `test -f 'getopt.c' || echo '$(srcdir)/'`getopt.c + +libgnu_a-getopt.obj: getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getopt.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getopt.Tpo -c -o libgnu_a-getopt.obj `if test -f 'getopt.c'; then $(CYGPATH_W) 'getopt.c'; else $(CYGPATH_W) '$(srcdir)/getopt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getopt.Tpo $(DEPDIR)/libgnu_a-getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getopt.c' object='libgnu_a-getopt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getopt.obj `if test -f 'getopt.c'; then $(CYGPATH_W) 'getopt.c'; else $(CYGPATH_W) '$(srcdir)/getopt.c'; fi` + +libgnu_a-getopt1.o: getopt1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getopt1.o -MD -MP -MF $(DEPDIR)/libgnu_a-getopt1.Tpo -c -o libgnu_a-getopt1.o `test -f 'getopt1.c' || echo '$(srcdir)/'`getopt1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getopt1.Tpo $(DEPDIR)/libgnu_a-getopt1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getopt1.c' object='libgnu_a-getopt1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getopt1.o `test -f 'getopt1.c' || echo '$(srcdir)/'`getopt1.c + +libgnu_a-getopt1.obj: getopt1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getopt1.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getopt1.Tpo -c -o libgnu_a-getopt1.obj `if test -f 'getopt1.c'; then $(CYGPATH_W) 'getopt1.c'; else $(CYGPATH_W) '$(srcdir)/getopt1.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getopt1.Tpo $(DEPDIR)/libgnu_a-getopt1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getopt1.c' object='libgnu_a-getopt1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getopt1.obj `if test -f 'getopt1.c'; then $(CYGPATH_W) 'getopt1.c'; else $(CYGPATH_W) '$(srcdir)/getopt1.c'; fi` + +libgnu_a-getpeername.o: getpeername.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getpeername.o -MD -MP -MF $(DEPDIR)/libgnu_a-getpeername.Tpo -c -o libgnu_a-getpeername.o `test -f 'getpeername.c' || echo '$(srcdir)/'`getpeername.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getpeername.Tpo $(DEPDIR)/libgnu_a-getpeername.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getpeername.c' object='libgnu_a-getpeername.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getpeername.o `test -f 'getpeername.c' || echo '$(srcdir)/'`getpeername.c + +libgnu_a-getpeername.obj: getpeername.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getpeername.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getpeername.Tpo -c -o libgnu_a-getpeername.obj `if test -f 'getpeername.c'; then $(CYGPATH_W) 'getpeername.c'; else $(CYGPATH_W) '$(srcdir)/getpeername.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getpeername.Tpo $(DEPDIR)/libgnu_a-getpeername.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getpeername.c' object='libgnu_a-getpeername.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getpeername.obj `if test -f 'getpeername.c'; then $(CYGPATH_W) 'getpeername.c'; else $(CYGPATH_W) '$(srcdir)/getpeername.c'; fi` + +libgnu_a-getprogname.o: getprogname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getprogname.o -MD -MP -MF $(DEPDIR)/libgnu_a-getprogname.Tpo -c -o libgnu_a-getprogname.o `test -f 'getprogname.c' || echo '$(srcdir)/'`getprogname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getprogname.Tpo $(DEPDIR)/libgnu_a-getprogname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getprogname.c' object='libgnu_a-getprogname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getprogname.o `test -f 'getprogname.c' || echo '$(srcdir)/'`getprogname.c + +libgnu_a-getprogname.obj: getprogname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getprogname.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getprogname.Tpo -c -o libgnu_a-getprogname.obj `if test -f 'getprogname.c'; then $(CYGPATH_W) 'getprogname.c'; else $(CYGPATH_W) '$(srcdir)/getprogname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getprogname.Tpo $(DEPDIR)/libgnu_a-getprogname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getprogname.c' object='libgnu_a-getprogname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getprogname.obj `if test -f 'getprogname.c'; then $(CYGPATH_W) 'getprogname.c'; else $(CYGPATH_W) '$(srcdir)/getprogname.c'; fi` + +libgnu_a-getrandom.o: getrandom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getrandom.o -MD -MP -MF $(DEPDIR)/libgnu_a-getrandom.Tpo -c -o libgnu_a-getrandom.o `test -f 'getrandom.c' || echo '$(srcdir)/'`getrandom.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getrandom.Tpo $(DEPDIR)/libgnu_a-getrandom.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getrandom.c' object='libgnu_a-getrandom.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getrandom.o `test -f 'getrandom.c' || echo '$(srcdir)/'`getrandom.c + +libgnu_a-getrandom.obj: getrandom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getrandom.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getrandom.Tpo -c -o libgnu_a-getrandom.obj `if test -f 'getrandom.c'; then $(CYGPATH_W) 'getrandom.c'; else $(CYGPATH_W) '$(srcdir)/getrandom.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getrandom.Tpo $(DEPDIR)/libgnu_a-getrandom.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getrandom.c' object='libgnu_a-getrandom.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getrandom.obj `if test -f 'getrandom.c'; then $(CYGPATH_W) 'getrandom.c'; else $(CYGPATH_W) '$(srcdir)/getrandom.c'; fi` + +libgnu_a-getsockname.o: getsockname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getsockname.o -MD -MP -MF $(DEPDIR)/libgnu_a-getsockname.Tpo -c -o libgnu_a-getsockname.o `test -f 'getsockname.c' || echo '$(srcdir)/'`getsockname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getsockname.Tpo $(DEPDIR)/libgnu_a-getsockname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getsockname.c' object='libgnu_a-getsockname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getsockname.o `test -f 'getsockname.c' || echo '$(srcdir)/'`getsockname.c + +libgnu_a-getsockname.obj: getsockname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getsockname.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getsockname.Tpo -c -o libgnu_a-getsockname.obj `if test -f 'getsockname.c'; then $(CYGPATH_W) 'getsockname.c'; else $(CYGPATH_W) '$(srcdir)/getsockname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getsockname.Tpo $(DEPDIR)/libgnu_a-getsockname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getsockname.c' object='libgnu_a-getsockname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getsockname.obj `if test -f 'getsockname.c'; then $(CYGPATH_W) 'getsockname.c'; else $(CYGPATH_W) '$(srcdir)/getsockname.c'; fi` + +libgnu_a-gettime.o: gettime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-gettime.o -MD -MP -MF $(DEPDIR)/libgnu_a-gettime.Tpo -c -o libgnu_a-gettime.o `test -f 'gettime.c' || echo '$(srcdir)/'`gettime.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-gettime.Tpo $(DEPDIR)/libgnu_a-gettime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gettime.c' object='libgnu_a-gettime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-gettime.o `test -f 'gettime.c' || echo '$(srcdir)/'`gettime.c + +libgnu_a-gettime.obj: gettime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-gettime.obj -MD -MP -MF $(DEPDIR)/libgnu_a-gettime.Tpo -c -o libgnu_a-gettime.obj `if test -f 'gettime.c'; then $(CYGPATH_W) 'gettime.c'; else $(CYGPATH_W) '$(srcdir)/gettime.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-gettime.Tpo $(DEPDIR)/libgnu_a-gettime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gettime.c' object='libgnu_a-gettime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-gettime.obj `if test -f 'gettime.c'; then $(CYGPATH_W) 'gettime.c'; else $(CYGPATH_W) '$(srcdir)/gettime.c'; fi` + +libgnu_a-gettimeofday.o: gettimeofday.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-gettimeofday.o -MD -MP -MF $(DEPDIR)/libgnu_a-gettimeofday.Tpo -c -o libgnu_a-gettimeofday.o `test -f 'gettimeofday.c' || echo '$(srcdir)/'`gettimeofday.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-gettimeofday.Tpo $(DEPDIR)/libgnu_a-gettimeofday.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gettimeofday.c' object='libgnu_a-gettimeofday.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-gettimeofday.o `test -f 'gettimeofday.c' || echo '$(srcdir)/'`gettimeofday.c + +libgnu_a-gettimeofday.obj: gettimeofday.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-gettimeofday.obj -MD -MP -MF $(DEPDIR)/libgnu_a-gettimeofday.Tpo -c -o libgnu_a-gettimeofday.obj `if test -f 'gettimeofday.c'; then $(CYGPATH_W) 'gettimeofday.c'; else $(CYGPATH_W) '$(srcdir)/gettimeofday.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-gettimeofday.Tpo $(DEPDIR)/libgnu_a-gettimeofday.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gettimeofday.c' object='libgnu_a-gettimeofday.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-gettimeofday.obj `if test -f 'gettimeofday.c'; then $(CYGPATH_W) 'gettimeofday.c'; else $(CYGPATH_W) '$(srcdir)/gettimeofday.c'; fi` + +libgnu_a-group-member.o: group-member.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-group-member.o -MD -MP -MF $(DEPDIR)/libgnu_a-group-member.Tpo -c -o libgnu_a-group-member.o `test -f 'group-member.c' || echo '$(srcdir)/'`group-member.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-group-member.Tpo $(DEPDIR)/libgnu_a-group-member.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='group-member.c' object='libgnu_a-group-member.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-group-member.o `test -f 'group-member.c' || echo '$(srcdir)/'`group-member.c + +libgnu_a-group-member.obj: group-member.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-group-member.obj -MD -MP -MF $(DEPDIR)/libgnu_a-group-member.Tpo -c -o libgnu_a-group-member.obj `if test -f 'group-member.c'; then $(CYGPATH_W) 'group-member.c'; else $(CYGPATH_W) '$(srcdir)/group-member.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-group-member.Tpo $(DEPDIR)/libgnu_a-group-member.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='group-member.c' object='libgnu_a-group-member.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-group-member.obj `if test -f 'group-member.c'; then $(CYGPATH_W) 'group-member.c'; else $(CYGPATH_W) '$(srcdir)/group-member.c'; fi` + +libgnu_a-hard-locale.o: hard-locale.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hard-locale.o -MD -MP -MF $(DEPDIR)/libgnu_a-hard-locale.Tpo -c -o libgnu_a-hard-locale.o `test -f 'hard-locale.c' || echo '$(srcdir)/'`hard-locale.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hard-locale.Tpo $(DEPDIR)/libgnu_a-hard-locale.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hard-locale.c' object='libgnu_a-hard-locale.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hard-locale.o `test -f 'hard-locale.c' || echo '$(srcdir)/'`hard-locale.c + +libgnu_a-hard-locale.obj: hard-locale.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hard-locale.obj -MD -MP -MF $(DEPDIR)/libgnu_a-hard-locale.Tpo -c -o libgnu_a-hard-locale.obj `if test -f 'hard-locale.c'; then $(CYGPATH_W) 'hard-locale.c'; else $(CYGPATH_W) '$(srcdir)/hard-locale.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hard-locale.Tpo $(DEPDIR)/libgnu_a-hard-locale.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hard-locale.c' object='libgnu_a-hard-locale.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hard-locale.obj `if test -f 'hard-locale.c'; then $(CYGPATH_W) 'hard-locale.c'; else $(CYGPATH_W) '$(srcdir)/hard-locale.c'; fi` + +libgnu_a-hash.o: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hash.o -MD -MP -MF $(DEPDIR)/libgnu_a-hash.Tpo -c -o libgnu_a-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hash.Tpo $(DEPDIR)/libgnu_a-hash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libgnu_a-hash.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c + +libgnu_a-hash.obj: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hash.obj -MD -MP -MF $(DEPDIR)/libgnu_a-hash.Tpo -c -o libgnu_a-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hash.Tpo $(DEPDIR)/libgnu_a-hash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libgnu_a-hash.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` + +libgnu_a-hash-pjw.o: hash-pjw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hash-pjw.o -MD -MP -MF $(DEPDIR)/libgnu_a-hash-pjw.Tpo -c -o libgnu_a-hash-pjw.o `test -f 'hash-pjw.c' || echo '$(srcdir)/'`hash-pjw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hash-pjw.Tpo $(DEPDIR)/libgnu_a-hash-pjw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash-pjw.c' object='libgnu_a-hash-pjw.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hash-pjw.o `test -f 'hash-pjw.c' || echo '$(srcdir)/'`hash-pjw.c + +libgnu_a-hash-pjw.obj: hash-pjw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hash-pjw.obj -MD -MP -MF $(DEPDIR)/libgnu_a-hash-pjw.Tpo -c -o libgnu_a-hash-pjw.obj `if test -f 'hash-pjw.c'; then $(CYGPATH_W) 'hash-pjw.c'; else $(CYGPATH_W) '$(srcdir)/hash-pjw.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hash-pjw.Tpo $(DEPDIR)/libgnu_a-hash-pjw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash-pjw.c' object='libgnu_a-hash-pjw.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hash-pjw.obj `if test -f 'hash-pjw.c'; then $(CYGPATH_W) 'hash-pjw.c'; else $(CYGPATH_W) '$(srcdir)/hash-pjw.c'; fi` + +libgnu_a-hash-triple-simple.o: hash-triple-simple.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hash-triple-simple.o -MD -MP -MF $(DEPDIR)/libgnu_a-hash-triple-simple.Tpo -c -o libgnu_a-hash-triple-simple.o `test -f 'hash-triple-simple.c' || echo '$(srcdir)/'`hash-triple-simple.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hash-triple-simple.Tpo $(DEPDIR)/libgnu_a-hash-triple-simple.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash-triple-simple.c' object='libgnu_a-hash-triple-simple.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hash-triple-simple.o `test -f 'hash-triple-simple.c' || echo '$(srcdir)/'`hash-triple-simple.c + +libgnu_a-hash-triple-simple.obj: hash-triple-simple.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-hash-triple-simple.obj -MD -MP -MF $(DEPDIR)/libgnu_a-hash-triple-simple.Tpo -c -o libgnu_a-hash-triple-simple.obj `if test -f 'hash-triple-simple.c'; then $(CYGPATH_W) 'hash-triple-simple.c'; else $(CYGPATH_W) '$(srcdir)/hash-triple-simple.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-hash-triple-simple.Tpo $(DEPDIR)/libgnu_a-hash-triple-simple.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash-triple-simple.c' object='libgnu_a-hash-triple-simple.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-hash-triple-simple.obj `if test -f 'hash-triple-simple.c'; then $(CYGPATH_W) 'hash-triple-simple.c'; else $(CYGPATH_W) '$(srcdir)/hash-triple-simple.c'; fi` + +libgnu_a-ialloc.o: ialloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ialloc.o -MD -MP -MF $(DEPDIR)/libgnu_a-ialloc.Tpo -c -o libgnu_a-ialloc.o `test -f 'ialloc.c' || echo '$(srcdir)/'`ialloc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ialloc.Tpo $(DEPDIR)/libgnu_a-ialloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ialloc.c' object='libgnu_a-ialloc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ialloc.o `test -f 'ialloc.c' || echo '$(srcdir)/'`ialloc.c + +libgnu_a-ialloc.obj: ialloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ialloc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-ialloc.Tpo -c -o libgnu_a-ialloc.obj `if test -f 'ialloc.c'; then $(CYGPATH_W) 'ialloc.c'; else $(CYGPATH_W) '$(srcdir)/ialloc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ialloc.Tpo $(DEPDIR)/libgnu_a-ialloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ialloc.c' object='libgnu_a-ialloc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ialloc.obj `if test -f 'ialloc.c'; then $(CYGPATH_W) 'ialloc.c'; else $(CYGPATH_W) '$(srcdir)/ialloc.c'; fi` + +libgnu_a-inet_ntop.o: inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-inet_ntop.o -MD -MP -MF $(DEPDIR)/libgnu_a-inet_ntop.Tpo -c -o libgnu_a-inet_ntop.o `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-inet_ntop.Tpo $(DEPDIR)/libgnu_a-inet_ntop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_ntop.c' object='libgnu_a-inet_ntop.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-inet_ntop.o `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c + +libgnu_a-inet_ntop.obj: inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-inet_ntop.obj -MD -MP -MF $(DEPDIR)/libgnu_a-inet_ntop.Tpo -c -o libgnu_a-inet_ntop.obj `if test -f 'inet_ntop.c'; then $(CYGPATH_W) 'inet_ntop.c'; else $(CYGPATH_W) '$(srcdir)/inet_ntop.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-inet_ntop.Tpo $(DEPDIR)/libgnu_a-inet_ntop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_ntop.c' object='libgnu_a-inet_ntop.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-inet_ntop.obj `if test -f 'inet_ntop.c'; then $(CYGPATH_W) 'inet_ntop.c'; else $(CYGPATH_W) '$(srcdir)/inet_ntop.c'; fi` + +libgnu_a-ioctl.o: ioctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ioctl.o -MD -MP -MF $(DEPDIR)/libgnu_a-ioctl.Tpo -c -o libgnu_a-ioctl.o `test -f 'ioctl.c' || echo '$(srcdir)/'`ioctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ioctl.Tpo $(DEPDIR)/libgnu_a-ioctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ioctl.c' object='libgnu_a-ioctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ioctl.o `test -f 'ioctl.c' || echo '$(srcdir)/'`ioctl.c + +libgnu_a-ioctl.obj: ioctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-ioctl.obj -MD -MP -MF $(DEPDIR)/libgnu_a-ioctl.Tpo -c -o libgnu_a-ioctl.obj `if test -f 'ioctl.c'; then $(CYGPATH_W) 'ioctl.c'; else $(CYGPATH_W) '$(srcdir)/ioctl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-ioctl.Tpo $(DEPDIR)/libgnu_a-ioctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ioctl.c' object='libgnu_a-ioctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-ioctl.obj `if test -f 'ioctl.c'; then $(CYGPATH_W) 'ioctl.c'; else $(CYGPATH_W) '$(srcdir)/ioctl.c'; fi` + +libgnu_a-isblank.o: isblank.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-isblank.o -MD -MP -MF $(DEPDIR)/libgnu_a-isblank.Tpo -c -o libgnu_a-isblank.o `test -f 'isblank.c' || echo '$(srcdir)/'`isblank.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-isblank.Tpo $(DEPDIR)/libgnu_a-isblank.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isblank.c' object='libgnu_a-isblank.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-isblank.o `test -f 'isblank.c' || echo '$(srcdir)/'`isblank.c + +libgnu_a-isblank.obj: isblank.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-isblank.obj -MD -MP -MF $(DEPDIR)/libgnu_a-isblank.Tpo -c -o libgnu_a-isblank.obj `if test -f 'isblank.c'; then $(CYGPATH_W) 'isblank.c'; else $(CYGPATH_W) '$(srcdir)/isblank.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-isblank.Tpo $(DEPDIR)/libgnu_a-isblank.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='isblank.c' object='libgnu_a-isblank.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-isblank.obj `if test -f 'isblank.c'; then $(CYGPATH_W) 'isblank.c'; else $(CYGPATH_W) '$(srcdir)/isblank.c'; fi` + +libgnu_a-iswblank.o: iswblank.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-iswblank.o -MD -MP -MF $(DEPDIR)/libgnu_a-iswblank.Tpo -c -o libgnu_a-iswblank.o `test -f 'iswblank.c' || echo '$(srcdir)/'`iswblank.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-iswblank.Tpo $(DEPDIR)/libgnu_a-iswblank.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iswblank.c' object='libgnu_a-iswblank.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-iswblank.o `test -f 'iswblank.c' || echo '$(srcdir)/'`iswblank.c + +libgnu_a-iswblank.obj: iswblank.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-iswblank.obj -MD -MP -MF $(DEPDIR)/libgnu_a-iswblank.Tpo -c -o libgnu_a-iswblank.obj `if test -f 'iswblank.c'; then $(CYGPATH_W) 'iswblank.c'; else $(CYGPATH_W) '$(srcdir)/iswblank.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-iswblank.Tpo $(DEPDIR)/libgnu_a-iswblank.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iswblank.c' object='libgnu_a-iswblank.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-iswblank.obj `if test -f 'iswblank.c'; then $(CYGPATH_W) 'iswblank.c'; else $(CYGPATH_W) '$(srcdir)/iswblank.c'; fi` + +libgnu_a-iswdigit.o: iswdigit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-iswdigit.o -MD -MP -MF $(DEPDIR)/libgnu_a-iswdigit.Tpo -c -o libgnu_a-iswdigit.o `test -f 'iswdigit.c' || echo '$(srcdir)/'`iswdigit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-iswdigit.Tpo $(DEPDIR)/libgnu_a-iswdigit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iswdigit.c' object='libgnu_a-iswdigit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-iswdigit.o `test -f 'iswdigit.c' || echo '$(srcdir)/'`iswdigit.c + +libgnu_a-iswdigit.obj: iswdigit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-iswdigit.obj -MD -MP -MF $(DEPDIR)/libgnu_a-iswdigit.Tpo -c -o libgnu_a-iswdigit.obj `if test -f 'iswdigit.c'; then $(CYGPATH_W) 'iswdigit.c'; else $(CYGPATH_W) '$(srcdir)/iswdigit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-iswdigit.Tpo $(DEPDIR)/libgnu_a-iswdigit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iswdigit.c' object='libgnu_a-iswdigit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-iswdigit.obj `if test -f 'iswdigit.c'; then $(CYGPATH_W) 'iswdigit.c'; else $(CYGPATH_W) '$(srcdir)/iswdigit.c'; fi` + +libgnu_a-iswxdigit.o: iswxdigit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-iswxdigit.o -MD -MP -MF $(DEPDIR)/libgnu_a-iswxdigit.Tpo -c -o libgnu_a-iswxdigit.o `test -f 'iswxdigit.c' || echo '$(srcdir)/'`iswxdigit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-iswxdigit.Tpo $(DEPDIR)/libgnu_a-iswxdigit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iswxdigit.c' object='libgnu_a-iswxdigit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-iswxdigit.o `test -f 'iswxdigit.c' || echo '$(srcdir)/'`iswxdigit.c + +libgnu_a-iswxdigit.obj: iswxdigit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-iswxdigit.obj -MD -MP -MF $(DEPDIR)/libgnu_a-iswxdigit.Tpo -c -o libgnu_a-iswxdigit.obj `if test -f 'iswxdigit.c'; then $(CYGPATH_W) 'iswxdigit.c'; else $(CYGPATH_W) '$(srcdir)/iswxdigit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-iswxdigit.Tpo $(DEPDIR)/libgnu_a-iswxdigit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iswxdigit.c' object='libgnu_a-iswxdigit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-iswxdigit.obj `if test -f 'iswxdigit.c'; then $(CYGPATH_W) 'iswxdigit.c'; else $(CYGPATH_W) '$(srcdir)/iswxdigit.c'; fi` + +libgnu_a-link.o: link.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-link.o -MD -MP -MF $(DEPDIR)/libgnu_a-link.Tpo -c -o libgnu_a-link.o `test -f 'link.c' || echo '$(srcdir)/'`link.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-link.Tpo $(DEPDIR)/libgnu_a-link.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='link.c' object='libgnu_a-link.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-link.o `test -f 'link.c' || echo '$(srcdir)/'`link.c + +libgnu_a-link.obj: link.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-link.obj -MD -MP -MF $(DEPDIR)/libgnu_a-link.Tpo -c -o libgnu_a-link.obj `if test -f 'link.c'; then $(CYGPATH_W) 'link.c'; else $(CYGPATH_W) '$(srcdir)/link.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-link.Tpo $(DEPDIR)/libgnu_a-link.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='link.c' object='libgnu_a-link.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-link.obj `if test -f 'link.c'; then $(CYGPATH_W) 'link.c'; else $(CYGPATH_W) '$(srcdir)/link.c'; fi` + +libgnu_a-listen.o: listen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-listen.o -MD -MP -MF $(DEPDIR)/libgnu_a-listen.Tpo -c -o libgnu_a-listen.o `test -f 'listen.c' || echo '$(srcdir)/'`listen.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-listen.Tpo $(DEPDIR)/libgnu_a-listen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='listen.c' object='libgnu_a-listen.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-listen.o `test -f 'listen.c' || echo '$(srcdir)/'`listen.c + +libgnu_a-listen.obj: listen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-listen.obj -MD -MP -MF $(DEPDIR)/libgnu_a-listen.Tpo -c -o libgnu_a-listen.obj `if test -f 'listen.c'; then $(CYGPATH_W) 'listen.c'; else $(CYGPATH_W) '$(srcdir)/listen.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-listen.Tpo $(DEPDIR)/libgnu_a-listen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='listen.c' object='libgnu_a-listen.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-listen.obj `if test -f 'listen.c'; then $(CYGPATH_W) 'listen.c'; else $(CYGPATH_W) '$(srcdir)/listen.c'; fi` + +libgnu_a-localcharset.o: localcharset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-localcharset.o -MD -MP -MF $(DEPDIR)/libgnu_a-localcharset.Tpo -c -o libgnu_a-localcharset.o `test -f 'localcharset.c' || echo '$(srcdir)/'`localcharset.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-localcharset.Tpo $(DEPDIR)/libgnu_a-localcharset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='localcharset.c' object='libgnu_a-localcharset.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-localcharset.o `test -f 'localcharset.c' || echo '$(srcdir)/'`localcharset.c + +libgnu_a-localcharset.obj: localcharset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-localcharset.obj -MD -MP -MF $(DEPDIR)/libgnu_a-localcharset.Tpo -c -o libgnu_a-localcharset.obj `if test -f 'localcharset.c'; then $(CYGPATH_W) 'localcharset.c'; else $(CYGPATH_W) '$(srcdir)/localcharset.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-localcharset.Tpo $(DEPDIR)/libgnu_a-localcharset.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='localcharset.c' object='libgnu_a-localcharset.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-localcharset.obj `if test -f 'localcharset.c'; then $(CYGPATH_W) 'localcharset.c'; else $(CYGPATH_W) '$(srcdir)/localcharset.c'; fi` + +libgnu_a-localeconv.o: localeconv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-localeconv.o -MD -MP -MF $(DEPDIR)/libgnu_a-localeconv.Tpo -c -o libgnu_a-localeconv.o `test -f 'localeconv.c' || echo '$(srcdir)/'`localeconv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-localeconv.Tpo $(DEPDIR)/libgnu_a-localeconv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='localeconv.c' object='libgnu_a-localeconv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-localeconv.o `test -f 'localeconv.c' || echo '$(srcdir)/'`localeconv.c + +libgnu_a-localeconv.obj: localeconv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-localeconv.obj -MD -MP -MF $(DEPDIR)/libgnu_a-localeconv.Tpo -c -o libgnu_a-localeconv.obj `if test -f 'localeconv.c'; then $(CYGPATH_W) 'localeconv.c'; else $(CYGPATH_W) '$(srcdir)/localeconv.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-localeconv.Tpo $(DEPDIR)/libgnu_a-localeconv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='localeconv.c' object='libgnu_a-localeconv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-localeconv.obj `if test -f 'localeconv.c'; then $(CYGPATH_W) 'localeconv.c'; else $(CYGPATH_W) '$(srcdir)/localeconv.c'; fi` + +glthread/libgnu_a-lock.o: glthread/lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT glthread/libgnu_a-lock.o -MD -MP -MF glthread/$(DEPDIR)/libgnu_a-lock.Tpo -c -o glthread/libgnu_a-lock.o `test -f 'glthread/lock.c' || echo '$(srcdir)/'`glthread/lock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) glthread/$(DEPDIR)/libgnu_a-lock.Tpo glthread/$(DEPDIR)/libgnu_a-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glthread/lock.c' object='glthread/libgnu_a-lock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o glthread/libgnu_a-lock.o `test -f 'glthread/lock.c' || echo '$(srcdir)/'`glthread/lock.c + +glthread/libgnu_a-lock.obj: glthread/lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT glthread/libgnu_a-lock.obj -MD -MP -MF glthread/$(DEPDIR)/libgnu_a-lock.Tpo -c -o glthread/libgnu_a-lock.obj `if test -f 'glthread/lock.c'; then $(CYGPATH_W) 'glthread/lock.c'; else $(CYGPATH_W) '$(srcdir)/glthread/lock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) glthread/$(DEPDIR)/libgnu_a-lock.Tpo glthread/$(DEPDIR)/libgnu_a-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glthread/lock.c' object='glthread/libgnu_a-lock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o glthread/libgnu_a-lock.obj `if test -f 'glthread/lock.c'; then $(CYGPATH_W) 'glthread/lock.c'; else $(CYGPATH_W) '$(srcdir)/glthread/lock.c'; fi` + +libgnu_a-lseek.o: lseek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-lseek.o -MD -MP -MF $(DEPDIR)/libgnu_a-lseek.Tpo -c -o libgnu_a-lseek.o `test -f 'lseek.c' || echo '$(srcdir)/'`lseek.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-lseek.Tpo $(DEPDIR)/libgnu_a-lseek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lseek.c' object='libgnu_a-lseek.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-lseek.o `test -f 'lseek.c' || echo '$(srcdir)/'`lseek.c + +libgnu_a-lseek.obj: lseek.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-lseek.obj -MD -MP -MF $(DEPDIR)/libgnu_a-lseek.Tpo -c -o libgnu_a-lseek.obj `if test -f 'lseek.c'; then $(CYGPATH_W) 'lseek.c'; else $(CYGPATH_W) '$(srcdir)/lseek.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-lseek.Tpo $(DEPDIR)/libgnu_a-lseek.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lseek.c' object='libgnu_a-lseek.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-lseek.obj `if test -f 'lseek.c'; then $(CYGPATH_W) 'lseek.c'; else $(CYGPATH_W) '$(srcdir)/lseek.c'; fi` + +libgnu_a-lstat.o: lstat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-lstat.o -MD -MP -MF $(DEPDIR)/libgnu_a-lstat.Tpo -c -o libgnu_a-lstat.o `test -f 'lstat.c' || echo '$(srcdir)/'`lstat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-lstat.Tpo $(DEPDIR)/libgnu_a-lstat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lstat.c' object='libgnu_a-lstat.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-lstat.o `test -f 'lstat.c' || echo '$(srcdir)/'`lstat.c + +libgnu_a-lstat.obj: lstat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-lstat.obj -MD -MP -MF $(DEPDIR)/libgnu_a-lstat.Tpo -c -o libgnu_a-lstat.obj `if test -f 'lstat.c'; then $(CYGPATH_W) 'lstat.c'; else $(CYGPATH_W) '$(srcdir)/lstat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-lstat.Tpo $(DEPDIR)/libgnu_a-lstat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lstat.c' object='libgnu_a-lstat.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-lstat.obj `if test -f 'lstat.c'; then $(CYGPATH_W) 'lstat.c'; else $(CYGPATH_W) '$(srcdir)/lstat.c'; fi` + +libgnu_a-malloca.o: malloca.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-malloca.o -MD -MP -MF $(DEPDIR)/libgnu_a-malloca.Tpo -c -o libgnu_a-malloca.o `test -f 'malloca.c' || echo '$(srcdir)/'`malloca.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-malloca.Tpo $(DEPDIR)/libgnu_a-malloca.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloca.c' object='libgnu_a-malloca.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-malloca.o `test -f 'malloca.c' || echo '$(srcdir)/'`malloca.c + +libgnu_a-malloca.obj: malloca.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-malloca.obj -MD -MP -MF $(DEPDIR)/libgnu_a-malloca.Tpo -c -o libgnu_a-malloca.obj `if test -f 'malloca.c'; then $(CYGPATH_W) 'malloca.c'; else $(CYGPATH_W) '$(srcdir)/malloca.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-malloca.Tpo $(DEPDIR)/libgnu_a-malloca.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloca.c' object='libgnu_a-malloca.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-malloca.obj `if test -f 'malloca.c'; then $(CYGPATH_W) 'malloca.c'; else $(CYGPATH_W) '$(srcdir)/malloca.c'; fi` + +libgnu_a-mbchar.o: mbchar.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbchar.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbchar.Tpo -c -o libgnu_a-mbchar.o `test -f 'mbchar.c' || echo '$(srcdir)/'`mbchar.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbchar.Tpo $(DEPDIR)/libgnu_a-mbchar.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbchar.c' object='libgnu_a-mbchar.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbchar.o `test -f 'mbchar.c' || echo '$(srcdir)/'`mbchar.c + +libgnu_a-mbchar.obj: mbchar.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbchar.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbchar.Tpo -c -o libgnu_a-mbchar.obj `if test -f 'mbchar.c'; then $(CYGPATH_W) 'mbchar.c'; else $(CYGPATH_W) '$(srcdir)/mbchar.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbchar.Tpo $(DEPDIR)/libgnu_a-mbchar.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbchar.c' object='libgnu_a-mbchar.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbchar.obj `if test -f 'mbchar.c'; then $(CYGPATH_W) 'mbchar.c'; else $(CYGPATH_W) '$(srcdir)/mbchar.c'; fi` + +libgnu_a-mbiter.o: mbiter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbiter.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbiter.Tpo -c -o libgnu_a-mbiter.o `test -f 'mbiter.c' || echo '$(srcdir)/'`mbiter.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbiter.Tpo $(DEPDIR)/libgnu_a-mbiter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbiter.c' object='libgnu_a-mbiter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbiter.o `test -f 'mbiter.c' || echo '$(srcdir)/'`mbiter.c + +libgnu_a-mbiter.obj: mbiter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbiter.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbiter.Tpo -c -o libgnu_a-mbiter.obj `if test -f 'mbiter.c'; then $(CYGPATH_W) 'mbiter.c'; else $(CYGPATH_W) '$(srcdir)/mbiter.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbiter.Tpo $(DEPDIR)/libgnu_a-mbiter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbiter.c' object='libgnu_a-mbiter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbiter.obj `if test -f 'mbiter.c'; then $(CYGPATH_W) 'mbiter.c'; else $(CYGPATH_W) '$(srcdir)/mbiter.c'; fi` + +libgnu_a-mbrtowc.o: mbrtowc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbrtowc.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbrtowc.Tpo -c -o libgnu_a-mbrtowc.o `test -f 'mbrtowc.c' || echo '$(srcdir)/'`mbrtowc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbrtowc.Tpo $(DEPDIR)/libgnu_a-mbrtowc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbrtowc.c' object='libgnu_a-mbrtowc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbrtowc.o `test -f 'mbrtowc.c' || echo '$(srcdir)/'`mbrtowc.c + +libgnu_a-mbrtowc.obj: mbrtowc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbrtowc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbrtowc.Tpo -c -o libgnu_a-mbrtowc.obj `if test -f 'mbrtowc.c'; then $(CYGPATH_W) 'mbrtowc.c'; else $(CYGPATH_W) '$(srcdir)/mbrtowc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbrtowc.Tpo $(DEPDIR)/libgnu_a-mbrtowc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbrtowc.c' object='libgnu_a-mbrtowc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbrtowc.obj `if test -f 'mbrtowc.c'; then $(CYGPATH_W) 'mbrtowc.c'; else $(CYGPATH_W) '$(srcdir)/mbrtowc.c'; fi` + +libgnu_a-mbsinit.o: mbsinit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbsinit.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbsinit.Tpo -c -o libgnu_a-mbsinit.o `test -f 'mbsinit.c' || echo '$(srcdir)/'`mbsinit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbsinit.Tpo $(DEPDIR)/libgnu_a-mbsinit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbsinit.c' object='libgnu_a-mbsinit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbsinit.o `test -f 'mbsinit.c' || echo '$(srcdir)/'`mbsinit.c + +libgnu_a-mbsinit.obj: mbsinit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbsinit.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbsinit.Tpo -c -o libgnu_a-mbsinit.obj `if test -f 'mbsinit.c'; then $(CYGPATH_W) 'mbsinit.c'; else $(CYGPATH_W) '$(srcdir)/mbsinit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbsinit.Tpo $(DEPDIR)/libgnu_a-mbsinit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbsinit.c' object='libgnu_a-mbsinit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbsinit.obj `if test -f 'mbsinit.c'; then $(CYGPATH_W) 'mbsinit.c'; else $(CYGPATH_W) '$(srcdir)/mbsinit.c'; fi` + +libgnu_a-mbsrtowcs.o: mbsrtowcs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbsrtowcs.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbsrtowcs.Tpo -c -o libgnu_a-mbsrtowcs.o `test -f 'mbsrtowcs.c' || echo '$(srcdir)/'`mbsrtowcs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbsrtowcs.Tpo $(DEPDIR)/libgnu_a-mbsrtowcs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbsrtowcs.c' object='libgnu_a-mbsrtowcs.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbsrtowcs.o `test -f 'mbsrtowcs.c' || echo '$(srcdir)/'`mbsrtowcs.c + +libgnu_a-mbsrtowcs.obj: mbsrtowcs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbsrtowcs.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbsrtowcs.Tpo -c -o libgnu_a-mbsrtowcs.obj `if test -f 'mbsrtowcs.c'; then $(CYGPATH_W) 'mbsrtowcs.c'; else $(CYGPATH_W) '$(srcdir)/mbsrtowcs.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbsrtowcs.Tpo $(DEPDIR)/libgnu_a-mbsrtowcs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbsrtowcs.c' object='libgnu_a-mbsrtowcs.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbsrtowcs.obj `if test -f 'mbsrtowcs.c'; then $(CYGPATH_W) 'mbsrtowcs.c'; else $(CYGPATH_W) '$(srcdir)/mbsrtowcs.c'; fi` + +libgnu_a-mbtowc.o: mbtowc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbtowc.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbtowc.Tpo -c -o libgnu_a-mbtowc.o `test -f 'mbtowc.c' || echo '$(srcdir)/'`mbtowc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbtowc.Tpo $(DEPDIR)/libgnu_a-mbtowc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbtowc.c' object='libgnu_a-mbtowc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbtowc.o `test -f 'mbtowc.c' || echo '$(srcdir)/'`mbtowc.c + +libgnu_a-mbtowc.obj: mbtowc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbtowc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbtowc.Tpo -c -o libgnu_a-mbtowc.obj `if test -f 'mbtowc.c'; then $(CYGPATH_W) 'mbtowc.c'; else $(CYGPATH_W) '$(srcdir)/mbtowc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbtowc.Tpo $(DEPDIR)/libgnu_a-mbtowc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbtowc.c' object='libgnu_a-mbtowc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbtowc.obj `if test -f 'mbtowc.c'; then $(CYGPATH_W) 'mbtowc.c'; else $(CYGPATH_W) '$(srcdir)/mbtowc.c'; fi` + +libgnu_a-memchr.o: memchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-memchr.o -MD -MP -MF $(DEPDIR)/libgnu_a-memchr.Tpo -c -o libgnu_a-memchr.o `test -f 'memchr.c' || echo '$(srcdir)/'`memchr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-memchr.Tpo $(DEPDIR)/libgnu_a-memchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memchr.c' object='libgnu_a-memchr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-memchr.o `test -f 'memchr.c' || echo '$(srcdir)/'`memchr.c + +libgnu_a-memchr.obj: memchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-memchr.obj -MD -MP -MF $(DEPDIR)/libgnu_a-memchr.Tpo -c -o libgnu_a-memchr.obj `if test -f 'memchr.c'; then $(CYGPATH_W) 'memchr.c'; else $(CYGPATH_W) '$(srcdir)/memchr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-memchr.Tpo $(DEPDIR)/libgnu_a-memchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memchr.c' object='libgnu_a-memchr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-memchr.obj `if test -f 'memchr.c'; then $(CYGPATH_W) 'memchr.c'; else $(CYGPATH_W) '$(srcdir)/memchr.c'; fi` + +libgnu_a-mempcpy.o: mempcpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mempcpy.o -MD -MP -MF $(DEPDIR)/libgnu_a-mempcpy.Tpo -c -o libgnu_a-mempcpy.o `test -f 'mempcpy.c' || echo '$(srcdir)/'`mempcpy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mempcpy.Tpo $(DEPDIR)/libgnu_a-mempcpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mempcpy.c' object='libgnu_a-mempcpy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mempcpy.o `test -f 'mempcpy.c' || echo '$(srcdir)/'`mempcpy.c + +libgnu_a-mempcpy.obj: mempcpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mempcpy.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mempcpy.Tpo -c -o libgnu_a-mempcpy.obj `if test -f 'mempcpy.c'; then $(CYGPATH_W) 'mempcpy.c'; else $(CYGPATH_W) '$(srcdir)/mempcpy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mempcpy.Tpo $(DEPDIR)/libgnu_a-mempcpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mempcpy.c' object='libgnu_a-mempcpy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mempcpy.obj `if test -f 'mempcpy.c'; then $(CYGPATH_W) 'mempcpy.c'; else $(CYGPATH_W) '$(srcdir)/mempcpy.c'; fi` + +libgnu_a-memrchr.o: memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-memrchr.o -MD -MP -MF $(DEPDIR)/libgnu_a-memrchr.Tpo -c -o libgnu_a-memrchr.o `test -f 'memrchr.c' || echo '$(srcdir)/'`memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-memrchr.Tpo $(DEPDIR)/libgnu_a-memrchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memrchr.c' object='libgnu_a-memrchr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-memrchr.o `test -f 'memrchr.c' || echo '$(srcdir)/'`memrchr.c + +libgnu_a-memrchr.obj: memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-memrchr.obj -MD -MP -MF $(DEPDIR)/libgnu_a-memrchr.Tpo -c -o libgnu_a-memrchr.obj `if test -f 'memrchr.c'; then $(CYGPATH_W) 'memrchr.c'; else $(CYGPATH_W) '$(srcdir)/memrchr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-memrchr.Tpo $(DEPDIR)/libgnu_a-memrchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memrchr.c' object='libgnu_a-memrchr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-memrchr.obj `if test -f 'memrchr.c'; then $(CYGPATH_W) 'memrchr.c'; else $(CYGPATH_W) '$(srcdir)/memrchr.c'; fi` + +libgnu_a-mkdir.o: mkdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mkdir.o -MD -MP -MF $(DEPDIR)/libgnu_a-mkdir.Tpo -c -o libgnu_a-mkdir.o `test -f 'mkdir.c' || echo '$(srcdir)/'`mkdir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mkdir.Tpo $(DEPDIR)/libgnu_a-mkdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkdir.c' object='libgnu_a-mkdir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mkdir.o `test -f 'mkdir.c' || echo '$(srcdir)/'`mkdir.c + +libgnu_a-mkdir.obj: mkdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mkdir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mkdir.Tpo -c -o libgnu_a-mkdir.obj `if test -f 'mkdir.c'; then $(CYGPATH_W) 'mkdir.c'; else $(CYGPATH_W) '$(srcdir)/mkdir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mkdir.Tpo $(DEPDIR)/libgnu_a-mkdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkdir.c' object='libgnu_a-mkdir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mkdir.obj `if test -f 'mkdir.c'; then $(CYGPATH_W) 'mkdir.c'; else $(CYGPATH_W) '$(srcdir)/mkdir.c'; fi` + +libgnu_a-mkostemp.o: mkostemp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mkostemp.o -MD -MP -MF $(DEPDIR)/libgnu_a-mkostemp.Tpo -c -o libgnu_a-mkostemp.o `test -f 'mkostemp.c' || echo '$(srcdir)/'`mkostemp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mkostemp.Tpo $(DEPDIR)/libgnu_a-mkostemp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkostemp.c' object='libgnu_a-mkostemp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mkostemp.o `test -f 'mkostemp.c' || echo '$(srcdir)/'`mkostemp.c + +libgnu_a-mkostemp.obj: mkostemp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mkostemp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mkostemp.Tpo -c -o libgnu_a-mkostemp.obj `if test -f 'mkostemp.c'; then $(CYGPATH_W) 'mkostemp.c'; else $(CYGPATH_W) '$(srcdir)/mkostemp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mkostemp.Tpo $(DEPDIR)/libgnu_a-mkostemp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkostemp.c' object='libgnu_a-mkostemp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mkostemp.obj `if test -f 'mkostemp.c'; then $(CYGPATH_W) 'mkostemp.c'; else $(CYGPATH_W) '$(srcdir)/mkostemp.c'; fi` + +libgnu_a-mkstemp.o: mkstemp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mkstemp.o -MD -MP -MF $(DEPDIR)/libgnu_a-mkstemp.Tpo -c -o libgnu_a-mkstemp.o `test -f 'mkstemp.c' || echo '$(srcdir)/'`mkstemp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mkstemp.Tpo $(DEPDIR)/libgnu_a-mkstemp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkstemp.c' object='libgnu_a-mkstemp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mkstemp.o `test -f 'mkstemp.c' || echo '$(srcdir)/'`mkstemp.c + +libgnu_a-mkstemp.obj: mkstemp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mkstemp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mkstemp.Tpo -c -o libgnu_a-mkstemp.obj `if test -f 'mkstemp.c'; then $(CYGPATH_W) 'mkstemp.c'; else $(CYGPATH_W) '$(srcdir)/mkstemp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mkstemp.Tpo $(DEPDIR)/libgnu_a-mkstemp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkstemp.c' object='libgnu_a-mkstemp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mkstemp.obj `if test -f 'mkstemp.c'; then $(CYGPATH_W) 'mkstemp.c'; else $(CYGPATH_W) '$(srcdir)/mkstemp.c'; fi` + +libgnu_a-msvc-inval.o: msvc-inval.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-msvc-inval.o -MD -MP -MF $(DEPDIR)/libgnu_a-msvc-inval.Tpo -c -o libgnu_a-msvc-inval.o `test -f 'msvc-inval.c' || echo '$(srcdir)/'`msvc-inval.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-msvc-inval.Tpo $(DEPDIR)/libgnu_a-msvc-inval.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='msvc-inval.c' object='libgnu_a-msvc-inval.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-msvc-inval.o `test -f 'msvc-inval.c' || echo '$(srcdir)/'`msvc-inval.c + +libgnu_a-msvc-inval.obj: msvc-inval.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-msvc-inval.obj -MD -MP -MF $(DEPDIR)/libgnu_a-msvc-inval.Tpo -c -o libgnu_a-msvc-inval.obj `if test -f 'msvc-inval.c'; then $(CYGPATH_W) 'msvc-inval.c'; else $(CYGPATH_W) '$(srcdir)/msvc-inval.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-msvc-inval.Tpo $(DEPDIR)/libgnu_a-msvc-inval.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='msvc-inval.c' object='libgnu_a-msvc-inval.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-msvc-inval.obj `if test -f 'msvc-inval.c'; then $(CYGPATH_W) 'msvc-inval.c'; else $(CYGPATH_W) '$(srcdir)/msvc-inval.c'; fi` + +libgnu_a-msvc-nothrow.o: msvc-nothrow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-msvc-nothrow.o -MD -MP -MF $(DEPDIR)/libgnu_a-msvc-nothrow.Tpo -c -o libgnu_a-msvc-nothrow.o `test -f 'msvc-nothrow.c' || echo '$(srcdir)/'`msvc-nothrow.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-msvc-nothrow.Tpo $(DEPDIR)/libgnu_a-msvc-nothrow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='msvc-nothrow.c' object='libgnu_a-msvc-nothrow.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-msvc-nothrow.o `test -f 'msvc-nothrow.c' || echo '$(srcdir)/'`msvc-nothrow.c + +libgnu_a-msvc-nothrow.obj: msvc-nothrow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-msvc-nothrow.obj -MD -MP -MF $(DEPDIR)/libgnu_a-msvc-nothrow.Tpo -c -o libgnu_a-msvc-nothrow.obj `if test -f 'msvc-nothrow.c'; then $(CYGPATH_W) 'msvc-nothrow.c'; else $(CYGPATH_W) '$(srcdir)/msvc-nothrow.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-msvc-nothrow.Tpo $(DEPDIR)/libgnu_a-msvc-nothrow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='msvc-nothrow.c' object='libgnu_a-msvc-nothrow.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-msvc-nothrow.obj `if test -f 'msvc-nothrow.c'; then $(CYGPATH_W) 'msvc-nothrow.c'; else $(CYGPATH_W) '$(srcdir)/msvc-nothrow.c'; fi` + +libgnu_a-nanosleep.o: nanosleep.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-nanosleep.o -MD -MP -MF $(DEPDIR)/libgnu_a-nanosleep.Tpo -c -o libgnu_a-nanosleep.o `test -f 'nanosleep.c' || echo '$(srcdir)/'`nanosleep.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-nanosleep.Tpo $(DEPDIR)/libgnu_a-nanosleep.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanosleep.c' object='libgnu_a-nanosleep.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-nanosleep.o `test -f 'nanosleep.c' || echo '$(srcdir)/'`nanosleep.c + +libgnu_a-nanosleep.obj: nanosleep.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-nanosleep.obj -MD -MP -MF $(DEPDIR)/libgnu_a-nanosleep.Tpo -c -o libgnu_a-nanosleep.obj `if test -f 'nanosleep.c'; then $(CYGPATH_W) 'nanosleep.c'; else $(CYGPATH_W) '$(srcdir)/nanosleep.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-nanosleep.Tpo $(DEPDIR)/libgnu_a-nanosleep.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanosleep.c' object='libgnu_a-nanosleep.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-nanosleep.obj `if test -f 'nanosleep.c'; then $(CYGPATH_W) 'nanosleep.c'; else $(CYGPATH_W) '$(srcdir)/nanosleep.c'; fi` + +libgnu_a-nl_langinfo.o: nl_langinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-nl_langinfo.o -MD -MP -MF $(DEPDIR)/libgnu_a-nl_langinfo.Tpo -c -o libgnu_a-nl_langinfo.o `test -f 'nl_langinfo.c' || echo '$(srcdir)/'`nl_langinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-nl_langinfo.Tpo $(DEPDIR)/libgnu_a-nl_langinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nl_langinfo.c' object='libgnu_a-nl_langinfo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-nl_langinfo.o `test -f 'nl_langinfo.c' || echo '$(srcdir)/'`nl_langinfo.c + +libgnu_a-nl_langinfo.obj: nl_langinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-nl_langinfo.obj -MD -MP -MF $(DEPDIR)/libgnu_a-nl_langinfo.Tpo -c -o libgnu_a-nl_langinfo.obj `if test -f 'nl_langinfo.c'; then $(CYGPATH_W) 'nl_langinfo.c'; else $(CYGPATH_W) '$(srcdir)/nl_langinfo.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-nl_langinfo.Tpo $(DEPDIR)/libgnu_a-nl_langinfo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nl_langinfo.c' object='libgnu_a-nl_langinfo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-nl_langinfo.obj `if test -f 'nl_langinfo.c'; then $(CYGPATH_W) 'nl_langinfo.c'; else $(CYGPATH_W) '$(srcdir)/nl_langinfo.c'; fi` + +libgnu_a-nl_langinfo-lock.o: nl_langinfo-lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-nl_langinfo-lock.o -MD -MP -MF $(DEPDIR)/libgnu_a-nl_langinfo-lock.Tpo -c -o libgnu_a-nl_langinfo-lock.o `test -f 'nl_langinfo-lock.c' || echo '$(srcdir)/'`nl_langinfo-lock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-nl_langinfo-lock.Tpo $(DEPDIR)/libgnu_a-nl_langinfo-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nl_langinfo-lock.c' object='libgnu_a-nl_langinfo-lock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-nl_langinfo-lock.o `test -f 'nl_langinfo-lock.c' || echo '$(srcdir)/'`nl_langinfo-lock.c + +libgnu_a-nl_langinfo-lock.obj: nl_langinfo-lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-nl_langinfo-lock.obj -MD -MP -MF $(DEPDIR)/libgnu_a-nl_langinfo-lock.Tpo -c -o libgnu_a-nl_langinfo-lock.obj `if test -f 'nl_langinfo-lock.c'; then $(CYGPATH_W) 'nl_langinfo-lock.c'; else $(CYGPATH_W) '$(srcdir)/nl_langinfo-lock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-nl_langinfo-lock.Tpo $(DEPDIR)/libgnu_a-nl_langinfo-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nl_langinfo-lock.c' object='libgnu_a-nl_langinfo-lock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-nl_langinfo-lock.obj `if test -f 'nl_langinfo-lock.c'; then $(CYGPATH_W) 'nl_langinfo-lock.c'; else $(CYGPATH_W) '$(srcdir)/nl_langinfo-lock.c'; fi` + +libgnu_a-open.o: open.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-open.o -MD -MP -MF $(DEPDIR)/libgnu_a-open.Tpo -c -o libgnu_a-open.o `test -f 'open.c' || echo '$(srcdir)/'`open.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-open.Tpo $(DEPDIR)/libgnu_a-open.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='open.c' object='libgnu_a-open.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-open.o `test -f 'open.c' || echo '$(srcdir)/'`open.c + +libgnu_a-open.obj: open.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-open.obj -MD -MP -MF $(DEPDIR)/libgnu_a-open.Tpo -c -o libgnu_a-open.obj `if test -f 'open.c'; then $(CYGPATH_W) 'open.c'; else $(CYGPATH_W) '$(srcdir)/open.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-open.Tpo $(DEPDIR)/libgnu_a-open.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='open.c' object='libgnu_a-open.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-open.obj `if test -f 'open.c'; then $(CYGPATH_W) 'open.c'; else $(CYGPATH_W) '$(srcdir)/open.c'; fi` + +libgnu_a-openat.o: openat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-openat.o -MD -MP -MF $(DEPDIR)/libgnu_a-openat.Tpo -c -o libgnu_a-openat.o `test -f 'openat.c' || echo '$(srcdir)/'`openat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-openat.Tpo $(DEPDIR)/libgnu_a-openat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openat.c' object='libgnu_a-openat.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-openat.o `test -f 'openat.c' || echo '$(srcdir)/'`openat.c + +libgnu_a-openat.obj: openat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-openat.obj -MD -MP -MF $(DEPDIR)/libgnu_a-openat.Tpo -c -o libgnu_a-openat.obj `if test -f 'openat.c'; then $(CYGPATH_W) 'openat.c'; else $(CYGPATH_W) '$(srcdir)/openat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-openat.Tpo $(DEPDIR)/libgnu_a-openat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openat.c' object='libgnu_a-openat.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-openat.obj `if test -f 'openat.c'; then $(CYGPATH_W) 'openat.c'; else $(CYGPATH_W) '$(srcdir)/openat.c'; fi` + +libgnu_a-openat-die.o: openat-die.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-openat-die.o -MD -MP -MF $(DEPDIR)/libgnu_a-openat-die.Tpo -c -o libgnu_a-openat-die.o `test -f 'openat-die.c' || echo '$(srcdir)/'`openat-die.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-openat-die.Tpo $(DEPDIR)/libgnu_a-openat-die.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openat-die.c' object='libgnu_a-openat-die.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-openat-die.o `test -f 'openat-die.c' || echo '$(srcdir)/'`openat-die.c + +libgnu_a-openat-die.obj: openat-die.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-openat-die.obj -MD -MP -MF $(DEPDIR)/libgnu_a-openat-die.Tpo -c -o libgnu_a-openat-die.obj `if test -f 'openat-die.c'; then $(CYGPATH_W) 'openat-die.c'; else $(CYGPATH_W) '$(srcdir)/openat-die.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-openat-die.Tpo $(DEPDIR)/libgnu_a-openat-die.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openat-die.c' object='libgnu_a-openat-die.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-openat-die.obj `if test -f 'openat-die.c'; then $(CYGPATH_W) 'openat-die.c'; else $(CYGPATH_W) '$(srcdir)/openat-die.c'; fi` + +libgnu_a-opendir.o: opendir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-opendir.o -MD -MP -MF $(DEPDIR)/libgnu_a-opendir.Tpo -c -o libgnu_a-opendir.o `test -f 'opendir.c' || echo '$(srcdir)/'`opendir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-opendir.Tpo $(DEPDIR)/libgnu_a-opendir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opendir.c' object='libgnu_a-opendir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-opendir.o `test -f 'opendir.c' || echo '$(srcdir)/'`opendir.c + +libgnu_a-opendir.obj: opendir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-opendir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-opendir.Tpo -c -o libgnu_a-opendir.obj `if test -f 'opendir.c'; then $(CYGPATH_W) 'opendir.c'; else $(CYGPATH_W) '$(srcdir)/opendir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-opendir.Tpo $(DEPDIR)/libgnu_a-opendir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opendir.c' object='libgnu_a-opendir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-opendir.obj `if test -f 'opendir.c'; then $(CYGPATH_W) 'opendir.c'; else $(CYGPATH_W) '$(srcdir)/opendir.c'; fi` + +libgnu_a-pipe.o: pipe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe.o -MD -MP -MF $(DEPDIR)/libgnu_a-pipe.Tpo -c -o libgnu_a-pipe.o `test -f 'pipe.c' || echo '$(srcdir)/'`pipe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe.Tpo $(DEPDIR)/libgnu_a-pipe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe.c' object='libgnu_a-pipe.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe.o `test -f 'pipe.c' || echo '$(srcdir)/'`pipe.c + +libgnu_a-pipe.obj: pipe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe.obj -MD -MP -MF $(DEPDIR)/libgnu_a-pipe.Tpo -c -o libgnu_a-pipe.obj `if test -f 'pipe.c'; then $(CYGPATH_W) 'pipe.c'; else $(CYGPATH_W) '$(srcdir)/pipe.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe.Tpo $(DEPDIR)/libgnu_a-pipe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe.c' object='libgnu_a-pipe.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe.obj `if test -f 'pipe.c'; then $(CYGPATH_W) 'pipe.c'; else $(CYGPATH_W) '$(srcdir)/pipe.c'; fi` + +libgnu_a-pipe2.o: pipe2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe2.o -MD -MP -MF $(DEPDIR)/libgnu_a-pipe2.Tpo -c -o libgnu_a-pipe2.o `test -f 'pipe2.c' || echo '$(srcdir)/'`pipe2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe2.Tpo $(DEPDIR)/libgnu_a-pipe2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe2.c' object='libgnu_a-pipe2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe2.o `test -f 'pipe2.c' || echo '$(srcdir)/'`pipe2.c + +libgnu_a-pipe2.obj: pipe2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe2.obj -MD -MP -MF $(DEPDIR)/libgnu_a-pipe2.Tpo -c -o libgnu_a-pipe2.obj `if test -f 'pipe2.c'; then $(CYGPATH_W) 'pipe2.c'; else $(CYGPATH_W) '$(srcdir)/pipe2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe2.Tpo $(DEPDIR)/libgnu_a-pipe2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe2.c' object='libgnu_a-pipe2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe2.obj `if test -f 'pipe2.c'; then $(CYGPATH_W) 'pipe2.c'; else $(CYGPATH_W) '$(srcdir)/pipe2.c'; fi` + +libgnu_a-pipe2-safer.o: pipe2-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe2-safer.o -MD -MP -MF $(DEPDIR)/libgnu_a-pipe2-safer.Tpo -c -o libgnu_a-pipe2-safer.o `test -f 'pipe2-safer.c' || echo '$(srcdir)/'`pipe2-safer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe2-safer.Tpo $(DEPDIR)/libgnu_a-pipe2-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe2-safer.c' object='libgnu_a-pipe2-safer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe2-safer.o `test -f 'pipe2-safer.c' || echo '$(srcdir)/'`pipe2-safer.c + +libgnu_a-pipe2-safer.obj: pipe2-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe2-safer.obj -MD -MP -MF $(DEPDIR)/libgnu_a-pipe2-safer.Tpo -c -o libgnu_a-pipe2-safer.obj `if test -f 'pipe2-safer.c'; then $(CYGPATH_W) 'pipe2-safer.c'; else $(CYGPATH_W) '$(srcdir)/pipe2-safer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe2-safer.Tpo $(DEPDIR)/libgnu_a-pipe2-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe2-safer.c' object='libgnu_a-pipe2-safer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe2-safer.obj `if test -f 'pipe2-safer.c'; then $(CYGPATH_W) 'pipe2-safer.c'; else $(CYGPATH_W) '$(srcdir)/pipe2-safer.c'; fi` + +libgnu_a-spawn.o: spawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn.Tpo -c -o libgnu_a-spawn.o `test -f 'spawn.c' || echo '$(srcdir)/'`spawn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn.Tpo $(DEPDIR)/libgnu_a-spawn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn.c' object='libgnu_a-spawn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn.o `test -f 'spawn.c' || echo '$(srcdir)/'`spawn.c + +libgnu_a-spawn.obj: spawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn.Tpo -c -o libgnu_a-spawn.obj `if test -f 'spawn.c'; then $(CYGPATH_W) 'spawn.c'; else $(CYGPATH_W) '$(srcdir)/spawn.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn.Tpo $(DEPDIR)/libgnu_a-spawn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn.c' object='libgnu_a-spawn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn.obj `if test -f 'spawn.c'; then $(CYGPATH_W) 'spawn.c'; else $(CYGPATH_W) '$(srcdir)/spawn.c'; fi` + +libgnu_a-spawni.o: spawni.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawni.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawni.Tpo -c -o libgnu_a-spawni.o `test -f 'spawni.c' || echo '$(srcdir)/'`spawni.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawni.Tpo $(DEPDIR)/libgnu_a-spawni.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawni.c' object='libgnu_a-spawni.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawni.o `test -f 'spawni.c' || echo '$(srcdir)/'`spawni.c + +libgnu_a-spawni.obj: spawni.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawni.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawni.Tpo -c -o libgnu_a-spawni.obj `if test -f 'spawni.c'; then $(CYGPATH_W) 'spawni.c'; else $(CYGPATH_W) '$(srcdir)/spawni.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawni.Tpo $(DEPDIR)/libgnu_a-spawni.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawni.c' object='libgnu_a-spawni.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawni.obj `if test -f 'spawni.c'; then $(CYGPATH_W) 'spawni.c'; else $(CYGPATH_W) '$(srcdir)/spawni.c'; fi` + +libgnu_a-spawn_faction_addchdir.o: spawn_faction_addchdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_addchdir.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_addchdir.Tpo -c -o libgnu_a-spawn_faction_addchdir.o `test -f 'spawn_faction_addchdir.c' || echo '$(srcdir)/'`spawn_faction_addchdir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_addchdir.Tpo $(DEPDIR)/libgnu_a-spawn_faction_addchdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_addchdir.c' object='libgnu_a-spawn_faction_addchdir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_addchdir.o `test -f 'spawn_faction_addchdir.c' || echo '$(srcdir)/'`spawn_faction_addchdir.c + +libgnu_a-spawn_faction_addchdir.obj: spawn_faction_addchdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_addchdir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_addchdir.Tpo -c -o libgnu_a-spawn_faction_addchdir.obj `if test -f 'spawn_faction_addchdir.c'; then $(CYGPATH_W) 'spawn_faction_addchdir.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_addchdir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_addchdir.Tpo $(DEPDIR)/libgnu_a-spawn_faction_addchdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_addchdir.c' object='libgnu_a-spawn_faction_addchdir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_addchdir.obj `if test -f 'spawn_faction_addchdir.c'; then $(CYGPATH_W) 'spawn_faction_addchdir.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_addchdir.c'; fi` + +libgnu_a-spawn_faction_addclose.o: spawn_faction_addclose.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_addclose.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_addclose.Tpo -c -o libgnu_a-spawn_faction_addclose.o `test -f 'spawn_faction_addclose.c' || echo '$(srcdir)/'`spawn_faction_addclose.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_addclose.Tpo $(DEPDIR)/libgnu_a-spawn_faction_addclose.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_addclose.c' object='libgnu_a-spawn_faction_addclose.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_addclose.o `test -f 'spawn_faction_addclose.c' || echo '$(srcdir)/'`spawn_faction_addclose.c + +libgnu_a-spawn_faction_addclose.obj: spawn_faction_addclose.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_addclose.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_addclose.Tpo -c -o libgnu_a-spawn_faction_addclose.obj `if test -f 'spawn_faction_addclose.c'; then $(CYGPATH_W) 'spawn_faction_addclose.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_addclose.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_addclose.Tpo $(DEPDIR)/libgnu_a-spawn_faction_addclose.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_addclose.c' object='libgnu_a-spawn_faction_addclose.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_addclose.obj `if test -f 'spawn_faction_addclose.c'; then $(CYGPATH_W) 'spawn_faction_addclose.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_addclose.c'; fi` + +libgnu_a-spawn_faction_adddup2.o: spawn_faction_adddup2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_adddup2.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_adddup2.Tpo -c -o libgnu_a-spawn_faction_adddup2.o `test -f 'spawn_faction_adddup2.c' || echo '$(srcdir)/'`spawn_faction_adddup2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_adddup2.Tpo $(DEPDIR)/libgnu_a-spawn_faction_adddup2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_adddup2.c' object='libgnu_a-spawn_faction_adddup2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_adddup2.o `test -f 'spawn_faction_adddup2.c' || echo '$(srcdir)/'`spawn_faction_adddup2.c + +libgnu_a-spawn_faction_adddup2.obj: spawn_faction_adddup2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_adddup2.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_adddup2.Tpo -c -o libgnu_a-spawn_faction_adddup2.obj `if test -f 'spawn_faction_adddup2.c'; then $(CYGPATH_W) 'spawn_faction_adddup2.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_adddup2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_adddup2.Tpo $(DEPDIR)/libgnu_a-spawn_faction_adddup2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_adddup2.c' object='libgnu_a-spawn_faction_adddup2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_adddup2.obj `if test -f 'spawn_faction_adddup2.c'; then $(CYGPATH_W) 'spawn_faction_adddup2.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_adddup2.c'; fi` + +libgnu_a-spawn_faction_addopen.o: spawn_faction_addopen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_addopen.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_addopen.Tpo -c -o libgnu_a-spawn_faction_addopen.o `test -f 'spawn_faction_addopen.c' || echo '$(srcdir)/'`spawn_faction_addopen.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_addopen.Tpo $(DEPDIR)/libgnu_a-spawn_faction_addopen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_addopen.c' object='libgnu_a-spawn_faction_addopen.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_addopen.o `test -f 'spawn_faction_addopen.c' || echo '$(srcdir)/'`spawn_faction_addopen.c + +libgnu_a-spawn_faction_addopen.obj: spawn_faction_addopen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_addopen.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_addopen.Tpo -c -o libgnu_a-spawn_faction_addopen.obj `if test -f 'spawn_faction_addopen.c'; then $(CYGPATH_W) 'spawn_faction_addopen.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_addopen.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_addopen.Tpo $(DEPDIR)/libgnu_a-spawn_faction_addopen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_addopen.c' object='libgnu_a-spawn_faction_addopen.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_addopen.obj `if test -f 'spawn_faction_addopen.c'; then $(CYGPATH_W) 'spawn_faction_addopen.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_addopen.c'; fi` + +libgnu_a-spawn_faction_destroy.o: spawn_faction_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_destroy.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_destroy.Tpo -c -o libgnu_a-spawn_faction_destroy.o `test -f 'spawn_faction_destroy.c' || echo '$(srcdir)/'`spawn_faction_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_destroy.Tpo $(DEPDIR)/libgnu_a-spawn_faction_destroy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_destroy.c' object='libgnu_a-spawn_faction_destroy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_destroy.o `test -f 'spawn_faction_destroy.c' || echo '$(srcdir)/'`spawn_faction_destroy.c + +libgnu_a-spawn_faction_destroy.obj: spawn_faction_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_destroy.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_destroy.Tpo -c -o libgnu_a-spawn_faction_destroy.obj `if test -f 'spawn_faction_destroy.c'; then $(CYGPATH_W) 'spawn_faction_destroy.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_destroy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_destroy.Tpo $(DEPDIR)/libgnu_a-spawn_faction_destroy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_destroy.c' object='libgnu_a-spawn_faction_destroy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_destroy.obj `if test -f 'spawn_faction_destroy.c'; then $(CYGPATH_W) 'spawn_faction_destroy.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_destroy.c'; fi` + +libgnu_a-spawn_faction_init.o: spawn_faction_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_init.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_init.Tpo -c -o libgnu_a-spawn_faction_init.o `test -f 'spawn_faction_init.c' || echo '$(srcdir)/'`spawn_faction_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_init.Tpo $(DEPDIR)/libgnu_a-spawn_faction_init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_init.c' object='libgnu_a-spawn_faction_init.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_init.o `test -f 'spawn_faction_init.c' || echo '$(srcdir)/'`spawn_faction_init.c + +libgnu_a-spawn_faction_init.obj: spawn_faction_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn_faction_init.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn_faction_init.Tpo -c -o libgnu_a-spawn_faction_init.obj `if test -f 'spawn_faction_init.c'; then $(CYGPATH_W) 'spawn_faction_init.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_init.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn_faction_init.Tpo $(DEPDIR)/libgnu_a-spawn_faction_init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn_faction_init.c' object='libgnu_a-spawn_faction_init.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn_faction_init.obj `if test -f 'spawn_faction_init.c'; then $(CYGPATH_W) 'spawn_faction_init.c'; else $(CYGPATH_W) '$(srcdir)/spawn_faction_init.c'; fi` + +libgnu_a-spawnattr_destroy.o: spawnattr_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_destroy.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_destroy.Tpo -c -o libgnu_a-spawnattr_destroy.o `test -f 'spawnattr_destroy.c' || echo '$(srcdir)/'`spawnattr_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_destroy.Tpo $(DEPDIR)/libgnu_a-spawnattr_destroy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_destroy.c' object='libgnu_a-spawnattr_destroy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_destroy.o `test -f 'spawnattr_destroy.c' || echo '$(srcdir)/'`spawnattr_destroy.c + +libgnu_a-spawnattr_destroy.obj: spawnattr_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_destroy.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_destroy.Tpo -c -o libgnu_a-spawnattr_destroy.obj `if test -f 'spawnattr_destroy.c'; then $(CYGPATH_W) 'spawnattr_destroy.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_destroy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_destroy.Tpo $(DEPDIR)/libgnu_a-spawnattr_destroy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_destroy.c' object='libgnu_a-spawnattr_destroy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_destroy.obj `if test -f 'spawnattr_destroy.c'; then $(CYGPATH_W) 'spawnattr_destroy.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_destroy.c'; fi` + +libgnu_a-spawnattr_init.o: spawnattr_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_init.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_init.Tpo -c -o libgnu_a-spawnattr_init.o `test -f 'spawnattr_init.c' || echo '$(srcdir)/'`spawnattr_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_init.Tpo $(DEPDIR)/libgnu_a-spawnattr_init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_init.c' object='libgnu_a-spawnattr_init.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_init.o `test -f 'spawnattr_init.c' || echo '$(srcdir)/'`spawnattr_init.c + +libgnu_a-spawnattr_init.obj: spawnattr_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_init.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_init.Tpo -c -o libgnu_a-spawnattr_init.obj `if test -f 'spawnattr_init.c'; then $(CYGPATH_W) 'spawnattr_init.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_init.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_init.Tpo $(DEPDIR)/libgnu_a-spawnattr_init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_init.c' object='libgnu_a-spawnattr_init.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_init.obj `if test -f 'spawnattr_init.c'; then $(CYGPATH_W) 'spawnattr_init.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_init.c'; fi` + +libgnu_a-spawnattr_setflags.o: spawnattr_setflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_setflags.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_setflags.Tpo -c -o libgnu_a-spawnattr_setflags.o `test -f 'spawnattr_setflags.c' || echo '$(srcdir)/'`spawnattr_setflags.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_setflags.Tpo $(DEPDIR)/libgnu_a-spawnattr_setflags.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_setflags.c' object='libgnu_a-spawnattr_setflags.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_setflags.o `test -f 'spawnattr_setflags.c' || echo '$(srcdir)/'`spawnattr_setflags.c + +libgnu_a-spawnattr_setflags.obj: spawnattr_setflags.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_setflags.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_setflags.Tpo -c -o libgnu_a-spawnattr_setflags.obj `if test -f 'spawnattr_setflags.c'; then $(CYGPATH_W) 'spawnattr_setflags.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_setflags.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_setflags.Tpo $(DEPDIR)/libgnu_a-spawnattr_setflags.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_setflags.c' object='libgnu_a-spawnattr_setflags.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_setflags.obj `if test -f 'spawnattr_setflags.c'; then $(CYGPATH_W) 'spawnattr_setflags.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_setflags.c'; fi` + +libgnu_a-spawnattr_setpgroup.o: spawnattr_setpgroup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_setpgroup.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_setpgroup.Tpo -c -o libgnu_a-spawnattr_setpgroup.o `test -f 'spawnattr_setpgroup.c' || echo '$(srcdir)/'`spawnattr_setpgroup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_setpgroup.Tpo $(DEPDIR)/libgnu_a-spawnattr_setpgroup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_setpgroup.c' object='libgnu_a-spawnattr_setpgroup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_setpgroup.o `test -f 'spawnattr_setpgroup.c' || echo '$(srcdir)/'`spawnattr_setpgroup.c + +libgnu_a-spawnattr_setpgroup.obj: spawnattr_setpgroup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_setpgroup.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_setpgroup.Tpo -c -o libgnu_a-spawnattr_setpgroup.obj `if test -f 'spawnattr_setpgroup.c'; then $(CYGPATH_W) 'spawnattr_setpgroup.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_setpgroup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_setpgroup.Tpo $(DEPDIR)/libgnu_a-spawnattr_setpgroup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_setpgroup.c' object='libgnu_a-spawnattr_setpgroup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_setpgroup.obj `if test -f 'spawnattr_setpgroup.c'; then $(CYGPATH_W) 'spawnattr_setpgroup.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_setpgroup.c'; fi` + +libgnu_a-spawnattr_setsigmask.o: spawnattr_setsigmask.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_setsigmask.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_setsigmask.Tpo -c -o libgnu_a-spawnattr_setsigmask.o `test -f 'spawnattr_setsigmask.c' || echo '$(srcdir)/'`spawnattr_setsigmask.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_setsigmask.Tpo $(DEPDIR)/libgnu_a-spawnattr_setsigmask.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_setsigmask.c' object='libgnu_a-spawnattr_setsigmask.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_setsigmask.o `test -f 'spawnattr_setsigmask.c' || echo '$(srcdir)/'`spawnattr_setsigmask.c + +libgnu_a-spawnattr_setsigmask.obj: spawnattr_setsigmask.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnattr_setsigmask.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawnattr_setsigmask.Tpo -c -o libgnu_a-spawnattr_setsigmask.obj `if test -f 'spawnattr_setsigmask.c'; then $(CYGPATH_W) 'spawnattr_setsigmask.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_setsigmask.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnattr_setsigmask.Tpo $(DEPDIR)/libgnu_a-spawnattr_setsigmask.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnattr_setsigmask.c' object='libgnu_a-spawnattr_setsigmask.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnattr_setsigmask.obj `if test -f 'spawnattr_setsigmask.c'; then $(CYGPATH_W) 'spawnattr_setsigmask.c'; else $(CYGPATH_W) '$(srcdir)/spawnattr_setsigmask.c'; fi` + +libgnu_a-spawnp.o: spawnp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnp.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawnp.Tpo -c -o libgnu_a-spawnp.o `test -f 'spawnp.c' || echo '$(srcdir)/'`spawnp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnp.Tpo $(DEPDIR)/libgnu_a-spawnp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnp.c' object='libgnu_a-spawnp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnp.o `test -f 'spawnp.c' || echo '$(srcdir)/'`spawnp.c + +libgnu_a-spawnp.obj: spawnp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawnp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawnp.Tpo -c -o libgnu_a-spawnp.obj `if test -f 'spawnp.c'; then $(CYGPATH_W) 'spawnp.c'; else $(CYGPATH_W) '$(srcdir)/spawnp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawnp.Tpo $(DEPDIR)/libgnu_a-spawnp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawnp.c' object='libgnu_a-spawnp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawnp.obj `if test -f 'spawnp.c'; then $(CYGPATH_W) 'spawnp.c'; else $(CYGPATH_W) '$(srcdir)/spawnp.c'; fi` + +libgnu_a-pselect.o: pselect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pselect.o -MD -MP -MF $(DEPDIR)/libgnu_a-pselect.Tpo -c -o libgnu_a-pselect.o `test -f 'pselect.c' || echo '$(srcdir)/'`pselect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pselect.Tpo $(DEPDIR)/libgnu_a-pselect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pselect.c' object='libgnu_a-pselect.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pselect.o `test -f 'pselect.c' || echo '$(srcdir)/'`pselect.c + +libgnu_a-pselect.obj: pselect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pselect.obj -MD -MP -MF $(DEPDIR)/libgnu_a-pselect.Tpo -c -o libgnu_a-pselect.obj `if test -f 'pselect.c'; then $(CYGPATH_W) 'pselect.c'; else $(CYGPATH_W) '$(srcdir)/pselect.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pselect.Tpo $(DEPDIR)/libgnu_a-pselect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pselect.c' object='libgnu_a-pselect.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pselect.obj `if test -f 'pselect.c'; then $(CYGPATH_W) 'pselect.c'; else $(CYGPATH_W) '$(srcdir)/pselect.c'; fi` + +libgnu_a-pthread_sigmask.o: pthread_sigmask.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pthread_sigmask.o -MD -MP -MF $(DEPDIR)/libgnu_a-pthread_sigmask.Tpo -c -o libgnu_a-pthread_sigmask.o `test -f 'pthread_sigmask.c' || echo '$(srcdir)/'`pthread_sigmask.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pthread_sigmask.Tpo $(DEPDIR)/libgnu_a-pthread_sigmask.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pthread_sigmask.c' object='libgnu_a-pthread_sigmask.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pthread_sigmask.o `test -f 'pthread_sigmask.c' || echo '$(srcdir)/'`pthread_sigmask.c + +libgnu_a-pthread_sigmask.obj: pthread_sigmask.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pthread_sigmask.obj -MD -MP -MF $(DEPDIR)/libgnu_a-pthread_sigmask.Tpo -c -o libgnu_a-pthread_sigmask.obj `if test -f 'pthread_sigmask.c'; then $(CYGPATH_W) 'pthread_sigmask.c'; else $(CYGPATH_W) '$(srcdir)/pthread_sigmask.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pthread_sigmask.Tpo $(DEPDIR)/libgnu_a-pthread_sigmask.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pthread_sigmask.c' object='libgnu_a-pthread_sigmask.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pthread_sigmask.obj `if test -f 'pthread_sigmask.c'; then $(CYGPATH_W) 'pthread_sigmask.c'; else $(CYGPATH_W) '$(srcdir)/pthread_sigmask.c'; fi` + +libgnu_a-quotearg.o: quotearg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-quotearg.o -MD -MP -MF $(DEPDIR)/libgnu_a-quotearg.Tpo -c -o libgnu_a-quotearg.o `test -f 'quotearg.c' || echo '$(srcdir)/'`quotearg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-quotearg.Tpo $(DEPDIR)/libgnu_a-quotearg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quotearg.c' object='libgnu_a-quotearg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-quotearg.o `test -f 'quotearg.c' || echo '$(srcdir)/'`quotearg.c + +libgnu_a-quotearg.obj: quotearg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-quotearg.obj -MD -MP -MF $(DEPDIR)/libgnu_a-quotearg.Tpo -c -o libgnu_a-quotearg.obj `if test -f 'quotearg.c'; then $(CYGPATH_W) 'quotearg.c'; else $(CYGPATH_W) '$(srcdir)/quotearg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-quotearg.Tpo $(DEPDIR)/libgnu_a-quotearg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quotearg.c' object='libgnu_a-quotearg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-quotearg.obj `if test -f 'quotearg.c'; then $(CYGPATH_W) 'quotearg.c'; else $(CYGPATH_W) '$(srcdir)/quotearg.c'; fi` + +libgnu_a-raise.o: raise.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-raise.o -MD -MP -MF $(DEPDIR)/libgnu_a-raise.Tpo -c -o libgnu_a-raise.o `test -f 'raise.c' || echo '$(srcdir)/'`raise.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-raise.Tpo $(DEPDIR)/libgnu_a-raise.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='raise.c' object='libgnu_a-raise.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-raise.o `test -f 'raise.c' || echo '$(srcdir)/'`raise.c + +libgnu_a-raise.obj: raise.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-raise.obj -MD -MP -MF $(DEPDIR)/libgnu_a-raise.Tpo -c -o libgnu_a-raise.obj `if test -f 'raise.c'; then $(CYGPATH_W) 'raise.c'; else $(CYGPATH_W) '$(srcdir)/raise.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-raise.Tpo $(DEPDIR)/libgnu_a-raise.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='raise.c' object='libgnu_a-raise.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-raise.obj `if test -f 'raise.c'; then $(CYGPATH_W) 'raise.c'; else $(CYGPATH_W) '$(srcdir)/raise.c'; fi` + +libgnu_a-rawmemchr.o: rawmemchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rawmemchr.o -MD -MP -MF $(DEPDIR)/libgnu_a-rawmemchr.Tpo -c -o libgnu_a-rawmemchr.o `test -f 'rawmemchr.c' || echo '$(srcdir)/'`rawmemchr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rawmemchr.Tpo $(DEPDIR)/libgnu_a-rawmemchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rawmemchr.c' object='libgnu_a-rawmemchr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rawmemchr.o `test -f 'rawmemchr.c' || echo '$(srcdir)/'`rawmemchr.c + +libgnu_a-rawmemchr.obj: rawmemchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rawmemchr.obj -MD -MP -MF $(DEPDIR)/libgnu_a-rawmemchr.Tpo -c -o libgnu_a-rawmemchr.obj `if test -f 'rawmemchr.c'; then $(CYGPATH_W) 'rawmemchr.c'; else $(CYGPATH_W) '$(srcdir)/rawmemchr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rawmemchr.Tpo $(DEPDIR)/libgnu_a-rawmemchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rawmemchr.c' object='libgnu_a-rawmemchr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rawmemchr.obj `if test -f 'rawmemchr.c'; then $(CYGPATH_W) 'rawmemchr.c'; else $(CYGPATH_W) '$(srcdir)/rawmemchr.c'; fi` + +libgnu_a-readdir.o: readdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-readdir.o -MD -MP -MF $(DEPDIR)/libgnu_a-readdir.Tpo -c -o libgnu_a-readdir.o `test -f 'readdir.c' || echo '$(srcdir)/'`readdir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-readdir.Tpo $(DEPDIR)/libgnu_a-readdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='readdir.c' object='libgnu_a-readdir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-readdir.o `test -f 'readdir.c' || echo '$(srcdir)/'`readdir.c + +libgnu_a-readdir.obj: readdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-readdir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-readdir.Tpo -c -o libgnu_a-readdir.obj `if test -f 'readdir.c'; then $(CYGPATH_W) 'readdir.c'; else $(CYGPATH_W) '$(srcdir)/readdir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-readdir.Tpo $(DEPDIR)/libgnu_a-readdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='readdir.c' object='libgnu_a-readdir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-readdir.obj `if test -f 'readdir.c'; then $(CYGPATH_W) 'readdir.c'; else $(CYGPATH_W) '$(srcdir)/readdir.c'; fi` + +libgnu_a-readlink.o: readlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-readlink.o -MD -MP -MF $(DEPDIR)/libgnu_a-readlink.Tpo -c -o libgnu_a-readlink.o `test -f 'readlink.c' || echo '$(srcdir)/'`readlink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-readlink.Tpo $(DEPDIR)/libgnu_a-readlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='readlink.c' object='libgnu_a-readlink.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-readlink.o `test -f 'readlink.c' || echo '$(srcdir)/'`readlink.c + +libgnu_a-readlink.obj: readlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-readlink.obj -MD -MP -MF $(DEPDIR)/libgnu_a-readlink.Tpo -c -o libgnu_a-readlink.obj `if test -f 'readlink.c'; then $(CYGPATH_W) 'readlink.c'; else $(CYGPATH_W) '$(srcdir)/readlink.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-readlink.Tpo $(DEPDIR)/libgnu_a-readlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='readlink.c' object='libgnu_a-readlink.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-readlink.obj `if test -f 'readlink.c'; then $(CYGPATH_W) 'readlink.c'; else $(CYGPATH_W) '$(srcdir)/readlink.c'; fi` + +libgnu_a-reallocarray.o: reallocarray.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-reallocarray.o -MD -MP -MF $(DEPDIR)/libgnu_a-reallocarray.Tpo -c -o libgnu_a-reallocarray.o `test -f 'reallocarray.c' || echo '$(srcdir)/'`reallocarray.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-reallocarray.Tpo $(DEPDIR)/libgnu_a-reallocarray.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='reallocarray.c' object='libgnu_a-reallocarray.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-reallocarray.o `test -f 'reallocarray.c' || echo '$(srcdir)/'`reallocarray.c + +libgnu_a-reallocarray.obj: reallocarray.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-reallocarray.obj -MD -MP -MF $(DEPDIR)/libgnu_a-reallocarray.Tpo -c -o libgnu_a-reallocarray.obj `if test -f 'reallocarray.c'; then $(CYGPATH_W) 'reallocarray.c'; else $(CYGPATH_W) '$(srcdir)/reallocarray.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-reallocarray.Tpo $(DEPDIR)/libgnu_a-reallocarray.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='reallocarray.c' object='libgnu_a-reallocarray.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-reallocarray.obj `if test -f 'reallocarray.c'; then $(CYGPATH_W) 'reallocarray.c'; else $(CYGPATH_W) '$(srcdir)/reallocarray.c'; fi` + +libgnu_a-recv.o: recv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-recv.o -MD -MP -MF $(DEPDIR)/libgnu_a-recv.Tpo -c -o libgnu_a-recv.o `test -f 'recv.c' || echo '$(srcdir)/'`recv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-recv.Tpo $(DEPDIR)/libgnu_a-recv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='recv.c' object='libgnu_a-recv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-recv.o `test -f 'recv.c' || echo '$(srcdir)/'`recv.c + +libgnu_a-recv.obj: recv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-recv.obj -MD -MP -MF $(DEPDIR)/libgnu_a-recv.Tpo -c -o libgnu_a-recv.obj `if test -f 'recv.c'; then $(CYGPATH_W) 'recv.c'; else $(CYGPATH_W) '$(srcdir)/recv.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-recv.Tpo $(DEPDIR)/libgnu_a-recv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='recv.c' object='libgnu_a-recv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-recv.obj `if test -f 'recv.c'; then $(CYGPATH_W) 'recv.c'; else $(CYGPATH_W) '$(srcdir)/recv.c'; fi` + +libgnu_a-regex.o: regex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regex.o -MD -MP -MF $(DEPDIR)/libgnu_a-regex.Tpo -c -o libgnu_a-regex.o `test -f 'regex.c' || echo '$(srcdir)/'`regex.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regex.Tpo $(DEPDIR)/libgnu_a-regex.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regex.c' object='libgnu_a-regex.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regex.o `test -f 'regex.c' || echo '$(srcdir)/'`regex.c + +libgnu_a-regex.obj: regex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regex.obj -MD -MP -MF $(DEPDIR)/libgnu_a-regex.Tpo -c -o libgnu_a-regex.obj `if test -f 'regex.c'; then $(CYGPATH_W) 'regex.c'; else $(CYGPATH_W) '$(srcdir)/regex.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regex.Tpo $(DEPDIR)/libgnu_a-regex.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regex.c' object='libgnu_a-regex.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regex.obj `if test -f 'regex.c'; then $(CYGPATH_W) 'regex.c'; else $(CYGPATH_W) '$(srcdir)/regex.c'; fi` + +libgnu_a-rename.o: rename.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rename.o -MD -MP -MF $(DEPDIR)/libgnu_a-rename.Tpo -c -o libgnu_a-rename.o `test -f 'rename.c' || echo '$(srcdir)/'`rename.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rename.Tpo $(DEPDIR)/libgnu_a-rename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rename.c' object='libgnu_a-rename.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rename.o `test -f 'rename.c' || echo '$(srcdir)/'`rename.c + +libgnu_a-rename.obj: rename.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rename.obj -MD -MP -MF $(DEPDIR)/libgnu_a-rename.Tpo -c -o libgnu_a-rename.obj `if test -f 'rename.c'; then $(CYGPATH_W) 'rename.c'; else $(CYGPATH_W) '$(srcdir)/rename.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rename.Tpo $(DEPDIR)/libgnu_a-rename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rename.c' object='libgnu_a-rename.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rename.obj `if test -f 'rename.c'; then $(CYGPATH_W) 'rename.c'; else $(CYGPATH_W) '$(srcdir)/rename.c'; fi` + +libgnu_a-rewinddir.o: rewinddir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rewinddir.o -MD -MP -MF $(DEPDIR)/libgnu_a-rewinddir.Tpo -c -o libgnu_a-rewinddir.o `test -f 'rewinddir.c' || echo '$(srcdir)/'`rewinddir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rewinddir.Tpo $(DEPDIR)/libgnu_a-rewinddir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rewinddir.c' object='libgnu_a-rewinddir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rewinddir.o `test -f 'rewinddir.c' || echo '$(srcdir)/'`rewinddir.c + +libgnu_a-rewinddir.obj: rewinddir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rewinddir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-rewinddir.Tpo -c -o libgnu_a-rewinddir.obj `if test -f 'rewinddir.c'; then $(CYGPATH_W) 'rewinddir.c'; else $(CYGPATH_W) '$(srcdir)/rewinddir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rewinddir.Tpo $(DEPDIR)/libgnu_a-rewinddir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rewinddir.c' object='libgnu_a-rewinddir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rewinddir.obj `if test -f 'rewinddir.c'; then $(CYGPATH_W) 'rewinddir.c'; else $(CYGPATH_W) '$(srcdir)/rewinddir.c'; fi` + +libgnu_a-rmdir.o: rmdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rmdir.o -MD -MP -MF $(DEPDIR)/libgnu_a-rmdir.Tpo -c -o libgnu_a-rmdir.o `test -f 'rmdir.c' || echo '$(srcdir)/'`rmdir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rmdir.Tpo $(DEPDIR)/libgnu_a-rmdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rmdir.c' object='libgnu_a-rmdir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rmdir.o `test -f 'rmdir.c' || echo '$(srcdir)/'`rmdir.c + +libgnu_a-rmdir.obj: rmdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-rmdir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-rmdir.Tpo -c -o libgnu_a-rmdir.obj `if test -f 'rmdir.c'; then $(CYGPATH_W) 'rmdir.c'; else $(CYGPATH_W) '$(srcdir)/rmdir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-rmdir.Tpo $(DEPDIR)/libgnu_a-rmdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rmdir.c' object='libgnu_a-rmdir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-rmdir.obj `if test -f 'rmdir.c'; then $(CYGPATH_W) 'rmdir.c'; else $(CYGPATH_W) '$(srcdir)/rmdir.c'; fi` + +libgnu_a-save-cwd.o: save-cwd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-save-cwd.o -MD -MP -MF $(DEPDIR)/libgnu_a-save-cwd.Tpo -c -o libgnu_a-save-cwd.o `test -f 'save-cwd.c' || echo '$(srcdir)/'`save-cwd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-save-cwd.Tpo $(DEPDIR)/libgnu_a-save-cwd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='save-cwd.c' object='libgnu_a-save-cwd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-save-cwd.o `test -f 'save-cwd.c' || echo '$(srcdir)/'`save-cwd.c + +libgnu_a-save-cwd.obj: save-cwd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-save-cwd.obj -MD -MP -MF $(DEPDIR)/libgnu_a-save-cwd.Tpo -c -o libgnu_a-save-cwd.obj `if test -f 'save-cwd.c'; then $(CYGPATH_W) 'save-cwd.c'; else $(CYGPATH_W) '$(srcdir)/save-cwd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-save-cwd.Tpo $(DEPDIR)/libgnu_a-save-cwd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='save-cwd.c' object='libgnu_a-save-cwd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-save-cwd.obj `if test -f 'save-cwd.c'; then $(CYGPATH_W) 'save-cwd.c'; else $(CYGPATH_W) '$(srcdir)/save-cwd.c'; fi` + +malloc/libgnu_a-scratch_buffer_dupfree.o: malloc/scratch_buffer_dupfree.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_dupfree.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Tpo -c -o malloc/libgnu_a-scratch_buffer_dupfree.o `test -f 'malloc/scratch_buffer_dupfree.c' || echo '$(srcdir)/'`malloc/scratch_buffer_dupfree.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_dupfree.c' object='malloc/libgnu_a-scratch_buffer_dupfree.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_dupfree.o `test -f 'malloc/scratch_buffer_dupfree.c' || echo '$(srcdir)/'`malloc/scratch_buffer_dupfree.c + +malloc/libgnu_a-scratch_buffer_dupfree.obj: malloc/scratch_buffer_dupfree.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_dupfree.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Tpo -c -o malloc/libgnu_a-scratch_buffer_dupfree.obj `if test -f 'malloc/scratch_buffer_dupfree.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_dupfree.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_dupfree.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_dupfree.c' object='malloc/libgnu_a-scratch_buffer_dupfree.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_dupfree.obj `if test -f 'malloc/scratch_buffer_dupfree.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_dupfree.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_dupfree.c'; fi` + +malloc/libgnu_a-scratch_buffer_grow.o: malloc/scratch_buffer_grow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_grow.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Tpo -c -o malloc/libgnu_a-scratch_buffer_grow.o `test -f 'malloc/scratch_buffer_grow.c' || echo '$(srcdir)/'`malloc/scratch_buffer_grow.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_grow.c' object='malloc/libgnu_a-scratch_buffer_grow.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_grow.o `test -f 'malloc/scratch_buffer_grow.c' || echo '$(srcdir)/'`malloc/scratch_buffer_grow.c + +malloc/libgnu_a-scratch_buffer_grow.obj: malloc/scratch_buffer_grow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_grow.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Tpo -c -o malloc/libgnu_a-scratch_buffer_grow.obj `if test -f 'malloc/scratch_buffer_grow.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_grow.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_grow.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_grow.c' object='malloc/libgnu_a-scratch_buffer_grow.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_grow.obj `if test -f 'malloc/scratch_buffer_grow.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_grow.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_grow.c'; fi` + +malloc/libgnu_a-scratch_buffer_grow_preserve.o: malloc/scratch_buffer_grow_preserve.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_grow_preserve.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Tpo -c -o malloc/libgnu_a-scratch_buffer_grow_preserve.o `test -f 'malloc/scratch_buffer_grow_preserve.c' || echo '$(srcdir)/'`malloc/scratch_buffer_grow_preserve.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_grow_preserve.c' object='malloc/libgnu_a-scratch_buffer_grow_preserve.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_grow_preserve.o `test -f 'malloc/scratch_buffer_grow_preserve.c' || echo '$(srcdir)/'`malloc/scratch_buffer_grow_preserve.c + +malloc/libgnu_a-scratch_buffer_grow_preserve.obj: malloc/scratch_buffer_grow_preserve.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_grow_preserve.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Tpo -c -o malloc/libgnu_a-scratch_buffer_grow_preserve.obj `if test -f 'malloc/scratch_buffer_grow_preserve.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_grow_preserve.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_grow_preserve.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_grow_preserve.c' object='malloc/libgnu_a-scratch_buffer_grow_preserve.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_grow_preserve.obj `if test -f 'malloc/scratch_buffer_grow_preserve.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_grow_preserve.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_grow_preserve.c'; fi` + +malloc/libgnu_a-scratch_buffer_set_array_size.o: malloc/scratch_buffer_set_array_size.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_set_array_size.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Tpo -c -o malloc/libgnu_a-scratch_buffer_set_array_size.o `test -f 'malloc/scratch_buffer_set_array_size.c' || echo '$(srcdir)/'`malloc/scratch_buffer_set_array_size.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_set_array_size.c' object='malloc/libgnu_a-scratch_buffer_set_array_size.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_set_array_size.o `test -f 'malloc/scratch_buffer_set_array_size.c' || echo '$(srcdir)/'`malloc/scratch_buffer_set_array_size.c + +malloc/libgnu_a-scratch_buffer_set_array_size.obj: malloc/scratch_buffer_set_array_size.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-scratch_buffer_set_array_size.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Tpo -c -o malloc/libgnu_a-scratch_buffer_set_array_size.obj `if test -f 'malloc/scratch_buffer_set_array_size.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_set_array_size.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_set_array_size.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Tpo malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/scratch_buffer_set_array_size.c' object='malloc/libgnu_a-scratch_buffer_set_array_size.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-scratch_buffer_set_array_size.obj `if test -f 'malloc/scratch_buffer_set_array_size.c'; then $(CYGPATH_W) 'malloc/scratch_buffer_set_array_size.c'; else $(CYGPATH_W) '$(srcdir)/malloc/scratch_buffer_set_array_size.c'; fi` + +libgnu_a-secure_getenv.o: secure_getenv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-secure_getenv.o -MD -MP -MF $(DEPDIR)/libgnu_a-secure_getenv.Tpo -c -o libgnu_a-secure_getenv.o `test -f 'secure_getenv.c' || echo '$(srcdir)/'`secure_getenv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-secure_getenv.Tpo $(DEPDIR)/libgnu_a-secure_getenv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='secure_getenv.c' object='libgnu_a-secure_getenv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-secure_getenv.o `test -f 'secure_getenv.c' || echo '$(srcdir)/'`secure_getenv.c + +libgnu_a-secure_getenv.obj: secure_getenv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-secure_getenv.obj -MD -MP -MF $(DEPDIR)/libgnu_a-secure_getenv.Tpo -c -o libgnu_a-secure_getenv.obj `if test -f 'secure_getenv.c'; then $(CYGPATH_W) 'secure_getenv.c'; else $(CYGPATH_W) '$(srcdir)/secure_getenv.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-secure_getenv.Tpo $(DEPDIR)/libgnu_a-secure_getenv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='secure_getenv.c' object='libgnu_a-secure_getenv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-secure_getenv.obj `if test -f 'secure_getenv.c'; then $(CYGPATH_W) 'secure_getenv.c'; else $(CYGPATH_W) '$(srcdir)/secure_getenv.c'; fi` + +libgnu_a-select.o: select.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-select.o -MD -MP -MF $(DEPDIR)/libgnu_a-select.Tpo -c -o libgnu_a-select.o `test -f 'select.c' || echo '$(srcdir)/'`select.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-select.Tpo $(DEPDIR)/libgnu_a-select.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='select.c' object='libgnu_a-select.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-select.o `test -f 'select.c' || echo '$(srcdir)/'`select.c + +libgnu_a-select.obj: select.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-select.obj -MD -MP -MF $(DEPDIR)/libgnu_a-select.Tpo -c -o libgnu_a-select.obj `if test -f 'select.c'; then $(CYGPATH_W) 'select.c'; else $(CYGPATH_W) '$(srcdir)/select.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-select.Tpo $(DEPDIR)/libgnu_a-select.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='select.c' object='libgnu_a-select.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-select.obj `if test -f 'select.c'; then $(CYGPATH_W) 'select.c'; else $(CYGPATH_W) '$(srcdir)/select.c'; fi` + +libgnu_a-send.o: send.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-send.o -MD -MP -MF $(DEPDIR)/libgnu_a-send.Tpo -c -o libgnu_a-send.o `test -f 'send.c' || echo '$(srcdir)/'`send.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-send.Tpo $(DEPDIR)/libgnu_a-send.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='send.c' object='libgnu_a-send.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-send.o `test -f 'send.c' || echo '$(srcdir)/'`send.c + +libgnu_a-send.obj: send.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-send.obj -MD -MP -MF $(DEPDIR)/libgnu_a-send.Tpo -c -o libgnu_a-send.obj `if test -f 'send.c'; then $(CYGPATH_W) 'send.c'; else $(CYGPATH_W) '$(srcdir)/send.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-send.Tpo $(DEPDIR)/libgnu_a-send.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='send.c' object='libgnu_a-send.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-send.obj `if test -f 'send.c'; then $(CYGPATH_W) 'send.c'; else $(CYGPATH_W) '$(srcdir)/send.c'; fi` + +libgnu_a-setlocale_null.o: setlocale_null.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-setlocale_null.o -MD -MP -MF $(DEPDIR)/libgnu_a-setlocale_null.Tpo -c -o libgnu_a-setlocale_null.o `test -f 'setlocale_null.c' || echo '$(srcdir)/'`setlocale_null.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-setlocale_null.Tpo $(DEPDIR)/libgnu_a-setlocale_null.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setlocale_null.c' object='libgnu_a-setlocale_null.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-setlocale_null.o `test -f 'setlocale_null.c' || echo '$(srcdir)/'`setlocale_null.c + +libgnu_a-setlocale_null.obj: setlocale_null.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-setlocale_null.obj -MD -MP -MF $(DEPDIR)/libgnu_a-setlocale_null.Tpo -c -o libgnu_a-setlocale_null.obj `if test -f 'setlocale_null.c'; then $(CYGPATH_W) 'setlocale_null.c'; else $(CYGPATH_W) '$(srcdir)/setlocale_null.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-setlocale_null.Tpo $(DEPDIR)/libgnu_a-setlocale_null.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setlocale_null.c' object='libgnu_a-setlocale_null.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-setlocale_null.obj `if test -f 'setlocale_null.c'; then $(CYGPATH_W) 'setlocale_null.c'; else $(CYGPATH_W) '$(srcdir)/setlocale_null.c'; fi` + +libgnu_a-setlocale-lock.o: setlocale-lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-setlocale-lock.o -MD -MP -MF $(DEPDIR)/libgnu_a-setlocale-lock.Tpo -c -o libgnu_a-setlocale-lock.o `test -f 'setlocale-lock.c' || echo '$(srcdir)/'`setlocale-lock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-setlocale-lock.Tpo $(DEPDIR)/libgnu_a-setlocale-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setlocale-lock.c' object='libgnu_a-setlocale-lock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-setlocale-lock.o `test -f 'setlocale-lock.c' || echo '$(srcdir)/'`setlocale-lock.c + +libgnu_a-setlocale-lock.obj: setlocale-lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-setlocale-lock.obj -MD -MP -MF $(DEPDIR)/libgnu_a-setlocale-lock.Tpo -c -o libgnu_a-setlocale-lock.obj `if test -f 'setlocale-lock.c'; then $(CYGPATH_W) 'setlocale-lock.c'; else $(CYGPATH_W) '$(srcdir)/setlocale-lock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-setlocale-lock.Tpo $(DEPDIR)/libgnu_a-setlocale-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setlocale-lock.c' object='libgnu_a-setlocale-lock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-setlocale-lock.obj `if test -f 'setlocale-lock.c'; then $(CYGPATH_W) 'setlocale-lock.c'; else $(CYGPATH_W) '$(srcdir)/setlocale-lock.c'; fi` + +libgnu_a-setsockopt.o: setsockopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-setsockopt.o -MD -MP -MF $(DEPDIR)/libgnu_a-setsockopt.Tpo -c -o libgnu_a-setsockopt.o `test -f 'setsockopt.c' || echo '$(srcdir)/'`setsockopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-setsockopt.Tpo $(DEPDIR)/libgnu_a-setsockopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setsockopt.c' object='libgnu_a-setsockopt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-setsockopt.o `test -f 'setsockopt.c' || echo '$(srcdir)/'`setsockopt.c + +libgnu_a-setsockopt.obj: setsockopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-setsockopt.obj -MD -MP -MF $(DEPDIR)/libgnu_a-setsockopt.Tpo -c -o libgnu_a-setsockopt.obj `if test -f 'setsockopt.c'; then $(CYGPATH_W) 'setsockopt.c'; else $(CYGPATH_W) '$(srcdir)/setsockopt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-setsockopt.Tpo $(DEPDIR)/libgnu_a-setsockopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setsockopt.c' object='libgnu_a-setsockopt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-setsockopt.obj `if test -f 'setsockopt.c'; then $(CYGPATH_W) 'setsockopt.c'; else $(CYGPATH_W) '$(srcdir)/setsockopt.c'; fi` + +libgnu_a-sigaction.o: sigaction.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sigaction.o -MD -MP -MF $(DEPDIR)/libgnu_a-sigaction.Tpo -c -o libgnu_a-sigaction.o `test -f 'sigaction.c' || echo '$(srcdir)/'`sigaction.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sigaction.Tpo $(DEPDIR)/libgnu_a-sigaction.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sigaction.c' object='libgnu_a-sigaction.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sigaction.o `test -f 'sigaction.c' || echo '$(srcdir)/'`sigaction.c + +libgnu_a-sigaction.obj: sigaction.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sigaction.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sigaction.Tpo -c -o libgnu_a-sigaction.obj `if test -f 'sigaction.c'; then $(CYGPATH_W) 'sigaction.c'; else $(CYGPATH_W) '$(srcdir)/sigaction.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sigaction.Tpo $(DEPDIR)/libgnu_a-sigaction.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sigaction.c' object='libgnu_a-sigaction.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sigaction.obj `if test -f 'sigaction.c'; then $(CYGPATH_W) 'sigaction.c'; else $(CYGPATH_W) '$(srcdir)/sigaction.c'; fi` + +libgnu_a-sig-handler.o: sig-handler.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sig-handler.o -MD -MP -MF $(DEPDIR)/libgnu_a-sig-handler.Tpo -c -o libgnu_a-sig-handler.o `test -f 'sig-handler.c' || echo '$(srcdir)/'`sig-handler.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sig-handler.Tpo $(DEPDIR)/libgnu_a-sig-handler.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sig-handler.c' object='libgnu_a-sig-handler.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sig-handler.o `test -f 'sig-handler.c' || echo '$(srcdir)/'`sig-handler.c + +libgnu_a-sig-handler.obj: sig-handler.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sig-handler.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sig-handler.Tpo -c -o libgnu_a-sig-handler.obj `if test -f 'sig-handler.c'; then $(CYGPATH_W) 'sig-handler.c'; else $(CYGPATH_W) '$(srcdir)/sig-handler.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sig-handler.Tpo $(DEPDIR)/libgnu_a-sig-handler.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sig-handler.c' object='libgnu_a-sig-handler.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sig-handler.obj `if test -f 'sig-handler.c'; then $(CYGPATH_W) 'sig-handler.c'; else $(CYGPATH_W) '$(srcdir)/sig-handler.c'; fi` + +libgnu_a-sigprocmask.o: sigprocmask.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sigprocmask.o -MD -MP -MF $(DEPDIR)/libgnu_a-sigprocmask.Tpo -c -o libgnu_a-sigprocmask.o `test -f 'sigprocmask.c' || echo '$(srcdir)/'`sigprocmask.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sigprocmask.Tpo $(DEPDIR)/libgnu_a-sigprocmask.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sigprocmask.c' object='libgnu_a-sigprocmask.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sigprocmask.o `test -f 'sigprocmask.c' || echo '$(srcdir)/'`sigprocmask.c + +libgnu_a-sigprocmask.obj: sigprocmask.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sigprocmask.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sigprocmask.Tpo -c -o libgnu_a-sigprocmask.obj `if test -f 'sigprocmask.c'; then $(CYGPATH_W) 'sigprocmask.c'; else $(CYGPATH_W) '$(srcdir)/sigprocmask.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sigprocmask.Tpo $(DEPDIR)/libgnu_a-sigprocmask.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sigprocmask.c' object='libgnu_a-sigprocmask.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sigprocmask.obj `if test -f 'sigprocmask.c'; then $(CYGPATH_W) 'sigprocmask.c'; else $(CYGPATH_W) '$(srcdir)/sigprocmask.c'; fi` + +libgnu_a-socket.o: socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-socket.o -MD -MP -MF $(DEPDIR)/libgnu_a-socket.Tpo -c -o libgnu_a-socket.o `test -f 'socket.c' || echo '$(srcdir)/'`socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-socket.Tpo $(DEPDIR)/libgnu_a-socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socket.c' object='libgnu_a-socket.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-socket.o `test -f 'socket.c' || echo '$(srcdir)/'`socket.c + +libgnu_a-socket.obj: socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-socket.obj -MD -MP -MF $(DEPDIR)/libgnu_a-socket.Tpo -c -o libgnu_a-socket.obj `if test -f 'socket.c'; then $(CYGPATH_W) 'socket.c'; else $(CYGPATH_W) '$(srcdir)/socket.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-socket.Tpo $(DEPDIR)/libgnu_a-socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socket.c' object='libgnu_a-socket.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-socket.obj `if test -f 'socket.c'; then $(CYGPATH_W) 'socket.c'; else $(CYGPATH_W) '$(srcdir)/socket.c'; fi` + +libgnu_a-sockets.o: sockets.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sockets.o -MD -MP -MF $(DEPDIR)/libgnu_a-sockets.Tpo -c -o libgnu_a-sockets.o `test -f 'sockets.c' || echo '$(srcdir)/'`sockets.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sockets.Tpo $(DEPDIR)/libgnu_a-sockets.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sockets.c' object='libgnu_a-sockets.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sockets.o `test -f 'sockets.c' || echo '$(srcdir)/'`sockets.c + +libgnu_a-sockets.obj: sockets.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sockets.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sockets.Tpo -c -o libgnu_a-sockets.obj `if test -f 'sockets.c'; then $(CYGPATH_W) 'sockets.c'; else $(CYGPATH_W) '$(srcdir)/sockets.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sockets.Tpo $(DEPDIR)/libgnu_a-sockets.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sockets.c' object='libgnu_a-sockets.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sockets.obj `if test -f 'sockets.c'; then $(CYGPATH_W) 'sockets.c'; else $(CYGPATH_W) '$(srcdir)/sockets.c'; fi` + +libgnu_a-spawn-pipe.o: spawn-pipe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn-pipe.o -MD -MP -MF $(DEPDIR)/libgnu_a-spawn-pipe.Tpo -c -o libgnu_a-spawn-pipe.o `test -f 'spawn-pipe.c' || echo '$(srcdir)/'`spawn-pipe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn-pipe.Tpo $(DEPDIR)/libgnu_a-spawn-pipe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn-pipe.c' object='libgnu_a-spawn-pipe.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn-pipe.o `test -f 'spawn-pipe.c' || echo '$(srcdir)/'`spawn-pipe.c + +libgnu_a-spawn-pipe.obj: spawn-pipe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-spawn-pipe.obj -MD -MP -MF $(DEPDIR)/libgnu_a-spawn-pipe.Tpo -c -o libgnu_a-spawn-pipe.obj `if test -f 'spawn-pipe.c'; then $(CYGPATH_W) 'spawn-pipe.c'; else $(CYGPATH_W) '$(srcdir)/spawn-pipe.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-spawn-pipe.Tpo $(DEPDIR)/libgnu_a-spawn-pipe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spawn-pipe.c' object='libgnu_a-spawn-pipe.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-spawn-pipe.obj `if test -f 'spawn-pipe.c'; then $(CYGPATH_W) 'spawn-pipe.c'; else $(CYGPATH_W) '$(srcdir)/spawn-pipe.c'; fi` + +libgnu_a-os2-spawn.o: os2-spawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-os2-spawn.o -MD -MP -MF $(DEPDIR)/libgnu_a-os2-spawn.Tpo -c -o libgnu_a-os2-spawn.o `test -f 'os2-spawn.c' || echo '$(srcdir)/'`os2-spawn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-os2-spawn.Tpo $(DEPDIR)/libgnu_a-os2-spawn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os2-spawn.c' object='libgnu_a-os2-spawn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-os2-spawn.o `test -f 'os2-spawn.c' || echo '$(srcdir)/'`os2-spawn.c + +libgnu_a-os2-spawn.obj: os2-spawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-os2-spawn.obj -MD -MP -MF $(DEPDIR)/libgnu_a-os2-spawn.Tpo -c -o libgnu_a-os2-spawn.obj `if test -f 'os2-spawn.c'; then $(CYGPATH_W) 'os2-spawn.c'; else $(CYGPATH_W) '$(srcdir)/os2-spawn.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-os2-spawn.Tpo $(DEPDIR)/libgnu_a-os2-spawn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os2-spawn.c' object='libgnu_a-os2-spawn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-os2-spawn.obj `if test -f 'os2-spawn.c'; then $(CYGPATH_W) 'os2-spawn.c'; else $(CYGPATH_W) '$(srcdir)/os2-spawn.c'; fi` + +libgnu_a-stat.o: stat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stat.o -MD -MP -MF $(DEPDIR)/libgnu_a-stat.Tpo -c -o libgnu_a-stat.o `test -f 'stat.c' || echo '$(srcdir)/'`stat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stat.Tpo $(DEPDIR)/libgnu_a-stat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stat.c' object='libgnu_a-stat.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stat.o `test -f 'stat.c' || echo '$(srcdir)/'`stat.c + +libgnu_a-stat.obj: stat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stat.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stat.Tpo -c -o libgnu_a-stat.obj `if test -f 'stat.c'; then $(CYGPATH_W) 'stat.c'; else $(CYGPATH_W) '$(srcdir)/stat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stat.Tpo $(DEPDIR)/libgnu_a-stat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stat.c' object='libgnu_a-stat.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stat.obj `if test -f 'stat.c'; then $(CYGPATH_W) 'stat.c'; else $(CYGPATH_W) '$(srcdir)/stat.c'; fi` + +libgnu_a-stat-time.o: stat-time.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stat-time.o -MD -MP -MF $(DEPDIR)/libgnu_a-stat-time.Tpo -c -o libgnu_a-stat-time.o `test -f 'stat-time.c' || echo '$(srcdir)/'`stat-time.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stat-time.Tpo $(DEPDIR)/libgnu_a-stat-time.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stat-time.c' object='libgnu_a-stat-time.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stat-time.o `test -f 'stat-time.c' || echo '$(srcdir)/'`stat-time.c + +libgnu_a-stat-time.obj: stat-time.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stat-time.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stat-time.Tpo -c -o libgnu_a-stat-time.obj `if test -f 'stat-time.c'; then $(CYGPATH_W) 'stat-time.c'; else $(CYGPATH_W) '$(srcdir)/stat-time.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stat-time.Tpo $(DEPDIR)/libgnu_a-stat-time.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stat-time.c' object='libgnu_a-stat-time.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stat-time.obj `if test -f 'stat-time.c'; then $(CYGPATH_W) 'stat-time.c'; else $(CYGPATH_W) '$(srcdir)/stat-time.c'; fi` + +libgnu_a-stdio-read.o: stdio-read.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stdio-read.o -MD -MP -MF $(DEPDIR)/libgnu_a-stdio-read.Tpo -c -o libgnu_a-stdio-read.o `test -f 'stdio-read.c' || echo '$(srcdir)/'`stdio-read.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stdio-read.Tpo $(DEPDIR)/libgnu_a-stdio-read.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio-read.c' object='libgnu_a-stdio-read.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stdio-read.o `test -f 'stdio-read.c' || echo '$(srcdir)/'`stdio-read.c + +libgnu_a-stdio-read.obj: stdio-read.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stdio-read.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stdio-read.Tpo -c -o libgnu_a-stdio-read.obj `if test -f 'stdio-read.c'; then $(CYGPATH_W) 'stdio-read.c'; else $(CYGPATH_W) '$(srcdir)/stdio-read.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stdio-read.Tpo $(DEPDIR)/libgnu_a-stdio-read.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio-read.c' object='libgnu_a-stdio-read.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stdio-read.obj `if test -f 'stdio-read.c'; then $(CYGPATH_W) 'stdio-read.c'; else $(CYGPATH_W) '$(srcdir)/stdio-read.c'; fi` + +libgnu_a-stdio-write.o: stdio-write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stdio-write.o -MD -MP -MF $(DEPDIR)/libgnu_a-stdio-write.Tpo -c -o libgnu_a-stdio-write.o `test -f 'stdio-write.c' || echo '$(srcdir)/'`stdio-write.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stdio-write.Tpo $(DEPDIR)/libgnu_a-stdio-write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio-write.c' object='libgnu_a-stdio-write.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stdio-write.o `test -f 'stdio-write.c' || echo '$(srcdir)/'`stdio-write.c + +libgnu_a-stdio-write.obj: stdio-write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stdio-write.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stdio-write.Tpo -c -o libgnu_a-stdio-write.obj `if test -f 'stdio-write.c'; then $(CYGPATH_W) 'stdio-write.c'; else $(CYGPATH_W) '$(srcdir)/stdio-write.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stdio-write.Tpo $(DEPDIR)/libgnu_a-stdio-write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stdio-write.c' object='libgnu_a-stdio-write.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stdio-write.obj `if test -f 'stdio-write.c'; then $(CYGPATH_W) 'stdio-write.c'; else $(CYGPATH_W) '$(srcdir)/stdio-write.c'; fi` + +libgnu_a-stpcpy.o: stpcpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stpcpy.o -MD -MP -MF $(DEPDIR)/libgnu_a-stpcpy.Tpo -c -o libgnu_a-stpcpy.o `test -f 'stpcpy.c' || echo '$(srcdir)/'`stpcpy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stpcpy.Tpo $(DEPDIR)/libgnu_a-stpcpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stpcpy.c' object='libgnu_a-stpcpy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stpcpy.o `test -f 'stpcpy.c' || echo '$(srcdir)/'`stpcpy.c + +libgnu_a-stpcpy.obj: stpcpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stpcpy.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stpcpy.Tpo -c -o libgnu_a-stpcpy.obj `if test -f 'stpcpy.c'; then $(CYGPATH_W) 'stpcpy.c'; else $(CYGPATH_W) '$(srcdir)/stpcpy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stpcpy.Tpo $(DEPDIR)/libgnu_a-stpcpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stpcpy.c' object='libgnu_a-stpcpy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stpcpy.obj `if test -f 'stpcpy.c'; then $(CYGPATH_W) 'stpcpy.c'; else $(CYGPATH_W) '$(srcdir)/stpcpy.c'; fi` + +libgnu_a-strcasecmp.o: strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strcasecmp.o -MD -MP -MF $(DEPDIR)/libgnu_a-strcasecmp.Tpo -c -o libgnu_a-strcasecmp.o `test -f 'strcasecmp.c' || echo '$(srcdir)/'`strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strcasecmp.Tpo $(DEPDIR)/libgnu_a-strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strcasecmp.c' object='libgnu_a-strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strcasecmp.o `test -f 'strcasecmp.c' || echo '$(srcdir)/'`strcasecmp.c + +libgnu_a-strcasecmp.obj: strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strcasecmp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strcasecmp.Tpo -c -o libgnu_a-strcasecmp.obj `if test -f 'strcasecmp.c'; then $(CYGPATH_W) 'strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strcasecmp.Tpo $(DEPDIR)/libgnu_a-strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strcasecmp.c' object='libgnu_a-strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strcasecmp.obj `if test -f 'strcasecmp.c'; then $(CYGPATH_W) 'strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/strcasecmp.c'; fi` + +libgnu_a-strncasecmp.o: strncasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strncasecmp.o -MD -MP -MF $(DEPDIR)/libgnu_a-strncasecmp.Tpo -c -o libgnu_a-strncasecmp.o `test -f 'strncasecmp.c' || echo '$(srcdir)/'`strncasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strncasecmp.Tpo $(DEPDIR)/libgnu_a-strncasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strncasecmp.c' object='libgnu_a-strncasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strncasecmp.o `test -f 'strncasecmp.c' || echo '$(srcdir)/'`strncasecmp.c + +libgnu_a-strncasecmp.obj: strncasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strncasecmp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strncasecmp.Tpo -c -o libgnu_a-strncasecmp.obj `if test -f 'strncasecmp.c'; then $(CYGPATH_W) 'strncasecmp.c'; else $(CYGPATH_W) '$(srcdir)/strncasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strncasecmp.Tpo $(DEPDIR)/libgnu_a-strncasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strncasecmp.c' object='libgnu_a-strncasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strncasecmp.obj `if test -f 'strncasecmp.c'; then $(CYGPATH_W) 'strncasecmp.c'; else $(CYGPATH_W) '$(srcdir)/strncasecmp.c'; fi` + +libgnu_a-strchrnul.o: strchrnul.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strchrnul.o -MD -MP -MF $(DEPDIR)/libgnu_a-strchrnul.Tpo -c -o libgnu_a-strchrnul.o `test -f 'strchrnul.c' || echo '$(srcdir)/'`strchrnul.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strchrnul.Tpo $(DEPDIR)/libgnu_a-strchrnul.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strchrnul.c' object='libgnu_a-strchrnul.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strchrnul.o `test -f 'strchrnul.c' || echo '$(srcdir)/'`strchrnul.c + +libgnu_a-strchrnul.obj: strchrnul.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strchrnul.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strchrnul.Tpo -c -o libgnu_a-strchrnul.obj `if test -f 'strchrnul.c'; then $(CYGPATH_W) 'strchrnul.c'; else $(CYGPATH_W) '$(srcdir)/strchrnul.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strchrnul.Tpo $(DEPDIR)/libgnu_a-strchrnul.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strchrnul.c' object='libgnu_a-strchrnul.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strchrnul.obj `if test -f 'strchrnul.c'; then $(CYGPATH_W) 'strchrnul.c'; else $(CYGPATH_W) '$(srcdir)/strchrnul.c'; fi` + +libgnu_a-strdup.o: strdup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strdup.o -MD -MP -MF $(DEPDIR)/libgnu_a-strdup.Tpo -c -o libgnu_a-strdup.o `test -f 'strdup.c' || echo '$(srcdir)/'`strdup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strdup.Tpo $(DEPDIR)/libgnu_a-strdup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strdup.c' object='libgnu_a-strdup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strdup.o `test -f 'strdup.c' || echo '$(srcdir)/'`strdup.c + +libgnu_a-strdup.obj: strdup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strdup.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strdup.Tpo -c -o libgnu_a-strdup.obj `if test -f 'strdup.c'; then $(CYGPATH_W) 'strdup.c'; else $(CYGPATH_W) '$(srcdir)/strdup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strdup.Tpo $(DEPDIR)/libgnu_a-strdup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strdup.c' object='libgnu_a-strdup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strdup.obj `if test -f 'strdup.c'; then $(CYGPATH_W) 'strdup.c'; else $(CYGPATH_W) '$(srcdir)/strdup.c'; fi` + +libgnu_a-strerror.o: strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strerror.o -MD -MP -MF $(DEPDIR)/libgnu_a-strerror.Tpo -c -o libgnu_a-strerror.o `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strerror.Tpo $(DEPDIR)/libgnu_a-strerror.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libgnu_a-strerror.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strerror.o `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c + +libgnu_a-strerror.obj: strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strerror.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strerror.Tpo -c -o libgnu_a-strerror.obj `if test -f 'strerror.c'; then $(CYGPATH_W) 'strerror.c'; else $(CYGPATH_W) '$(srcdir)/strerror.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strerror.Tpo $(DEPDIR)/libgnu_a-strerror.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libgnu_a-strerror.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strerror.obj `if test -f 'strerror.c'; then $(CYGPATH_W) 'strerror.c'; else $(CYGPATH_W) '$(srcdir)/strerror.c'; fi` + +libgnu_a-strerror-override.o: strerror-override.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strerror-override.o -MD -MP -MF $(DEPDIR)/libgnu_a-strerror-override.Tpo -c -o libgnu_a-strerror-override.o `test -f 'strerror-override.c' || echo '$(srcdir)/'`strerror-override.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strerror-override.Tpo $(DEPDIR)/libgnu_a-strerror-override.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror-override.c' object='libgnu_a-strerror-override.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strerror-override.o `test -f 'strerror-override.c' || echo '$(srcdir)/'`strerror-override.c + +libgnu_a-strerror-override.obj: strerror-override.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strerror-override.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strerror-override.Tpo -c -o libgnu_a-strerror-override.obj `if test -f 'strerror-override.c'; then $(CYGPATH_W) 'strerror-override.c'; else $(CYGPATH_W) '$(srcdir)/strerror-override.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strerror-override.Tpo $(DEPDIR)/libgnu_a-strerror-override.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror-override.c' object='libgnu_a-strerror-override.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strerror-override.obj `if test -f 'strerror-override.c'; then $(CYGPATH_W) 'strerror-override.c'; else $(CYGPATH_W) '$(srcdir)/strerror-override.c'; fi` + +libgnu_a-strndup.o: strndup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strndup.o -MD -MP -MF $(DEPDIR)/libgnu_a-strndup.Tpo -c -o libgnu_a-strndup.o `test -f 'strndup.c' || echo '$(srcdir)/'`strndup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strndup.Tpo $(DEPDIR)/libgnu_a-strndup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strndup.c' object='libgnu_a-strndup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strndup.o `test -f 'strndup.c' || echo '$(srcdir)/'`strndup.c + +libgnu_a-strndup.obj: strndup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strndup.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strndup.Tpo -c -o libgnu_a-strndup.obj `if test -f 'strndup.c'; then $(CYGPATH_W) 'strndup.c'; else $(CYGPATH_W) '$(srcdir)/strndup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strndup.Tpo $(DEPDIR)/libgnu_a-strndup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strndup.c' object='libgnu_a-strndup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strndup.obj `if test -f 'strndup.c'; then $(CYGPATH_W) 'strndup.c'; else $(CYGPATH_W) '$(srcdir)/strndup.c'; fi` + +libgnu_a-strnlen.o: strnlen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strnlen.o -MD -MP -MF $(DEPDIR)/libgnu_a-strnlen.Tpo -c -o libgnu_a-strnlen.o `test -f 'strnlen.c' || echo '$(srcdir)/'`strnlen.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strnlen.Tpo $(DEPDIR)/libgnu_a-strnlen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strnlen.c' object='libgnu_a-strnlen.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strnlen.o `test -f 'strnlen.c' || echo '$(srcdir)/'`strnlen.c + +libgnu_a-strnlen.obj: strnlen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strnlen.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strnlen.Tpo -c -o libgnu_a-strnlen.obj `if test -f 'strnlen.c'; then $(CYGPATH_W) 'strnlen.c'; else $(CYGPATH_W) '$(srcdir)/strnlen.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strnlen.Tpo $(DEPDIR)/libgnu_a-strnlen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strnlen.c' object='libgnu_a-strnlen.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strnlen.obj `if test -f 'strnlen.c'; then $(CYGPATH_W) 'strnlen.c'; else $(CYGPATH_W) '$(srcdir)/strnlen.c'; fi` + +libgnu_a-strnlen1.o: strnlen1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strnlen1.o -MD -MP -MF $(DEPDIR)/libgnu_a-strnlen1.Tpo -c -o libgnu_a-strnlen1.o `test -f 'strnlen1.c' || echo '$(srcdir)/'`strnlen1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strnlen1.Tpo $(DEPDIR)/libgnu_a-strnlen1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strnlen1.c' object='libgnu_a-strnlen1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strnlen1.o `test -f 'strnlen1.c' || echo '$(srcdir)/'`strnlen1.c + +libgnu_a-strnlen1.obj: strnlen1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strnlen1.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strnlen1.Tpo -c -o libgnu_a-strnlen1.obj `if test -f 'strnlen1.c'; then $(CYGPATH_W) 'strnlen1.c'; else $(CYGPATH_W) '$(srcdir)/strnlen1.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strnlen1.Tpo $(DEPDIR)/libgnu_a-strnlen1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strnlen1.c' object='libgnu_a-strnlen1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strnlen1.obj `if test -f 'strnlen1.c'; then $(CYGPATH_W) 'strnlen1.c'; else $(CYGPATH_W) '$(srcdir)/strnlen1.c'; fi` + +libgnu_a-strpbrk.o: strpbrk.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strpbrk.o -MD -MP -MF $(DEPDIR)/libgnu_a-strpbrk.Tpo -c -o libgnu_a-strpbrk.o `test -f 'strpbrk.c' || echo '$(srcdir)/'`strpbrk.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strpbrk.Tpo $(DEPDIR)/libgnu_a-strpbrk.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strpbrk.c' object='libgnu_a-strpbrk.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strpbrk.o `test -f 'strpbrk.c' || echo '$(srcdir)/'`strpbrk.c + +libgnu_a-strpbrk.obj: strpbrk.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strpbrk.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strpbrk.Tpo -c -o libgnu_a-strpbrk.obj `if test -f 'strpbrk.c'; then $(CYGPATH_W) 'strpbrk.c'; else $(CYGPATH_W) '$(srcdir)/strpbrk.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strpbrk.Tpo $(DEPDIR)/libgnu_a-strpbrk.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strpbrk.c' object='libgnu_a-strpbrk.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strpbrk.obj `if test -f 'strpbrk.c'; then $(CYGPATH_W) 'strpbrk.c'; else $(CYGPATH_W) '$(srcdir)/strpbrk.c'; fi` + +libgnu_a-strptime.o: strptime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strptime.o -MD -MP -MF $(DEPDIR)/libgnu_a-strptime.Tpo -c -o libgnu_a-strptime.o `test -f 'strptime.c' || echo '$(srcdir)/'`strptime.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strptime.Tpo $(DEPDIR)/libgnu_a-strptime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strptime.c' object='libgnu_a-strptime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strptime.o `test -f 'strptime.c' || echo '$(srcdir)/'`strptime.c + +libgnu_a-strptime.obj: strptime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strptime.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strptime.Tpo -c -o libgnu_a-strptime.obj `if test -f 'strptime.c'; then $(CYGPATH_W) 'strptime.c'; else $(CYGPATH_W) '$(srcdir)/strptime.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strptime.Tpo $(DEPDIR)/libgnu_a-strptime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strptime.c' object='libgnu_a-strptime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strptime.obj `if test -f 'strptime.c'; then $(CYGPATH_W) 'strptime.c'; else $(CYGPATH_W) '$(srcdir)/strptime.c'; fi` + +libgnu_a-strtok_r.o: strtok_r.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strtok_r.o -MD -MP -MF $(DEPDIR)/libgnu_a-strtok_r.Tpo -c -o libgnu_a-strtok_r.o `test -f 'strtok_r.c' || echo '$(srcdir)/'`strtok_r.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strtok_r.Tpo $(DEPDIR)/libgnu_a-strtok_r.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtok_r.c' object='libgnu_a-strtok_r.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strtok_r.o `test -f 'strtok_r.c' || echo '$(srcdir)/'`strtok_r.c + +libgnu_a-strtok_r.obj: strtok_r.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strtok_r.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strtok_r.Tpo -c -o libgnu_a-strtok_r.obj `if test -f 'strtok_r.c'; then $(CYGPATH_W) 'strtok_r.c'; else $(CYGPATH_W) '$(srcdir)/strtok_r.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strtok_r.Tpo $(DEPDIR)/libgnu_a-strtok_r.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtok_r.c' object='libgnu_a-strtok_r.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strtok_r.obj `if test -f 'strtok_r.c'; then $(CYGPATH_W) 'strtok_r.c'; else $(CYGPATH_W) '$(srcdir)/strtok_r.c'; fi` + +libgnu_a-strtol.o: strtol.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strtol.o -MD -MP -MF $(DEPDIR)/libgnu_a-strtol.Tpo -c -o libgnu_a-strtol.o `test -f 'strtol.c' || echo '$(srcdir)/'`strtol.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strtol.Tpo $(DEPDIR)/libgnu_a-strtol.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtol.c' object='libgnu_a-strtol.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strtol.o `test -f 'strtol.c' || echo '$(srcdir)/'`strtol.c + +libgnu_a-strtol.obj: strtol.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strtol.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strtol.Tpo -c -o libgnu_a-strtol.obj `if test -f 'strtol.c'; then $(CYGPATH_W) 'strtol.c'; else $(CYGPATH_W) '$(srcdir)/strtol.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strtol.Tpo $(DEPDIR)/libgnu_a-strtol.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtol.c' object='libgnu_a-strtol.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strtol.obj `if test -f 'strtol.c'; then $(CYGPATH_W) 'strtol.c'; else $(CYGPATH_W) '$(srcdir)/strtol.c'; fi` + +libgnu_a-strtoll.o: strtoll.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strtoll.o -MD -MP -MF $(DEPDIR)/libgnu_a-strtoll.Tpo -c -o libgnu_a-strtoll.o `test -f 'strtoll.c' || echo '$(srcdir)/'`strtoll.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strtoll.Tpo $(DEPDIR)/libgnu_a-strtoll.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtoll.c' object='libgnu_a-strtoll.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strtoll.o `test -f 'strtoll.c' || echo '$(srcdir)/'`strtoll.c + +libgnu_a-strtoll.obj: strtoll.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strtoll.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strtoll.Tpo -c -o libgnu_a-strtoll.obj `if test -f 'strtoll.c'; then $(CYGPATH_W) 'strtoll.c'; else $(CYGPATH_W) '$(srcdir)/strtoll.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strtoll.Tpo $(DEPDIR)/libgnu_a-strtoll.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtoll.c' object='libgnu_a-strtoll.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strtoll.obj `if test -f 'strtoll.c'; then $(CYGPATH_W) 'strtoll.c'; else $(CYGPATH_W) '$(srcdir)/strtoll.c'; fi` + +libgnu_a-symlink.o: symlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-symlink.o -MD -MP -MF $(DEPDIR)/libgnu_a-symlink.Tpo -c -o libgnu_a-symlink.o `test -f 'symlink.c' || echo '$(srcdir)/'`symlink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-symlink.Tpo $(DEPDIR)/libgnu_a-symlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='symlink.c' object='libgnu_a-symlink.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-symlink.o `test -f 'symlink.c' || echo '$(srcdir)/'`symlink.c + +libgnu_a-symlink.obj: symlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-symlink.obj -MD -MP -MF $(DEPDIR)/libgnu_a-symlink.Tpo -c -o libgnu_a-symlink.obj `if test -f 'symlink.c'; then $(CYGPATH_W) 'symlink.c'; else $(CYGPATH_W) '$(srcdir)/symlink.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-symlink.Tpo $(DEPDIR)/libgnu_a-symlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='symlink.c' object='libgnu_a-symlink.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-symlink.obj `if test -f 'symlink.c'; then $(CYGPATH_W) 'symlink.c'; else $(CYGPATH_W) '$(srcdir)/symlink.c'; fi` + +libgnu_a-sys_socket.o: sys_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sys_socket.o -MD -MP -MF $(DEPDIR)/libgnu_a-sys_socket.Tpo -c -o libgnu_a-sys_socket.o `test -f 'sys_socket.c' || echo '$(srcdir)/'`sys_socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sys_socket.Tpo $(DEPDIR)/libgnu_a-sys_socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys_socket.c' object='libgnu_a-sys_socket.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sys_socket.o `test -f 'sys_socket.c' || echo '$(srcdir)/'`sys_socket.c + +libgnu_a-sys_socket.obj: sys_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-sys_socket.obj -MD -MP -MF $(DEPDIR)/libgnu_a-sys_socket.Tpo -c -o libgnu_a-sys_socket.obj `if test -f 'sys_socket.c'; then $(CYGPATH_W) 'sys_socket.c'; else $(CYGPATH_W) '$(srcdir)/sys_socket.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-sys_socket.Tpo $(DEPDIR)/libgnu_a-sys_socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys_socket.c' object='libgnu_a-sys_socket.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-sys_socket.obj `if test -f 'sys_socket.c'; then $(CYGPATH_W) 'sys_socket.c'; else $(CYGPATH_W) '$(srcdir)/sys_socket.c'; fi` + +libgnu_a-tempname.o: tempname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-tempname.o -MD -MP -MF $(DEPDIR)/libgnu_a-tempname.Tpo -c -o libgnu_a-tempname.o `test -f 'tempname.c' || echo '$(srcdir)/'`tempname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-tempname.Tpo $(DEPDIR)/libgnu_a-tempname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tempname.c' object='libgnu_a-tempname.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-tempname.o `test -f 'tempname.c' || echo '$(srcdir)/'`tempname.c + +libgnu_a-tempname.obj: tempname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-tempname.obj -MD -MP -MF $(DEPDIR)/libgnu_a-tempname.Tpo -c -o libgnu_a-tempname.obj `if test -f 'tempname.c'; then $(CYGPATH_W) 'tempname.c'; else $(CYGPATH_W) '$(srcdir)/tempname.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-tempname.Tpo $(DEPDIR)/libgnu_a-tempname.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tempname.c' object='libgnu_a-tempname.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-tempname.obj `if test -f 'tempname.c'; then $(CYGPATH_W) 'tempname.c'; else $(CYGPATH_W) '$(srcdir)/tempname.c'; fi` + +glthread/libgnu_a-threadlib.o: glthread/threadlib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT glthread/libgnu_a-threadlib.o -MD -MP -MF glthread/$(DEPDIR)/libgnu_a-threadlib.Tpo -c -o glthread/libgnu_a-threadlib.o `test -f 'glthread/threadlib.c' || echo '$(srcdir)/'`glthread/threadlib.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) glthread/$(DEPDIR)/libgnu_a-threadlib.Tpo glthread/$(DEPDIR)/libgnu_a-threadlib.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glthread/threadlib.c' object='glthread/libgnu_a-threadlib.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o glthread/libgnu_a-threadlib.o `test -f 'glthread/threadlib.c' || echo '$(srcdir)/'`glthread/threadlib.c + +glthread/libgnu_a-threadlib.obj: glthread/threadlib.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT glthread/libgnu_a-threadlib.obj -MD -MP -MF glthread/$(DEPDIR)/libgnu_a-threadlib.Tpo -c -o glthread/libgnu_a-threadlib.obj `if test -f 'glthread/threadlib.c'; then $(CYGPATH_W) 'glthread/threadlib.c'; else $(CYGPATH_W) '$(srcdir)/glthread/threadlib.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) glthread/$(DEPDIR)/libgnu_a-threadlib.Tpo glthread/$(DEPDIR)/libgnu_a-threadlib.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glthread/threadlib.c' object='glthread/libgnu_a-threadlib.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o glthread/libgnu_a-threadlib.obj `if test -f 'glthread/threadlib.c'; then $(CYGPATH_W) 'glthread/threadlib.c'; else $(CYGPATH_W) '$(srcdir)/glthread/threadlib.c'; fi` + +libgnu_a-time_r.o: time_r.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-time_r.o -MD -MP -MF $(DEPDIR)/libgnu_a-time_r.Tpo -c -o libgnu_a-time_r.o `test -f 'time_r.c' || echo '$(srcdir)/'`time_r.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-time_r.Tpo $(DEPDIR)/libgnu_a-time_r.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time_r.c' object='libgnu_a-time_r.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-time_r.o `test -f 'time_r.c' || echo '$(srcdir)/'`time_r.c + +libgnu_a-time_r.obj: time_r.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-time_r.obj -MD -MP -MF $(DEPDIR)/libgnu_a-time_r.Tpo -c -o libgnu_a-time_r.obj `if test -f 'time_r.c'; then $(CYGPATH_W) 'time_r.c'; else $(CYGPATH_W) '$(srcdir)/time_r.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-time_r.Tpo $(DEPDIR)/libgnu_a-time_r.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time_r.c' object='libgnu_a-time_r.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-time_r.obj `if test -f 'time_r.c'; then $(CYGPATH_W) 'time_r.c'; else $(CYGPATH_W) '$(srcdir)/time_r.c'; fi` + +libgnu_a-timegm.o: timegm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-timegm.o -MD -MP -MF $(DEPDIR)/libgnu_a-timegm.Tpo -c -o libgnu_a-timegm.o `test -f 'timegm.c' || echo '$(srcdir)/'`timegm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-timegm.Tpo $(DEPDIR)/libgnu_a-timegm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timegm.c' object='libgnu_a-timegm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-timegm.o `test -f 'timegm.c' || echo '$(srcdir)/'`timegm.c + +libgnu_a-timegm.obj: timegm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-timegm.obj -MD -MP -MF $(DEPDIR)/libgnu_a-timegm.Tpo -c -o libgnu_a-timegm.obj `if test -f 'timegm.c'; then $(CYGPATH_W) 'timegm.c'; else $(CYGPATH_W) '$(srcdir)/timegm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-timegm.Tpo $(DEPDIR)/libgnu_a-timegm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timegm.c' object='libgnu_a-timegm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-timegm.obj `if test -f 'timegm.c'; then $(CYGPATH_W) 'timegm.c'; else $(CYGPATH_W) '$(srcdir)/timegm.c'; fi` + +libgnu_a-timespec.o: timespec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-timespec.o -MD -MP -MF $(DEPDIR)/libgnu_a-timespec.Tpo -c -o libgnu_a-timespec.o `test -f 'timespec.c' || echo '$(srcdir)/'`timespec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-timespec.Tpo $(DEPDIR)/libgnu_a-timespec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timespec.c' object='libgnu_a-timespec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-timespec.o `test -f 'timespec.c' || echo '$(srcdir)/'`timespec.c + +libgnu_a-timespec.obj: timespec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-timespec.obj -MD -MP -MF $(DEPDIR)/libgnu_a-timespec.Tpo -c -o libgnu_a-timespec.obj `if test -f 'timespec.c'; then $(CYGPATH_W) 'timespec.c'; else $(CYGPATH_W) '$(srcdir)/timespec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-timespec.Tpo $(DEPDIR)/libgnu_a-timespec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timespec.c' object='libgnu_a-timespec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-timespec.obj `if test -f 'timespec.c'; then $(CYGPATH_W) 'timespec.c'; else $(CYGPATH_W) '$(srcdir)/timespec.c'; fi` + +libgnu_a-tmpdir.o: tmpdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-tmpdir.o -MD -MP -MF $(DEPDIR)/libgnu_a-tmpdir.Tpo -c -o libgnu_a-tmpdir.o `test -f 'tmpdir.c' || echo '$(srcdir)/'`tmpdir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-tmpdir.Tpo $(DEPDIR)/libgnu_a-tmpdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tmpdir.c' object='libgnu_a-tmpdir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-tmpdir.o `test -f 'tmpdir.c' || echo '$(srcdir)/'`tmpdir.c + +libgnu_a-tmpdir.obj: tmpdir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-tmpdir.obj -MD -MP -MF $(DEPDIR)/libgnu_a-tmpdir.Tpo -c -o libgnu_a-tmpdir.obj `if test -f 'tmpdir.c'; then $(CYGPATH_W) 'tmpdir.c'; else $(CYGPATH_W) '$(srcdir)/tmpdir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-tmpdir.Tpo $(DEPDIR)/libgnu_a-tmpdir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tmpdir.c' object='libgnu_a-tmpdir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-tmpdir.obj `if test -f 'tmpdir.c'; then $(CYGPATH_W) 'tmpdir.c'; else $(CYGPATH_W) '$(srcdir)/tmpdir.c'; fi` + +libgnu_a-u64.o: u64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-u64.o -MD -MP -MF $(DEPDIR)/libgnu_a-u64.Tpo -c -o libgnu_a-u64.o `test -f 'u64.c' || echo '$(srcdir)/'`u64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-u64.Tpo $(DEPDIR)/libgnu_a-u64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='u64.c' object='libgnu_a-u64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-u64.o `test -f 'u64.c' || echo '$(srcdir)/'`u64.c + +libgnu_a-u64.obj: u64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-u64.obj -MD -MP -MF $(DEPDIR)/libgnu_a-u64.Tpo -c -o libgnu_a-u64.obj `if test -f 'u64.c'; then $(CYGPATH_W) 'u64.c'; else $(CYGPATH_W) '$(srcdir)/u64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-u64.Tpo $(DEPDIR)/libgnu_a-u64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='u64.c' object='libgnu_a-u64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-u64.obj `if test -f 'u64.c'; then $(CYGPATH_W) 'u64.c'; else $(CYGPATH_W) '$(srcdir)/u64.c'; fi` + +unicase/libgnu_a-cased.o: unicase/cased.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-cased.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-cased.Tpo -c -o unicase/libgnu_a-cased.o `test -f 'unicase/cased.c' || echo '$(srcdir)/'`unicase/cased.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-cased.Tpo unicase/$(DEPDIR)/libgnu_a-cased.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/cased.c' object='unicase/libgnu_a-cased.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-cased.o `test -f 'unicase/cased.c' || echo '$(srcdir)/'`unicase/cased.c + +unicase/libgnu_a-cased.obj: unicase/cased.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-cased.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-cased.Tpo -c -o unicase/libgnu_a-cased.obj `if test -f 'unicase/cased.c'; then $(CYGPATH_W) 'unicase/cased.c'; else $(CYGPATH_W) '$(srcdir)/unicase/cased.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-cased.Tpo unicase/$(DEPDIR)/libgnu_a-cased.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/cased.c' object='unicase/libgnu_a-cased.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-cased.obj `if test -f 'unicase/cased.c'; then $(CYGPATH_W) 'unicase/cased.c'; else $(CYGPATH_W) '$(srcdir)/unicase/cased.c'; fi` + +unicase/libgnu_a-empty-prefix-context.o: unicase/empty-prefix-context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-empty-prefix-context.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Tpo -c -o unicase/libgnu_a-empty-prefix-context.o `test -f 'unicase/empty-prefix-context.c' || echo '$(srcdir)/'`unicase/empty-prefix-context.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Tpo unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/empty-prefix-context.c' object='unicase/libgnu_a-empty-prefix-context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-empty-prefix-context.o `test -f 'unicase/empty-prefix-context.c' || echo '$(srcdir)/'`unicase/empty-prefix-context.c + +unicase/libgnu_a-empty-prefix-context.obj: unicase/empty-prefix-context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-empty-prefix-context.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Tpo -c -o unicase/libgnu_a-empty-prefix-context.obj `if test -f 'unicase/empty-prefix-context.c'; then $(CYGPATH_W) 'unicase/empty-prefix-context.c'; else $(CYGPATH_W) '$(srcdir)/unicase/empty-prefix-context.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Tpo unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/empty-prefix-context.c' object='unicase/libgnu_a-empty-prefix-context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-empty-prefix-context.obj `if test -f 'unicase/empty-prefix-context.c'; then $(CYGPATH_W) 'unicase/empty-prefix-context.c'; else $(CYGPATH_W) '$(srcdir)/unicase/empty-prefix-context.c'; fi` + +unicase/libgnu_a-empty-suffix-context.o: unicase/empty-suffix-context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-empty-suffix-context.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Tpo -c -o unicase/libgnu_a-empty-suffix-context.o `test -f 'unicase/empty-suffix-context.c' || echo '$(srcdir)/'`unicase/empty-suffix-context.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Tpo unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/empty-suffix-context.c' object='unicase/libgnu_a-empty-suffix-context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-empty-suffix-context.o `test -f 'unicase/empty-suffix-context.c' || echo '$(srcdir)/'`unicase/empty-suffix-context.c + +unicase/libgnu_a-empty-suffix-context.obj: unicase/empty-suffix-context.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-empty-suffix-context.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Tpo -c -o unicase/libgnu_a-empty-suffix-context.obj `if test -f 'unicase/empty-suffix-context.c'; then $(CYGPATH_W) 'unicase/empty-suffix-context.c'; else $(CYGPATH_W) '$(srcdir)/unicase/empty-suffix-context.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Tpo unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/empty-suffix-context.c' object='unicase/libgnu_a-empty-suffix-context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-empty-suffix-context.obj `if test -f 'unicase/empty-suffix-context.c'; then $(CYGPATH_W) 'unicase/empty-suffix-context.c'; else $(CYGPATH_W) '$(srcdir)/unicase/empty-suffix-context.c'; fi` + +unicase/libgnu_a-ignorable.o: unicase/ignorable.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-ignorable.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-ignorable.Tpo -c -o unicase/libgnu_a-ignorable.o `test -f 'unicase/ignorable.c' || echo '$(srcdir)/'`unicase/ignorable.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-ignorable.Tpo unicase/$(DEPDIR)/libgnu_a-ignorable.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/ignorable.c' object='unicase/libgnu_a-ignorable.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-ignorable.o `test -f 'unicase/ignorable.c' || echo '$(srcdir)/'`unicase/ignorable.c + +unicase/libgnu_a-ignorable.obj: unicase/ignorable.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-ignorable.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-ignorable.Tpo -c -o unicase/libgnu_a-ignorable.obj `if test -f 'unicase/ignorable.c'; then $(CYGPATH_W) 'unicase/ignorable.c'; else $(CYGPATH_W) '$(srcdir)/unicase/ignorable.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-ignorable.Tpo unicase/$(DEPDIR)/libgnu_a-ignorable.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/ignorable.c' object='unicase/libgnu_a-ignorable.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-ignorable.obj `if test -f 'unicase/ignorable.c'; then $(CYGPATH_W) 'unicase/ignorable.c'; else $(CYGPATH_W) '$(srcdir)/unicase/ignorable.c'; fi` + +unicase/libgnu_a-special-casing.o: unicase/special-casing.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-special-casing.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-special-casing.Tpo -c -o unicase/libgnu_a-special-casing.o `test -f 'unicase/special-casing.c' || echo '$(srcdir)/'`unicase/special-casing.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-special-casing.Tpo unicase/$(DEPDIR)/libgnu_a-special-casing.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/special-casing.c' object='unicase/libgnu_a-special-casing.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-special-casing.o `test -f 'unicase/special-casing.c' || echo '$(srcdir)/'`unicase/special-casing.c + +unicase/libgnu_a-special-casing.obj: unicase/special-casing.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-special-casing.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-special-casing.Tpo -c -o unicase/libgnu_a-special-casing.obj `if test -f 'unicase/special-casing.c'; then $(CYGPATH_W) 'unicase/special-casing.c'; else $(CYGPATH_W) '$(srcdir)/unicase/special-casing.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-special-casing.Tpo unicase/$(DEPDIR)/libgnu_a-special-casing.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/special-casing.c' object='unicase/libgnu_a-special-casing.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-special-casing.obj `if test -f 'unicase/special-casing.c'; then $(CYGPATH_W) 'unicase/special-casing.c'; else $(CYGPATH_W) '$(srcdir)/unicase/special-casing.c'; fi` + +unicase/libgnu_a-tolower.o: unicase/tolower.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-tolower.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-tolower.Tpo -c -o unicase/libgnu_a-tolower.o `test -f 'unicase/tolower.c' || echo '$(srcdir)/'`unicase/tolower.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-tolower.Tpo unicase/$(DEPDIR)/libgnu_a-tolower.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/tolower.c' object='unicase/libgnu_a-tolower.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-tolower.o `test -f 'unicase/tolower.c' || echo '$(srcdir)/'`unicase/tolower.c + +unicase/libgnu_a-tolower.obj: unicase/tolower.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-tolower.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-tolower.Tpo -c -o unicase/libgnu_a-tolower.obj `if test -f 'unicase/tolower.c'; then $(CYGPATH_W) 'unicase/tolower.c'; else $(CYGPATH_W) '$(srcdir)/unicase/tolower.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-tolower.Tpo unicase/$(DEPDIR)/libgnu_a-tolower.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/tolower.c' object='unicase/libgnu_a-tolower.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-tolower.obj `if test -f 'unicase/tolower.c'; then $(CYGPATH_W) 'unicase/tolower.c'; else $(CYGPATH_W) '$(srcdir)/unicase/tolower.c'; fi` + +unicase/libgnu_a-u8-casemap.o: unicase/u8-casemap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-u8-casemap.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-u8-casemap.Tpo -c -o unicase/libgnu_a-u8-casemap.o `test -f 'unicase/u8-casemap.c' || echo '$(srcdir)/'`unicase/u8-casemap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-u8-casemap.Tpo unicase/$(DEPDIR)/libgnu_a-u8-casemap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/u8-casemap.c' object='unicase/libgnu_a-u8-casemap.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-u8-casemap.o `test -f 'unicase/u8-casemap.c' || echo '$(srcdir)/'`unicase/u8-casemap.c + +unicase/libgnu_a-u8-casemap.obj: unicase/u8-casemap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-u8-casemap.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-u8-casemap.Tpo -c -o unicase/libgnu_a-u8-casemap.obj `if test -f 'unicase/u8-casemap.c'; then $(CYGPATH_W) 'unicase/u8-casemap.c'; else $(CYGPATH_W) '$(srcdir)/unicase/u8-casemap.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-u8-casemap.Tpo unicase/$(DEPDIR)/libgnu_a-u8-casemap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/u8-casemap.c' object='unicase/libgnu_a-u8-casemap.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-u8-casemap.obj `if test -f 'unicase/u8-casemap.c'; then $(CYGPATH_W) 'unicase/u8-casemap.c'; else $(CYGPATH_W) '$(srcdir)/unicase/u8-casemap.c'; fi` + +unicase/libgnu_a-u8-tolower.o: unicase/u8-tolower.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-u8-tolower.o -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-u8-tolower.Tpo -c -o unicase/libgnu_a-u8-tolower.o `test -f 'unicase/u8-tolower.c' || echo '$(srcdir)/'`unicase/u8-tolower.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-u8-tolower.Tpo unicase/$(DEPDIR)/libgnu_a-u8-tolower.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/u8-tolower.c' object='unicase/libgnu_a-u8-tolower.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-u8-tolower.o `test -f 'unicase/u8-tolower.c' || echo '$(srcdir)/'`unicase/u8-tolower.c + +unicase/libgnu_a-u8-tolower.obj: unicase/u8-tolower.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unicase/libgnu_a-u8-tolower.obj -MD -MP -MF unicase/$(DEPDIR)/libgnu_a-u8-tolower.Tpo -c -o unicase/libgnu_a-u8-tolower.obj `if test -f 'unicase/u8-tolower.c'; then $(CYGPATH_W) 'unicase/u8-tolower.c'; else $(CYGPATH_W) '$(srcdir)/unicase/u8-tolower.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unicase/$(DEPDIR)/libgnu_a-u8-tolower.Tpo unicase/$(DEPDIR)/libgnu_a-u8-tolower.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unicase/u8-tolower.c' object='unicase/libgnu_a-u8-tolower.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unicase/libgnu_a-u8-tolower.obj `if test -f 'unicase/u8-tolower.c'; then $(CYGPATH_W) 'unicase/u8-tolower.c'; else $(CYGPATH_W) '$(srcdir)/unicase/u8-tolower.c'; fi` + +unictype/libgnu_a-combiningclass.o: unictype/combiningclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unictype/libgnu_a-combiningclass.o -MD -MP -MF unictype/$(DEPDIR)/libgnu_a-combiningclass.Tpo -c -o unictype/libgnu_a-combiningclass.o `test -f 'unictype/combiningclass.c' || echo '$(srcdir)/'`unictype/combiningclass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unictype/$(DEPDIR)/libgnu_a-combiningclass.Tpo unictype/$(DEPDIR)/libgnu_a-combiningclass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unictype/combiningclass.c' object='unictype/libgnu_a-combiningclass.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unictype/libgnu_a-combiningclass.o `test -f 'unictype/combiningclass.c' || echo '$(srcdir)/'`unictype/combiningclass.c + +unictype/libgnu_a-combiningclass.obj: unictype/combiningclass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unictype/libgnu_a-combiningclass.obj -MD -MP -MF unictype/$(DEPDIR)/libgnu_a-combiningclass.Tpo -c -o unictype/libgnu_a-combiningclass.obj `if test -f 'unictype/combiningclass.c'; then $(CYGPATH_W) 'unictype/combiningclass.c'; else $(CYGPATH_W) '$(srcdir)/unictype/combiningclass.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unictype/$(DEPDIR)/libgnu_a-combiningclass.Tpo unictype/$(DEPDIR)/libgnu_a-combiningclass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unictype/combiningclass.c' object='unictype/libgnu_a-combiningclass.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unictype/libgnu_a-combiningclass.obj `if test -f 'unictype/combiningclass.c'; then $(CYGPATH_W) 'unictype/combiningclass.c'; else $(CYGPATH_W) '$(srcdir)/unictype/combiningclass.c'; fi` + +unictype/libgnu_a-pr_soft_dotted.o: unictype/pr_soft_dotted.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unictype/libgnu_a-pr_soft_dotted.o -MD -MP -MF unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Tpo -c -o unictype/libgnu_a-pr_soft_dotted.o `test -f 'unictype/pr_soft_dotted.c' || echo '$(srcdir)/'`unictype/pr_soft_dotted.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Tpo unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unictype/pr_soft_dotted.c' object='unictype/libgnu_a-pr_soft_dotted.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unictype/libgnu_a-pr_soft_dotted.o `test -f 'unictype/pr_soft_dotted.c' || echo '$(srcdir)/'`unictype/pr_soft_dotted.c + +unictype/libgnu_a-pr_soft_dotted.obj: unictype/pr_soft_dotted.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unictype/libgnu_a-pr_soft_dotted.obj -MD -MP -MF unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Tpo -c -o unictype/libgnu_a-pr_soft_dotted.obj `if test -f 'unictype/pr_soft_dotted.c'; then $(CYGPATH_W) 'unictype/pr_soft_dotted.c'; else $(CYGPATH_W) '$(srcdir)/unictype/pr_soft_dotted.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Tpo unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unictype/pr_soft_dotted.c' object='unictype/libgnu_a-pr_soft_dotted.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unictype/libgnu_a-pr_soft_dotted.obj `if test -f 'unictype/pr_soft_dotted.c'; then $(CYGPATH_W) 'unictype/pr_soft_dotted.c'; else $(CYGPATH_W) '$(srcdir)/unictype/pr_soft_dotted.c'; fi` + +uninorm/libgnu_a-decompose-internal.o: uninorm/decompose-internal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT uninorm/libgnu_a-decompose-internal.o -MD -MP -MF uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Tpo -c -o uninorm/libgnu_a-decompose-internal.o `test -f 'uninorm/decompose-internal.c' || echo '$(srcdir)/'`uninorm/decompose-internal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Tpo uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uninorm/decompose-internal.c' object='uninorm/libgnu_a-decompose-internal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o uninorm/libgnu_a-decompose-internal.o `test -f 'uninorm/decompose-internal.c' || echo '$(srcdir)/'`uninorm/decompose-internal.c + +uninorm/libgnu_a-decompose-internal.obj: uninorm/decompose-internal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT uninorm/libgnu_a-decompose-internal.obj -MD -MP -MF uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Tpo -c -o uninorm/libgnu_a-decompose-internal.obj `if test -f 'uninorm/decompose-internal.c'; then $(CYGPATH_W) 'uninorm/decompose-internal.c'; else $(CYGPATH_W) '$(srcdir)/uninorm/decompose-internal.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Tpo uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uninorm/decompose-internal.c' object='uninorm/libgnu_a-decompose-internal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o uninorm/libgnu_a-decompose-internal.obj `if test -f 'uninorm/decompose-internal.c'; then $(CYGPATH_W) 'uninorm/decompose-internal.c'; else $(CYGPATH_W) '$(srcdir)/uninorm/decompose-internal.c'; fi` + +uninorm/libgnu_a-u8-normalize.o: uninorm/u8-normalize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT uninorm/libgnu_a-u8-normalize.o -MD -MP -MF uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Tpo -c -o uninorm/libgnu_a-u8-normalize.o `test -f 'uninorm/u8-normalize.c' || echo '$(srcdir)/'`uninorm/u8-normalize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Tpo uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uninorm/u8-normalize.c' object='uninorm/libgnu_a-u8-normalize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o uninorm/libgnu_a-u8-normalize.o `test -f 'uninorm/u8-normalize.c' || echo '$(srcdir)/'`uninorm/u8-normalize.c + +uninorm/libgnu_a-u8-normalize.obj: uninorm/u8-normalize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT uninorm/libgnu_a-u8-normalize.obj -MD -MP -MF uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Tpo -c -o uninorm/libgnu_a-u8-normalize.obj `if test -f 'uninorm/u8-normalize.c'; then $(CYGPATH_W) 'uninorm/u8-normalize.c'; else $(CYGPATH_W) '$(srcdir)/uninorm/u8-normalize.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Tpo uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uninorm/u8-normalize.c' object='uninorm/libgnu_a-u8-normalize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o uninorm/libgnu_a-u8-normalize.obj `if test -f 'uninorm/u8-normalize.c'; then $(CYGPATH_W) 'uninorm/u8-normalize.c'; else $(CYGPATH_W) '$(srcdir)/uninorm/u8-normalize.c'; fi` + +libgnu_a-unistd.o: unistd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-unistd.o -MD -MP -MF $(DEPDIR)/libgnu_a-unistd.Tpo -c -o libgnu_a-unistd.o `test -f 'unistd.c' || echo '$(srcdir)/'`unistd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-unistd.Tpo $(DEPDIR)/libgnu_a-unistd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistd.c' object='libgnu_a-unistd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-unistd.o `test -f 'unistd.c' || echo '$(srcdir)/'`unistd.c + +libgnu_a-unistd.obj: unistd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-unistd.obj -MD -MP -MF $(DEPDIR)/libgnu_a-unistd.Tpo -c -o libgnu_a-unistd.obj `if test -f 'unistd.c'; then $(CYGPATH_W) 'unistd.c'; else $(CYGPATH_W) '$(srcdir)/unistd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-unistd.Tpo $(DEPDIR)/libgnu_a-unistd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistd.c' object='libgnu_a-unistd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-unistd.obj `if test -f 'unistd.c'; then $(CYGPATH_W) 'unistd.c'; else $(CYGPATH_W) '$(srcdir)/unistd.c'; fi` + +libgnu_a-dup-safer.o: dup-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup-safer.o -MD -MP -MF $(DEPDIR)/libgnu_a-dup-safer.Tpo -c -o libgnu_a-dup-safer.o `test -f 'dup-safer.c' || echo '$(srcdir)/'`dup-safer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup-safer.Tpo $(DEPDIR)/libgnu_a-dup-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup-safer.c' object='libgnu_a-dup-safer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup-safer.o `test -f 'dup-safer.c' || echo '$(srcdir)/'`dup-safer.c + +libgnu_a-dup-safer.obj: dup-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-dup-safer.obj -MD -MP -MF $(DEPDIR)/libgnu_a-dup-safer.Tpo -c -o libgnu_a-dup-safer.obj `if test -f 'dup-safer.c'; then $(CYGPATH_W) 'dup-safer.c'; else $(CYGPATH_W) '$(srcdir)/dup-safer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-dup-safer.Tpo $(DEPDIR)/libgnu_a-dup-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dup-safer.c' object='libgnu_a-dup-safer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-dup-safer.obj `if test -f 'dup-safer.c'; then $(CYGPATH_W) 'dup-safer.c'; else $(CYGPATH_W) '$(srcdir)/dup-safer.c'; fi` + +libgnu_a-fd-safer.o: fd-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fd-safer.o -MD -MP -MF $(DEPDIR)/libgnu_a-fd-safer.Tpo -c -o libgnu_a-fd-safer.o `test -f 'fd-safer.c' || echo '$(srcdir)/'`fd-safer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fd-safer.Tpo $(DEPDIR)/libgnu_a-fd-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fd-safer.c' object='libgnu_a-fd-safer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fd-safer.o `test -f 'fd-safer.c' || echo '$(srcdir)/'`fd-safer.c + +libgnu_a-fd-safer.obj: fd-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fd-safer.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fd-safer.Tpo -c -o libgnu_a-fd-safer.obj `if test -f 'fd-safer.c'; then $(CYGPATH_W) 'fd-safer.c'; else $(CYGPATH_W) '$(srcdir)/fd-safer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fd-safer.Tpo $(DEPDIR)/libgnu_a-fd-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fd-safer.c' object='libgnu_a-fd-safer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fd-safer.obj `if test -f 'fd-safer.c'; then $(CYGPATH_W) 'fd-safer.c'; else $(CYGPATH_W) '$(srcdir)/fd-safer.c'; fi` + +libgnu_a-pipe-safer.o: pipe-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe-safer.o -MD -MP -MF $(DEPDIR)/libgnu_a-pipe-safer.Tpo -c -o libgnu_a-pipe-safer.o `test -f 'pipe-safer.c' || echo '$(srcdir)/'`pipe-safer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe-safer.Tpo $(DEPDIR)/libgnu_a-pipe-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe-safer.c' object='libgnu_a-pipe-safer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe-safer.o `test -f 'pipe-safer.c' || echo '$(srcdir)/'`pipe-safer.c + +libgnu_a-pipe-safer.obj: pipe-safer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-pipe-safer.obj -MD -MP -MF $(DEPDIR)/libgnu_a-pipe-safer.Tpo -c -o libgnu_a-pipe-safer.obj `if test -f 'pipe-safer.c'; then $(CYGPATH_W) 'pipe-safer.c'; else $(CYGPATH_W) '$(srcdir)/pipe-safer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-pipe-safer.Tpo $(DEPDIR)/libgnu_a-pipe-safer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pipe-safer.c' object='libgnu_a-pipe-safer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-pipe-safer.obj `if test -f 'pipe-safer.c'; then $(CYGPATH_W) 'pipe-safer.c'; else $(CYGPATH_W) '$(srcdir)/pipe-safer.c'; fi` + +unistr/libgnu_a-u8-cpy.o: unistr/u8-cpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-cpy.o -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-cpy.Tpo -c -o unistr/libgnu_a-u8-cpy.o `test -f 'unistr/u8-cpy.c' || echo '$(srcdir)/'`unistr/u8-cpy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-cpy.Tpo unistr/$(DEPDIR)/libgnu_a-u8-cpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-cpy.c' object='unistr/libgnu_a-u8-cpy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-cpy.o `test -f 'unistr/u8-cpy.c' || echo '$(srcdir)/'`unistr/u8-cpy.c + +unistr/libgnu_a-u8-cpy.obj: unistr/u8-cpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-cpy.obj -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-cpy.Tpo -c -o unistr/libgnu_a-u8-cpy.obj `if test -f 'unistr/u8-cpy.c'; then $(CYGPATH_W) 'unistr/u8-cpy.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-cpy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-cpy.Tpo unistr/$(DEPDIR)/libgnu_a-u8-cpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-cpy.c' object='unistr/libgnu_a-u8-cpy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-cpy.obj `if test -f 'unistr/u8-cpy.c'; then $(CYGPATH_W) 'unistr/u8-cpy.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-cpy.c'; fi` + +unistr/libgnu_a-u8-mbtouc-unsafe.o: unistr/u8-mbtouc-unsafe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-mbtouc-unsafe.o -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Tpo -c -o unistr/libgnu_a-u8-mbtouc-unsafe.o `test -f 'unistr/u8-mbtouc-unsafe.c' || echo '$(srcdir)/'`unistr/u8-mbtouc-unsafe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Tpo unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-mbtouc-unsafe.c' object='unistr/libgnu_a-u8-mbtouc-unsafe.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-mbtouc-unsafe.o `test -f 'unistr/u8-mbtouc-unsafe.c' || echo '$(srcdir)/'`unistr/u8-mbtouc-unsafe.c + +unistr/libgnu_a-u8-mbtouc-unsafe.obj: unistr/u8-mbtouc-unsafe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-mbtouc-unsafe.obj -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Tpo -c -o unistr/libgnu_a-u8-mbtouc-unsafe.obj `if test -f 'unistr/u8-mbtouc-unsafe.c'; then $(CYGPATH_W) 'unistr/u8-mbtouc-unsafe.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-mbtouc-unsafe.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Tpo unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-mbtouc-unsafe.c' object='unistr/libgnu_a-u8-mbtouc-unsafe.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-mbtouc-unsafe.obj `if test -f 'unistr/u8-mbtouc-unsafe.c'; then $(CYGPATH_W) 'unistr/u8-mbtouc-unsafe.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-mbtouc-unsafe.c'; fi` + +unistr/libgnu_a-u8-mbtouc-unsafe-aux.o: unistr/u8-mbtouc-unsafe-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-mbtouc-unsafe-aux.o -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Tpo -c -o unistr/libgnu_a-u8-mbtouc-unsafe-aux.o `test -f 'unistr/u8-mbtouc-unsafe-aux.c' || echo '$(srcdir)/'`unistr/u8-mbtouc-unsafe-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Tpo unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-mbtouc-unsafe-aux.c' object='unistr/libgnu_a-u8-mbtouc-unsafe-aux.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-mbtouc-unsafe-aux.o `test -f 'unistr/u8-mbtouc-unsafe-aux.c' || echo '$(srcdir)/'`unistr/u8-mbtouc-unsafe-aux.c + +unistr/libgnu_a-u8-mbtouc-unsafe-aux.obj: unistr/u8-mbtouc-unsafe-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-mbtouc-unsafe-aux.obj -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Tpo -c -o unistr/libgnu_a-u8-mbtouc-unsafe-aux.obj `if test -f 'unistr/u8-mbtouc-unsafe-aux.c'; then $(CYGPATH_W) 'unistr/u8-mbtouc-unsafe-aux.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-mbtouc-unsafe-aux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Tpo unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-mbtouc-unsafe-aux.c' object='unistr/libgnu_a-u8-mbtouc-unsafe-aux.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-mbtouc-unsafe-aux.obj `if test -f 'unistr/u8-mbtouc-unsafe-aux.c'; then $(CYGPATH_W) 'unistr/u8-mbtouc-unsafe-aux.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-mbtouc-unsafe-aux.c'; fi` + +unistr/libgnu_a-u8-strlen.o: unistr/u8-strlen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-strlen.o -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-strlen.Tpo -c -o unistr/libgnu_a-u8-strlen.o `test -f 'unistr/u8-strlen.c' || echo '$(srcdir)/'`unistr/u8-strlen.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-strlen.Tpo unistr/$(DEPDIR)/libgnu_a-u8-strlen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-strlen.c' object='unistr/libgnu_a-u8-strlen.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-strlen.o `test -f 'unistr/u8-strlen.c' || echo '$(srcdir)/'`unistr/u8-strlen.c + +unistr/libgnu_a-u8-strlen.obj: unistr/u8-strlen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-strlen.obj -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-strlen.Tpo -c -o unistr/libgnu_a-u8-strlen.obj `if test -f 'unistr/u8-strlen.c'; then $(CYGPATH_W) 'unistr/u8-strlen.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-strlen.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-strlen.Tpo unistr/$(DEPDIR)/libgnu_a-u8-strlen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-strlen.c' object='unistr/libgnu_a-u8-strlen.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-strlen.obj `if test -f 'unistr/u8-strlen.c'; then $(CYGPATH_W) 'unistr/u8-strlen.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-strlen.c'; fi` + +unistr/libgnu_a-u8-uctomb.o: unistr/u8-uctomb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-uctomb.o -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Tpo -c -o unistr/libgnu_a-u8-uctomb.o `test -f 'unistr/u8-uctomb.c' || echo '$(srcdir)/'`unistr/u8-uctomb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Tpo unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-uctomb.c' object='unistr/libgnu_a-u8-uctomb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-uctomb.o `test -f 'unistr/u8-uctomb.c' || echo '$(srcdir)/'`unistr/u8-uctomb.c + +unistr/libgnu_a-u8-uctomb.obj: unistr/u8-uctomb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-uctomb.obj -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Tpo -c -o unistr/libgnu_a-u8-uctomb.obj `if test -f 'unistr/u8-uctomb.c'; then $(CYGPATH_W) 'unistr/u8-uctomb.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-uctomb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Tpo unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-uctomb.c' object='unistr/libgnu_a-u8-uctomb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-uctomb.obj `if test -f 'unistr/u8-uctomb.c'; then $(CYGPATH_W) 'unistr/u8-uctomb.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-uctomb.c'; fi` + +unistr/libgnu_a-u8-uctomb-aux.o: unistr/u8-uctomb-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-uctomb-aux.o -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Tpo -c -o unistr/libgnu_a-u8-uctomb-aux.o `test -f 'unistr/u8-uctomb-aux.c' || echo '$(srcdir)/'`unistr/u8-uctomb-aux.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Tpo unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-uctomb-aux.c' object='unistr/libgnu_a-u8-uctomb-aux.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-uctomb-aux.o `test -f 'unistr/u8-uctomb-aux.c' || echo '$(srcdir)/'`unistr/u8-uctomb-aux.c + +unistr/libgnu_a-u8-uctomb-aux.obj: unistr/u8-uctomb-aux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT unistr/libgnu_a-u8-uctomb-aux.obj -MD -MP -MF unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Tpo -c -o unistr/libgnu_a-u8-uctomb-aux.obj `if test -f 'unistr/u8-uctomb-aux.c'; then $(CYGPATH_W) 'unistr/u8-uctomb-aux.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-uctomb-aux.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Tpo unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unistr/u8-uctomb-aux.c' object='unistr/libgnu_a-u8-uctomb-aux.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o unistr/libgnu_a-u8-uctomb-aux.obj `if test -f 'unistr/u8-uctomb-aux.c'; then $(CYGPATH_W) 'unistr/u8-uctomb-aux.c'; else $(CYGPATH_W) '$(srcdir)/unistr/u8-uctomb-aux.c'; fi` + +uniwidth/libgnu_a-width.o: uniwidth/width.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT uniwidth/libgnu_a-width.o -MD -MP -MF uniwidth/$(DEPDIR)/libgnu_a-width.Tpo -c -o uniwidth/libgnu_a-width.o `test -f 'uniwidth/width.c' || echo '$(srcdir)/'`uniwidth/width.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) uniwidth/$(DEPDIR)/libgnu_a-width.Tpo uniwidth/$(DEPDIR)/libgnu_a-width.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uniwidth/width.c' object='uniwidth/libgnu_a-width.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o uniwidth/libgnu_a-width.o `test -f 'uniwidth/width.c' || echo '$(srcdir)/'`uniwidth/width.c + +uniwidth/libgnu_a-width.obj: uniwidth/width.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT uniwidth/libgnu_a-width.obj -MD -MP -MF uniwidth/$(DEPDIR)/libgnu_a-width.Tpo -c -o uniwidth/libgnu_a-width.obj `if test -f 'uniwidth/width.c'; then $(CYGPATH_W) 'uniwidth/width.c'; else $(CYGPATH_W) '$(srcdir)/uniwidth/width.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) uniwidth/$(DEPDIR)/libgnu_a-width.Tpo uniwidth/$(DEPDIR)/libgnu_a-width.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uniwidth/width.c' object='uniwidth/libgnu_a-width.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o uniwidth/libgnu_a-width.obj `if test -f 'uniwidth/width.c'; then $(CYGPATH_W) 'uniwidth/width.c'; else $(CYGPATH_W) '$(srcdir)/uniwidth/width.c'; fi` + +libgnu_a-unlink.o: unlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-unlink.o -MD -MP -MF $(DEPDIR)/libgnu_a-unlink.Tpo -c -o libgnu_a-unlink.o `test -f 'unlink.c' || echo '$(srcdir)/'`unlink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-unlink.Tpo $(DEPDIR)/libgnu_a-unlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unlink.c' object='libgnu_a-unlink.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-unlink.o `test -f 'unlink.c' || echo '$(srcdir)/'`unlink.c + +libgnu_a-unlink.obj: unlink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-unlink.obj -MD -MP -MF $(DEPDIR)/libgnu_a-unlink.Tpo -c -o libgnu_a-unlink.obj `if test -f 'unlink.c'; then $(CYGPATH_W) 'unlink.c'; else $(CYGPATH_W) '$(srcdir)/unlink.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-unlink.Tpo $(DEPDIR)/libgnu_a-unlink.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unlink.c' object='libgnu_a-unlink.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-unlink.obj `if test -f 'unlink.c'; then $(CYGPATH_W) 'unlink.c'; else $(CYGPATH_W) '$(srcdir)/unlink.c'; fi` + +libgnu_a-utime.o: utime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-utime.o -MD -MP -MF $(DEPDIR)/libgnu_a-utime.Tpo -c -o libgnu_a-utime.o `test -f 'utime.c' || echo '$(srcdir)/'`utime.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-utime.Tpo $(DEPDIR)/libgnu_a-utime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utime.c' object='libgnu_a-utime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-utime.o `test -f 'utime.c' || echo '$(srcdir)/'`utime.c + +libgnu_a-utime.obj: utime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-utime.obj -MD -MP -MF $(DEPDIR)/libgnu_a-utime.Tpo -c -o libgnu_a-utime.obj `if test -f 'utime.c'; then $(CYGPATH_W) 'utime.c'; else $(CYGPATH_W) '$(srcdir)/utime.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-utime.Tpo $(DEPDIR)/libgnu_a-utime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utime.c' object='libgnu_a-utime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-utime.obj `if test -f 'utime.c'; then $(CYGPATH_W) 'utime.c'; else $(CYGPATH_W) '$(srcdir)/utime.c'; fi` + +libgnu_a-utimens.o: utimens.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-utimens.o -MD -MP -MF $(DEPDIR)/libgnu_a-utimens.Tpo -c -o libgnu_a-utimens.o `test -f 'utimens.c' || echo '$(srcdir)/'`utimens.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-utimens.Tpo $(DEPDIR)/libgnu_a-utimens.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utimens.c' object='libgnu_a-utimens.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-utimens.o `test -f 'utimens.c' || echo '$(srcdir)/'`utimens.c + +libgnu_a-utimens.obj: utimens.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-utimens.obj -MD -MP -MF $(DEPDIR)/libgnu_a-utimens.Tpo -c -o libgnu_a-utimens.obj `if test -f 'utimens.c'; then $(CYGPATH_W) 'utimens.c'; else $(CYGPATH_W) '$(srcdir)/utimens.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-utimens.Tpo $(DEPDIR)/libgnu_a-utimens.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utimens.c' object='libgnu_a-utimens.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-utimens.obj `if test -f 'utimens.c'; then $(CYGPATH_W) 'utimens.c'; else $(CYGPATH_W) '$(srcdir)/utimens.c'; fi` + +libgnu_a-wait-process.o: wait-process.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wait-process.o -MD -MP -MF $(DEPDIR)/libgnu_a-wait-process.Tpo -c -o libgnu_a-wait-process.o `test -f 'wait-process.c' || echo '$(srcdir)/'`wait-process.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wait-process.Tpo $(DEPDIR)/libgnu_a-wait-process.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wait-process.c' object='libgnu_a-wait-process.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wait-process.o `test -f 'wait-process.c' || echo '$(srcdir)/'`wait-process.c + +libgnu_a-wait-process.obj: wait-process.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wait-process.obj -MD -MP -MF $(DEPDIR)/libgnu_a-wait-process.Tpo -c -o libgnu_a-wait-process.obj `if test -f 'wait-process.c'; then $(CYGPATH_W) 'wait-process.c'; else $(CYGPATH_W) '$(srcdir)/wait-process.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wait-process.Tpo $(DEPDIR)/libgnu_a-wait-process.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wait-process.c' object='libgnu_a-wait-process.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wait-process.obj `if test -f 'wait-process.c'; then $(CYGPATH_W) 'wait-process.c'; else $(CYGPATH_W) '$(srcdir)/wait-process.c'; fi` + +libgnu_a-waitpid.o: waitpid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-waitpid.o -MD -MP -MF $(DEPDIR)/libgnu_a-waitpid.Tpo -c -o libgnu_a-waitpid.o `test -f 'waitpid.c' || echo '$(srcdir)/'`waitpid.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-waitpid.Tpo $(DEPDIR)/libgnu_a-waitpid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='waitpid.c' object='libgnu_a-waitpid.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-waitpid.o `test -f 'waitpid.c' || echo '$(srcdir)/'`waitpid.c + +libgnu_a-waitpid.obj: waitpid.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-waitpid.obj -MD -MP -MF $(DEPDIR)/libgnu_a-waitpid.Tpo -c -o libgnu_a-waitpid.obj `if test -f 'waitpid.c'; then $(CYGPATH_W) 'waitpid.c'; else $(CYGPATH_W) '$(srcdir)/waitpid.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-waitpid.Tpo $(DEPDIR)/libgnu_a-waitpid.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='waitpid.c' object='libgnu_a-waitpid.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-waitpid.obj `if test -f 'waitpid.c'; then $(CYGPATH_W) 'waitpid.c'; else $(CYGPATH_W) '$(srcdir)/waitpid.c'; fi` + +libgnu_a-wcrtomb.o: wcrtomb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wcrtomb.o -MD -MP -MF $(DEPDIR)/libgnu_a-wcrtomb.Tpo -c -o libgnu_a-wcrtomb.o `test -f 'wcrtomb.c' || echo '$(srcdir)/'`wcrtomb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wcrtomb.Tpo $(DEPDIR)/libgnu_a-wcrtomb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wcrtomb.c' object='libgnu_a-wcrtomb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wcrtomb.o `test -f 'wcrtomb.c' || echo '$(srcdir)/'`wcrtomb.c + +libgnu_a-wcrtomb.obj: wcrtomb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wcrtomb.obj -MD -MP -MF $(DEPDIR)/libgnu_a-wcrtomb.Tpo -c -o libgnu_a-wcrtomb.obj `if test -f 'wcrtomb.c'; then $(CYGPATH_W) 'wcrtomb.c'; else $(CYGPATH_W) '$(srcdir)/wcrtomb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wcrtomb.Tpo $(DEPDIR)/libgnu_a-wcrtomb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wcrtomb.c' object='libgnu_a-wcrtomb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wcrtomb.obj `if test -f 'wcrtomb.c'; then $(CYGPATH_W) 'wcrtomb.c'; else $(CYGPATH_W) '$(srcdir)/wcrtomb.c'; fi` + +libgnu_a-wctype-h.o: wctype-h.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wctype-h.o -MD -MP -MF $(DEPDIR)/libgnu_a-wctype-h.Tpo -c -o libgnu_a-wctype-h.o `test -f 'wctype-h.c' || echo '$(srcdir)/'`wctype-h.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wctype-h.Tpo $(DEPDIR)/libgnu_a-wctype-h.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wctype-h.c' object='libgnu_a-wctype-h.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wctype-h.o `test -f 'wctype-h.c' || echo '$(srcdir)/'`wctype-h.c + +libgnu_a-wctype-h.obj: wctype-h.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wctype-h.obj -MD -MP -MF $(DEPDIR)/libgnu_a-wctype-h.Tpo -c -o libgnu_a-wctype-h.obj `if test -f 'wctype-h.c'; then $(CYGPATH_W) 'wctype-h.c'; else $(CYGPATH_W) '$(srcdir)/wctype-h.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wctype-h.Tpo $(DEPDIR)/libgnu_a-wctype-h.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wctype-h.c' object='libgnu_a-wctype-h.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wctype-h.obj `if test -f 'wctype-h.c'; then $(CYGPATH_W) 'wctype-h.c'; else $(CYGPATH_W) '$(srcdir)/wctype-h.c'; fi` + +libgnu_a-wcwidth.o: wcwidth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wcwidth.o -MD -MP -MF $(DEPDIR)/libgnu_a-wcwidth.Tpo -c -o libgnu_a-wcwidth.o `test -f 'wcwidth.c' || echo '$(srcdir)/'`wcwidth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wcwidth.Tpo $(DEPDIR)/libgnu_a-wcwidth.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wcwidth.c' object='libgnu_a-wcwidth.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wcwidth.o `test -f 'wcwidth.c' || echo '$(srcdir)/'`wcwidth.c + +libgnu_a-wcwidth.obj: wcwidth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wcwidth.obj -MD -MP -MF $(DEPDIR)/libgnu_a-wcwidth.Tpo -c -o libgnu_a-wcwidth.obj `if test -f 'wcwidth.c'; then $(CYGPATH_W) 'wcwidth.c'; else $(CYGPATH_W) '$(srcdir)/wcwidth.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wcwidth.Tpo $(DEPDIR)/libgnu_a-wcwidth.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wcwidth.c' object='libgnu_a-wcwidth.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wcwidth.obj `if test -f 'wcwidth.c'; then $(CYGPATH_W) 'wcwidth.c'; else $(CYGPATH_W) '$(srcdir)/wcwidth.c'; fi` + +libgnu_a-windows-mutex.o: windows-mutex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-mutex.o -MD -MP -MF $(DEPDIR)/libgnu_a-windows-mutex.Tpo -c -o libgnu_a-windows-mutex.o `test -f 'windows-mutex.c' || echo '$(srcdir)/'`windows-mutex.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-mutex.Tpo $(DEPDIR)/libgnu_a-windows-mutex.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-mutex.c' object='libgnu_a-windows-mutex.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-mutex.o `test -f 'windows-mutex.c' || echo '$(srcdir)/'`windows-mutex.c + +libgnu_a-windows-mutex.obj: windows-mutex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-mutex.obj -MD -MP -MF $(DEPDIR)/libgnu_a-windows-mutex.Tpo -c -o libgnu_a-windows-mutex.obj `if test -f 'windows-mutex.c'; then $(CYGPATH_W) 'windows-mutex.c'; else $(CYGPATH_W) '$(srcdir)/windows-mutex.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-mutex.Tpo $(DEPDIR)/libgnu_a-windows-mutex.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-mutex.c' object='libgnu_a-windows-mutex.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-mutex.obj `if test -f 'windows-mutex.c'; then $(CYGPATH_W) 'windows-mutex.c'; else $(CYGPATH_W) '$(srcdir)/windows-mutex.c'; fi` + +libgnu_a-windows-once.o: windows-once.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-once.o -MD -MP -MF $(DEPDIR)/libgnu_a-windows-once.Tpo -c -o libgnu_a-windows-once.o `test -f 'windows-once.c' || echo '$(srcdir)/'`windows-once.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-once.Tpo $(DEPDIR)/libgnu_a-windows-once.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-once.c' object='libgnu_a-windows-once.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-once.o `test -f 'windows-once.c' || echo '$(srcdir)/'`windows-once.c + +libgnu_a-windows-once.obj: windows-once.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-once.obj -MD -MP -MF $(DEPDIR)/libgnu_a-windows-once.Tpo -c -o libgnu_a-windows-once.obj `if test -f 'windows-once.c'; then $(CYGPATH_W) 'windows-once.c'; else $(CYGPATH_W) '$(srcdir)/windows-once.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-once.Tpo $(DEPDIR)/libgnu_a-windows-once.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-once.c' object='libgnu_a-windows-once.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-once.obj `if test -f 'windows-once.c'; then $(CYGPATH_W) 'windows-once.c'; else $(CYGPATH_W) '$(srcdir)/windows-once.c'; fi` + +libgnu_a-windows-recmutex.o: windows-recmutex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-recmutex.o -MD -MP -MF $(DEPDIR)/libgnu_a-windows-recmutex.Tpo -c -o libgnu_a-windows-recmutex.o `test -f 'windows-recmutex.c' || echo '$(srcdir)/'`windows-recmutex.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-recmutex.Tpo $(DEPDIR)/libgnu_a-windows-recmutex.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-recmutex.c' object='libgnu_a-windows-recmutex.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-recmutex.o `test -f 'windows-recmutex.c' || echo '$(srcdir)/'`windows-recmutex.c + +libgnu_a-windows-recmutex.obj: windows-recmutex.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-recmutex.obj -MD -MP -MF $(DEPDIR)/libgnu_a-windows-recmutex.Tpo -c -o libgnu_a-windows-recmutex.obj `if test -f 'windows-recmutex.c'; then $(CYGPATH_W) 'windows-recmutex.c'; else $(CYGPATH_W) '$(srcdir)/windows-recmutex.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-recmutex.Tpo $(DEPDIR)/libgnu_a-windows-recmutex.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-recmutex.c' object='libgnu_a-windows-recmutex.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-recmutex.obj `if test -f 'windows-recmutex.c'; then $(CYGPATH_W) 'windows-recmutex.c'; else $(CYGPATH_W) '$(srcdir)/windows-recmutex.c'; fi` + +libgnu_a-windows-rwlock.o: windows-rwlock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-rwlock.o -MD -MP -MF $(DEPDIR)/libgnu_a-windows-rwlock.Tpo -c -o libgnu_a-windows-rwlock.o `test -f 'windows-rwlock.c' || echo '$(srcdir)/'`windows-rwlock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-rwlock.Tpo $(DEPDIR)/libgnu_a-windows-rwlock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-rwlock.c' object='libgnu_a-windows-rwlock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-rwlock.o `test -f 'windows-rwlock.c' || echo '$(srcdir)/'`windows-rwlock.c + +libgnu_a-windows-rwlock.obj: windows-rwlock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-rwlock.obj -MD -MP -MF $(DEPDIR)/libgnu_a-windows-rwlock.Tpo -c -o libgnu_a-windows-rwlock.obj `if test -f 'windows-rwlock.c'; then $(CYGPATH_W) 'windows-rwlock.c'; else $(CYGPATH_W) '$(srcdir)/windows-rwlock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-rwlock.Tpo $(DEPDIR)/libgnu_a-windows-rwlock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-rwlock.c' object='libgnu_a-windows-rwlock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-rwlock.obj `if test -f 'windows-rwlock.c'; then $(CYGPATH_W) 'windows-rwlock.c'; else $(CYGPATH_W) '$(srcdir)/windows-rwlock.c'; fi` + +libgnu_a-windows-spawn.o: windows-spawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-spawn.o -MD -MP -MF $(DEPDIR)/libgnu_a-windows-spawn.Tpo -c -o libgnu_a-windows-spawn.o `test -f 'windows-spawn.c' || echo '$(srcdir)/'`windows-spawn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-spawn.Tpo $(DEPDIR)/libgnu_a-windows-spawn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-spawn.c' object='libgnu_a-windows-spawn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-spawn.o `test -f 'windows-spawn.c' || echo '$(srcdir)/'`windows-spawn.c + +libgnu_a-windows-spawn.obj: windows-spawn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-windows-spawn.obj -MD -MP -MF $(DEPDIR)/libgnu_a-windows-spawn.Tpo -c -o libgnu_a-windows-spawn.obj `if test -f 'windows-spawn.c'; then $(CYGPATH_W) 'windows-spawn.c'; else $(CYGPATH_W) '$(srcdir)/windows-spawn.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-windows-spawn.Tpo $(DEPDIR)/libgnu_a-windows-spawn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows-spawn.c' object='libgnu_a-windows-spawn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-windows-spawn.obj `if test -f 'windows-spawn.c'; then $(CYGPATH_W) 'windows-spawn.c'; else $(CYGPATH_W) '$(srcdir)/windows-spawn.c'; fi` + +libgnu_a-wmemchr.o: wmemchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wmemchr.o -MD -MP -MF $(DEPDIR)/libgnu_a-wmemchr.Tpo -c -o libgnu_a-wmemchr.o `test -f 'wmemchr.c' || echo '$(srcdir)/'`wmemchr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wmemchr.Tpo $(DEPDIR)/libgnu_a-wmemchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wmemchr.c' object='libgnu_a-wmemchr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wmemchr.o `test -f 'wmemchr.c' || echo '$(srcdir)/'`wmemchr.c + +libgnu_a-wmemchr.obj: wmemchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wmemchr.obj -MD -MP -MF $(DEPDIR)/libgnu_a-wmemchr.Tpo -c -o libgnu_a-wmemchr.obj `if test -f 'wmemchr.c'; then $(CYGPATH_W) 'wmemchr.c'; else $(CYGPATH_W) '$(srcdir)/wmemchr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wmemchr.Tpo $(DEPDIR)/libgnu_a-wmemchr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wmemchr.c' object='libgnu_a-wmemchr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wmemchr.obj `if test -f 'wmemchr.c'; then $(CYGPATH_W) 'wmemchr.c'; else $(CYGPATH_W) '$(srcdir)/wmemchr.c'; fi` + +libgnu_a-wmempcpy.o: wmempcpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wmempcpy.o -MD -MP -MF $(DEPDIR)/libgnu_a-wmempcpy.Tpo -c -o libgnu_a-wmempcpy.o `test -f 'wmempcpy.c' || echo '$(srcdir)/'`wmempcpy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wmempcpy.Tpo $(DEPDIR)/libgnu_a-wmempcpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wmempcpy.c' object='libgnu_a-wmempcpy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wmempcpy.o `test -f 'wmempcpy.c' || echo '$(srcdir)/'`wmempcpy.c + +libgnu_a-wmempcpy.obj: wmempcpy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-wmempcpy.obj -MD -MP -MF $(DEPDIR)/libgnu_a-wmempcpy.Tpo -c -o libgnu_a-wmempcpy.obj `if test -f 'wmempcpy.c'; then $(CYGPATH_W) 'wmempcpy.c'; else $(CYGPATH_W) '$(srcdir)/wmempcpy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-wmempcpy.Tpo $(DEPDIR)/libgnu_a-wmempcpy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wmempcpy.c' object='libgnu_a-wmempcpy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-wmempcpy.obj `if test -f 'wmempcpy.c'; then $(CYGPATH_W) 'wmempcpy.c'; else $(CYGPATH_W) '$(srcdir)/wmempcpy.c'; fi` + +libgnu_a-write.o: write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-write.o -MD -MP -MF $(DEPDIR)/libgnu_a-write.Tpo -c -o libgnu_a-write.o `test -f 'write.c' || echo '$(srcdir)/'`write.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-write.Tpo $(DEPDIR)/libgnu_a-write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='write.c' object='libgnu_a-write.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-write.o `test -f 'write.c' || echo '$(srcdir)/'`write.c + +libgnu_a-write.obj: write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-write.obj -MD -MP -MF $(DEPDIR)/libgnu_a-write.Tpo -c -o libgnu_a-write.obj `if test -f 'write.c'; then $(CYGPATH_W) 'write.c'; else $(CYGPATH_W) '$(srcdir)/write.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-write.Tpo $(DEPDIR)/libgnu_a-write.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='write.c' object='libgnu_a-write.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-write.obj `if test -f 'write.c'; then $(CYGPATH_W) 'write.c'; else $(CYGPATH_W) '$(srcdir)/write.c'; fi` + +libgnu_a-xmalloc.o: xmalloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xmalloc.o -MD -MP -MF $(DEPDIR)/libgnu_a-xmalloc.Tpo -c -o libgnu_a-xmalloc.o `test -f 'xmalloc.c' || echo '$(srcdir)/'`xmalloc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xmalloc.Tpo $(DEPDIR)/libgnu_a-xmalloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmalloc.c' object='libgnu_a-xmalloc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xmalloc.o `test -f 'xmalloc.c' || echo '$(srcdir)/'`xmalloc.c + +libgnu_a-xmalloc.obj: xmalloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xmalloc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-xmalloc.Tpo -c -o libgnu_a-xmalloc.obj `if test -f 'xmalloc.c'; then $(CYGPATH_W) 'xmalloc.c'; else $(CYGPATH_W) '$(srcdir)/xmalloc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xmalloc.Tpo $(DEPDIR)/libgnu_a-xmalloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmalloc.c' object='libgnu_a-xmalloc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xmalloc.obj `if test -f 'xmalloc.c'; then $(CYGPATH_W) 'xmalloc.c'; else $(CYGPATH_W) '$(srcdir)/xmalloc.c'; fi` + +libgnu_a-xalloc-die.o: xalloc-die.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xalloc-die.o -MD -MP -MF $(DEPDIR)/libgnu_a-xalloc-die.Tpo -c -o libgnu_a-xalloc-die.o `test -f 'xalloc-die.c' || echo '$(srcdir)/'`xalloc-die.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xalloc-die.Tpo $(DEPDIR)/libgnu_a-xalloc-die.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xalloc-die.c' object='libgnu_a-xalloc-die.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xalloc-die.o `test -f 'xalloc-die.c' || echo '$(srcdir)/'`xalloc-die.c + +libgnu_a-xalloc-die.obj: xalloc-die.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xalloc-die.obj -MD -MP -MF $(DEPDIR)/libgnu_a-xalloc-die.Tpo -c -o libgnu_a-xalloc-die.obj `if test -f 'xalloc-die.c'; then $(CYGPATH_W) 'xalloc-die.c'; else $(CYGPATH_W) '$(srcdir)/xalloc-die.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xalloc-die.Tpo $(DEPDIR)/libgnu_a-xalloc-die.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xalloc-die.c' object='libgnu_a-xalloc-die.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xalloc-die.obj `if test -f 'xalloc-die.c'; then $(CYGPATH_W) 'xalloc-die.c'; else $(CYGPATH_W) '$(srcdir)/xalloc-die.c'; fi` + +libgnu_a-xmemdup0.o: xmemdup0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xmemdup0.o -MD -MP -MF $(DEPDIR)/libgnu_a-xmemdup0.Tpo -c -o libgnu_a-xmemdup0.o `test -f 'xmemdup0.c' || echo '$(srcdir)/'`xmemdup0.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xmemdup0.Tpo $(DEPDIR)/libgnu_a-xmemdup0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmemdup0.c' object='libgnu_a-xmemdup0.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xmemdup0.o `test -f 'xmemdup0.c' || echo '$(srcdir)/'`xmemdup0.c + +libgnu_a-xmemdup0.obj: xmemdup0.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xmemdup0.obj -MD -MP -MF $(DEPDIR)/libgnu_a-xmemdup0.Tpo -c -o libgnu_a-xmemdup0.obj `if test -f 'xmemdup0.c'; then $(CYGPATH_W) 'xmemdup0.c'; else $(CYGPATH_W) '$(srcdir)/xmemdup0.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xmemdup0.Tpo $(DEPDIR)/libgnu_a-xmemdup0.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmemdup0.c' object='libgnu_a-xmemdup0.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xmemdup0.obj `if test -f 'xmemdup0.c'; then $(CYGPATH_W) 'xmemdup0.c'; else $(CYGPATH_W) '$(srcdir)/xmemdup0.c'; fi` + +libgnu_a-xsize.o: xsize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xsize.o -MD -MP -MF $(DEPDIR)/libgnu_a-xsize.Tpo -c -o libgnu_a-xsize.o `test -f 'xsize.c' || echo '$(srcdir)/'`xsize.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xsize.Tpo $(DEPDIR)/libgnu_a-xsize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsize.c' object='libgnu_a-xsize.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xsize.o `test -f 'xsize.c' || echo '$(srcdir)/'`xsize.c + +libgnu_a-xsize.obj: xsize.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xsize.obj -MD -MP -MF $(DEPDIR)/libgnu_a-xsize.Tpo -c -o libgnu_a-xsize.obj `if test -f 'xsize.c'; then $(CYGPATH_W) 'xsize.c'; else $(CYGPATH_W) '$(srcdir)/xsize.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xsize.Tpo $(DEPDIR)/libgnu_a-xsize.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xsize.c' object='libgnu_a-xsize.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xsize.obj `if test -f 'xsize.c'; then $(CYGPATH_W) 'xsize.c'; else $(CYGPATH_W) '$(srcdir)/xsize.c'; fi` + +libgnu_a-xstrndup.o: xstrndup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xstrndup.o -MD -MP -MF $(DEPDIR)/libgnu_a-xstrndup.Tpo -c -o libgnu_a-xstrndup.o `test -f 'xstrndup.c' || echo '$(srcdir)/'`xstrndup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xstrndup.Tpo $(DEPDIR)/libgnu_a-xstrndup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xstrndup.c' object='libgnu_a-xstrndup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xstrndup.o `test -f 'xstrndup.c' || echo '$(srcdir)/'`xstrndup.c + +libgnu_a-xstrndup.obj: xstrndup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-xstrndup.obj -MD -MP -MF $(DEPDIR)/libgnu_a-xstrndup.Tpo -c -o libgnu_a-xstrndup.obj `if test -f 'xstrndup.c'; then $(CYGPATH_W) 'xstrndup.c'; else $(CYGPATH_W) '$(srcdir)/xstrndup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-xstrndup.Tpo $(DEPDIR)/libgnu_a-xstrndup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xstrndup.c' object='libgnu_a-xstrndup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-xstrndup.obj `if test -f 'xstrndup.c'; then $(CYGPATH_W) 'xstrndup.c'; else $(CYGPATH_W) '$(srcdir)/xstrndup.c'; fi` + +libgnu_a-alloca.o: alloca.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-alloca.o -MD -MP -MF $(DEPDIR)/libgnu_a-alloca.Tpo -c -o libgnu_a-alloca.o `test -f 'alloca.c' || echo '$(srcdir)/'`alloca.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-alloca.Tpo $(DEPDIR)/libgnu_a-alloca.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alloca.c' object='libgnu_a-alloca.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-alloca.o `test -f 'alloca.c' || echo '$(srcdir)/'`alloca.c + +libgnu_a-alloca.obj: alloca.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-alloca.obj -MD -MP -MF $(DEPDIR)/libgnu_a-alloca.Tpo -c -o libgnu_a-alloca.obj `if test -f 'alloca.c'; then $(CYGPATH_W) 'alloca.c'; else $(CYGPATH_W) '$(srcdir)/alloca.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-alloca.Tpo $(DEPDIR)/libgnu_a-alloca.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alloca.c' object='libgnu_a-alloca.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-alloca.obj `if test -f 'alloca.c'; then $(CYGPATH_W) 'alloca.c'; else $(CYGPATH_W) '$(srcdir)/alloca.c'; fi` + +libgnu_a-calloc.o: calloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-calloc.o -MD -MP -MF $(DEPDIR)/libgnu_a-calloc.Tpo -c -o libgnu_a-calloc.o `test -f 'calloc.c' || echo '$(srcdir)/'`calloc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-calloc.Tpo $(DEPDIR)/libgnu_a-calloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='calloc.c' object='libgnu_a-calloc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-calloc.o `test -f 'calloc.c' || echo '$(srcdir)/'`calloc.c + +libgnu_a-calloc.obj: calloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-calloc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-calloc.Tpo -c -o libgnu_a-calloc.obj `if test -f 'calloc.c'; then $(CYGPATH_W) 'calloc.c'; else $(CYGPATH_W) '$(srcdir)/calloc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-calloc.Tpo $(DEPDIR)/libgnu_a-calloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='calloc.c' object='libgnu_a-calloc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-calloc.obj `if test -f 'calloc.c'; then $(CYGPATH_W) 'calloc.c'; else $(CYGPATH_W) '$(srcdir)/calloc.c'; fi` + +malloc/libgnu_a-dynarray-skeleton.o: malloc/dynarray-skeleton.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray-skeleton.o -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Tpo -c -o malloc/libgnu_a-dynarray-skeleton.o `test -f 'malloc/dynarray-skeleton.c' || echo '$(srcdir)/'`malloc/dynarray-skeleton.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray-skeleton.c' object='malloc/libgnu_a-dynarray-skeleton.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray-skeleton.o `test -f 'malloc/dynarray-skeleton.c' || echo '$(srcdir)/'`malloc/dynarray-skeleton.c + +malloc/libgnu_a-dynarray-skeleton.obj: malloc/dynarray-skeleton.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT malloc/libgnu_a-dynarray-skeleton.obj -MD -MP -MF malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Tpo -c -o malloc/libgnu_a-dynarray-skeleton.obj `if test -f 'malloc/dynarray-skeleton.c'; then $(CYGPATH_W) 'malloc/dynarray-skeleton.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray-skeleton.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Tpo malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc/dynarray-skeleton.c' object='malloc/libgnu_a-dynarray-skeleton.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o malloc/libgnu_a-dynarray-skeleton.obj `if test -f 'malloc/dynarray-skeleton.c'; then $(CYGPATH_W) 'malloc/dynarray-skeleton.c'; else $(CYGPATH_W) '$(srcdir)/malloc/dynarray-skeleton.c'; fi` + +libgnu_a-fnmatch.o: fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fnmatch.o -MD -MP -MF $(DEPDIR)/libgnu_a-fnmatch.Tpo -c -o libgnu_a-fnmatch.o `test -f 'fnmatch.c' || echo '$(srcdir)/'`fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fnmatch.Tpo $(DEPDIR)/libgnu_a-fnmatch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fnmatch.c' object='libgnu_a-fnmatch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fnmatch.o `test -f 'fnmatch.c' || echo '$(srcdir)/'`fnmatch.c + +libgnu_a-fnmatch.obj: fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fnmatch.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fnmatch.Tpo -c -o libgnu_a-fnmatch.obj `if test -f 'fnmatch.c'; then $(CYGPATH_W) 'fnmatch.c'; else $(CYGPATH_W) '$(srcdir)/fnmatch.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fnmatch.Tpo $(DEPDIR)/libgnu_a-fnmatch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fnmatch.c' object='libgnu_a-fnmatch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fnmatch.obj `if test -f 'fnmatch.c'; then $(CYGPATH_W) 'fnmatch.c'; else $(CYGPATH_W) '$(srcdir)/fnmatch.c'; fi` + +libgnu_a-fnmatch_loop.o: fnmatch_loop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fnmatch_loop.o -MD -MP -MF $(DEPDIR)/libgnu_a-fnmatch_loop.Tpo -c -o libgnu_a-fnmatch_loop.o `test -f 'fnmatch_loop.c' || echo '$(srcdir)/'`fnmatch_loop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fnmatch_loop.Tpo $(DEPDIR)/libgnu_a-fnmatch_loop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fnmatch_loop.c' object='libgnu_a-fnmatch_loop.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fnmatch_loop.o `test -f 'fnmatch_loop.c' || echo '$(srcdir)/'`fnmatch_loop.c + +libgnu_a-fnmatch_loop.obj: fnmatch_loop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fnmatch_loop.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fnmatch_loop.Tpo -c -o libgnu_a-fnmatch_loop.obj `if test -f 'fnmatch_loop.c'; then $(CYGPATH_W) 'fnmatch_loop.c'; else $(CYGPATH_W) '$(srcdir)/fnmatch_loop.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fnmatch_loop.Tpo $(DEPDIR)/libgnu_a-fnmatch_loop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fnmatch_loop.c' object='libgnu_a-fnmatch_loop.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fnmatch_loop.obj `if test -f 'fnmatch_loop.c'; then $(CYGPATH_W) 'fnmatch_loop.c'; else $(CYGPATH_W) '$(srcdir)/fnmatch_loop.c'; fi` + +libgnu_a-fopen.o: fopen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fopen.o -MD -MP -MF $(DEPDIR)/libgnu_a-fopen.Tpo -c -o libgnu_a-fopen.o `test -f 'fopen.c' || echo '$(srcdir)/'`fopen.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fopen.Tpo $(DEPDIR)/libgnu_a-fopen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fopen.c' object='libgnu_a-fopen.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fopen.o `test -f 'fopen.c' || echo '$(srcdir)/'`fopen.c + +libgnu_a-fopen.obj: fopen.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-fopen.obj -MD -MP -MF $(DEPDIR)/libgnu_a-fopen.Tpo -c -o libgnu_a-fopen.obj `if test -f 'fopen.c'; then $(CYGPATH_W) 'fopen.c'; else $(CYGPATH_W) '$(srcdir)/fopen.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-fopen.Tpo $(DEPDIR)/libgnu_a-fopen.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fopen.c' object='libgnu_a-fopen.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-fopen.obj `if test -f 'fopen.c'; then $(CYGPATH_W) 'fopen.c'; else $(CYGPATH_W) '$(srcdir)/fopen.c'; fi` + +libgnu_a-stat-w32.o: stat-w32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stat-w32.o -MD -MP -MF $(DEPDIR)/libgnu_a-stat-w32.Tpo -c -o libgnu_a-stat-w32.o `test -f 'stat-w32.c' || echo '$(srcdir)/'`stat-w32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stat-w32.Tpo $(DEPDIR)/libgnu_a-stat-w32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stat-w32.c' object='libgnu_a-stat-w32.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stat-w32.o `test -f 'stat-w32.c' || echo '$(srcdir)/'`stat-w32.c + +libgnu_a-stat-w32.obj: stat-w32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-stat-w32.obj -MD -MP -MF $(DEPDIR)/libgnu_a-stat-w32.Tpo -c -o libgnu_a-stat-w32.obj `if test -f 'stat-w32.c'; then $(CYGPATH_W) 'stat-w32.c'; else $(CYGPATH_W) '$(srcdir)/stat-w32.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-stat-w32.Tpo $(DEPDIR)/libgnu_a-stat-w32.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stat-w32.c' object='libgnu_a-stat-w32.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-stat-w32.obj `if test -f 'stat-w32.c'; then $(CYGPATH_W) 'stat-w32.c'; else $(CYGPATH_W) '$(srcdir)/stat-w32.c'; fi` + +libgnu_a-at-func.o: at-func.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-at-func.o -MD -MP -MF $(DEPDIR)/libgnu_a-at-func.Tpo -c -o libgnu_a-at-func.o `test -f 'at-func.c' || echo '$(srcdir)/'`at-func.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-at-func.Tpo $(DEPDIR)/libgnu_a-at-func.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='at-func.c' object='libgnu_a-at-func.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-at-func.o `test -f 'at-func.c' || echo '$(srcdir)/'`at-func.c + +libgnu_a-at-func.obj: at-func.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-at-func.obj -MD -MP -MF $(DEPDIR)/libgnu_a-at-func.Tpo -c -o libgnu_a-at-func.obj `if test -f 'at-func.c'; then $(CYGPATH_W) 'at-func.c'; else $(CYGPATH_W) '$(srcdir)/at-func.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-at-func.Tpo $(DEPDIR)/libgnu_a-at-func.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='at-func.c' object='libgnu_a-at-func.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-at-func.obj `if test -f 'at-func.c'; then $(CYGPATH_W) 'at-func.c'; else $(CYGPATH_W) '$(srcdir)/at-func.c'; fi` + +libgnu_a-getpass.o: getpass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getpass.o -MD -MP -MF $(DEPDIR)/libgnu_a-getpass.Tpo -c -o libgnu_a-getpass.o `test -f 'getpass.c' || echo '$(srcdir)/'`getpass.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getpass.Tpo $(DEPDIR)/libgnu_a-getpass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getpass.c' object='libgnu_a-getpass.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getpass.o `test -f 'getpass.c' || echo '$(srcdir)/'`getpass.c + +libgnu_a-getpass.obj: getpass.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-getpass.obj -MD -MP -MF $(DEPDIR)/libgnu_a-getpass.Tpo -c -o libgnu_a-getpass.obj `if test -f 'getpass.c'; then $(CYGPATH_W) 'getpass.c'; else $(CYGPATH_W) '$(srcdir)/getpass.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-getpass.Tpo $(DEPDIR)/libgnu_a-getpass.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getpass.c' object='libgnu_a-getpass.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-getpass.obj `if test -f 'getpass.c'; then $(CYGPATH_W) 'getpass.c'; else $(CYGPATH_W) '$(srcdir)/getpass.c'; fi` + +libgnu_a-malloc.o: malloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-malloc.o -MD -MP -MF $(DEPDIR)/libgnu_a-malloc.Tpo -c -o libgnu_a-malloc.o `test -f 'malloc.c' || echo '$(srcdir)/'`malloc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-malloc.Tpo $(DEPDIR)/libgnu_a-malloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc.c' object='libgnu_a-malloc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-malloc.o `test -f 'malloc.c' || echo '$(srcdir)/'`malloc.c + +libgnu_a-malloc.obj: malloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-malloc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-malloc.Tpo -c -o libgnu_a-malloc.obj `if test -f 'malloc.c'; then $(CYGPATH_W) 'malloc.c'; else $(CYGPATH_W) '$(srcdir)/malloc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-malloc.Tpo $(DEPDIR)/libgnu_a-malloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc.c' object='libgnu_a-malloc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-malloc.obj `if test -f 'malloc.c'; then $(CYGPATH_W) 'malloc.c'; else $(CYGPATH_W) '$(srcdir)/malloc.c'; fi` + +libgnu_a-lc-charset-dispatch.o: lc-charset-dispatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-lc-charset-dispatch.o -MD -MP -MF $(DEPDIR)/libgnu_a-lc-charset-dispatch.Tpo -c -o libgnu_a-lc-charset-dispatch.o `test -f 'lc-charset-dispatch.c' || echo '$(srcdir)/'`lc-charset-dispatch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-lc-charset-dispatch.Tpo $(DEPDIR)/libgnu_a-lc-charset-dispatch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lc-charset-dispatch.c' object='libgnu_a-lc-charset-dispatch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-lc-charset-dispatch.o `test -f 'lc-charset-dispatch.c' || echo '$(srcdir)/'`lc-charset-dispatch.c + +libgnu_a-lc-charset-dispatch.obj: lc-charset-dispatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-lc-charset-dispatch.obj -MD -MP -MF $(DEPDIR)/libgnu_a-lc-charset-dispatch.Tpo -c -o libgnu_a-lc-charset-dispatch.obj `if test -f 'lc-charset-dispatch.c'; then $(CYGPATH_W) 'lc-charset-dispatch.c'; else $(CYGPATH_W) '$(srcdir)/lc-charset-dispatch.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-lc-charset-dispatch.Tpo $(DEPDIR)/libgnu_a-lc-charset-dispatch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lc-charset-dispatch.c' object='libgnu_a-lc-charset-dispatch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-lc-charset-dispatch.obj `if test -f 'lc-charset-dispatch.c'; then $(CYGPATH_W) 'lc-charset-dispatch.c'; else $(CYGPATH_W) '$(srcdir)/lc-charset-dispatch.c'; fi` + +libgnu_a-mbtowc-lock.o: mbtowc-lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbtowc-lock.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbtowc-lock.Tpo -c -o libgnu_a-mbtowc-lock.o `test -f 'mbtowc-lock.c' || echo '$(srcdir)/'`mbtowc-lock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbtowc-lock.Tpo $(DEPDIR)/libgnu_a-mbtowc-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbtowc-lock.c' object='libgnu_a-mbtowc-lock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbtowc-lock.o `test -f 'mbtowc-lock.c' || echo '$(srcdir)/'`mbtowc-lock.c + +libgnu_a-mbtowc-lock.obj: mbtowc-lock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbtowc-lock.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbtowc-lock.Tpo -c -o libgnu_a-mbtowc-lock.obj `if test -f 'mbtowc-lock.c'; then $(CYGPATH_W) 'mbtowc-lock.c'; else $(CYGPATH_W) '$(srcdir)/mbtowc-lock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbtowc-lock.Tpo $(DEPDIR)/libgnu_a-mbtowc-lock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbtowc-lock.c' object='libgnu_a-mbtowc-lock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbtowc-lock.obj `if test -f 'mbtowc-lock.c'; then $(CYGPATH_W) 'mbtowc-lock.c'; else $(CYGPATH_W) '$(srcdir)/mbtowc-lock.c'; fi` + +libgnu_a-mbsrtowcs-state.o: mbsrtowcs-state.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbsrtowcs-state.o -MD -MP -MF $(DEPDIR)/libgnu_a-mbsrtowcs-state.Tpo -c -o libgnu_a-mbsrtowcs-state.o `test -f 'mbsrtowcs-state.c' || echo '$(srcdir)/'`mbsrtowcs-state.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbsrtowcs-state.Tpo $(DEPDIR)/libgnu_a-mbsrtowcs-state.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbsrtowcs-state.c' object='libgnu_a-mbsrtowcs-state.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbsrtowcs-state.o `test -f 'mbsrtowcs-state.c' || echo '$(srcdir)/'`mbsrtowcs-state.c + +libgnu_a-mbsrtowcs-state.obj: mbsrtowcs-state.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mbsrtowcs-state.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mbsrtowcs-state.Tpo -c -o libgnu_a-mbsrtowcs-state.obj `if test -f 'mbsrtowcs-state.c'; then $(CYGPATH_W) 'mbsrtowcs-state.c'; else $(CYGPATH_W) '$(srcdir)/mbsrtowcs-state.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mbsrtowcs-state.Tpo $(DEPDIR)/libgnu_a-mbsrtowcs-state.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mbsrtowcs-state.c' object='libgnu_a-mbsrtowcs-state.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mbsrtowcs-state.obj `if test -f 'mbsrtowcs-state.c'; then $(CYGPATH_W) 'mbsrtowcs-state.c'; else $(CYGPATH_W) '$(srcdir)/mbsrtowcs-state.c'; fi` + +libgnu_a-mktime.o: mktime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mktime.o -MD -MP -MF $(DEPDIR)/libgnu_a-mktime.Tpo -c -o libgnu_a-mktime.o `test -f 'mktime.c' || echo '$(srcdir)/'`mktime.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mktime.Tpo $(DEPDIR)/libgnu_a-mktime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mktime.c' object='libgnu_a-mktime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mktime.o `test -f 'mktime.c' || echo '$(srcdir)/'`mktime.c + +libgnu_a-mktime.obj: mktime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-mktime.obj -MD -MP -MF $(DEPDIR)/libgnu_a-mktime.Tpo -c -o libgnu_a-mktime.obj `if test -f 'mktime.c'; then $(CYGPATH_W) 'mktime.c'; else $(CYGPATH_W) '$(srcdir)/mktime.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-mktime.Tpo $(DEPDIR)/libgnu_a-mktime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mktime.c' object='libgnu_a-mktime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-mktime.obj `if test -f 'mktime.c'; then $(CYGPATH_W) 'mktime.c'; else $(CYGPATH_W) '$(srcdir)/mktime.c'; fi` + +libgnu_a-realloc.o: realloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-realloc.o -MD -MP -MF $(DEPDIR)/libgnu_a-realloc.Tpo -c -o libgnu_a-realloc.o `test -f 'realloc.c' || echo '$(srcdir)/'`realloc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-realloc.Tpo $(DEPDIR)/libgnu_a-realloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='realloc.c' object='libgnu_a-realloc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-realloc.o `test -f 'realloc.c' || echo '$(srcdir)/'`realloc.c + +libgnu_a-realloc.obj: realloc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-realloc.obj -MD -MP -MF $(DEPDIR)/libgnu_a-realloc.Tpo -c -o libgnu_a-realloc.obj `if test -f 'realloc.c'; then $(CYGPATH_W) 'realloc.c'; else $(CYGPATH_W) '$(srcdir)/realloc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-realloc.Tpo $(DEPDIR)/libgnu_a-realloc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='realloc.c' object='libgnu_a-realloc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-realloc.obj `if test -f 'realloc.c'; then $(CYGPATH_W) 'realloc.c'; else $(CYGPATH_W) '$(srcdir)/realloc.c'; fi` + +libgnu_a-regcomp.o: regcomp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regcomp.o -MD -MP -MF $(DEPDIR)/libgnu_a-regcomp.Tpo -c -o libgnu_a-regcomp.o `test -f 'regcomp.c' || echo '$(srcdir)/'`regcomp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regcomp.Tpo $(DEPDIR)/libgnu_a-regcomp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regcomp.c' object='libgnu_a-regcomp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regcomp.o `test -f 'regcomp.c' || echo '$(srcdir)/'`regcomp.c + +libgnu_a-regcomp.obj: regcomp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regcomp.obj -MD -MP -MF $(DEPDIR)/libgnu_a-regcomp.Tpo -c -o libgnu_a-regcomp.obj `if test -f 'regcomp.c'; then $(CYGPATH_W) 'regcomp.c'; else $(CYGPATH_W) '$(srcdir)/regcomp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regcomp.Tpo $(DEPDIR)/libgnu_a-regcomp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regcomp.c' object='libgnu_a-regcomp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regcomp.obj `if test -f 'regcomp.c'; then $(CYGPATH_W) 'regcomp.c'; else $(CYGPATH_W) '$(srcdir)/regcomp.c'; fi` + +libgnu_a-regex_internal.o: regex_internal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regex_internal.o -MD -MP -MF $(DEPDIR)/libgnu_a-regex_internal.Tpo -c -o libgnu_a-regex_internal.o `test -f 'regex_internal.c' || echo '$(srcdir)/'`regex_internal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regex_internal.Tpo $(DEPDIR)/libgnu_a-regex_internal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regex_internal.c' object='libgnu_a-regex_internal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regex_internal.o `test -f 'regex_internal.c' || echo '$(srcdir)/'`regex_internal.c + +libgnu_a-regex_internal.obj: regex_internal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regex_internal.obj -MD -MP -MF $(DEPDIR)/libgnu_a-regex_internal.Tpo -c -o libgnu_a-regex_internal.obj `if test -f 'regex_internal.c'; then $(CYGPATH_W) 'regex_internal.c'; else $(CYGPATH_W) '$(srcdir)/regex_internal.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regex_internal.Tpo $(DEPDIR)/libgnu_a-regex_internal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regex_internal.c' object='libgnu_a-regex_internal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regex_internal.obj `if test -f 'regex_internal.c'; then $(CYGPATH_W) 'regex_internal.c'; else $(CYGPATH_W) '$(srcdir)/regex_internal.c'; fi` + +libgnu_a-regexec.o: regexec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regexec.o -MD -MP -MF $(DEPDIR)/libgnu_a-regexec.Tpo -c -o libgnu_a-regexec.o `test -f 'regexec.c' || echo '$(srcdir)/'`regexec.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regexec.Tpo $(DEPDIR)/libgnu_a-regexec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regexec.c' object='libgnu_a-regexec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regexec.o `test -f 'regexec.c' || echo '$(srcdir)/'`regexec.c + +libgnu_a-regexec.obj: regexec.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-regexec.obj -MD -MP -MF $(DEPDIR)/libgnu_a-regexec.Tpo -c -o libgnu_a-regexec.obj `if test -f 'regexec.c'; then $(CYGPATH_W) 'regexec.c'; else $(CYGPATH_W) '$(srcdir)/regexec.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-regexec.Tpo $(DEPDIR)/libgnu_a-regexec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regexec.c' object='libgnu_a-regexec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-regexec.obj `if test -f 'regexec.c'; then $(CYGPATH_W) 'regexec.c'; else $(CYGPATH_W) '$(srcdir)/regexec.c'; fi` + +libgnu_a-snprintf.o: snprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-snprintf.o -MD -MP -MF $(DEPDIR)/libgnu_a-snprintf.Tpo -c -o libgnu_a-snprintf.o `test -f 'snprintf.c' || echo '$(srcdir)/'`snprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-snprintf.Tpo $(DEPDIR)/libgnu_a-snprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='snprintf.c' object='libgnu_a-snprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-snprintf.o `test -f 'snprintf.c' || echo '$(srcdir)/'`snprintf.c + +libgnu_a-snprintf.obj: snprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-snprintf.obj -MD -MP -MF $(DEPDIR)/libgnu_a-snprintf.Tpo -c -o libgnu_a-snprintf.obj `if test -f 'snprintf.c'; then $(CYGPATH_W) 'snprintf.c'; else $(CYGPATH_W) '$(srcdir)/snprintf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-snprintf.Tpo $(DEPDIR)/libgnu_a-snprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='snprintf.c' object='libgnu_a-snprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-snprintf.obj `if test -f 'snprintf.c'; then $(CYGPATH_W) 'snprintf.c'; else $(CYGPATH_W) '$(srcdir)/snprintf.c'; fi` + +libgnu_a-strerror_r.o: strerror_r.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strerror_r.o -MD -MP -MF $(DEPDIR)/libgnu_a-strerror_r.Tpo -c -o libgnu_a-strerror_r.o `test -f 'strerror_r.c' || echo '$(srcdir)/'`strerror_r.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strerror_r.Tpo $(DEPDIR)/libgnu_a-strerror_r.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror_r.c' object='libgnu_a-strerror_r.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strerror_r.o `test -f 'strerror_r.c' || echo '$(srcdir)/'`strerror_r.c + +libgnu_a-strerror_r.obj: strerror_r.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-strerror_r.obj -MD -MP -MF $(DEPDIR)/libgnu_a-strerror_r.Tpo -c -o libgnu_a-strerror_r.obj `if test -f 'strerror_r.c'; then $(CYGPATH_W) 'strerror_r.c'; else $(CYGPATH_W) '$(srcdir)/strerror_r.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-strerror_r.Tpo $(DEPDIR)/libgnu_a-strerror_r.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror_r.c' object='libgnu_a-strerror_r.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-strerror_r.obj `if test -f 'strerror_r.c'; then $(CYGPATH_W) 'strerror_r.c'; else $(CYGPATH_W) '$(srcdir)/strerror_r.c'; fi` + +libgnu_a-asnprintf.o: asnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-asnprintf.o -MD -MP -MF $(DEPDIR)/libgnu_a-asnprintf.Tpo -c -o libgnu_a-asnprintf.o `test -f 'asnprintf.c' || echo '$(srcdir)/'`asnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-asnprintf.Tpo $(DEPDIR)/libgnu_a-asnprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asnprintf.c' object='libgnu_a-asnprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-asnprintf.o `test -f 'asnprintf.c' || echo '$(srcdir)/'`asnprintf.c + +libgnu_a-asnprintf.obj: asnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-asnprintf.obj -MD -MP -MF $(DEPDIR)/libgnu_a-asnprintf.Tpo -c -o libgnu_a-asnprintf.obj `if test -f 'asnprintf.c'; then $(CYGPATH_W) 'asnprintf.c'; else $(CYGPATH_W) '$(srcdir)/asnprintf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-asnprintf.Tpo $(DEPDIR)/libgnu_a-asnprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asnprintf.c' object='libgnu_a-asnprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-asnprintf.obj `if test -f 'asnprintf.c'; then $(CYGPATH_W) 'asnprintf.c'; else $(CYGPATH_W) '$(srcdir)/asnprintf.c'; fi` + +libgnu_a-printf-args.o: printf-args.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-printf-args.o -MD -MP -MF $(DEPDIR)/libgnu_a-printf-args.Tpo -c -o libgnu_a-printf-args.o `test -f 'printf-args.c' || echo '$(srcdir)/'`printf-args.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-printf-args.Tpo $(DEPDIR)/libgnu_a-printf-args.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='printf-args.c' object='libgnu_a-printf-args.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-printf-args.o `test -f 'printf-args.c' || echo '$(srcdir)/'`printf-args.c + +libgnu_a-printf-args.obj: printf-args.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-printf-args.obj -MD -MP -MF $(DEPDIR)/libgnu_a-printf-args.Tpo -c -o libgnu_a-printf-args.obj `if test -f 'printf-args.c'; then $(CYGPATH_W) 'printf-args.c'; else $(CYGPATH_W) '$(srcdir)/printf-args.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-printf-args.Tpo $(DEPDIR)/libgnu_a-printf-args.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='printf-args.c' object='libgnu_a-printf-args.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-printf-args.obj `if test -f 'printf-args.c'; then $(CYGPATH_W) 'printf-args.c'; else $(CYGPATH_W) '$(srcdir)/printf-args.c'; fi` + +libgnu_a-printf-parse.o: printf-parse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-printf-parse.o -MD -MP -MF $(DEPDIR)/libgnu_a-printf-parse.Tpo -c -o libgnu_a-printf-parse.o `test -f 'printf-parse.c' || echo '$(srcdir)/'`printf-parse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-printf-parse.Tpo $(DEPDIR)/libgnu_a-printf-parse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='printf-parse.c' object='libgnu_a-printf-parse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-printf-parse.o `test -f 'printf-parse.c' || echo '$(srcdir)/'`printf-parse.c + +libgnu_a-printf-parse.obj: printf-parse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-printf-parse.obj -MD -MP -MF $(DEPDIR)/libgnu_a-printf-parse.Tpo -c -o libgnu_a-printf-parse.obj `if test -f 'printf-parse.c'; then $(CYGPATH_W) 'printf-parse.c'; else $(CYGPATH_W) '$(srcdir)/printf-parse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-printf-parse.Tpo $(DEPDIR)/libgnu_a-printf-parse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='printf-parse.c' object='libgnu_a-printf-parse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-printf-parse.obj `if test -f 'printf-parse.c'; then $(CYGPATH_W) 'printf-parse.c'; else $(CYGPATH_W) '$(srcdir)/printf-parse.c'; fi` + +libgnu_a-vasnprintf.o: vasnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-vasnprintf.o -MD -MP -MF $(DEPDIR)/libgnu_a-vasnprintf.Tpo -c -o libgnu_a-vasnprintf.o `test -f 'vasnprintf.c' || echo '$(srcdir)/'`vasnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-vasnprintf.Tpo $(DEPDIR)/libgnu_a-vasnprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vasnprintf.c' object='libgnu_a-vasnprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-vasnprintf.o `test -f 'vasnprintf.c' || echo '$(srcdir)/'`vasnprintf.c + +libgnu_a-vasnprintf.obj: vasnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-vasnprintf.obj -MD -MP -MF $(DEPDIR)/libgnu_a-vasnprintf.Tpo -c -o libgnu_a-vasnprintf.obj `if test -f 'vasnprintf.c'; then $(CYGPATH_W) 'vasnprintf.c'; else $(CYGPATH_W) '$(srcdir)/vasnprintf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-vasnprintf.Tpo $(DEPDIR)/libgnu_a-vasnprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vasnprintf.c' object='libgnu_a-vasnprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-vasnprintf.obj `if test -f 'vasnprintf.c'; then $(CYGPATH_W) 'vasnprintf.c'; else $(CYGPATH_W) '$(srcdir)/vasnprintf.c'; fi` + +libgnu_a-asprintf.o: asprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-asprintf.o -MD -MP -MF $(DEPDIR)/libgnu_a-asprintf.Tpo -c -o libgnu_a-asprintf.o `test -f 'asprintf.c' || echo '$(srcdir)/'`asprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-asprintf.Tpo $(DEPDIR)/libgnu_a-asprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asprintf.c' object='libgnu_a-asprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-asprintf.o `test -f 'asprintf.c' || echo '$(srcdir)/'`asprintf.c + +libgnu_a-asprintf.obj: asprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-asprintf.obj -MD -MP -MF $(DEPDIR)/libgnu_a-asprintf.Tpo -c -o libgnu_a-asprintf.obj `if test -f 'asprintf.c'; then $(CYGPATH_W) 'asprintf.c'; else $(CYGPATH_W) '$(srcdir)/asprintf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-asprintf.Tpo $(DEPDIR)/libgnu_a-asprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asprintf.c' object='libgnu_a-asprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-asprintf.obj `if test -f 'asprintf.c'; then $(CYGPATH_W) 'asprintf.c'; else $(CYGPATH_W) '$(srcdir)/asprintf.c'; fi` + +libgnu_a-vasprintf.o: vasprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-vasprintf.o -MD -MP -MF $(DEPDIR)/libgnu_a-vasprintf.Tpo -c -o libgnu_a-vasprintf.o `test -f 'vasprintf.c' || echo '$(srcdir)/'`vasprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-vasprintf.Tpo $(DEPDIR)/libgnu_a-vasprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vasprintf.c' object='libgnu_a-vasprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-vasprintf.o `test -f 'vasprintf.c' || echo '$(srcdir)/'`vasprintf.c + +libgnu_a-vasprintf.obj: vasprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-vasprintf.obj -MD -MP -MF $(DEPDIR)/libgnu_a-vasprintf.Tpo -c -o libgnu_a-vasprintf.obj `if test -f 'vasprintf.c'; then $(CYGPATH_W) 'vasprintf.c'; else $(CYGPATH_W) '$(srcdir)/vasprintf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-vasprintf.Tpo $(DEPDIR)/libgnu_a-vasprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vasprintf.c' object='libgnu_a-vasprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-vasprintf.obj `if test -f 'vasprintf.c'; then $(CYGPATH_W) 'vasprintf.c'; else $(CYGPATH_W) '$(srcdir)/vasprintf.c'; fi` + +libgnu_a-vsnprintf.o: vsnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-vsnprintf.o -MD -MP -MF $(DEPDIR)/libgnu_a-vsnprintf.Tpo -c -o libgnu_a-vsnprintf.o `test -f 'vsnprintf.c' || echo '$(srcdir)/'`vsnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-vsnprintf.Tpo $(DEPDIR)/libgnu_a-vsnprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vsnprintf.c' object='libgnu_a-vsnprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-vsnprintf.o `test -f 'vsnprintf.c' || echo '$(srcdir)/'`vsnprintf.c + +libgnu_a-vsnprintf.obj: vsnprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -MT libgnu_a-vsnprintf.obj -MD -MP -MF $(DEPDIR)/libgnu_a-vsnprintf.Tpo -c -o libgnu_a-vsnprintf.obj `if test -f 'vsnprintf.c'; then $(CYGPATH_W) 'vsnprintf.c'; else $(CYGPATH_W) '$(srcdir)/vsnprintf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgnu_a-vsnprintf.Tpo $(DEPDIR)/libgnu_a-vsnprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vsnprintf.c' object='libgnu_a-vsnprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgnu_a_CFLAGS) $(CFLAGS) -c -o libgnu_a-vsnprintf.obj `if test -f 'vsnprintf.c'; then $(CYGPATH_W) 'vsnprintf.c'; else $(CYGPATH_W) '$(srcdir)/vsnprintf.c'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f glthread/$(DEPDIR)/$(am__dirstamp) + -rm -f glthread/$(am__dirstamp) + -rm -f malloc/$(DEPDIR)/$(am__dirstamp) + -rm -f malloc/$(am__dirstamp) + -rm -f unicase/$(DEPDIR)/$(am__dirstamp) + -rm -f unicase/$(am__dirstamp) + -rm -f unictype/$(DEPDIR)/$(am__dirstamp) + -rm -f unictype/$(am__dirstamp) + -rm -f uninorm/$(DEPDIR)/$(am__dirstamp) + -rm -f uninorm/$(am__dirstamp) + -rm -f unistr/$(DEPDIR)/$(am__dirstamp) + -rm -f unistr/$(am__dirstamp) + -rm -f uniwidth/$(DEPDIR)/$(am__dirstamp) + -rm -f uniwidth/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/alloca.Po + -rm -f ./$(DEPDIR)/libgnu_a-accept.Po + -rm -f ./$(DEPDIR)/libgnu_a-access.Po + -rm -f ./$(DEPDIR)/libgnu_a-af_alg.Po + -rm -f ./$(DEPDIR)/libgnu_a-alloca.Po + -rm -f ./$(DEPDIR)/libgnu_a-asnprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-asprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-at-func.Po + -rm -f ./$(DEPDIR)/libgnu_a-base32.Po + -rm -f ./$(DEPDIR)/libgnu_a-basename-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-basename.Po + -rm -f ./$(DEPDIR)/libgnu_a-binary-io.Po + -rm -f ./$(DEPDIR)/libgnu_a-bind.Po + -rm -f ./$(DEPDIR)/libgnu_a-bitrotate.Po + -rm -f ./$(DEPDIR)/libgnu_a-btowc.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-ctype.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-strcasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-strcasestr.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-strncasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-calloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-canonicalize-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-canonicalize.Po + -rm -f ./$(DEPDIR)/libgnu_a-chdir-long.Po + -rm -f ./$(DEPDIR)/libgnu_a-cloexec.Po + -rm -f ./$(DEPDIR)/libgnu_a-close.Po + -rm -f ./$(DEPDIR)/libgnu_a-closedir.Po + -rm -f ./$(DEPDIR)/libgnu_a-concat-filename.Po + -rm -f ./$(DEPDIR)/libgnu_a-connect.Po + -rm -f ./$(DEPDIR)/libgnu_a-dirfd.Po + -rm -f ./$(DEPDIR)/libgnu_a-dirname-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-dirname.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup-safer-flag.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup2.Po + -rm -f ./$(DEPDIR)/libgnu_a-error.Po + -rm -f ./$(DEPDIR)/libgnu_a-exitfail.Po + -rm -f ./$(DEPDIR)/libgnu_a-fatal-signal.Po + -rm -f ./$(DEPDIR)/libgnu_a-fchdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-fcntl.Po + -rm -f ./$(DEPDIR)/libgnu_a-fd-hook.Po + -rm -f ./$(DEPDIR)/libgnu_a-fd-safer-flag.Po + -rm -f ./$(DEPDIR)/libgnu_a-fd-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-fdopendir.Po + -rm -f ./$(DEPDIR)/libgnu_a-fflush.Po + -rm -f ./$(DEPDIR)/libgnu_a-file-set.Po + -rm -f ./$(DEPDIR)/libgnu_a-filenamecat-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-findprog-in.Po + -rm -f ./$(DEPDIR)/libgnu_a-float.Po + -rm -f ./$(DEPDIR)/libgnu_a-flock.Po + -rm -f ./$(DEPDIR)/libgnu_a-fnmatch.Po + -rm -f ./$(DEPDIR)/libgnu_a-fnmatch_loop.Po + -rm -f ./$(DEPDIR)/libgnu_a-fopen.Po + -rm -f ./$(DEPDIR)/libgnu_a-fpurge.Po + -rm -f ./$(DEPDIR)/libgnu_a-freading.Po + -rm -f ./$(DEPDIR)/libgnu_a-free.Po + -rm -f ./$(DEPDIR)/libgnu_a-fseek.Po + -rm -f ./$(DEPDIR)/libgnu_a-fseeko.Po + -rm -f ./$(DEPDIR)/libgnu_a-fstat.Po + -rm -f ./$(DEPDIR)/libgnu_a-fstatat.Po + -rm -f ./$(DEPDIR)/libgnu_a-ftell.Po + -rm -f ./$(DEPDIR)/libgnu_a-ftello.Po + -rm -f ./$(DEPDIR)/libgnu_a-futimens.Po + -rm -f ./$(DEPDIR)/libgnu_a-gai_strerror.Po + -rm -f ./$(DEPDIR)/libgnu_a-getaddrinfo.Po + -rm -f ./$(DEPDIR)/libgnu_a-getcwd-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-getcwd.Po + -rm -f ./$(DEPDIR)/libgnu_a-getdelim.Po + -rm -f ./$(DEPDIR)/libgnu_a-getdtablesize.Po + -rm -f ./$(DEPDIR)/libgnu_a-getgroups.Po + -rm -f ./$(DEPDIR)/libgnu_a-getline.Po + -rm -f ./$(DEPDIR)/libgnu_a-getopt.Po + -rm -f ./$(DEPDIR)/libgnu_a-getopt1.Po + -rm -f ./$(DEPDIR)/libgnu_a-getpass.Po + -rm -f ./$(DEPDIR)/libgnu_a-getpeername.Po + -rm -f ./$(DEPDIR)/libgnu_a-getprogname.Po + -rm -f ./$(DEPDIR)/libgnu_a-getrandom.Po + -rm -f ./$(DEPDIR)/libgnu_a-getsockname.Po + -rm -f ./$(DEPDIR)/libgnu_a-gettime.Po + -rm -f ./$(DEPDIR)/libgnu_a-gettimeofday.Po + -rm -f ./$(DEPDIR)/libgnu_a-group-member.Po + -rm -f ./$(DEPDIR)/libgnu_a-hard-locale.Po + -rm -f ./$(DEPDIR)/libgnu_a-hash-pjw.Po + -rm -f ./$(DEPDIR)/libgnu_a-hash-triple-simple.Po + -rm -f ./$(DEPDIR)/libgnu_a-hash.Po + -rm -f ./$(DEPDIR)/libgnu_a-ialloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-inet_ntop.Po + -rm -f ./$(DEPDIR)/libgnu_a-ioctl.Po + -rm -f ./$(DEPDIR)/libgnu_a-isblank.Po + -rm -f ./$(DEPDIR)/libgnu_a-iswblank.Po + -rm -f ./$(DEPDIR)/libgnu_a-iswdigit.Po + -rm -f ./$(DEPDIR)/libgnu_a-iswxdigit.Po + -rm -f ./$(DEPDIR)/libgnu_a-itold.Po + -rm -f ./$(DEPDIR)/libgnu_a-lc-charset-dispatch.Po + -rm -f ./$(DEPDIR)/libgnu_a-link.Po + -rm -f ./$(DEPDIR)/libgnu_a-listen.Po + -rm -f ./$(DEPDIR)/libgnu_a-localcharset.Po + -rm -f ./$(DEPDIR)/libgnu_a-localeconv.Po + -rm -f ./$(DEPDIR)/libgnu_a-lseek.Po + -rm -f ./$(DEPDIR)/libgnu_a-lstat.Po + -rm -f ./$(DEPDIR)/libgnu_a-malloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-malloca.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbchar.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbiter.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbrtowc.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbsinit.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbsrtowcs-state.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbsrtowcs.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbtowc-lock.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbtowc.Po + -rm -f ./$(DEPDIR)/libgnu_a-md2-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-md2.Po + -rm -f ./$(DEPDIR)/libgnu_a-md4-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-md4.Po + -rm -f ./$(DEPDIR)/libgnu_a-md5-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-md5.Po + -rm -f ./$(DEPDIR)/libgnu_a-memchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-mempcpy.Po + -rm -f ./$(DEPDIR)/libgnu_a-memrchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-mkdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-mkostemp.Po + -rm -f ./$(DEPDIR)/libgnu_a-mkstemp.Po + -rm -f ./$(DEPDIR)/libgnu_a-mktime.Po + -rm -f ./$(DEPDIR)/libgnu_a-msvc-inval.Po + -rm -f ./$(DEPDIR)/libgnu_a-msvc-nothrow.Po + -rm -f ./$(DEPDIR)/libgnu_a-nanosleep.Po + -rm -f ./$(DEPDIR)/libgnu_a-nl_langinfo-lock.Po + -rm -f ./$(DEPDIR)/libgnu_a-nl_langinfo.Po + -rm -f ./$(DEPDIR)/libgnu_a-open.Po + -rm -f ./$(DEPDIR)/libgnu_a-openat-die.Po + -rm -f ./$(DEPDIR)/libgnu_a-openat-proc.Po + -rm -f ./$(DEPDIR)/libgnu_a-openat.Po + -rm -f ./$(DEPDIR)/libgnu_a-opendir.Po + -rm -f ./$(DEPDIR)/libgnu_a-os2-spawn.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe2-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe2.Po + -rm -f ./$(DEPDIR)/libgnu_a-printf-args.Po + -rm -f ./$(DEPDIR)/libgnu_a-printf-parse.Po + -rm -f ./$(DEPDIR)/libgnu_a-pselect.Po + -rm -f ./$(DEPDIR)/libgnu_a-pthread_sigmask.Po + -rm -f ./$(DEPDIR)/libgnu_a-quotearg.Po + -rm -f ./$(DEPDIR)/libgnu_a-raise.Po + -rm -f ./$(DEPDIR)/libgnu_a-rawmemchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-readdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-readlink.Po + -rm -f ./$(DEPDIR)/libgnu_a-realloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-reallocarray.Po + -rm -f ./$(DEPDIR)/libgnu_a-recv.Po + -rm -f ./$(DEPDIR)/libgnu_a-regcomp.Po + -rm -f ./$(DEPDIR)/libgnu_a-regex.Po + -rm -f ./$(DEPDIR)/libgnu_a-regex_internal.Po + -rm -f ./$(DEPDIR)/libgnu_a-regexec.Po + -rm -f ./$(DEPDIR)/libgnu_a-rename.Po + -rm -f ./$(DEPDIR)/libgnu_a-rewinddir.Po + -rm -f ./$(DEPDIR)/libgnu_a-rmdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-save-cwd.Po + -rm -f ./$(DEPDIR)/libgnu_a-secure_getenv.Po + -rm -f ./$(DEPDIR)/libgnu_a-select.Po + -rm -f ./$(DEPDIR)/libgnu_a-send.Po + -rm -f ./$(DEPDIR)/libgnu_a-setlocale-lock.Po + -rm -f ./$(DEPDIR)/libgnu_a-setlocale_null.Po + -rm -f ./$(DEPDIR)/libgnu_a-setsockopt.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha1-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha1.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha256-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha256.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha512-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha512.Po + -rm -f ./$(DEPDIR)/libgnu_a-sig-handler.Po + -rm -f ./$(DEPDIR)/libgnu_a-sigaction.Po + -rm -f ./$(DEPDIR)/libgnu_a-sigprocmask.Po + -rm -f ./$(DEPDIR)/libgnu_a-snprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-socket.Po + -rm -f ./$(DEPDIR)/libgnu_a-sockets.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn-pipe.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_addchdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_addclose.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_adddup2.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_addopen.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_destroy.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_init.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_destroy.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_init.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_setflags.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_setpgroup.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_setsigmask.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawni.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnp.Po + -rm -f ./$(DEPDIR)/libgnu_a-stat-time.Po + -rm -f ./$(DEPDIR)/libgnu_a-stat-w32.Po + -rm -f ./$(DEPDIR)/libgnu_a-stat.Po + -rm -f ./$(DEPDIR)/libgnu_a-stdio-read.Po + -rm -f ./$(DEPDIR)/libgnu_a-stdio-write.Po + -rm -f ./$(DEPDIR)/libgnu_a-stpcpy.Po + -rm -f ./$(DEPDIR)/libgnu_a-strcasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-strchrnul.Po + -rm -f ./$(DEPDIR)/libgnu_a-strdup.Po + -rm -f ./$(DEPDIR)/libgnu_a-strerror-override.Po + -rm -f ./$(DEPDIR)/libgnu_a-strerror.Po + -rm -f ./$(DEPDIR)/libgnu_a-strerror_r.Po + -rm -f ./$(DEPDIR)/libgnu_a-stripslash.Po + -rm -f ./$(DEPDIR)/libgnu_a-strncasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-strndup.Po + -rm -f ./$(DEPDIR)/libgnu_a-strnlen.Po + -rm -f ./$(DEPDIR)/libgnu_a-strnlen1.Po + -rm -f ./$(DEPDIR)/libgnu_a-strpbrk.Po + -rm -f ./$(DEPDIR)/libgnu_a-strptime.Po + -rm -f ./$(DEPDIR)/libgnu_a-strtok_r.Po + -rm -f ./$(DEPDIR)/libgnu_a-strtol.Po + -rm -f ./$(DEPDIR)/libgnu_a-strtoll.Po + -rm -f ./$(DEPDIR)/libgnu_a-symlink.Po + -rm -f ./$(DEPDIR)/libgnu_a-sys_socket.Po + -rm -f ./$(DEPDIR)/libgnu_a-tempname.Po + -rm -f ./$(DEPDIR)/libgnu_a-time_r.Po + -rm -f ./$(DEPDIR)/libgnu_a-timegm.Po + -rm -f ./$(DEPDIR)/libgnu_a-timespec.Po + -rm -f ./$(DEPDIR)/libgnu_a-tmpdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-u64.Po + -rm -f ./$(DEPDIR)/libgnu_a-unistd.Po + -rm -f ./$(DEPDIR)/libgnu_a-unlink.Po + -rm -f ./$(DEPDIR)/libgnu_a-utime.Po + -rm -f ./$(DEPDIR)/libgnu_a-utimens.Po + -rm -f ./$(DEPDIR)/libgnu_a-vasnprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-vasprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-vsnprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-wait-process.Po + -rm -f ./$(DEPDIR)/libgnu_a-waitpid.Po + -rm -f ./$(DEPDIR)/libgnu_a-wcrtomb.Po + -rm -f ./$(DEPDIR)/libgnu_a-wctype-h.Po + -rm -f ./$(DEPDIR)/libgnu_a-wcwidth.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-mutex.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-once.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-recmutex.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-rwlock.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-spawn.Po + -rm -f ./$(DEPDIR)/libgnu_a-wmemchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-wmempcpy.Po + -rm -f ./$(DEPDIR)/libgnu_a-write.Po + -rm -f ./$(DEPDIR)/libgnu_a-xalloc-die.Po + -rm -f ./$(DEPDIR)/libgnu_a-xmalloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-xmemdup0.Po + -rm -f ./$(DEPDIR)/libgnu_a-xsize.Po + -rm -f ./$(DEPDIR)/libgnu_a-xstrndup.Po + -rm -f glthread/$(DEPDIR)/libgnu_a-lock.Po + -rm -f glthread/$(DEPDIR)/libgnu_a-threadlib.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-cased.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-ignorable.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-special-casing.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-tolower.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-u8-casemap.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-u8-tolower.Po + -rm -f unictype/$(DEPDIR)/libgnu_a-combiningclass.Po + -rm -f unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Po + -rm -f uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Po + -rm -f uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-cpy.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-strlen.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Po + -rm -f uniwidth/$(DEPDIR)/libgnu_a-width.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/alloca.Po + -rm -f ./$(DEPDIR)/libgnu_a-accept.Po + -rm -f ./$(DEPDIR)/libgnu_a-access.Po + -rm -f ./$(DEPDIR)/libgnu_a-af_alg.Po + -rm -f ./$(DEPDIR)/libgnu_a-alloca.Po + -rm -f ./$(DEPDIR)/libgnu_a-asnprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-asprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-at-func.Po + -rm -f ./$(DEPDIR)/libgnu_a-base32.Po + -rm -f ./$(DEPDIR)/libgnu_a-basename-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-basename.Po + -rm -f ./$(DEPDIR)/libgnu_a-binary-io.Po + -rm -f ./$(DEPDIR)/libgnu_a-bind.Po + -rm -f ./$(DEPDIR)/libgnu_a-bitrotate.Po + -rm -f ./$(DEPDIR)/libgnu_a-btowc.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-ctype.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-strcasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-strcasestr.Po + -rm -f ./$(DEPDIR)/libgnu_a-c-strncasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-calloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-canonicalize-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-canonicalize.Po + -rm -f ./$(DEPDIR)/libgnu_a-chdir-long.Po + -rm -f ./$(DEPDIR)/libgnu_a-cloexec.Po + -rm -f ./$(DEPDIR)/libgnu_a-close.Po + -rm -f ./$(DEPDIR)/libgnu_a-closedir.Po + -rm -f ./$(DEPDIR)/libgnu_a-concat-filename.Po + -rm -f ./$(DEPDIR)/libgnu_a-connect.Po + -rm -f ./$(DEPDIR)/libgnu_a-dirfd.Po + -rm -f ./$(DEPDIR)/libgnu_a-dirname-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-dirname.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup-safer-flag.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup.Po + -rm -f ./$(DEPDIR)/libgnu_a-dup2.Po + -rm -f ./$(DEPDIR)/libgnu_a-error.Po + -rm -f ./$(DEPDIR)/libgnu_a-exitfail.Po + -rm -f ./$(DEPDIR)/libgnu_a-fatal-signal.Po + -rm -f ./$(DEPDIR)/libgnu_a-fchdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-fcntl.Po + -rm -f ./$(DEPDIR)/libgnu_a-fd-hook.Po + -rm -f ./$(DEPDIR)/libgnu_a-fd-safer-flag.Po + -rm -f ./$(DEPDIR)/libgnu_a-fd-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-fdopendir.Po + -rm -f ./$(DEPDIR)/libgnu_a-fflush.Po + -rm -f ./$(DEPDIR)/libgnu_a-file-set.Po + -rm -f ./$(DEPDIR)/libgnu_a-filenamecat-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-findprog-in.Po + -rm -f ./$(DEPDIR)/libgnu_a-float.Po + -rm -f ./$(DEPDIR)/libgnu_a-flock.Po + -rm -f ./$(DEPDIR)/libgnu_a-fnmatch.Po + -rm -f ./$(DEPDIR)/libgnu_a-fnmatch_loop.Po + -rm -f ./$(DEPDIR)/libgnu_a-fopen.Po + -rm -f ./$(DEPDIR)/libgnu_a-fpurge.Po + -rm -f ./$(DEPDIR)/libgnu_a-freading.Po + -rm -f ./$(DEPDIR)/libgnu_a-free.Po + -rm -f ./$(DEPDIR)/libgnu_a-fseek.Po + -rm -f ./$(DEPDIR)/libgnu_a-fseeko.Po + -rm -f ./$(DEPDIR)/libgnu_a-fstat.Po + -rm -f ./$(DEPDIR)/libgnu_a-fstatat.Po + -rm -f ./$(DEPDIR)/libgnu_a-ftell.Po + -rm -f ./$(DEPDIR)/libgnu_a-ftello.Po + -rm -f ./$(DEPDIR)/libgnu_a-futimens.Po + -rm -f ./$(DEPDIR)/libgnu_a-gai_strerror.Po + -rm -f ./$(DEPDIR)/libgnu_a-getaddrinfo.Po + -rm -f ./$(DEPDIR)/libgnu_a-getcwd-lgpl.Po + -rm -f ./$(DEPDIR)/libgnu_a-getcwd.Po + -rm -f ./$(DEPDIR)/libgnu_a-getdelim.Po + -rm -f ./$(DEPDIR)/libgnu_a-getdtablesize.Po + -rm -f ./$(DEPDIR)/libgnu_a-getgroups.Po + -rm -f ./$(DEPDIR)/libgnu_a-getline.Po + -rm -f ./$(DEPDIR)/libgnu_a-getopt.Po + -rm -f ./$(DEPDIR)/libgnu_a-getopt1.Po + -rm -f ./$(DEPDIR)/libgnu_a-getpass.Po + -rm -f ./$(DEPDIR)/libgnu_a-getpeername.Po + -rm -f ./$(DEPDIR)/libgnu_a-getprogname.Po + -rm -f ./$(DEPDIR)/libgnu_a-getrandom.Po + -rm -f ./$(DEPDIR)/libgnu_a-getsockname.Po + -rm -f ./$(DEPDIR)/libgnu_a-gettime.Po + -rm -f ./$(DEPDIR)/libgnu_a-gettimeofday.Po + -rm -f ./$(DEPDIR)/libgnu_a-group-member.Po + -rm -f ./$(DEPDIR)/libgnu_a-hard-locale.Po + -rm -f ./$(DEPDIR)/libgnu_a-hash-pjw.Po + -rm -f ./$(DEPDIR)/libgnu_a-hash-triple-simple.Po + -rm -f ./$(DEPDIR)/libgnu_a-hash.Po + -rm -f ./$(DEPDIR)/libgnu_a-ialloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-inet_ntop.Po + -rm -f ./$(DEPDIR)/libgnu_a-ioctl.Po + -rm -f ./$(DEPDIR)/libgnu_a-isblank.Po + -rm -f ./$(DEPDIR)/libgnu_a-iswblank.Po + -rm -f ./$(DEPDIR)/libgnu_a-iswdigit.Po + -rm -f ./$(DEPDIR)/libgnu_a-iswxdigit.Po + -rm -f ./$(DEPDIR)/libgnu_a-itold.Po + -rm -f ./$(DEPDIR)/libgnu_a-lc-charset-dispatch.Po + -rm -f ./$(DEPDIR)/libgnu_a-link.Po + -rm -f ./$(DEPDIR)/libgnu_a-listen.Po + -rm -f ./$(DEPDIR)/libgnu_a-localcharset.Po + -rm -f ./$(DEPDIR)/libgnu_a-localeconv.Po + -rm -f ./$(DEPDIR)/libgnu_a-lseek.Po + -rm -f ./$(DEPDIR)/libgnu_a-lstat.Po + -rm -f ./$(DEPDIR)/libgnu_a-malloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-malloca.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbchar.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbiter.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbrtowc.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbsinit.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbsrtowcs-state.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbsrtowcs.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbtowc-lock.Po + -rm -f ./$(DEPDIR)/libgnu_a-mbtowc.Po + -rm -f ./$(DEPDIR)/libgnu_a-md2-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-md2.Po + -rm -f ./$(DEPDIR)/libgnu_a-md4-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-md4.Po + -rm -f ./$(DEPDIR)/libgnu_a-md5-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-md5.Po + -rm -f ./$(DEPDIR)/libgnu_a-memchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-mempcpy.Po + -rm -f ./$(DEPDIR)/libgnu_a-memrchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-mkdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-mkostemp.Po + -rm -f ./$(DEPDIR)/libgnu_a-mkstemp.Po + -rm -f ./$(DEPDIR)/libgnu_a-mktime.Po + -rm -f ./$(DEPDIR)/libgnu_a-msvc-inval.Po + -rm -f ./$(DEPDIR)/libgnu_a-msvc-nothrow.Po + -rm -f ./$(DEPDIR)/libgnu_a-nanosleep.Po + -rm -f ./$(DEPDIR)/libgnu_a-nl_langinfo-lock.Po + -rm -f ./$(DEPDIR)/libgnu_a-nl_langinfo.Po + -rm -f ./$(DEPDIR)/libgnu_a-open.Po + -rm -f ./$(DEPDIR)/libgnu_a-openat-die.Po + -rm -f ./$(DEPDIR)/libgnu_a-openat-proc.Po + -rm -f ./$(DEPDIR)/libgnu_a-openat.Po + -rm -f ./$(DEPDIR)/libgnu_a-opendir.Po + -rm -f ./$(DEPDIR)/libgnu_a-os2-spawn.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe2-safer.Po + -rm -f ./$(DEPDIR)/libgnu_a-pipe2.Po + -rm -f ./$(DEPDIR)/libgnu_a-printf-args.Po + -rm -f ./$(DEPDIR)/libgnu_a-printf-parse.Po + -rm -f ./$(DEPDIR)/libgnu_a-pselect.Po + -rm -f ./$(DEPDIR)/libgnu_a-pthread_sigmask.Po + -rm -f ./$(DEPDIR)/libgnu_a-quotearg.Po + -rm -f ./$(DEPDIR)/libgnu_a-raise.Po + -rm -f ./$(DEPDIR)/libgnu_a-rawmemchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-readdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-readlink.Po + -rm -f ./$(DEPDIR)/libgnu_a-realloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-reallocarray.Po + -rm -f ./$(DEPDIR)/libgnu_a-recv.Po + -rm -f ./$(DEPDIR)/libgnu_a-regcomp.Po + -rm -f ./$(DEPDIR)/libgnu_a-regex.Po + -rm -f ./$(DEPDIR)/libgnu_a-regex_internal.Po + -rm -f ./$(DEPDIR)/libgnu_a-regexec.Po + -rm -f ./$(DEPDIR)/libgnu_a-rename.Po + -rm -f ./$(DEPDIR)/libgnu_a-rewinddir.Po + -rm -f ./$(DEPDIR)/libgnu_a-rmdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-save-cwd.Po + -rm -f ./$(DEPDIR)/libgnu_a-secure_getenv.Po + -rm -f ./$(DEPDIR)/libgnu_a-select.Po + -rm -f ./$(DEPDIR)/libgnu_a-send.Po + -rm -f ./$(DEPDIR)/libgnu_a-setlocale-lock.Po + -rm -f ./$(DEPDIR)/libgnu_a-setlocale_null.Po + -rm -f ./$(DEPDIR)/libgnu_a-setsockopt.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha1-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha1.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha256-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha256.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha512-stream.Po + -rm -f ./$(DEPDIR)/libgnu_a-sha512.Po + -rm -f ./$(DEPDIR)/libgnu_a-sig-handler.Po + -rm -f ./$(DEPDIR)/libgnu_a-sigaction.Po + -rm -f ./$(DEPDIR)/libgnu_a-sigprocmask.Po + -rm -f ./$(DEPDIR)/libgnu_a-snprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-socket.Po + -rm -f ./$(DEPDIR)/libgnu_a-sockets.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn-pipe.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_addchdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_addclose.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_adddup2.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_addopen.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_destroy.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawn_faction_init.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_destroy.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_init.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_setflags.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_setpgroup.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnattr_setsigmask.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawni.Po + -rm -f ./$(DEPDIR)/libgnu_a-spawnp.Po + -rm -f ./$(DEPDIR)/libgnu_a-stat-time.Po + -rm -f ./$(DEPDIR)/libgnu_a-stat-w32.Po + -rm -f ./$(DEPDIR)/libgnu_a-stat.Po + -rm -f ./$(DEPDIR)/libgnu_a-stdio-read.Po + -rm -f ./$(DEPDIR)/libgnu_a-stdio-write.Po + -rm -f ./$(DEPDIR)/libgnu_a-stpcpy.Po + -rm -f ./$(DEPDIR)/libgnu_a-strcasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-strchrnul.Po + -rm -f ./$(DEPDIR)/libgnu_a-strdup.Po + -rm -f ./$(DEPDIR)/libgnu_a-strerror-override.Po + -rm -f ./$(DEPDIR)/libgnu_a-strerror.Po + -rm -f ./$(DEPDIR)/libgnu_a-strerror_r.Po + -rm -f ./$(DEPDIR)/libgnu_a-stripslash.Po + -rm -f ./$(DEPDIR)/libgnu_a-strncasecmp.Po + -rm -f ./$(DEPDIR)/libgnu_a-strndup.Po + -rm -f ./$(DEPDIR)/libgnu_a-strnlen.Po + -rm -f ./$(DEPDIR)/libgnu_a-strnlen1.Po + -rm -f ./$(DEPDIR)/libgnu_a-strpbrk.Po + -rm -f ./$(DEPDIR)/libgnu_a-strptime.Po + -rm -f ./$(DEPDIR)/libgnu_a-strtok_r.Po + -rm -f ./$(DEPDIR)/libgnu_a-strtol.Po + -rm -f ./$(DEPDIR)/libgnu_a-strtoll.Po + -rm -f ./$(DEPDIR)/libgnu_a-symlink.Po + -rm -f ./$(DEPDIR)/libgnu_a-sys_socket.Po + -rm -f ./$(DEPDIR)/libgnu_a-tempname.Po + -rm -f ./$(DEPDIR)/libgnu_a-time_r.Po + -rm -f ./$(DEPDIR)/libgnu_a-timegm.Po + -rm -f ./$(DEPDIR)/libgnu_a-timespec.Po + -rm -f ./$(DEPDIR)/libgnu_a-tmpdir.Po + -rm -f ./$(DEPDIR)/libgnu_a-u64.Po + -rm -f ./$(DEPDIR)/libgnu_a-unistd.Po + -rm -f ./$(DEPDIR)/libgnu_a-unlink.Po + -rm -f ./$(DEPDIR)/libgnu_a-utime.Po + -rm -f ./$(DEPDIR)/libgnu_a-utimens.Po + -rm -f ./$(DEPDIR)/libgnu_a-vasnprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-vasprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-vsnprintf.Po + -rm -f ./$(DEPDIR)/libgnu_a-wait-process.Po + -rm -f ./$(DEPDIR)/libgnu_a-waitpid.Po + -rm -f ./$(DEPDIR)/libgnu_a-wcrtomb.Po + -rm -f ./$(DEPDIR)/libgnu_a-wctype-h.Po + -rm -f ./$(DEPDIR)/libgnu_a-wcwidth.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-mutex.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-once.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-recmutex.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-rwlock.Po + -rm -f ./$(DEPDIR)/libgnu_a-windows-spawn.Po + -rm -f ./$(DEPDIR)/libgnu_a-wmemchr.Po + -rm -f ./$(DEPDIR)/libgnu_a-wmempcpy.Po + -rm -f ./$(DEPDIR)/libgnu_a-write.Po + -rm -f ./$(DEPDIR)/libgnu_a-xalloc-die.Po + -rm -f ./$(DEPDIR)/libgnu_a-xmalloc.Po + -rm -f ./$(DEPDIR)/libgnu_a-xmemdup0.Po + -rm -f ./$(DEPDIR)/libgnu_a-xsize.Po + -rm -f ./$(DEPDIR)/libgnu_a-xstrndup.Po + -rm -f glthread/$(DEPDIR)/libgnu_a-lock.Po + -rm -f glthread/$(DEPDIR)/libgnu_a-threadlib.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray-skeleton.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_at_failure.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_emplace_enlarge.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_finalize.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_resize.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-dynarray_resize_clear.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_dupfree.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_grow_preserve.Po + -rm -f malloc/$(DEPDIR)/libgnu_a-scratch_buffer_set_array_size.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-cased.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-empty-prefix-context.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-empty-suffix-context.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-ignorable.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-special-casing.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-tolower.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-u8-casemap.Po + -rm -f unicase/$(DEPDIR)/libgnu_a-u8-tolower.Po + -rm -f unictype/$(DEPDIR)/libgnu_a-combiningclass.Po + -rm -f unictype/$(DEPDIR)/libgnu_a-pr_soft_dotted.Po + -rm -f uninorm/$(DEPDIR)/libgnu_a-decompose-internal.Po + -rm -f uninorm/$(DEPDIR)/libgnu_a-u8-normalize.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-cpy.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe-aux.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-mbtouc-unsafe.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-strlen.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-uctomb-aux.Po + -rm -f unistr/$(DEPDIR)/libgnu_a-u8-uctomb.Po + -rm -f uniwidth/$(DEPDIR)/libgnu_a-width.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-local + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check install install-am install-exec install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-local distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic maintainer-clean-local mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-local pdf \ + pdf-am ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_ALLOCA_H_TRUE@alloca.h: alloca.in.h $(top_builddir)/config.status +@GL_GENERATE_ALLOCA_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_ALLOCA_H_TRUE@ -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' \ +@GL_GENERATE_ALLOCA_H_TRUE@ $(srcdir)/alloca.in.h > $@-t +@GL_GENERATE_ALLOCA_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_ALLOCA_H_FALSE@alloca.h: $(top_builddir)/config.status +@GL_GENERATE_ALLOCA_H_FALSE@ rm -f $@ + +# 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_GEN)$(MKDIR_P) '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''@/$(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' \ + -e 's|@''REPLACE_INET_PTON''@|$(REPLACE_INET_PTON)|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)/arpa_inet.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one. +@GL_GENERATE_BYTESWAP_H_TRUE@byteswap.h: byteswap.in.h $(top_builddir)/config.status +@GL_GENERATE_BYTESWAP_H_TRUE@ $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/byteswap.in.h +@GL_GENERATE_BYTESWAP_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_BYTESWAP_H_FALSE@byteswap.h: $(top_builddir)/config.status +@GL_GENERATE_BYTESWAP_H_FALSE@ rm -f $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +ctype.h: ctype.in.h $(top_builddir)/config.status $(CXXDEFS_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_CTYPE_H''@|$(NEXT_CTYPE_H)|g' \ + -e 's/@''GNULIB_ISBLANK''@/$(GL_GNULIB_ISBLANK)/g' \ + -e 's/@''HAVE_ISBLANK''@/$(HAVE_ISBLANK)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/ctype.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +dirent.h: dirent.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|@''HAVE_DIRENT_H''@|$(HAVE_DIRENT_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_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \ + -e 's/@''GNULIB_OPENDIR''@/$(GL_GNULIB_OPENDIR)/g' \ + -e 's/@''GNULIB_READDIR''@/$(GL_GNULIB_READDIR)/g' \ + -e 's/@''GNULIB_REWINDDIR''@/$(GL_GNULIB_REWINDDIR)/g' \ + -e 's/@''GNULIB_CLOSEDIR''@/$(GL_GNULIB_CLOSEDIR)/g' \ + -e 's/@''GNULIB_DIRFD''@/$(GL_GNULIB_DIRFD)/g' \ + -e 's/@''GNULIB_FDOPENDIR''@/$(GL_GNULIB_FDOPENDIR)/g' \ + -e 's/@''GNULIB_SCANDIR''@/$(GL_GNULIB_SCANDIR)/g' \ + -e 's/@''GNULIB_ALPHASORT''@/$(GL_GNULIB_ALPHASORT)/g' \ + -e 's/@''HAVE_OPENDIR''@/$(HAVE_OPENDIR)/g' \ + -e 's/@''HAVE_READDIR''@/$(HAVE_READDIR)/g' \ + -e 's/@''HAVE_REWINDDIR''@/$(HAVE_REWINDDIR)/g' \ + -e 's/@''HAVE_CLOSEDIR''@/$(HAVE_CLOSEDIR)/g' \ + -e 's|@''HAVE_DECL_DIRFD''@|$(HAVE_DECL_DIRFD)|g' \ + -e 's|@''HAVE_DECL_FDOPENDIR''@|$(HAVE_DECL_FDOPENDIR)|g' \ + -e 's|@''HAVE_FDOPENDIR''@|$(HAVE_FDOPENDIR)|g' \ + -e 's|@''HAVE_SCANDIR''@|$(HAVE_SCANDIR)|g' \ + -e 's|@''HAVE_ALPHASORT''@|$(HAVE_ALPHASORT)|g' \ + -e 's|@''REPLACE_OPENDIR''@|$(REPLACE_OPENDIR)|g' \ + -e 's|@''REPLACE_CLOSEDIR''@|$(REPLACE_CLOSEDIR)|g' \ + -e 's|@''REPLACE_DIRFD''@|$(REPLACE_DIRFD)|g' \ + -e 's|@''REPLACE_FDOPENDIR''@|$(REPLACE_FDOPENDIR)|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)/dirent.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +malloc/dynarray.gl.h: malloc/dynarray.h + $(AM_V_GEN)$(MKDIR_P) 'malloc' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e '/libc_hidden_proto/d' \ + $(srcdir)/malloc/dynarray.h > $@-t + $(AM_V_at)mv $@-t $@ + +malloc/dynarray-skeleton.gl.h: malloc/dynarray-skeleton.c + $(AM_V_GEN)$(MKDIR_P) '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 $@ + +# We need the following in order to create when the system +# doesn't have one that is POSIX compliant. +@GL_GENERATE_ERRNO_H_TRUE@errno.h: errno.in.h $(top_builddir)/config.status +@GL_GENERATE_ERRNO_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \ +@GL_GENERATE_ERRNO_H_TRUE@ $(srcdir)/errno.in.h > $@-t +@GL_GENERATE_ERRNO_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_ERRNO_H_FALSE@errno.h: $(top_builddir)/config.status +@GL_GENERATE_ERRNO_H_FALSE@ rm -f $@ + +# 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 $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_FLOAT_H_TRUE@float.h: float.in.h $(top_builddir)/config.status +@GL_GENERATE_FLOAT_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_FLOAT_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_FLOAT_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_FLOAT_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_FLOAT_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_FLOAT_H_TRUE@ -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ +@GL_GENERATE_FLOAT_H_TRUE@ -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \ +@GL_GENERATE_FLOAT_H_TRUE@ $(srcdir)/float.in.h > $@-t +@GL_GENERATE_FLOAT_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_FLOAT_H_FALSE@float.h: $(top_builddir)/config.status +@GL_GENERATE_FLOAT_H_FALSE@ rm -f $@ + +# We need the following in order to create . +@GL_GENERATE_FNMATCH_H_TRUE@fnmatch.h: fnmatch.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) +@GL_GENERATE_FNMATCH_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''HAVE_FNMATCH_H''@|$(HAVE_FNMATCH_H)|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''NEXT_FNMATCH_H''@|$(NEXT_FNMATCH_H)|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's/@''GNULIB_FNMATCH''@/$(GL_GNULIB_FNMATCH)/g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''HAVE_FNMATCH''@|$(HAVE_FNMATCH)|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e 's|@''REPLACE_FNMATCH''@|$(REPLACE_FNMATCH)|g' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +@GL_GENERATE_FNMATCH_H_TRUE@ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ +@GL_GENERATE_FNMATCH_H_TRUE@ $(srcdir)/fnmatch.in.h > $@-t +@GL_GENERATE_FNMATCH_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_FNMATCH_H_FALSE@fnmatch.h: $(top_builddir)/config.status +@GL_GENERATE_FNMATCH_H_FALSE@ rm -f $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_GETOPT_H_TRUE@getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) +@GL_GENERATE_GETOPT_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_GETOPT_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_GETOPT_H_TRUE@ -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ +@GL_GENERATE_GETOPT_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_GETOPT_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_GETOPT_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_GETOPT_H_TRUE@ -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ +@GL_GENERATE_GETOPT_H_TRUE@ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +@GL_GENERATE_GETOPT_H_TRUE@ $(srcdir)/getopt.in.h > $@-t +@GL_GENERATE_GETOPT_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_GETOPT_H_FALSE@getopt.h: $(top_builddir)/config.status +@GL_GENERATE_GETOPT_H_FALSE@ rm -f $@ + +@GL_GENERATE_GETOPT_CDEFS_H_TRUE@getopt-cdefs.h: getopt-cdefs.in.h $(top_builddir)/config.status +@GL_GENERATE_GETOPT_CDEFS_H_TRUE@ $(AM_V_GEN)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_GETOPT_CDEFS_H_TRUE@ -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \ +@GL_GENERATE_GETOPT_CDEFS_H_TRUE@ $(srcdir)/getopt-cdefs.in.h > $@-t +@GL_GENERATE_GETOPT_CDEFS_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_GETOPT_CDEFS_H_FALSE@getopt-cdefs.h: $(top_builddir)/config.status +@GL_GENERATE_GETOPT_CDEFS_H_FALSE@ rm -f $@ +distclean-local: clean-GNUmakefile +clean-GNUmakefile: + test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_ICONV_H_TRUE@iconv.h: iconv.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) +@GL_GENERATE_ICONV_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''NEXT_ICONV_H''@|$(NEXT_ICONV_H)|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's/@''GNULIB_ICONV''@/$(GL_GNULIB_ICONV)/g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''ICONV_CONST''@|$(ICONV_CONST)|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''REPLACE_ICONV''@|$(REPLACE_ICONV)|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''REPLACE_ICONV_OPEN''@|$(REPLACE_ICONV_OPEN)|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e 's|@''REPLACE_ICONV_UTF''@|$(REPLACE_ICONV_UTF)|g' \ +@GL_GENERATE_ICONV_H_TRUE@ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ +@GL_GENERATE_ICONV_H_TRUE@ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +@GL_GENERATE_ICONV_H_TRUE@ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ +@GL_GENERATE_ICONV_H_TRUE@ $(srcdir)/iconv.in.h > $@-t +@GL_GENERATE_ICONV_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_ICONV_H_FALSE@iconv.h: $(top_builddir)/config.status +@GL_GENERATE_ICONV_H_FALSE@ rm -f $@ + +# 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 $@ + +# 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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one that is compatible with GNU. +@GL_GENERATE_LIMITS_H_TRUE@limits.h: limits.in.h $(top_builddir)/config.status +@GL_GENERATE_LIMITS_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_LIMITS_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_LIMITS_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_LIMITS_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_LIMITS_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_LIMITS_H_TRUE@ -e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \ +@GL_GENERATE_LIMITS_H_TRUE@ $(srcdir)/limits.in.h > $@-t +@GL_GENERATE_LIMITS_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_LIMITS_H_FALSE@limits.h: $(top_builddir)/config.status +@GL_GENERATE_LIMITS_H_FALSE@ rm -f $@ + +# 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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ + +# 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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one. +@GL_GENERATE_NETINET_IN_H_TRUE@netinet/in.h: netinet_in.in.h $(top_builddir)/config.status +@GL_GENERATE_NETINET_IN_H_TRUE@ $(AM_V_GEN)$(MKDIR_P) 'netinet' +@GL_GENERATE_NETINET_IN_H_TRUE@ $(AM_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_NETINET_IN_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_NETINET_IN_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_NETINET_IN_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_NETINET_IN_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_NETINET_IN_H_TRUE@ -e 's|@''NEXT_NETINET_IN_H''@|$(NEXT_NETINET_IN_H)|g' \ +@GL_GENERATE_NETINET_IN_H_TRUE@ -e 's|@''HAVE_NETINET_IN_H''@|$(HAVE_NETINET_IN_H)|g' \ +@GL_GENERATE_NETINET_IN_H_TRUE@ $(srcdir)/netinet_in.in.h > $@-t +@GL_GENERATE_NETINET_IN_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_NETINET_IN_H_FALSE@netinet/in.h: $(top_builddir)/config.status +@GL_GENERATE_NETINET_IN_H_FALSE@ rm -f $@ + +# We need the following in order to create a replacement for when +# the system doesn't have one. +sched.h: sched.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_SCHED_H''@|$(HAVE_SCHED_H)|g' \ + -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_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_SCHED_H''@|$(NEXT_SCHED_H)|g' \ + -e 's|@''HAVE_STRUCT_SCHED_PARAM''@|$(HAVE_STRUCT_SCHED_PARAM)|g' \ + -e 's/@''GNULIB_SCHED_YIELD''@/$(GL_GNULIB_SCHED_YIELD)/g' \ + -e 's|@''HAVE_SCHED_YIELD''@|$(HAVE_SCHED_YIELD)|g' \ + -e 's|@''REPLACE_SCHED_YIELD''@|$(REPLACE_SCHED_YIELD)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sched.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +malloc/scratch_buffer.gl.h: malloc/scratch_buffer.h + $(AM_V_GEN)$(MKDIR_P) 'malloc' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|__always_inline|inline _GL_ATTRIBUTE_ALWAYS_INLINE|g' \ + -e 's|__glibc_likely|_GL_LIKELY|g' \ + -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \ + -e '/libc_hidden_proto/d' \ + $(srcdir)/malloc/scratch_buffer.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have a complete one. +signal.h: signal.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_SIGNAL_H''@|$(NEXT_SIGNAL_H)|g' \ + -e 's/@''GNULIB_PTHREAD_SIGMASK''@/$(GL_GNULIB_PTHREAD_SIGMASK)/g' \ + -e 's/@''GNULIB_RAISE''@/$(GL_GNULIB_RAISE)/g' \ + -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GL_GNULIB_SIGNAL_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_SIGPROCMASK''@/$(GL_GNULIB_SIGPROCMASK)/g' \ + -e 's/@''GNULIB_SIGACTION''@/$(GL_GNULIB_SIGACTION)/g' \ + -e 's|@''HAVE_POSIX_SIGNALBLOCKING''@|$(HAVE_POSIX_SIGNALBLOCKING)|g' \ + -e 's|@''HAVE_PTHREAD_SIGMASK''@|$(HAVE_PTHREAD_SIGMASK)|g' \ + -e 's|@''HAVE_RAISE''@|$(HAVE_RAISE)|g' \ + -e 's|@''HAVE_SIGSET_T''@|$(HAVE_SIGSET_T)|g' \ + -e 's|@''HAVE_SIGINFO_T''@|$(HAVE_SIGINFO_T)|g' \ + -e 's|@''HAVE_SIGACTION''@|$(HAVE_SIGACTION)|g' \ + -e 's|@''HAVE_STRUCT_SIGACTION_SA_SIGACTION''@|$(HAVE_STRUCT_SIGACTION_SA_SIGACTION)|g' \ + -e 's|@''HAVE_TYPE_VOLATILE_SIG_ATOMIC_T''@|$(HAVE_TYPE_VOLATILE_SIG_ATOMIC_T)|g' \ + -e 's|@''HAVE_SIGHANDLER_T''@|$(HAVE_SIGHANDLER_T)|g' \ + -e 's|@''REPLACE_PTHREAD_SIGMASK''@|$(REPLACE_PTHREAD_SIGMASK)|g' \ + -e 's|@''REPLACE_RAISE''@|$(REPLACE_RAISE)|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)/signal.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create a replacement for when +# the system doesn't have one. +spawn.h: spawn.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|@''HAVE_SPAWN_H''@|$(HAVE_SPAWN_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_SPAWN_H''@|$(NEXT_SPAWN_H)|g' \ + -e 's/@''GNULIB_POSIX_SPAWN''@/$(GL_GNULIB_POSIX_SPAWN)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNP''@/$(GL_GNULIB_POSIX_SPAWNP)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_INIT''@/$(GL_GNULIB_POSIX_SPAWNATTR_INIT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETFLAGS''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETFLAGS''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETPGROUP''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETPGROUP''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSIGMASK''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSIGMASK''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_DESTROY''@/$(GL_GNULIB_POSIX_SPAWNATTR_DESTROY)/g' \ + -e 's|@''HAVE_POSIX_SPAWN''@|$(HAVE_POSIX_SPAWN)|g' \ + -e 's|@''HAVE_POSIX_SPAWNATTR_T''@|$(HAVE_POSIX_SPAWNATTR_T)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_T''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_T)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN''@|$(REPLACE_POSIX_SPAWN)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)|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)/spawn.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one that works. +@GL_GENERATE_STDALIGN_H_TRUE@stdalign.h: stdalign.in.h $(top_builddir)/config.status +@GL_GENERATE_STDALIGN_H_TRUE@ $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/stdalign.in.h +@GL_GENERATE_STDALIGN_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_STDALIGN_H_FALSE@stdalign.h: $(top_builddir)/config.status +@GL_GENERATE_STDALIGN_H_FALSE@ rm -f $@ + +# We need the following in order to create when the system +# doesn't have one that works. +@GL_GENERATE_STDBOOL_H_TRUE@stdbool.h: stdbool.in.h $(top_builddir)/config.status +@GL_GENERATE_STDBOOL_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_STDBOOL_H_TRUE@ -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' \ +@GL_GENERATE_STDBOOL_H_TRUE@ $(srcdir)/stdbool.in.h > $@-t +@GL_GENERATE_STDBOOL_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_STDBOOL_H_FALSE@stdbool.h: $(top_builddir)/config.status +@GL_GENERATE_STDBOOL_H_FALSE@ rm -f $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_STDDEF_H_TRUE@stddef.h: stddef.in.h $(top_builddir)/config.status +@GL_GENERATE_STDDEF_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ +@GL_GENERATE_STDDEF_H_TRUE@ $(srcdir)/stddef.in.h > $@-t +@GL_GENERATE_STDDEF_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_STDDEF_H_FALSE@stddef.h: $(top_builddir)/config.status +@GL_GENERATE_STDDEF_H_FALSE@ rm -f $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +@GL_GENERATE_STDINT_H_TRUE@stdint.h: stdint.in.h $(top_builddir)/config.status +@GL_GENERATE_STDINT_H_TRUE@ $(gl_V_at)$(SED_HEADER_STDOUT) \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''GUARD_PREFIX''@|GL|g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_C99_STDINT_H''@/$(HAVE_C99_STDINT_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \ +@GL_GENERATE_STDINT_H_TRUE@ $(srcdir)/stdint.in.h > $@-t +@GL_GENERATE_STDINT_H_TRUE@ $(AM_V_at)mv $@-t $@ +@GL_GENERATE_STDINT_H_FALSE@stdint.h: $(top_builddir)/config.status +@GL_GENERATE_STDINT_H_FALSE@ rm -f $@ + +# 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) + $(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''@/$(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_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' \ + -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ + -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ + -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ + -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ + -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \ + -e 's|@''HAVE_FSEEKO''@|$(HAVE_FSEEKO)|g' \ + -e 's|@''HAVE_FTELLO''@|$(HAVE_FTELLO)|g' \ + -e 's|@''HAVE_PCLOSE''@|$(HAVE_PCLOSE)|g' \ + -e 's|@''HAVE_POPEN''@|$(HAVE_POPEN)|g' \ + -e 's|@''HAVE_RENAMEAT''@|$(HAVE_RENAMEAT)|g' \ + -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ + -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ + -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ + -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ + -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' \ + -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ + -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ + -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ + -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ + -e 's|@''REPLACE_GETDELIM''@|$(REPLACE_GETDELIM)|g' \ + -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ + -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \ + -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \ + -e 's|@''REPLACE_POPEN''@|$(REPLACE_POPEN)|g' \ + -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ + -e 's|@''REPLACE_REMOVE''@|$(REPLACE_REMOVE)|g' \ + -e 's|@''REPLACE_RENAME''@|$(REPLACE_RENAME)|g' \ + -e 's|@''REPLACE_RENAMEAT''@|$(REPLACE_RENAMEAT)|g' \ + -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ + -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ + -e 's|@''REPLACE_STDIO_READ_FUNCS''@|$(REPLACE_STDIO_READ_FUNCS)|g' \ + -e 's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \ + -e 's|@''REPLACE_TMPFILE''@|$(REPLACE_TMPFILE)|g' \ + -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ + -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ + -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ + -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ + -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ + -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ + -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 + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# 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) + $(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''@/$(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_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_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_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 + $(AM_V_at)mv $@-t $@ + +# 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) + $(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_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_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_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ + -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ + -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \ + -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ + -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ + -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ + -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ + -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ + -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ + -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ + -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ + -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_FFSLL''@|$(REPLACE_FFSLL)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|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_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ + -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ + -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|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)' \ + > $@-t + $(AM_V_at)mv $@-t $@ + +# 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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# has one that is incomplete. +sys/file.h: sys_file.in.h $(top_builddir)/config.status $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) 'sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's/@''HAVE_SYS_FILE_H''@/$(HAVE_SYS_FILE_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_SYS_FILE_H''@|$(NEXT_SYS_FILE_H)|g' \ + -e 's/@''HAVE_FLOCK''@/$(HAVE_FLOCK)/g' \ + -e 's/@''GNULIB_FLOCK''@/$(GL_GNULIB_FLOCK)/g' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_file.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# does not have a complete one. +sys/ioctl.h: sys_ioctl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) 'sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_SYS_IOCTL_H''@|$(HAVE_SYS_IOCTL_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_SYS_IOCTL_H''@|$(NEXT_SYS_IOCTL_H)|g' \ + -e 's/@''GNULIB_IOCTL''@/$(GL_GNULIB_IOCTL)/g' \ + -e 's|@''SYS_IOCTL_H_HAVE_WINSOCK2_H''@|$(SYS_IOCTL_H_HAVE_WINSOCK2_H)|g' \ + -e 's|@''SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ + -e 's|@''REPLACE_IOCTL''@|$(REPLACE_IOCTL)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_ioctl.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one. +sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) '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_RANDOM_H''@|$(NEXT_SYS_RANDOM_H)|g' \ + -e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \ + -e 's/@''GNULIB_GETRANDOM''@/$(GL_GNULIB_GETRANDOM)/g' \ + -e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \ + -e 's/@''REPLACE_GETRANDOM''@/$(REPLACE_GETRANDOM)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_random.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) '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_SELECT_H''@|$(NEXT_SYS_SELECT_H)|g' \ + -e 's|@''HAVE_SYS_SELECT_H''@|$(HAVE_SYS_SELECT_H)|g' \ + -e 's/@''GNULIB_PSELECT''@/$(GL_GNULIB_PSELECT)/g' \ + -e 's/@''GNULIB_SELECT''@/$(GL_GNULIB_SELECT)/g' \ + -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ + -e 's|@''HAVE_PSELECT''@|$(HAVE_PSELECT)|g' \ + -e 's|@''REPLACE_PSELECT''@|$(REPLACE_PSELECT)|g' \ + -e 's|@''REPLACE_SELECT''@|$(REPLACE_SELECT)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_select.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# 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_GEN)$(MKDIR_P) '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''@/$(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' \ + -e 's|@''HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY''@|$(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)|g' \ + -e 's|@''HAVE_SA_FAMILY_T''@|$(HAVE_SA_FAMILY_T)|g' \ + -e 's|@''HAVE_ACCEPT4''@|$(HAVE_ACCEPT4)|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_socket.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# 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) '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_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_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 $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +sys/time.h: sys_time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) 'sys' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's/@''HAVE_SYS_TIME_H''@/$(HAVE_SYS_TIME_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_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|g' \ + -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GL_GNULIB_GETTIMEOFDAY)/g' \ + -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ + -e 's/@''HAVE_GETTIMEOFDAY''@/$(HAVE_GETTIMEOFDAY)/g' \ + -e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \ + -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \ + -e 's/@''REPLACE_STRUCT_TIMEVAL''@/$(REPLACE_STRUCT_TIMEVAL)/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_time.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# 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_GEN)$(MKDIR_P) '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' \ + -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \ + $(srcdir)/sys_types.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# 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_GEN)$(MKDIR_P) '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 + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# has one that is incomplete. +sys/wait.h: sys_wait.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)$(MKDIR_P) '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_WAIT_H''@|$(NEXT_SYS_WAIT_H)|g' \ + -e 's/@''GNULIB_WAITPID''@/$(GL_GNULIB_WAITPID)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_wait.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# 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) + $(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_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 + $(AM_V_at)mv $@-t $@ + +unicase.h: unicase.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unicase.in.h + $(AM_V_at)mv $@-t $@ + +$(srcdir)/unicase/special-casing-table.h: $(srcdir)/unicase/special-casing-table.gperf + $(V_GPERF)$(GPERF) -m 10 $(srcdir)/unicase/special-casing-table.gperf > $(srcdir)/unicase/special-casing-table.h-t && \ + mv $(srcdir)/unicase/special-casing-table.h-t $(srcdir)/unicase/special-casing-table.h + +# Generate special-casing.h with a declaration that depends on the gperf version. +unicase/special-casing.h: unicase/special-casing.in.h unicase/special-casing-table.h + $(AM_V_GEN)$(MKDIR_P) 'unicase' + $(AM_V_at)declaration=`grep '^gl_unicase_special_lookup' $(srcdir)/unicase/special-casing-table.h | sed -e 's/register //g'` && \ + $(SED_HEADER_STDOUT) \ + -e "/gl_unicase_special_lookup/s/gl_unicase_special_lookup.*/$${declaration};/" \ + $(srcdir)/unicase/special-casing.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +unictype.h: unictype.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unictype.in.h + $(AM_V_at)mv $@-t $@ + +uninorm.h: uninorm.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/uninorm.in.h + $(AM_V_at)mv $@-t $@ + +# 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) + $(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_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_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' \ + -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \ + -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ + -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ + -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ + -e 's|@''HAVE_GETENTROPY''@|$(HAVE_GETENTROPY)|g' \ + -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ + -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ + -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ + -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' \ + -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \ + -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \ + -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \ + -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \ + -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \ + -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ + -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \ + -e 's|@''HAVE_SETHOSTNAME''@|$(HAVE_SETHOSTNAME)|g' \ + -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ + -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \ + -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \ + -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_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' \ + -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \ + -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \ + -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 + $(AM_V_at)mv $@-t $@ + +unistr.h: unistr.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unistr.in.h + $(AM_V_at)mv $@-t $@ + +unitypes.h: unitypes.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unitypes.in.h + $(AM_V_at)mv $@-t $@ + +uniwidth.h: uniwidth.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/uniwidth.in.h + $(AM_V_at)mv $@-t $@ + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +utime.h: utime.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/@''HAVE_UTIME_H''@/$(HAVE_UTIME_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_UTIME_H''@|$(NEXT_UTIME_H)|g' \ + -e 's/@''GNULIB_UTIME''@/$(GL_GNULIB_UTIME)/g' \ + -e 's/@''GNULIB_MDA_UTIME''@/$(GL_GNULIB_MDA_UTIME)/g' \ + -e 's|@''HAVE_UTIME''@|$(HAVE_UTIME)|g' \ + -e 's|@''REPLACE_UTIME''@|$(REPLACE_UTIME)|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)/utime.in.h > $@-t + $(AM_V_at)mv $@-t $@ + +# 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) + $(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/@''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' \ + -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ + -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ + -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \ + -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \ + -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \ + -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ + -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ + -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ + -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \ + -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' \ + -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \ + -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \ + -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \ + -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \ + -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \ + -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \ + -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \ + -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \ + -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \ + -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \ + -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \ + -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \ + -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \ + -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \ + -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \ + -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \ + -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \ + -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \ + -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' \ + -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \ + -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ + -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ + -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ + -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 + $(AM_V_at)mv $@-t $@ + +# 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) + $(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/@''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 + $(AM_V_at)mv $@-t $@ + +mostlyclean-local: mostlyclean-generic + @for dir in '' $(MOSTLYCLEANDIRS); do \ + if test -n "$$dir" && test -d $$dir; then \ + echo "rmdir $$dir"; rmdir $$dir; \ + fi; \ + done; \ + : +distclean-local: distclean-gnulib-libobjs +distclean-gnulib-libobjs: + -rm -f @gl_LIBOBJDEPS@ +maintainer-clean-local: distclean-gnulib-libobjs + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h new file mode 100644 index 0000000..e914627 --- /dev/null +++ b/lib/_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/lib/accept.c b/lib/accept.c new file mode 100644 index 0000000..5c4d1f3 --- /dev/null +++ b/lib/accept.c @@ -0,0 +1,52 @@ +/* accept.c --- wrappers for Windows accept function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef accept + +int +rpl_accept (int fd, struct sockaddr *addr, socklen_t *addrlen) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + SOCKET fh = accept (sock, addr, addrlen); + if (fh == INVALID_SOCKET) + { + set_winsock_errno (); + return -1; + } + else + return SOCKET_TO_FD (fh); + } +} diff --git a/lib/access.c b/lib/access.c new file mode 100644 index 0000000..e39c158 --- /dev/null +++ b/lib/access.c @@ -0,0 +1,31 @@ +/* Test the access rights of a file. + 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +int +access (const char *file, int mode) +{ + if ((mode & X_OK) != 0) + mode = (mode & ~X_OK) | R_OK; + return _access (file, mode); +} diff --git a/lib/af_alg.c b/lib/af_alg.c new file mode 100644 index 0000000..084bff6 --- /dev/null +++ b/lib/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/lib/af_alg.h b/lib/af_alg.h new file mode 100644 index 0000000..ddd6568 --- /dev/null +++ b/lib/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/lib/alloca.c b/lib/alloca.c new file mode 100644 index 0000000..4880283 --- /dev/null +++ b/lib/alloca.c @@ -0,0 +1,202 @@ +/* alloca.c -- allocate automatically reclaimed memory + This file is in the public domain. */ + +/* (Mostly) portable implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#include + +#include + +#include +#include + +#ifdef emacs +# include "lisp.h" +# include "blockinput.h" +# ifdef EMACS_FREE +# undef free +# define free EMACS_FREE +# endif +#else +# define memory_full() abort () +#endif + +/* If compiling with GCC or clang, this file is not needed. */ +#if !(defined __GNUC__ || defined __clang__) + +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +# ifndef alloca + +# ifdef emacs +# ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +# ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +/* Using #error here is not wise since this file should work for + old and obscure compilers. */ +# endif /* STACK_DIRECTION undefined */ +# endif /* static */ +# endif /* emacs */ + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +# ifndef STACK_DIRECTION +# define STACK_DIRECTION 0 /* Direction unknown. */ +# endif + +# if STACK_DIRECTION != 0 + +# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +# else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +# define STACK_DIR stack_dir + +static int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +# endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +# ifndef ALIGN_SIZE +# define ALIGN_SIZE sizeof(double) +# endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +void * +alloca (size_t size) +{ + auto char probe; /* Probes stack depth: */ + register char *depth = &probe; + +# if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + STACK_DIR = find_stack_direction (NULL, (size & 1) + 20); +# endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + +# ifdef emacs + BLOCK_INPUT; +# endif + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free (hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + +# ifdef emacs + UNBLOCK_INPUT; +# endif + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + /* Address of header. */ + register header *new; + + size_t combined_size = sizeof (header) + size; + if (combined_size < sizeof (header)) + memory_full (); + + new = malloc (combined_size); + + if (! new) + memory_full (); + + new->h.next = last_alloca_header; + new->h.deep = depth; + + last_alloca_header = new; + + /* User storage begins just after header. */ + + return (void *) (new + 1); + } +} + +# endif /* no alloca */ +#endif /* not GCC || clang */ diff --git a/lib/alloca.in.h b/lib/alloca.in.h new file mode 100644 index 0000000..e2b1461 --- /dev/null +++ b/lib/alloca.in.h @@ -0,0 +1,72 @@ +/* Memory allocation on the stack. + + Copyright (C) 1995, 1999, 2001-2004, 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 . */ + +/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H + means there is a real alloca function. */ +#ifndef _GL_ALLOCA_H +#define _GL_ALLOCA_H + +/* alloca (N) returns a pointer to N bytes of memory + allocated on the stack, which will last until the function returns. + Use of alloca should be avoided: + - inside arguments of function calls - undefined behaviour, + - in inline functions - the allocation may actually last until the + calling function returns, + - for huge N (say, N >= 65536) - you never know how large (or small) + the stack is, and when the stack cannot fulfill the memory allocation + request, the program just crashes. + */ + +#ifndef alloca + /* 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 +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif defined __DECC && defined __VMS +# define alloca __ALLOCA +# elif defined __TANDEM && defined _TNS_E_TARGET +# ifdef __cplusplus +extern "C" +# endif +void *_alloca (unsigned short); +# pragma intrinsic (_alloca) +# define alloca _alloca +# elif defined __MVS__ +# include +# else +# include +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#endif /* _GL_ALLOCA_H */ diff --git a/lib/arg-nonnull.h b/lib/arg-nonnull.h new file mode 100644 index 0000000..e4513ef --- /dev/null +++ b/lib/arg-nonnull.h @@ -0,0 +1,26 @@ +/* A C macro for declaring that specific arguments must not be NULL. + 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 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 . */ + +/* _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__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__ +# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) +# else +# define _GL_ARG_NONNULL(params) +# endif +#endif diff --git a/lib/arpa_inet.in.h b/lib/arpa_inet.in.h new file mode 100644 index 0000000..f5d7db2 --- /dev/null +++ b/lib/arpa_inet.in.h @@ -0,0 +1,150 @@ +/* A GNU-like . + + Copyright (C) 2005-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 . */ + +#ifndef _@GUARD_PREFIX@_ARPA_INET_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if @HAVE_FEATURES_H@ +# include /* for __GLIBC__ */ +#endif + +/* Gnulib's sys/socket.h is responsible for defining socklen_t (used below) and + for pulling in winsock2.h etc. under MinGW. + But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include +#endif + +/* On NonStop Kernel, inet_ntop and inet_pton are declared in . + But avoid namespace pollution on glibc systems. */ +#if defined __TANDEM && !defined __GLIBC__ +# include +#endif + +#if @HAVE_ARPA_INET_H@ + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_ARPA_INET_H@ + +#endif + +#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. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +#if @GNULIB_INET_NTOP@ +/* Converts an internet address from internal format to a printable, + presentable format. + AF is an internet address family, such as AF_INET or AF_INET6. + SRC points to a 'struct in_addr' (for AF_INET) or 'struct in6_addr' + (for AF_INET6). + DST points to a buffer having room for CNT bytes. + The printable representation of the address (in numeric form, not + surrounded by [...], no reverse DNS is done) is placed in DST, and + DST is returned. If an error occurs, the return value is NULL and + errno is set. If CNT bytes are not sufficient to hold the result, + the return value is NULL and errno is set to ENOSPC. A good value + for CNT is 46. + + For more details, see the POSIX:2008 specification + . */ +# if @REPLACE_INET_NTOP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef inet_ntop +# define inet_ntop rpl_inet_ntop +# endif +_GL_FUNCDECL_RPL (inet_ntop, const char *, + (int af, const void *restrict src, + char *restrict dst, socklen_t cnt) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (inet_ntop, const char *, + (int af, const void *restrict src, + char *restrict dst, socklen_t cnt)); +# else +# if !@HAVE_DECL_INET_NTOP@ +_GL_FUNCDECL_SYS (inet_ntop, const char *, + (int af, const void *restrict src, + char *restrict dst, socklen_t cnt) + _GL_ARG_NONNULL ((2, 3))); +# endif +/* Need to cast, because on NonStop Kernel, the fourth parameter is + size_t cnt. */ +_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 +_GL_WARN_ON_USE (inet_ntop, "inet_ntop is unportable - " + "use gnulib module inet_ntop for portability"); +# endif +#endif + +#if @GNULIB_INET_PTON@ +# if @REPLACE_INET_PTON@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef inet_pton +# define inet_pton rpl_inet_pton +# endif +_GL_FUNCDECL_RPL (inet_pton, int, + (int af, const char *restrict src, void *restrict dst) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (inet_pton, int, + (int af, const char *restrict src, void *restrict dst)); +# else +# if !@HAVE_DECL_INET_PTON@ +_GL_FUNCDECL_SYS (inet_pton, int, + (int af, const char *restrict src, void *restrict dst) + _GL_ARG_NONNULL ((2, 3))); +# endif +_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 +_GL_WARN_ON_USE (inet_pton, "inet_pton is unportable - " + "use gnulib module inet_pton for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_ARPA_INET_H */ +#endif /* _@GUARD_PREFIX@_ARPA_INET_H */ diff --git a/lib/array-mergesort.h b/lib/array-mergesort.h new file mode 100644 index 0000000..c70dc73 --- /dev/null +++ b/lib/array-mergesort.h @@ -0,0 +1,281 @@ +/* Stable-sorting of an array using mergesort. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 . */ + +/* This file implements stable sorting of an array, using the mergesort + algorithm. + Worst-case running time for an array of length N is O(N log N). + Unlike the mpsort module, the algorithm here attempts to minimize not + only the number of comparisons, but also the number of copying operations. + + Before including this file, you need to define + ELEMENT The type of every array element. + COMPARE A two-argument macro that takes two 'const ELEMENT *' + pointers and returns a negative, zero, or positive 'int' + value if the element pointed to by the first argument is, + respectively, less, equal, or greater than the element + pointed to by the second argument. + STATIC The storage class of the functions being defined. + STATIC_FROMTO (Optional.) Overrides STATIC for the 'merge_sort_fromto' + function. + Before including this file, you also need to include: + #include + */ + +/* Merge the sorted arrays src1[0..n1-1] and src2[0..n2-1] into + dst[0..n1+n2-1]. In case of ambiguity, put the elements of src1 + before the elements of src2. + n1 and n2 must be > 0. + The arrays src1 and src2 must not overlap the dst array, except that + src1 may be dst[n2..n1+n2-1], or src2 may be dst[n1..n1+n2-1]. */ +static void +merge (const ELEMENT *src1, size_t n1, + const ELEMENT *src2, size_t n2, + ELEMENT *dst) +{ + for (;;) /* while (n1 > 0 && n2 > 0) */ + { + if (COMPARE (src1, src2) <= 0) + { + *dst++ = *src1++; + n1--; + if (n1 == 0) + break; + } + else + { + *dst++ = *src2++; + n2--; + if (n2 == 0) + break; + } + } + /* Here n1 == 0 || n2 == 0 but also n1 > 0 || n2 > 0. */ + if (n1 > 0) + { + if (dst != src1) + do + { + *dst++ = *src1++; + n1--; + } + while (n1 > 0); + } + else /* n2 > 0 */ + { + if (dst != src2) + do + { + *dst++ = *src2++; + n2--; + } + while (n2 > 0); + } +} + +/* Sort src[0..n-1] into dst[0..n-1], using tmp[0..n/2-1] as temporary + (scratch) storage. + The arrays src, dst, tmp must not overlap. */ +#ifdef STATIC_FROMTO +STATIC_FROMTO +#else +STATIC +#endif +void +merge_sort_fromto (const ELEMENT *src, ELEMENT *dst, size_t n, ELEMENT *tmp) +{ + switch (n) + { + case 0: + return; + case 1: + /* Nothing to do. */ + dst[0] = src[0]; + return; + case 2: + /* Trivial case. */ + if (COMPARE (&src[0], &src[1]) <= 0) + { + /* src[0] <= src[1] */ + dst[0] = src[0]; + dst[1] = src[1]; + } + else + { + dst[0] = src[1]; + dst[1] = src[0]; + } + break; + case 3: + /* Simple case. */ + if (COMPARE (&src[0], &src[1]) <= 0) + { + if (COMPARE (&src[1], &src[2]) <= 0) + { + /* src[0] <= src[1] <= src[2] */ + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + } + else if (COMPARE (&src[0], &src[2]) <= 0) + { + /* src[0] <= src[2] < src[1] */ + dst[0] = src[0]; + dst[1] = src[2]; + dst[2] = src[1]; + } + else + { + /* src[2] < src[0] <= src[1] */ + dst[0] = src[2]; + dst[1] = src[0]; + dst[2] = src[1]; + } + } + else + { + if (COMPARE (&src[0], &src[2]) <= 0) + { + /* src[1] < src[0] <= src[2] */ + dst[0] = src[1]; + dst[1] = src[0]; + dst[2] = src[2]; + } + else if (COMPARE (&src[1], &src[2]) <= 0) + { + /* src[1] <= src[2] < src[0] */ + dst[0] = src[1]; + dst[1] = src[2]; + dst[2] = src[0]; + } + else + { + /* src[2] < src[1] < src[0] */ + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + } + } + break; + default: + { + size_t n1 = n / 2; + size_t n2 = (n + 1) / 2; + /* Note: n1 + n2 = n, n1 <= n2. */ + /* Sort src[n1..n-1] into dst[n1..n-1], scratching tmp[0..n2/2-1]. */ + merge_sort_fromto (src + n1, dst + n1, n2, tmp); + /* Sort src[0..n1-1] into tmp[0..n1-1], scratching dst[0..n1-1]. */ + merge_sort_fromto (src, tmp, n1, dst); + /* Merge the two half results. */ + merge (tmp, n1, dst + n1, n2, dst); + } + break; + } +} + +/* Sort src[0..n-1], using tmp[0..n-1] as temporary (scratch) storage. + The arrays src, tmp must not overlap. */ +STATIC void +merge_sort_inplace (ELEMENT *src, size_t n, ELEMENT *tmp) +{ + switch (n) + { + case 0: + case 1: + /* Nothing to do. */ + return; + case 2: + /* Trivial case. */ + if (COMPARE (&src[0], &src[1]) <= 0) + { + /* src[0] <= src[1] */ + } + else + { + ELEMENT t = src[0]; + src[0] = src[1]; + src[1] = t; + } + break; + case 3: + /* Simple case. */ + if (COMPARE (&src[0], &src[1]) <= 0) + { + if (COMPARE (&src[1], &src[2]) <= 0) + { + /* src[0] <= src[1] <= src[2] */ + } + else if (COMPARE (&src[0], &src[2]) <= 0) + { + /* src[0] <= src[2] < src[1] */ + ELEMENT t = src[1]; + src[1] = src[2]; + src[2] = t; + } + else + { + /* src[2] < src[0] <= src[1] */ + ELEMENT t = src[0]; + src[0] = src[2]; + src[2] = src[1]; + src[1] = t; + } + } + else + { + if (COMPARE (&src[0], &src[2]) <= 0) + { + /* src[1] < src[0] <= src[2] */ + ELEMENT t = src[0]; + src[0] = src[1]; + src[1] = t; + } + else if (COMPARE (&src[1], &src[2]) <= 0) + { + /* src[1] <= src[2] < src[0] */ + ELEMENT t = src[0]; + src[0] = src[1]; + src[1] = src[2]; + src[2] = t; + } + else + { + /* src[2] < src[1] < src[0] */ + ELEMENT t = src[0]; + src[0] = src[2]; + src[2] = t; + } + } + break; + default: + { + size_t n1 = n / 2; + size_t n2 = (n + 1) / 2; + /* Note: n1 + n2 = n, n1 <= n2. */ + /* Sort src[n1..n-1], scratching tmp[0..n2-1]. */ + merge_sort_inplace (src + n1, n2, tmp); + /* Sort src[0..n1-1] into tmp[0..n1-1], scratching tmp[n1..2*n1-1]. */ + merge_sort_fromto (src, tmp, n1, tmp + n1); + /* Merge the two half results. */ + merge (tmp, n1, src + n1, n2, src); + } + break; + } +} + +#undef ELEMENT +#undef COMPARE +#undef STATIC diff --git a/lib/asnprintf.c b/lib/asnprintf.c new file mode 100644 index 0000000..0c5c76e --- /dev/null +++ b/lib/asnprintf.c @@ -0,0 +1,34 @@ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 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 . */ + +#include + +/* Specification. */ +#include "vasnprintf.h" + +#include + +char * +asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) +{ + va_list args; + char *result; + + va_start (args, format); + result = vasnprintf (resultbuf, lengthp, format, args); + va_end (args); + return result; +} diff --git a/lib/asprintf.c b/lib/asprintf.c new file mode 100644 index 0000000..9c163f3 --- /dev/null +++ b/lib/asprintf.c @@ -0,0 +1,39 @@ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 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 + +/* Specification. */ +#ifdef IN_LIBASPRINTF +# include "vasprintf.h" +#else +# include +#endif + +#include + +int +asprintf (char **resultp, const char *format, ...) +{ + va_list args; + int result; + + va_start (args, format); + result = vasprintf (resultp, format, args); + va_end (args); + return result; +} diff --git a/lib/assure.h b/lib/assure.h new file mode 100644 index 0000000..20e806a --- /dev/null +++ b/lib/assure.h @@ -0,0 +1,57 @@ +/* Run-time assert-like macros. + + Copyright (C) 2014-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 _GL_ASSURE_H +#define _GL_ASSURE_H + +#include +#include "verify.h" + +/* Evaluate an assertion E that is guaranteed to be true. + If NDEBUG is not defined, abort the program if E is false. + If NDEBUG is defined, the compiler can assume E and behavior is + undefined if E is false, fails to evaluate, or has side effects. + + Unlike standard 'assert', this macro evaluates E even when NDEBUG + is defined, so as to catch typos, avoid some GCC warnings, and + improve performance when E is simple enough. + + Also see the documentation for 'assume' in verify.h. */ + +#ifdef NDEBUG +# define affirm(E) assume (E) +#else +# define affirm(E) assert (E) +#endif + +/* Check E's value at runtime, and report an error and abort if not. + However, do nothing if NDEBUG is defined. + + Unlike standard 'assert', this macro compiles E even when NDEBUG + is defined, so as to catch typos and avoid some GCC warnings. + Unlike 'affirm', it is OK for E to use hard-to-optimize features, + since E is not executed if NDEBUG is defined. */ + +#ifdef NDEBUG +# define assure(E) ((void) (0 && (E))) +#else +# define assure(E) assert (E) +#endif + +#endif diff --git a/lib/at-func.c b/lib/at-func.c new file mode 100644 index 0000000..afcc819 --- /dev/null +++ b/lib/at-func.c @@ -0,0 +1,146 @@ +/* Define at-style functions like fstatat, unlinkat, fchownat, etc. + Copyright (C) 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 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 */ + +#include "filename.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ + +#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD +# include +# ifndef ENOTSUP +# define ENOTSUP EINVAL +# endif +#else +# include "openat.h" +# include "openat-priv.h" +# include "save-cwd.h" +#endif + +#ifdef AT_FUNC_USE_F1_COND +# define CALL_FUNC(F) \ + (flag == AT_FUNC_USE_F1_COND \ + ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \ + : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS)) +# define VALIDATE_FLAG(F) \ + if (flag & ~AT_FUNC_USE_F1_COND) \ + { \ + errno = EINVAL; \ + return FUNC_FAIL; \ + } +#else +# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS)) +# define VALIDATE_FLAG(F) /* empty */ +#endif + +#ifdef AT_FUNC_RESULT +# define FUNC_RESULT AT_FUNC_RESULT +#else +# define FUNC_RESULT int +#endif + +#ifdef AT_FUNC_FAIL +# define FUNC_FAIL AT_FUNC_FAIL +#else +# define FUNC_FAIL -1 +#endif + +/* Call AT_FUNC_F1 to operate on FILE, which is in the directory + open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value, + AT_FUNC_POST_FILE_PARAM_DECLS must include a parameter named flag; + call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than + AT_FUNC_USE_F1_COND. Return int and fail with -1 unless AT_FUNC_RESULT + or AT_FUNC_FAIL are defined. If possible, do it without changing the + working directory. Otherwise, resort to using save_cwd/fchdir, + then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd + fails, then give a diagnostic and exit nonzero. */ +FUNC_RESULT +AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) +{ + VALIDATE_FLAG (flag); + + if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) + return CALL_FUNC (file); + +#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD + errno = ENOTSUP; + return FUNC_FAIL; +#else + { + /* Be careful to choose names unlikely to conflict with + AT_FUNC_POST_FILE_PARAM_DECLS. */ + struct saved_cwd saved_cwd; + int saved_errno; + FUNC_RESULT err; + + { + char proc_buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (proc_buf, fd, file); + if (proc_file) + { + FUNC_RESULT proc_result = CALL_FUNC (proc_file); + int proc_errno = errno; + if (proc_file != proc_buf) + free (proc_file); + /* If the syscall succeeds, or if it fails with an unexpected + errno value, then return right away. Otherwise, fall through + and resort to using save_cwd/restore_cwd. */ + if (FUNC_FAIL != proc_result) + return proc_result; + if (! EXPECTED_ERRNO (proc_errno)) + { + errno = proc_errno; + return proc_result; + } + } + } + + if (save_cwd (&saved_cwd) != 0) + openat_save_fail (errno); + if (0 <= fd && fd == saved_cwd.desc) + { + /* If saving the working directory collides with the user's + requested fd, then the user's fd must have been closed to + begin with. */ + free_cwd (&saved_cwd); + errno = EBADF; + return FUNC_FAIL; + } + + if (fchdir (fd) != 0) + { + saved_errno = errno; + free_cwd (&saved_cwd); + errno = saved_errno; + return FUNC_FAIL; + } + + err = CALL_FUNC (file); + saved_errno = (err == FUNC_FAIL ? errno : 0); + + if (restore_cwd (&saved_cwd) != 0) + openat_restore_fail (errno); + + free_cwd (&saved_cwd); + + if (saved_errno) + errno = saved_errno; + return err; + } +#endif +} +#undef CALL_FUNC +#undef FUNC_RESULT +#undef FUNC_FAIL diff --git a/lib/attribute.h b/lib/attribute.h new file mode 100644 index 0000000..378d4f0 --- /dev/null +++ b/lib/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/lib/base32.c b/lib/base32.c new file mode 100644 index 0000000..ea87338 --- /dev/null +++ b/lib/base32.c @@ -0,0 +1,586 @@ +/* base32.c -- Encode binary data using printable characters. + Copyright (C) 1999-2001, 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 . */ + +/* Adapted from Simon Josefsson's base64 code by Gijs van Tulder. + * + * See also RFC 4648 . + * + * Be careful with error checking. Here is how you would typically + * use these functions: + * + * bool ok = base32_decode_alloc (in, inlen, &out, &outlen); + * if (!ok) + * FAIL: input was not valid base32 + * if (out == NULL) + * FAIL: memory allocation error + * OK: data in OUT/OUTLEN + * + * idx_t outlen = base32_encode_alloc (in, inlen, &out); + * if (out == NULL && outlen == 0 && inlen != 0) + * FAIL: input too long + * if (out == NULL) + * FAIL: memory allocation error + * OK: data in OUT/OUTLEN. + * + */ + +#include + +/* Get prototype. */ +#include "base32.h" + +/* Get imalloc. */ +#include + +#include + +/* Get UCHAR_MAX. */ +#include + +#include + +/* Convert 'char' to 'unsigned char' without casting. */ +static unsigned char +to_uchar (char ch) +{ + return ch; +} + +/* Base32 encode IN array of size INLEN into OUT array of size OUTLEN. + If OUTLEN is less than BASE32_LENGTH(INLEN), write as many bytes as + possible. If OUTLEN is larger than BASE32_LENGTH(INLEN), also zero + terminate the output buffer. */ +void +base32_encode (const char *restrict in, idx_t inlen, + char *restrict out, idx_t outlen) +{ + static const char b32str[32] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + + while (inlen && outlen) + { + *out++ = b32str[(to_uchar (in[0]) >> 3) & 0x1f]; + if (!--outlen) + break; + *out++ = b32str[((to_uchar (in[0]) << 2) + + (--inlen ? to_uchar (in[1]) >> 6 : 0)) + & 0x1f]; + if (!--outlen) + break; + *out++ = + (inlen + ? b32str[(to_uchar (in[1]) >> 1) & 0x1f] + : '='); + if (!--outlen) + break; + *out++ = + (inlen + ? b32str[((to_uchar (in[1]) << 4) + + (--inlen ? to_uchar (in[2]) >> 4 : 0)) + & 0x1f] + : '='); + if (!--outlen) + break; + *out++ = + (inlen + ? b32str[((to_uchar (in[2]) << 1) + + (--inlen ? to_uchar (in[3]) >> 7 : 0)) + & 0x1f] + : '='); + if (!--outlen) + break; + *out++ = + (inlen + ? b32str[(to_uchar (in[3]) >> 2) & 0x1f] + : '='); + if (!--outlen) + break; + *out++ = + (inlen + ? b32str[((to_uchar (in[3]) << 3) + + (--inlen ? to_uchar (in[4]) >> 5 : 0)) + & 0x1f] + : '='); + if (!--outlen) + break; + *out++ = inlen ? b32str[to_uchar (in[4]) & 0x1f] : '='; + if (!--outlen) + break; + if (inlen) + inlen--; + if (inlen) + in += 5; + } + + if (outlen) + *out = '\0'; +} + +/* Allocate a buffer and store zero terminated base32 encoded data + from array IN of size INLEN, returning BASE32_LENGTH(INLEN), i.e., + the length of the encoded data, excluding the terminating zero. On + return, the OUT variable will hold a pointer to newly allocated + memory that must be deallocated by the caller. If output string + length would overflow, 0 is returned and OUT is set to NULL. If + memory allocation failed, OUT is set to NULL, and the return value + indicates length of the requested memory block, i.e., + BASE32_LENGTH(inlen) + 1. */ +idx_t +base32_encode_alloc (const char *in, idx_t inlen, char **out) +{ + /* Check for overflow in outlen computation. + Treat negative INLEN as overflow, for better compatibility with + pre-2021-08-27 API, which used size_t. */ + idx_t in_over_5 = inlen / 5 + (inlen % 5 != 0), outlen; + if (! INT_MULTIPLY_OK (in_over_5, 8, &outlen) || inlen < 0) + { + *out = NULL; + return 0; + } + outlen++; + + *out = imalloc (outlen); + if (!*out) + return outlen; + + base32_encode (in, inlen, *out, outlen); + + return outlen - 1; +} + +/* With this approach this file works independent of the charset used + (think EBCDIC). However, it does assume that the characters in the + Base32 alphabet (A-Z2-7) are encoded in 0..255. POSIX + 1003.1-2001 require that char and unsigned char are 8-bit + quantities, though, taking care of that problem. But this may be a + potential problem on non-POSIX C99 platforms. + + IBM C V6 for AIX mishandles "#define B32(x) ...'x'...", so use "_" + as the formal parameter rather than "x". */ +#define B32(_) \ + ((_) == 'A' ? 0 \ + : (_) == 'B' ? 1 \ + : (_) == 'C' ? 2 \ + : (_) == 'D' ? 3 \ + : (_) == 'E' ? 4 \ + : (_) == 'F' ? 5 \ + : (_) == 'G' ? 6 \ + : (_) == 'H' ? 7 \ + : (_) == 'I' ? 8 \ + : (_) == 'J' ? 9 \ + : (_) == 'K' ? 10 \ + : (_) == 'L' ? 11 \ + : (_) == 'M' ? 12 \ + : (_) == 'N' ? 13 \ + : (_) == 'O' ? 14 \ + : (_) == 'P' ? 15 \ + : (_) == 'Q' ? 16 \ + : (_) == 'R' ? 17 \ + : (_) == 'S' ? 18 \ + : (_) == 'T' ? 19 \ + : (_) == 'U' ? 20 \ + : (_) == 'V' ? 21 \ + : (_) == 'W' ? 22 \ + : (_) == 'X' ? 23 \ + : (_) == 'Y' ? 24 \ + : (_) == 'Z' ? 25 \ + : (_) == '2' ? 26 \ + : (_) == '3' ? 27 \ + : (_) == '4' ? 28 \ + : (_) == '5' ? 29 \ + : (_) == '6' ? 30 \ + : (_) == '7' ? 31 \ + : -1) + +static const signed char b32[0x100] = { + B32 (0), B32 (1), B32 (2), B32 (3), + B32 (4), B32 (5), B32 (6), B32 (7), + B32 (8), B32 (9), B32 (10), B32 (11), + B32 (12), B32 (13), B32 (14), B32 (15), + B32 (16), B32 (17), B32 (18), B32 (19), + B32 (20), B32 (21), B32 (22), B32 (23), + B32 (24), B32 (25), B32 (26), B32 (27), + B32 (28), B32 (29), B32 (30), B32 (31), + B32 (32), B32 (33), B32 (34), B32 (35), + B32 (36), B32 (37), B32 (38), B32 (39), + B32 (40), B32 (41), B32 (42), B32 (43), + B32 (44), B32 (45), B32 (46), B32 (47), + B32 (48), B32 (49), B32 (50), B32 (51), + B32 (52), B32 (53), B32 (54), B32 (55), + B32 (56), B32 (57), B32 (58), B32 (59), + B32 (60), B32 (61), B32 (62), B32 (63), + B32 (32), B32 (65), B32 (66), B32 (67), + B32 (68), B32 (69), B32 (70), B32 (71), + B32 (72), B32 (73), B32 (74), B32 (75), + B32 (76), B32 (77), B32 (78), B32 (79), + B32 (80), B32 (81), B32 (82), B32 (83), + B32 (84), B32 (85), B32 (86), B32 (87), + B32 (88), B32 (89), B32 (90), B32 (91), + B32 (92), B32 (93), B32 (94), B32 (95), + B32 (96), B32 (97), B32 (98), B32 (99), + B32 (100), B32 (101), B32 (102), B32 (103), + B32 (104), B32 (105), B32 (106), B32 (107), + B32 (108), B32 (109), B32 (110), B32 (111), + B32 (112), B32 (113), B32 (114), B32 (115), + B32 (116), B32 (117), B32 (118), B32 (119), + B32 (120), B32 (121), B32 (122), B32 (123), + B32 (124), B32 (125), B32 (126), B32 (127), + B32 (128), B32 (129), B32 (130), B32 (131), + B32 (132), B32 (133), B32 (134), B32 (135), + B32 (136), B32 (137), B32 (138), B32 (139), + B32 (140), B32 (141), B32 (142), B32 (143), + B32 (144), B32 (145), B32 (146), B32 (147), + B32 (148), B32 (149), B32 (150), B32 (151), + B32 (152), B32 (153), B32 (154), B32 (155), + B32 (156), B32 (157), B32 (158), B32 (159), + B32 (160), B32 (161), B32 (162), B32 (163), + B32 (132), B32 (165), B32 (166), B32 (167), + B32 (168), B32 (169), B32 (170), B32 (171), + B32 (172), B32 (173), B32 (174), B32 (175), + B32 (176), B32 (177), B32 (178), B32 (179), + B32 (180), B32 (181), B32 (182), B32 (183), + B32 (184), B32 (185), B32 (186), B32 (187), + B32 (188), B32 (189), B32 (190), B32 (191), + B32 (192), B32 (193), B32 (194), B32 (195), + B32 (196), B32 (197), B32 (198), B32 (199), + B32 (200), B32 (201), B32 (202), B32 (203), + B32 (204), B32 (205), B32 (206), B32 (207), + B32 (208), B32 (209), B32 (210), B32 (211), + B32 (212), B32 (213), B32 (214), B32 (215), + B32 (216), B32 (217), B32 (218), B32 (219), + B32 (220), B32 (221), B32 (222), B32 (223), + B32 (224), B32 (225), B32 (226), B32 (227), + B32 (228), B32 (229), B32 (230), B32 (231), + B32 (232), B32 (233), B32 (234), B32 (235), + B32 (236), B32 (237), B32 (238), B32 (239), + B32 (240), B32 (241), B32 (242), B32 (243), + B32 (244), B32 (245), B32 (246), B32 (247), + B32 (248), B32 (249), B32 (250), B32 (251), + B32 (252), B32 (253), B32 (254), B32 (255) +}; + +#if UCHAR_MAX == 255 +# define uchar_in_range(c) true +#else +# define uchar_in_range(c) ((c) <= 255) +#endif + +/* Return true if CH is a character from the Base32 alphabet, and + false otherwise. Note that '=' is padding and not considered to be + part of the alphabet. */ +bool +isbase32 (char ch) +{ + return uchar_in_range (to_uchar (ch)) && 0 <= b32[to_uchar (ch)]; +} + +/* Initialize decode-context buffer, CTX. */ +void +base32_decode_ctx_init (struct base32_decode_context *ctx) +{ + ctx->i = 0; +} + +/* If CTX->i is 0 or 8, there are eight or more bytes in [*IN..IN_END), and + none of those eight is a newline, then return *IN. Otherwise, copy up to + 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at + index CTX->i and setting CTX->i to reflect the number of bytes copied, + and return CTX->buf. In either case, advance *IN to point to the byte + after the last one processed, and set *N_NON_NEWLINE to the number of + verified non-newline bytes accessible through the returned pointer. */ +static char * +get_8 (struct base32_decode_context *ctx, + char const *restrict *in, char const *restrict in_end, + idx_t *n_non_newline) +{ + if (ctx->i == 8) + ctx->i = 0; + + if (ctx->i == 0) + { + char const *t = *in; + if (8 <= in_end - *in && memchr (t, '\n', 8) == NULL) + { + /* This is the common case: no newline. */ + *in += 8; + *n_non_newline = 8; + return (char *) t; + } + } + + { + /* Copy non-newline bytes into BUF. */ + char const *p = *in; + while (p < in_end) + { + char c = *p++; + if (c != '\n') + { + ctx->buf[ctx->i++] = c; + if (ctx->i == 8) + break; + } + } + + *in = p; + *n_non_newline = ctx->i; + return ctx->buf; + } +} + +#define return_false \ + do \ + { \ + *outp = out; \ + return false; \ + } \ + while (false) + +/* Decode eight bytes of base32-encoded data, IN, of length INLEN + into the output buffer, *OUT, of size *OUTLEN bytes. Return true if + decoding is successful, false otherwise. If *OUTLEN is too small, + as many bytes as possible are written to *OUT. On return, advance + *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_8 (char const *restrict in, idx_t inlen, + char *restrict *outp, idx_t *outleft) +{ + char *out = *outp; + if (inlen < 8) + return false; + + if (!isbase32 (in[0]) || !isbase32 (in[1])) + return false; + + if (*outleft) + { + *out++ = ((b32[to_uchar (in[0])] << 3) + | (b32[to_uchar (in[1])] >> 2)); + --*outleft; + } + + if (in[2] == '=') + { + if (in[3] != '=' || in[4] != '=' || in[5] != '=' + || in[6] != '=' || in[7] != '=') + return_false; + } + else + { + if (!isbase32 (in[2]) || !isbase32 (in[3])) + return_false; + + if (*outleft) + { + *out++ = ((b32[to_uchar (in[1])] << 6) + | (b32[to_uchar (in[2])] << 1) + | (b32[to_uchar (in[3])] >> 4)); + --*outleft; + } + + if (in[4] == '=') + { + if (in[5] != '=' || in[6] != '=' || in[7] != '=') + return_false; + } + else + { + if (!isbase32 (in[4])) + return_false; + + if (*outleft) + { + *out++ = ((b32[to_uchar (in[3])] << 4) + | (b32[to_uchar (in[4])] >> 1)); + --*outleft; + } + + if (in[5] == '=') + { + if (in[6] != '=' || in[7] != '=') + return_false; + } + else + { + if (!isbase32 (in[5]) || !isbase32 (in[6])) + return_false; + + if (*outleft) + { + *out++ = ((b32[to_uchar (in[4])] << 7) + | (b32[to_uchar (in[5])] << 2) + | (b32[to_uchar (in[6])] >> 3)); + --*outleft; + } + + if (in[7] != '=') + { + if (!isbase32 (in[7])) + return_false; + + if (*outleft) + { + *out++ = ((b32[to_uchar (in[6])] << 5) + | (b32[to_uchar (in[7])])); + --*outleft; + } + } + } + } + } + + *outp = out; + return true; +} + +/* Decode base32-encoded input array IN of length INLEN to output array + OUT that can hold *OUTLEN bytes. The input data may be interspersed + with newlines. Return true if decoding was successful, i.e. if the + input was valid base32 data, false otherwise. If *OUTLEN is too + small, as many bytes as possible will be written to OUT. On return, + *OUTLEN holds the length of decoded bytes in OUT. Note that as soon + as any non-alphabet, non-newline character is encountered, decoding + is stopped and false is returned. If INLEN is zero, then process + only whatever data is stored in CTX. + + Initially, CTX must have been initialized via base32_decode_ctx_init. + Subsequent calls to this function must reuse whatever state is recorded + in that buffer. It is necessary for when a octuple of base32 input + bytes spans two input buffers. + + If CTX is NULL then newlines are treated as garbage and the input + buffer is processed as a unit. */ + +bool +base32_decode_ctx (struct base32_decode_context *ctx, + const char *restrict in, idx_t inlen, + char *restrict out, idx_t *outlen) +{ + idx_t outleft = *outlen; + bool ignore_newlines = ctx != NULL; + bool flush_ctx = false; + unsigned int ctx_i = 0; + + if (ignore_newlines) + { + ctx_i = ctx->i; + flush_ctx = inlen == 0; + } + + + while (true) + { + idx_t outleft_save = outleft; + if (ctx_i == 0 && !flush_ctx) + { + while (true) + { + /* Save a copy of outleft, in case we need to re-parse this + block of four bytes. */ + outleft_save = outleft; + if (!decode_8 (in, inlen, &out, &outleft)) + break; + + in += 8; + inlen -= 8; + } + } + + if (inlen == 0 && !flush_ctx) + break; + + /* Handle the common case of 72-byte wrapped lines. + This also handles any other multiple-of-8-byte wrapping. */ + if (inlen && *in == '\n' && ignore_newlines) + { + ++in; + --inlen; + continue; + } + + /* Restore OUT and OUTLEFT. */ + out -= outleft_save - outleft; + outleft = outleft_save; + + { + char const *in_end = in + inlen; + char const *non_nl; + + if (ignore_newlines) + non_nl = get_8 (ctx, &in, in_end, &inlen); + else + non_nl = in; /* Might have nl in this case. */ + + /* If the input is empty or consists solely of newlines (0 non-newlines), + then we're done. Likewise if there are fewer than 8 bytes when not + flushing context and not treating newlines as garbage. */ + if (inlen == 0 || (inlen < 8 && !flush_ctx && ignore_newlines)) + { + inlen = 0; + break; + } + if (!decode_8 (non_nl, inlen, &out, &outleft)) + break; + + inlen = in_end - in; + } + } + + *outlen -= outleft; + + return inlen == 0; +} + +/* Allocate an output buffer in *OUT, and decode the base32 encoded + data stored in IN of size INLEN to the *OUT buffer. On return, the + size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL, + if the caller is not interested in the decoded length. *OUT may be + NULL to indicate an out of memory error, in which case *OUTLEN + contains the size of the memory block needed. The function returns + true on successful decoding and memory allocation errors. (Use the + *OUT and *OUTLEN parameters to differentiate between successful + decoding and memory error.) The function returns false if the + input was invalid, in which case *OUT is NULL and *OUTLEN is + undefined. */ +bool +base32_decode_alloc_ctx (struct base32_decode_context *ctx, + 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 5 * inlen / 8, minus one or more bytes if the + input is padded with one or more "=". + Shifting before multiplying avoids the possibility of overflow. */ + idx_t needlen = 5 * ((inlen >> 3) + 1); + + *out = imalloc (needlen); + if (!*out) + return true; + + if (!base32_decode_ctx (ctx, in, inlen, *out, &needlen)) + { + free (*out); + *out = NULL; + return false; + } + + if (outlen) + *outlen = needlen; + + return true; +} diff --git a/lib/base32.h b/lib/base32.h new file mode 100644 index 0000000..4145fe7 --- /dev/null +++ b/lib/base32.h @@ -0,0 +1,60 @@ +/* base32.h -- Encode binary data using printable characters. + Copyright (C) 2004-2006, 2009-2022 Free Software Foundation, Inc. + Adapted from Simon Josefsson's base64 code by Gijs van Tulder. + + 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 BASE32_H +# define BASE32_H + +/* Get idx_t. */ +# include + +/* Get bool. */ +# include + +/* This uses that the expression (n+(k-1))/k means the smallest + integer >= n/k, i.e., the ceiling of n/k. */ +# define BASE32_LENGTH(inlen) ((((inlen) + 4) / 5) * 8) + +struct base32_decode_context +{ + int i; + char buf[8]; +}; + +extern bool isbase32 (char ch) _GL_ATTRIBUTE_CONST; + +extern void base32_encode (const char *restrict in, idx_t inlen, + char *restrict out, idx_t outlen); + +extern idx_t base32_encode_alloc (const char *in, idx_t inlen, char **out); + +extern void base32_decode_ctx_init (struct base32_decode_context *ctx); + +extern bool base32_decode_ctx (struct base32_decode_context *ctx, + const char *restrict in, idx_t inlen, + char *restrict out, idx_t *outlen); + +extern bool base32_decode_alloc_ctx (struct base32_decode_context *ctx, + const char *in, idx_t inlen, + char **out, idx_t *outlen); + +#define base32_decode(in, inlen, out, outlen) \ + base32_decode_ctx (NULL, in, inlen, out, outlen) + +#define base32_decode_alloc(in, inlen, out, outlen) \ + base32_decode_alloc_ctx (NULL, in, inlen, out, outlen) + +#endif /* BASE32_H */ diff --git a/lib/basename-lgpl.c b/lib/basename-lgpl.c new file mode 100644 index 0000000..eb07e25 --- /dev/null +++ b/lib/basename-lgpl.c @@ -0,0 +1,71 @@ +/* basename.c -- return the last element in a file name + + Copyright (C) 1990, 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 . */ + +#include + +/* Specification. */ +#include "basename-lgpl.h" + +#include +#include + +#include "filename.h" + +char * +last_component (char const *name) +{ + char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); + char const *p; + bool last_was_slash = false; + + while (ISSLASH (*base)) + base++; + + for (p = base; *p; p++) + { + if (ISSLASH (*p)) + last_was_slash = true; + else if (last_was_slash) + { + base = p; + last_was_slash = false; + } + } + + return (char *) base; +} + +size_t +base_len (char const *name) +{ + size_t len; + size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); + + for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) + continue; + + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1 + && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2]) + return 2; + + if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len + && len == prefix_len && ISSLASH (name[prefix_len])) + return prefix_len + 1; + + return len; +} diff --git a/lib/basename-lgpl.h b/lib/basename-lgpl.h new file mode 100644 index 0000000..5569f21 --- /dev/null +++ b/lib/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/lib/basename.c b/lib/basename.c new file mode 100644 index 0000000..0e372ca --- /dev/null +++ b/lib/basename.c @@ -0,0 +1,64 @@ +/* basename.c -- return the last element in a file name + + 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 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 "dirname.h" + +#include +#include "xalloc.h" + +char * +base_name (char const *name) +{ + char const *base = last_component (name); + 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) + { + p[0] = '.'; + p[1] = '/'; + } + + /* Finally, copy the basename. */ + memcpy (p + dotslash_len, base, length); + p[dotslash_len + length] = '\0'; + return p; +} diff --git a/lib/binary-io.c b/lib/binary-io.c new file mode 100644 index 0000000..ea407fd --- /dev/null +++ b/lib/binary-io.c @@ -0,0 +1,39 @@ +/* Binary mode I/O. + Copyright 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 . */ + +#include + +#define BINARY_IO_INLINE _GL_EXTERN_INLINE +#include "binary-io.h" + +#if defined __DJGPP__ || defined __EMX__ +# include + +int +set_binary_mode (int fd, int mode) +{ + if (isatty (fd)) + /* If FD refers to a console (not a pipe, not a regular file), + O_TEXT is the only reasonable mode, both on input and on output. + Silently ignore the request. If we were to return -1 here, + all programs that use xset_binary_mode would fail when run + with console input or console output. */ + return O_TEXT; + else + return __gl_setmode (fd, mode); +} + +#endif diff --git a/lib/binary-io.h b/lib/binary-io.h new file mode 100644 index 0000000..5b7661e --- /dev/null +++ b/lib/binary-io.h @@ -0,0 +1,77 @@ +/* Binary mode I/O. + Copyright (C) 2001, 2003, 2005, 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 . */ + +#ifndef _BINARY_H +#define _BINARY_H + +/* For systems that distinguish between text and binary I/O. + O_BINARY is guaranteed by the gnulib . */ +#include + +/* The MSVC7 doesn't like to be included after '#define fileno ...', + so we include it here first. */ +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef BINARY_IO_INLINE +# define BINARY_IO_INLINE _GL_INLINE +#endif + +#if O_BINARY +# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__ +# include /* declares setmode() */ +# define __gl_setmode setmode +# else +# define __gl_setmode _setmode +# undef fileno +# define fileno _fileno +# endif +#else + /* On reasonable systems, binary I/O is the only choice. */ + /* Use a function rather than a macro, to avoid gcc warnings + "warning: statement with no effect". */ +BINARY_IO_INLINE int +__gl_setmode (_GL_UNUSED int fd, _GL_UNUSED int mode) +{ + return O_BINARY; +} +#endif + +/* Set FD's mode to MODE, which should be either O_TEXT or O_BINARY. + Return the old mode if successful, -1 (setting errno) on failure. + Ordinarily this function would be called 'setmode', since that is + its old name on MS-Windows, but it is called 'set_binary_mode' here + to avoid colliding with a BSD function of another name. */ + +#if defined __DJGPP__ || defined __EMX__ +extern int set_binary_mode (int fd, int mode); +#else +BINARY_IO_INLINE int +set_binary_mode (int fd, int mode) +{ + return __gl_setmode (fd, mode); +} +#endif + +/* This macro is obsolescent. */ +#define SET_BINARY(fd) ((void) set_binary_mode (fd, O_BINARY)) + +_GL_INLINE_HEADER_END + +#endif /* _BINARY_H */ diff --git a/lib/bind.c b/lib/bind.c new file mode 100644 index 0000000..199e0ba --- /dev/null +++ b/lib/bind.c @@ -0,0 +1,49 @@ +/* bind.c --- wrappers for Windows bind function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef bind + +int +rpl_bind (int fd, const struct sockaddr *sockaddr, socklen_t len) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = bind (sock, sockaddr, len); + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/bitrotate.c b/lib/bitrotate.c new file mode 100644 index 0000000..101be6d --- /dev/null +++ b/lib/bitrotate.c @@ -0,0 +1,21 @@ +/* Rotate bits in integers. + + 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 BITROTATE_INLINE _GL_EXTERN_INLINE +#include "bitrotate.h" diff --git a/lib/bitrotate.h b/lib/bitrotate.h new file mode 100644 index 0000000..ee6e61e --- /dev/null +++ b/lib/bitrotate.h @@ -0,0 +1,138 @@ +/* bitrotate.h - Rotate bits in integers + 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 . */ + +/* Written by Simon Josefsson , 2008. */ + +#ifndef _GL_BITROTATE_H +#define _GL_BITROTATE_H + +#include +#include +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef BITROTATE_INLINE +# define BITROTATE_INLINE _GL_INLINE +#endif + +#ifdef UINT64_MAX +/* Given an unsigned 64-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 and + 63 inclusive. */ +BITROTATE_INLINE uint64_t +rotl64 (uint64_t x, int n) +{ + return ((x << n) | (x >> (64 - n))) & UINT64_MAX; +} + +/* Given an unsigned 64-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be between 1 to + 63 inclusive.*/ +BITROTATE_INLINE uint64_t +rotr64 (uint64_t x, int n) +{ + return ((x >> n) | (x << (64 - n))) & UINT64_MAX; +} +#endif + +/* Given an unsigned 32-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 and + 31 inclusive. */ +BITROTATE_INLINE uint32_t +rotl32 (uint32_t x, int n) +{ + return ((x << n) | (x >> (32 - n))) & UINT32_MAX; +} + +/* Given an unsigned 32-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be between 1 to + 31 inclusive.*/ +BITROTATE_INLINE uint32_t +rotr32 (uint32_t x, int n) +{ + return ((x >> n) | (x << (32 - n))) & UINT32_MAX; +} + +/* Given a size_t argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 and + (CHAR_BIT * sizeof (size_t) - 1) inclusive. */ +BITROTATE_INLINE size_t +rotl_sz (size_t x, int n) +{ + return ((x << n) | (x >> ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX; +} + +/* Given a size_t argument X, return the value corresponding + to rotating the bits N steps to the right. N must be between 1 to + (CHAR_BIT * sizeof (size_t) - 1) inclusive. */ +BITROTATE_INLINE size_t +rotr_sz (size_t x, int n) +{ + return ((x >> n) | (x << ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX; +} + +/* Given an unsigned 16-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 to + 15 inclusive, but on most relevant targets N can also be 0 and 16 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint16_t +rotl16 (uint16_t x, int n) +{ + return (((unsigned int) x << n) | ((unsigned int) x >> (16 - n))) + & UINT16_MAX; +} + +/* Given an unsigned 16-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be in 1 to 15 + inclusive, but on most relevant targets N can also be 0 and 16 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint16_t +rotr16 (uint16_t x, int n) +{ + return (((unsigned int) x >> n) | ((unsigned int) x << (16 - n))) + & UINT16_MAX; +} + +/* Given an unsigned 8-bit argument X, return the value corresponding + to rotating the bits N steps to the left. N must be between 1 to 7 + inclusive, but on most relevant targets N can also be 0 and 8 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint8_t +rotl8 (uint8_t x, int n) +{ + return (((unsigned int) x << n) | ((unsigned int) x >> (8 - n))) & UINT8_MAX; +} + +/* Given an unsigned 8-bit argument X, return the value corresponding + to rotating the bits N steps to the right. N must be in 1 to 7 + inclusive, but on most relevant targets N can also be 0 and 8 + because 'int' is at least 32 bits and the arguments must widen + before shifting. */ +BITROTATE_INLINE uint8_t +rotr8 (uint8_t x, int n) +{ + return (((unsigned int) x >> n) | ((unsigned int) x << (8 - n))) & UINT8_MAX; +} + +_GL_INLINE_HEADER_END + +#endif /* _GL_BITROTATE_H */ diff --git a/lib/btowc.c b/lib/btowc.c new file mode 100644 index 0000000..4af58bb --- /dev/null +++ b/lib/btowc.c @@ -0,0 +1,39 @@ +/* Convert unibyte character to wide character. + Copyright (C) 2008, 2010-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 + +#include +#include + +wint_t +btowc (int c) +{ + if (c != EOF) + { + char buf[1]; + wchar_t wc; + + buf[0] = c; + if (mbtowc (&wc, buf, 1) >= 0) + return wc; + } + return WEOF; +} diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h new file mode 100644 index 0000000..f4746d3 --- /dev/null +++ b/lib/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/lib/c++defs.h b/lib/c++defs.h new file mode 100644 index 0000000..ad18155 --- /dev/null +++ b/lib/c++defs.h @@ -0,0 +1,331 @@ +/* C++ compatible function declaration macros. + 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 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 _GL_CXXDEFS_H +#define _GL_CXXDEFS_H + +/* Begin/end the GNULIB_NAMESPACE namespace. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE { +# define _GL_END_NAMESPACE } +#else +# define _GL_BEGIN_NAMESPACE +# define _GL_END_NAMESPACE +#endif + +/* 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, ...)); + + Wrapping rpl_func in an object with an inline conversion operator + avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is + actually used in the program. */ +#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 \ + { \ + static const struct _gl_ ## func ## _wrapper \ + { \ + typedef rettype (*type) parameters; \ + \ + inline operator type () const \ + { \ + return ::rpl_func; \ + } \ + } 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_MDA (func, rettype, parameters); + is to be used when func is a Microsoft deprecated alias, on native Windows. + It declares a C++ alias called GNULIB_NAMESPACE::func + that redirects to _func, if GNULIB_NAMESPACE is defined. + Example: + _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); + */ +#define _GL_CXXALIAS_MDA(func,rettype,parameters) \ + _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters) + +/* _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 \ + { \ + static const struct _gl_ ## func ## _wrapper \ + { \ + typedef rettype (*type) parameters; \ + \ + inline operator type () const \ + { \ + return reinterpret_cast(::rpl_func); \ + } \ + } 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_MDA_CAST (func, rettype, parameters); + is like _GL_CXXALIAS_MDA (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. */ +#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \ + _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters) + +/* _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, ...)); + + Wrapping func in an object with an inline conversion operator + avoids a reference to func unless GNULIB_NAMESPACE::func is + actually used in the program. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ + namespace GNULIB_NAMESPACE \ + { \ + static const struct _gl_ ## func ## _wrapper \ + { \ + typedef rettype (*type) parameters; \ + \ + inline operator type () const \ + { \ + return ::func; \ + } \ + } 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 const struct _gl_ ## func ## _wrapper \ + { \ + typedef rettype (*type) parameters; \ + \ + inline operator type () const \ + { \ + return reinterpret_cast(::func); \ + } \ + } 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 const struct _gl_ ## func ## _wrapper \ + { \ + typedef rettype (*type) parameters; \ + \ + inline operator type () const \ + { \ + return reinterpret_cast((rettype2 (*) parameters2)(::func)); \ + } \ + } 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 !(defined __GNUC__ && !defined __clang__ && __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 !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) +# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ + _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \ + "The symbol ::" #func " refers to the system function. " \ + "Use " #namespace "::" #func " instead.") +# 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/lib/c-ctype.c b/lib/c-ctype.c new file mode 100644 index 0000000..a247514 --- /dev/null +++ b/lib/c-ctype.c @@ -0,0 +1,21 @@ +/* Character handling in C locale. + + Copyright (C) 2003-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 C_CTYPE_INLINE _GL_EXTERN_INLINE +#include "c-ctype.h" diff --git a/lib/c-ctype.h b/lib/c-ctype.h new file mode 100644 index 0000000..1a4f603 --- /dev/null +++ b/lib/c-ctype.h @@ -0,0 +1,366 @@ +/* Character handling in C locale. + + These functions work like the corresponding functions in , + except that they have the C (POSIX) locale hardwired, whereas the + functions' behaviour depends on the current locale set via + setlocale. + + Copyright (C) 2000-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 . */ + +#ifndef C_CTYPE_H +#define C_CTYPE_H + +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef C_CTYPE_INLINE +# define C_CTYPE_INLINE _GL_INLINE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* The functions defined in this file assume the "C" locale and a character + set without diacritics (ASCII-US or EBCDIC-US or something like that). + Even if the "C" locale on a particular system is an extension of the ASCII + character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it + is ISO-8859-1), the functions in this file recognize only the ASCII + characters. */ + + +#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) +/* The character set is ASCII or one of its variants or extensions, not EBCDIC. + Testing the value of '\n' and '\r' is not relevant. */ +# define C_CTYPE_ASCII 1 +#elif ! (' ' == '\x40' && '0' == '\xf0' \ + && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \ + && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2') +# error "Only ASCII and EBCDIC are supported" +#endif + +#if 'A' < 0 +# error "EBCDIC and char is signed -- not supported" +#endif + +/* Cases for control characters. */ + +#define _C_CTYPE_CNTRL \ + case '\a': case '\b': case '\f': case '\n': \ + case '\r': case '\t': case '\v': \ + _C_CTYPE_OTHER_CNTRL + +/* ASCII control characters other than those with \-letter escapes. */ + +#if C_CTYPE_ASCII +# define _C_CTYPE_OTHER_CNTRL \ + case '\x00': case '\x01': case '\x02': case '\x03': \ + case '\x04': case '\x05': case '\x06': case '\x0e': \ + case '\x0f': case '\x10': case '\x11': case '\x12': \ + case '\x13': case '\x14': case '\x15': case '\x16': \ + case '\x17': case '\x18': case '\x19': case '\x1a': \ + case '\x1b': case '\x1c': case '\x1d': case '\x1e': \ + case '\x1f': case '\x7f' +#else + /* Use EBCDIC code page 1047's assignments for ASCII control chars; + assume all EBCDIC code pages agree about these assignments. */ +# define _C_CTYPE_OTHER_CNTRL \ + case '\x00': case '\x01': case '\x02': case '\x03': \ + case '\x07': case '\x0e': case '\x0f': case '\x10': \ + case '\x11': case '\x12': case '\x13': case '\x18': \ + case '\x19': case '\x1c': case '\x1d': case '\x1e': \ + case '\x1f': case '\x26': case '\x27': case '\x2d': \ + case '\x2e': case '\x32': case '\x37': case '\x3c': \ + case '\x3d': case '\x3f' +#endif + +/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */ + +#define _C_CTYPE_LOWER_A_THRU_F_N(N) \ + case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \ + case 'e' + (N): case 'f' + (N) +#define _C_CTYPE_LOWER_N(N) \ + _C_CTYPE_LOWER_A_THRU_F_N(N): \ + case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \ + case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \ + case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \ + case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \ + case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N) + +/* Cases for hex letters, digits, lower, punct, and upper. */ + +#define _C_CTYPE_A_THRU_F \ + _C_CTYPE_LOWER_A_THRU_F_N (0): \ + _C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a') +#define _C_CTYPE_DIGIT \ + case '0': case '1': case '2': case '3': \ + case '4': case '5': case '6': case '7': \ + case '8': case '9' +#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0) +#define _C_CTYPE_PUNCT \ + case '!': case '"': case '#': case '$': \ + case '%': case '&': case '\'': case '(': \ + case ')': case '*': case '+': case ',': \ + case '-': case '.': case '/': case ':': \ + case ';': case '<': case '=': case '>': \ + case '?': case '@': case '[': case '\\': \ + case ']': case '^': case '_': case '`': \ + case '{': case '|': case '}': case '~' +#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a') + + +/* Function definitions. */ + +/* Unlike the functions in , which require an argument in the range + of the 'unsigned char' type, the functions here operate on values that are + in the 'unsigned char' range or in the 'char' range. In other words, + when you have a 'char' value, you need to cast it before using it as + argument to a function: + + const char *s = ...; + if (isalpha ((unsigned char) *s)) ... + + but you don't need to cast it for the functions defined in this file: + + const char *s = ...; + if (c_isalpha (*s)) ... + */ + +C_CTYPE_INLINE bool +c_isalnum (int c) +{ + switch (c) + { + _C_CTYPE_DIGIT: + _C_CTYPE_LOWER: + _C_CTYPE_UPPER: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isalpha (int c) +{ + switch (c) + { + _C_CTYPE_LOWER: + _C_CTYPE_UPPER: + return true; + default: + return false; + } +} + +/* The function isascii is not locale dependent. + Its use in EBCDIC is questionable. */ +C_CTYPE_INLINE bool +c_isascii (int c) +{ + switch (c) + { + case ' ': + _C_CTYPE_CNTRL: + _C_CTYPE_DIGIT: + _C_CTYPE_LOWER: + _C_CTYPE_PUNCT: + _C_CTYPE_UPPER: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isblank (int c) +{ + return c == ' ' || c == '\t'; +} + +C_CTYPE_INLINE bool +c_iscntrl (int c) +{ + switch (c) + { + _C_CTYPE_CNTRL: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isdigit (int c) +{ + switch (c) + { + _C_CTYPE_DIGIT: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isgraph (int c) +{ + switch (c) + { + _C_CTYPE_DIGIT: + _C_CTYPE_LOWER: + _C_CTYPE_PUNCT: + _C_CTYPE_UPPER: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_islower (int c) +{ + switch (c) + { + _C_CTYPE_LOWER: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isprint (int c) +{ + switch (c) + { + case ' ': + _C_CTYPE_DIGIT: + _C_CTYPE_LOWER: + _C_CTYPE_PUNCT: + _C_CTYPE_UPPER: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_ispunct (int c) +{ + switch (c) + { + _C_CTYPE_PUNCT: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isspace (int c) +{ + switch (c) + { + case ' ': case '\t': case '\n': case '\v': case '\f': case '\r': + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isupper (int c) +{ + switch (c) + { + _C_CTYPE_UPPER: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE bool +c_isxdigit (int c) +{ + switch (c) + { + _C_CTYPE_DIGIT: + _C_CTYPE_A_THRU_F: + return true; + default: + return false; + } +} + +C_CTYPE_INLINE int +c_tolower (int c) +{ + switch (c) + { + _C_CTYPE_UPPER: + return c - 'A' + 'a'; + default: + return c; + } +} + +C_CTYPE_INLINE int +c_toupper (int c) +{ + switch (c) + { + _C_CTYPE_LOWER: + return c - 'a' + 'A'; + default: + return c; + } +} + +#ifdef __cplusplus +} +#endif + +_GL_INLINE_HEADER_END + +#endif /* C_CTYPE_H */ diff --git a/lib/c-strcase.h b/lib/c-strcase.h new file mode 100644 index 0000000..3e874b5 --- /dev/null +++ b/lib/c-strcase.h @@ -0,0 +1,56 @@ +/* Case-insensitive string comparison functions in C locale. + Copyright (C) 1995-1996, 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 C_STRCASE_H +#define C_STRCASE_H + +#include + + +/* The functions defined in this file assume the "C" locale and a character + set without diacritics (ASCII-US or EBCDIC-US or something like that). + Even if the "C" locale on a particular system is an extension of the ASCII + character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it + is ISO-8859-1), the functions in this file recognize only the ASCII + characters. More precisely, one of the string arguments must be an ASCII + string; the other one can also contain non-ASCII characters (but then + the comparison result will be nonzero). */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. */ +extern int c_strcasecmp (const char *s1, const char *s2) _GL_ATTRIBUTE_PURE; + +/* Compare no more than N characters of strings S1 and S2, ignoring case, + returning less than, equal to or greater than zero if S1 is + lexicographically less than, equal to or greater than S2. */ +extern int c_strncasecmp (const char *s1, const char *s2, size_t n) + _GL_ATTRIBUTE_PURE; + + +#ifdef __cplusplus +} +#endif + + +#endif /* C_STRCASE_H */ diff --git a/lib/c-strcasecmp.c b/lib/c-strcasecmp.c new file mode 100644 index 0000000..87b993c --- /dev/null +++ b/lib/c-strcasecmp.c @@ -0,0 +1,56 @@ +/* c-strcasecmp.c -- case insensitive string comparator in C locale + Copyright (C) 1998-1999, 2005-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 . */ + +#include + +/* Specification. */ +#include "c-strcase.h" + +#include + +#include "c-ctype.h" + +int +c_strcasecmp (const char *s1, const char *s2) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = c_tolower (*p1); + c2 = c_tolower (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* 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 _GL_CMP (c1, c2); +} diff --git a/lib/c-strcaseeq.h b/lib/c-strcaseeq.h new file mode 100644 index 0000000..1c4607c --- /dev/null +++ b/lib/c-strcaseeq.h @@ -0,0 +1,181 @@ +/* Optimized case-insensitive string comparison in C locale. + Copyright (C) 2001-2002, 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 Bruno Haible . */ + +#include "c-strcase.h" +#include "c-ctype.h" + +/* STRCASEEQ allows to optimize string comparison with a small literal string. + STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0) + is semantically equivalent to + c_strcasecmp (s, "UTF-8") == 0 + just faster. */ + +/* Help GCC to generate good code for string comparisons with + immediate strings. */ +#if (defined __GNUC__ || defined __clang__) && defined __OPTIMIZE__ + +/* Case insensitive comparison of ASCII characters. */ +# if C_CTYPE_ASCII +# define CASEEQ(other,upper) \ + (c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper)) +# else +# define CASEEQ(other,upper) \ + (c_toupper (other) == (upper)) +# endif + +static inline int +strcaseeq9 (const char *s1, const char *s2) +{ + return c_strcasecmp (s1 + 9, s2 + 9) == 0; +} + +static inline int +strcaseeq8 (const char *s1, const char *s2, char s28) +{ + if (CASEEQ (s1[8], s28)) + { + if (s28 == 0) + return 1; + else + return strcaseeq9 (s1, s2); + } + else + return 0; +} + +static inline int +strcaseeq7 (const char *s1, const char *s2, char s27, char s28) +{ + if (CASEEQ (s1[7], s27)) + { + if (s27 == 0) + return 1; + else + return strcaseeq8 (s1, s2, s28); + } + else + return 0; +} + +static inline int +strcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28) +{ + if (CASEEQ (s1[6], s26)) + { + if (s26 == 0) + return 1; + else + return strcaseeq7 (s1, s2, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[5], s25)) + { + if (s25 == 0) + return 1; + else + return strcaseeq6 (s1, s2, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[4], s24)) + { + if (s24 == 0) + return 1; + else + return strcaseeq5 (s1, s2, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[3], s23)) + { + if (s23 == 0) + return 1; + else + return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[2], s22)) + { + if (s22 == 0) + return 1; + else + return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[1], s21)) + { + if (s21 == 0) + return 1; + else + return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +strcaseeq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (CASEEQ (s1[0], s20)) + { + if (s20 == 0) + return 1; + else + return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) + +#else + +#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + (c_strcasecmp (s1, s2) == 0) + +#endif diff --git a/lib/c-strcasestr.c b/lib/c-strcasestr.c new file mode 100644 index 0000000..0c69185 --- /dev/null +++ b/lib/c-strcasestr.c @@ -0,0 +1,77 @@ +/* c-strcasestr.c -- case insensitive substring search in C locale + Copyright (C) 2005-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 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 . */ + +#include + +/* Specification. */ +#include "c-strcasestr.h" + +#include +#include + +#include "c-ctype.h" +#include "c-strcase.h" + +/* Two-Way algorithm. */ +#define RETURN_TYPE char * +#define AVAILABLE(h, h_l, j, n_l) \ + (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l)) \ + && ((h_l) = (j) + (n_l))) +#define CANON_ELEMENT c_tolower +#define CMP_FUNC(p1, p2, l) \ + c_strncasecmp ((const char *) (p1), (const char *) (p2), l) +#include "str-two-way.h" + +/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive + comparison from the C locale, regardless of the current locale. */ +char * +c_strcasestr (const char *haystack_start, const char *needle_start) +{ + const char *haystack = haystack_start; + const char *needle = needle_start; + size_t needle_len; /* Length of NEEDLE. */ + size_t haystack_len; /* Known minimum length of HAYSTACK. */ + bool ok = true; /* True if NEEDLE is prefix of HAYSTACK. */ + + /* Determine length of NEEDLE, and in the process, make sure + HAYSTACK is at least as long (no point processing all of a long + NEEDLE if HAYSTACK is too short). */ + while (*haystack && *needle) + ok &= (c_tolower ((unsigned char) *haystack++) + == c_tolower ((unsigned char) *needle++)); + if (*needle) + return NULL; + if (ok) + return (char *) haystack_start; + needle_len = needle - needle_start; + haystack = haystack_start + 1; + haystack_len = needle_len - 1; + + /* Perform the search. Abstract memory is considered to be an array + of 'unsigned char' values, not an array of 'char' values. See + ISO C 99 section 6.2.6.1. */ + if (needle_len < LONG_NEEDLE_THRESHOLD) + return two_way_short_needle ((const unsigned char *) haystack, + haystack_len, + (const unsigned char *) needle_start, + needle_len); + return two_way_long_needle ((const unsigned char *) haystack, haystack_len, + (const unsigned char *) needle_start, + needle_len); +} + +#undef LONG_NEEDLE_THRESHOLD diff --git a/lib/c-strcasestr.h b/lib/c-strcasestr.h new file mode 100644 index 0000000..1ef50ab --- /dev/null +++ b/lib/c-strcasestr.h @@ -0,0 +1,36 @@ +/* Case-insensitive searching in a string in C locale. + Copyright (C) 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 C_STRCASESTR_H +#define C_STRCASESTR_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive + comparison. */ +extern char *c_strcasestr (const char *haystack, const char *needle); + + +#ifdef __cplusplus +} +#endif + + +#endif /* C_STRCASESTR_H */ diff --git a/lib/c-strncasecmp.c b/lib/c-strncasecmp.c new file mode 100644 index 0000000..5a5d30b --- /dev/null +++ b/lib/c-strncasecmp.c @@ -0,0 +1,56 @@ +/* c-strncasecmp.c -- case insensitive string comparator in C locale + Copyright (C) 1998-1999, 2005-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 . */ + +#include + +/* Specification. */ +#include "c-strcase.h" + +#include + +#include "c-ctype.h" + +int +c_strncasecmp (const char *s1, const char *s2, size_t n) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = c_tolower (*p1); + c2 = c_tolower (*p2); + + if (--n == 0 || c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* 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 _GL_CMP (c1, c2); +} diff --git a/lib/calloc.c b/lib/calloc.c new file mode 100644 index 0000000..0a934b3 --- /dev/null +++ b/lib/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/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c new file mode 100644 index 0000000..a7fa7fe --- /dev/null +++ b/lib/canonicalize-lgpl.c @@ -0,0 +1,472 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-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 +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +# define _GL_ARG_NONNULL(params) + +# include +#endif + +/* Specification. */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef _LIBC +# include +# define GCC_LINT 1 +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define __canonicalize_file_name canonicalize_file_name +# define __realpath realpath +# include "pathmax.h" +# define __faccessat faccessat +# if defined _WIN32 && !defined __CYGWIN__ +# define __getcwd _getcwd +# elif HAVE_GETCWD +# if IN_RELOCWRAPPER + /* When building the relocatable program wrapper, use the system's getcwd + function, not the gnulib override, otherwise we would get a link error. + */ +# undef getcwd +# endif +# if defined VMS && !defined getcwd + /* We want the directory in Unix syntax, not in VMS syntax. + The gnulib override of 'getcwd' takes 2 arguments; the original VMS + 'getcwd' takes 3 arguments. */ +# define __getcwd(buf, max) getcwd (buf, max, 0) +# else +# define __getcwd getcwd +# endif +# else +# define __getcwd(buf, max) getwd (buf) +# endif +# define __mempcpy mempcpy +# define __pathconf pathconf +# define __rawmemchr rawmemchr +# define __readlink readlink +# if IN_RELOCWRAPPER + /* When building the relocatable program wrapper, use the system's memmove + function, not the gnulib override, otherwise we would get a link error. + */ +# undef memmove +# endif +#endif + +/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */ +#if defined GCC_LINT || defined lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ +#endif + +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT false +#endif + +#if defined _LIBC || !FUNC_REALPATH_WORKS + +/* Return true if FILE's existence can be shown, false (setting errno) + otherwise. Follow symbolic links. */ +static bool +file_accessible (char const *file) +{ +# if defined _LIBC || HAVE_FACCESSAT + return __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0; +# else + struct stat st; + return stat (file, &st) == 0 || errno == EOVERFLOW; +# endif +} + +/* True if concatenating END as a suffix to a file name means that the + code needs to check that the file name is that of a searchable + directory, since the canonicalize_filename_mode_stk code won't + check this later anyway when it checks an ordinary file name + component within END. END must either be empty, or start with a + slash. */ + +static bool _GL_ATTRIBUTE_PURE +suffix_requires_dir_check (char const *end) +{ + /* If END does not start with a slash, the suffix is OK. */ + while (ISSLASH (*end)) + { + /* Two or more slashes act like a single slash. */ + do + end++; + while (ISSLASH (*end)); + + switch (*end++) + { + default: return false; /* An ordinary file name component is OK. */ + case '\0': return true; /* Trailing "/" is trouble. */ + case '.': break; /* Possibly "." or "..". */ + } + /* Trailing "/.", or "/.." even if not trailing, is trouble. */ + if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1])))) + return true; + } + + return false; +} + +/* Append this to a file name to test whether it is a searchable directory. + On POSIX platforms "/" suffices, but "/./" is sometimes needed on + macOS 10.13 , and should also work on + platforms like AIX 7.2 that need at least "/.". */ + +# if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK +static char const dir_suffix[] = "/"; +# else +static char const dir_suffix[] = "/./"; +# endif + +/* Return true if DIR is a searchable dir, false (setting errno) otherwise. + DIREND points to the NUL byte at the end of the DIR string. + Store garbage into DIREND[0 .. strlen (dir_suffix)]. */ + +static bool +dir_check (char *dir, char *dirend) +{ + strcpy (dirend, dir_suffix); + return file_accessible (dir); +} + +static idx_t +get_path_max (void) +{ +# ifdef PATH_MAX + long int path_max = PATH_MAX; +# else + /* The caller invoked realpath with a null RESOLVED, even though + PATH_MAX is not defined as a constant. The glibc manual says + programs should not do this, and POSIX says the behavior is undefined. + Historically, glibc here used the result of pathconf, or 1024 if that + failed; stay consistent with this (dubious) historical practice. */ + int err = errno; + long int path_max = __pathconf ("/", _PC_PATH_MAX); + __set_errno (err); +# endif + return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX; +} + +/* Act like __realpath (see below), with an additional argument + rname_buf that can be used as temporary storage. + + If GCC_LINT is defined, do not inline this function with GCC 10.1 + and later, to avoid creating a pointer to the stack that GCC + -Wreturn-local-addr incorrectly complains about. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 + Although the noinline attribute can hurt performance a bit, no better way + to pacify GCC is known; even an explicit #pragma does not pacify GCC. + When the GCC bug is fixed this workaround should be limited to the + broken GCC versions. */ +# if __GNUC_PREREQ (10, 1) +# if defined GCC_LINT || defined lint +__attribute__ ((__noinline__)) +# elif __OPTIMIZE__ && !__NO_INLINE__ +# define GCC_BOGUS_WRETURN_LOCAL_ADDR +# endif +# endif +static char * +realpath_stk (const char *name, char *resolved, + struct scratch_buffer *rname_buf) +{ + char *dest; + char const *start; + char const *end; + int num_links = 0; + + if (name == NULL) + { + /* As per Single Unix Specification V2 we must return an error if + either parameter is a null pointer. We extend this to allow + the RESOLVED parameter to be NULL in case the we are expected to + allocate the room for the return value. */ + __set_errno (EINVAL); + return NULL; + } + + if (name[0] == '\0') + { + /* As per Single Unix Specification V2 we must return an error if + the name argument points to an empty string. */ + __set_errno (ENOENT); + return NULL; + } + + struct scratch_buffer extra_buffer, link_buffer; + scratch_buffer_init (&extra_buffer); + scratch_buffer_init (&link_buffer); + scratch_buffer_init (rname_buf); + char *rname_on_stack = rname_buf->data; + char *rname = rname_on_stack; + bool end_in_extra_buffer = false; + bool failed = true; + + /* This is always zero for Posix hosts, but can be 2 for MS-Windows + and MS-DOS X:/foo/bar file names. */ + idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); + + if (!IS_ABSOLUTE_FILE_NAME (name)) + { + while (!__getcwd (rname, rname_buf->length)) + { + if (errno != ERANGE) + { + dest = rname; + goto error; + } + if (!scratch_buffer_grow (rname_buf)) + goto error_nomem; + rname = rname_buf->data; + } + dest = __rawmemchr (rname, '\0'); + start = name; + prefix_len = FILE_SYSTEM_PREFIX_LEN (rname); + } + else + { + dest = __mempcpy (rname, name, prefix_len); + *dest++ = '/'; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT) + { + if (prefix_len == 0 /* implies ISSLASH (name[0]) */ + && ISSLASH (name[1]) && !ISSLASH (name[2])) + *dest++ = '/'; + *dest = '\0'; + } + start = name + prefix_len; + } + + for ( ; *start; start = end) + { + /* Skip sequence of multiple file name separators. */ + while (ISSLASH (*start)) + ++start; + + /* Find end of component. */ + for (end = start; *end && !ISSLASH (*end); ++end) + /* Nothing. */; + + /* Length of this file name component; it can be zero if a file + name ends in '/'. */ + idx_t startlen = end - start; + + if (startlen == 0) + break; + else if (startlen == 1 && start[0] == '.') + /* nothing */; + else if (startlen == 2 && start[0] == '.' && start[1] == '.') + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rname + prefix_len + 1) + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest) + continue; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT + && dest == rname + 1 && !prefix_len + && ISSLASH (*dest) && !ISSLASH (dest[1])) + dest++; + } + else + { + if (!ISSLASH (dest[-1])) + *dest++ = '/'; + + while (rname + rname_buf->length - dest + < startlen + sizeof dir_suffix) + { + idx_t dest_offset = dest - rname; + if (!scratch_buffer_grow_preserve (rname_buf)) + goto error_nomem; + rname = rname_buf->data; + dest = rname + dest_offset; + } + + dest = __mempcpy (dest, start, startlen); + *dest = '\0'; + + char *buf; + ssize_t n; + while (true) + { + buf = link_buffer.data; + idx_t bufsize = link_buffer.length; + n = __readlink (rname, buf, bufsize - 1); + if (n < bufsize - 1) + break; + if (!scratch_buffer_grow (&link_buffer)) + goto error_nomem; + } + if (0 <= n) + { + if (++num_links > __eloop_threshold ()) + { + __set_errno (ELOOP); + goto error; + } + + buf[n] = '\0'; + + char *extra_buf = extra_buffer.data; + idx_t end_idx IF_LINT (= 0); + if (end_in_extra_buffer) + end_idx = end - extra_buf; + size_t len = strlen (end); + if (INT_ADD_OVERFLOW (len, n)) + { + __set_errno (ENOMEM); + goto error_nomem; + } + while (extra_buffer.length <= len + n) + { + if (!scratch_buffer_grow_preserve (&extra_buffer)) + goto error_nomem; + extra_buf = extra_buffer.data; + } + if (end_in_extra_buffer) + end = extra_buf + end_idx; + + /* Careful here, end may be a pointer into extra_buf... */ + memmove (&extra_buf[n], end, len + 1); + name = end = memcpy (extra_buf, buf, n); + end_in_extra_buffer = true; + + if (IS_ABSOLUTE_FILE_NAME (buf)) + { + idx_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf); + + dest = __mempcpy (rname, buf, pfxlen); + *dest++ = '/'; /* It's an absolute symlink */ + if (DOUBLE_SLASH_IS_DISTINCT_ROOT) + { + if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen) + *dest++ = '/'; + *dest = '\0'; + } + /* Install the new prefix to be in effect hereafter. */ + prefix_len = pfxlen; + } + else + { + /* Back up to previous component, ignore if at root + already: */ + if (dest > rname + prefix_len + 1) + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest) + continue; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 + && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len) + dest++; + } + } + else if (! (suffix_requires_dir_check (end) + ? dir_check (rname, dest) + : errno == EINVAL)) + goto error; + } + } + if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1])) + --dest; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len + && ISSLASH (*dest) && !ISSLASH (dest[1])) + dest++; + failed = false; + +error: + *dest++ = '\0'; + if (resolved != NULL && dest - rname <= get_path_max ()) + rname = strcpy (resolved, rname); + +error_nomem: + scratch_buffer_free (&extra_buffer); + scratch_buffer_free (&link_buffer); + + if (failed || rname == resolved) + { + scratch_buffer_free (rname_buf); + return failed ? NULL : resolved; + } + + return scratch_buffer_dupfree (rname_buf, dest - rname); +} + +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any ".", ".." components nor any repeated file name + separators ('/') or symlinks. All file name components must exist. If + RESOLVED is null, the result is malloc'd; otherwise, if the + canonical name is PATH_MAX chars or more, returns null with 'errno' + set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, + returns the name in RESOLVED. If the name cannot be resolved and + RESOLVED is non-NULL, it contains the name of the first component + that cannot be resolved. If the name can be resolved, RESOLVED + holds the same value as the value returned. */ + +char * +__realpath (const char *name, char *resolved) +{ + #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR + #warning "GCC might issue a bogus -Wreturn-local-addr warning here." + #warning "See ." + #endif + struct scratch_buffer rname_buffer; + return realpath_stk (name, resolved, &rname_buffer); +} +libc_hidden_def (__realpath) +versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); + +#endif /* defined _LIBC || !FUNC_REALPATH_WORKS */ + + +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) +char * +attribute_compat_text_section +__old_realpath (const char *name, char *resolved) +{ + if (resolved == NULL) + { + __set_errno (EINVAL); + return NULL; + } + + return __realpath (name, resolved); +} +compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0); +#endif + + +char * +__canonicalize_file_name (const char *name) +{ + return __realpath (name, NULL); +} +weak_alias (__canonicalize_file_name, canonicalize_file_name) diff --git a/lib/canonicalize.c b/lib/canonicalize.c new file mode 100644 index 0000000..eaf18c6 --- /dev/null +++ b/lib/canonicalize.c @@ -0,0 +1,489 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-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 . */ + +#include + +#include "canonicalize.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "attribute.h" +#include "file-set.h" +#include "hash-triple.h" +#include "xalloc.h" + +/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */ +#if defined GCC_LINT || defined lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ +#endif + +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT false +#endif + +#if ISSLASH ('\\') +# define SLASHES "/\\" +#else +# define SLASHES "/" +#endif + +/* Return true if FILE's existence can be shown, false (setting errno) + otherwise. Follow symbolic links. */ +static bool +file_accessible (char const *file) +{ +# if HAVE_FACCESSAT + return faccessat (AT_FDCWD, file, F_OK, AT_EACCESS) == 0; +# else + struct stat st; + return stat (file, &st) == 0 || errno == EOVERFLOW; +# endif +} + +/* True if concatenating END as a suffix to a file name means that the + code needs to check that the file name is that of a searchable + directory, since the canonicalize_filename_mode_stk code won't + check this later anyway when it checks an ordinary file name + component within END. END must either be empty, or start with a + slash. */ + +static bool _GL_ATTRIBUTE_PURE +suffix_requires_dir_check (char const *end) +{ + /* If END does not start with a slash, the suffix is OK. */ + while (ISSLASH (*end)) + { + /* Two or more slashes act like a single slash. */ + do + end++; + while (ISSLASH (*end)); + + switch (*end++) + { + default: return false; /* An ordinary file name component is OK. */ + case '\0': return true; /* Trailing "/" is trouble. */ + case '.': break; /* Possibly "." or "..". */ + } + /* Trailing "/.", or "/.." even if not trailing, is trouble. */ + if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1])))) + return true; + } + + return false; +} + +/* Append this to a file name to test whether it is a searchable directory. + On POSIX platforms "/" suffices, but "/./" is sometimes needed on + macOS 10.13 , and should also work on + platforms like AIX 7.2 that need at least "/.". */ + +#ifdef LSTAT_FOLLOWS_SLASHED_SYMLINK +static char const dir_suffix[] = "/"; +#else +static char const dir_suffix[] = "/./"; +#endif + +/* Return true if DIR is a searchable dir, false (setting errno) otherwise. + DIREND points to the NUL byte at the end of the DIR string. + Store garbage into DIREND[0 .. strlen (dir_suffix)]. */ + +static bool +dir_check (char *dir, char *dirend) +{ + strcpy (dirend, dir_suffix); + return file_accessible (dir); +} + +#if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS) \ + || GNULIB_CANONICALIZE_LGPL) +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any ".", ".." components nor any repeated file name + separators ('/') or symlinks. All components must exist. + The result is malloc'd. */ + +char * +canonicalize_file_name (const char *name) +{ + return canonicalize_filename_mode (name, CAN_EXISTING); +} +#endif /* !HAVE_CANONICALIZE_FILE_NAME */ + +static bool +multiple_bits_set (canonicalize_mode_t i) +{ + return (i & (i - 1)) != 0; +} + +/* Return true if we've already seen the triple, . + If *HT is not initialized, initialize it. */ +static bool +seen_triple (Hash_table **ht, char const *filename, struct stat const *st) +{ + if (*ht == NULL) + { + idx_t initial_capacity = 7; + *ht = hash_initialize (initial_capacity, + NULL, + triple_hash, + triple_compare_ino_str, + triple_free); + if (*ht == NULL) + xalloc_die (); + } + + if (seen_file (*ht, filename, st)) + return true; + + record_file (*ht, filename, st); + return false; +} + + +/* Act like canonicalize_filename_mode (see below), with an additional argument + rname_buf that can be used as temporary storage. + + If GCC_LINT is defined, do not inline this function with GCC 10.1 + and later, to avoid creating a pointer to the stack that GCC + -Wreturn-local-addr incorrectly complains about. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 + Although the noinline attribute can hurt performance a bit, no better way + to pacify GCC is known; even an explicit #pragma does not pacify GCC. + When the GCC bug is fixed this workaround should be limited to the + broken GCC versions. */ +#if _GL_GNUC_PREREQ (10, 1) +# if defined GCC_LINT || defined lint +__attribute__ ((__noinline__)) +# elif __OPTIMIZE__ && !__NO_INLINE__ +# define GCC_BOGUS_WRETURN_LOCAL_ADDR +# endif +#endif +static char * +canonicalize_filename_mode_stk (const char *name, canonicalize_mode_t can_mode, + struct scratch_buffer *rname_buf) +{ + char *dest; + char const *start; + char const *end; + Hash_table *ht = NULL; + bool logical = (can_mode & CAN_NOLINKS) != 0; + int num_links = 0; + + canonicalize_mode_t can_exist = can_mode & CAN_MODE_MASK; + if (multiple_bits_set (can_exist)) + { + errno = EINVAL; + return NULL; + } + + if (name == NULL) + { + errno = EINVAL; + return NULL; + } + + if (name[0] == '\0') + { + errno = ENOENT; + return NULL; + } + + struct scratch_buffer extra_buffer, link_buffer; + scratch_buffer_init (&extra_buffer); + scratch_buffer_init (&link_buffer); + scratch_buffer_init (rname_buf); + char *rname_on_stack = rname_buf->data; + char *rname = rname_on_stack; + bool end_in_extra_buffer = false; + bool failed = true; + + /* This is always zero for Posix hosts, but can be 2 for MS-Windows + and MS-DOS X:/foo/bar file names. */ + idx_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); + + if (!IS_ABSOLUTE_FILE_NAME (name)) + { + while (!getcwd (rname, rname_buf->length)) + { + switch (errno) + { + case ERANGE: + if (scratch_buffer_grow (rname_buf)) + break; + FALLTHROUGH; + case ENOMEM: + xalloc_die (); + + default: + dest = rname; + goto error; + } + rname = rname_buf->data; + } + dest = rawmemchr (rname, '\0'); + start = name; + prefix_len = FILE_SYSTEM_PREFIX_LEN (rname); + } + else + { + dest = mempcpy (rname, name, prefix_len); + *dest++ = '/'; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT) + { + if (prefix_len == 0 /* implies ISSLASH (name[0]) */ + && ISSLASH (name[1]) && !ISSLASH (name[2])) + { + *dest++ = '/'; +#if defined _WIN32 && !defined __CYGWIN__ + /* For UNC file names '\\server\path\to\file', extend the prefix + to include the server: '\\server\'. */ + { + idx_t i; + for (i = 2; name[i] != '\0' && !ISSLASH (name[i]); ) + i++; + if (name[i] != '\0' /* implies ISSLASH (name[i]) */ + && i + 1 < rname_buf->length) + { + prefix_len = i; + memcpy (dest, name + 2, i - 2 + 1); + dest += i - 2 + 1; + } + else + { + /* Either name = '\\server'; this is an invalid file name. + Or name = '\\server\...' and server is more than + rname_buf->length - 4 bytes long. In either + case, stop the UNC processing. */ + } + } +#endif + } + *dest = '\0'; + } + start = name + prefix_len; + } + + for ( ; *start; start = end) + { + /* Skip sequence of multiple file name separators. */ + while (ISSLASH (*start)) + ++start; + + /* Find end of component. */ + for (end = start; *end && !ISSLASH (*end); ++end) + /* Nothing. */; + + /* Length of this file name component; it can be zero if a file + name ends in '/'. */ + idx_t startlen = end - start; + + if (startlen == 0) + break; + else if (startlen == 1 && start[0] == '.') + /* nothing */; + else if (startlen == 2 && start[0] == '.' && start[1] == '.') + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rname + prefix_len + 1) + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest) + continue; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT + && dest == rname + 1 && !prefix_len + && ISSLASH (*dest) && !ISSLASH (dest[1])) + dest++; + } + else + { + if (!ISSLASH (dest[-1])) + *dest++ = '/'; + + while (rname + rname_buf->length - dest + < startlen + sizeof dir_suffix) + { + idx_t dest_offset = dest - rname; + if (!scratch_buffer_grow_preserve (rname_buf)) + xalloc_die (); + rname = rname_buf->data; + dest = rname + dest_offset; + } + + dest = mempcpy (dest, start, startlen); + *dest = '\0'; + + char *buf; + ssize_t n = -1; + if (!logical) + { + while (true) + { + buf = link_buffer.data; + idx_t bufsize = link_buffer.length; + n = readlink (rname, buf, bufsize - 1); + if (n < bufsize - 1) + break; + if (!scratch_buffer_grow (&link_buffer)) + xalloc_die (); + } + } + if (0 <= n) + { + /* A physical traversal and RNAME is a symbolic link. */ + + if (num_links < 20) + num_links++; + else if (*start) + { + /* Enough symlinks have been seen that it is time to + worry about being in a symlink cycle. + Get the device and inode of the parent directory, as + pre-2017 POSIX says this info is not reliable for + symlinks. */ + struct stat st; + dest[- startlen] = '\0'; + if (stat (*rname ? rname : ".", &st) != 0) + goto error; + dest[- startlen] = *start; + + /* Detect loops. We cannot use the cycle-check module here, + since it's possible to encounter the same parent + directory more than once in a given traversal. However, + encountering the same (parentdir, START) pair twice does + indicate a loop. */ + if (seen_triple (&ht, start, &st)) + { + if (can_exist == CAN_MISSING) + continue; + errno = ELOOP; + goto error; + } + } + + buf[n] = '\0'; + + char *extra_buf = extra_buffer.data; + idx_t end_idx IF_LINT (= 0); + if (end_in_extra_buffer) + end_idx = end - extra_buf; + size_t len = strlen (end); + if (INT_ADD_OVERFLOW (len, n)) + xalloc_die (); + while (extra_buffer.length <= len + n) + { + if (!scratch_buffer_grow_preserve (&extra_buffer)) + xalloc_die (); + extra_buf = extra_buffer.data; + } + if (end_in_extra_buffer) + end = extra_buf + end_idx; + + /* Careful here, end may be a pointer into extra_buf... */ + memmove (&extra_buf[n], end, len + 1); + name = end = memcpy (extra_buf, buf, n); + end_in_extra_buffer = true; + + if (IS_ABSOLUTE_FILE_NAME (buf)) + { + idx_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf); + + dest = mempcpy (rname, buf, pfxlen); + *dest++ = '/'; /* It's an absolute symlink */ + if (DOUBLE_SLASH_IS_DISTINCT_ROOT) + { + if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen) + *dest++ = '/'; + *dest = '\0'; + } + /* Install the new prefix to be in effect hereafter. */ + prefix_len = pfxlen; + } + else + { + /* Back up to previous component, ignore if at root + already: */ + if (dest > rname + prefix_len + 1) + for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest) + continue; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 + && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len) + dest++; + } + } + else if (! (can_exist == CAN_MISSING + || (suffix_requires_dir_check (end) + ? dir_check (rname, dest) + : !logical + ? errno == EINVAL + : *end || file_accessible (rname)) + || (can_exist == CAN_ALL_BUT_LAST + && errno == ENOENT + && !end[strspn (end, SLASHES)]))) + goto error; + } + } + if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1])) + --dest; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len + && ISSLASH (*dest) && !ISSLASH (dest[1])) + dest++; + failed = false; + +error: + if (ht) + hash_free (ht); + scratch_buffer_free (&extra_buffer); + scratch_buffer_free (&link_buffer); + + if (failed) + { + scratch_buffer_free (rname_buf); + return NULL; + } + + *dest++ = '\0'; + char *result = scratch_buffer_dupfree (rname_buf, dest - rname); + if (!result) + xalloc_die (); + return result; +} + +/* Return the canonical absolute name of file NAME, while treating + missing elements according to CAN_MODE. A canonical name + does not contain any ".", ".." components nor any repeated file name + separators ('/') or, depending on other CAN_MODE flags, symlinks. + Whether components must exist or not depends on canonicalize mode. + The result is malloc'd. */ + +char * +canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode) +{ + #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR + #warning "GCC might issue a bogus -Wreturn-local-addr warning here." + #warning "See ." + #endif + struct scratch_buffer rname_buffer; + return canonicalize_filename_mode_stk (name, can_mode, &rname_buffer); +} diff --git a/lib/canonicalize.h b/lib/canonicalize.h new file mode 100644 index 0000000..817da1f --- /dev/null +++ b/lib/canonicalize.h @@ -0,0 +1,58 @@ +/* Return the canonical absolute name of a given file. + Copyright (C) 1996-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 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 CANONICALIZE_H_ +# define CANONICALIZE_H_ + +#include /* for canonicalize_file_name */ + +#define CAN_MODE_MASK (CAN_EXISTING | CAN_ALL_BUT_LAST | CAN_MISSING) + +#ifdef __cplusplus +extern "C" { +#endif + +enum canonicalize_mode_t + { + /* All components must exist. */ + CAN_EXISTING = 0, + + /* All components excluding last one must exist. */ + CAN_ALL_BUT_LAST = 1, + + /* No requirements on components existence. */ + CAN_MISSING = 2, + + /* Don't expand symlinks. */ + CAN_NOLINKS = 4 + }; +typedef enum canonicalize_mode_t canonicalize_mode_t; + +/* Return the canonical absolute name of file NAME, while treating + missing elements according to CAN_MODE. A canonical name + does not contain any `.', `..' components nor any repeated file name + separators ('/') or, depending on other CAN_MODE flags, symlinks. + Whether components must exist or not depends on canonicalize mode. + The result is malloc'd. + Upon failure, return NULL with errno set. */ +char *canonicalize_filename_mode (const char *, canonicalize_mode_t) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + +#ifdef __cplusplus +} +#endif + +#endif /* !CANONICALIZE_H_ */ diff --git a/lib/cdefs.h b/lib/cdefs.h new file mode 100644 index 0000000..cb25145 --- /dev/null +++ b/lib/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. The -1 check is + redundant because since it implies that __glibc_safe_len_cond is true. */ +#define __glibc_safe_or_unknown_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)) + +/* 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/lib/chdir-long.c b/lib/chdir-long.c new file mode 100644 index 0000000..f4efb20 --- /dev/null +++ b/lib/chdir-long.c @@ -0,0 +1,264 @@ +/* provide a chdir function that tries not to fail due to ENAMETOOLONG + Copyright (C) 2004-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 */ + +#include + +#include "chdir-long.h" + +#include +#include +#include +#include +#include +#include + +#include "assure.h" + +#ifndef PATH_MAX +# error "compile this file only if your system defines PATH_MAX" +#endif + +/* The results of openat() in this file are not leaked to any + single-threaded code that could use stdio. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use openat_safer. */ + +struct cd_buf +{ + int fd; +}; + +static void +cdb_init (struct cd_buf *cdb) +{ + cdb->fd = AT_FDCWD; +} + +static int +cdb_fchdir (struct cd_buf const *cdb) +{ + return fchdir (cdb->fd); +} + +static void +cdb_free (struct cd_buf const *cdb) +{ + if (0 <= cdb->fd) + { + bool close_fail = close (cdb->fd); + assure (! close_fail); + } +} + +/* Given a file descriptor of an open directory (or AT_FDCWD), CDB->fd, + try to open the CDB->fd-relative directory, DIR. If the open succeeds, + update CDB->fd with the resulting descriptor, close the incoming file + descriptor, and return zero. Upon failure, return -1 and set errno. */ +static int +cdb_advance_fd (struct cd_buf *cdb, char const *dir) +{ + int new_fd = openat (cdb->fd, dir, + O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); + if (new_fd < 0) + return -1; + + cdb_free (cdb); + cdb->fd = new_fd; + + return 0; +} + +/* Return a pointer to the first non-slash in S. */ +static char * _GL_ATTRIBUTE_PURE +find_non_slash (char const *s) +{ + size_t n_slash = strspn (s, "/"); + return (char *) s + n_slash; +} + +/* This is a function much like chdir, but without the PATH_MAX limitation + on the length of the directory name. A significant difference is that + it must be able to modify (albeit only temporarily) the directory + name. It handles an arbitrarily long directory name by operating + on manageable portions of the name. On systems without the openat + syscall, this means changing the working directory to more and more + "distant" points along the long directory name and then restoring + the working directory. If any of those attempts to save or restore + the working directory fails, this function exits nonzero. + + Note that this function may still fail with errno == ENAMETOOLONG, but + only if the specified directory name contains a component that is long + enough to provoke such a failure all by itself (e.g. if the component + has length PATH_MAX or greater on systems that define PATH_MAX). */ + +int +chdir_long (char *dir) +{ + int e = chdir (dir); + if (e == 0 || errno != ENAMETOOLONG) + return e; + + { + size_t len = strlen (dir); + char *dir_end = dir + len; + struct cd_buf cdb; + size_t n_leading_slash; + + cdb_init (&cdb); + + /* If DIR is the empty string, then the chdir above + must have failed and set errno to ENOENT. */ + assure (0 < len); + assure (PATH_MAX <= len); + + /* Count leading slashes. */ + n_leading_slash = strspn (dir, "/"); + + /* Handle any leading slashes as well as any name that matches + the regular expression, m!^//hostname[/]*! . Handling this + prefix separately usually results in a single additional + cdb_advance_fd call, but it's worthwhile, since it makes the + code in the following loop cleaner. */ + if (n_leading_slash == 2) + { + int err; + /* Find next slash. + We already know that dir[2] is neither a slash nor '\0'. */ + char *slash = memchr (dir + 3, '/', dir_end - (dir + 3)); + if (slash == NULL) + { + errno = ENAMETOOLONG; + return -1; + } + *slash = '\0'; + err = cdb_advance_fd (&cdb, dir); + *slash = '/'; + if (err != 0) + goto Fail; + dir = find_non_slash (slash + 1); + } + else if (n_leading_slash) + { + if (cdb_advance_fd (&cdb, "/") != 0) + goto Fail; + dir += n_leading_slash; + } + + assure (*dir != '/'); + assure (dir <= dir_end); + + while (PATH_MAX <= dir_end - dir) + { + int err; + /* Find a slash that is PATH_MAX or fewer bytes away from dir. + I.e. see if there is a slash that will give us a name of + length PATH_MAX-1 or less. */ + char *slash = memrchr (dir, '/', PATH_MAX); + if (slash == NULL) + { + errno = ENAMETOOLONG; + return -1; + } + + *slash = '\0'; + assure (slash - dir < PATH_MAX); + err = cdb_advance_fd (&cdb, dir); + *slash = '/'; + if (err != 0) + goto Fail; + + dir = find_non_slash (slash + 1); + } + + if (dir < dir_end) + { + if (cdb_advance_fd (&cdb, dir) != 0) + goto Fail; + } + + if (cdb_fchdir (&cdb) != 0) + goto Fail; + + cdb_free (&cdb); + return 0; + + Fail: + { + int saved_errno = errno; + cdb_free (&cdb); + errno = saved_errno; + return -1; + } + } +} + +#if TEST_CHDIR + +# include "closeout.h" +# include "error.h" + +int +main (int argc, char *argv[]) +{ + char *line = NULL; + size_t n = 0; + int len; + + atexit (close_stdout); + + len = getline (&line, &n, stdin); + if (len < 0) + { + int saved_errno = errno; + if (feof (stdin)) + exit (0); + + error (EXIT_FAILURE, saved_errno, + "reading standard input"); + } + else if (len == 0) + exit (0); + + if (line[len-1] == '\n') + line[len-1] = '\0'; + + if (chdir_long (line) != 0) + error (EXIT_FAILURE, errno, + "chdir_long failed: %s", line); + + if (argc <= 1) + { + /* Using 'pwd' here makes sense only if it is a robust implementation, + like the one in coreutils after the 2004-04-19 changes. */ + char const *cmd = "pwd"; + execlp (cmd, (char *) NULL); + error (EXIT_FAILURE, errno, "%s", cmd); + } + + fclose (stdin); + fclose (stderr); + + exit (EXIT_SUCCESS); +} +#endif + +/* +Local Variables: +compile-command: "gcc -DTEST_CHDIR=1 -g -O -W -Wall chdir-long.c libcoreutils.a" +End: +*/ diff --git a/lib/chdir-long.h b/lib/chdir-long.h new file mode 100644 index 0000000..84a7298 --- /dev/null +++ b/lib/chdir-long.h @@ -0,0 +1,30 @@ +/* provide a chdir function that tries not to fail due to ENAMETOOLONG + Copyright (C) 2004-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 + (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. */ + +#include +#include + +#include "pathmax.h" + +/* On systems without PATH_MAX, presume that chdir accepts + arbitrarily long directory names. */ +#ifndef PATH_MAX +# define chdir_long(Dir) chdir (Dir) +#else +int chdir_long (char *dir); +#endif diff --git a/lib/cloexec.c b/lib/cloexec.c new file mode 100644 index 0000000..812be01 --- /dev/null +++ b/lib/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/lib/cloexec.h b/lib/cloexec.h new file mode 100644 index 0000000..7a22d77 --- /dev/null +++ b/lib/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/lib/close.c b/lib/close.c new file mode 100644 index 0000000..44990ba --- /dev/null +++ b/lib/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/lib/closedir.c b/lib/closedir.c new file mode 100644 index 0000000..a273122 --- /dev/null +++ b/lib/closedir.c @@ -0,0 +1,71 @@ +/* Stop reading the entries of a directory. + 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 . */ + +#include + +/* Specification. */ +#include + +#if REPLACE_FCHDIR +# include +#endif + +#if HAVE_CLOSEDIR + +/* Override closedir(), to keep track of the open file descriptors. + Needed because there is a function dirfd(). */ + +#else + +# include + +# include "dirent-private.h" + +#endif + +int +closedir (DIR *dirp) +{ +# if REPLACE_FCHDIR || REPLACE_DIRFD + int fd = dirfd (dirp); +# endif + int retval; + +#if HAVE_CLOSEDIR +# undef closedir + + retval = closedir (dirp); + +# ifdef __KLIBC__ + if (!retval) + _gl_unregister_dirp_fd (fd); +# endif +#else + + if (dirp->current != INVALID_HANDLE_VALUE) + FindClose (dirp->current); + free (dirp); + + retval = 0; + +#endif + +#if REPLACE_FCHDIR + if (retval >= 0) + _gl_unregister_fd (fd); +#endif + return retval; +} diff --git a/lib/concat-filename.c b/lib/concat-filename.c new file mode 100644 index 0000000..f054849 --- /dev/null +++ b/lib/concat-filename.c @@ -0,0 +1,73 @@ +/* Construct a full filename from a directory and a relative filename. + Copyright (C) 2001-2004, 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 Bruno Haible . */ + +#include + +/* Specification. */ +#include "concat-filename.h" + +#include +#include +#include + +#include "filename.h" + +/* Concatenate a directory filename, a relative filename and an optional + suffix. The directory may end with the directory separator. The second + argument may not start with the directory separator (it is relative). + Return a freshly allocated filename. Return NULL and set errno + upon memory allocation failure. */ +char * +concatenated_filename (const char *directory, const char *filename, + const char *suffix) +{ + char *result; + char *p; + + if (strcmp (directory, ".") == 0) + { + /* No need to prepend the directory. */ + result = (char *) malloc (strlen (filename) + + (suffix != NULL ? strlen (suffix) : 0) + + 1); + if (result == NULL) + return NULL; /* errno is set here */ + p = result; + } + else + { + size_t directory_len = strlen (directory); + int need_slash = + (directory_len > FILE_SYSTEM_PREFIX_LEN (directory) + && !ISSLASH (directory[directory_len - 1])); + result = (char *) malloc (directory_len + need_slash + + strlen (filename) + + (suffix != NULL ? strlen (suffix) : 0) + + 1); + if (result == NULL) + return NULL; /* errno is set here */ + memcpy (result, directory, directory_len); + p = result + directory_len; + if (need_slash) + *p++ = '/'; + } + p = stpcpy (p, filename); + if (suffix != NULL) + stpcpy (p, suffix); + return result; +} diff --git a/lib/concat-filename.h b/lib/concat-filename.h new file mode 100644 index 0000000..0348b0d --- /dev/null +++ b/lib/concat-filename.h @@ -0,0 +1,46 @@ +/* Construct a full filename from a directory and a relative filename. + Copyright (C) 2001-2004, 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 . */ + +#ifndef _CONCAT_FILENAME_H +#define _CONCAT_FILENAME_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Concatenate a directory filename, a relative filename and an optional + suffix. Return a freshly allocated filename. Return NULL and set errno + upon memory allocation failure. */ +extern char *concatenated_filename (const char *directory, + const char *filename, const char *suffix) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + +/* Concatenate a directory filename, a relative filename and an optional + suffix. Return a freshly allocated filename. */ +extern char *xconcatenated_filename (const char *directory, + const char *filename, const char *suffix) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; + + +#ifdef __cplusplus +} +#endif + +#endif /* _CONCAT_FILENAME_H */ diff --git a/lib/connect.c b/lib/connect.c new file mode 100644 index 0000000..d160063 --- /dev/null +++ b/lib/connect.c @@ -0,0 +1,56 @@ +/* connect.c --- wrappers for Windows connect function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef connect + +int +rpl_connect (int fd, const struct sockaddr *sockaddr, socklen_t len) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = connect (sock, sockaddr, len); + if (r < 0) + { + /* EINPROGRESS is not returned by WinSock 2.0; for backwards + compatibility, connect(2) uses EWOULDBLOCK. */ + if (WSAGetLastError () == WSAEWOULDBLOCK) + WSASetLastError (WSAEINPROGRESS); + + set_winsock_errno (); + } + + return r; + } +} diff --git a/lib/ctype.in.h b/lib/ctype.in.h new file mode 100644 index 0000000..dc81170 --- /dev/null +++ b/lib/ctype.in.h @@ -0,0 +1,57 @@ +/* A substitute for ISO C99 , for platforms on which it is incomplete. + + 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 Bruno Haible. */ + +/* + * ISO C 99 for platforms on which it is incomplete. + * + */ + +#ifndef _@GUARD_PREFIX@_CTYPE_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* Include the original . */ +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_CTYPE_H@ + +#ifndef _@GUARD_PREFIX@_CTYPE_H +#define _@GUARD_PREFIX@_CTYPE_H + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Return non-zero if c is a blank, i.e. a space or tab character. */ +#if @GNULIB_ISBLANK@ +# if !@HAVE_ISBLANK@ +_GL_EXTERN_C int isblank (int c); +# endif +#elif defined GNULIB_POSIXCHECK +# undef isblank +# if HAVE_RAW_DECL_ISBLANK +_GL_WARN_ON_USE (isblank, "isblank is unportable - " + "use gnulib module isblank for portability"); +# endif +#endif + +#endif /* _@GUARD_PREFIX@_CTYPE_H */ +#endif /* _@GUARD_PREFIX@_CTYPE_H */ diff --git a/lib/dirent-private.h b/lib/dirent-private.h new file mode 100644 index 0000000..30cf5d9 --- /dev/null +++ b/lib/dirent-private.h @@ -0,0 +1,44 @@ +/* Private details of the DIR type. + 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 . */ + +#ifndef _DIRENT_PRIVATE_H +#define _DIRENT_PRIVATE_H 1 + +#define WIN32_LEAN_AND_MEAN +#include + +/* Don't assume that UNICODE is not defined. */ +#undef WIN32_FIND_DATA +#define WIN32_FIND_DATA WIN32_FIND_DATAA + +struct gl_directory +{ + /* Status, or error code to produce in next readdir() call. + -2 means the end of the directory is already reached, + -1 means the entry was already filled by FindFirstFile, + 0 means the entry needs to be filled using FindNextFile. + A positive value is an error code. */ + int status; + /* Handle, reading the directory, at current position. */ + HANDLE current; + /* Found directory entry. */ + WIN32_FIND_DATA entry; + /* Argument to pass to FindFirstFile. It consists of the absolutized + directory name, followed by a directory separator and the wildcards. */ + char dir_name_mask[1]; +}; + +#endif /* _DIRENT_PRIVATE_H */ diff --git a/lib/dirent.in.h b/lib/dirent.in.h new file mode 100644 index 0000000..f28288d --- /dev/null +++ b/lib/dirent.in.h @@ -0,0 +1,321 @@ +/* A GNU-like . + 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 . */ + +#ifndef _@GUARD_PREFIX@_DIRENT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_DIRENT_H@ +# @INCLUDE_NEXT@ @NEXT_DIRENT_H@ +#endif + +#ifndef _@GUARD_PREFIX@_DIRENT_H +#define _@GUARD_PREFIX@_DIRENT_H + +/* Get ino_t. Needed on some systems, including glibc 2.8. */ +#include + +#if !@HAVE_DIRENT_H@ +/* Define types DIR and 'struct dirent'. */ +# if !GNULIB_defined_struct_dirent +struct dirent +{ + char d_type; + char d_name[1]; +}; +/* Possible values for 'd_type'. */ +# define DT_UNKNOWN 0 +# define DT_FIFO 1 /* FIFO */ +# define DT_CHR 2 /* character device */ +# define DT_DIR 4 /* directory */ +# define DT_BLK 6 /* block device */ +# define DT_REG 8 /* regular file */ +# define DT_LNK 10 /* symbolic link */ +# define DT_SOCK 12 /* socket */ +# define DT_WHT 14 /* whiteout */ +typedef struct gl_directory DIR; +# define GNULIB_defined_struct_dirent 1 +# endif +#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_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. */ + + +/* Declare overridden functions. */ + +#if @GNULIB_CLOSEDIR@ +# if @REPLACE_CLOSEDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef closedir +# define closedir rpl_closedir +# define GNULIB_defined_closedir 1 +# endif +_GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (closedir, int, (DIR *dirp)); +# else +# if !@HAVE_CLOSEDIR@ +_GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (closedir, int, (DIR *dirp)); +# endif +_GL_CXXALIASWARN (closedir); +#elif defined GNULIB_POSIXCHECK +# undef closedir +# if HAVE_RAW_DECL_CLOSEDIR +_GL_WARN_ON_USE (closedir, "closedir is not portable - " + "use gnulib module closedir for portability"); +# endif +#endif + +#if @GNULIB_OPENDIR@ +# if @REPLACE_OPENDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef opendir +# define opendir rpl_opendir +# define GNULIB_defined_opendir 1 +# endif +_GL_FUNCDECL_RPL (opendir, DIR *, + (const char *dir_name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1)); +_GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name)); +# else +# if !@HAVE_OPENDIR@ || __GNUC__ >= 11 +_GL_FUNCDECL_SYS (opendir, DIR *, + (const char *dir_name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1)); +# endif +_GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name)); +# endif +_GL_CXXALIASWARN (opendir); +#else +# if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined opendir +/* For -Wmismatched-dealloc: Associate opendir with closedir or + rpl_closedir. */ +_GL_FUNCDECL_SYS (opendir, DIR *, + (const char *dir_name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1)); +# endif +# if defined GNULIB_POSIXCHECK +# undef opendir +# if HAVE_RAW_DECL_OPENDIR +_GL_WARN_ON_USE (opendir, "opendir is not portable - " + "use gnulib module opendir for portability"); +# endif +# endif +#endif + +#if @GNULIB_READDIR@ +# if !@HAVE_READDIR@ +_GL_FUNCDECL_SYS (readdir, struct dirent *, (DIR *dirp) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (readdir, struct dirent *, (DIR *dirp)); +_GL_CXXALIASWARN (readdir); +#elif defined GNULIB_POSIXCHECK +# undef readdir +# if HAVE_RAW_DECL_READDIR +_GL_WARN_ON_USE (readdir, "readdir is not portable - " + "use gnulib module readdir for portability"); +# endif +#endif + +#if @GNULIB_REWINDDIR@ +# if !@HAVE_REWINDDIR@ +_GL_FUNCDECL_SYS (rewinddir, void, (DIR *dirp) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (rewinddir, void, (DIR *dirp)); +_GL_CXXALIASWARN (rewinddir); +#elif defined GNULIB_POSIXCHECK +# undef rewinddir +# if HAVE_RAW_DECL_REWINDDIR +_GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - " + "use gnulib module rewinddir for portability"); +# endif +#endif + +#if @GNULIB_DIRFD@ +/* Return the file descriptor associated with the given directory stream, + or -1 if none exists. */ +# if @REPLACE_DIRFD@ +/* On kLIBC, dirfd() is a macro that does not work. Undefine it. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) || defined dirfd +# undef dirfd +# define dirfd rpl_dirfd +# endif +_GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (dirfd, int, (DIR *)); + +# ifdef __KLIBC__ +/* Gnulib internal hooks needed to maintain the dirfd metadata. */ +_GL_EXTERN_C int _gl_register_dirp_fd (int fd, DIR *dirp) + _GL_ARG_NONNULL ((2)); +_GL_EXTERN_C void _gl_unregister_dirp_fd (int fd); +# endif +# else +# if defined __cplusplus && defined GNULIB_NAMESPACE && defined dirfd + /* dirfd is defined as a macro and not as a function. + Turn it into a function and get rid of the macro. */ +static inline int (dirfd) (DIR *dp) { return dirfd (dp); } +# undef dirfd +# endif +# if !(@HAVE_DECL_DIRFD@ || defined dirfd) +_GL_FUNCDECL_SYS (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (dirfd, int, (DIR *)); +# endif +_GL_CXXALIASWARN (dirfd); +#elif defined GNULIB_POSIXCHECK +# undef dirfd +# if HAVE_RAW_DECL_DIRFD +_GL_WARN_ON_USE (dirfd, "dirfd is unportable - " + "use gnulib module dirfd for portability"); +# endif +#endif + +#if @GNULIB_FDOPENDIR@ +/* Open a directory stream visiting the given directory file + descriptor. Return NULL and set errno if fd is not visiting a + directory. On success, this function consumes fd (it will be + implicitly closed either by this function or by a subsequent + closedir). */ +# if @REPLACE_FDOPENDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fdopendir +# define fdopendir rpl_fdopendir +# endif +_GL_FUNCDECL_RPL (fdopendir, DIR *, + (int fd) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1)); +_GL_CXXALIAS_RPL (fdopendir, DIR *, (int fd)); +# else +# if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@ || __GNUC__ >= 11 +_GL_FUNCDECL_SYS (fdopendir, DIR *, + (int fd) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1)); +# endif +_GL_CXXALIAS_SYS (fdopendir, DIR *, (int fd)); +# endif +_GL_CXXALIASWARN (fdopendir); +#else +# if @GNULIB_CLOSEDIR@ && __GNUC__ >= 11 && !defined fdopendir +/* For -Wmismatched-dealloc: Associate fdopendir with closedir or + rpl_closedir. */ +_GL_FUNCDECL_SYS (fdopendir, DIR *, + (int fd) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (closedir, 1)); +# endif +# if defined GNULIB_POSIXCHECK +# undef fdopendir +# if HAVE_RAW_DECL_FDOPENDIR +_GL_WARN_ON_USE (fdopendir, "fdopendir is unportable - " + "use gnulib module fdopendir for portability"); +# endif +# endif +#endif + +#if @GNULIB_SCANDIR@ +/* Scan the directory DIR, calling FILTER on each directory entry. + Entries for which FILTER returns nonzero are individually malloc'd, + sorted using qsort with CMP, and collected in a malloc'd array in + *NAMELIST. Returns the number of entries selected, or -1 on error. */ +# if !@HAVE_SCANDIR@ +_GL_FUNCDECL_SYS (scandir, int, + (const char *dir, struct dirent ***namelist, + int (*filter) (const struct dirent *), + int (*cmp) (const struct dirent **, const struct dirent **)) + _GL_ARG_NONNULL ((1, 2, 4))); +# endif +/* Need to cast, because on glibc systems, the fourth parameter is + int (*cmp) (const void *, const void *). */ +_GL_CXXALIAS_SYS_CAST (scandir, int, + (const char *dir, struct dirent ***namelist, + int (*filter) (const struct dirent *), + int (*cmp) (const struct dirent **, const struct dirent **))); +_GL_CXXALIASWARN (scandir); +#elif defined GNULIB_POSIXCHECK +# undef scandir +# if HAVE_RAW_DECL_SCANDIR +_GL_WARN_ON_USE (scandir, "scandir is unportable - " + "use gnulib module scandir for portability"); +# endif +#endif + +#if @GNULIB_ALPHASORT@ +/* Compare two 'struct dirent' entries alphabetically. */ +# if !@HAVE_ALPHASORT@ +_GL_FUNCDECL_SYS (alphasort, int, + (const struct dirent **, const struct dirent **) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +# endif +/* Need to cast, because on glibc systems, the parameters are + (const void *, const void *). */ +_GL_CXXALIAS_SYS_CAST (alphasort, int, + (const struct dirent **, const struct dirent **)); +_GL_CXXALIASWARN (alphasort); +#elif defined GNULIB_POSIXCHECK +# undef alphasort +# if HAVE_RAW_DECL_ALPHASORT +_GL_WARN_ON_USE (alphasort, "alphasort is unportable - " + "use gnulib module alphasort for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_DIRENT_H */ +#endif /* _@GUARD_PREFIX@_DIRENT_H */ diff --git a/lib/dirfd.c b/lib/dirfd.c new file mode 100644 index 0000000..4104683 --- /dev/null +++ b/lib/dirfd.c @@ -0,0 +1,98 @@ +/* dirfd.c -- return the file descriptor associated with an open DIR* + + Copyright (C) 2001, 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 Jim Meyering. */ + +#include + +#include +#include + +#ifdef __KLIBC__ +# include +# include + +static struct dirp_fd_list +{ + DIR *dirp; + int fd; + struct dirp_fd_list *next; +} *dirp_fd_start = NULL; + +/* Register fd associated with dirp to dirp_fd_list. */ +int +_gl_register_dirp_fd (int fd, DIR *dirp) +{ + struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd); + if (!new_dirp_fd) + return -1; + + new_dirp_fd->dirp = dirp; + new_dirp_fd->fd = fd; + new_dirp_fd->next = dirp_fd_start; + + dirp_fd_start = new_dirp_fd; + + return 0; +} + +/* Unregister fd from dirp_fd_list with closing it */ +void +_gl_unregister_dirp_fd (int fd) +{ + struct dirp_fd_list *dirp_fd; + struct dirp_fd_list *dirp_fd_prev; + + for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd; + dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next) + { + if (dirp_fd->fd == fd) + { + if (dirp_fd_prev) + dirp_fd_prev->next = dirp_fd->next; + else /* dirp_fd == dirp_fd_start */ + dirp_fd_start = dirp_fd_start->next; + + close (fd); + free (dirp_fd); + break; + } + } +} +#endif + +int +dirfd (DIR *dir_p) +{ + int fd = DIR_TO_FD (dir_p); + if (fd == -1) +#ifndef __KLIBC__ + errno = ENOTSUP; +#else + { + struct dirp_fd_list *dirp_fd; + + for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next) + if (dirp_fd->dirp == dir_p) + return dirp_fd->fd; + + errno = EINVAL; + } +#endif + + return fd; +} diff --git a/lib/dirname-lgpl.c b/lib/dirname-lgpl.c new file mode 100644 index 0000000..d54f6a9 --- /dev/null +++ b/lib/dirname-lgpl.c @@ -0,0 +1,86 @@ +/* dirname.c -- return all but the last element in a file name + + Copyright (C) 1990, 1998, 2000-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 . */ + +#include + +#include "dirname.h" + +#include +#include + +/* Return the length of the prefix of FILE that will be used by + dir_name. If FILE is in the working directory, this returns zero + even though 'dir_name (FILE)' will return ".". Works properly even + if there are trailing slashes (by effectively ignoring them). */ + +size_t +dir_len (char const *file) +{ + size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file); + size_t length; + + /* Advance prefix_length beyond important leading slashes. */ + prefix_length += (prefix_length != 0 + ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE + && ISSLASH (file[prefix_length])) + : (ISSLASH (file[0]) + ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT + && ISSLASH (file[1]) && ! ISSLASH (file[2]) + ? 2 : 1)) + : 0)); + + /* Strip the basename and any redundant slashes before it. */ + for (length = last_component (file) - file; + prefix_length < length; length--) + if (! ISSLASH (file[length - 1])) + break; + return length; +} + + +/* In general, we can't use the builtin 'dirname' function if available, + since it has different meanings in different environments. + In some environments the builtin 'dirname' modifies its argument. + + Return the leading directories part of FILE, allocated with malloc. + Works properly even if there are trailing slashes (by effectively + ignoring them). Return NULL on failure. + + If lstat (FILE) would succeed, then { chdir (dir_name (FILE)); + lstat (base_name (FILE)); } will access the same file. Likewise, + if the sequence { chdir (dir_name (FILE)); + rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE + to "foo" in the same directory FILE was in. */ + +char * +mdir_name (char const *file) +{ + size_t length = dir_len (file); + bool append_dot = (length == 0 + || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE + && length == FILE_SYSTEM_PREFIX_LEN (file) + && file[2] != '\0' && ! ISSLASH (file[2]))); + char *dir = malloc (length + append_dot + 1); + if (!dir) + return NULL; + memcpy (dir, file, length); + if (append_dot) + dir[length++] = '.'; + dir[length] = '\0'; + return dir; +} diff --git a/lib/dirname.c b/lib/dirname.c new file mode 100644 index 0000000..3d2aaf1 --- /dev/null +++ b/lib/dirname.c @@ -0,0 +1,38 @@ +/* dirname.c -- return all but the last element in a file name + + 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 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 "dirname.h" + +#include +#include +#include "xalloc.h" + +/* Just like mdir_name (dirname-lgpl.c), except, rather than + returning NULL upon malloc failure, here, we report the + "memory exhausted" condition and exit. */ + +char * +dir_name (char const *file) +{ + char *result = mdir_name (file); + if (!result) + xalloc_die (); + return result; +} diff --git a/lib/dirname.h b/lib/dirname.h new file mode 100644 index 0000000..e18a97e --- /dev/null +++ b/lib/dirname.h @@ -0,0 +1,54 @@ +/* Take file names apart into directory and base names. + + 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 DIRNAME_H_ +# define DIRNAME_H_ 1 + +# include +# include +# include "filename.h" +# include "basename-lgpl.h" + +# ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if GNULIB_DIRNAME +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) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; +size_t dir_len (char const *file) _GL_ATTRIBUTE_PURE; + +bool strip_trailing_slashes (char *file); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* not DIRNAME_H_ */ diff --git a/lib/dup-safer-flag.c b/lib/dup-safer-flag.c new file mode 100644 index 0000000..f87792a --- /dev/null +++ b/lib/dup-safer-flag.c @@ -0,0 +1,38 @@ +/* Duplicate a file descriptor result, avoiding clobbering + STD{IN,OUT,ERR}_FILENO, with specific flags. + + Copyright (C) 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 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 Paul Eggert and Eric Blake. */ + +#include + +/* Specification. */ +#include "unistd-safer.h" + +#include +#include + +/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or + STDERR_FILENO. If FLAG contains O_CLOEXEC, behave like + fcntl(F_DUPFD_CLOEXEC) rather than fcntl(F_DUPFD). */ + +int +dup_safer_flag (int fd, int flag) +{ + return fcntl (fd, (flag & O_CLOEXEC) ? F_DUPFD_CLOEXEC : F_DUPFD, + STDERR_FILENO + 1); +} diff --git a/lib/dup-safer.c b/lib/dup-safer.c new file mode 100644 index 0000000..38ff74c --- /dev/null +++ b/lib/dup-safer.c @@ -0,0 +1,34 @@ +/* Invoke dup, but avoid some glitches. + + Copyright (C) 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 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 Paul Eggert. */ + +#include + +#include "unistd-safer.h" + +#include +#include + +/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or + STDERR_FILENO. */ + +int +dup_safer (int fd) +{ + return fcntl (fd, F_DUPFD, STDERR_FILENO + 1); +} diff --git a/lib/dup.c b/lib/dup.c new file mode 100644 index 0000000..17a9c58 --- /dev/null +++ b/lib/dup.c @@ -0,0 +1,92 @@ +/* Duplicate an open file descriptor. + + 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 . */ + +#include + +/* Specification. */ +#include + +#include + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +#endif + +#undef dup + +#if defined _WIN32 && !defined __CYGWIN__ +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static int +dup_nothrow (int fd) +{ + int result; + + TRY_MSVC_INVAL + { + result = _dup (fd); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EBADF; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define dup_nothrow _dup +# endif +#elif defined __KLIBC__ +# include +# include + +# include + +static int +dup_nothrow (int fd) +{ + int dupfd; + struct stat sbuf; + + dupfd = dup (fd); + if (dupfd == -1 && errno == ENOTSUP \ + && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) + { + char path[_MAX_PATH]; + + /* Get a path from fd */ + if (!__libc_Back_ioFHToPath (fd, path, sizeof (path))) + dupfd = open (path, O_RDONLY); + } + + return dupfd; +} +#else +# define dup_nothrow dup +#endif + +int +rpl_dup (int fd) +{ + int result = dup_nothrow (fd); +#if REPLACE_FCHDIR + if (result >= 0) + result = _gl_register_dup (fd, result); +#endif + return result; +} diff --git a/lib/dup2.c b/lib/dup2.c new file mode 100644 index 0000000..1c766ab --- /dev/null +++ b/lib/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/lib/dynarray.h b/lib/dynarray.h new file mode 100644 index 0000000..ca6439d --- /dev/null +++ b/lib/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/lib/eloop-threshold.h b/lib/eloop-threshold.h new file mode 100644 index 0000000..8b31457 --- /dev/null +++ b/lib/eloop-threshold.h @@ -0,0 +1,83 @@ +/* Threshold at which to diagnose ELOOP. Generic version. + Copyright (C) 2012-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 _ELOOP_THRESHOLD_H +#define _ELOOP_THRESHOLD_H 1 + +#include +#ifdef _LIBC +# include +# define _GL_ATTRIBUTE_CONST __attribute__ ((const)) +#else +# include +# include "minmax.h" +# define __sysconf sysconf +# if (!defined SYMLOOP_MAX \ + && ! (defined _SC_SYMLOOP_MAX && defined _POSIX_SYMLOOP_MAX)) +# define SYMLOOP_MAX 8 +# endif +#endif + +/* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic + links that can be reliably traversed in the resolution of a + pathname in the absence of a loop." This makes it a minimum that + we should certainly accept. But it leaves open the possibility + that more might sometimes work--just not "reliably". + + For example, Linux implements a complex policy whereby there is a + small limit on the number of direct symlink traversals (a symlink + to a symlink to a symlink), but larger limit on the total number of + symlink traversals overall. Hence the SYMLOOP_MAX number should be + the small one, but the limit library functions enforce on users + should be the larger one. + + So, we use the larger of the reported SYMLOOP_MAX (if any) and our + own constant MIN_ELOOP_THRESHOLD, below. This constant should be + large enough that it never rules out a file name and directory tree + that the underlying system (i.e. calls to 'open' et al) would + resolve successfully. It should be small enough that actual loops + are detected without a huge number of iterations. */ + +#ifndef MIN_ELOOP_THRESHOLD +# define MIN_ELOOP_THRESHOLD 40 +#endif + +/* Return the maximum number of symlink traversals to permit + before diagnosing ELOOP. */ +static inline unsigned int _GL_ATTRIBUTE_CONST +__eloop_threshold (void) +{ +#ifdef SYMLOOP_MAX + const int symloop_max = SYMLOOP_MAX; +#else + /* The function is marked 'const' even though we use memory and + call a function, because sysconf is required to return the + same value in every call and so it must always be safe to + call __eloop_threshold exactly once and reuse the value. */ + static long int sysconf_symloop_max; + if (sysconf_symloop_max == 0) + sysconf_symloop_max = __sysconf (_SC_SYMLOOP_MAX); + const unsigned int symloop_max = (sysconf_symloop_max <= 0 + ? _POSIX_SYMLOOP_MAX + : sysconf_symloop_max); +#endif + + return MAX (symloop_max, MIN_ELOOP_THRESHOLD); +} + +#endif /* eloop-threshold.h */ diff --git a/lib/errno.in.h b/lib/errno.in.h new file mode 100644 index 0000000..3ec1845 --- /dev/null +++ b/lib/errno.in.h @@ -0,0 +1,279 @@ +/* A POSIX-like . + + 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 . */ + +#ifndef _@GUARD_PREFIX@_ERRNO_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_ERRNO_H@ + +#ifndef _@GUARD_PREFIX@_ERRNO_H +#define _@GUARD_PREFIX@_ERRNO_H + + +/* On native Windows platforms, many macros are not defined. */ +# if defined _WIN32 && ! defined __CYGWIN__ + +/* These are the same values as defined by MSVC 10, for interoperability. */ + +# ifndef ENOMSG +# define ENOMSG 122 +# define GNULIB_defined_ENOMSG 1 +# endif + +# ifndef EIDRM +# define EIDRM 111 +# define GNULIB_defined_EIDRM 1 +# endif + +# ifndef ENOLINK +# define ENOLINK 121 +# define GNULIB_defined_ENOLINK 1 +# endif + +# ifndef EPROTO +# define EPROTO 134 +# define GNULIB_defined_EPROTO 1 +# endif + +# ifndef EBADMSG +# define EBADMSG 104 +# define GNULIB_defined_EBADMSG 1 +# endif + +# ifndef EOVERFLOW +# define EOVERFLOW 132 +# define GNULIB_defined_EOVERFLOW 1 +# endif + +# ifndef ENOTSUP +# define ENOTSUP 129 +# define GNULIB_defined_ENOTSUP 1 +# endif + +# ifndef ENETRESET +# define ENETRESET 117 +# define GNULIB_defined_ENETRESET 1 +# endif + +# ifndef ECONNABORTED +# define ECONNABORTED 106 +# define GNULIB_defined_ECONNABORTED 1 +# endif + +# ifndef ECANCELED +# define ECANCELED 105 +# define GNULIB_defined_ECANCELED 1 +# endif + +# ifndef EOWNERDEAD +# define EOWNERDEAD 133 +# define GNULIB_defined_EOWNERDEAD 1 +# endif + +# ifndef ENOTRECOVERABLE +# define ENOTRECOVERABLE 127 +# define GNULIB_defined_ENOTRECOVERABLE 1 +# endif + +# ifndef EINPROGRESS +# define EINPROGRESS 112 +# define EALREADY 103 +# define ENOTSOCK 128 +# define EDESTADDRREQ 109 +# define EMSGSIZE 115 +# define EPROTOTYPE 136 +# define ENOPROTOOPT 123 +# define EPROTONOSUPPORT 135 +# define EOPNOTSUPP 130 +# define EAFNOSUPPORT 102 +# define EADDRINUSE 100 +# define EADDRNOTAVAIL 101 +# define ENETDOWN 116 +# define ENETUNREACH 118 +# define ECONNRESET 108 +# define ENOBUFS 119 +# define EISCONN 113 +# define ENOTCONN 126 +# define ETIMEDOUT 138 +# define ECONNREFUSED 107 +# define ELOOP 114 +# define EHOSTUNREACH 110 +# define EWOULDBLOCK 140 +# define GNULIB_defined_ESOCK 1 +# endif + +# ifndef ETXTBSY +# define ETXTBSY 139 +# define ENODATA 120 /* not required by POSIX */ +# define ENOSR 124 /* not required by POSIX */ +# define ENOSTR 125 /* not required by POSIX */ +# define ETIME 137 /* not required by POSIX */ +# define EOTHER 131 /* not required by POSIX */ +# define GNULIB_defined_ESTREAMS 1 +# endif + +/* These are intentionally the same values as the WSA* error numbers, defined + in . */ +# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ +# define EPFNOSUPPORT 10046 /* not required by POSIX */ +# define ESHUTDOWN 10058 /* not required by POSIX */ +# define ETOOMANYREFS 10059 /* not required by POSIX */ +# define EHOSTDOWN 10064 /* not required by POSIX */ +# define EPROCLIM 10067 /* not required by POSIX */ +# define EUSERS 10068 /* not required by POSIX */ +# define EDQUOT 10069 +# define ESTALE 10070 +# define EREMOTE 10071 /* not required by POSIX */ +# define GNULIB_defined_EWINSOCK 1 + +# endif + + +/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros + EMULTIHOP, ENOLINK, EOVERFLOW are not defined. */ +# if @EMULTIHOP_HIDDEN@ +# define EMULTIHOP @EMULTIHOP_VALUE@ +# define GNULIB_defined_EMULTIHOP 1 +# endif +# if @ENOLINK_HIDDEN@ +# define ENOLINK @ENOLINK_VALUE@ +# define GNULIB_defined_ENOLINK 1 +# endif +# if @EOVERFLOW_HIDDEN@ +# define EOVERFLOW @EOVERFLOW_VALUE@ +# define GNULIB_defined_EOVERFLOW 1 +# endif + + +/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK, + EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined. + Likewise, on NonStop Kernel, EDQUOT is not defined. + Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151, + HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133. + + Note: When one of these systems defines some of these macros some day, + binaries will have to be recompiled so that they recognizes the new + errno values from the system. */ + +# ifndef ENOMSG +# define ENOMSG 2000 +# define GNULIB_defined_ENOMSG 1 +# endif + +# ifndef EIDRM +# define EIDRM 2001 +# define GNULIB_defined_EIDRM 1 +# endif + +# ifndef ENOLINK +# define ENOLINK 2002 +# define GNULIB_defined_ENOLINK 1 +# endif + +# ifndef EPROTO +# define EPROTO 2003 +# define GNULIB_defined_EPROTO 1 +# endif + +# ifndef EMULTIHOP +# define EMULTIHOP 2004 +# define GNULIB_defined_EMULTIHOP 1 +# endif + +# ifndef EBADMSG +# define EBADMSG 2005 +# define GNULIB_defined_EBADMSG 1 +# endif + +# ifndef EOVERFLOW +# define EOVERFLOW 2006 +# define GNULIB_defined_EOVERFLOW 1 +# endif + +# ifndef ENOTSUP +# define ENOTSUP 2007 +# define GNULIB_defined_ENOTSUP 1 +# endif + +# ifndef ENETRESET +# define ENETRESET 2011 +# define GNULIB_defined_ENETRESET 1 +# endif + +# ifndef ECONNABORTED +# define ECONNABORTED 2012 +# define GNULIB_defined_ECONNABORTED 1 +# endif + +# ifndef ESTALE +# define ESTALE 2009 +# define GNULIB_defined_ESTALE 1 +# endif + +# ifndef EDQUOT +# define EDQUOT 2010 +# define GNULIB_defined_EDQUOT 1 +# endif + +# ifndef ECANCELED +# define ECANCELED 2008 +# define GNULIB_defined_ECANCELED 1 +# endif + +/* On many platforms, the macros EOWNERDEAD and ENOTRECOVERABLE are not + defined. */ + +# ifndef EOWNERDEAD +# if defined __sun + /* Use the same values as defined for Solaris >= 8, for + interoperability. */ +# define EOWNERDEAD 58 +# define ENOTRECOVERABLE 59 +# 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 + /* Use the same values as defined by pthreads-win32, for + interoperability. */ +# define EOWNERDEAD 43 +# define ENOTRECOVERABLE 44 +# else + /* Use the same values as defined by MSVC 10, for + interoperability. */ +# define EOWNERDEAD 133 +# define ENOTRECOVERABLE 127 +# endif +# else +# define EOWNERDEAD 2013 +# define ENOTRECOVERABLE 2014 +# endif +# define GNULIB_defined_EOWNERDEAD 1 +# define GNULIB_defined_ENOTRECOVERABLE 1 +# endif + +# ifndef EILSEQ +# define EILSEQ 2015 +# define GNULIB_defined_EILSEQ 1 +# endif + +#endif /* _@GUARD_PREFIX@_ERRNO_H */ +#endif /* _@GUARD_PREFIX@_ERRNO_H */ diff --git a/lib/error.c b/lib/error.c new file mode 100644 index 0000000..272d45e --- /dev/null +++ b/lib/error.c @@ -0,0 +1,411 @@ +/* Error handler for noninteractive utilities + Copyright (C) 1990-1998, 2000-2007, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +/* Written by David MacKenzie . */ + +#if !_LIBC +# include +#endif + +#include "error.h" + +#include +#include +#include +#include + +#if !_LIBC && ENABLE_NLS +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif + +#ifdef _LIBC +# include +# include +# 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 +# include "unlocked-io.h" +#endif + +#ifndef _ +# define _(String) String +#endif + +/* If NULL, error will flush stdout, then print on stderr the program + name, a colon and a space. Otherwise, error will call this + function without parameters instead. */ +void (*error_print_progname) (void); + +/* This variable is incremented each time 'error' is called. */ +unsigned int error_message_count; + +#ifdef _LIBC +/* In the GNU C library, there is a predefined variable for this. */ + +# define program_name program_invocation_name +# include +# include +# include + +/* In GNU libc we want do not want to use the common name 'error' directly. + Instead make it a weak alias. */ +extern void __error (int status, int errnum, const char *message, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +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))); +# define error __error +# define error_at_line __error_at_line + +# include +# define fflush(s) _IO_fflush (s) +# undef putc +# define putc(c, fp) _IO_putc (c, fp) + +# include + +#else /* not _LIBC */ + +# include +# include + +# 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 +# endif + +/* The gnulib override of fcntl is not needed in this file. */ +# undef fcntl + +# 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 (int errnum, char *buf, size_t buflen); +# else +int strerror_r (int errnum, char *buf, size_t buflen); +# endif +# endif + +# define program_name getprogname () + +# if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r +# define __strerror_r strerror_r +# endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */ +#endif /* not _LIBC */ + +#if !_LIBC +/* Return non-zero if FD is open. */ +static int +is_open (int fd) +{ +# 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 + F_GETFL. */ + return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE; +# else +# ifndef F_GETFL +# error Please port fcntl to your platform +# endif + return 0 <= fcntl (fd, F_GETFL); +# endif +} +#endif + +static void +flush_stdout (void) +{ +#if !_LIBC + int stdout_fd; + +# if GNULIB_FREOPEN_SAFER + /* Use of gnulib's freopen-safer module normally ensures that + fileno (stdout) == 1 + whenever stdout is open. */ + stdout_fd = STDOUT_FILENO; +# else + /* POSIX states that fileno (stdout) after fclose is unspecified. But in + practice it is not a problem, because stdout is statically allocated and + the fd of a FILE stream is stored as a field in its allocated memory. */ + stdout_fd = fileno (stdout); +# endif + /* POSIX states that fflush (stdout) after fclose is unspecified; it + is safe in glibc, but not on all other platforms. fflush (NULL) + is always defined, but too draconian. */ + if (0 <= stdout_fd && is_open (stdout_fd)) +#endif + fflush (stdout); +} + +static void +print_errno_message (int errnum) +{ + char const *s; + +#if _LIBC || GNULIB_STRERROR_R_POSIX || defined HAVE_STRERROR_R + char errbuf[1024]; +# 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) + s = errbuf; + else + s = 0; +# endif +#else + s = strerror (errnum); +#endif + +#if !_LIBC + if (! s) + s = _("Unknown system error"); +#endif + +#if _LIBC + __fxprintf (NULL, ": %s", s); +#else + fprintf (stderr, ": %s", s); +#endif +} + +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) + { + size_t len = strlen (message) + 1; + wchar_t *wmessage = NULL; + mbstate_t st; + size_t res; + const char *tmp; + bool use_malloc = false; + + while (1) + { + if (__libc_use_alloca (len * sizeof (wchar_t))) + wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); + else + { + if (!use_malloc) + wmessage = NULL; + + wchar_t *p = (wchar_t *) realloc (wmessage, + len * sizeof (wchar_t)); + if (p == NULL) + { + free (wmessage); + fputws_unlocked (L"out of memory\n", stderr); + return; + } + wmessage = p; + use_malloc = true; + } + + memset (&st, '\0', sizeof (st)); + tmp = message; + + res = mbsrtowcs (wmessage, &tmp, len, &st); + if (res != len) + break; + + if (__builtin_expect (len >= SIZE_MAX / sizeof (wchar_t) / 2, 0)) + { + /* This really should not happen if everything is fine. */ + res = (size_t) -1; + break; + } + + len *= 2; + } + + if (res == (size_t) -1) + { + /* The string cannot be converted. */ + if (use_malloc) + { + free (wmessage); + use_malloc = false; + } + wmessage = (wchar_t *) L"???"; + } + + __vfwprintf (stderr, wmessage, args); + + if (use_malloc) + free (wmessage); + } + else +#endif + vfprintf (stderr, message, args); + + ++error_message_count; + if (errnum) + print_errno_message (errnum); +#if _LIBC + __fxprintf (NULL, "\n"); +#else + putc ('\n', stderr); +#endif + fflush (stderr); + if (status) + exit (status); +} + + +/* Print the program name and error message MESSAGE, which is a printf-style + format string with optional args. + If ERRNUM is nonzero, print its corresponding system error message. + Exit with status STATUS if it is nonzero. */ +void +error (int status, int errnum, const char *message, ...) +{ + va_list args; + +#if defined _LIBC && defined __libc_ptf_call + /* We do not want this call to be cut short by a thread + cancellation. Therefore disable cancellation for now. */ + int state = PTHREAD_CANCEL_ENABLE; + __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), + 0); +#endif + + flush_stdout (); +#ifdef _LIBC + _IO_flockfile (stderr); +#endif + if (error_print_progname) + (*error_print_progname) (); + else + { +#if _LIBC + __fxprintf (NULL, "%s: ", program_name); +#else + fprintf (stderr, "%s: ", program_name); +#endif + } + + va_start (args, message); + error_tail (status, errnum, message, args); + va_end (args); + +#ifdef _LIBC + _IO_funlockfile (stderr); +# ifdef __libc_ptf_call + __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); +# endif +#endif +} + +/* Sometimes we want to have at most one error per line. This + variable controls whether this mode is selected or not. */ +int error_one_per_line; + +void +error_at_line (int status, int errnum, const char *file_name, + unsigned int line_number, const char *message, ...) +{ + va_list args; + + if (error_one_per_line) + { + static const char *old_file_name; + static unsigned int old_line_number; + + if (old_line_number == line_number + && (file_name == old_file_name + || (old_file_name != NULL + && file_name != NULL + && strcmp (old_file_name, file_name) == 0))) + + /* Simply return and print nothing. */ + return; + + old_file_name = file_name; + old_line_number = line_number; + } + +#if defined _LIBC && defined __libc_ptf_call + /* We do not want this call to be cut short by a thread + cancellation. Therefore disable cancellation for now. */ + int state = PTHREAD_CANCEL_ENABLE; + __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), + 0); +#endif + + flush_stdout (); +#ifdef _LIBC + _IO_flockfile (stderr); +#endif + if (error_print_progname) + (*error_print_progname) (); + else + { +#if _LIBC + __fxprintf (NULL, "%s:", program_name); +#else + fprintf (stderr, "%s:", program_name); +#endif + } + +#if _LIBC + __fxprintf (NULL, file_name != NULL ? "%s:%u: " : " ", + file_name, line_number); +#else + 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); +# ifdef __libc_ptf_call + __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); +# endif +#endif +} + +#ifdef _LIBC +/* Make the weak alias. */ +# undef error +# undef error_at_line +weak_alias (__error, error) +weak_alias (__error_at_line, error_at_line) +#endif diff --git a/lib/error.h b/lib/error.h new file mode 100644 index 0000000..45ec2a5 --- /dev/null +++ b/lib/error.h @@ -0,0 +1,66 @@ +/* Declaration for error-reporting function + Copyright (C) 1995-1997, 2003, 2006, 2008-2022 Free Software Foundation, + Inc. + This file is part of 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 _ERROR_H +#define _ERROR_H 1 + +/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Print a message with 'fprintf (stderr, FORMAT, ...)'; + if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). + If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ + +extern void error (int __status, int __errnum, const char *__format, ...) +#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, ...) +#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 + function without parameters instead. */ +extern void (*error_print_progname) (void); + +/* This variable is incremented each time 'error' is called. */ +extern unsigned int error_message_count; + +/* Sometimes we want to have at most one error per line. This + variable controls whether this mode is selected or not. */ +extern int error_one_per_line; + +#ifdef __cplusplus +} +#endif + +#endif /* error.h */ diff --git a/lib/exitfail.c b/lib/exitfail.c new file mode 100644 index 0000000..84fb0ef --- /dev/null +++ b/lib/exitfail.c @@ -0,0 +1,24 @@ +/* Failure exit status + + Copyright (C) 2002-2003, 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 . */ + +#include + +#include "exitfail.h" + +#include + +int volatile exit_failure = EXIT_FAILURE; diff --git a/lib/exitfail.h b/lib/exitfail.h new file mode 100644 index 0000000..865f096 --- /dev/null +++ b/lib/exitfail.h @@ -0,0 +1,18 @@ +/* Failure exit status + + Copyright (C) 2002, 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 . */ + +extern int volatile exit_failure; diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c new file mode 100644 index 0000000..f036785 --- /dev/null +++ b/lib/fatal-signal.c @@ -0,0 +1,372 @@ +/* Emergency actions in case of a fatal signal. + Copyright (C) 2003-2004, 2006-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + 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 "fatal-signal.h" + +#include +#include +#include +#include + +#include "glthread/lock.h" +#include "thread-optim.h" +#include "sig-handler.h" + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + +/* ========================================================================= */ + + +/* The list of fatal signals. + These are those signals whose default action is to terminate the process + without a core dump, except + SIGKILL - because it cannot be caught, + SIGALRM SIGUSR1 SIGUSR2 SIGPOLL SIGIO SIGLOST - because applications + often use them for their own purpose, + SIGPROF SIGVTALRM - because they are used for profiling, + SIGSTKFLT - because it is more similar to SIGFPE, SIGSEGV, SIGBUS, + SIGSYS - because it is more similar to SIGABRT, SIGSEGV, + SIGPWR - because it of too special use, + SIGRTMIN...SIGRTMAX - because they are reserved for application use. + plus + SIGXCPU, SIGXFSZ - because they are quite similar to SIGTERM. */ + +static int fatal_signals[] = + { + /* ISO C 99 signals. */ +#ifdef SIGINT + SIGINT, +#endif +#ifdef SIGTERM + SIGTERM, +#endif + /* POSIX:2001 signals. */ +#ifdef SIGHUP + SIGHUP, +#endif +#ifdef SIGPIPE + SIGPIPE, +#endif + /* BSD signals. */ +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + /* Native Windows signals. */ +#ifdef SIGBREAK + SIGBREAK, +#endif + 0 + }; + +#define num_fatal_signals (SIZEOF (fatal_signals) - 1) + +/* Eliminate signals whose signal handler is SIG_IGN. */ + +static void +init_fatal_signals (void) +{ + /* This function is multithread-safe even without synchronization, because + if two threads execute it simultaneously, the fatal_signals[] array will + not change any more after the first of the threads has completed this + function. */ + static bool fatal_signals_initialized = false; + if (!fatal_signals_initialized) + { + size_t i; + + for (i = 0; i < num_fatal_signals; i++) + { + struct sigaction action; + + if (sigaction (fatal_signals[i], NULL, &action) >= 0 + && get_handler (&action) == SIG_IGN) + fatal_signals[i] = -1; + } + + fatal_signals_initialized = true; + } +} + + +/* ========================================================================= */ + + +typedef _GL_ASYNC_SAFE void (*action_t) (int sig); + +/* Type of an entry in the actions array. + The 'action' field is accessed from within the fatal_signal_handler(), + therefore we mark it as 'volatile'. */ +typedef struct +{ + volatile action_t action; +} +actions_entry_t; + +/* The registered cleanup actions. */ +static actions_entry_t static_actions[32]; +static actions_entry_t * volatile actions = static_actions; +static sig_atomic_t volatile actions_count = 0; +static size_t actions_allocated = SIZEOF (static_actions); + + +/* The saved signal handlers. + Size 32 would not be sufficient: On HP-UX, SIGXCPU = 33, SIGXFSZ = 34. */ +static struct sigaction saved_sigactions[64]; + + +/* Uninstall the handlers. */ +static _GL_ASYNC_SAFE void +uninstall_handlers (void) +{ + size_t i; + + for (i = 0; i < num_fatal_signals; i++) + if (fatal_signals[i] >= 0) + { + int sig = fatal_signals[i]; + if (saved_sigactions[sig].sa_handler == SIG_IGN) + saved_sigactions[sig].sa_handler = SIG_DFL; + sigaction (sig, &saved_sigactions[sig], NULL); + } +} + + +/* The signal handler. It gets called asynchronously. */ +static _GL_ASYNC_SAFE void +fatal_signal_handler (int sig) +{ + for (;;) + { + /* Get the last registered cleanup action, in a reentrant way. */ + action_t action; + size_t n = actions_count; + if (n == 0) + break; + n--; + actions_count = n; + action = actions[n].action; + /* Execute the action. */ + action (sig); + } + + /* Now execute the signal's default action. + If the signal being delivered was blocked, the re-raised signal would be + delivered when this handler returns. But the way we install this handler, + no signal is blocked, and the re-raised signal is delivered already + during raise(). */ + uninstall_handlers (); + raise (sig); +} + + +/* Install the handlers. */ +static void +install_handlers (void) +{ + size_t i; + struct sigaction action; + + action.sa_handler = &fatal_signal_handler; + /* If we get a fatal signal while executing fatal_signal_handler, enter + fatal_signal_handler recursively, since it is reentrant. Hence no + SA_RESETHAND. */ + action.sa_flags = SA_NODEFER; + sigemptyset (&action.sa_mask); + for (i = 0; i < num_fatal_signals; i++) + if (fatal_signals[i] >= 0) + { + int sig = fatal_signals[i]; + + if (!(sig < sizeof (saved_sigactions) / sizeof (saved_sigactions[0]))) + abort (); + sigaction (sig, &action, &saved_sigactions[sig]); + } +} + + +/* Lock that makes at_fatal_signal multi-thread safe. */ +gl_lock_define_initialized (static, at_fatal_signal_lock) + +/* Register a cleanup function to be executed when a catchable fatal signal + occurs. */ +int +at_fatal_signal (action_t action) +{ + bool mt = gl_multithreaded (); + + if (mt) gl_lock_lock (at_fatal_signal_lock); + + static bool cleanup_initialized = false; + if (!cleanup_initialized) + { + init_fatal_signals (); + install_handlers (); + cleanup_initialized = true; + } + + int ret = 0; + + if (actions_count == actions_allocated) + { + /* Extend the actions array. Note that we cannot use xrealloc(), + because then the cleanup() function could access an already + deallocated array. */ + actions_entry_t *old_actions = actions; + size_t old_actions_allocated = actions_allocated; + size_t new_actions_allocated = 2 * actions_allocated; + actions_entry_t *new_actions = + (actions_entry_t *) + malloc (new_actions_allocated * sizeof (actions_entry_t)); + if (new_actions == NULL) + { + ret = -1; + goto done; + } + + size_t k; + /* Don't use memcpy() here, because memcpy takes non-volatile arguments + and is therefore not guaranteed to complete all memory stores before + the next statement. */ + for (k = 0; k < old_actions_allocated; k++) + new_actions[k] = old_actions[k]; + actions = new_actions; + actions_allocated = new_actions_allocated; + /* Now we can free the old actions array. */ + /* No, we can't do that. If fatal_signal_handler is running in a + different thread and has already fetched the actions pointer (getting + old_actions) but not yet accessed its n-th element, that thread may + crash when accessing an element of the already freed old_actions + array. */ + #if 0 + if (old_actions != static_actions) + free (old_actions); + #endif + } + /* The two uses of 'volatile' in the types above (and ISO C 99 section + 5.1.2.3.(5)) ensure that we increment the actions_count only after + the new action has been written to the memory location + actions[actions_count]. */ + actions[actions_count].action = action; + actions_count++; + + done: + if (mt) gl_lock_unlock (at_fatal_signal_lock); + + return ret; +} + + +/* ========================================================================= */ + + +static sigset_t fatal_signal_set; + +static void +do_init_fatal_signal_set (void) +{ + size_t i; + + init_fatal_signals (); + + sigemptyset (&fatal_signal_set); + for (i = 0; i < num_fatal_signals; i++) + if (fatal_signals[i] >= 0) + sigaddset (&fatal_signal_set, fatal_signals[i]); +} + +/* Ensure that do_init_fatal_signal_set is called once only. */ +gl_once_define(static, fatal_signal_set_once) + +static void +init_fatal_signal_set (void) +{ + gl_once (fatal_signal_set_once, do_init_fatal_signal_set); +} + +/* Lock and counter that allow block_fatal_signals/unblock_fatal_signals pairs + to occur in different threads and even overlap in time. */ +gl_lock_define_initialized (static, fatal_signals_block_lock) +static unsigned int fatal_signals_block_counter = 0; + +/* Temporarily delay the catchable fatal signals. */ +void +block_fatal_signals (void) +{ + bool mt = gl_multithreaded (); + + if (mt) gl_lock_lock (fatal_signals_block_lock); + + if (fatal_signals_block_counter++ == 0) + { + init_fatal_signal_set (); + sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL); + } + + if (mt) gl_lock_unlock (fatal_signals_block_lock); +} + +/* Stop delaying the catchable fatal signals. */ +void +unblock_fatal_signals (void) +{ + bool mt = gl_multithreaded (); + + if (mt) gl_lock_lock (fatal_signals_block_lock); + + if (fatal_signals_block_counter == 0) + /* There are more calls to unblock_fatal_signals() than to + block_fatal_signals(). */ + abort (); + if (--fatal_signals_block_counter == 0) + { + init_fatal_signal_set (); + sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); + } + + if (mt) gl_lock_unlock (fatal_signals_block_lock); +} + + +unsigned int +get_fatal_signals (int signals[64]) +{ + init_fatal_signal_set (); + + { + int *p = signals; + size_t i; + + for (i = 0; i < num_fatal_signals; i++) + if (fatal_signals[i] >= 0) + *p++ = fatal_signals[i]; + return p - signals; + } +} + +const sigset_t * +get_fatal_signal_set (void) +{ + init_fatal_signal_set (); + return &fatal_signal_set; +} diff --git a/lib/fatal-signal.h b/lib/fatal-signal.h new file mode 100644 index 0000000..a784b58 --- /dev/null +++ b/lib/fatal-signal.h @@ -0,0 +1,96 @@ +/* Emergency actions in case of a fatal signal. + Copyright (C) 2003-2004, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + 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 _FATAL_SIGNAL_H +#define _FATAL_SIGNAL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* It is often useful to do some cleanup action when a usually fatal signal + terminates the process, like removing a temporary file or killing a + subprocess that may be stuck waiting for a device, pipe or network input. + Such signals are SIGHUP, SIGINT, SIGPIPE, SIGTERM, and possibly others. + The limitation of this facility is that it cannot work for SIGKILL. + + Signals with a SIG_IGN handler are considered to be non-fatal. The + functions in this file assume that when a SIG_IGN handler is installed + for a signal, it was installed before any functions in this file were + called and it stays so for the whole lifetime of the process. */ + +/* Register a cleanup function to be executed when a catchable fatal signal + occurs. + + Restrictions for the cleanup function: + - The cleanup function can do all kinds of system calls. It may also + modify (clobber) errno. + - It can also access application dependent memory locations and data + structures provided they are in a consistent state. One way to ensure + this is through block_fatal_signals()/unblock_fatal_signals(), see + below. Another - more tricky - way to ensure this is the careful use + of 'volatile'. + However, + - malloc() and similarly complex facilities are not safe to be called + because they are not guaranteed to be in a consistent state. + - Also, the cleanup function must not block the catchable fatal signals + and leave them blocked upon return. + + The cleanup function is executed asynchronously. It is unspecified + whether during its execution the catchable fatal signals are blocked + or not. + + Return 0 upon success, or -1 if there was a memory allocation problem. */ +extern int at_fatal_signal (_GL_ASYNC_SAFE void (*function) (int sig)); + + +/* Sometimes it is necessary to block the usually fatal signals while the + data structures being accessed by the cleanup action are being built or + reorganized. This is the case, for example, when a temporary file or + directory is created through mkstemp() or mkdtemp(), because these + functions create the temporary file or directory _before_ returning its + name to the application. */ + +/* Temporarily delay the catchable fatal signals. + The signals will be blocked (= delayed) until the next call to + unblock_fatal_signals(). If the signals are already blocked, a further + call to block_fatal_signals() has no effect. */ +extern void block_fatal_signals (void); + +/* Stop delaying the catchable fatal signals. */ +extern void unblock_fatal_signals (void); + + +/* Return the list of signals that block_fatal_signals/unblock_fatal_signals + would block or unblock. + Fills signals[0..count-1] and returns count. */ +extern unsigned int get_fatal_signals (int signals[64]); + +/* Return the list of signals that block_fatal_signals/unblock_fatal_signals + would block or unblock. */ +extern const sigset_t * get_fatal_signal_set (void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _FATAL_SIGNAL_H */ diff --git a/lib/fchdir.c b/lib/fchdir.c new file mode 100644 index 0000000..99e4aa8 --- /dev/null +++ b/lib/fchdir.c @@ -0,0 +1,206 @@ +/* fchdir replacement. + 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 3 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 +#include +#include +#include +#include +#include +#include + +#include "assure.h" +#include "filename.h" +#include "filenamecat.h" + +#ifndef REPLACE_OPEN_DIRECTORY +# define REPLACE_OPEN_DIRECTORY 0 +#endif + +/* This replacement assumes that a directory is not renamed while opened + through a file descriptor. + + FIXME: On mingw, this would be possible to enforce if we were to + also open a HANDLE to each directory currently visited by a file + descriptor, since mingw refuses to rename any in-use file system + object. */ + +/* Array of file descriptors opened. If REPLACE_OPEN_DIRECTORY or if it points + to a directory, it stores info about this directory. */ +typedef struct +{ + char *name; /* Absolute name of the directory, or NULL. */ + /* FIXME - add a DIR* member to make dirfd possible on mingw? */ +} dir_info_t; +static dir_info_t *dirs; +static size_t dirs_allocated; + +/* Try to ensure dirs has enough room for a slot at index fd; free any + contents already in that slot. Return false and set errno to + ENOMEM on allocation failure. */ +static bool +ensure_dirs_slot (size_t fd) +{ + if (fd < dirs_allocated) + free (dirs[fd].name); + else + { + size_t new_allocated; + dir_info_t *new_dirs; + + new_allocated = 2 * dirs_allocated + 1; + if (new_allocated <= fd) + new_allocated = fd + 1; + new_dirs = + (dirs != NULL + ? (dir_info_t *) realloc (dirs, new_allocated * sizeof *dirs) + : (dir_info_t *) malloc (new_allocated * sizeof *dirs)); + if (new_dirs == NULL) + return false; + memset (new_dirs + dirs_allocated, 0, + (new_allocated - dirs_allocated) * sizeof *dirs); + dirs = new_dirs; + dirs_allocated = new_allocated; + } + return true; +} + +/* Return an absolute name of DIR in malloc'd storage. + Upon failure, return NULL with errno set. */ +static char * +get_name (char const *dir) +{ + char *cwd; + char *result; + + if (IS_ABSOLUTE_FILE_NAME (dir)) + return strdup (dir); + + /* We often encounter "."; treat it as a special case. */ + cwd = getcwd (NULL, 0); + if (!cwd || (dir[0] == '.' && dir[1] == '\0')) + return cwd; + + result = mfile_name_concat (cwd, dir, NULL); + free (cwd); + return result; +} + +/* Hook into the gnulib replacements for open() and close() to keep track + of the open file descriptors. */ + +/* Close FD, cleaning up any fd to name mapping if fd was visiting a + directory. */ +void +_gl_unregister_fd (int fd) +{ + if (fd >= 0 && fd < dirs_allocated) + { + free (dirs[fd].name); + dirs[fd].name = NULL; + } +} + +/* Mark FD as visiting FILENAME. FD must be non-negative, and refer + to an open file descriptor. If REPLACE_OPEN_DIRECTORY is non-zero, + this should only be called if FD is visiting a directory. Close FD + and return -1 with errno set if there is insufficient memory to track + the directory name; otherwise return FD. */ +int +_gl_register_fd (int fd, const char *filename) +{ + struct stat statbuf; + + assure (0 <= fd); + if (REPLACE_OPEN_DIRECTORY + || (fstat (fd, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))) + { + if (!ensure_dirs_slot (fd) + || (dirs[fd].name = get_name (filename)) == NULL) + { + int saved_errno = errno; + close (fd); + errno = saved_errno; + return -1; + } + } + return fd; +} + +/* Mark NEWFD as a duplicate of OLDFD; useful from dup, dup2, dup3, + and fcntl. Both arguments must be valid and distinct file + descriptors. Close NEWFD and return -1 if OLDFD is tracking a + directory, but there is insufficient memory to track the same + directory in NEWFD; otherwise return NEWFD. */ +int +_gl_register_dup (int oldfd, int newfd) +{ + assure (0 <= oldfd && 0 <= newfd && oldfd != newfd); + if (oldfd < dirs_allocated && dirs[oldfd].name) + { + /* Duplicated a directory; must ensure newfd is allocated. */ + if (!ensure_dirs_slot (newfd) + || (dirs[newfd].name = strdup (dirs[oldfd].name)) == NULL) + { + int saved_errno = errno; + close (newfd); + errno = saved_errno; + newfd = -1; + } + } + else if (newfd < dirs_allocated) + { + /* Duplicated a non-directory; ensure newfd is cleared. */ + free (dirs[newfd].name); + dirs[newfd].name = NULL; + } + return newfd; +} + +/* If FD is currently visiting a directory, then return the name of + that directory. Otherwise, return NULL and set errno. */ +const char * +_gl_directory_name (int fd) +{ + if (0 <= fd && fd < dirs_allocated && dirs[fd].name != NULL) + return dirs[fd].name; + /* At this point, fd is either invalid, or open but not a directory. + If dup2 fails, errno is correctly EBADF. */ + if (0 <= fd) + { + if (dup2 (fd, fd) == fd) + errno = ENOTDIR; + } + else + errno = EBADF; + return NULL; +} + + +/* Implement fchdir() in terms of chdir(). */ + +int +fchdir (int fd) +{ + const char *name = _gl_directory_name (fd); + return name ? chdir (name) : -1; +} diff --git a/lib/fcntl.c b/lib/fcntl.c new file mode 100644 index 0000000..f9753c4 --- /dev/null +++ b/lib/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/lib/fcntl.in.h b/lib/fcntl.in.h new file mode 100644 index 0000000..3e0c302 --- /dev/null +++ b/lib/fcntl.in.h @@ -0,0 +1,441 @@ +/* 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 + + +#endif /* _@GUARD_PREFIX@_FCNTL_H */ +#endif /* _@GUARD_PREFIX@_FCNTL_H */ +#endif diff --git a/lib/fd-hook.c b/lib/fd-hook.c new file mode 100644 index 0000000..64a7a80 --- /dev/null +++ b/lib/fd-hook.c @@ -0,0 +1,116 @@ +/* Hook for making file descriptor functions close(), ioctl() extensible. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 "fd-hook.h" + +#include + +/* Currently, this entire code is only needed for the handling of sockets + on native Windows platforms. */ +#if WINDOWS_SOCKETS + +/* The first and last link in the doubly linked list. + Initially the list is empty. */ +static struct fd_hook anchor = { &anchor, &anchor, NULL, NULL }; + +int +execute_close_hooks (const struct fd_hook *remaining_list, gl_close_fn primary, + int fd) +{ + if (remaining_list == &anchor) + /* End of list reached. */ + return primary (fd); + else + return remaining_list->private_close_fn (remaining_list->private_next, + primary, fd); +} + +int +execute_all_close_hooks (gl_close_fn primary, int fd) +{ + return execute_close_hooks (anchor.private_next, primary, fd); +} + +int +execute_ioctl_hooks (const struct fd_hook *remaining_list, gl_ioctl_fn primary, + int fd, int request, void *arg) +{ + if (remaining_list == &anchor) + /* End of list reached. */ + return primary (fd, request, arg); + else + return remaining_list->private_ioctl_fn (remaining_list->private_next, + primary, fd, request, arg); +} + +int +execute_all_ioctl_hooks (gl_ioctl_fn primary, + int fd, int request, void *arg) +{ + return execute_ioctl_hooks (anchor.private_next, primary, fd, request, arg); +} + +void +register_fd_hook (close_hook_fn close_hook, ioctl_hook_fn ioctl_hook, struct fd_hook *link) +{ + if (close_hook == NULL) + close_hook = execute_close_hooks; + if (ioctl_hook == NULL) + ioctl_hook = execute_ioctl_hooks; + + if (link->private_next == NULL && link->private_prev == NULL) + { + /* Add the link to the doubly linked list. */ + link->private_next = anchor.private_next; + link->private_prev = &anchor; + link->private_close_fn = close_hook; + link->private_ioctl_fn = ioctl_hook; + anchor.private_next->private_prev = link; + anchor.private_next = link; + } + else + { + /* The link is already in use. */ + if (link->private_close_fn != close_hook + || link->private_ioctl_fn != ioctl_hook) + abort (); + } +} + +void +unregister_fd_hook (struct fd_hook *link) +{ + struct fd_hook *next = link->private_next; + struct fd_hook *prev = link->private_prev; + + if (next != NULL && prev != NULL) + { + /* The link is in use. Remove it from the doubly linked list. */ + prev->private_next = next; + next->private_prev = prev; + /* Clear the link, to mark it unused. */ + link->private_next = NULL; + link->private_prev = NULL; + link->private_close_fn = NULL; + link->private_ioctl_fn = NULL; + } +} + +#endif diff --git a/lib/fd-hook.h b/lib/fd-hook.h new file mode 100644 index 0000000..d6c4964 --- /dev/null +++ b/lib/fd-hook.h @@ -0,0 +1,119 @@ +/* Hook for making file descriptor functions close(), ioctl() extensible. + 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 . */ + + +#ifndef FD_HOOK_H +#define FD_HOOK_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Currently, this entire code is only needed for the handling of sockets + on native Windows platforms. */ +#if WINDOWS_SOCKETS + + +/* Type of function that closes FD. */ +typedef int (*gl_close_fn) (int fd); + +/* Type of function that applies a control request to FD. */ +typedef int (*gl_ioctl_fn) (int fd, int request, void *arg); + +/* An element of the list of file descriptor hooks. + In CLOS (Common Lisp Object System) speak, it consists of an "around" + method for the close() function and an "around" method for the ioctl() + function. + The fields of this structure are considered private. */ +struct fd_hook +{ + /* Doubly linked list. */ + struct fd_hook *private_next; + struct fd_hook *private_prev; + /* Function that treats the types of FD that it knows about and calls + execute_close_hooks (REMAINING_LIST, PRIMARY, FD) as a fallback. */ + int (*private_close_fn) (const struct fd_hook *remaining_list, + gl_close_fn primary, + int fd); + /* Function that treats the types of FD that it knows about and calls + execute_ioctl_hooks (REMAINING_LIST, PRIMARY, FD, REQUEST, ARG) as a + fallback. */ + int (*private_ioctl_fn) (const struct fd_hook *remaining_list, + gl_ioctl_fn primary, + int fd, int request, void *arg); +}; + +/* This type of function closes FD, applying special knowledge for the FD + types it knows about, and calls + execute_close_hooks (REMAINING_LIST, PRIMARY, FD) + for the other FD types. + In CLOS speak, REMAINING_LIST is the remaining list of "around" methods, + and PRIMARY is the "primary" method for close(). */ +typedef int (*close_hook_fn) (const struct fd_hook *remaining_list, + gl_close_fn primary, + int fd); + +/* Execute the close hooks in REMAINING_LIST, with PRIMARY as "primary" method. + Return 0 or -1, like close() would do. */ +extern int execute_close_hooks (const struct fd_hook *remaining_list, + gl_close_fn primary, + int fd); + +/* Execute all close hooks, with PRIMARY as "primary" method. + Return 0 or -1, like close() would do. */ +extern int execute_all_close_hooks (gl_close_fn primary, int fd); + +/* This type of function applies a control request to FD, applying special + knowledge for the FD types it knows about, and calls + execute_ioctl_hooks (REMAINING_LIST, PRIMARY, FD, REQUEST, ARG) + for the other FD types. + In CLOS speak, REMAINING_LIST is the remaining list of "around" methods, + and PRIMARY is the "primary" method for ioctl(). */ +typedef int (*ioctl_hook_fn) (const struct fd_hook *remaining_list, + gl_ioctl_fn primary, + int fd, int request, void *arg); + +/* Execute the ioctl hooks in REMAINING_LIST, with PRIMARY as "primary" method. + Return 0 or -1, like ioctl() would do. */ +extern int execute_ioctl_hooks (const struct fd_hook *remaining_list, + gl_ioctl_fn primary, + int fd, int request, void *arg); + +/* Execute all ioctl hooks, with PRIMARY as "primary" method. + Return 0 or -1, like ioctl() would do. */ +extern int execute_all_ioctl_hooks (gl_ioctl_fn primary, + int fd, int request, void *arg); + +/* Add a function pair to the list of file descriptor hooks. + CLOSE_HOOK and IOCTL_HOOK may be NULL, indicating no change. + The LINK variable points to a piece of memory which is guaranteed to be + accessible until the corresponding call to unregister_fd_hook. */ +extern void register_fd_hook (close_hook_fn close_hook, ioctl_hook_fn ioctl_hook, + struct fd_hook *link); + +/* Removes a hook from the list of file descriptor hooks. */ +extern void unregister_fd_hook (struct fd_hook *link); + + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* FD_HOOK_H */ diff --git a/lib/fd-safer-flag.c b/lib/fd-safer-flag.c new file mode 100644 index 0000000..2e07cb9 --- /dev/null +++ b/lib/fd-safer-flag.c @@ -0,0 +1,52 @@ +/* Adjust a file descriptor result so that it avoids clobbering + STD{IN,OUT,ERR}_FILENO, with specific flags. + + 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 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 Paul Eggert and Eric Blake. */ + +#include + +/* Specification. */ +#include "unistd-safer.h" + +#include +#include + +/* Return FD, unless FD would be a copy of standard input, output, or + error; in that case, return a duplicate of FD, closing FD. If FLAG + contains O_CLOEXEC, the returned FD will have close-on-exec + semantics. On failure to duplicate, close FD, set errno, and + return -1. Preserve errno if FD is negative, so that the caller + can always inspect errno when the returned value is negative. + + This function is usefully wrapped around functions that return file + descriptors, e.g., fd_safer_flag (open ("file", O_RDONLY | flag), flag). */ + +int +fd_safer_flag (int fd, int flag) +{ + if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) + { + int f = dup_safer_flag (fd, flag); + int e = errno; + close (fd); + errno = e; + fd = f; + } + + return fd; +} diff --git a/lib/fd-safer.c b/lib/fd-safer.c new file mode 100644 index 0000000..e37b7b3 --- /dev/null +++ b/lib/fd-safer.c @@ -0,0 +1,49 @@ +/* Return a safer copy of a file descriptor. + + 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 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 Paul Eggert. */ + +#include + +#include "unistd-safer.h" + +#include +#include + +/* Return FD, unless FD would be a copy of standard input, output, or + error; in that case, return a duplicate of FD, closing FD. On + failure to duplicate, close FD, set errno, and return -1. Preserve + errno if FD is negative, so that the caller can always inspect + errno when the returned value is negative. + + This function is usefully wrapped around functions that return file + descriptors, e.g., fd_safer (open ("file", O_RDONLY)). */ + +int +fd_safer (int fd) +{ + if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) + { + int f = dup_safer (fd); + int e = errno; + close (fd); + errno = e; + fd = f; + } + + return fd; +} diff --git a/lib/fdopendir.c b/lib/fdopendir.c new file mode 100644 index 0000000..c2b0e1e --- /dev/null +++ b/lib/fdopendir.c @@ -0,0 +1,249 @@ +/* provide a replacement fdopendir function + Copyright (C) 2004-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 */ + +#include + +#include + +#include +#include + +#if !HAVE_FDOPENDIR + +# include "openat.h" +# include "openat-priv.h" +# include "save-cwd.h" + +# if GNULIB_DIRENT_SAFER +# include "dirent--.h" +# endif + +# ifndef REPLACE_FCHDIR +# define REPLACE_FCHDIR 0 +# endif + +static DIR *fdopendir_with_dup (int, int, struct saved_cwd const *); +static DIR *fd_clone_opendir (int, struct saved_cwd const *); + +/* Replacement for POSIX fdopendir. + + First, try to simulate it via opendir ("/proc/self/fd/..."). Failing + that, simulate it by using fchdir metadata, or by doing + save_cwd/fchdir/opendir(".")/restore_cwd. + If either the save_cwd or the restore_cwd fails (relatively unlikely), + then give a diagnostic and exit nonzero. + + If successful, the resulting stream is based on FD in + implementations where streams are based on file descriptors and in + applications where no other thread or signal handler allocates or + frees file descriptors. In other cases, consult dirfd on the result + to find out whether FD is still being used. + + Otherwise, this function works just like POSIX fdopendir. + + W A R N I N G: + + Unlike other fd-related functions, this one places constraints on FD. + If this function returns successfully, FD is under control of the + dirent.h system, and the caller should not close or modify the state of + FD other than by the dirent.h functions. */ +# ifdef __KLIBC__ +# include + +DIR * +fdopendir (int fd) +{ + char path[_MAX_PATH]; + DIR *dirp; + + /* Get a path from fd */ + if (__libc_Back_ioFHToPath (fd, path, sizeof (path))) + return NULL; + + dirp = opendir (path); + if (!dirp) + return NULL; + + /* Unregister fd registered by opendir() */ + _gl_unregister_dirp_fd (dirfd (dirp)); + + /* Register our fd */ + if (_gl_register_dirp_fd (fd, dirp)) + { + int saved_errno = errno; + + closedir (dirp); + + errno = saved_errno; + + dirp = NULL; + } + + return dirp; +} +# else +DIR * +fdopendir (int fd) +{ + DIR *dir = fdopendir_with_dup (fd, -1, NULL); + + if (! REPLACE_FCHDIR && ! dir) + { + int saved_errno = errno; + if (EXPECTED_ERRNO (saved_errno)) + { + struct saved_cwd cwd; + if (save_cwd (&cwd) != 0) + openat_save_fail (errno); + dir = fdopendir_with_dup (fd, -1, &cwd); + saved_errno = errno; + free_cwd (&cwd); + errno = saved_errno; + } + } + + return dir; +} +# endif + +/* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known + to be a dup of FD which is less than FD - 1 and which will be + closed by the caller and not otherwise used by the caller. This + function makes sure that FD is closed and all file descriptors less + than FD are open, and then calls fd_clone_opendir on a dup of FD. + That way, barring race conditions, fd_clone_opendir returns a + stream whose file descriptor is FD. + + If REPLACE_FCHDIR or CWD is null, use opendir ("/proc/self/fd/...", + falling back on fchdir metadata. Otherwise, CWD is a saved version + of the working directory; use fchdir/opendir(".")/restore_cwd(CWD). */ +static DIR * +fdopendir_with_dup (int fd, int older_dupfd, struct saved_cwd const *cwd) +{ + int dupfd = dup (fd); + if (dupfd < 0 && errno == EMFILE) + dupfd = older_dupfd; + if (dupfd < 0) + return NULL; + else + { + DIR *dir; + int saved_errno; + if (dupfd < fd - 1 && dupfd != older_dupfd) + { + dir = fdopendir_with_dup (fd, dupfd, cwd); + saved_errno = errno; + } + else + { + close (fd); + dir = fd_clone_opendir (dupfd, cwd); + saved_errno = errno; + if (! dir) + { + int fd1 = dup (dupfd); + if (fd1 != fd) + openat_save_fail (fd1 < 0 ? errno : EBADF); + } + } + + if (dupfd != older_dupfd) + close (dupfd); + errno = saved_errno; + return dir; + } +} + +/* Like fdopendir, except the result controls a clone of FD. It is + the caller's responsibility both to close FD and (if the result is + not null) to closedir the result. */ +static DIR * +fd_clone_opendir (int fd, struct saved_cwd const *cwd) +{ + if (REPLACE_FCHDIR || ! cwd) + { + DIR *dir = NULL; + int saved_errno = EOPNOTSUPP; + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) + { + dir = opendir (proc_file); + saved_errno = errno; + if (proc_file != buf) + free (proc_file); + } +# if REPLACE_FCHDIR + if (! dir && EXPECTED_ERRNO (saved_errno)) + { + char const *name = _gl_directory_name (fd); + DIR *dp = name ? opendir (name) : NULL; + + /* The caller has done an elaborate dance to arrange for opendir to + consume just the right file descriptor. If dirfd returns -1, + though, we're on a system like mingw where opendir does not + consume a file descriptor. Consume it via 'dup' instead. */ + if (dp && dirfd (dp) < 0) + dup (fd); + + return dp; + } +# endif + errno = saved_errno; + return dir; + } + else + { + if (fchdir (fd) != 0) + return NULL; + else + { + DIR *dir = opendir ("."); + int saved_errno = errno; + if (restore_cwd (cwd) != 0) + openat_restore_fail (errno); + errno = saved_errno; + return dir; + } + } +} + +#else /* HAVE_FDOPENDIR */ + +# include +# include + +# undef fdopendir + +/* Like fdopendir, but work around GNU/Hurd bug by validating FD. */ + +DIR * +rpl_fdopendir (int fd) +{ + struct stat st; + if (fstat (fd, &st)) + return NULL; + if (!S_ISDIR (st.st_mode)) + { + errno = ENOTDIR; + return NULL; + } + return fdopendir (fd); +} + +#endif /* HAVE_FDOPENDIR */ diff --git a/lib/fflush.c b/lib/fflush.c new file mode 100644 index 0000000..69511cd --- /dev/null +++ b/lib/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/lib/file-set.c b/lib/file-set.c new file mode 100644 index 0000000..3270551 --- /dev/null +++ b/lib/file-set.c @@ -0,0 +1,74 @@ +/* Specialized functions to manipulate a set of files. + 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 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 */ + +#include +#include "file-set.h" + +#include "hash-triple.h" +#include "xalloc.h" + +/* Record file, FILE, and dev/ino from *STATS, in the hash table, HT. + If HT is NULL, return immediately. + If memory allocation fails, exit immediately. */ +void +record_file (Hash_table *ht, char const *file, struct stat const *stats) +{ + struct F_triple *ent; + + if (ht == NULL) + return; + + ent = xmalloc (sizeof *ent); + ent->name = xstrdup (file); + ent->st_ino = stats->st_ino; + ent->st_dev = stats->st_dev; + + { + struct F_triple *ent_from_table = hash_insert (ht, ent); + if (ent_from_table == NULL) + { + /* Insertion failed due to lack of memory. */ + xalloc_die (); + } + + if (ent_from_table != ent) + { + /* There was already a matching entry in the table, so ENT was + not inserted. Free it. */ + triple_free (ent); + } + } +} + +/* Return true if there is an entry in hash table, HT, + for the file described by FILE and STATS. */ +bool +seen_file (Hash_table const *ht, char const *file, + struct stat const *stats) +{ + struct F_triple new_ent; + + if (ht == NULL) + return false; + + new_ent.name = (char *) file; + new_ent.st_ino = stats->st_ino; + new_ent.st_dev = stats->st_dev; + + return !!hash_lookup (ht, &new_ent); +} diff --git a/lib/file-set.h b/lib/file-set.h new file mode 100644 index 0000000..dc9d0ae --- /dev/null +++ b/lib/file-set.h @@ -0,0 +1,33 @@ +/* Very specialized set-of-files code. + 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 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, 2007. */ + +#include +#include +#include + +#include "hash.h" + +extern void record_file (Hash_table *ht, char const *file, + struct stat const *stats) +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__ + __attribute__ ((__nonnull__ (2, 3))) +#endif +; + +extern bool seen_file (Hash_table const *ht, char const *file, + struct stat const *stats); diff --git a/lib/filename.h b/lib/filename.h new file mode 100644 index 0000000..ab77ca2 --- /dev/null +++ b/lib/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/lib/filenamecat-lgpl.c b/lib/filenamecat-lgpl.c new file mode 100644 index 0000000..56981aa --- /dev/null +++ b/lib/filenamecat-lgpl.c @@ -0,0 +1,90 @@ +/* Concatenate two arbitrary file names. + + Copyright (C) 1996-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. */ + +#include + +/* Specification. */ +#include "filenamecat.h" + +#include +#include + +#include "basename-lgpl.h" +#include "filename.h" + +#if ! HAVE_MEMPCPY && ! defined mempcpy +# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) +#endif + +/* Concatenate two file name components, DIR and BASE, in + newly-allocated storage and return the result. + The resulting file name F is such that the commands "ls F" and "(cd + DIR; ls ./BASE)" refer to the same file. If necessary, put + a separator between DIR and BASE in the result. Typically this + separator is "/", but in rare cases it might be ".". + In any case, if BASE_IN_RESULT is non-NULL, set + *BASE_IN_RESULT to point to the copy of BASE at the end of the + returned concatenation. + + If malloc fails, return NULL with errno set. */ + +char * +mfile_name_concat (char const *dir, char const *base, char **base_in_result) +{ + char const *dirbase = last_component (dir); + size_t dirbaselen = base_len (dirbase); + size_t dirlen = dirbase - dir + dirbaselen; + size_t baselen = strlen (base); + char sep = '\0'; + if (dirbaselen) + { + /* DIR is not a file system root, so separate with / if needed. */ + if (! ISSLASH (dir[dirlen - 1]) && ! ISSLASH (*base)) + sep = '/'; + } + else if (ISSLASH (*base)) + { + /* DIR is a file system root and BASE begins with a slash, so + separate with ".". For example, if DIR is "/" and BASE is + "/foo" then return "/./foo", as "//foo" would be wrong on + some POSIX systems. A fancier algorithm could omit "." in + some cases but is not worth the trouble. */ + sep = '.'; + } + + char *p_concat = malloc (dirlen + (sep != '\0') + baselen + 1); + if (p_concat == NULL) + return NULL; + + { + char *p; + + p = mempcpy (p_concat, dir, dirlen); + *p = sep; + p += sep != '\0'; + + if (base_in_result) + *base_in_result = p; + + p = mempcpy (p, base, baselen); + *p = '\0'; + } + + return p_concat; +} diff --git a/lib/filenamecat.h b/lib/filenamecat.h new file mode 100644 index 0000000..f11bd28 --- /dev/null +++ b/lib/filenamecat.h @@ -0,0 +1,32 @@ +/* Concatenate two arbitrary file names. + + Copyright (C) 1996-1997, 2003, 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 Jim Meyering. */ + +#include + +#if GNULIB_FILENAMECAT +char *file_name_concat (char const *dir, char const *base, + char **base_in_result) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; +#endif + +char *mfile_name_concat (char const *dir, char const *base, + char **base_in_result) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; diff --git a/lib/findprog-in.c b/lib/findprog-in.c new file mode 100644 index 0000000..72a05db --- /dev/null +++ b/lib/findprog-in.c @@ -0,0 +1,399 @@ +/* Locating a program in a given path. + Copyright (C) 2001-2004, 2006-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2001, 2019. + + 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 "findprog.h" + +#include +#include +#include +#include +#include +#include + +#include "filename.h" +#include "concat-filename.h" + +#if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ + /* Native Windows, OS/2, DOS */ +# define NATIVE_SLASH '\\' +#else + /* Unix */ +# define NATIVE_SLASH '/' +#endif + +/* Separator in PATH like lists of pathnames. */ +#if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ + /* Native Windows, OS/2, DOS */ +# define PATH_SEPARATOR ';' +#else + /* Unix */ +# define PATH_SEPARATOR ':' +#endif + +/* The list of suffixes that the execlp/execvp function tries when searching + for the program. */ +static const char * const suffixes[] = + { + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + "", ".com", ".exe", ".bat", ".cmd" + /* Note: Files without any suffix are not considered executable. */ + /* Note: The cmd.exe program does a different lookup: It searches according + to the PATHEXT environment variable. + See . + Also, it executes files ending in .bat and .cmd directly without letting + the kernel interpret the program file. */ + #elif defined __CYGWIN__ + "", ".exe", ".com" + #elif defined __EMX__ + "", ".exe" + #elif defined __DJGPP__ + "", ".com", ".exe", ".bat" + #else /* Unix */ + "" + #endif + }; + +const char * +find_in_given_path (const char *progname, const char *path, + const char *directory, bool optimize_for_exec) +{ + { + bool has_slash = false; + { + const char *p; + + for (p = progname; *p != '\0'; p++) + if (ISSLASH (*p)) + { + has_slash = true; + break; + } + } + if (has_slash) + { + /* If progname contains a slash, it is either absolute or relative to + the current directory. PATH is not used. */ + if (optimize_for_exec) + /* The execl/execv/execlp/execvp functions will try the various + suffixes anyway and fail if no executable is found. */ + return progname; + else + { + /* Try the various suffixes and see whether one of the files + with such a suffix is actually executable. */ + int failure_errno; + size_t i; + + const char *directory_as_prefix = + (directory != NULL && IS_RELATIVE_FILE_NAME (progname) + ? directory + : ""); + + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + const char *progbasename; + + { + const char *p; + + progbasename = progname; + for (p = progname; *p != '\0'; p++) + if (ISSLASH (*p)) + progbasename = p + 1; + } + + bool progbasename_has_dot = (strchr (progbasename, '.') != NULL); + #endif + + /* Try all platform-dependent suffixes. */ + failure_errno = ENOENT; + for (i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); i++) + { + const char *suffix = suffixes[i]; + + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + /* File names without a '.' are not considered executable, and + for file names with a '.' no additional suffix is tried. */ + if ((*suffix != '\0') != progbasename_has_dot) + #endif + { + /* Concatenate directory_as_prefix, progname, suffix. */ + char *progpathname = + concatenated_filename (directory_as_prefix, progname, + suffix); + + if (progpathname == NULL) + return NULL; /* errno is set here */ + + /* On systems which have the eaccess() system call, let's + use it. On other systems, let's hope that this program + is not installed setuid or setgid, so that it is ok to + call access() despite its design flaw. */ + if (eaccess (progpathname, X_OK) == 0) + { + /* Check that the progpathname does not point to a + directory. */ + struct stat statbuf; + + if (stat (progpathname, &statbuf) >= 0) + { + if (! S_ISDIR (statbuf.st_mode)) + { + /* Found! */ + if (strcmp (progpathname, progname) == 0) + { + free (progpathname); + return progname; + } + else + return progpathname; + } + + errno = EACCES; + } + } + + if (errno != ENOENT) + failure_errno = errno; + + free (progpathname); + } + } + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + if (failure_errno == ENOENT && !progbasename_has_dot) + { + /* In the loop above, we skipped suffix = "". Do this loop + round now, merely to provide a better errno than ENOENT. */ + + char *progpathname = + concatenated_filename (directory_as_prefix, progname, ""); + + if (progpathname == NULL) + return NULL; /* errno is set here */ + + if (eaccess (progpathname, X_OK) == 0) + { + struct stat statbuf; + + if (stat (progpathname, &statbuf) >= 0) + { + if (! S_ISDIR (statbuf.st_mode)) + errno = ENOEXEC; + else + errno = EACCES; + } + } + + failure_errno = errno; + + free (progpathname); + } + #endif + + errno = failure_errno; + return NULL; + } + } + } + + if (path == NULL) + /* If PATH is not set, the default search path is implementation dependent. + In practice, it is treated like an empty PATH. */ + path = ""; + + { + /* Make a copy, to prepare for destructive modifications. */ + char *path_copy = strdup (path); + if (path_copy == NULL) + return NULL; /* errno is set here */ + + int failure_errno; + char *path_rest; + char *cp; + + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + bool progname_has_dot = (strchr (progname, '.') != NULL); + #endif + + failure_errno = ENOENT; + for (path_rest = path_copy; ; path_rest = cp + 1) + { + const char *dir; + bool last; + char *dir_as_prefix_to_free; + const char *dir_as_prefix; + size_t i; + + /* Extract next directory in PATH. */ + dir = path_rest; + for (cp = path_rest; *cp != '\0' && *cp != PATH_SEPARATOR; cp++) + ; + last = (*cp == '\0'); + *cp = '\0'; + + /* Empty PATH components designate the current directory. */ + if (dir == cp) + dir = "."; + + /* Concatenate directory and dir. */ + if (directory != NULL && IS_RELATIVE_FILE_NAME (dir)) + { + dir_as_prefix_to_free = + concatenated_filename (directory, dir, NULL); + if (dir_as_prefix_to_free == NULL) + { + /* errno is set here. */ + failure_errno = errno; + goto failed; + } + dir_as_prefix = dir_as_prefix_to_free; + } + else + { + dir_as_prefix_to_free = NULL; + dir_as_prefix = dir; + } + + /* Try all platform-dependent suffixes. */ + for (i = 0; i < sizeof (suffixes) / sizeof (suffixes[0]); i++) + { + const char *suffix = suffixes[i]; + + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + /* File names without a '.' are not considered executable, and + for file names with a '.' no additional suffix is tried. */ + if ((*suffix != '\0') != progname_has_dot) + #endif + { + /* Concatenate dir_as_prefix, progname, and suffix. */ + char *progpathname = + concatenated_filename (dir_as_prefix, progname, suffix); + + if (progpathname == NULL) + { + /* errno is set here. */ + failure_errno = errno; + free (dir_as_prefix_to_free); + goto failed; + } + + /* On systems which have the eaccess() system call, let's + use it. On other systems, let's hope that this program + is not installed setuid or setgid, so that it is ok to + call access() despite its design flaw. */ + if (eaccess (progpathname, X_OK) == 0) + { + /* Check that the progpathname does not point to a + directory. */ + struct stat statbuf; + + if (stat (progpathname, &statbuf) >= 0) + { + if (! S_ISDIR (statbuf.st_mode)) + { + /* Found! */ + if (strcmp (progpathname, progname) == 0) + { + free (progpathname); + + /* Add the "./" prefix for real, that + concatenated_filename() optimized away. + This avoids a second PATH search when the + caller uses execl/execv/execlp/execvp. */ + progpathname = + (char *) malloc (2 + strlen (progname) + 1); + if (progpathname == NULL) + { + /* errno is set here. */ + failure_errno = errno; + free (dir_as_prefix_to_free); + goto failed; + } + progpathname[0] = '.'; + progpathname[1] = NATIVE_SLASH; + memcpy (progpathname + 2, progname, + strlen (progname) + 1); + } + + free (dir_as_prefix_to_free); + free (path_copy); + return progpathname; + } + + errno = EACCES; + } + } + + if (errno != ENOENT) + failure_errno = errno; + + free (progpathname); + } + } + #if defined _WIN32 && !defined __CYGWIN__ /* Native Windows */ + if (failure_errno == ENOENT && !progname_has_dot) + { + /* In the loop above, we skipped suffix = "". Do this loop + round now, merely to provide a better errno than ENOENT. */ + + char *progpathname = + concatenated_filename (dir_as_prefix, progname, ""); + + if (progpathname == NULL) + { + /* errno is set here. */ + failure_errno = errno; + free (dir_as_prefix_to_free); + goto failed; + } + + if (eaccess (progpathname, X_OK) == 0) + { + struct stat statbuf; + + if (stat (progpathname, &statbuf) >= 0) + { + if (! S_ISDIR (statbuf.st_mode)) + errno = ENOEXEC; + else + errno = EACCES; + } + } + + failure_errno = errno; + + free (progpathname); + } + #endif + + free (dir_as_prefix_to_free); + + if (last) + break; + } + + failed: + /* Not found in PATH. */ + free (path_copy); + + errno = failure_errno; + return NULL; + } +} diff --git a/lib/findprog.h b/lib/findprog.h new file mode 100644 index 0000000..e47acc5 --- /dev/null +++ b/lib/findprog.h @@ -0,0 +1,77 @@ +/* Locating a program in PATH. + Copyright (C) 2001-2003, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + 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 _FINDPROG_H +#define _FINDPROG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Looks up a program in the PATH. + Attempts to determine the pathname that would be called by execlp/execvp + of PROGNAME. If successful, it returns a pathname containing a slash + (either absolute or relative to the current directory). Otherwise, it + returns PROGNAME unmodified. + Because of the latter case, callers should use execlp/execvp, not + execl/execv on the returned pathname. + The returned string is freshly malloc()ed if it is != PROGNAME. */ +extern const char *find_in_path (const char *progname); + +/* Looks up a program in the given PATH-like string. + + The PATH argument consists of a list of directories, separated by ':' or + (on native Windows) by ';'. An empty PATH element designates the current + directory. A null PATH is equivalent to an empty PATH, that is, to the + singleton list that contains only the current directory. + + If DIRECTORY is not NULL, all relative filenames (i.e. PROGNAME when it + contains a slash, and the PATH elements) are considered relative to + DIRECTORY instead of relative to the current directory of this process. + + Determines the pathname that would be called by execlp/execvp of PROGNAME. + - If successful, it returns a pathname containing a slash (either absolute + or relative to the current directory). The returned string can be used + with either execl/execv or execlp/execvp. It is freshly malloc()ed if it + is != PROGNAME. + - Otherwise, it sets errno and returns NULL. + Specific errno values include: + - ENOENT: means that the program's file was not found. + - EACCES: means that the program's file cannot be accessed (due to some + issue with one of the ancestor directories) or lacks the execute + permissions. + - ENOMEM: means out of memory. + If OPTIMIZE_FOR_EXEC is true, the function saves some work, under the + assumption that the resulting pathname will not be accessed directly, + only through execl/execv or execlp/execvp. + + Here, a "slash" means: + - On POSIX systems excluding Cygwin: a '/', + - On Windows, OS/2, DOS platforms: a '/' or '\'. */ +extern const char *find_in_given_path (const char *progname, const char *path, + const char *directory, + bool optimize_for_exec); + + +#ifdef __cplusplus +} +#endif + +#endif /* _FINDPROG_H */ diff --git a/lib/flexmember.h b/lib/flexmember.h new file mode 100644 index 0000000..1545639 --- /dev/null +++ b/lib/flexmember.h @@ -0,0 +1,60 @@ +/* Sizes of structs with flexible array members. + + Copyright 2016-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 + . + + Written by Paul Eggert. */ + +#include + +/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below. + On older platforms without _Alignof, use a pessimistic bound that is + safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1. + On newer platforms, use _Alignof to get a tighter bound. */ + +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 +# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1)) +#else +# define FLEXALIGNOF(type) _Alignof (type) +#endif + +/* Yield a properly aligned upper bound on the size of a struct of + type TYPE with a flexible array member named MEMBER that is + followed by N bytes of other data. The result is suitable as an + argument to malloc. For example: + + struct s { int n; char d[FLEXIBLE_ARRAY_MEMBER]; }; + struct s *p = malloc (FLEXSIZEOF (struct s, d, n * sizeof (char))); + + FLEXSIZEOF (TYPE, MEMBER, N) is not simply (sizeof (TYPE) + N), + since FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms. Nor is + it simply (offsetof (TYPE, MEMBER) + N), as that might yield a size + that causes malloc to yield a pointer that is not properly aligned + for TYPE; for example, if sizeof (int) == alignof (int) == 4, + malloc (offsetof (struct s, d) + 3 * sizeof (char)) is equivalent + to malloc (7) and might yield a pointer that is not a multiple of 4 + (which means the pointer is not properly aligned for struct s), + whereas malloc (FLEXSIZEOF (struct s, d, 3 * sizeof (char))) is + equivalent to malloc (8) and must yield a pointer that is a + multiple of 4. + + Yield a value less than N if and only if arithmetic overflow occurs. */ + +#define FLEXSIZEOF(type, member, n) \ + ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \ + & ~ (FLEXALIGNOF (type) - 1)) diff --git a/lib/float+.h b/lib/float+.h new file mode 100644 index 0000000..9ab4520 --- /dev/null +++ b/lib/float+.h @@ -0,0 +1,147 @@ +/* Supplemental information about the floating-point formats. + Copyright (C) 2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2007. + + 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 _FLOATPLUS_H +#define _FLOATPLUS_H + +#include +#include + +/* Number of bits in the mantissa of a floating-point number, including the + "hidden bit". */ +#if FLT_RADIX == 2 +# define FLT_MANT_BIT FLT_MANT_DIG +# define DBL_MANT_BIT DBL_MANT_DIG +# define LDBL_MANT_BIT LDBL_MANT_DIG +#elif FLT_RADIX == 4 +# define FLT_MANT_BIT (FLT_MANT_DIG * 2) +# define DBL_MANT_BIT (DBL_MANT_DIG * 2) +# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2) +#elif FLT_RADIX == 16 +# define FLT_MANT_BIT (FLT_MANT_DIG * 4) +# define DBL_MANT_BIT (DBL_MANT_DIG * 4) +# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4) +#endif + +/* Bit mask that can be used to mask the exponent, as an unsigned number. */ +#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7) +#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) +#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7) + +/* Number of bits used for the exponent of a floating-point number, including + the exponent's sign. */ +#define FLT_EXP_BIT \ + (FLT_EXP_MASK < 0x100 ? 8 : \ + FLT_EXP_MASK < 0x200 ? 9 : \ + FLT_EXP_MASK < 0x400 ? 10 : \ + FLT_EXP_MASK < 0x800 ? 11 : \ + FLT_EXP_MASK < 0x1000 ? 12 : \ + FLT_EXP_MASK < 0x2000 ? 13 : \ + FLT_EXP_MASK < 0x4000 ? 14 : \ + FLT_EXP_MASK < 0x8000 ? 15 : \ + FLT_EXP_MASK < 0x10000 ? 16 : \ + FLT_EXP_MASK < 0x20000 ? 17 : \ + FLT_EXP_MASK < 0x40000 ? 18 : \ + FLT_EXP_MASK < 0x80000 ? 19 : \ + FLT_EXP_MASK < 0x100000 ? 20 : \ + FLT_EXP_MASK < 0x200000 ? 21 : \ + FLT_EXP_MASK < 0x400000 ? 22 : \ + FLT_EXP_MASK < 0x800000 ? 23 : \ + FLT_EXP_MASK < 0x1000000 ? 24 : \ + FLT_EXP_MASK < 0x2000000 ? 25 : \ + FLT_EXP_MASK < 0x4000000 ? 26 : \ + FLT_EXP_MASK < 0x8000000 ? 27 : \ + FLT_EXP_MASK < 0x10000000 ? 28 : \ + FLT_EXP_MASK < 0x20000000 ? 29 : \ + FLT_EXP_MASK < 0x40000000 ? 30 : \ + FLT_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) +#define DBL_EXP_BIT \ + (DBL_EXP_MASK < 0x100 ? 8 : \ + DBL_EXP_MASK < 0x200 ? 9 : \ + DBL_EXP_MASK < 0x400 ? 10 : \ + DBL_EXP_MASK < 0x800 ? 11 : \ + DBL_EXP_MASK < 0x1000 ? 12 : \ + DBL_EXP_MASK < 0x2000 ? 13 : \ + DBL_EXP_MASK < 0x4000 ? 14 : \ + DBL_EXP_MASK < 0x8000 ? 15 : \ + DBL_EXP_MASK < 0x10000 ? 16 : \ + DBL_EXP_MASK < 0x20000 ? 17 : \ + DBL_EXP_MASK < 0x40000 ? 18 : \ + DBL_EXP_MASK < 0x80000 ? 19 : \ + DBL_EXP_MASK < 0x100000 ? 20 : \ + DBL_EXP_MASK < 0x200000 ? 21 : \ + DBL_EXP_MASK < 0x400000 ? 22 : \ + DBL_EXP_MASK < 0x800000 ? 23 : \ + DBL_EXP_MASK < 0x1000000 ? 24 : \ + DBL_EXP_MASK < 0x2000000 ? 25 : \ + DBL_EXP_MASK < 0x4000000 ? 26 : \ + DBL_EXP_MASK < 0x8000000 ? 27 : \ + DBL_EXP_MASK < 0x10000000 ? 28 : \ + DBL_EXP_MASK < 0x20000000 ? 29 : \ + DBL_EXP_MASK < 0x40000000 ? 30 : \ + DBL_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) +#define LDBL_EXP_BIT \ + (LDBL_EXP_MASK < 0x100 ? 8 : \ + LDBL_EXP_MASK < 0x200 ? 9 : \ + LDBL_EXP_MASK < 0x400 ? 10 : \ + LDBL_EXP_MASK < 0x800 ? 11 : \ + LDBL_EXP_MASK < 0x1000 ? 12 : \ + LDBL_EXP_MASK < 0x2000 ? 13 : \ + LDBL_EXP_MASK < 0x4000 ? 14 : \ + LDBL_EXP_MASK < 0x8000 ? 15 : \ + LDBL_EXP_MASK < 0x10000 ? 16 : \ + LDBL_EXP_MASK < 0x20000 ? 17 : \ + LDBL_EXP_MASK < 0x40000 ? 18 : \ + LDBL_EXP_MASK < 0x80000 ? 19 : \ + LDBL_EXP_MASK < 0x100000 ? 20 : \ + LDBL_EXP_MASK < 0x200000 ? 21 : \ + LDBL_EXP_MASK < 0x400000 ? 22 : \ + LDBL_EXP_MASK < 0x800000 ? 23 : \ + LDBL_EXP_MASK < 0x1000000 ? 24 : \ + LDBL_EXP_MASK < 0x2000000 ? 25 : \ + LDBL_EXP_MASK < 0x4000000 ? 26 : \ + LDBL_EXP_MASK < 0x8000000 ? 27 : \ + LDBL_EXP_MASK < 0x10000000 ? 28 : \ + LDBL_EXP_MASK < 0x20000000 ? 29 : \ + LDBL_EXP_MASK < 0x40000000 ? 30 : \ + LDBL_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) + +/* Number of bits used for a floating-point number: the mantissa (not + counting the "hidden bit", since it may or may not be explicit), the + exponent, and the sign. */ +#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1) +#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1) +#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1) + +/* Number of bytes used for a floating-point number. + This can be smaller than the 'sizeof'. For example, on i386 systems, + 'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence + LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but + sizeof (long double) = 12 or = 16. */ +#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) +#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) +#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) + +/* Verify that SIZEOF_FLT <= sizeof (float) etc. */ +typedef int verify_sizeof_flt[SIZEOF_FLT <= sizeof (float) ? 1 : -1]; +typedef int verify_sizeof_dbl[SIZEOF_DBL <= sizeof (double) ? 1 : - 1]; +typedef int verify_sizeof_ldbl[SIZEOF_LDBL <= sizeof (long double) ? 1 : - 1]; + +#endif /* _FLOATPLUS_H */ diff --git a/lib/float.c b/lib/float.c new file mode 100644 index 0000000..de85064 --- /dev/null +++ b/lib/float.c @@ -0,0 +1,33 @@ +/* Auxiliary definitions for . + Copyright (C) 2011-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 + +#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ +const union gl_long_double_union gl_LDBL_MAX = + { { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL } }; +#elif defined __i386__ +const union gl_long_double_union gl_LDBL_MAX = + { { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } }; +#else +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; +#endif diff --git a/lib/float.in.h b/lib/float.in.h new file mode 100644 index 0000000..a418376 --- /dev/null +++ b/lib/float.in.h @@ -0,0 +1,194 @@ +/* A correct . + + 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 . */ + +#ifndef _@GUARD_PREFIX@_FLOAT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_FLOAT_H@ + +#ifndef _@GUARD_PREFIX@_FLOAT_H +#define _@GUARD_PREFIX@_FLOAT_H + +/* 'long double' properties. */ + +#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) +/* Number of mantissa units, in base FLT_RADIX. */ +# undef LDBL_MANT_DIG +# define LDBL_MANT_DIG 64 +/* Number of decimal digits that is sufficient for representing a number. */ +# undef LDBL_DIG +# define LDBL_DIG 18 +/* x-1 where x is the smallest representable number > 1. */ +# undef LDBL_EPSILON +# define LDBL_EPSILON 1.0842021724855044340E-19L +/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ +# undef LDBL_MIN_EXP +# define LDBL_MIN_EXP (-16381) +/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ +# undef LDBL_MAX_EXP +# define LDBL_MAX_EXP 16384 +/* Minimum positive normalized number. */ +# undef LDBL_MIN +# define LDBL_MIN 3.3621031431120935063E-4932L +/* Maximum representable finite number. */ +# undef LDBL_MAX +# define LDBL_MAX 1.1897314953572317650E+4932L +/* Minimum e such that 10^e is in the range of normalized numbers. */ +# undef LDBL_MIN_10_EXP +# define LDBL_MIN_10_EXP (-4931) +/* Maximum e such that 10^e is in the range of representable finite numbers. */ +# undef LDBL_MAX_10_EXP +# define LDBL_MAX_10_EXP 4932 +#endif + +/* 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__ || defined __DragonFly__) +/* Number of mantissa units, in base FLT_RADIX. */ +# undef LDBL_MANT_DIG +# define LDBL_MANT_DIG 64 +/* Number of decimal digits that is sufficient for representing a number. */ +# undef LDBL_DIG +# define LDBL_DIG 18 +/* x-1 where x is the smallest representable number > 1. */ +# undef LDBL_EPSILON +# define LDBL_EPSILON 1.084202172485504434007452800869941711426e-19L /* 2^-63 */ +/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ +# undef LDBL_MIN_EXP +# define LDBL_MIN_EXP (-16381) +/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ +# undef LDBL_MAX_EXP +# define LDBL_MAX_EXP 16384 +/* Minimum positive normalized number. */ +# undef LDBL_MIN +# define LDBL_MIN 3.362103143112093506262677817321752E-4932L /* = 0x1p-16382L */ +/* Maximum representable finite number. */ +# undef LDBL_MAX +/* LDBL_MAX is represented as { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }. + But the largest literal that GCC allows us to write is + 0x0.fffffffffffff8p16384L = { 0xFFFFF800, 0xFFFFFFFF, 32766 }. + So, define it like this through a reference to an external variable + + const unsigned int LDBL_MAX[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }; + 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. */ +# undef LDBL_MIN_10_EXP +# define LDBL_MIN_10_EXP (-4931) +/* Maximum e such that 10^e is in the range of representable finite numbers. */ +# undef LDBL_MAX_10_EXP +# define LDBL_MAX_10_EXP 4932 +#endif + +/* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are + wrong. + On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */ +#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__ +# undef LDBL_MIN_EXP +# define LDBL_MIN_EXP DBL_MIN_EXP +# undef LDBL_MIN_10_EXP +# define LDBL_MIN_10_EXP DBL_MIN_10_EXP +# undef LDBL_MIN +# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ +#endif +#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ +# undef LDBL_MAX +/* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }. + It is not easy to define: + #define LDBL_MAX 1.79769313486231580793728971405302307166e308L + is too small, whereas + #define LDBL_MAX 1.79769313486231580793728971405302307167e308L + is too large. Apparently a bug in GCC decimal-to-binary conversion. + Also, I can't get values larger than + #define LDBL63 ((long double) (1ULL << 63)) + #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) + #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) + #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) + #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL) + which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }. + So, define it like this through a reference to an external variable + + const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; + extern const long double LDBL_MAX; + + or through a pointer cast + + #define LDBL_MAX \ + (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) + + 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 + +/* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. + On IRIX 6.5, with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_EPSILON + are wrong. */ +#if defined __sgi && (LDBL_MANT_DIG >= 106) +# undef LDBL_MANT_DIG +# define LDBL_MANT_DIG 106 +# if defined __GNUC__ +# undef LDBL_MIN_EXP +# define LDBL_MIN_EXP DBL_MIN_EXP +# undef LDBL_MIN_10_EXP +# define LDBL_MIN_10_EXP DBL_MIN_10_EXP +# undef LDBL_MIN +# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ +# undef LDBL_EPSILON +# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ +# endif +#endif + +#if @REPLACE_ITOLD@ +/* Pull in a function that fixes the 'int' to 'long double' conversion + of glibc 2.7. */ +extern +# ifdef __cplusplus +"C" +# endif +void _Qp_itoq (long double *, int); +static void (*_gl_float_fix_itold) (long double *, int) = _Qp_itoq; +#endif + +#endif /* _@GUARD_PREFIX@_FLOAT_H */ +#endif /* _@GUARD_PREFIX@_FLOAT_H */ diff --git a/lib/flock.c b/lib/flock.c new file mode 100644 index 0000000..28773d5 --- /dev/null +++ b/lib/flock.c @@ -0,0 +1,224 @@ +/* Emulate flock on platforms that lack it, primarily Windows and MinGW. + + This is derived from sqlite3 sources. + https://www.sqlite.org/src/finfo?name=src/os_win.c + https://www.sqlite.org/copyright.html + + Written by Richard W.M. Jones + + Copyright (C) 2008-2022 Free Software Foundation, Inc. + + This 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 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 this program. If not, see . */ + +#include +#include + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* LockFileEx */ +# define WIN32_LEAN_AND_MEAN +# include + +# include + +/* _get_osfhandle */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +/* Determine the current size of a file. Because the other braindead + * APIs we'll call need lower/upper 32 bit pairs, keep the file size + * like that too. + */ +static BOOL +file_size (HANDLE h, DWORD * lower, DWORD * upper) +{ + *lower = GetFileSize (h, upper); + return 1; +} + +/* LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. */ +# ifndef LOCKFILE_FAIL_IMMEDIATELY +# define LOCKFILE_FAIL_IMMEDIATELY 1 +# endif + +/* Acquire a lock. */ +static BOOL +do_lock (HANDLE h, int non_blocking, int exclusive) +{ + BOOL res; + DWORD size_lower, size_upper; + OVERLAPPED ovlp; + int flags = 0; + + /* We're going to lock the whole file, so get the file size. */ + res = file_size (h, &size_lower, &size_upper); + if (!res) + return 0; + + /* Start offset is 0, and also zero the remaining members of this struct. */ + memset (&ovlp, 0, sizeof ovlp); + + if (non_blocking) + flags |= LOCKFILE_FAIL_IMMEDIATELY; + if (exclusive) + flags |= LOCKFILE_EXCLUSIVE_LOCK; + + return LockFileEx (h, flags, 0, size_lower, size_upper, &ovlp); +} + +/* Unlock reader or exclusive lock. */ +static BOOL +do_unlock (HANDLE h) +{ + int res; + DWORD size_lower, size_upper; + + res = file_size (h, &size_lower, &size_upper); + if (!res) + return 0; + + return UnlockFile (h, 0, 0, size_lower, size_upper); +} + +/* Now our BSD-like flock operation. */ +int +flock (int fd, int operation) +{ + HANDLE h = (HANDLE) _get_osfhandle (fd); + DWORD res; + int non_blocking; + + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + non_blocking = operation & LOCK_NB; + operation &= ~LOCK_NB; + + switch (operation) + { + case LOCK_SH: + res = do_lock (h, non_blocking, 0); + break; + case LOCK_EX: + res = do_lock (h, non_blocking, 1); + break; + case LOCK_UN: + res = do_unlock (h); + break; + default: + errno = EINVAL; + return -1; + } + + /* Map Windows errors into Unix errnos. As usual MSDN fails to + * document the permissible error codes. + */ + if (!res) + { + DWORD err = GetLastError (); + switch (err) + { + /* This means someone else is holding a lock. */ + case ERROR_LOCK_VIOLATION: + errno = EAGAIN; + break; + + /* Out of memory. */ + case ERROR_NOT_ENOUGH_MEMORY: + errno = ENOMEM; + break; + + case ERROR_BAD_COMMAND: + errno = EINVAL; + break; + + /* Unlikely to be other errors, but at least don't lose the + * error code. + */ + default: + errno = err; + } + + return -1; + } + + return 0; +} + +#else /* !Windows */ + +# ifdef HAVE_STRUCT_FLOCK_L_TYPE +/* We know how to implement flock in terms of fcntl. */ + +# include + +# ifdef HAVE_UNISTD_H +# include +# endif + +# include +# include + +int +flock (int fd, int operation) +{ + int cmd, r; + struct flock fl; + + if (operation & LOCK_NB) + cmd = F_SETLK; + else + cmd = F_SETLKW; + operation &= ~LOCK_NB; + + memset (&fl, 0, sizeof fl); + fl.l_whence = SEEK_SET; + /* l_start & l_len are 0, which as a special case means "whole file". */ + + switch (operation) + { + case LOCK_SH: + fl.l_type = F_RDLCK; + break; + case LOCK_EX: + fl.l_type = F_WRLCK; + break; + case LOCK_UN: + fl.l_type = F_UNLCK; + break; + default: + errno = EINVAL; + return -1; + } + + r = fcntl (fd, cmd, &fl); + if (r == -1 && errno == EACCES) + errno = EAGAIN; + + return r; +} + +# else /* !HAVE_STRUCT_FLOCK_L_TYPE */ + +# error "This platform lacks flock function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib." + +# endif /* !HAVE_STRUCT_FLOCK_L_TYPE */ + +#endif /* !Windows */ diff --git a/lib/fnmatch.c b/lib/fnmatch.c new file mode 100644 index 0000000..b33a127 --- /dev/null +++ b/lib/fnmatch.c @@ -0,0 +1,361 @@ +/* Copyright (C) 1991-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 + +/* Enable GNU extensions in fnmatch.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#include + +#include +#include +#include +#include +#include +#if defined _LIBC || HAVE_ALLOCA +# include +#endif +#include +#include +#include +#include + +/* We need some of the locale data (the collation sequence information) + but there is no interface to get this information in general. Therefore + we support a correct implementation only in glibc. */ +#ifdef _LIBC +# include "../locale/localeinfo.h" +# include "../locale/coll-lookup.h" +# include + +# define CONCAT(a,b) __CONCAT(a,b) +# define btowc __btowc +# define iswctype __iswctype +# define mbsrtowcs __mbsrtowcs +# define mempcpy __mempcpy +# define strnlen __strnlen +# define towlower __towlower +# define wcscat __wcscat +# define wcslen __wcslen +# define wctype __wctype +# define wmemchr __wmemchr +# define wmempcpy __wmempcpy +# define fnmatch __fnmatch +extern int fnmatch (const char *pattern, const char *string, int flags); +#endif + +#ifdef _LIBC +# if __GNUC__ >= 7 +# define FALLTHROUGH __attribute__ ((__fallthrough__)) +# else +# define FALLTHROUGH ((void) 0) +# endif +#else +# include "attribute.h" +#endif + +#include +#include + +#ifdef _LIBC +typedef ptrdiff_t idx_t; +#else +# include "idx.h" +#endif + +/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ +#define NO_LEADING_PERIOD(flags) \ + ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD)) + +#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 +/* Just use malloc. */ +# define __libc_use_alloca(n) false +# undef alloca +# define alloca(n) malloc (n) +# endif +# define alloca_account(size, avar) ((avar) += (size), alloca (size)) +#endif + +/* Provide support for user-defined character classes, based on the functions + from ISO C 90 amendment 1. */ +#ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +#else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +#endif + +#define IS_CHAR_CLASS(string) wctype (string) + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +/* Global variable. */ +static int posixly_correct; + +/* Note that this evaluates C many times. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) +#define CHAR char +#define UCHAR unsigned char +#define INT int +#define FCT internal_fnmatch +#define EXT ext_match +#define END end_pattern +#define STRUCT fnmatch_struct +#define L_(CS) CS +#define BTOWC(C) btowc (C) +#define STRLEN(S) strlen (S) +#define STRCAT(D, S) strcat (D, S) +#define MEMPCPY(D, S, N) mempcpy (D, S, N) +#define MEMCHR(S, C, N) memchr (S, C, N) +#define WIDE_CHAR_VERSION 0 +#ifdef _LIBC +# include +# define FINDIDX findidx +#endif +#include "fnmatch_loop.c" + + +#define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c)) +#define CHAR wchar_t +#define UCHAR wint_t +#define INT wint_t +#define FCT internal_fnwmatch +#define EXT ext_wmatch +#define END end_wpattern +#define L_(CS) L##CS +#define BTOWC(C) (C) +#define STRLEN(S) wcslen (S) +#define STRCAT(D, S) wcscat (D, S) +#define MEMPCPY(D, S, N) wmempcpy (D, S, N) +#define MEMCHR(S, C, N) wmemchr (S, C, N) +#define WIDE_CHAR_VERSION 1 +#ifdef _LIBC +/* Change the name the header defines so it doesn't conflict with + the version included above. */ +# define findidx findidxwc +# include +# undef findidx +# define FINDIDX findidxwc +#endif + +#undef IS_CHAR_CLASS +/* We have to convert the wide character string in a multibyte string. But + we know that the character class names consist of alphanumeric characters + from the portable character set, and since the wide character encoding + for a member of the portable character set is the same code point as + its single-byte encoding, we can use a simplified method to convert the + string to a multibyte character string. */ +static wctype_t +is_char_class (const wchar_t *wcs) +{ + char s[CHAR_CLASS_MAX_LENGTH + 1]; + char *cp = s; + + do + { + /* Test for a printable character from the portable character set. */ +#ifdef _LIBC + if (*wcs < 0x20 || *wcs > 0x7e + || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) + return (wctype_t) 0; +#else + switch (*wcs) + { + case L' ': case L'!': case L'"': case L'#': case L'%': + case L'&': case L'\'': case L'(': case L')': case L'*': + case L'+': case L',': case L'-': case L'.': case L'/': + case L'0': case L'1': case L'2': case L'3': case L'4': + case L'5': case L'6': case L'7': case L'8': case L'9': + case L':': case L';': case L'<': case L'=': case L'>': + case L'?': + case L'A': case L'B': case L'C': case L'D': case L'E': + case L'F': case L'G': case L'H': case L'I': case L'J': + case L'K': case L'L': case L'M': case L'N': case L'O': + case L'P': case L'Q': case L'R': case L'S': case L'T': + case L'U': case L'V': case L'W': case L'X': case L'Y': + case L'Z': + case L'[': case L'\\': case L']': case L'^': case L'_': + case L'a': case L'b': case L'c': case L'd': case L'e': + case L'f': case L'g': case L'h': case L'i': case L'j': + case L'k': case L'l': case L'm': case L'n': case L'o': + case L'p': case L'q': case L'r': case L's': case L't': + case L'u': case L'v': case L'w': case L'x': case L'y': + case L'z': case L'{': case L'|': case L'}': case L'~': + break; + default: + return (wctype_t) 0; + } +#endif + + /* Avoid overrunning the buffer. */ + if (cp == s + CHAR_CLASS_MAX_LENGTH) + return (wctype_t) 0; + + *cp++ = (char) *wcs++; + } + while (*wcs != L'\0'); + + *cp = '\0'; + + return wctype (s); +} +#define IS_CHAR_CLASS(string) is_char_class (string) + +#include "fnmatch_loop.c" + + +int +fnmatch (const char *pattern, const char *string, int flags) +{ + if (__glibc_unlikely (MB_CUR_MAX != 1)) + { + mbstate_t ps; + size_t n; + const char *p; + wchar_t *wpattern_malloc = NULL; + wchar_t *wpattern; + wchar_t *wstring_malloc = NULL; + wchar_t *wstring; + size_t alloca_used = 0; + + /* Convert the strings into wide characters. */ + memset (&ps, '\0', sizeof (ps)); + p = pattern; + n = strnlen (pattern, 1024); + if (__glibc_likely (n < 1024)) + { + wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), + alloca_used); + n = mbsrtowcs (wpattern, &p, n + 1, &ps); + if (__glibc_unlikely (n == (size_t) -1)) + /* Something wrong. + XXX Do we have to set 'errno' to something which mbsrtows hasn't + already done? */ + return -1; + if (p) + { + memset (&ps, '\0', sizeof (ps)); + goto prepare_wpattern; + } + } + else + { + prepare_wpattern: + n = mbsrtowcs (NULL, &pattern, 0, &ps); + if (__glibc_unlikely (n == (size_t) -1)) + /* Something wrong. + XXX Do we have to set 'errno' to something which mbsrtows hasn't + already done? */ + return -1; + if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) + { + __set_errno (ENOMEM); + return -2; + } + wpattern_malloc = wpattern + = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t)); + assert (mbsinit (&ps)); + if (wpattern == NULL) + return -2; + (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps); + } + + assert (mbsinit (&ps)); + n = strnlen (string, 1024); + p = string; + if (__glibc_likely (n < 1024)) + { + wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), + alloca_used); + n = mbsrtowcs (wstring, &p, n + 1, &ps); + if (__glibc_unlikely (n == (size_t) -1)) + { + /* Something wrong. + XXX Do we have to set 'errno' to something which + mbsrtows hasn't already done? */ + free_return: + free (wpattern_malloc); + return -1; + } + if (p) + { + memset (&ps, '\0', sizeof (ps)); + goto prepare_wstring; + } + } + else + { + prepare_wstring: + n = mbsrtowcs (NULL, &string, 0, &ps); + if (__glibc_unlikely (n == (size_t) -1)) + /* Something wrong. + XXX Do we have to set 'errno' to something which mbsrtows hasn't + already done? */ + goto free_return; + if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) + { + free (wpattern_malloc); + __set_errno (ENOMEM); + return -2; + } + + wstring_malloc = wstring + = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t)); + if (wstring == NULL) + { + free (wpattern_malloc); + return -2; + } + assert (mbsinit (&ps)); + (void) mbsrtowcs (wstring, &string, n + 1, &ps); + } + + int res = internal_fnwmatch (wpattern, wstring, wstring + n, + flags & FNM_PERIOD, flags, NULL, + alloca_used); + + free (wstring_malloc); + free (wpattern_malloc); + + return res; + } + + return internal_fnmatch (pattern, string, string + strlen (string), + flags & FNM_PERIOD, flags, NULL, 0); +} + +#undef fnmatch +versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3); +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3) +strong_alias (__fnmatch, __fnmatch_old) +compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); +#endif +libc_hidden_ver (__fnmatch, fnmatch) diff --git a/lib/fnmatch.in.h b/lib/fnmatch.in.h new file mode 100644 index 0000000..a282c09 --- /dev/null +++ b/lib/fnmatch.in.h @@ -0,0 +1,110 @@ +/* Substitute for and wrapper around . + Copyright (C) 1991-1993, 1996-1999, 2001-2003, 2005, 2007, 2009-2022 Free + Software Foundation, Inc. + + This file is part of 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 _@GUARD_PREFIX@_FNMATCH_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_FNMATCH_H@ && !@REPLACE_FNMATCH@ +# @INCLUDE_NEXT@ @NEXT_FNMATCH_H@ +#endif + +#ifndef _@GUARD_PREFIX@_FNMATCH_H +#define _@GUARD_PREFIX@_FNMATCH_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. */ + +#if !@HAVE_FNMATCH_H@ || @REPLACE_FNMATCH@ + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to 'fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match '/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading '.' is matched only explicitly. */ + +#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE +# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +# define FNM_LEADING_DIR (1 << 3) /* Ignore '/...' after a match. */ +# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ +#endif + +/* Value returned by 'fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* This value is returned if the implementation does not support + 'fnmatch'. Since this is not the case here it will never be + returned but the conformance test suites still require the symbol + to be defined. */ +#ifdef _XOPEN_SOURCE +# define FNM_NOSYS (-1) +#endif + +#endif + + +#if @GNULIB_FNMATCH@ +/* Match NAME against the file name pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +# if @REPLACE_FNMATCH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fnmatch rpl_fnmatch +# endif +_GL_FUNCDECL_RPL (fnmatch, int, + (const char *pattern, const char *name, int flags) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fnmatch, int, + (const char *pattern, const char *name, int flags)); +# else +# if !@HAVE_FNMATCH@ +_GL_FUNCDECL_SYS (fnmatch, int, + (const char *pattern, const char *name, int flags) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (fnmatch, int, + (const char *pattern, const char *name, int flags)); +# endif +# if !GNULIB_FNMATCH_GNU && __GLIBC__ >= 2 +_GL_CXXALIASWARN (fnmatch); +# endif +#elif defined GNULIB_POSIXCHECK +# undef fnmatch +# if HAVE_RAW_DECL_FNMATCH +_GL_WARN_ON_USE (fnmatch, + "fnmatch does not portably work - " + "use gnulib module fnmatch for portability or gnulib module fnmatch-gnu for a glibc compatible implementation"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_FNMATCH_H */ +#endif /* _@GUARD_PREFIX@_FNMATCH_H */ diff --git a/lib/fnmatch_loop.c b/lib/fnmatch_loop.c new file mode 100644 index 0000000..e635953 --- /dev/null +++ b/lib/fnmatch_loop.c @@ -0,0 +1,1211 @@ +/* Copyright (C) 1991-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 + . */ + +#ifdef _LIBC +# include +#endif + +struct STRUCT +{ + const CHAR *pattern; + const CHAR *string; + bool no_leading_period; +}; + +/* Match STRING against the file name pattern PATTERN, returning zero if + it matches, nonzero if not. */ +static int FCT (const CHAR *pattern, const CHAR *string, + const CHAR *string_end, bool no_leading_period, int flags, + struct STRUCT *ends, size_t alloca_used); +static int EXT (INT opt, const CHAR *pattern, const CHAR *string, + const CHAR *string_end, bool no_leading_period, int flags, + size_t alloca_used); +static const CHAR *END (const CHAR *patternp); + +static int +FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + bool no_leading_period, int flags, struct STRUCT *ends, size_t alloca_used) +{ + const CHAR *p = pattern, *n = string; + UCHAR c; +#ifdef _LIBC +# if WIDE_CHAR_VERSION + const char *collseq = (const char *) + _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); +# else + const UCHAR *collseq = (const UCHAR *) + _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB); +# endif +#endif + + while ((c = *p++) != L_('\0')) + { + bool new_no_leading_period = false; + c = FOLD (c); + + switch (c) + { + case L_('?'): + if (__glibc_unlikely (flags & FNM_EXTMATCH) && *p == '(') + { + int res = EXT (c, p, n, string_end, no_leading_period, + flags, alloca_used); + if (res != -1) + return res; + } + + if (n == string_end) + return FNM_NOMATCH; + else if (*n == L_('/') && (flags & FNM_FILE_NAME)) + return FNM_NOMATCH; + else if (*n == L_('.') && no_leading_period) + return FNM_NOMATCH; + break; + + case L_('\\'): + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + if (c == L_('\0')) + /* Trailing \ loses. */ + return FNM_NOMATCH; + c = FOLD (c); + } + if (n == string_end || FOLD ((UCHAR) *n) != c) + return FNM_NOMATCH; + break; + + case L_('*'): + if (__glibc_unlikely (flags & FNM_EXTMATCH) && *p == '(') + { + int res = EXT (c, p, n, string_end, no_leading_period, + flags, alloca_used); + if (res != -1) + return res; + } + else if (ends != NULL) + { + ends->pattern = p - 1; + ends->string = n; + ends->no_leading_period = no_leading_period; + return 0; + } + + if (n != string_end && *n == L_('.') && no_leading_period) + return FNM_NOMATCH; + + for (c = *p++; c == L_('?') || c == L_('*'); c = *p++) + { + if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0) + { + const CHAR *endp = END (p); + if (endp != p) + { + /* This is a pattern. Skip over it. */ + p = endp; + continue; + } + } + + if (c == L_('?')) + { + /* A ? needs to match one character. */ + if (n == string_end) + /* There isn't another character; no match. */ + return FNM_NOMATCH; + else if (*n == L_('/') + && __glibc_unlikely (flags & FNM_FILE_NAME)) + /* A slash does not match a wildcard under + FNM_FILE_NAME. */ + return FNM_NOMATCH; + else + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + less than three characters. */ + ++n; + } + } + + if (c == L_('\0')) + /* The wildcard(s) is/are the last element of the pattern. + If the name is a file name and contains another slash + this means it cannot match, unless the FNM_LEADING_DIR + flag is set. */ + { + int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH; + + if (flags & FNM_FILE_NAME) + { + if (flags & FNM_LEADING_DIR) + result = 0; + else + { + if (MEMCHR (n, L_('/'), string_end - n) == NULL) + result = 0; + } + } + + return result; + } + else + { + const CHAR *endp; + struct STRUCT end; + + end.pattern = NULL; + endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), + string_end - n); + if (endp == NULL) + endp = string_end; + + if (c == L_('[') + || (__glibc_unlikely (flags & FNM_EXTMATCH) + && (c == L_('@') || c == L_('+') || c == L_('!')) + && *p == L_('('))) + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + + for (--p; n < endp; ++n, no_leading_period = false) + if (FCT (p, n, string_end, no_leading_period, flags2, + &end, alloca_used) == 0) + goto found; + } + else if (c == L_('/') && (flags & FNM_FILE_NAME)) + { + while (n < string_end && *n != L_('/')) + ++n; + if (n < string_end && *n == L_('/') + && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags, + NULL, alloca_used) == 0)) + return 0; + } + else + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + + if (c == L_('\\') && !(flags & FNM_NOESCAPE)) + c = *p; + c = FOLD (c); + for (--p; n < endp; ++n, no_leading_period = false) + if (FOLD ((UCHAR) *n) == c + && (FCT (p, n, string_end, no_leading_period, flags2, + &end, alloca_used) == 0)) + { + found: + if (end.pattern == NULL) + return 0; + break; + } + if (end.pattern != NULL) + { + p = end.pattern; + n = end.string; + no_leading_period = end.no_leading_period; + continue; + } + } + } + + /* If we come here no match is possible with the wildcard. */ + return FNM_NOMATCH; + + case L_('['): + { + /* Nonzero if the sense of the character class is inverted. */ + const CHAR *p_init = p; + const CHAR *n_init = n; + bool not; + CHAR cold; + UCHAR fn; + + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + + if (n == string_end) + return FNM_NOMATCH; + + if (*n == L_('.') && no_leading_period) + return FNM_NOMATCH; + + if (*n == L_('/') && (flags & FNM_FILE_NAME)) + /* '/' cannot be matched. */ + return FNM_NOMATCH; + + not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); + if (not) + ++p; + + fn = FOLD ((UCHAR) *n); + + c = *p++; + for (;;) + { + if (!(flags & FNM_NOESCAPE) && c == L_('\\')) + { + if (*p == L_('\0')) + return FNM_NOMATCH; + c = FOLD ((UCHAR) *p); + ++p; + + goto normal_bracket; + } + else if (c == L_('[') && *p == L_(':')) + { + /* Leave room for the null. */ + CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; + size_t c1 = 0; + wctype_t wt; + const CHAR *startp = p; + + for (;;) + { + if (c1 == CHAR_CLASS_MAX_LENGTH) + /* The name is too long and therefore the pattern + is ill-formed. */ + return FNM_NOMATCH; + + c = *++p; + if (c == L_(':') && p[1] == L_(']')) + { + p += 2; + break; + } + if (c < L_('a') || c >= L_('z')) + { + /* This cannot possibly be a character class name. + Match it as a normal range. */ + p = startp; + c = L_('['); + goto normal_bracket; + } + str[c1++] = c; + } + str[c1] = L_('\0'); + + wt = IS_CHAR_CLASS (str); + if (wt == 0) + /* Invalid character class name. */ + return FNM_NOMATCH; + +#if defined _LIBC && ! WIDE_CHAR_VERSION + /* The following code is glibc specific but does + there a good job in speeding up the code since + we can avoid the btowc() call. */ + if (_ISCTYPE ((UCHAR) *n, wt)) + goto matched; +#else + if (iswctype (BTOWC ((UCHAR) *n), wt)) + goto matched; +#endif + c = *p++; + } +#ifdef _LIBC + else if (c == L_('[') && *p == L_('=')) + { + /* It's important that STR be a scalar variable rather + than a one-element array, because GCC (at least 4.9.2 + -O2 on x86-64) can be confused by the array and + diagnose a "used initialized" in a dead branch in the + findidx function. */ + UCHAR str; + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + const CHAR *startp = p; + + c = *++p; + if (c == L_('\0')) + { + p = startp; + c = L_('['); + goto normal_bracket; + } + str = c; + + c = *++p; + if (c != L_('=') || p[1] != L_(']')) + { + p = startp; + c = L_('['); + goto normal_bracket; + } + p += 2; + + if (nrules == 0) + { + if ((UCHAR) *n == str) + goto matched; + } + else + { + const int32_t *table; +# if WIDE_CHAR_VERSION + const int32_t *weights; + const wint_t *extra; +# else + const unsigned char *weights; + const unsigned char *extra; +# endif + const int32_t *indirect; + int32_t idx; + const UCHAR *cp = (const UCHAR *) &str; + +# if WIDE_CHAR_VERSION + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); + weights = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); + extra = (const wint_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); +# else + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); +# endif + + idx = FINDIDX (table, indirect, extra, &cp, 1); + if (idx != 0) + { + /* We found a table entry. Now see whether the + character we are currently at has the same + equivalence class value. */ + int len = weights[idx & 0xffffff]; + int32_t idx2; + const UCHAR *np = (const UCHAR *) n; + + idx2 = FINDIDX (table, indirect, extra, + &np, string_end - n); + if (idx2 != 0 + && (idx >> 24) == (idx2 >> 24) + && len == weights[idx2 & 0xffffff]) + { + int cnt = 0; + + idx &= 0xffffff; + idx2 &= 0xffffff; + + while (cnt < len + && (weights[idx + 1 + cnt] + == weights[idx2 + 1 + cnt])) + ++cnt; + + if (cnt == len) + goto matched; + } + } + } + + c = *p++; + } +#endif + else if (c == L_('\0')) + { + /* [ unterminated, treat as normal character. */ + p = p_init; + n = n_init; + c = L_('['); + goto normal_match; + } + else + { + bool is_range = false; + +#ifdef _LIBC + bool is_seqval = false; + + if (c == L_('[') && *p == L_('.')) + { + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + const CHAR *startp = p; + size_t c1 = 0; + + while (1) + { + c = *++p; + if (c == L_('.') && p[1] == L_(']')) + { + p += 2; + break; + } + if (c == '\0') + return FNM_NOMATCH; + ++c1; + } + + /* We have to handling the symbols differently in + ranges since then the collation sequence is + important. */ + is_range = *p == L_('-') && p[1] != L_('\0'); + + if (nrules == 0) + { + /* There are no names defined in the collation + data. Therefore we only accept the trivial + names consisting of the character itself. */ + if (c1 != 1) + return FNM_NOMATCH; + + if (!is_range && *n == startp[1]) + goto matched; + + cold = startp[1]; + c = *p++; + } + else + { + int32_t table_size; + const int32_t *symb_table; + const unsigned char *extra; + int32_t idx; + int32_t elem; +# if WIDE_CHAR_VERSION + CHAR *wextra; +# endif + + 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); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_EXTRAMB); + + for (elem = 0; elem < table_size; elem++) + if (symb_table[2 * elem] != 0) + { + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element. */ + idx += 1 + extra[idx]; +# if WIDE_CHAR_VERSION + /* Skip the byte sequence of the + collating element. */ + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + + wextra = (CHAR *) &extra[idx + 4]; + + if (/* Compare the length of the sequence. */ + c1 == wextra[0] + /* Compare the wide char sequence. */ + && (__wmemcmp (startp + 1, &wextra[1], + c1) + == 0)) + /* Yep, this is the entry. */ + break; +# else + if (/* Compare the length of the sequence. */ + c1 == extra[idx] + /* Compare the byte sequence. */ + && memcmp (startp + 1, + &extra[idx + 1], c1) == 0) + /* Yep, this is the entry. */ + break; +# endif + } + + if (elem < table_size) + { + /* Compare the byte sequence but only if + this is not part of a range. */ + if (! is_range + +# if WIDE_CHAR_VERSION + && __wmemcmp (n, &wextra[1], c1) == 0 +# else + && memcmp (n, &extra[idx + 1], c1) == 0 +# endif + ) + { + n += c1 - 1; + goto matched; + } + + /* Get the collation sequence value. */ + is_seqval = true; +# if WIDE_CHAR_VERSION + cold = wextra[1 + wextra[0]]; +# else + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + cold = *((int32_t *) &extra[idx]); +# endif + + c = *p++; + } + else if (c1 == 1) + { + /* No valid character. Match it as a + single byte. */ + if (!is_range && *n == startp[1]) + goto matched; + + cold = startp[1]; + c = *p++; + } + else + return FNM_NOMATCH; + } + } + else +#endif + { + c = FOLD (c); + normal_bracket: + + /* We have to handling the symbols differently in + ranges since then the collation sequence is + important. */ + is_range = (*p == L_('-') && p[1] != L_('\0') + && p[1] != L_(']')); + + if (!is_range && c == fn) + goto matched; + +#if _LIBC + /* This is needed if we goto normal_bracket; from + outside of is_seqval's scope. */ + is_seqval = false; +#endif + cold = c; + c = *p++; + } + + if (c == L_('-') && *p != L_(']')) + { +#if _LIBC + /* We have to find the collation sequence + value for C. Collation sequence is nothing + we can regularly access. The sequence + value is defined by the order in which the + definitions of the collation values for the + various characters appear in the source + file. A strange concept, nowhere + documented. */ + uint32_t fcollseq; + uint32_t lcollseq; + UCHAR cend = *p++; + +# if WIDE_CHAR_VERSION + /* Search in the 'names' array for the characters. */ + fcollseq = __collseq_table_lookup (collseq, fn); + if (fcollseq == ~((uint32_t) 0)) + /* XXX We don't know anything about the character + we are supposed to match. This means we are + failing. */ + goto range_not_matched; + + if (is_seqval) + lcollseq = cold; + else + lcollseq = __collseq_table_lookup (collseq, cold); +# else + fcollseq = collseq[fn]; + lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; +# endif + + is_seqval = false; + if (cend == L_('[') && *p == L_('.')) + { + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, + _NL_COLLATE_NRULES); + const CHAR *startp = p; + size_t c1 = 0; + + while (1) + { + c = *++p; + if (c == L_('.') && p[1] == L_(']')) + { + p += 2; + break; + } + if (c == '\0') + return FNM_NOMATCH; + ++c1; + } + + if (nrules == 0) + { + /* There are no names defined in the + collation data. Therefore we only + accept the trivial names consisting + of the character itself. */ + if (c1 != 1) + return FNM_NOMATCH; + + cend = startp[1]; + } + else + { + int32_t table_size; + const int32_t *symb_table; + const unsigned char *extra; + int32_t idx; + int32_t elem; +# if WIDE_CHAR_VERSION + CHAR *wextra; +# endif + + 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); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_EXTRAMB); + + for (elem = 0; elem < table_size; elem++) + if (symb_table[2 * elem] != 0) + { + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating + element. */ + idx += 1 + extra[idx]; +# if WIDE_CHAR_VERSION + /* Skip the byte sequence of the + collating element. */ + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + + wextra = (CHAR *) &extra[idx + 4]; + + if (/* Compare the length of the + sequence. */ + c1 == wextra[0] + /* Compare the wide char sequence. */ + && (__wmemcmp (startp + 1, + &wextra[1], c1) + == 0)) + /* Yep, this is the entry. */ + break; +# else + if (/* Compare the length of the + sequence. */ + c1 == extra[idx] + /* Compare the byte sequence. */ + && memcmp (startp + 1, + &extra[idx + 1], c1) == 0) + /* Yep, this is the entry. */ + break; +# endif + } + + if (elem < table_size) + { + /* Get the collation sequence value. */ + is_seqval = true; +# if WIDE_CHAR_VERSION + cend = wextra[1 + wextra[0]]; +# else + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + cend = *((int32_t *) &extra[idx]); +# endif + } + else if (c1 == 1) + { + cend = startp[1]; + c = *p++; + } + else + return FNM_NOMATCH; + } + } + else + { + if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) + cend = *p++; + if (cend == L_('\0')) + return FNM_NOMATCH; + cend = FOLD (cend); + } + + /* XXX It is not entirely clear to me how to handle + characters which are not mentioned in the + collation specification. */ + if ( +# if WIDE_CHAR_VERSION + lcollseq == 0xffffffff || +# endif + lcollseq <= fcollseq) + { + /* We have to look at the upper bound. */ + uint32_t hcollseq; + + if (is_seqval) + hcollseq = cend; + else + { +# if WIDE_CHAR_VERSION + hcollseq = + __collseq_table_lookup (collseq, cend); + if (hcollseq == ~((uint32_t) 0)) + { + /* Hum, no information about the upper + bound. The matching succeeds if the + lower bound is matched exactly. */ + if (lcollseq != fcollseq) + goto range_not_matched; + + goto matched; + } +# else + hcollseq = collseq[cend]; +# endif + } + + if (lcollseq <= hcollseq && fcollseq <= hcollseq) + goto matched; + } +# if WIDE_CHAR_VERSION + range_not_matched: +# endif +#else + /* We use a boring value comparison of the character + values. This is better than comparing using + 'strcoll' since the latter would have surprising + and sometimes fatal consequences. */ + UCHAR cend = *p++; + + if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) + cend = *p++; + if (cend == L_('\0')) + return FNM_NOMATCH; + + /* It is a range. */ + if ((UCHAR) cold <= fn && fn <= cend) + goto matched; +#endif + + c = *p++; + } + } + + if (c == L_(']')) + break; + } + + if (!not) + return FNM_NOMATCH; + break; + + matched: + /* Skip the rest of the [...] that already matched. */ + while ((c = *p++) != L_(']')) + { + if (c == L_('\0')) + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + if (!(flags & FNM_NOESCAPE) && c == L_('\\')) + { + if (*p == L_('\0')) + return FNM_NOMATCH; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + else if (c == L_('[') && *p == L_(':')) + { + int c1 = 0; + const CHAR *startp = p; + + while (1) + { + c = *++p; + if (++c1 == CHAR_CLASS_MAX_LENGTH) + return FNM_NOMATCH; + + if (*p == L_(':') && p[1] == L_(']')) + break; + + if (c < L_('a') || c >= L_('z')) + { + p = startp - 2; + break; + } + } + p += 2; + } + else if (c == L_('[') && *p == L_('=')) + { + c = *++p; + if (c == L_('\0')) + return FNM_NOMATCH; + c = *++p; + if (c != L_('=') || p[1] != L_(']')) + return FNM_NOMATCH; + p += 2; + } + else if (c == L_('[') && *p == L_('.')) + { + while (1) + { + c = *++p; + if (c == L_('\0')) + return FNM_NOMATCH; + + if (c == L_('.') && p[1] == L_(']')) + break; + } + p += 2; + } + } + if (not) + return FNM_NOMATCH; + } + break; + + case L_('+'): + case L_('@'): + case L_('!'): + if (__glibc_unlikely (flags & FNM_EXTMATCH) && *p == '(') + { + int res = EXT (c, p, n, string_end, no_leading_period, flags, + alloca_used); + if (res != -1) + return res; + } + goto normal_match; + + case L_('/'): + if (NO_LEADING_PERIOD (flags)) + { + if (n == string_end || c != (UCHAR) *n) + return FNM_NOMATCH; + + new_no_leading_period = true; + break; + } + FALLTHROUGH; + default: + normal_match: + if (n == string_end || c != FOLD ((UCHAR) *n)) + return FNM_NOMATCH; + } + + no_leading_period = new_no_leading_period; + ++n; + } + + if (n == string_end) + return 0; + + if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/')) + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} + + +static const CHAR * +END (const CHAR *pattern) +{ + const CHAR *p = pattern; + + while (1) + if (*++p == L_('\0')) + /* This is an invalid pattern. */ + return pattern; + else if (*p == L_('[')) + { + /* Handle brackets special. */ + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + + /* Skip the not sign. We have to recognize it because of a possibly + following ']'. */ + if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) + ++p; + /* A leading ']' is recognized as such. */ + if (*p == L_(']')) + ++p; + /* Skip over all characters of the list. */ + while (*p != L_(']')) + if (*p++ == L_('\0')) + /* This is no valid pattern. */ + return pattern; + } + else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') + || *p == L_('!')) && p[1] == L_('(')) + { + p = END (p + 1); + if (*p == L_('\0')) + /* This is an invalid pattern. */ + return pattern; + } + else if (*p == L_(')')) + break; + + return p + 1; +} + + +static int +EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, + bool no_leading_period, int flags, size_t alloca_used) +{ + const CHAR *startp; + ptrdiff_t level; + struct patternlist + { + struct patternlist *next; + CHAR malloced; + CHAR str __flexarr; + } *list = NULL; + struct patternlist **lastp = &list; + size_t pattern_len = STRLEN (pattern); + bool any_malloced = false; + const CHAR *p; + const CHAR *rs; + int retval = 0; + + /* Parse the pattern. Store the individual parts in the list. */ + level = 0; + for (startp = p = pattern + 1; level >= 0; ++p) + if (*p == L_('\0')) + { + /* This is an invalid pattern. */ + retval = -1; + goto out; + } + else if (*p == L_('[')) + { + /* Handle brackets special. */ + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + + /* Skip the not sign. We have to recognize it because of a possibly + following ']'. */ + if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) + ++p; + /* A leading ']' is recognized as such. */ + if (*p == L_(']')) + ++p; + /* Skip over all characters of the list. */ + while (*p != L_(']')) + if (*p++ == L_('\0')) + { + /* This is no valid pattern. */ + retval = -1; + goto out; + } + } + else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') + || *p == L_('!')) && p[1] == L_('(')) + /* Remember the nesting level. */ + ++level; + else if (*p == L_(')')) + { + if (level-- == 0) + { + /* This means we found the end of the pattern. */ +#define NEW_PATTERN \ + struct patternlist *newp; \ + size_t plen = (opt == L_('?') || opt == L_('@') \ + ? pattern_len : (p - startp + 1UL)); \ + idx_t slen = FLEXSIZEOF (struct patternlist, str, 0); \ + idx_t new_used = alloca_used + slen; \ + idx_t plensize; \ + if (INT_MULTIPLY_WRAPV (plen, sizeof (CHAR), &plensize) \ + || INT_ADD_WRAPV (new_used, plensize, &new_used)) \ + { \ + retval = -2; \ + goto out; \ + } \ + slen += plensize; \ + bool malloced = ! __libc_use_alloca (new_used); \ + if (__glibc_unlikely (malloced)) \ + { \ + newp = malloc (slen); \ + if (newp == NULL) \ + { \ + retval = -2; \ + goto out; \ + } \ + any_malloced = true; \ + } \ + else \ + newp = alloca_account (slen, alloca_used); \ + newp->next = NULL; \ + newp->malloced = malloced; \ + *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ + *lastp = newp; \ + lastp = &newp->next + NEW_PATTERN; + } + } + else if (*p == L_('|')) + { + if (level == 0) + { + NEW_PATTERN; + startp = p + 1; + } + } + assert (list != NULL); + assert (p[-1] == L_(')')); +#undef NEW_PATTERN + + switch (opt) + { + case L_('*'): + if (FCT (p, string, string_end, no_leading_period, flags, NULL, + alloca_used) == 0) + goto success; + FALLTHROUGH; + case L_('+'): + do + { + for (rs = string; rs <= string_end; ++rs) + /* First match the prefix with the current pattern with the + current pattern. */ + if (FCT (list->str, string, rs, no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, + NULL, alloca_used) == 0 + /* This was successful. Now match the rest with the rest + of the pattern. */ + && (FCT (p, rs, string_end, + rs == string + ? no_leading_period + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), + flags & FNM_FILE_NAME + ? flags : flags & ~FNM_PERIOD, NULL, alloca_used) == 0 + /* This didn't work. Try the whole pattern. */ + || (rs != string + && FCT (pattern - 1, rs, string_end, + rs == string + ? no_leading_period + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), + flags & FNM_FILE_NAME + ? flags : flags & ~FNM_PERIOD, NULL, + alloca_used) == 0))) + /* It worked. Signal success. */ + goto success; + } + while ((list = list->next) != NULL); + + /* None of the patterns lead to a match. */ + retval = FNM_NOMATCH; + break; + + case L_('?'): + if (FCT (p, string, string_end, no_leading_period, flags, NULL, + alloca_used) == 0) + goto success; + FALLTHROUGH; + case L_('@'): + do + /* I cannot believe it but 'strcat' is actually acceptable + here. Match the entire string with the prefix from the + pattern list and the rest of the pattern following the + pattern list. */ + if (FCT (STRCAT (list->str, p), string, string_end, + no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, + NULL, alloca_used) == 0) + /* It worked. Signal success. */ + goto success; + while ((list = list->next) != NULL); + + /* None of the patterns lead to a match. */ + retval = FNM_NOMATCH; + break; + + case L_('!'): + for (rs = string; rs <= string_end; ++rs) + { + struct patternlist *runp; + + for (runp = list; runp != NULL; runp = runp->next) + if (FCT (runp->str, string, rs, no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, + NULL, alloca_used) == 0) + break; + + /* If none of the patterns matched see whether the rest does. */ + if (runp == NULL + && (FCT (p, rs, string_end, + rs == string + ? no_leading_period + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, + NULL, alloca_used) == 0)) + /* This is successful. */ + goto success; + } + + /* None of the patterns together with the rest of the pattern + lead to a match. */ + retval = FNM_NOMATCH; + break; + + default: + assert (! "Invalid extended matching operator"); + retval = -1; + break; + } + + success: + out: + if (any_malloced) + while (list != NULL) + { + struct patternlist *old = list; + list = list->next; + if (old->malloced) + free (old); + } + + return retval; +} + + +#undef FOLD +#undef CHAR +#undef UCHAR +#undef INT +#undef FCT +#undef EXT +#undef END +#undef STRUCT +#undef MEMPCPY +#undef MEMCHR +#undef STRLEN +#undef STRCAT +#undef L_ +#undef BTOWC +#undef WIDE_CHAR_VERSION +#undef FINDIDX diff --git a/lib/fopen.c b/lib/fopen.c new file mode 100644 index 0000000..a5b3ae3 --- /dev/null +++ b/lib/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/lib/fpurge.c b/lib/fpurge.c new file mode 100644 index 0000000..21e3b86 --- /dev/null +++ b/lib/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/lib/freading.c b/lib/freading.c new file mode 100644 index 0000000..93e96e0 --- /dev/null +++ b/lib/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/lib/freading.h b/lib/freading.h new file mode 100644 index 0000000..74fed22 --- /dev/null +++ b/lib/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/lib/free.c b/lib/free.c new file mode 100644 index 0000000..86ebe6c --- /dev/null +++ b/lib/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/lib/fseek.c b/lib/fseek.c new file mode 100644 index 0000000..e9f9314 --- /dev/null +++ b/lib/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/lib/fseeko.c b/lib/fseeko.c new file mode 100644 index 0000000..2ca2db8 --- /dev/null +++ b/lib/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/lib/fstat.c b/lib/fstat.c new file mode 100644 index 0000000..3928c86 --- /dev/null +++ b/lib/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/lib/fstatat.c b/lib/fstatat.c new file mode 100644 index 0000000..6e83449 --- /dev/null +++ b/lib/fstatat.c @@ -0,0 +1,148 @@ +/* Work around an fstatat bug on Solaris 9. + + Copyright (C) 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 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 Paul Eggert and Jim Meyering. */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_fstatat doesn't recurse to + rpl_fstatat. */ +#define __need_system_sys_stat_h +#include + +/* Get the original definition of fstatat. It might be defined as a macro. */ +#include +#include +#undef __need_system_sys_stat_h + +#if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG +static int +orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) +{ + return fstatat (fd, filename, buf, flags); +} +#endif + +#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 + +#if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG + +# ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK +# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 +# endif + +static int +normal_fstatat (int fd, char const *file, struct stat *st, int flag) +{ + return stat_time_normalize (orig_fstatat (fd, file, st, flag), st); +} + +/* fstatat should always follow symbolic links that end in /, but on + Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. + Likewise, trailing slash on a non-directory should be an error. + These are the same problems that lstat.c and stat.c address, so + solve it in a similar way. + + AIX 7.1 fstatat (AT_FDCWD, ..., 0) always fails, which is a bug. + Work around this bug if FSTATAT_AT_FDCWD_0_BROKEN is nonzero. */ + +int +rpl_fstatat (int fd, char const *file, struct stat *st, int flag) +{ + int result = normal_fstatat (fd, file, st, flag); + size_t len; + + if (LSTAT_FOLLOWS_SLASHED_SYMLINK || result != 0) + return result; + len = strlen (file); + if (flag & AT_SYMLINK_NOFOLLOW) + { + /* Fix lstat behavior. */ + if (file[len - 1] != '/' || S_ISDIR (st->st_mode)) + return 0; + if (!S_ISLNK (st->st_mode)) + { + errno = ENOTDIR; + return -1; + } + result = normal_fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW); + } + /* Fix stat behavior. */ + if (result == 0 && !S_ISDIR (st->st_mode) && file[len - 1] == '/') + { + errno = ENOTDIR; + return -1; + } + return result; +} + +#else /* ! (HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG) */ + +/* On mingw, the gnulib defines 'stat' as a function-like + macro; but using it in AT_FUNC_F2 causes compilation failure + because the preprocessor sees a use of a macro that requires two + arguments but is only given one. Hence, we need an inline + forwarder to get past the preprocessor. */ +static int +stat_func (char const *name, struct stat *st) +{ + return stat (name, st); +} + +/* Likewise, if there is no native 'lstat', then the gnulib + defined it as stat, which also needs adjustment. */ +# if !HAVE_LSTAT +# undef lstat +# define lstat stat_func +# endif + +/* Replacement for Solaris' function by the same name. + + First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE"). + Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd. + If either the save_cwd or the restore_cwd fails (relatively unlikely), + then give a diagnostic and exit nonzero. + Otherwise, this function works just like Solaris' fstatat. */ + +# define AT_FUNC_NAME fstatat +# define AT_FUNC_F1 lstat +# define AT_FUNC_F2 stat_func +# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW +# define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag +# define AT_FUNC_POST_FILE_ARGS , st +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_F2 +# undef AT_FUNC_USE_F1_COND +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +#endif /* !HAVE_FSTATAT */ diff --git a/lib/ftell.c b/lib/ftell.c new file mode 100644 index 0000000..3fbd9e9 --- /dev/null +++ b/lib/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/lib/ftello.c b/lib/ftello.c new file mode 100644 index 0000000..989614a --- /dev/null +++ b/lib/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/lib/futimens.c b/lib/futimens.c new file mode 100644 index 0000000..bc3e41a --- /dev/null +++ b/lib/futimens.c @@ -0,0 +1,37 @@ +/* Set the access and modification time of an open fd. + 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 3 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 + +#include + +#include "utimens.h" + +/* Set the access and modification timestamps of FD to be + TIMESPEC[0] and TIMESPEC[1], respectively. + Fail with ENOSYS on systems without futimes (or equivalent). + If TIMESPEC is null, set the timestamps to the current time. + Return 0 on success, -1 (setting errno) on failure. */ +int +futimens (int fd, struct timespec const times[2]) +{ + /* fdutimens also works around bugs in native futimens, when running + with glibc compiled against newer headers but on a Linux kernel + older than 2.6.32. */ + return fdutimens (fd, NULL, times); +} diff --git a/lib/gai_strerror.c b/lib/gai_strerror.c new file mode 100644 index 0000000..c7eedb2 --- /dev/null +++ b/lib/gai_strerror.c @@ -0,0 +1,92 @@ +/* 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 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 _LIBC +# include +#endif + +#include +#include + +#ifdef _LIBC +# include +#else +# include "gettext.h" +# define _(String) gettext (String) +# define N_(String) String +#endif + +#if HAVE_DECL_GAI_STRERROR + +# include +# undef gai_strerror +# if HAVE_DECL_GAI_STRERRORA +# define gai_strerror gai_strerrorA +# endif + +const char * +rpl_gai_strerror (int code) +{ + return gai_strerror (code); +} + +#else /* !HAVE_DECL_GAI_STRERROR */ + +static struct + { + int code; + const char *msg; + } +values[] = + { + { EAI_ADDRFAMILY, N_("Address family for hostname not supported") }, + { EAI_AGAIN, N_("Temporary failure in name resolution") }, + { EAI_BADFLAGS, N_("Bad value for ai_flags") }, + { EAI_FAIL, N_("Non-recoverable failure in name resolution") }, + { EAI_FAMILY, N_("ai_family not supported") }, + { EAI_MEMORY, N_("Memory allocation failure") }, + { EAI_NODATA, N_("No address associated with hostname") }, + { EAI_NONAME, N_("Name or service not known") }, + { EAI_SERVICE, N_("Servname not supported for ai_socktype") }, + { EAI_SOCKTYPE, N_("ai_socktype not supported") }, + { EAI_SYSTEM, N_("System error") }, + { EAI_OVERFLOW, N_("Argument buffer too small") }, +#ifdef EAI_INPROGRESS + { EAI_INPROGRESS, N_("Processing request in progress") }, + { EAI_CANCELED, N_("Request canceled") }, + { EAI_NOTCANCELED, N_("Request not canceled") }, + { EAI_ALLDONE, N_("All requests done") }, + { EAI_INTR, N_("Interrupted by a signal") }, + { EAI_IDN_ENCODE, N_("Parameter string not correctly encoded") } +#endif + }; + +const char * +gai_strerror (int code) +{ + size_t i; + for (i = 0; i < sizeof (values) / sizeof (values[0]); ++i) + if (values[i].code == code) + return _(values[i].msg); + + return _("Unknown error"); +} +# ifdef _LIBC +libc_hidden_def (gai_strerror) +# endif +#endif /* !HAVE_DECL_GAI_STRERROR */ diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c new file mode 100644 index 0000000..3922898 --- /dev/null +++ b/lib/getaddrinfo.c @@ -0,0 +1,505 @@ +/* Get address information (partial implementation). + Copyright (C) 1997, 2001-2002, 2004-2022 Free Software Foundation, Inc. + Contributed by Simon Josefsson . + + 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 . */ + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the sa == NULL test below. */ +#define _GL_ARG_NONNULL(params) + +#include + +#include + +#if HAVE_NETINET_IN_H +# include +#endif + +/* Get inet_ntop. */ +#include + +/* Get calloc. */ +#include + +/* Get memcpy, strdup. */ +#include + +/* Get snprintf. */ +#include + +#include + +#include "gettext.h" +#define _(String) gettext (String) +#define N_(String) String + +/* BeOS has AF_INET, but not PF_INET. */ +#ifndef PF_INET +# define PF_INET AF_INET +#endif +/* BeOS also lacks PF_UNSPEC. */ +#ifndef PF_UNSPEC +# define PF_UNSPEC 0 +#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" + +# 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 + +typedef int (WSAAPI *getaddrinfo_func) (const char*, const char*, + const struct addrinfo*, + struct addrinfo**); +typedef void (WSAAPI *freeaddrinfo_func) (struct addrinfo*); +typedef int (WSAAPI *getnameinfo_func) (const struct sockaddr*, + socklen_t, char*, DWORD, + char*, DWORD, int); + +static getaddrinfo_func getaddrinfo_ptr = NULL; +static freeaddrinfo_func freeaddrinfo_ptr = NULL; +static getnameinfo_func getnameinfo_ptr = NULL; + +static int +use_win32_p (void) +{ + static int done = 0; + HMODULE h; + + if (done) + return getaddrinfo_ptr ? 1 : 0; + + done = 1; + + h = GetModuleHandle ("ws2_32.dll"); + + if (h) + { + getaddrinfo_ptr = (getaddrinfo_func) GetProcAddress (h, "getaddrinfo"); + freeaddrinfo_ptr = (freeaddrinfo_func) GetProcAddress (h, "freeaddrinfo"); + getnameinfo_ptr = (getnameinfo_func) GetProcAddress (h, "getnameinfo"); + } + + /* If either is missing, something is odd. */ + if (!getaddrinfo_ptr || !freeaddrinfo_ptr || !getnameinfo_ptr) + { + getaddrinfo_ptr = NULL; + freeaddrinfo_ptr = NULL; + getnameinfo_ptr = NULL; + return 0; + } + + gl_sockets_startup (SOCKETS_1_1); + + return 1; +} + +# 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 (family == PF_INET) + return true; +# endif +# if HAVE_IPV6 + if (family == PF_INET6) + return true; +# endif + if (family == PF_UNSPEC) + return true; + return false; +} + +/* Translate name of a service location and/or a service name to set of + socket addresses. */ +int +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 + struct v6_pair { + struct addrinfo addrinfo; + struct sockaddr_in6 sockaddr_in6; + }; +# endif +# if HAVE_IPV4 + struct v4_pair { + struct addrinfo addrinfo; + struct sockaddr_in sockaddr_in; + }; +# endif + +# ifdef WINDOWS_NATIVE + if (use_win32_p ()) + return getaddrinfo_ptr (nodename, servname, hints, res); +# endif + + if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE))) + /* FIXME: Support more flags. */ + return EAI_BADFLAGS; + + if (hints && !validate_family (hints->ai_family)) + return EAI_FAMILY; + + if (hints && + hints->ai_socktype != SOCK_STREAM && hints->ai_socktype != SOCK_DGRAM) + /* FIXME: Support other socktype. */ + return EAI_SOCKTYPE; /* FIXME: Better return code? */ + + if (!nodename) + { + if (!(hints->ai_flags & AI_PASSIVE)) + return EAI_NONAME; + +# ifdef HAVE_IPV6 + nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; +# else + nodename = "0.0.0.0"; +# endif + } + + if (servname) + { + struct servent *se = NULL; + const char *proto = + (hints && hints->ai_socktype == SOCK_DGRAM) ? "udp" : "tcp"; + + if (hints == NULL || !(hints->ai_flags & AI_NUMERICSERV)) + /* FIXME: Use getservbyname_r if available. */ + se = getservbyname (servname, proto); + + if (!se) + { + char *c; + if (!(*servname >= '0' && *servname <= '9')) + return EAI_NONAME; + port = strtoul (servname, &c, 10); + if (*c || port > 0xffff) + return EAI_NONAME; + port = htons (port); + } + else + port = se->s_port; + } + + /* FIXME: Use gethostbyname_r if available. */ + he = gethostbyname (nodename); + if (!he || he->h_addr_list[0] == NULL) + return EAI_NONAME; + + switch (he->h_addrtype) + { +# if HAVE_IPV6 + case PF_INET6: + size = sizeof (struct v6_pair); + break; +# endif + +# if HAVE_IPV4 + case PF_INET: + size = sizeof (struct v4_pair); + break; +# endif + + default: + return EAI_NODATA; + } + + storage = calloc (1, size); + if (!storage) + return EAI_MEMORY; + + switch (he->h_addrtype) + { +# if HAVE_IPV6 + case PF_INET6: + { + struct v6_pair *p = storage; + struct sockaddr_in6 *sinp = &p->sockaddr_in6; + tmp = &p->addrinfo; + + if (port) + sinp->sin6_port = port; + + if (he->h_length != sizeof (sinp->sin6_addr)) + { + free (storage); + return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */ + } + + memcpy (&sinp->sin6_addr, he->h_addr_list[0], sizeof sinp->sin6_addr); + + tmp->ai_addr = (struct sockaddr *) sinp; + tmp->ai_addrlen = sizeof *sinp; + } + break; +# endif + +# if HAVE_IPV4 + case PF_INET: + { + struct v4_pair *p = storage; + struct sockaddr_in *sinp = &p->sockaddr_in; + tmp = &p->addrinfo; + + if (port) + sinp->sin_port = port; + + if (he->h_length != sizeof (sinp->sin_addr)) + { + free (storage); + return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */ + } + + memcpy (&sinp->sin_addr, he->h_addr_list[0], sizeof sinp->sin_addr); + + tmp->ai_addr = (struct sockaddr *) sinp; + tmp->ai_addrlen = sizeof *sinp; + } + break; +# endif + + default: + free (storage); + return EAI_NODATA; + } + + if (hints && hints->ai_flags & AI_CANONNAME) + { + const char *cn; + if (he->h_name) + cn = he->h_name; + else + cn = nodename; + + tmp->ai_canonname = strdup (cn); + if (!tmp->ai_canonname) + { + free (storage); + return EAI_MEMORY; + } + } + + tmp->ai_protocol = (hints) ? hints->ai_protocol : 0; + tmp->ai_socktype = (hints) ? hints->ai_socktype : 0; + tmp->ai_addr->sa_family = he->h_addrtype; + tmp->ai_family = he->h_addrtype; + +# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + switch (he->h_addrtype) + { +# if HAVE_IPV4 + case AF_INET: + tmp->ai_addr->sa_len = sizeof (struct sockaddr_in); + break; +# endif +# if HAVE_IPV6 + case AF_INET6: + tmp->ai_addr->sa_len = sizeof (struct sockaddr_in6); + break; +# endif + } +# endif + + /* FIXME: If more than one address, create linked list of addrinfo's. */ + + *res = tmp; + + return 0; +} + +/* Free 'addrinfo' structure AI including associated storage. */ +void +freeaddrinfo (struct addrinfo *ai) +#undef freeaddrinfo +{ +# ifdef WINDOWS_NATIVE + if (use_win32_p ()) + { + freeaddrinfo_ptr (ai); + return; + } +# endif + + while (ai) + { + struct addrinfo *cur; + + cur = ai; + ai = ai->ai_next; + + free (cur->ai_canonname); + free (cur); + } +} + +int +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 + if (use_win32_p ()) + return getnameinfo_ptr (sa, salen, node, nodelen, + service, servicelen, flags); +# endif + + /* FIXME: Support other flags. */ + if ((node && nodelen > 0 && !(flags & NI_NUMERICHOST)) || + (service && servicelen > 0 && !(flags & NI_NUMERICHOST)) || + (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV))) + return EAI_BADFLAGS; + + if (sa == NULL || salen < sizeof (sa->sa_family)) + return EAI_FAMILY; + + switch (sa->sa_family) + { +# if HAVE_IPV4 + case AF_INET: + if (salen < sizeof (struct sockaddr_in)) + return EAI_FAMILY; + break; +# endif +# if HAVE_IPV6 + case AF_INET6: + if (salen < sizeof (struct sockaddr_in6)) + return EAI_FAMILY; + break; +# endif + default: + return EAI_FAMILY; + } + + if (node && nodelen > 0 && flags & NI_NUMERICHOST) + { + switch (sa->sa_family) + { +# 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 + +# 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 + + default: + return EAI_FAMILY; + } + } + + if (service && servicelen > 0 && flags & NI_NUMERICSERV) + switch (sa->sa_family) + { +# if HAVE_IPV4 + case AF_INET: +# endif +# if HAVE_IPV6 + case AF_INET6: +# endif + { + unsigned short int port + = ntohs (((const struct sockaddr_in *) sa)->sin_port); + if (servicelen <= snprintf (service, servicelen, "%u", port)) + return EAI_OVERFLOW; + } + break; + } + + return 0; +} + +#endif diff --git a/lib/getcwd-lgpl.c b/lib/getcwd-lgpl.c new file mode 100644 index 0000000..f449ac8 --- /dev/null +++ b/lib/getcwd-lgpl.c @@ -0,0 +1,127 @@ +/* Copyright (C) 2011-2022 Free Software Foundation, Inc. + 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 . */ + +#include + +/* Specification */ +#include + +#include +#include +#include + +#if GNULIB_GETCWD +/* Favor GPL getcwd.c if both getcwd and getcwd-lgpl modules are in use. */ +typedef int dummy; +#else + +/* Get the name of the current working directory, and put it in SIZE + bytes of BUF. Returns NULL if the directory couldn't be determined + (perhaps because the absolute name was longer than PATH_MAX, or + because of missing read/search permissions on parent directories) + or SIZE was too small. If successful, returns BUF. 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 + necessary. */ + +# undef getcwd +# if defined _WIN32 && !defined __CYGWIN__ +# define getcwd _getcwd +# endif + +char * +rpl_getcwd (char *buf, size_t size) +{ + char *ptr; + char *result; + + /* Handle single size operations. */ + if (buf) + { + if (!size) + { + errno = EINVAL; + return NULL; + } + return getcwd (buf, size); + } + + if (size) + { + buf = malloc (size); + if (!buf) + { + errno = ENOMEM; + return NULL; + } + result = getcwd (buf, size); + if (!result) + free (buf); + return result; + } + + /* Flexible sizing requested. Avoid over-allocation for the common + case of a name that fits within a 4k page, minus some space for + local variables, to be sure we don't skip over a guard page. */ + { + char tmp[4032]; + size = sizeof tmp; + ptr = getcwd (tmp, size); + if (ptr) + { + result = strdup (ptr); + if (!result) + errno = ENOMEM; + return result; + } + if (errno != ERANGE) + return NULL; + } + + /* My what a large directory name we have. */ + do + { + size <<= 1; + ptr = realloc (buf, size); + if (ptr == NULL) + { + free (buf); + errno = ENOMEM; + return NULL; + } + buf = ptr; + result = getcwd (buf, size); + } + while (!result && errno == ERANGE); + + if (!result) + free (buf); + else + { + /* Here result == buf. */ + /* Shrink result before returning it. */ + size_t actual_size = strlen (result) + 1; + if (actual_size < size) + { + char *shrinked_result = realloc (result, actual_size); + if (shrinked_result != NULL) + result = shrinked_result; + } + } + return result; +} + +#endif diff --git a/lib/getcwd.c b/lib/getcwd.c new file mode 100644 index 0000000..113332f --- /dev/null +++ b/lib/getcwd.c @@ -0,0 +1,495 @@ +/* Copyright (C) 1991-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 (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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if !_LIBC +# include +# include +# include "pathmax.h" +#else +# define HAVE_OPENAT 1 +# define D_INO_IN_DIRENT 1 +# define HAVE_MSVC_INVALID_PARAMETER_HANDLER 0 +# define HAVE_MINIMALLY_WORKING_GETCWD 0 +#endif + +#include +#include +#include +#include +#include + +#include /* For AT_FDCWD on Solaris 9. */ + +/* If this host provides the openat function or if we're using the + gnulib replacement function with a native fdopendir, then enable + code below to make getcwd more efficient and robust. */ +#if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR) +# define HAVE_OPENAT_SUPPORT 1 +#else +# define HAVE_OPENAT_SUPPORT 0 +#endif + +#ifndef __set_errno +# define __set_errno(val) (errno = (val)) +#endif + +#include +#ifndef _D_EXACT_NAMLEN +# define _D_EXACT_NAMLEN(d) strlen ((d)->d_name) +#endif +#ifndef _D_ALLOC_NAMLEN +# define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1) +#endif + +#include +#include +#include + +#if _LIBC +# ifndef mempcpy +# define mempcpy __mempcpy +# endif +#endif + +#ifndef MAX +# define MAX(a, b) ((a) < (b) ? (b) : (a)) +#endif +#ifndef MIN +# define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* In this file, PATH_MAX only serves as a threshold for choosing among two + algorithms. */ +#ifndef PATH_MAX +# define PATH_MAX 8192 +#endif + +#if D_INO_IN_DIRENT +# define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino)) +#else +# define MATCHING_INO(dp, ino) true +#endif + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +#endif + +#if !_LIBC +# define GETCWD_RETURN_TYPE char * +# define __close_nocancel_nostatus close +# define __getcwd_generic rpl_getcwd +# undef stat64 +# define stat64 stat +# define __fstat64 fstat +# define __fstatat64 fstatat +# define __lstat64 lstat +# define __closedir closedir +# define __opendir opendir +# define __readdir64 readdir +# define __fdopendir fdopendir +# define __openat openat +# define __rewinddir rewinddir +# define __openat64 openat +# define dirent64 dirent +#else +# include +#endif + +/* The results of opendir() in this file are not used with dirfd and fchdir, + and we do not leak fds to any single-threaded code that could use stdio, + therefore save some unnecessary recursion in fchdir.c. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use opendir_safer and + openat_safer. */ +#ifdef GNULIB_defined_opendir +# undef opendir +#endif +#ifdef GNULIB_defined_closedir +# undef closedir +#endif + +#if defined _WIN32 && !defined __CYGWIN__ +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static char * +getcwd_nothrow (char *buf, size_t size) +{ + char *result; + + TRY_MSVC_INVAL + { + result = _getcwd (buf, size); + } + CATCH_MSVC_INVAL + { + result = NULL; + errno = ERANGE; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define getcwd_nothrow _getcwd +# endif +# define getcwd_system getcwd_nothrow +#else +# define getcwd_system getcwd +#endif + +/* Get the name of the current working directory, and put it in SIZE + bytes of BUF. Returns NULL with errno set if the directory couldn't be + determined or SIZE was too small. If successful, returns BUF. In GNU, + 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 necessary. */ + +GETCWD_RETURN_TYPE +__getcwd_generic (char *buf, size_t size) +{ + /* Lengths of big file name components and entire file names, and a + deep level of file name nesting. These numbers are not upper + bounds; they are merely large values suitable for initial + allocations, designed to be large enough for most real-world + uses. */ + enum + { + BIG_FILE_NAME_COMPONENT_LENGTH = 255, + BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1), + DEEP_NESTING = 100 + }; + +#if HAVE_OPENAT_SUPPORT + int fd = AT_FDCWD; + bool fd_needs_closing = false; +#else + char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1]; + char *dotlist = dots; + size_t dotsize = sizeof dots; + size_t dotlen = 0; +#endif + DIR *dirstream = NULL; + dev_t rootdev, thisdev; + ino_t rootino, thisino; + char *dir; + register char *dirp; + struct stat64 st; + size_t allocated = size; + size_t used; + +#if HAVE_MINIMALLY_WORKING_GETCWD + /* If AT_FDCWD is not defined, the algorithm below is O(N**2) and + this is much slower than the system getcwd (at least on + GNU/Linux). So trust the system getcwd's results unless they + look suspicious. + + Use the system getcwd even if we have openat support, since the + system getcwd works even when a parent is unreadable, while the + openat-based approach does not. + + But on AIX 5.1..7.1, the system getcwd is not even minimally + working: If the current directory name is slightly longer than + PATH_MAX, it omits the first directory component and returns + this wrong result with errno = 0. */ + +# undef getcwd + dir = getcwd_system (buf, size); + if (dir || (size && errno == ERANGE)) + return dir; + + /* Solaris getcwd (NULL, 0) fails with errno == EINVAL, but it has + internal magic that lets it work even if an ancestor directory is + inaccessible, which is better in many cases. So in this case try + again with a buffer that's almost always big enough. */ + if (errno == EINVAL && buf == NULL && size == 0) + { + char big_buffer[BIG_FILE_NAME_LENGTH + 1]; + dir = getcwd_system (big_buffer, sizeof big_buffer); + if (dir) + return strdup (dir); + } + +# if HAVE_PARTLY_WORKING_GETCWD + /* The system getcwd works, except it sometimes fails when it + shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. */ + if (errno != ERANGE && errno != ENAMETOOLONG && errno != ENOENT) + return NULL; +# endif +#endif + if (size == 0) + { + if (buf != NULL) + { + __set_errno (EINVAL); + return NULL; + } + + allocated = BIG_FILE_NAME_LENGTH + 1; + } + + if (buf == NULL) + { + dir = malloc (allocated); + if (dir == NULL) + return NULL; + } + else + dir = buf; + + dirp = dir + allocated; + *--dirp = '\0'; + + if (__lstat64 (".", &st) < 0) + goto lose; + thisdev = st.st_dev; + thisino = st.st_ino; + + if (__lstat64 ("/", &st) < 0) + goto lose; + rootdev = st.st_dev; + rootino = st.st_ino; + + while (!(thisdev == rootdev && thisino == rootino)) + { + struct dirent64 *d; + dev_t dotdev; + ino_t dotino; + bool mount_point; + int parent_status; + size_t dirroom; + size_t namlen; + bool use_d_ino = true; + + /* Look at the parent directory. */ +#if HAVE_OPENAT_SUPPORT + fd = __openat64 (fd, "..", O_RDONLY); + if (fd < 0) + goto lose; + fd_needs_closing = true; + parent_status = __fstat64 (fd, &st); +#else + dotlist[dotlen++] = '.'; + dotlist[dotlen++] = '.'; + dotlist[dotlen] = '\0'; + parent_status = __lstat64 (dotlist, &st); +#endif + if (parent_status != 0) + goto lose; + + if (dirstream && __closedir (dirstream) != 0) + { + dirstream = NULL; + goto lose; + } + + /* Figure out if this directory is a mount point. */ + dotdev = st.st_dev; + dotino = st.st_ino; + mount_point = dotdev != thisdev; + + /* Search for the last directory. */ +#if HAVE_OPENAT_SUPPORT + dirstream = __fdopendir (fd); + if (dirstream == NULL) + goto lose; + fd_needs_closing = false; +#else + dirstream = __opendir (dotlist); + if (dirstream == NULL) + goto lose; + dotlist[dotlen++] = '/'; +#endif + for (;;) + { + /* Clear errno to distinguish EOF from error if readdir returns + NULL. */ + __set_errno (0); + d = __readdir64 (dirstream); + + /* When we've iterated through all directory entries without finding + one with a matching d_ino, rewind the stream and consider each + name again, but this time, using lstat. This is necessary in a + chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where + .., ../.., ../../.., etc. all had the same device number, yet the + d_ino values for entries in / did not match those obtained + via lstat. */ + if (d == NULL && errno == 0 && use_d_ino) + { + use_d_ino = false; + __rewinddir (dirstream); + d = __readdir64 (dirstream); + } + + if (d == NULL) + { + if (errno == 0) + /* EOF on dirstream, which can mean e.g., that the current + directory has been removed. */ + __set_errno (ENOENT); + goto lose; + } + if (d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; + + if (use_d_ino) + { + bool match = (MATCHING_INO (d, thisino) || mount_point); + if (! match) + continue; + } + + { + int entry_status; +#if HAVE_OPENAT_SUPPORT + entry_status = __fstatat64 (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); +#else + /* Compute size needed for this file name, or for the file + name ".." in the same directory, whichever is larger. + Room for ".." might be needed the next time through + the outer loop. */ + size_t name_alloc = _D_ALLOC_NAMLEN (d); + size_t filesize = dotlen + MAX (sizeof "..", name_alloc); + + if (filesize < dotlen) + goto memory_exhausted; + + if (dotsize < filesize) + { + /* My, what a deep directory tree you have, Grandma. */ + size_t newsize = MAX (filesize, dotsize * 2); + size_t i; + if (newsize < dotsize) + goto memory_exhausted; + if (dotlist != dots) + free (dotlist); + dotlist = malloc (newsize); + if (dotlist == NULL) + goto lose; + dotsize = newsize; + + i = 0; + do + { + dotlist[i++] = '.'; + dotlist[i++] = '.'; + dotlist[i++] = '/'; + } + while (i < dotlen); + } + + memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); + entry_status = __lstat64 (dotlist, &st); +#endif + /* We don't fail here if we cannot stat() a directory entry. + This can happen when (network) file systems fail. If this + entry is in fact the one we are looking for we will find + out soon as we reach the end of the directory without + having found anything. */ + if (entry_status == 0 && S_ISDIR (st.st_mode) + && st.st_dev == thisdev && st.st_ino == thisino) + break; + } + } + + dirroom = dirp - dir; + namlen = _D_EXACT_NAMLEN (d); + + if (dirroom <= namlen) + { + if (size != 0) + { + __set_errno (ERANGE); + goto lose; + } + else + { + char *tmp; + size_t oldsize = allocated; + + allocated += MAX (allocated, namlen); + if (allocated < oldsize + || ! (tmp = realloc (dir, allocated))) + goto memory_exhausted; + + /* Move current contents up to the end of the buffer. + This is guaranteed to be non-overlapping. */ + dirp = memcpy (tmp + allocated - (oldsize - dirroom), + tmp + dirroom, + oldsize - dirroom); + dir = tmp; + } + } + dirp -= namlen; + memcpy (dirp, d->d_name, namlen); + *--dirp = '/'; + + thisdev = dotdev; + thisino = dotino; + } + + if (dirstream && __closedir (dirstream) != 0) + { + dirstream = NULL; + goto lose; + } + + if (dirp == &dir[allocated - 1]) + *--dirp = '/'; + +#if ! HAVE_OPENAT_SUPPORT + if (dotlist != dots) + free (dotlist); +#endif + + used = dir + allocated - dirp; + memmove (dir, dirp, used); + + if (size == 0) + /* Ensure that the buffer is only as large as necessary. */ + buf = (used < allocated ? realloc (dir, used) : dir); + + if (buf == NULL) + /* Either buf was NULL all along, or 'realloc' failed but + we still have the original string. */ + buf = dir; + + return buf; + + memory_exhausted: + __set_errno (ENOMEM); + lose: + { + int save = errno; + if (dirstream) + __closedir (dirstream); +#if HAVE_OPENAT_SUPPORT + if (fd_needs_closing) + __close_nocancel_nostatus (fd); +#else + if (dotlist != dots) + free (dotlist); +#endif + if (buf == NULL) + free (dir); + __set_errno (save); + } + return NULL; +} + +#if defined _LIBC && !defined GETCWD_RETURN_TYPE +libc_hidden_def (__getcwd) +weak_alias (__getcwd, getcwd) +#endif diff --git a/lib/getdelim.c b/lib/getdelim.c new file mode 100644 index 0000000..9eb0483 --- /dev/null +++ b/lib/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/lib/getdtablesize.c b/lib/getdtablesize.c new file mode 100644 index 0000000..793e0f8 --- /dev/null +++ b/lib/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/lib/getgroups.c b/lib/getgroups.c new file mode 100644 index 0000000..f7abd72 --- /dev/null +++ b/lib/getgroups.c @@ -0,0 +1,125 @@ +/* provide consistent interface to getgroups for systems that don't allow N==0 + + Copyright (C) 1996, 1999, 2003, 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 Jim Meyering */ + +#include + +#include + +#include +#include +#include + +#if !HAVE_GETGROUPS + +/* Provide a stub that fails with ENOSYS, since there is no group + information available on mingw. */ +int +getgroups (_GL_UNUSED int n, _GL_UNUSED GETGROUPS_T *groups) +{ + errno = ENOSYS; + return -1; +} + +#else /* HAVE_GETGROUPS */ + +# undef getgroups +# ifndef GETGROUPS_ZERO_BUG +# define GETGROUPS_ZERO_BUG 0 +# endif + +/* On OS X 10.6 and later, use the usual getgroups, not the one + supplied when _DARWIN_C_SOURCE is defined. _DARWIN_C_SOURCE is + normally defined, since it means "conform to POSIX, but add + non-POSIX extensions even if that violates the POSIX namespace + rules", which is what we normally want. But with getgroups there + is an inconsistency, and _DARWIN_C_SOURCE means "change getgroups() + so that it no longer works right". The BUGS section of compat(5) + says that the behavior is dubious if you compile different sections + of a program with different _DARWIN_C_SOURCE settings, so fix only + the offending symbol. */ +# ifdef __APPLE__ +int posix_getgroups (int, gid_t []) __asm ("_getgroups"); +# define getgroups posix_getgroups +# endif + +/* On at least NeXTstep 3.2, getgroups (0, NULL) always fails. + On other systems, it returns the number of supplemental + groups for the process. This function handles that special case + and lets the system-provided function handle all others. However, + it can fail with ENOMEM if memory is tight. It is unspecified + whether the effective group id is included in the list. */ + +int +rpl_getgroups (int n, gid_t *group) +{ + int n_groups; + GETGROUPS_T *gbuf; + + if (n < 0) + { + errno = EINVAL; + return -1; + } + + if (n != 0 || !GETGROUPS_ZERO_BUG) + { + int result; + if (sizeof *group == sizeof *gbuf) + return getgroups (n, (GETGROUPS_T *) group); + + if (SIZE_MAX / sizeof *gbuf <= n) + { + errno = ENOMEM; + return -1; + } + gbuf = malloc (n * sizeof *gbuf); + if (!gbuf) + return -1; + result = getgroups (n, gbuf); + if (0 <= result) + { + n = result; + while (n--) + group[n] = gbuf[n]; + } + free (gbuf); + return result; + } + + n = 20; + while (1) + { + /* No need to worry about address arithmetic overflow here, + since the ancient systems that we're running on have low + limits on the number of secondary groups. */ + gbuf = malloc (n * sizeof *gbuf); + if (!gbuf) + return -1; + n_groups = getgroups (n, gbuf); + if (n_groups == -1 ? errno != EINVAL : n_groups < n) + break; + free (gbuf); + n *= 2; + } + + free (gbuf); + return n_groups; +} + +#endif /* HAVE_GETGROUPS */ diff --git a/lib/getline.c b/lib/getline.c new file mode 100644 index 0000000..34b9117 --- /dev/null +++ b/lib/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/lib/getopt-cdefs.in.h b/lib/getopt-cdefs.in.h new file mode 100644 index 0000000..b6dd913 --- /dev/null +++ b/lib/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/lib/getopt-core.h b/lib/getopt-core.h new file mode 100644 index 0000000..1c40ecc --- /dev/null +++ b/lib/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/lib/getopt-ext.h b/lib/getopt-ext.h new file mode 100644 index 0000000..d661fcc --- /dev/null +++ b/lib/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/lib/getopt-pfx-core.h b/lib/getopt-pfx-core.h new file mode 100644 index 0000000..3eead0e --- /dev/null +++ b/lib/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/lib/getopt-pfx-ext.h b/lib/getopt-pfx-ext.h new file mode 100644 index 0000000..85a6cb5 --- /dev/null +++ b/lib/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/lib/getopt.c b/lib/getopt.c new file mode 100644 index 0000000..128dc7f --- /dev/null +++ b/lib/getopt.c @@ -0,0 +1,811 @@ +/* Getopt for GNU. + 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 + 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 "getopt.h" + +#include +#include +#include +#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 + +/* 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. + + 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" + +/* 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. */ + +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. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Keep a global copy of all internal members of getopt_data. */ + +static struct _getopt_data getopt_data; + +/* 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. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + 'first_nonopt' and 'last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (char **argv, struct _getopt_data *d) +{ + int bottom = d->__first_nonopt; + int middle = d->__last_nonopt; + int top = d->optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* 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; + 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. */ + + d->__first_nonopt += (d->optind - d->__last_nonopt); + d->__last_nonopt = d->optind; +} + +/* 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 (_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; + + /* Determine how to handle the ordering of options and nonoptions. */ + if (optstring[0] == '-') + { + d->__ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + d->__ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct || !!getenv ("POSIXLY_CORRECT")) + d->__ordering = REQUIRE_ORDER; + else + d->__ordering = PERMUTE; + + d->__initialized = 1; + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If 'getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If 'getopt' finds another option character, it returns that character, + updating 'optind' and 'nextchar' so that the next call to 'getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, 'getopt' returns -1. + Then 'optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set 'opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in 'optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in 'optarg', otherwise 'optarg' is set to zero. + + If OPTSTRING starts with '-' or '+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with '--' instead of '-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a '=', or else the in next ARGV-element. + When 'getopt' finds a long-named option, it returns 0 if that option's + 'flag' field is nonzero, the value of the option's 'val' field + if the 'flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of 'struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +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) +{ + int print_errors = d->opterr; + + if (argc < 1) + return -1; + + d->optarg = NULL; + + if (d->optind == 0 || !d->__initialized) + 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. */ +#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). */ + if (d->__last_nonopt > d->optind) + d->__last_nonopt = d->optind; + if (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 (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. */ + + 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. */ + + if (d->optind != argc && !strcmp (argv[d->optind], "--")) + { + d->optind++; + + 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; + } + + /* If we have done all the ARGV-elements, stop the scan + 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; + } + + /* 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. */ + + if (NONOPTION_P) + { + if (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + 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. */ + + { + char c = *d->__nextchar++; + const char *temp = strchr (optstring, c); + + /* Increment 'optind' when we start to process its last character. */ + if (*d->__nextchar == '\0') + ++d->optind; + + if (temp == NULL || c == ':' || c == ';') + { + 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] == ';' && longopts != NULL) + { + /* 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) + 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; + } +} + +int +_getopt_internal (int argc, char **argv, const char *optstring, + const struct option *longopts, int *longind, int long_only, + int posixly_correct) +{ + int result; + + getopt_data.optind = optind; + getopt_data.opterr = opterr; + + result = _getopt_internal_r (argc, argv, optstring, longopts, + longind, long_only, &getopt_data, + posixly_correct); + + optind = getopt_data.optind; + optarg = getopt_data.optarg; + optopt = getopt_data.optopt; + + return result; +} + +/* 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 +GETOPT_ENTRY(getopt, 0) +GETOPT_ENTRY(__posix_getopt, 1) +#else +GETOPT_ENTRY(getopt, 1) +#endif + + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of 'getopt'. */ + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + 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); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/lib/getopt.in.h b/lib/getopt.in.h new file mode 100644 index 0000000..9bc50ee --- /dev/null +++ b/lib/getopt.in.h @@ -0,0 +1,61 @@ +/* Declarations for getopt. + 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 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 _@GUARD_PREFIX@_GETOPT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. We must + also inform the replacement unistd.h to not recursively use + ; our definitions will be present soon enough. */ +#if @HAVE_GETOPT_H@ +# define _GL_SYSTEM_GETOPT +# @INCLUDE_NEXT@ @NEXT_GETOPT_H@ +# undef _GL_SYSTEM_GETOPT +#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 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 +# undef __need_system_stdlib_h +# include +# include +# endif +#endif + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +#include +#include +#include + +#endif /* _@GUARD_PREFIX@_GETOPT_H */ diff --git a/lib/getopt1.c b/lib/getopt1.c new file mode 100644 index 0000000..990eee1 --- /dev/null +++ b/lib/getopt1.c @@ -0,0 +1,159 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + 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 + 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 "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) +{ + return _getopt_internal (argc, (char **) argv, options, long_options, + 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) +{ + return _getopt_internal_r (argc, argv, options, long_options, opt_index, + 0, d, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (int argc, char *__getopt_argv_const *argv, + const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, (char **) argv, options, long_options, + 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) +{ + return _getopt_internal_r (argc, argv, options, long_options, opt_index, + 1, d, 0); +} + + +#ifdef TEST + +#include +#include + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + 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} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + 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); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/lib/getopt_int.h b/lib/getopt_int.h new file mode 100644 index 0000000..ccdbb97 --- /dev/null +++ b/lib/getopt_int.h @@ -0,0 +1,118 @@ +/* Internal declarations for getopt. + 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_INT_H +#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); + + +/* Reentrant versions which can handle parsing multiple argument + vectors at the same time. */ + +/* Describe how to deal with options that follow non-option ARGV-elements. + + 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. + + 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. + + The special argument '--' forces an end of option-scanning regardless + of the value of 'ordering'. In the case of RETURN_IN_ORDER, only + '--' can cause 'getopt' to return -1 with 'optind' != ARGC. */ + +enum __ord + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + }; + +/* Data type for reentrant functions. */ +struct _getopt_data +{ + /* These have exactly the same meaning as the corresponding global + variables, except that they are used for the reentrant + versions of getopt. */ + int optind; + int opterr; + int optopt; + char *optarg; + + /* Internal members. */ + + /* True if the internal members have been initialized. */ + int __initialized; + + /* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + char *__nextchar; + + /* See __ord above. */ + enum __ord __ordering; + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + been skipped. 'first_nonopt' is the index in ARGV of the first + of them; 'last_nonopt' is the index after the last of them. */ + + int __first_nonopt; + int __last_nonopt; +}; + +/* 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 } + +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); + +extern int _getopt_long_r (int ___argc, char **___argv, + 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); + +#endif /* getopt_int.h */ diff --git a/lib/getpass.c b/lib/getpass.c new file mode 100644 index 0000000..063985f --- /dev/null +++ b/lib/getpass.c @@ -0,0 +1,237 @@ +/* Copyright (C) 1992-2001, 2003-2007, 2009-2022 Free Software Foundation, Inc. + + This file is part of 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 _LIBC +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + warns for the null checks on 'prompt' below. */ +# define _GL_ARG_NONNULL(params) +# include +#endif + +#include "getpass.h" + +#include + +#if !(defined _WIN32 && !defined __CYGWIN__) + +# include + +# if HAVE_DECL___FSETLOCKING && HAVE___FSETLOCKING +# if HAVE_STDIO_EXT_H +# include +# endif +# else +# define __fsetlocking(stream, type) /* empty */ +# endif + +# if HAVE_TERMIOS_H +# include +# endif + +# if USE_UNLOCKED_IO +# include "unlocked-io.h" +# else +# if !HAVE_DECL_FFLUSH_UNLOCKED +# undef fflush_unlocked +# define fflush_unlocked(x) fflush (x) +# endif +# if !HAVE_DECL_FLOCKFILE +# undef flockfile +# define flockfile(x) ((void) 0) +# endif +# if !HAVE_DECL_FUNLOCKFILE +# undef funlockfile +# define funlockfile(x) ((void) 0) +# endif +# if !HAVE_DECL_FPUTS_UNLOCKED +# undef fputs_unlocked +# define fputs_unlocked(str,stream) fputs (str, stream) +# endif +# if !HAVE_DECL_PUTC_UNLOCKED +# undef putc_unlocked +# define putc_unlocked(c,stream) putc (c, stream) +# endif +# endif + +/* It is desirable to use this bit on systems that have it. + The only bit of terminal state we want to twiddle is echoing, which is + done in software; there is no need to change the state of the terminal + hardware. */ + +# ifndef TCSASOFT +# define TCSASOFT 0 +# endif + +static void +call_fclose (void *arg) +{ + if (arg != NULL) + fclose (arg); +} + +char * +getpass (const char *prompt) +{ + FILE *tty; + FILE *in, *out; +# if HAVE_TCGETATTR + struct termios s, t; +# endif + bool tty_changed = false; + static char *buf; + static size_t bufsize; + ssize_t nread; + + /* Try to write to and read from the terminal if we can. + If we can't open the terminal, use stderr and stdin. */ + + tty = fopen ("/dev/tty", "w+e"); + if (tty == NULL) + { + in = stdin; + out = stderr; + } + else + { + /* We do the locking ourselves. */ + __fsetlocking (tty, FSETLOCKING_BYCALLER); + + out = in = tty; + } + + flockfile (out); + + /* Turn echoing off if it is on now. */ +# if HAVE_TCGETATTR + if (tcgetattr (fileno (in), &t) == 0) + { + /* Save the old one. */ + s = t; + /* Tricky, tricky. */ + t.c_lflag &= ~(ECHO | ISIG); + tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0); + } +# endif + + if (prompt) + { + /* Write the prompt. */ + fputs_unlocked (prompt, out); + fflush_unlocked (out); + } + + /* Read the password. */ + nread = getline (&buf, &bufsize, in); + + /* According to the C standard, input may not be followed by output + on the same stream without an intervening call to a file + positioning function. Suppose in == out; then without this fseek + call, on Solaris, HP-UX, AIX, OSF/1, the previous input gets + echoed, whereas on IRIX, the following newline is not output as + it should be. POSIX imposes similar restrictions if fileno (in) + == fileno (out). The POSIX restrictions are tricky and change + from POSIX version to POSIX version, so play it safe and invoke + fseek even if in != out. */ + fseeko (out, 0, SEEK_CUR); + + if (buf != NULL) + { + if (nread < 0) + buf[0] = '\0'; + else if (buf[nread - 1] == '\n') + { + /* Remove the newline. */ + buf[nread - 1] = '\0'; + if (tty_changed) + { + /* Write the newline that was not echoed. */ + putc_unlocked ('\n', out); + } + } + } + + /* Restore the original setting. */ +# if HAVE_TCSETATTR + if (tty_changed) + tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s); +# endif + + funlockfile (out); + + call_fclose (tty); + + return buf; +} + +#else /* W32 native */ + +/* Windows implementation by Martin Lambers , + improved by Simon Josefsson. */ + +/* For PASS_MAX. */ +# include +/* For _getch(). */ +# include +/* For strdup(). */ +# include + +# ifndef PASS_MAX +# define PASS_MAX 512 +# endif + +char * +getpass (const char *prompt) +{ + char getpassbuf[PASS_MAX + 1]; + size_t i = 0; + int c; + + if (prompt) + { + fputs (prompt, stderr); + fflush (stderr); + } + + for (;;) + { + c = _getch (); + if (c == '\r') + { + getpassbuf[i] = '\0'; + break; + } + else if (i < PASS_MAX) + { + getpassbuf[i++] = c; + } + + if (i >= PASS_MAX) + { + getpassbuf[i] = '\0'; + break; + } + } + + if (prompt) + { + fputs ("\r\n", stderr); + fflush (stderr); + } + + return strdup (getpassbuf); +} +#endif diff --git a/lib/getpass.h b/lib/getpass.h new file mode 100644 index 0000000..8c05e87 --- /dev/null +++ b/lib/getpass.h @@ -0,0 +1,21 @@ +/* Read a password from /dec/tty. + + Copyright (C) 2004-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 . */ + +/* Obsolete; consider using unistd.h instead. */ + +/* Get getpass declaration, if available. */ +#include diff --git a/lib/getpeername.c b/lib/getpeername.c new file mode 100644 index 0000000..ac4926f --- /dev/null +++ b/lib/getpeername.c @@ -0,0 +1,49 @@ +/* getpeername.c --- wrappers for Windows getpeername function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef getpeername + +int +rpl_getpeername (int fd, struct sockaddr *addr, socklen_t *addrlen) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = getpeername (sock, addr, addrlen); + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/getprogname.c b/lib/getprogname.c new file mode 100644 index 0000000..62a4800 --- /dev/null +++ b/lib/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/lib/getprogname.h b/lib/getprogname.h new file mode 100644 index 0000000..9a35e58 --- /dev/null +++ b/lib/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/lib/getrandom.c b/lib/getrandom.c new file mode 100644 index 0000000..e146873 --- /dev/null +++ b/lib/getrandom.c @@ -0,0 +1,191 @@ +/* Obtain a series of random bytes. + + 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. */ + +#include + +#include + +#include +#include +#include +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# if HAVE_BCRYPT_H +# include +# else +# define NTSTATUS LONG +typedef void * BCRYPT_ALG_HANDLE; +# define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 +# if HAVE_LIB_BCRYPT +extern NTSTATUS WINAPI BCryptGenRandom (BCRYPT_ALG_HANDLE, UCHAR *, ULONG, ULONG); +# endif +# endif +# if !HAVE_LIB_BCRYPT +# include +# ifndef CRYPT_VERIFY_CONTEXT +# define CRYPT_VERIFY_CONTEXT 0xF0000000 +# endif +# endif +#endif + +#include "minmax.h" + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* Don't assume that UNICODE is not defined. */ +# undef LoadLibrary +# define LoadLibrary LoadLibraryA +# undef CryptAcquireContext +# define CryptAcquireContext CryptAcquireContextA + +# if !HAVE_LIB_BCRYPT + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress + +/* BCryptGenRandom with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag works only + starting with Windows 7. */ +typedef NTSTATUS (WINAPI * BCryptGenRandomFuncType) (BCRYPT_ALG_HANDLE, UCHAR *, ULONG, ULONG); +static BCryptGenRandomFuncType BCryptGenRandomFunc = NULL; +static BOOL initialized = FALSE; + +static void +initialize (void) +{ + HMODULE bcrypt = LoadLibrary ("bcrypt.dll"); + if (bcrypt != NULL) + { + BCryptGenRandomFunc = + (BCryptGenRandomFuncType) GetProcAddress (bcrypt, "BCryptGenRandom"); + } + initialized = TRUE; +} + +# else + +# define BCryptGenRandomFunc BCryptGenRandom + +# endif + +#else +/* These devices exist on all platforms except native Windows. */ + +/* Name of a device through which the kernel returns high quality random + numbers, from an entropy pool. When the pool is empty, the call blocks + until entropy sources have added enough bits of entropy. */ +# ifndef NAME_OF_RANDOM_DEVICE +# define NAME_OF_RANDOM_DEVICE "/dev/random" +# endif + +/* Name of a device through which the kernel returns random or pseudo-random + numbers. It uses an entropy pool, but, in order to avoid blocking, adds + bits generated by a pseudo-random number generator, as needed. */ +# ifndef NAME_OF_NONCE_DEVICE +# define NAME_OF_NONCE_DEVICE "/dev/urandom" +# endif + +#endif + +/* Set BUFFER (of size LENGTH) to random bytes under the control of FLAGS. + Return the number of bytes written (> 0). + Upon error, return -1 and set errno. */ +ssize_t +getrandom (void *buffer, size_t length, unsigned int flags) +#undef getrandom +{ +#if defined _WIN32 && ! defined __CYGWIN__ + /* BCryptGenRandom, defined in + + with the BCRYPT_USE_SYSTEM_PREFERRED_RNG flag + works in Windows 7 and newer. */ + static int bcrypt_not_working /* = 0 */; + if (!bcrypt_not_working) + { +# if !HAVE_LIB_BCRYPT + if (!initialized) + initialize (); +# endif + if (BCryptGenRandomFunc != NULL + && BCryptGenRandomFunc (NULL, buffer, length, + BCRYPT_USE_SYSTEM_PREFERRED_RNG) + == 0 /*STATUS_SUCCESS*/) + return length; + bcrypt_not_working = 1; + } +# if !HAVE_LIB_BCRYPT + /* CryptGenRandom, defined in + + works in older releases as well, but is now deprecated. + CryptAcquireContext, defined in + */ + { + static int crypt_initialized /* = 0 */; + static HCRYPTPROV provider; + if (!crypt_initialized) + { + if (CryptAcquireContext (&provider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFY_CONTEXT)) + crypt_initialized = 1; + else + crypt_initialized = -1; + } + if (crypt_initialized >= 0) + { + if (!CryptGenRandom (provider, length, buffer)) + { + errno = EIO; + return -1; + } + return length; + } + } +# endif + errno = ENOSYS; + return -1; +#elif HAVE_GETRANDOM + return getrandom (buffer, length, flags); +#else + static int randfd[2] = { -1, -1 }; + bool devrandom = (flags & GRND_RANDOM) != 0; + int fd = randfd[devrandom]; + + if (fd < 0) + { + static char const randdevice[][MAX (sizeof NAME_OF_NONCE_DEVICE, + sizeof NAME_OF_RANDOM_DEVICE)] + = { NAME_OF_NONCE_DEVICE, NAME_OF_RANDOM_DEVICE }; + int oflags = (O_RDONLY + O_CLOEXEC + + (flags & GRND_NONBLOCK ? O_NONBLOCK : 0)); + fd = open (randdevice[devrandom], oflags); + if (fd < 0) + { + if (errno == ENOENT || errno == ENOTDIR) + errno = ENOSYS; + return -1; + } + randfd[devrandom] = fd; + } + + return read (fd, buffer, length); +#endif +} diff --git a/lib/getsockname.c b/lib/getsockname.c new file mode 100644 index 0000000..3ab3a75 --- /dev/null +++ b/lib/getsockname.c @@ -0,0 +1,49 @@ +/* getsockname.c --- wrappers for Windows getsockname function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef getsockname + +int +rpl_getsockname (int fd, struct sockaddr *addr, socklen_t *addrlen) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = getsockname (sock, addr, addrlen); + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/gettext.h b/lib/gettext.h new file mode 100644 index 0000000..b3577a0 --- /dev/null +++ b/lib/gettext.h @@ -0,0 +1,300 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 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 . */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* 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 + +/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by + the gettext() and ngettext() macros. This is an alternative to calling + textdomain(), and is useful for libraries. */ +# ifdef DEFAULT_TEXT_DOMAIN +# undef gettext +# define gettext(Msgid) \ + dgettext (DEFAULT_TEXT_DOMAIN, Msgid) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) +# endif + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H +# include +# endif +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# undef gettext +# define gettext(Msgid) ((const char *) (Msgid)) +# undef dgettext +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# undef dcgettext +# define dcgettext(Domainname, Msgid, Category) \ + ((void) (Category), dgettext (Domainname, Msgid)) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) (Msgid1)) \ + : ((void) (Msgid1), (const char *) (Msgid2))) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) +# undef textdomain +# define textdomain(Domainname) ((const char *) (Domainname)) +# undef bindtextdomain +# define bindtextdomain(Domainname, Dirname) \ + ((void) (Domainname), (const char *) (Dirname)) +# undef bind_textdomain_codeset +# define bind_textdomain_codeset(Domainname, Codeset) \ + ((void) (Domainname), (const char *) (Codeset)) + +#endif + +/* Prefer gnulib's setlocale override over libintl's setlocale override. */ +#ifdef GNULIB_defined_setlocale +# undef setlocale +# define setlocale rpl_setlocale +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +/* The separator between msgctxt and msgid in a .mo file. */ +#define GETTEXT_CONTEXT_GLUE "\004" + +/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a + MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be + short and rarely need to change. + The letter 'p' stands for 'particular' or 'special'. */ +#ifdef DEFAULT_TEXT_DOMAIN +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#else +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#endif +#define dpgettext(Domainname, Msgctxt, Msgid) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) +#ifdef DEFAULT_TEXT_DOMAIN +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#else +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#endif +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) + +#if defined __GNUC__ || defined __clang__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +pgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + int category) +{ + const char *translation = dcgettext (domain, msg_ctxt_id, category); + if (translation == msg_ctxt_id) + return msgid; + else + return translation; +} + +#if defined __GNUC__ || defined __clang__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +npgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + const char *translation = + dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + if (translation == msg_ctxt_id || translation == msgid_plural) + return (n == 1 ? msgid : msgid_plural); + else + return translation; +} + +/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID + can be arbitrary expressions. But for string literals these macros are + less efficient than those above. */ + +#include + +/* 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 +#endif + +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS +#include +#endif + +#define pgettext_expr(Msgctxt, Msgid) \ + dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) +#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ + dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) + +#if defined __GNUC__ || defined __clang__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + 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 (found_translation) + return translation; + } + return msgid; +} + +#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) + +#if defined __GNUC__ || defined __clang__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcnpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + 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 (found_translation) + return translation; + } + return (n == 1 ? msgid : msgid_plural); +} + +#endif /* _LIBGETTEXT_H */ diff --git a/lib/gettime.c b/lib/gettime.c new file mode 100644 index 0000000..541af18 --- /dev/null +++ b/lib/gettime.c @@ -0,0 +1,51 @@ +/* gettime -- get the system clock + + Copyright (C) 2002, 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 3 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 + +#include "timespec.h" + +#include + +/* Get the system time into *TS. */ + +void +gettime (struct timespec *ts) +{ +#if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME + clock_gettime (CLOCK_REALTIME, ts); +#elif defined HAVE_TIMESPEC_GET + timespec_get (ts, TIME_UTC); +#else + struct timeval tv; + gettimeofday (&tv, NULL); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; +#endif +} + +/* Return the current system time as a struct timespec. */ + +struct timespec +current_timespec (void) +{ + struct timespec ts; + gettime (&ts); + return ts; +} diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c new file mode 100644 index 0000000..36c7920 --- /dev/null +++ b/lib/gettimeofday.c @@ -0,0 +1,153 @@ +/* Provide gettimeofday for systems that don't have it or for which it's broken. + + Copyright (C) 2001-2003, 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 Jim Meyering */ + +#include + +/* Specification. */ +#include + +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +# define WINDOWS_NATIVE +# include +#endif + +#ifdef WINDOWS_NATIVE + +/* Don't assume that UNICODE is not defined. */ +# undef LoadLibrary +# define LoadLibrary LoadLibraryA + +# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8) + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress + +/* GetSystemTimePreciseAsFileTime was introduced only in Windows 8. */ +typedef void (WINAPI * GetSystemTimePreciseAsFileTimeFuncType) (FILETIME *lpTime); +static GetSystemTimePreciseAsFileTimeFuncType GetSystemTimePreciseAsFileTimeFunc = NULL; +static BOOL initialized = FALSE; + +static void +initialize (void) +{ + HMODULE kernel32 = LoadLibrary ("kernel32.dll"); + if (kernel32 != NULL) + { + GetSystemTimePreciseAsFileTimeFunc = + (GetSystemTimePreciseAsFileTimeFuncType) GetProcAddress (kernel32, "GetSystemTimePreciseAsFileTime"); + } + initialized = TRUE; +} + +# else + +# define GetSystemTimePreciseAsFileTimeFunc GetSystemTimePreciseAsFileTime + +# endif + +#endif + +/* This is a wrapper for gettimeofday. It is used only on systems + that lack this function, or whose implementation of this function + causes problems. + Work around the bug in some systems whereby gettimeofday clobbers + the static buffer that localtime uses for its return value. The + gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has + this problem. */ + +int +gettimeofday (struct timeval *restrict tv, void *restrict tz) +{ +#undef gettimeofday +#ifdef WINDOWS_NATIVE + + /* On native Windows, there are two ways to get the current time: + GetSystemTimeAsFileTime + + or + GetSystemTimePreciseAsFileTime + . + GetSystemTimeAsFileTime produces values that jump by increments of + 15.627 milliseconds (!) on average. + Whereas GetSystemTimePreciseAsFileTime values usually jump by 1 or 2 + microseconds. + More discussion on this topic: + . */ + FILETIME current_time; + +# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8) + if (!initialized) + initialize (); +# endif + if (GetSystemTimePreciseAsFileTimeFunc != NULL) + GetSystemTimePreciseAsFileTimeFunc (¤t_time); + else + GetSystemTimeAsFileTime (¤t_time); + + /* Convert from FILETIME to 'struct timeval'. */ + /* FILETIME: */ + ULONGLONG since_1601 = + ((ULONGLONG) current_time.dwHighDateTime << 32) + | (ULONGLONG) current_time.dwLowDateTime; + /* Between 1601-01-01 and 1970-01-01 there were 280 normal years and 89 leap + years, in total 134774 days. */ + ULONGLONG since_1970 = + since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000; + ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10; + tv->tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000; + tv->tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000; + + return 0; + +#else + +# if HAVE_GETTIMEOFDAY + +# if defined timeval /* 'struct timeval' overridden by gnulib? */ +# undef timeval + struct timeval otv; + int result = gettimeofday (&otv, (struct timezone *) tz); + if (result == 0) + { + tv->tv_sec = otv.tv_sec; + tv->tv_usec = otv.tv_usec; + } +# else + int result = gettimeofday (tv, (struct timezone *) tz); +# endif + + return result; + +# else + +# if !defined OK_TO_USE_1S_CLOCK +# error "Only 1-second nominal clock resolution found. Is that intended?" \ + "If so, compile with the -DOK_TO_USE_1S_CLOCK option." +# endif + tv->tv_sec = time (NULL); + tv->tv_usec = 0; + + return 0; + +# endif +#endif +} diff --git a/lib/gl_openssl.h b/lib/gl_openssl.h new file mode 100644 index 0000000..4c42ac8 --- /dev/null +++ b/lib/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/lib/glthread/lock.c b/lib/glthread/lock.c new file mode 100644 index 0000000..b650c21 --- /dev/null +++ b/lib/glthread/lock.c @@ -0,0 +1,749 @@ +/* Locking in multithreaded situations. + 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-posix.h, gthr-posix95.h. */ + +#include + +#include "glthread/lock.h" + +/* ========================================================================= */ + +#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 && (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; + + 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) +{ + int err; + + err = pthread_rwlock_init (&lock->rwlock, NULL); + if (err != 0) + return err; + lock->initialized = 1; + return 0; +} + +int +glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) +{ + if (!lock->initialized) + { + int err; + + err = pthread_mutex_lock (&lock->guard); + if (err != 0) + return err; + if (!lock->initialized) + { + err = glthread_rwlock_init_multithreaded (lock); + if (err != 0) + { + pthread_mutex_unlock (&lock->guard); + return err; + } + } + err = pthread_mutex_unlock (&lock->guard); + if (err != 0) + return err; + } + return pthread_rwlock_rdlock (&lock->rwlock); +} + +int +glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) +{ + if (!lock->initialized) + { + int err; + + err = pthread_mutex_lock (&lock->guard); + if (err != 0) + return err; + if (!lock->initialized) + { + err = glthread_rwlock_init_multithreaded (lock); + if (err != 0) + { + pthread_mutex_unlock (&lock->guard); + return err; + } + } + err = pthread_mutex_unlock (&lock->guard); + if (err != 0) + return err; + } + return pthread_rwlock_wrlock (&lock->rwlock); +} + +int +glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) +{ + if (!lock->initialized) + return EINVAL; + return pthread_rwlock_unlock (&lock->rwlock); +} + +int +glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) +{ + int err; + + if (!lock->initialized) + return EINVAL; + err = pthread_rwlock_destroy (&lock->rwlock); + if (err != 0) + return err; + lock->initialized = 0; + return 0; +} + +# endif + +# else + +int +glthread_rwlock_init_multithreaded (gl_rwlock_t *lock) +{ + int err; + + err = pthread_mutex_init (&lock->lock, NULL); + if (err != 0) + return err; + err = pthread_cond_init (&lock->waiting_readers, NULL); + if (err != 0) + return err; + err = pthread_cond_init (&lock->waiting_writers, NULL); + if (err != 0) + return err; + lock->waiting_writers_count = 0; + lock->runcount = 0; + return 0; +} + +int +glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock) +{ + int err; + + err = pthread_mutex_lock (&lock->lock); + if (err != 0) + return err; + /* 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. */ + err = pthread_cond_wait (&lock->waiting_readers, &lock->lock); + if (err != 0) + { + pthread_mutex_unlock (&lock->lock); + return err; + } + } + lock->runcount++; + return pthread_mutex_unlock (&lock->lock); +} + +int +glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock) +{ + int err; + + err = pthread_mutex_lock (&lock->lock); + if (err != 0) + return err; + /* 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++; + err = pthread_cond_wait (&lock->waiting_writers, &lock->lock); + if (err != 0) + { + lock->waiting_writers_count--; + pthread_mutex_unlock (&lock->lock); + return err; + } + lock->waiting_writers_count--; + } + lock->runcount--; /* runcount becomes -1 */ + return pthread_mutex_unlock (&lock->lock); +} + +int +glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock) +{ + int err; + + err = pthread_mutex_lock (&lock->lock); + if (err != 0) + return err; + if (lock->runcount < 0) + { + /* Drop a writer lock. */ + if (!(lock->runcount == -1)) + { + pthread_mutex_unlock (&lock->lock); + return EINVAL; + } + lock->runcount = 0; + } + else + { + /* Drop a reader lock. */ + if (!(lock->runcount > 0)) + { + pthread_mutex_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. */ + err = pthread_cond_signal (&lock->waiting_writers); + if (err != 0) + { + pthread_mutex_unlock (&lock->lock); + return err; + } + } + else + { + /* Wake up all waiting readers. */ + err = pthread_cond_broadcast (&lock->waiting_readers); + if (err != 0) + { + pthread_mutex_unlock (&lock->lock); + return err; + } + } + } + return pthread_mutex_unlock (&lock->lock); +} + +int +glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock) +{ + int err; + + err = pthread_mutex_destroy (&lock->lock); + if (err != 0) + return err; + err = pthread_cond_destroy (&lock->waiting_readers); + if (err != 0) + return err; + err = pthread_cond_destroy (&lock->waiting_writers); + if (err != 0) + return err; + return 0; +} + +# endif + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +# if HAVE_PTHREAD_MUTEX_RECURSIVE + +# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + +int +glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) +{ + pthread_mutexattr_t attributes; + int err; + + err = pthread_mutexattr_init (&attributes); + if (err != 0) + return err; + err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); + if (err != 0) + { + pthread_mutexattr_destroy (&attributes); + return err; + } + err = pthread_mutex_init (lock, &attributes); + if (err != 0) + { + pthread_mutexattr_destroy (&attributes); + return err; + } + err = pthread_mutexattr_destroy (&attributes); + if (err != 0) + return err; + return 0; +} + +# else + +int +glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) +{ + pthread_mutexattr_t attributes; + int err; + + err = pthread_mutexattr_init (&attributes); + if (err != 0) + return err; + err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); + if (err != 0) + { + pthread_mutexattr_destroy (&attributes); + return err; + } + err = pthread_mutex_init (&lock->recmutex, &attributes); + if (err != 0) + { + pthread_mutexattr_destroy (&attributes); + return err; + } + err = pthread_mutexattr_destroy (&attributes); + if (err != 0) + return err; + lock->initialized = 1; + return 0; +} + +int +glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock) +{ + if (!lock->initialized) + { + int err; + + err = pthread_mutex_lock (&lock->guard); + if (err != 0) + return err; + if (!lock->initialized) + { + err = glthread_recursive_lock_init_multithreaded (lock); + if (err != 0) + { + pthread_mutex_unlock (&lock->guard); + return err; + } + } + err = pthread_mutex_unlock (&lock->guard); + if (err != 0) + return err; + } + return pthread_mutex_lock (&lock->recmutex); +} + +int +glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock) +{ + if (!lock->initialized) + return EINVAL; + return pthread_mutex_unlock (&lock->recmutex); +} + +int +glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) +{ + int err; + + if (!lock->initialized) + return EINVAL; + err = pthread_mutex_destroy (&lock->recmutex); + if (err != 0) + return err; + lock->initialized = 0; + return 0; +} + +# endif + +# else + +int +glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock) +{ + int err; + + err = pthread_mutex_init (&lock->mutex, NULL); + if (err != 0) + return err; + lock->owner = (pthread_t) 0; + lock->depth = 0; + return 0; +} + +int +glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock) +{ + pthread_t self = pthread_self (); + if (lock->owner != self) + { + int err; + + err = pthread_mutex_lock (&lock->mutex); + if (err != 0) + return err; + lock->owner = self; + } + if (++(lock->depth) == 0) /* wraparound? */ + { + lock->depth--; + return EAGAIN; + } + return 0; +} + +int +glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock) +{ + if (lock->owner != pthread_self ()) + return EPERM; + if (lock->depth == 0) + return EINVAL; + if (--(lock->depth) == 0) + { + lock->owner = (pthread_t) 0; + return pthread_mutex_unlock (&lock->mutex); + } + else + return 0; +} + +int +glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) +{ + if (lock->owner != (pthread_t) 0) + return EBUSY; + return pthread_mutex_destroy (&lock->mutex); +} + +# endif + +/* -------------------------- gl_once_t datatype -------------------------- */ + +static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; + +int +glthread_once_singlethreaded (pthread_once_t *once_control) +{ + /* We don't know whether pthread_once_t is an integer type, a floating-point + type, a pointer type, or a structure type. */ + char *firstbyte = (char *)once_control; + if (*firstbyte == *(const char *)&fresh_once) + { + /* First time use of once_control. Invert the first byte. */ + *firstbyte = ~ *(const char *)&fresh_once; + return 1; + } + else + return 0; +} + +# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) + +int +glthread_once_multithreaded (pthread_once_t *once_control, + void (*init_function) (void)) +{ + int err = pthread_once (once_control, init_function); + if (err == ENOSYS) + { + /* This happens on FreeBSD 11: The pthread_once function in libc returns + ENOSYS. */ + if (glthread_once_singlethreaded (once_control)) + init_function (); + return 0; + } + return err; +} + +# endif + +#endif + +/* ========================================================================= */ + +#if USE_WINDOWS_THREADS + +#endif + +/* ========================================================================= */ diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h new file mode 100644 index 0000000..47eed8f --- /dev/null +++ b/lib/glthread/lock.h @@ -0,0 +1,791 @@ +/* Locking in multithreaded situations. + 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-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 + synchronization primitives. + + Normal (non-recursive) locks: + Type: gl_lock_t + Declaration: gl_lock_define(extern, name) + Initializer: gl_lock_define_initialized(, name) + Initialization: gl_lock_init (name); + Taking the lock: gl_lock_lock (name); + Releasing the lock: gl_lock_unlock (name); + De-initialization: gl_lock_destroy (name); + Equivalent functions with control of error handling: + Initialization: err = glthread_lock_init (&name); + Taking the lock: err = glthread_lock_lock (&name); + Releasing the lock: err = glthread_lock_unlock (&name); + De-initialization: err = glthread_lock_destroy (&name); + + Read-Write (non-recursive) locks: + Type: gl_rwlock_t + Declaration: gl_rwlock_define(extern, name) + Initializer: gl_rwlock_define_initialized(, name) + Initialization: gl_rwlock_init (name); + Taking the lock: gl_rwlock_rdlock (name); + gl_rwlock_wrlock (name); + Releasing the lock: gl_rwlock_unlock (name); + De-initialization: gl_rwlock_destroy (name); + Equivalent functions with control of error handling: + Initialization: err = glthread_rwlock_init (&name); + Taking the lock: err = glthread_rwlock_rdlock (&name); + err = glthread_rwlock_wrlock (&name); + Releasing the lock: err = glthread_rwlock_unlock (&name); + De-initialization: err = glthread_rwlock_destroy (&name); + + Recursive locks: + Type: gl_recursive_lock_t + Declaration: gl_recursive_lock_define(extern, name) + Initializer: gl_recursive_lock_define_initialized(, name) + Initialization: gl_recursive_lock_init (name); + Taking the lock: gl_recursive_lock_lock (name); + Releasing the lock: gl_recursive_lock_unlock (name); + De-initialization: gl_recursive_lock_destroy (name); + Equivalent functions with control of error handling: + Initialization: err = glthread_recursive_lock_init (&name); + Taking the lock: err = glthread_recursive_lock_lock (&name); + Releasing the lock: err = glthread_recursive_lock_unlock (&name); + De-initialization: err = glthread_recursive_lock_destroy (&name); + + Once-only execution: + Type: gl_once_t + Initializer: gl_once_define(extern, name) + Execution: gl_once (name, initfunction); + Equivalent functions with control of error handling: + Execution: err = glthread_once (&name, initfunction); +*/ + + +#ifndef _LOCK_H +#define _LOCK_H + +#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 + +/* Use the POSIX threads library. */ + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# if PTHREAD_IN_USE_DETECTION_HARD + +/* The pthread_in_use() detection needs to be done at runtime. */ +# define pthread_in_use() \ + glthread_in_use () +extern int glthread_in_use (void); + +# endif + +# if USE_POSIX_THREADS_WEAK + +/* Use weak references to the POSIX threads library. */ + +/* Weak references avoid dragging in external libraries if the other parts + of the program don't use them. Here we use them, because we don't want + every program that uses libintl to depend on libpthread. This assumes + that libpthread would not be loaded after libintl; i.e. if libintl is + loaded first, by an executable that does not depend on libpthread, and + then a module is dynamically loaded that depends on libpthread, libintl + will not be multithread-safe. */ + +/* The way to test at runtime whether libpthread is present is to test + whether a function pointer's value, such as &pthread_mutex_init, is + non-NULL. However, some versions of GCC have a bug through which, in + PIC mode, &foo != NULL always evaluates to true if there is a direct + call to foo(...) in the same function. To avoid this, we test the + address of a function in libpthread that we don't use. */ + +# pragma weak pthread_mutex_init +# pragma weak pthread_mutex_lock +# pragma weak pthread_mutex_unlock +# pragma weak pthread_mutex_destroy +# pragma weak pthread_rwlock_init +# pragma weak pthread_rwlock_rdlock +# pragma weak pthread_rwlock_wrlock +# pragma weak pthread_rwlock_unlock +# pragma weak pthread_rwlock_destroy +# pragma weak pthread_once +# pragma weak pthread_cond_init +# pragma weak pthread_cond_wait +# pragma weak pthread_cond_signal +# pragma weak pthread_cond_broadcast +# pragma weak pthread_cond_destroy +# 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 + /* 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 + +# if !PTHREAD_IN_USE_DETECTION_HARD +# define pthread_in_use() 1 +# endif + +# endif + +/* -------------------------- gl_lock_t datatype -------------------------- */ + +typedef pthread_mutex_t gl_lock_t; +# define gl_lock_define(STORAGECLASS, NAME) \ + STORAGECLASS pthread_mutex_t NAME; +# define gl_lock_define_initialized(STORAGECLASS, NAME) \ + STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer; +# define gl_lock_initializer \ + PTHREAD_MUTEX_INITIALIZER +# define glthread_lock_init(LOCK) \ + (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0) +# define glthread_lock_lock(LOCK) \ + (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0) +# define glthread_lock_unlock(LOCK) \ + (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0) +# define glthread_lock_destroy(LOCK) \ + (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0) + +/* ------------------------- gl_rwlock_t datatype ------------------------- */ + +# 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 + +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; +# 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) \ + (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0) +# define glthread_rwlock_unlock(LOCK) \ + (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0) +# define glthread_rwlock_destroy(LOCK) \ + (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0) + +# else + +typedef struct + { + int initialized; + pthread_mutex_t guard; /* protects the initialization */ + pthread_rwlock_t rwlock; /* read-write lock */ + } + 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, PTHREAD_MUTEX_INITIALIZER } +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) +# define glthread_rwlock_rdlock(LOCK) \ + (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_wrlock(LOCK) \ + (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_unlock(LOCK) \ + (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_destroy(LOCK) \ + (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0) +extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock); + +# endif + +# else + +typedef struct + { + pthread_mutex_t lock; /* protects the remaining fields */ + pthread_cond_t waiting_readers; /* waiting readers */ + pthread_cond_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) \ + STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 } +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) +# define glthread_rwlock_rdlock(LOCK) \ + (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_wrlock(LOCK) \ + (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_unlock(LOCK) \ + (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_destroy(LOCK) \ + (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0) +extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock); + +# endif + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +# if HAVE_PTHREAD_MUTEX_RECURSIVE + +# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + +typedef pthread_mutex_t gl_recursive_lock_t; +# define gl_recursive_lock_define(STORAGECLASS, NAME) \ + STORAGECLASS pthread_mutex_t NAME; +# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ + STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer; +# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER +# define gl_recursive_lock_initializer \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER +# else +# define gl_recursive_lock_initializer \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +# endif +# define glthread_recursive_lock_init(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_lock(LOCK) \ + (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0) +# define glthread_recursive_lock_unlock(LOCK) \ + (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0) +# define glthread_recursive_lock_destroy(LOCK) \ + (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0) +extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock); + +# else + +typedef struct + { + pthread_mutex_t recmutex; /* recursive mutex */ + pthread_mutex_t guard; /* protects the initialization */ + int initialized; + } + 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 \ + { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 } +# define glthread_recursive_lock_init(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_lock(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_unlock(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_destroy(LOCK) \ + (pthread_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); + +# endif + +# else + +/* Old versions of POSIX threads on Solaris did not have recursive locks. + We have to implement them ourselves. */ + +typedef struct + { + pthread_mutex_t mutex; + pthread_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 \ + { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 } +# define glthread_recursive_lock_init(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_lock(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_unlock(LOCK) \ + (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0) +# define glthread_recursive_lock_destroy(LOCK) \ + (pthread_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); + +# endif + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef pthread_once_t gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; +# 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 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 +extern int glthread_once_singlethreaded (pthread_once_t *once_control); + +# ifdef __cplusplus +} +# endif + +#endif + +/* ========================================================================= */ + +#if USE_WINDOWS_THREADS + +# 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 + +/* We can use CRITICAL_SECTION directly, rather than the native Windows Event, + Mutex, Semaphore types, because + - we need only to synchronize inside a single process (address space), + not inter-process locking, + - we don't need to support trylock operations. (TryEnterCriticalSection + does not work on Windows 95/98/ME. Packages that need trylock usually + define their own mutex type.) */ + +/* There is no way to statically initialize a CRITICAL_SECTION. It needs + to be done lazily, once only. For this we need spinlocks. */ + +/* -------------------------- gl_lock_t datatype -------------------------- */ + +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 \ + GLWTHREAD_MUTEX_INIT +# define glthread_lock_init(LOCK) \ + (glwthread_mutex_init (LOCK), 0) +# define glthread_lock_lock(LOCK) \ + glwthread_mutex_lock (LOCK) +# define glthread_lock_unlock(LOCK) \ + glwthread_mutex_unlock (LOCK) +# define glthread_lock_destroy(LOCK) \ + glwthread_mutex_destroy (LOCK) + +/* ------------------------- gl_rwlock_t datatype ------------------------- */ + +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 \ + GLWTHREAD_RWLOCK_INIT +# define glthread_rwlock_init(LOCK) \ + (glwthread_rwlock_init (LOCK), 0) +# define glthread_rwlock_rdlock(LOCK) \ + glwthread_rwlock_rdlock (LOCK) +# define glthread_rwlock_wrlock(LOCK) \ + glwthread_rwlock_wrlock (LOCK) +# define glthread_rwlock_unlock(LOCK) \ + glwthread_rwlock_unlock (LOCK) +# define glthread_rwlock_destroy(LOCK) \ + glwthread_rwlock_destroy (LOCK) + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +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 \ + GLWTHREAD_RECMUTEX_INIT +# define glthread_recursive_lock_init(LOCK) \ + (glwthread_recmutex_init (LOCK), 0) +# define glthread_recursive_lock_lock(LOCK) \ + glwthread_recmutex_lock (LOCK) +# define glthread_recursive_lock_unlock(LOCK) \ + glwthread_recmutex_unlock (LOCK) +# define glthread_recursive_lock_destroy(LOCK) \ + glwthread_recmutex_destroy (LOCK) + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef glwthread_once_t gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) + +# ifdef __cplusplus +} +# endif + +#endif + +/* ========================================================================= */ + +#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) + +/* Provide dummy implementation if threads are not supported. */ + +/* -------------------------- gl_lock_t datatype -------------------------- */ + +typedef int gl_lock_t; +# define gl_lock_define(STORAGECLASS, NAME) +# define gl_lock_define_initialized(STORAGECLASS, NAME) +# define glthread_lock_init(NAME) 0 +# define glthread_lock_lock(NAME) 0 +# define glthread_lock_unlock(NAME) 0 +# define glthread_lock_destroy(NAME) 0 + +/* ------------------------- gl_rwlock_t datatype ------------------------- */ + +typedef int gl_rwlock_t; +# define gl_rwlock_define(STORAGECLASS, NAME) +# define gl_rwlock_define_initialized(STORAGECLASS, NAME) +# define glthread_rwlock_init(NAME) 0 +# define glthread_rwlock_rdlock(NAME) 0 +# define glthread_rwlock_wrlock(NAME) 0 +# define glthread_rwlock_unlock(NAME) 0 +# define glthread_rwlock_destroy(NAME) 0 + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +typedef int gl_recursive_lock_t; +# define gl_recursive_lock_define(STORAGECLASS, NAME) +# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) +# define glthread_recursive_lock_init(NAME) 0 +# define glthread_recursive_lock_lock(NAME) 0 +# define glthread_recursive_lock_unlock(NAME) 0 +# define glthread_recursive_lock_destroy(NAME) 0 + +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef int gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_once_t NAME = 0; +# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ + (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) + +#endif + +/* ========================================================================= */ + +/* Macros with built-in error handling. */ + +/* -------------------------- gl_lock_t datatype -------------------------- */ + +#define gl_lock_init(NAME) \ + do \ + { \ + if (glthread_lock_init (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_lock_lock(NAME) \ + do \ + { \ + if (glthread_lock_lock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_lock_unlock(NAME) \ + do \ + { \ + if (glthread_lock_unlock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_lock_destroy(NAME) \ + do \ + { \ + if (glthread_lock_destroy (&NAME)) \ + abort (); \ + } \ + while (0) + +/* ------------------------- gl_rwlock_t datatype ------------------------- */ + +#define gl_rwlock_init(NAME) \ + do \ + { \ + if (glthread_rwlock_init (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_rwlock_rdlock(NAME) \ + do \ + { \ + if (glthread_rwlock_rdlock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_rwlock_wrlock(NAME) \ + do \ + { \ + if (glthread_rwlock_wrlock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_rwlock_unlock(NAME) \ + do \ + { \ + if (glthread_rwlock_unlock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_rwlock_destroy(NAME) \ + do \ + { \ + if (glthread_rwlock_destroy (&NAME)) \ + abort (); \ + } \ + while (0) + +/* --------------------- gl_recursive_lock_t datatype --------------------- */ + +#define gl_recursive_lock_init(NAME) \ + do \ + { \ + if (glthread_recursive_lock_init (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_recursive_lock_lock(NAME) \ + do \ + { \ + if (glthread_recursive_lock_lock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_recursive_lock_unlock(NAME) \ + do \ + { \ + if (glthread_recursive_lock_unlock (&NAME)) \ + abort (); \ + } \ + while (0) +#define gl_recursive_lock_destroy(NAME) \ + do \ + { \ + if (glthread_recursive_lock_destroy (&NAME)) \ + abort (); \ + } \ + while (0) + +/* -------------------------- gl_once_t datatype -------------------------- */ + +#define gl_once(NAME, INITFUNCTION) \ + do \ + { \ + if (glthread_once (&NAME, INITFUNCTION)) \ + abort (); \ + } \ + while (0) + +/* ========================================================================= */ + +#endif /* _LOCK_H */ diff --git a/lib/glthread/threadlib.c b/lib/glthread/threadlib.c new file mode 100644 index 0000000..88a76ba --- /dev/null +++ b/lib/glthread/threadlib.c @@ -0,0 +1,108 @@ +/* Multithreading primitives. + 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. */ + +#include + +/* ========================================================================= */ + +#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) +{ + return arg; +} + +int +glthread_in_use (void) +{ + static int tested; + static int result; /* 1: linked with -lpthread, 0: only with libc */ + + if (!tested) + { + pthread_t thread; + + if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0) + /* Thread creation failed. */ + result = 0; + else + { + /* Thread creation works. */ + void *retval; + if (pthread_join (thread, &retval) != 0) + abort (); + result = 1; + } + tested = 1; + } + return result; +} + +# endif + +# endif + +#endif + +/* ========================================================================= */ + +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; diff --git a/lib/gnulib.mk b/lib/gnulib.mk new file mode 100644 index 0000000..5ce3120 --- /dev/null +++ b/lib/gnulib.mk @@ -0,0 +1,4711 @@ +## DO NOT EDIT! GENERATED AUTOMATICALLY! +## Process this file with automake to produce Makefile.in. +# 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 +# (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. +# +# You should have received a copy of the GNU General Public License +# 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 +# contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# Reproduce by: +# gnulib-tool --import --local-dir=gl \ +# --lib=libgnu \ +# --source-base=lib \ +# --m4-base=m4 \ +# --po-base=gnulib_po \ +# --doc-base=doc \ +# --tests-base=lib/tests \ +# --aux-dir=build-aux \ +# --makefile-name=gnulib.mk \ +# --no-conditional-dependencies \ +# --no-libtool \ +# --macro-prefix=gl \ +# --po-domain=wget \ +# accept \ +# announce-gen \ +# base32 \ +# bind \ +# c-ctype \ +# c-strcase \ +# c-strcasestr \ +# clock-time \ +# close \ +# connect \ +# crypto/md2 \ +# crypto/md4 \ +# crypto/md5 \ +# crypto/sha1 \ +# crypto/sha256 \ +# crypto/sha512 \ +# dirname \ +# fcntl \ +# flock \ +# fnmatch-gnu \ +# fopen \ +# ftello \ +# futimens \ +# gendocs \ +# getaddrinfo \ +# getline \ +# getopt-gnu \ +# getpass-gnu \ +# getpeername \ +# getsockname \ +# gettext-h \ +# git-version-gen \ +# gitlog-to-changelog \ +# gnu-web-doc-update \ +# gnupload \ +# group-member \ +# hostent \ +# iconv \ +# iconv-h \ +# inet_ntop \ +# intprops \ +# inttypes \ +# ioctl \ +# langinfo \ +# libunistring-optional \ +# limits-h \ +# link \ +# listen \ +# maintainer-makefile \ +# mbiter \ +# mbtowc \ +# memrchr \ +# mkdir \ +# mkostemp \ +# mkstemp \ +# nanosleep \ +# open \ +# pipe-posix \ +# posix_spawn \ +# quote \ +# quotearg \ +# recv \ +# regex \ +# rename \ +# select \ +# send \ +# setsockopt \ +# signal-h \ +# sigpipe \ +# sigprocmask \ +# snprintf \ +# socket \ +# spawn-pipe \ +# stat \ +# stdbool \ +# stdint \ +# strcase \ +# strerror_r-posix \ +# strpbrk \ +# strptime \ +# strtok_r \ +# strtol \ +# strtoll \ +# symlink \ +# sys_types \ +# timegm \ +# tmpdir \ +# unicase/u8-tolower \ +# unistr/u8-strlen \ +# unlink \ +# unlocked-io \ +# update-copyright \ +# utime \ +# utimens \ +# vasprintf \ +# vsnprintf \ +# warnings \ +# wcwidth \ +# write \ +# xmemdup0 \ +# xstrndup + + +MOSTLYCLEANFILES += core *.stackdump +# No GNU Make output. + +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 = + +AM_CPPFLAGS += -DDEFAULT_TEXT_DOMAIN=\"wget-gnulib\" + +## 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 accept + +if GL_COND_OBJ_ACCEPT +libgnu_a_SOURCES += accept.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module accept + +## begin gnulib module access + +if GL_COND_OBJ_ACCESS +libgnu_a_SOURCES += access.c +endif + +## end gnulib module access + +## begin gnulib module alloca + + +libgnu_a_LIBADD += @ALLOCA@ +libgnu_a_DEPENDENCIES += @ALLOCA@ +EXTRA_DIST += alloca.c + +EXTRA_libgnu_a_SOURCES += alloca.c + +## end gnulib module alloca + +## begin gnulib module alloca-opt + +BUILT_SOURCES += $(ALLOCA_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_ALLOCA_H +alloca.h: alloca.in.h $(top_builddir)/config.status + $(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 $@ +endif +MOSTLYCLEANFILES += alloca.h alloca.h-t + +EXTRA_DIST += alloca.in.h + +## end gnulib module alloca-opt + +## begin gnulib module announce-gen + + +EXTRA_DIST += $(top_srcdir)/build-aux/announce-gen + +## end gnulib module announce-gen + +## begin gnulib module arpa_inet + +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_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''@/$(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' \ + -e 's|@''REPLACE_INET_PTON''@|$(REPLACE_INET_PTON)|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)/arpa_inet.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += arpa/inet.h arpa/inet.h-t +MOSTLYCLEANDIRS += arpa + +EXTRA_DIST += arpa_inet.in.h + +## end gnulib module arpa_inet + +## begin gnulib module array-mergesort + + +EXTRA_DIST += array-mergesort.h + +## end gnulib module array-mergesort + +## begin gnulib module assure + + +EXTRA_DIST += assure.h + +## end gnulib module assure + +## begin gnulib module at-internal + +libgnu_a_SOURCES += openat-priv.h openat-proc.c + +## end gnulib module at-internal + +## begin gnulib module attribute + + +EXTRA_DIST += attribute.h + +## end gnulib module attribute + +## begin gnulib module base32 + +libgnu_a_SOURCES += base32.h base32.c + +## end gnulib module base32 + +## begin gnulib module basename-lgpl + +libgnu_a_SOURCES += basename-lgpl.c + +EXTRA_DIST += basename-lgpl.h + +## end gnulib module basename-lgpl + +## begin gnulib module binary-io + +libgnu_a_SOURCES += binary-io.h binary-io.c + +## end gnulib module binary-io + +## begin gnulib module bind + +if GL_COND_OBJ_BIND +libgnu_a_SOURCES += bind.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module bind + +## begin gnulib module bitrotate + +libgnu_a_SOURCES += bitrotate.h bitrotate.c + +## end gnulib module bitrotate + +## begin gnulib module btowc + +if GL_COND_OBJ_BTOWC +libgnu_a_SOURCES += btowc.c +endif + +## end gnulib module btowc + +## 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 c-ctype + +libgnu_a_SOURCES += c-ctype.h c-ctype.c + +## end gnulib module c-ctype + +## begin gnulib module c-strcase + +libgnu_a_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c + +## end gnulib module c-strcase + +## begin gnulib module c-strcaseeq + + +EXTRA_DIST += c-strcaseeq.h + +## end gnulib module c-strcaseeq + +## begin gnulib module c-strcasestr + +libgnu_a_SOURCES += c-strcasestr.h c-strcasestr.c + +EXTRA_DIST += str-two-way.h + +## end gnulib module c-strcasestr + +## 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 canonicalize + +libgnu_a_SOURCES += canonicalize.c + +EXTRA_DIST += canonicalize.h + +## end gnulib module canonicalize + +## begin gnulib module canonicalize-lgpl + +if GL_COND_OBJ_CANONICALIZE_LGPL +libgnu_a_SOURCES += canonicalize-lgpl.c +endif + +## end gnulib module canonicalize-lgpl + +## begin gnulib module chdir-long + +if GL_COND_OBJ_CHDIR_LONG +libgnu_a_SOURCES += chdir-long.c +endif + +EXTRA_DIST += chdir-long.h + +## end gnulib module chdir-long + +## 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 closedir + +if GL_COND_OBJ_CLOSEDIR +libgnu_a_SOURCES += closedir.c +endif + +EXTRA_DIST += dirent-private.h + +## end gnulib module closedir + +## begin gnulib module concat-filename + +libgnu_a_SOURCES += concat-filename.c + +EXTRA_DIST += concat-filename.h + +## end gnulib module concat-filename + +## begin gnulib module connect + +if GL_COND_OBJ_CONNECT +libgnu_a_SOURCES += connect.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module connect + +## 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/md2 + +libgnu_a_SOURCES += md2-stream.c + +## end gnulib module crypto/md2 + +## begin gnulib module crypto/md2-buffer + +libgnu_a_SOURCES += md2.c + +EXTRA_DIST += md2.h + +## end gnulib module crypto/md2-buffer + +## begin gnulib module crypto/md4 + +libgnu_a_SOURCES += md4-stream.c + +## end gnulib module crypto/md4 + +## begin gnulib module crypto/md4-buffer + +libgnu_a_SOURCES += md4.c + +EXTRA_DIST += md4.h + +## end gnulib module crypto/md4-buffer + +## begin gnulib module crypto/md5 + +libgnu_a_SOURCES += md5-stream.c + +## end gnulib module crypto/md5 + +## begin gnulib module crypto/md5-buffer + +libgnu_a_SOURCES += md5.c + +EXTRA_DIST += gl_openssl.h md5.h + +## end gnulib module crypto/md5-buffer + +## 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 += gl_openssl.h sha1.h + +## end gnulib module crypto/sha1-buffer + +## begin gnulib module crypto/sha256 + +libgnu_a_SOURCES += sha256-stream.c + +## end gnulib module crypto/sha256 + +## begin gnulib module crypto/sha256-buffer + +libgnu_a_SOURCES += sha256.c + +EXTRA_DIST += gl_openssl.h sha256.h + +## end gnulib module crypto/sha256-buffer + +## begin gnulib module crypto/sha512 + +libgnu_a_SOURCES += sha512-stream.c + +## end gnulib module crypto/sha512 + +## begin gnulib module crypto/sha512-buffer + +libgnu_a_SOURCES += sha512.c + +EXTRA_DIST += gl_openssl.h sha512.h + +## end gnulib module crypto/sha512-buffer + +## begin gnulib module ctype + +BUILT_SOURCES += ctype.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +ctype.h: ctype.in.h $(top_builddir)/config.status $(CXXDEFS_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_CTYPE_H''@|$(NEXT_CTYPE_H)|g' \ + -e 's/@''GNULIB_ISBLANK''@/$(GL_GNULIB_ISBLANK)/g' \ + -e 's/@''HAVE_ISBLANK''@/$(HAVE_ISBLANK)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/ctype.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += ctype.h ctype.h-t + +EXTRA_DIST += ctype.in.h + +## end gnulib module ctype + +## begin gnulib module dirent + +BUILT_SOURCES += dirent.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +dirent.h: dirent.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|@''HAVE_DIRENT_H''@|$(HAVE_DIRENT_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_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \ + -e 's/@''GNULIB_OPENDIR''@/$(GL_GNULIB_OPENDIR)/g' \ + -e 's/@''GNULIB_READDIR''@/$(GL_GNULIB_READDIR)/g' \ + -e 's/@''GNULIB_REWINDDIR''@/$(GL_GNULIB_REWINDDIR)/g' \ + -e 's/@''GNULIB_CLOSEDIR''@/$(GL_GNULIB_CLOSEDIR)/g' \ + -e 's/@''GNULIB_DIRFD''@/$(GL_GNULIB_DIRFD)/g' \ + -e 's/@''GNULIB_FDOPENDIR''@/$(GL_GNULIB_FDOPENDIR)/g' \ + -e 's/@''GNULIB_SCANDIR''@/$(GL_GNULIB_SCANDIR)/g' \ + -e 's/@''GNULIB_ALPHASORT''@/$(GL_GNULIB_ALPHASORT)/g' \ + -e 's/@''HAVE_OPENDIR''@/$(HAVE_OPENDIR)/g' \ + -e 's/@''HAVE_READDIR''@/$(HAVE_READDIR)/g' \ + -e 's/@''HAVE_REWINDDIR''@/$(HAVE_REWINDDIR)/g' \ + -e 's/@''HAVE_CLOSEDIR''@/$(HAVE_CLOSEDIR)/g' \ + -e 's|@''HAVE_DECL_DIRFD''@|$(HAVE_DECL_DIRFD)|g' \ + -e 's|@''HAVE_DECL_FDOPENDIR''@|$(HAVE_DECL_FDOPENDIR)|g' \ + -e 's|@''HAVE_FDOPENDIR''@|$(HAVE_FDOPENDIR)|g' \ + -e 's|@''HAVE_SCANDIR''@|$(HAVE_SCANDIR)|g' \ + -e 's|@''HAVE_ALPHASORT''@|$(HAVE_ALPHASORT)|g' \ + -e 's|@''REPLACE_OPENDIR''@|$(REPLACE_OPENDIR)|g' \ + -e 's|@''REPLACE_CLOSEDIR''@|$(REPLACE_CLOSEDIR)|g' \ + -e 's|@''REPLACE_DIRFD''@|$(REPLACE_DIRFD)|g' \ + -e 's|@''REPLACE_FDOPENDIR''@|$(REPLACE_FDOPENDIR)|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)/dirent.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += dirent.h dirent.h-t + +EXTRA_DIST += dirent.in.h + +## end gnulib module dirent + +## begin gnulib module dirfd + +if GL_COND_OBJ_DIRFD +libgnu_a_SOURCES += dirfd.c +endif + +## end gnulib module dirfd + +## begin gnulib module dirname + +libgnu_a_SOURCES += dirname.c basename.c + +EXTRA_DIST += stripslash.c + +EXTRA_libgnu_a_SOURCES += stripslash.c + +## end gnulib module dirname + +## begin gnulib module dirname-lgpl + +libgnu_a_SOURCES += dirname-lgpl.c stripslash.c + +EXTRA_DIST += dirname.h + +## end gnulib module dirname-lgpl + +## begin gnulib module dup + +if GL_COND_OBJ_DUP +libgnu_a_SOURCES += dup.c +endif + +## end gnulib module dup + +## 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 + +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 + +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 eloop-threshold + + +EXTRA_DIST += eloop-threshold.h + +## end gnulib module eloop-threshold + +## begin gnulib module errno + +BUILT_SOURCES += $(ERRNO_H) + +# We need the following in order to create when the system +# doesn't have one that is POSIX compliant. +if GL_GENERATE_ERRNO_H +errno.h: errno.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_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ + -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ + -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ + -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \ + -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 + $(AM_V_at)mv $@-t $@ +else +errno.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += errno.h errno.h-t + +EXTRA_DIST += errno.in.h + +## end gnulib module errno + +## begin gnulib module error + +if GL_COND_OBJ_ERROR +libgnu_a_SOURCES += error.c +endif + +EXTRA_DIST += error.h + +## end gnulib module error + +## begin gnulib module exitfail + +libgnu_a_SOURCES += exitfail.c + +EXTRA_DIST += exitfail.h + +## end gnulib module exitfail + +## begin gnulib module fatal-signal + +libgnu_a_SOURCES += fatal-signal.h fatal-signal.c + +## end gnulib module fatal-signal + +## begin gnulib module fchdir + +if GL_COND_OBJ_FCHDIR +libgnu_a_SOURCES += fchdir.c +endif + +## end gnulib module fchdir + +## 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 + +EXTRA_DIST += fd-hook.h + +## end gnulib module fd-hook + +## begin gnulib module fd-safer-flag + +libgnu_a_SOURCES += fd-safer-flag.c dup-safer-flag.c + +## end gnulib module fd-safer-flag + +## begin gnulib module fdopendir + +if GL_COND_OBJ_FDOPENDIR +libgnu_a_SOURCES += fdopendir.c +endif + +## end gnulib module fdopendir + +## 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 file-set + +libgnu_a_SOURCES += file-set.c + +EXTRA_DIST += file-set.h + +## end gnulib module file-set + +## begin gnulib module filename + + +EXTRA_DIST += filename.h + +## end gnulib module filename + +## begin gnulib module filenamecat-lgpl + +libgnu_a_SOURCES += filenamecat-lgpl.c + +EXTRA_DIST += filenamecat.h + +## end gnulib module filenamecat-lgpl + +## begin gnulib module findprog-in + +libgnu_a_SOURCES += findprog.h findprog-in.c + +## end gnulib module findprog-in + +## begin gnulib module flexmember + + +EXTRA_DIST += flexmember.h + +## end gnulib module flexmember + +## begin gnulib module float + +BUILT_SOURCES += $(FLOAT_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_FLOAT_H +float.h: float.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_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ + -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \ + $(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 + +if GL_COND_OBJ_FLOAT +libgnu_a_SOURCES += float.c +endif +if GL_COND_OBJ_ITOLD +libgnu_a_SOURCES += itold.c +endif + +EXTRA_DIST += float.in.h + +## end gnulib module float + +## begin gnulib module flock + +if GL_COND_OBJ_FLOCK +libgnu_a_SOURCES += flock.c +endif + +## end gnulib module flock + +## begin gnulib module fnmatch + + +EXTRA_DIST += fnmatch.c fnmatch_loop.c + +EXTRA_libgnu_a_SOURCES += fnmatch.c fnmatch_loop.c + +## end gnulib module fnmatch + +## begin gnulib module fnmatch-gnu + + +EXTRA_DIST += fnmatch.c + +EXTRA_libgnu_a_SOURCES += fnmatch.c + +## end gnulib module fnmatch-gnu + +## begin gnulib module fnmatch-h + +BUILT_SOURCES += $(FNMATCH_H) + +# We need the following in order to create . +if GL_GENERATE_FNMATCH_H +fnmatch.h: fnmatch.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|@''HAVE_FNMATCH_H''@|$(HAVE_FNMATCH_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_FNMATCH_H''@|$(NEXT_FNMATCH_H)|g' \ + -e 's/@''GNULIB_FNMATCH''@/$(GL_GNULIB_FNMATCH)/g' \ + -e 's|@''HAVE_FNMATCH''@|$(HAVE_FNMATCH)|g' \ + -e 's|@''REPLACE_FNMATCH''@|$(REPLACE_FNMATCH)|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)/fnmatch.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +fnmatch.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t + +EXTRA_DIST += fnmatch.in.h + +## end gnulib module fnmatch-h + +## begin gnulib module fopen + + +EXTRA_DIST += fopen.c + +EXTRA_libgnu_a_SOURCES += fopen.c + +## end gnulib module fopen + +## begin gnulib module fopen-gnu + + +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 fstatat + +if GL_COND_OBJ_FSTATAT +libgnu_a_SOURCES += fstatat.c +endif + +EXTRA_DIST += at-func.c + +EXTRA_libgnu_a_SOURCES += at-func.c + +## end gnulib module fstatat + +## begin gnulib module ftell + +if GL_COND_OBJ_FTELL +libgnu_a_SOURCES += ftell.c +endif + +## end gnulib module ftell + +## begin gnulib module ftello + +if GL_COND_OBJ_FTELLO +libgnu_a_SOURCES += ftello.c +endif + +EXTRA_DIST += stdio-impl.h + +## end gnulib module ftello + +## begin gnulib module futimens + +if GL_COND_OBJ_FUTIMENS +libgnu_a_SOURCES += futimens.c +endif + +## end gnulib module futimens + +## 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 + +# '$(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' + +# 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 gendocs + + +EXTRA_DIST += $(top_srcdir)/build-aux/gendocs.sh + +## end gnulib module gendocs + +## 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 getcwd + +if GL_COND_OBJ_GETCWD +libgnu_a_SOURCES += getcwd.c +endif + +## end gnulib module getcwd + +## begin gnulib module getcwd-lgpl + +if GL_COND_OBJ_GETCWD_LGPL +libgnu_a_SOURCES += getcwd-lgpl.c +endif + +## end gnulib module getcwd-lgpl + +## 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 getgroups + +if GL_COND_OBJ_GETGROUPS +libgnu_a_SOURCES += getgroups.c +endif + +## end gnulib module getgroups + +## begin gnulib module getline + +if GL_COND_OBJ_GETLINE +libgnu_a_SOURCES += getline.c +endif + +## end gnulib module getline + +## begin gnulib module getopt-posix + +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) + $(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 + $(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 + +if GL_COND_OBJ_GETOPT +libgnu_a_SOURCES += getopt.c getopt1.c +endif + +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 getpass + + +EXTRA_DIST += getpass.c getpass.h + +EXTRA_libgnu_a_SOURCES += getpass.c + +## end gnulib module getpass + +## begin gnulib module getpass-gnu + + +EXTRA_DIST += getpass.c getpass.h + +EXTRA_libgnu_a_SOURCES += getpass.c + +## end gnulib module getpass-gnu + +## begin gnulib module getpeername + +if GL_COND_OBJ_GETPEERNAME +libgnu_a_SOURCES += getpeername.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module getpeername + +## begin gnulib module getprogname + +libgnu_a_SOURCES += getprogname.h getprogname.c + +## end gnulib module getprogname + +## begin gnulib module getrandom + +if GL_COND_OBJ_GETRANDOM +libgnu_a_SOURCES += getrandom.c +endif + +## end gnulib module getrandom + +## begin gnulib module getsockname + +if GL_COND_OBJ_GETSOCKNAME +libgnu_a_SOURCES += getsockname.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module getsockname + +## begin gnulib module gettext-h + +libgnu_a_SOURCES += gettext.h + +## end gnulib module gettext-h + +## begin gnulib module gettime + +libgnu_a_SOURCES += gettime.c + +## end gnulib module gettime + +## begin gnulib module gettimeofday + +if GL_COND_OBJ_GETTIMEOFDAY +libgnu_a_SOURCES += gettimeofday.c +endif + +## end gnulib module gettimeofday + +## begin gnulib module git-version-gen + + +EXTRA_DIST += $(top_srcdir)/build-aux/git-version-gen + +## end gnulib module git-version-gen + +## begin gnulib module gitlog-to-changelog + + +EXTRA_DIST += $(top_srcdir)/build-aux/gitlog-to-changelog + +## end gnulib module gitlog-to-changelog + +## begin gnulib module gnu-web-doc-update + + +EXTRA_DIST += $(top_srcdir)/build-aux/gnu-web-doc-update + +## end gnulib module gnu-web-doc-update + +## begin gnulib module gnumakefile + +EXTRA_DIST += $(top_srcdir)/GNUmakefile +distclean-local: clean-GNUmakefile +clean-GNUmakefile: + test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile + +## end gnulib module gnumakefile + +## begin gnulib module gnupload + + +EXTRA_DIST += $(top_srcdir)/build-aux/gnupload + +## end gnulib module gnupload + +## begin gnulib module gperf + +GPERF = gperf +V_GPERF = $(V_GPERF_@AM_V@) +V_GPERF_ = $(V_GPERF_@AM_DEFAULT_V@) +V_GPERF_0 = @echo " GPERF " $@; + +## end gnulib module gperf + +## begin gnulib module group-member + +if GL_COND_OBJ_GROUP_MEMBER +libgnu_a_SOURCES += group-member.c +endif + +## end gnulib module group-member + +## begin gnulib module hard-locale + +libgnu_a_SOURCES += hard-locale.c + +EXTRA_DIST += hard-locale.h + +## end gnulib module hard-locale + +## begin gnulib module hash + +libgnu_a_SOURCES += hash.c + +EXTRA_DIST += hash.h + +## end gnulib module hash + +## begin gnulib module hash-pjw + +libgnu_a_SOURCES += hash-pjw.h hash-pjw.c + +## end gnulib module hash-pjw + +## begin gnulib module hash-triple-simple + +libgnu_a_SOURCES += hash-triple-simple.c + +EXTRA_DIST += hash-triple.h + +## end gnulib module hash-triple-simple + +## begin gnulib module havelib + + +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 iconv-h + +BUILT_SOURCES += $(ICONV_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_ICONV_H +iconv.h: iconv.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_ICONV_H''@|$(NEXT_ICONV_H)|g' \ + -e 's/@''GNULIB_ICONV''@/$(GL_GNULIB_ICONV)/g' \ + -e 's|@''ICONV_CONST''@|$(ICONV_CONST)|g' \ + -e 's|@''REPLACE_ICONV''@|$(REPLACE_ICONV)|g' \ + -e 's|@''REPLACE_ICONV_OPEN''@|$(REPLACE_ICONV_OPEN)|g' \ + -e 's|@''REPLACE_ICONV_UTF''@|$(REPLACE_ICONV_UTF)|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)/iconv.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +iconv.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += iconv.h iconv.h-t + +EXTRA_DIST += iconv.in.h + +## end gnulib module iconv-h + +## begin gnulib module idx + +libgnu_a_SOURCES += idx.h + +## end gnulib module idx + +## begin gnulib module inet_ntop + +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 + +## 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 ioctl + +if GL_COND_OBJ_IOCTL +libgnu_a_SOURCES += ioctl.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module ioctl + +## begin gnulib module isblank + +if GL_COND_OBJ_ISBLANK +libgnu_a_SOURCES += isblank.c +endif + +## end gnulib module isblank + +## begin gnulib module iswblank + +if GL_COND_OBJ_ISWBLANK +libgnu_a_SOURCES += iswblank.c +endif + +## end gnulib module iswblank + +## begin gnulib module iswdigit + +if GL_COND_OBJ_ISWDIGIT +libgnu_a_SOURCES += iswdigit.c +endif + +## end gnulib module iswdigit + +## begin gnulib module iswxdigit + +if GL_COND_OBJ_ISWXDIGIT +libgnu_a_SOURCES += iswxdigit.c +endif + +## end gnulib module iswxdigit + +## begin gnulib module langinfo + +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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += langinfo.h langinfo.h-t + +EXTRA_DIST += langinfo.in.h + +## end gnulib module langinfo + +## begin gnulib module libc-config + + +EXTRA_DIST += cdefs.h libc-config.h + +## end gnulib module libc-config + +## begin gnulib module libunistring-optional + + +EXTRA_DIST += libunistring.valgrind + +## end gnulib module libunistring-optional + +## 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 + +## begin gnulib module link + +if GL_COND_OBJ_LINK +libgnu_a_SOURCES += link.c +endif + +## end gnulib module link + +## begin gnulib module listen + +if GL_COND_OBJ_LISTEN +libgnu_a_SOURCES += listen.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module listen + +## begin gnulib module localcharset + +libgnu_a_SOURCES += localcharset.c + +EXTRA_DIST += localcharset.h + +## end gnulib module localcharset + +## begin gnulib module locale + +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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += locale.h locale.h-t + +EXTRA_DIST += locale.in.h + +## end gnulib module locale + +## begin gnulib module localeconv + +if GL_COND_OBJ_LOCALECONV +libgnu_a_SOURCES += localeconv.c +endif + +## end gnulib module localeconv + +## begin gnulib module lock + +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 lstat + +if GL_COND_OBJ_LSTAT +libgnu_a_SOURCES += lstat.c +endif + +## end gnulib module lstat + +## begin gnulib module maintainer-makefile + +EXTRA_DIST += $(top_srcdir)/maint.mk + +## end gnulib module maintainer-makefile + +## begin gnulib module malloc-gnu + + +EXTRA_DIST += malloc.c + +EXTRA_libgnu_a_SOURCES += malloc.c + +## end gnulib module malloc-gnu + +## begin gnulib module malloc-posix + + +EXTRA_DIST += malloc.c + +EXTRA_libgnu_a_SOURCES += malloc.c + +## end gnulib module malloc-posix + +## begin gnulib module malloca + +libgnu_a_SOURCES += malloca.c + +EXTRA_DIST += malloca.h + +## end gnulib module malloca + +## begin gnulib module mbchar + +libgnu_a_SOURCES += mbchar.c + +EXTRA_DIST += mbchar.h + +## end gnulib module mbchar + +## begin gnulib module mbiter + +libgnu_a_SOURCES += mbiter.h mbiter.c + +## end gnulib module mbiter + +## begin gnulib module mbrtowc + +if GL_COND_OBJ_MBRTOWC +libgnu_a_SOURCES += mbrtowc.c +endif + +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 += lc-charset-dispatch.c mbtowc-lock.c + +## end gnulib module mbrtowc + +## begin gnulib module mbsinit + +if GL_COND_OBJ_MBSINIT +libgnu_a_SOURCES += mbsinit.c +endif + +## end gnulib module mbsinit + +## begin gnulib module mbsrtowcs + +if GL_COND_OBJ_MBSRTOWCS +libgnu_a_SOURCES += mbsrtowcs.c +endif + +EXTRA_DIST += mbsrtowcs-impl.h mbsrtowcs-state.c + +EXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c + +## end gnulib module mbsrtowcs + +## begin gnulib module mbtowc + +if GL_COND_OBJ_MBTOWC +libgnu_a_SOURCES += mbtowc.c +endif + +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.valgrind + +## end gnulib module memchr + +## begin gnulib module mempcpy + +if GL_COND_OBJ_MEMPCPY +libgnu_a_SOURCES += mempcpy.c +endif + +## end gnulib module mempcpy + +## begin gnulib module memrchr + +if GL_COND_OBJ_MEMRCHR +libgnu_a_SOURCES += memrchr.c +endif + +## end gnulib module memrchr + +## begin gnulib module minmax + +libgnu_a_SOURCES += minmax.h + +## end gnulib module minmax + +## begin gnulib module mkdir + +if GL_COND_OBJ_MKDIR +libgnu_a_SOURCES += mkdir.c +endif + +## end gnulib module mkdir + +## begin gnulib module mkostemp + +if GL_COND_OBJ_MKOSTEMP +libgnu_a_SOURCES += mkostemp.c +endif + +## end gnulib module mkostemp + +## begin gnulib module mkstemp + +if GL_COND_OBJ_MKSTEMP +libgnu_a_SOURCES += mkstemp.c +endif + +## end gnulib module mkstemp + +## begin gnulib module mktime + + +EXTRA_DIST += mktime-internal.h mktime.c + +EXTRA_libgnu_a_SOURCES += mktime.c + +## end gnulib module mktime + +## begin gnulib module mktime-internal + + +EXTRA_DIST += mktime-internal.h mktime.c + +EXTRA_libgnu_a_SOURCES += mktime.c + +## end gnulib module mktime-internal + +## begin gnulib module msvc-inval + +if GL_COND_OBJ_MSVC_INVAL +libgnu_a_SOURCES += msvc-inval.c +endif + +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.h + +## end gnulib module msvc-nothrow + +## begin gnulib module nanosleep + +if GL_COND_OBJ_NANOSLEEP +libgnu_a_SOURCES += nanosleep.c +endif + +## end gnulib module nanosleep + +## begin gnulib module netdb + +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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += netdb.h netdb.h-t + +EXTRA_DIST += netdb.in.h + +## end gnulib module netdb + +## begin gnulib module netinet_in + +BUILT_SOURCES += $(NETINET_IN_H) + +# We need the following in order to create when the system +# doesn't have one. +if GL_GENERATE_NETINET_IN_H +netinet/in.h: netinet_in.in.h $(top_builddir)/config.status + $(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 + $(AM_V_at)mv $@-t $@ +else +netinet/in.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += netinet/in.h netinet/in.h-t +MOSTLYCLEANDIRS += netinet + +EXTRA_DIST += netinet_in.in.h + +## end gnulib module netinet_in + +## 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 += windows-initguard.h + +## end gnulib module nl_langinfo + +## begin gnulib module open + +if GL_COND_OBJ_OPEN +libgnu_a_SOURCES += open.c +endif + +## end gnulib module open + +## begin gnulib module openat + +if GL_COND_OBJ_OPENAT +libgnu_a_SOURCES += openat.c +endif + +## end gnulib module openat + +## begin gnulib module openat-die + +libgnu_a_SOURCES += openat-die.c + +## end gnulib module openat-die + +## begin gnulib module openat-h + + +EXTRA_DIST += openat.h + +## end gnulib module openat-h + +## begin gnulib module opendir + +if GL_COND_OBJ_OPENDIR +libgnu_a_SOURCES += opendir.c +endif + +EXTRA_DIST += dirent-private.h + +## end gnulib module opendir + +## begin gnulib module pathmax + + +EXTRA_DIST += pathmax.h + +## end gnulib module pathmax + +## begin gnulib module pipe-posix + +if GL_COND_OBJ_PIPE +libgnu_a_SOURCES += pipe.c +endif + +## end gnulib module pipe-posix + +## begin gnulib module pipe2 + +libgnu_a_SOURCES += pipe2.c + +## end gnulib module pipe2 + +## begin gnulib module pipe2-safer + +libgnu_a_SOURCES += pipe2-safer.c + +## end gnulib module pipe2-safer + +## begin gnulib module posix_spawn + +if GL_COND_OBJ_SPAWN +libgnu_a_SOURCES += spawn.c +endif + +## end gnulib module posix_spawn + +## begin gnulib module posix_spawn-internal + +if GL_COND_OBJ_SPAWNI +libgnu_a_SOURCES += spawni.c +endif + +EXTRA_DIST += spawn_int.h + +## end gnulib module posix_spawn-internal + +## begin gnulib module posix_spawn_file_actions_addchdir + +if GL_COND_OBJ_SPAWN_FACTION_ADDCHDIR +libgnu_a_SOURCES += spawn_faction_addchdir.c +endif + +EXTRA_DIST += spawn_int.h + +## end gnulib module posix_spawn_file_actions_addchdir + +## begin gnulib module posix_spawn_file_actions_addclose + +if GL_COND_OBJ_SPAWN_FACTION_ADDCLOSE +libgnu_a_SOURCES += spawn_faction_addclose.c +endif + +EXTRA_DIST += spawn_int.h + +## end gnulib module posix_spawn_file_actions_addclose + +## begin gnulib module posix_spawn_file_actions_adddup2 + +if GL_COND_OBJ_SPAWN_FACTION_ADDDUP2 +libgnu_a_SOURCES += spawn_faction_adddup2.c +endif + +EXTRA_DIST += spawn_int.h + +## end gnulib module posix_spawn_file_actions_adddup2 + +## begin gnulib module posix_spawn_file_actions_addopen + +if GL_COND_OBJ_SPAWN_FACTION_ADDOPEN +libgnu_a_SOURCES += spawn_faction_addopen.c +endif + +EXTRA_DIST += spawn_int.h + +## end gnulib module posix_spawn_file_actions_addopen + +## begin gnulib module posix_spawn_file_actions_destroy + +if GL_COND_OBJ_SPAWN_FACTION_DESTROY +libgnu_a_SOURCES += spawn_faction_destroy.c +endif + +## end gnulib module posix_spawn_file_actions_destroy + +## begin gnulib module posix_spawn_file_actions_init + +if GL_COND_OBJ_SPAWN_FACTION_INIT +libgnu_a_SOURCES += spawn_faction_init.c +endif + +EXTRA_DIST += spawn_int.h + +## end gnulib module posix_spawn_file_actions_init + +## begin gnulib module posix_spawnattr_destroy + +if GL_COND_OBJ_SPAWNATTR_DESTROY +libgnu_a_SOURCES += spawnattr_destroy.c +endif + +## end gnulib module posix_spawnattr_destroy + +## begin gnulib module posix_spawnattr_init + +if GL_COND_OBJ_SPAWNATTR_INIT +libgnu_a_SOURCES += spawnattr_init.c +endif + +## end gnulib module posix_spawnattr_init + +## begin gnulib module posix_spawnattr_setflags + +if GL_COND_OBJ_SPAWNATTR_SETFLAGS +libgnu_a_SOURCES += spawnattr_setflags.c +endif + +## end gnulib module posix_spawnattr_setflags + +## begin gnulib module posix_spawnattr_setpgroup + +if GL_COND_OBJ_SPAWNATTR_SETPGROUP +libgnu_a_SOURCES += spawnattr_setpgroup.c +endif + +## end gnulib module posix_spawnattr_setpgroup + +## begin gnulib module posix_spawnattr_setsigmask + +if GL_COND_OBJ_SPAWNATTR_SETSIGMASK +libgnu_a_SOURCES += spawnattr_setsigmask.c +endif + +## end gnulib module posix_spawnattr_setsigmask + +## begin gnulib module posix_spawnp + +if GL_COND_OBJ_SPAWNP +libgnu_a_SOURCES += spawnp.c +endif + +## end gnulib module posix_spawnp + +## begin gnulib module pselect + +if GL_COND_OBJ_PSELECT +libgnu_a_SOURCES += pselect.c +endif + +## end gnulib module pselect + +## begin gnulib module pthread_sigmask + +if GL_COND_OBJ_PTHREAD_SIGMASK +libgnu_a_SOURCES += pthread_sigmask.c +endif + +## end gnulib module pthread_sigmask + +## begin gnulib module quote + + +EXTRA_DIST += quote.h + +## end gnulib module quote + +## begin gnulib module quotearg + +libgnu_a_SOURCES += quotearg.c + +EXTRA_DIST += quote.h quotearg.h + +## end gnulib module quotearg + +## begin gnulib module raise + +if GL_COND_OBJ_RAISE +libgnu_a_SOURCES += raise.c +endif + +## end gnulib module raise + +## begin gnulib module rawmemchr + +if GL_COND_OBJ_RAWMEMCHR +libgnu_a_SOURCES += rawmemchr.c +endif + +EXTRA_DIST += rawmemchr.valgrind + +## end gnulib module rawmemchr + +## begin gnulib module readdir + +if GL_COND_OBJ_READDIR +libgnu_a_SOURCES += readdir.c +endif + +EXTRA_DIST += dirent-private.h + +## end gnulib module readdir + +## begin gnulib module readlink + +if GL_COND_OBJ_READLINK +libgnu_a_SOURCES += readlink.c +endif + +## end gnulib module readlink + +## begin gnulib module realloc-gnu + + +EXTRA_DIST += realloc.c + +EXTRA_libgnu_a_SOURCES += realloc.c + +## end gnulib module realloc-gnu + +## begin gnulib module realloc-posix + + +EXTRA_DIST += realloc.c + +EXTRA_libgnu_a_SOURCES += realloc.c + +## end gnulib module realloc-posix + +## begin gnulib module reallocarray + +if GL_COND_OBJ_REALLOCARRAY +libgnu_a_SOURCES += reallocarray.c +endif + +## end gnulib module reallocarray + +## begin gnulib module recv + +if GL_COND_OBJ_RECV +libgnu_a_SOURCES += recv.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module recv + +## 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 rename + +if GL_COND_OBJ_RENAME +libgnu_a_SOURCES += rename.c +endif + +## end gnulib module rename + +## begin gnulib module rewinddir + +if GL_COND_OBJ_REWINDDIR +libgnu_a_SOURCES += rewinddir.c +endif + +EXTRA_DIST += dirent-private.h + +## end gnulib module rewinddir + +## begin gnulib module rmdir + +if GL_COND_OBJ_RMDIR +libgnu_a_SOURCES += rmdir.c +endif + +## end gnulib module rmdir + +## begin gnulib module same-inode + + +EXTRA_DIST += same-inode.h + +## end gnulib module same-inode + +## begin gnulib module save-cwd + +libgnu_a_SOURCES += save-cwd.c + +EXTRA_DIST += save-cwd.h + +## end gnulib module save-cwd + +## begin gnulib module sched + +BUILT_SOURCES += sched.h + +# We need the following in order to create a replacement for when +# the system doesn't have one. +sched.h: sched.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''HAVE_SCHED_H''@|$(HAVE_SCHED_H)|g' \ + -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_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_SCHED_H''@|$(NEXT_SCHED_H)|g' \ + -e 's|@''HAVE_STRUCT_SCHED_PARAM''@|$(HAVE_STRUCT_SCHED_PARAM)|g' \ + -e 's/@''GNULIB_SCHED_YIELD''@/$(GL_GNULIB_SCHED_YIELD)/g' \ + -e 's|@''HAVE_SCHED_YIELD''@|$(HAVE_SCHED_YIELD)|g' \ + -e 's|@''REPLACE_SCHED_YIELD''@|$(REPLACE_SCHED_YIELD)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sched.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sched.h sched.h-t + +EXTRA_DIST += sched.in.h + +## end gnulib module sched + +## begin gnulib module scratch_buffer + +BUILT_SOURCES += malloc/scratch_buffer.gl.h + +malloc/scratch_buffer.gl.h: malloc/scratch_buffer.h + $(AM_V_GEN)$(MKDIR_P) '%reldir%/malloc' + $(AM_V_at)$(SED_HEADER_STDOUT) \ + -e 's|__always_inline|inline _GL_ATTRIBUTE_ALWAYS_INLINE|g' \ + -e 's|__glibc_likely|_GL_LIKELY|g' \ + -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \ + -e '/libc_hidden_proto/d' \ + $(srcdir)/malloc/scratch_buffer.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += malloc/scratch_buffer.gl.h malloc/scratch_buffer.gl.h-t + +libgnu_a_SOURCES += malloc/scratch_buffer_dupfree.c malloc/scratch_buffer_grow.c malloc/scratch_buffer_grow_preserve.c malloc/scratch_buffer_set_array_size.c + +EXTRA_DIST += malloc/scratch_buffer.h scratch_buffer.h + +## end gnulib module scratch_buffer + +## begin gnulib module secure_getenv + +if GL_COND_OBJ_SECURE_GETENV +libgnu_a_SOURCES += secure_getenv.c +endif + +## end gnulib module secure_getenv + +## begin gnulib module select + +if GL_COND_OBJ_SELECT +libgnu_a_SOURCES += select.c +endif + +## end gnulib module select + +## begin gnulib module send + +if GL_COND_OBJ_SEND +libgnu_a_SOURCES += send.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module send + +## 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 setsockopt + +if GL_COND_OBJ_SETSOCKOPT +libgnu_a_SOURCES += setsockopt.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module setsockopt + +## begin gnulib module sigaction + +if GL_COND_OBJ_SIGACTION +libgnu_a_SOURCES += sigaction.c +endif +libgnu_a_SOURCES += sig-handler.c + +EXTRA_DIST += sig-handler.h + +## end gnulib module sigaction + +## begin gnulib module signal-h + +BUILT_SOURCES += signal.h + +# We need the following in order to create when the system +# doesn't have a complete one. +signal.h: signal.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_SIGNAL_H''@|$(NEXT_SIGNAL_H)|g' \ + -e 's/@''GNULIB_PTHREAD_SIGMASK''@/$(GL_GNULIB_PTHREAD_SIGMASK)/g' \ + -e 's/@''GNULIB_RAISE''@/$(GL_GNULIB_RAISE)/g' \ + -e 's/@''GNULIB_SIGNAL_H_SIGPIPE''@/$(GL_GNULIB_SIGNAL_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_SIGPROCMASK''@/$(GL_GNULIB_SIGPROCMASK)/g' \ + -e 's/@''GNULIB_SIGACTION''@/$(GL_GNULIB_SIGACTION)/g' \ + -e 's|@''HAVE_POSIX_SIGNALBLOCKING''@|$(HAVE_POSIX_SIGNALBLOCKING)|g' \ + -e 's|@''HAVE_PTHREAD_SIGMASK''@|$(HAVE_PTHREAD_SIGMASK)|g' \ + -e 's|@''HAVE_RAISE''@|$(HAVE_RAISE)|g' \ + -e 's|@''HAVE_SIGSET_T''@|$(HAVE_SIGSET_T)|g' \ + -e 's|@''HAVE_SIGINFO_T''@|$(HAVE_SIGINFO_T)|g' \ + -e 's|@''HAVE_SIGACTION''@|$(HAVE_SIGACTION)|g' \ + -e 's|@''HAVE_STRUCT_SIGACTION_SA_SIGACTION''@|$(HAVE_STRUCT_SIGACTION_SA_SIGACTION)|g' \ + -e 's|@''HAVE_TYPE_VOLATILE_SIG_ATOMIC_T''@|$(HAVE_TYPE_VOLATILE_SIG_ATOMIC_T)|g' \ + -e 's|@''HAVE_SIGHANDLER_T''@|$(HAVE_SIGHANDLER_T)|g' \ + -e 's|@''REPLACE_PTHREAD_SIGMASK''@|$(REPLACE_PTHREAD_SIGMASK)|g' \ + -e 's|@''REPLACE_RAISE''@|$(REPLACE_RAISE)|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)/signal.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += signal.h signal.h-t + +EXTRA_DIST += signal.in.h + +## end gnulib module signal-h + +## begin gnulib module sigpipe + + +EXTRA_DIST += stdio-write.c + +EXTRA_libgnu_a_SOURCES += stdio-write.c + +## end gnulib module sigpipe + +## begin gnulib module sigprocmask + +if GL_COND_OBJ_SIGPROCMASK +libgnu_a_SOURCES += sigprocmask.c +endif + +## end gnulib module sigprocmask + +## begin gnulib module size_max + +libgnu_a_SOURCES += size_max.h + +## end gnulib module size_max + +## begin gnulib module snippet/_Noreturn + +# 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. + +_NORETURN_H=$(srcdir)/_Noreturn.h + +EXTRA_DIST += _Noreturn.h + +## end gnulib module snippet/_Noreturn + +## begin gnulib module snippet/arg-nonnull + +# 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=$(srcdir)/arg-nonnull.h + +EXTRA_DIST += arg-nonnull.h + +## end gnulib module snippet/arg-nonnull + +## begin gnulib module snippet/c++defs + +# 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=$(srcdir)/c++defs.h + +EXTRA_DIST += c++defs.h + +## end gnulib module snippet/c++defs + +## begin gnulib module snippet/warn-on-use + +# 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=$(srcdir)/warn-on-use.h + +EXTRA_DIST += warn-on-use.h + +## end gnulib module snippet/warn-on-use + +## begin gnulib module snprintf + + +EXTRA_DIST += snprintf.c + +EXTRA_libgnu_a_SOURCES += snprintf.c + +## end gnulib module snprintf + +## begin gnulib module socket + +if GL_COND_OBJ_SOCKET +libgnu_a_SOURCES += socket.c +endif + +EXTRA_DIST += w32sock.h + +## end gnulib module socket + +## begin gnulib module sockets + +libgnu_a_SOURCES += sockets.h sockets.c + +EXTRA_DIST += w32sock.h + +## end gnulib module sockets + +## begin gnulib module spawn + +BUILT_SOURCES += spawn.h + +# We need the following in order to create a replacement for when +# the system doesn't have one. +spawn.h: spawn.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|@''HAVE_SPAWN_H''@|$(HAVE_SPAWN_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_SPAWN_H''@|$(NEXT_SPAWN_H)|g' \ + -e 's/@''GNULIB_POSIX_SPAWN''@/$(GL_GNULIB_POSIX_SPAWN)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNP''@/$(GL_GNULIB_POSIX_SPAWNP)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)/g' \ + -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY''@/$(GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_INIT''@/$(GL_GNULIB_POSIX_SPAWNATTR_INIT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETFLAGS''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETFLAGS''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETPGROUP''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETPGROUP''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_GETSIGMASK''@/$(GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_SETSIGMASK''@/$(GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK)/g' \ + -e 's/@''GNULIB_POSIX_SPAWNATTR_DESTROY''@/$(GL_GNULIB_POSIX_SPAWNATTR_DESTROY)/g' \ + -e 's|@''HAVE_POSIX_SPAWN''@|$(HAVE_POSIX_SPAWN)|g' \ + -e 's|@''HAVE_POSIX_SPAWNATTR_T''@|$(HAVE_POSIX_SPAWNATTR_T)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_T''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_T)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \ + -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN''@|$(REPLACE_POSIX_SPAWN)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \ + -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)|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)/spawn.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += spawn.h spawn.h-t + +EXTRA_DIST += spawn.in.h + +## end gnulib module spawn + +## begin gnulib module spawn-pipe + +libgnu_a_SOURCES += spawn-pipe.h spawn-pipe.c +if GL_COND_OBJ_OS2_SPAWN +libgnu_a_SOURCES += os2-spawn.c +endif + +EXTRA_DIST += os2-spawn.h + +## end gnulib module spawn-pipe + +## 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) + +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_STDALIGN_H +stdalign.h: stdalign.in.h $(top_builddir)/config.status + $(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 $@ +endif +MOSTLYCLEANFILES += stdalign.h stdalign.h-t + +EXTRA_DIST += stdalign.in.h + +## end gnulib module stdalign + +## begin gnulib module stdbool + +BUILT_SOURCES += $(STDBOOL_H) + +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_STDBOOL_H +stdbool.h: stdbool.in.h $(top_builddir)/config.status + $(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 $@ +endif +MOSTLYCLEANFILES += stdbool.h stdbool.h-t + +EXTRA_DIST += stdbool.in.h + +## end gnulib module stdbool + +## begin gnulib module stddef + +BUILT_SOURCES += $(STDDEF_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_STDDEF_H +stddef.h: stddef.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_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 + $(AM_V_at)mv $@-t $@ +else +stddef.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stddef.h stddef.h-t + +EXTRA_DIST += stddef.in.h + +## end gnulib module stddef + +## begin gnulib module stdint + +BUILT_SOURCES += $(STDINT_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_STDINT_H +stdint.h: stdint.in.h $(top_builddir)/config.status + $(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/@''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' \ + -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ + -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ + -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ + -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ + -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ + -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ + -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' \ + -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 $@ +endif +MOSTLYCLEANFILES += stdint.h stdint.h-t + +EXTRA_DIST += stdint.in.h + +## end gnulib module stdint + +## begin gnulib module stdio + +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) + $(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''@/$(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_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' \ + -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ + -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ + -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ + -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ + -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \ + -e 's|@''HAVE_FSEEKO''@|$(HAVE_FSEEKO)|g' \ + -e 's|@''HAVE_FTELLO''@|$(HAVE_FTELLO)|g' \ + -e 's|@''HAVE_PCLOSE''@|$(HAVE_PCLOSE)|g' \ + -e 's|@''HAVE_POPEN''@|$(HAVE_POPEN)|g' \ + -e 's|@''HAVE_RENAMEAT''@|$(HAVE_RENAMEAT)|g' \ + -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ + -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ + -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ + -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ + -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' \ + -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ + -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ + -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ + -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ + -e 's|@''REPLACE_GETDELIM''@|$(REPLACE_GETDELIM)|g' \ + -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ + -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \ + -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \ + -e 's|@''REPLACE_POPEN''@|$(REPLACE_POPEN)|g' \ + -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ + -e 's|@''REPLACE_REMOVE''@|$(REPLACE_REMOVE)|g' \ + -e 's|@''REPLACE_RENAME''@|$(REPLACE_RENAME)|g' \ + -e 's|@''REPLACE_RENAMEAT''@|$(REPLACE_RENAMEAT)|g' \ + -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ + -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ + -e 's|@''REPLACE_STDIO_READ_FUNCS''@|$(REPLACE_STDIO_READ_FUNCS)|g' \ + -e 's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \ + -e 's|@''REPLACE_TMPFILE''@|$(REPLACE_TMPFILE)|g' \ + -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ + -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ + -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ + -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ + -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ + -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ + -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 + $(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 + +## begin gnulib module stdlib + +BUILT_SOURCES += stdlib.h + +# We need the following in order to create when the system +# 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) + $(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''@/$(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_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_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_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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += stdlib.h stdlib.h-t + +EXTRA_DIST += stdlib.in.h + +## end gnulib module stdlib + +## begin gnulib module stpcpy + +if GL_COND_OBJ_STPCPY +libgnu_a_SOURCES += stpcpy.c +endif + +## end gnulib module stpcpy + +## 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 + +## begin gnulib module strchrnul + +if GL_COND_OBJ_STRCHRNUL +libgnu_a_SOURCES += strchrnul.c +endif + +EXTRA_DIST += strchrnul.valgrind + +## end gnulib module strchrnul + +## begin gnulib module strdup-posix + +if GL_COND_OBJ_STRDUP +libgnu_a_SOURCES += strdup.c +endif + +## end gnulib module strdup-posix + +## begin gnulib module streq + + +EXTRA_DIST += streq.h + +## end gnulib module streq + +## begin gnulib module strerror + +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.h + +## end gnulib module strerror-override + +## begin gnulib module strerror_r-posix + + +EXTRA_DIST += strerror_r.c + +EXTRA_libgnu_a_SOURCES += strerror_r.c + +## end gnulib module strerror_r-posix + +## begin gnulib module string + +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) + $(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_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_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_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ + -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ + -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \ + -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ + -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ + -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ + -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ + -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ + -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ + -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ + -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ + -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_FFSLL''@|$(REPLACE_FFSLL)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|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_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ + -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ + -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|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)' \ + > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += string.h string.h-t + +EXTRA_DIST += string.in.h + +## end gnulib module string + +## begin gnulib module strings + +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) + $(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''@/$(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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += strings.h strings.h-t + +EXTRA_DIST += strings.in.h + +## end gnulib module strings + +## begin gnulib module strndup + +if GL_COND_OBJ_STRNDUP +libgnu_a_SOURCES += strndup.c +endif + +## end gnulib module strndup + +## begin gnulib module strnlen + +if GL_COND_OBJ_STRNLEN +libgnu_a_SOURCES += strnlen.c +endif + +## end gnulib module strnlen + +## begin gnulib module strnlen1 + +libgnu_a_SOURCES += strnlen1.h strnlen1.c + +## end gnulib module strnlen1 + +## begin gnulib module strpbrk + +if GL_COND_OBJ_STRPBRK +libgnu_a_SOURCES += strpbrk.c +endif + +## end gnulib module strpbrk + +## begin gnulib module strptime + +if GL_COND_OBJ_STRPTIME +libgnu_a_SOURCES += strptime.c +endif + +## end gnulib module strptime + +## begin gnulib module strtok_r + +if GL_COND_OBJ_STRTOK_R +libgnu_a_SOURCES += strtok_r.c +endif + +## end gnulib module strtok_r + +## begin gnulib module strtol + +if GL_COND_OBJ_STRTOL +libgnu_a_SOURCES += strtol.c +endif + +## end gnulib module strtol + +## begin gnulib module strtoll + +if GL_COND_OBJ_STRTOLL +libgnu_a_SOURCES += strtoll.c +endif + +EXTRA_DIST += strtol.c + +EXTRA_libgnu_a_SOURCES += strtol.c + +## end gnulib module strtoll + +## begin gnulib module symlink + +if GL_COND_OBJ_SYMLINK +libgnu_a_SOURCES += symlink.c +endif + +## end gnulib module symlink + +## begin gnulib module sys_file + +BUILT_SOURCES += sys/file.h + +# We need the following in order to create when the system +# has one that is incomplete. +sys/file.h: sys_file.in.h $(top_builddir)/config.status $(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/@''HAVE_SYS_FILE_H''@/$(HAVE_SYS_FILE_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_SYS_FILE_H''@|$(NEXT_SYS_FILE_H)|g' \ + -e 's/@''HAVE_FLOCK''@/$(HAVE_FLOCK)/g' \ + -e 's/@''GNULIB_FLOCK''@/$(GL_GNULIB_FLOCK)/g' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_file.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/file.h sys/file.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_file.in.h + +## end gnulib module sys_file + +## begin gnulib module sys_ioctl + +BUILT_SOURCES += sys/ioctl.h + +# We need the following in order to create when the system +# does not have a complete one. +sys/ioctl.h: sys_ioctl.in.h $(top_builddir)/config.status $(CXXDEFS_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|@''HAVE_SYS_IOCTL_H''@|$(HAVE_SYS_IOCTL_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_SYS_IOCTL_H''@|$(NEXT_SYS_IOCTL_H)|g' \ + -e 's/@''GNULIB_IOCTL''@/$(GL_GNULIB_IOCTL)/g' \ + -e 's|@''SYS_IOCTL_H_HAVE_WINSOCK2_H''@|$(SYS_IOCTL_H_HAVE_WINSOCK2_H)|g' \ + -e 's|@''SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ + -e 's|@''REPLACE_IOCTL''@|$(REPLACE_IOCTL)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_ioctl.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/ioctl.h sys/ioctl.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_ioctl.in.h + +## end gnulib module sys_ioctl + +## begin gnulib module sys_random + +BUILT_SOURCES += sys/random.h + +# We need the following in order to create when the system +# doesn't have one. +sys/random.h: sys_random.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_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_RANDOM_H''@|$(NEXT_SYS_RANDOM_H)|g' \ + -e 's|@''HAVE_SYS_RANDOM_H''@|$(HAVE_SYS_RANDOM_H)|g' \ + -e 's/@''GNULIB_GETRANDOM''@/$(GL_GNULIB_GETRANDOM)/g' \ + -e 's/@''HAVE_GETRANDOM''@/$(HAVE_GETRANDOM)/g' \ + -e 's/@''REPLACE_GETRANDOM''@/$(REPLACE_GETRANDOM)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_random.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/random.h sys/random.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_random.in.h + +## end gnulib module sys_random + +## begin gnulib module sys_select + +BUILT_SOURCES += sys/select.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_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_SELECT_H''@|$(NEXT_SYS_SELECT_H)|g' \ + -e 's|@''HAVE_SYS_SELECT_H''@|$(HAVE_SYS_SELECT_H)|g' \ + -e 's/@''GNULIB_PSELECT''@/$(GL_GNULIB_PSELECT)/g' \ + -e 's/@''GNULIB_SELECT''@/$(GL_GNULIB_SELECT)/g' \ + -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ + -e 's|@''HAVE_PSELECT''@|$(HAVE_PSELECT)|g' \ + -e 's|@''REPLACE_PSELECT''@|$(REPLACE_PSELECT)|g' \ + -e 's|@''REPLACE_SELECT''@|$(REPLACE_SELECT)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_select.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/select.h sys/select.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_select.in.h + +## end gnulib module sys_select + +## begin gnulib module sys_socket + +BUILT_SOURCES += sys/socket.h +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_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''@/$(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' \ + -e 's|@''HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY''@|$(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)|g' \ + -e 's|@''HAVE_SA_FAMILY_T''@|$(HAVE_SA_FAMILY_T)|g' \ + -e 's|@''HAVE_ACCEPT4''@|$(HAVE_ACCEPT4)|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_socket.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/socket.h sys/socket.h-t +MOSTLYCLEANDIRS += sys + +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_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_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_time + +BUILT_SOURCES += sys/time.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +sys/time.h: sys_time.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/@''HAVE_SYS_TIME_H''@/$(HAVE_SYS_TIME_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_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|g' \ + -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GL_GNULIB_GETTIMEOFDAY)/g' \ + -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ + -e 's/@''HAVE_GETTIMEOFDAY''@/$(HAVE_GETTIMEOFDAY)/g' \ + -e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \ + -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \ + -e 's/@''REPLACE_STRUCT_TIMEVAL''@/$(REPLACE_STRUCT_TIMEVAL)/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_time.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/time.h sys/time.h-t + +EXTRA_DIST += sys_time.in.h + +## end gnulib module sys_time + +## begin gnulib module sys_types + +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_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' \ + -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 + +## end gnulib module sys_types + +## begin gnulib module sys_uio + +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_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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/uio.h sys/uio.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_uio.in.h + +## end gnulib module sys_uio + +## begin gnulib module sys_wait + +BUILT_SOURCES += sys/wait.h + +# We need the following in order to create when the system +# has one that is incomplete. +sys/wait.h: sys_wait.in.h $(top_builddir)/config.status $(CXXDEFS_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_WAIT_H''@|$(NEXT_SYS_WAIT_H)|g' \ + -e 's/@''GNULIB_WAITPID''@/$(GL_GNULIB_WAITPID)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + $(srcdir)/sys_wait.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += sys/wait.h sys/wait.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_wait.in.h + +## end gnulib module sys_wait + +## begin gnulib module tempname + +libgnu_a_SOURCES += tempname.c + +EXTRA_DIST += tempname.h + +## end gnulib module tempname + +## begin gnulib module thread-optim + + +EXTRA_DIST += thread-optim.h + +## end gnulib module thread-optim + +## begin gnulib module threadlib + +libgnu_a_SOURCES += glthread/threadlib.c + +## end gnulib module threadlib + +## begin gnulib module time + +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) + $(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_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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += time.h time.h-t + +EXTRA_DIST += time.in.h + +## end gnulib module time + +## begin gnulib module time_r + +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 + +## end gnulib module timegm + +## begin gnulib module timespec + +libgnu_a_SOURCES += timespec.c + +EXTRA_DIST += timespec.h + +## end gnulib module timespec + +## begin gnulib module tmpdir + +libgnu_a_SOURCES += tmpdir.h tmpdir.c + +## end gnulib module tmpdir + +## begin gnulib module u64 + +libgnu_a_SOURCES += u64.c + +EXTRA_DIST += u64.h + +## end gnulib module u64 + +## begin gnulib module unicase/base + +BUILT_SOURCES += $(LIBUNISTRING_UNICASE_H) + +unicase.h: unicase.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unicase.in.h + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += unicase.h unicase.h-t + +EXTRA_DIST += unicase.in.h + +## end gnulib module unicase/base + +## begin gnulib module unicase/cased + +libgnu_a_SOURCES += unicase/cased.c + +EXTRA_DIST += unicase/cased.h unicase/caseprop.h unictype/bitmap.h + +## end gnulib module unicase/cased + +## begin gnulib module unicase/empty-prefix-context + +if LIBUNISTRING_COMPILE_UNICASE_EMPTY_PREFIX_CONTEXT +libgnu_a_SOURCES += unicase/empty-prefix-context.c +endif + +## end gnulib module unicase/empty-prefix-context + +## begin gnulib module unicase/empty-suffix-context + +if LIBUNISTRING_COMPILE_UNICASE_EMPTY_SUFFIX_CONTEXT +libgnu_a_SOURCES += unicase/empty-suffix-context.c +endif + +## end gnulib module unicase/empty-suffix-context + +## begin gnulib module unicase/ignorable + +libgnu_a_SOURCES += unicase/ignorable.c + +EXTRA_DIST += unicase/caseprop.h unicase/ignorable.h unictype/bitmap.h + +## end gnulib module unicase/ignorable + +## begin gnulib module unicase/special-casing + +libgnu_a_SOURCES += unicase/special-casing.c + +$(srcdir)/unicase/special-casing-table.h: $(srcdir)/unicase/special-casing-table.gperf + $(V_GPERF)$(GPERF) -m 10 $(srcdir)/unicase/special-casing-table.gperf > $(srcdir)/unicase/special-casing-table.h-t && \ + mv $(srcdir)/unicase/special-casing-table.h-t $(srcdir)/unicase/special-casing-table.h +BUILT_SOURCES += unicase/special-casing-table.h +MOSTLYCLEANFILES += unicase/special-casing-table.h-t +MAINTAINERCLEANFILES += unicase/special-casing-table.h +EXTRA_DIST += unicase/special-casing-table.h + +# Generate special-casing.h with a declaration that depends on the gperf version. +unicase/special-casing.h: unicase/special-casing.in.h unicase/special-casing-table.h + $(AM_V_GEN)$(MKDIR_P) '%reldir%/unicase' + $(AM_V_at)declaration=`grep '^gl_unicase_special_lookup' $(srcdir)/unicase/special-casing-table.h | sed -e 's/register //g'` && \ + $(SED_HEADER_STDOUT) \ + -e "/gl_unicase_special_lookup/s/gl_unicase_special_lookup.*/$${declaration};/" \ + $(srcdir)/unicase/special-casing.in.h > $@-t + $(AM_V_at)mv $@-t $@ +BUILT_SOURCES += unicase/special-casing.h +MOSTLYCLEANFILES += unicase/special-casing.h unicase/special-casing.h-t + +EXTRA_DIST += unicase/special-casing-table.gperf unicase/special-casing.in.h + +## end gnulib module unicase/special-casing + +## begin gnulib module unicase/tolower + +if LIBUNISTRING_COMPILE_UNICASE_TOLOWER +libgnu_a_SOURCES += unicase/tolower.c +endif + +EXTRA_DIST += unicase/simple-mapping.h unicase/tolower.h + +## end gnulib module unicase/tolower + +## begin gnulib module unicase/u8-casemap + +libgnu_a_SOURCES += unicase/u8-casemap.c + +EXTRA_DIST += unicase/context.h unicase/u-casemap.h unicase/unicasemap.h + +## end gnulib module unicase/u8-casemap + +## begin gnulib module unicase/u8-tolower + +if LIBUNISTRING_COMPILE_UNICASE_U8_TOLOWER +libgnu_a_SOURCES += unicase/u8-tolower.c +endif + +## end gnulib module unicase/u8-tolower + +## begin gnulib module unictype/base + +BUILT_SOURCES += $(LIBUNISTRING_UNICTYPE_H) + +unictype.h: unictype.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unictype.in.h + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += unictype.h unictype.h-t + +EXTRA_DIST += unictype.in.h + +## end gnulib module unictype/base + +## begin gnulib module unictype/combining-class + +if LIBUNISTRING_COMPILE_UNICTYPE_COMBINING_CLASS +libgnu_a_SOURCES += unictype/combiningclass.c +endif + +EXTRA_DIST += unictype/combiningclass.h + +## end gnulib module unictype/combining-class + +## begin gnulib module unictype/property-soft-dotted + +if LIBUNISTRING_COMPILE_UNICTYPE_PROPERTY_SOFT_DOTTED +libgnu_a_SOURCES += unictype/pr_soft_dotted.c +endif + +EXTRA_DIST += unictype/bitmap.h unictype/pr_soft_dotted.h + +## end gnulib module unictype/property-soft-dotted + +## begin gnulib module uninorm/base + +BUILT_SOURCES += $(LIBUNISTRING_UNINORM_H) + +uninorm.h: uninorm.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/uninorm.in.h + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += uninorm.h uninorm.h-t + +EXTRA_DIST += uninorm.in.h + +## end gnulib module uninorm/base + +## begin gnulib module uninorm/decompose-internal + +libgnu_a_SOURCES += uninorm/decompose-internal.c + +EXTRA_DIST += uninorm/decompose-internal.h + +## end gnulib module uninorm/decompose-internal + +## begin gnulib module uninorm/u8-normalize + +if LIBUNISTRING_COMPILE_UNINORM_U8_NORMALIZE +libgnu_a_SOURCES += uninorm/u8-normalize.c +endif + +EXTRA_DIST += uninorm/normalize-internal.h uninorm/u-normalize-internal.h + +## end gnulib module uninorm/u8-normalize + +## begin gnulib module unistd + +BUILT_SOURCES += unistd.h +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) + $(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_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_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' \ + -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \ + -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ + -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ + -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ + -e 's|@''HAVE_GETENTROPY''@|$(HAVE_GETENTROPY)|g' \ + -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ + -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ + -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ + -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' \ + -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \ + -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \ + -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \ + -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \ + -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \ + -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ + -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \ + -e 's|@''HAVE_SETHOSTNAME''@|$(HAVE_SETHOSTNAME)|g' \ + -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ + -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \ + -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \ + -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_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' \ + -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \ + -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \ + -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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += unistd.h unistd.h-t + +EXTRA_DIST += unistd.in.h + +## end gnulib module unistd + +## begin gnulib module unistd-safer + +libgnu_a_SOURCES += dup-safer.c fd-safer.c pipe-safer.c + +EXTRA_DIST += unistd--.h unistd-safer.h + +## end gnulib module unistd-safer + +## begin gnulib module unistr/base + +BUILT_SOURCES += $(LIBUNISTRING_UNISTR_H) + +unistr.h: unistr.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unistr.in.h + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += unistr.h unistr.h-t + +EXTRA_DIST += unistr.in.h + +## end gnulib module unistr/base + +## begin gnulib module unistr/u8-cpy + +if LIBUNISTRING_COMPILE_UNISTR_U8_CPY +libgnu_a_SOURCES += unistr/u8-cpy.c +endif + +EXTRA_DIST += unistr/u-cpy.h + +## end gnulib module unistr/u8-cpy + +## begin gnulib module unistr/u8-mbtouc-unsafe + +if LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUC_UNSAFE +libgnu_a_SOURCES += unistr/u8-mbtouc-unsafe.c unistr/u8-mbtouc-unsafe-aux.c +endif + +## end gnulib module unistr/u8-mbtouc-unsafe + +## begin gnulib module unistr/u8-strlen + +if LIBUNISTRING_COMPILE_UNISTR_U8_STRLEN +libgnu_a_SOURCES += unistr/u8-strlen.c +endif + +## end gnulib module unistr/u8-strlen + +## begin gnulib module unistr/u8-uctomb + +if LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB +libgnu_a_SOURCES += unistr/u8-uctomb.c unistr/u8-uctomb-aux.c +endif + +## end gnulib module unistr/u8-uctomb + +## begin gnulib module unitypes + +BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H) + +unitypes.h: unitypes.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unitypes.in.h + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += unitypes.h unitypes.h-t + +EXTRA_DIST += unitypes.in.h + +## end gnulib module unitypes + +## begin gnulib module uniwidth/base + +BUILT_SOURCES += $(LIBUNISTRING_UNIWIDTH_H) + +uniwidth.h: uniwidth.in.h + $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/uniwidth.in.h + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += uniwidth.h uniwidth.h-t + +EXTRA_DIST += localcharset.h uniwidth.in.h + +## end gnulib module uniwidth/base + +## begin gnulib module uniwidth/width + +if LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH +libgnu_a_SOURCES += uniwidth/width.c +endif + +EXTRA_DIST += unictype/bitmap.h uniwidth/cjk.h uniwidth/width0.h uniwidth/width2.h + +## end gnulib module uniwidth/width + +## begin gnulib module unlink + +if GL_COND_OBJ_UNLINK +libgnu_a_SOURCES += unlink.c +endif + +## end gnulib module unlink + +## begin gnulib module unlocked-io-internal + + +EXTRA_DIST += unlocked-io.h + +## end gnulib module unlocked-io-internal + +## begin gnulib module update-copyright + + +EXTRA_DIST += $(top_srcdir)/build-aux/update-copyright + +## end gnulib module update-copyright + +## begin gnulib module useless-if-before-free + + +EXTRA_DIST += $(top_srcdir)/build-aux/useless-if-before-free + +## end gnulib module useless-if-before-free + +## begin gnulib module utime + +if GL_COND_OBJ_UTIME +libgnu_a_SOURCES += utime.c +endif + +## end gnulib module utime + +## begin gnulib module utime-h + +BUILT_SOURCES += utime.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +utime.h: utime.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/@''HAVE_UTIME_H''@/$(HAVE_UTIME_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_UTIME_H''@|$(NEXT_UTIME_H)|g' \ + -e 's/@''GNULIB_UTIME''@/$(GL_GNULIB_UTIME)/g' \ + -e 's/@''GNULIB_MDA_UTIME''@/$(GL_GNULIB_MDA_UTIME)/g' \ + -e 's|@''HAVE_UTIME''@|$(HAVE_UTIME)|g' \ + -e 's|@''REPLACE_UTIME''@|$(REPLACE_UTIME)|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)/utime.in.h > $@-t + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += utime.h utime.h-t + +EXTRA_DIST += utime.in.h + +## end gnulib module utime-h + +## begin gnulib module utimens + +libgnu_a_SOURCES += utimens.c + +EXTRA_DIST += utimens.h + +## end gnulib module utimens + +## begin gnulib module vasnprintf + + +EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h + +EXTRA_libgnu_a_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c + +## end gnulib module vasnprintf + +## begin gnulib module vasprintf + + +EXTRA_DIST += asprintf.c vasprintf.c + +EXTRA_libgnu_a_SOURCES += asprintf.c vasprintf.c + +## end gnulib module vasprintf + +## begin gnulib module vc-list-files + + +EXTRA_DIST += $(top_srcdir)/build-aux/vc-list-files + +## end gnulib module vc-list-files + +## begin gnulib module verify + + +EXTRA_DIST += verify.h + +## end gnulib module verify + +## begin gnulib module vsnprintf + + +EXTRA_DIST += vsnprintf.c + +EXTRA_libgnu_a_SOURCES += vsnprintf.c + +## end gnulib module vsnprintf + +## begin gnulib module wait-process + +libgnu_a_SOURCES += wait-process.h wait-process.c + +## end gnulib module wait-process + +## begin gnulib module waitpid + +if GL_COND_OBJ_WAITPID +libgnu_a_SOURCES += waitpid.c +endif + +## end gnulib module waitpid + +## begin gnulib module wchar + +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) + $(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/@''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' \ + -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ + -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ + -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \ + -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \ + -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \ + -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ + -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ + -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ + -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \ + -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' \ + -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \ + -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \ + -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \ + -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \ + -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \ + -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \ + -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \ + -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \ + -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \ + -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \ + -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \ + -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \ + -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \ + -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \ + -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \ + -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \ + -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \ + -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \ + -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' \ + -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \ + -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ + -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ + -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ + -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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += wchar.h wchar.h-t + +EXTRA_DIST += wchar.in.h + +## end gnulib module wchar + +## begin gnulib module wcrtomb + +if GL_COND_OBJ_WCRTOMB +libgnu_a_SOURCES += wcrtomb.c +endif + +## end gnulib module wcrtomb + +## begin gnulib module wctype-h + +BUILT_SOURCES += wctype.h +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) + $(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/@''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 + $(AM_V_at)mv $@-t $@ +MOSTLYCLEANFILES += wctype.h wctype.h-t + +EXTRA_DIST += wctype.in.h + +## end gnulib module wctype-h + +## begin gnulib module wcwidth + +if GL_COND_OBJ_WCWIDTH +libgnu_a_SOURCES += wcwidth.c +endif + +## end gnulib module wcwidth + +## 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 windows-spawn + +if GL_COND_OBJ_WINDOWS_SPAWN +libgnu_a_SOURCES += windows-spawn.c +endif + +EXTRA_DIST += windows-spawn.h + +## end gnulib module windows-spawn + +## begin gnulib module wmemchr + +if GL_COND_OBJ_WMEMCHR +libgnu_a_SOURCES += wmemchr.c +endif + +EXTRA_DIST += wmemchr-impl.h + +## end gnulib module wmemchr + +## begin gnulib module wmempcpy + +if GL_COND_OBJ_WMEMPCPY +libgnu_a_SOURCES += wmempcpy.c +endif + +## end gnulib module wmempcpy + +## begin gnulib module write + +if GL_COND_OBJ_WRITE +libgnu_a_SOURCES += write.c +endif + +## end gnulib module write + +## begin gnulib module xalloc + +libgnu_a_SOURCES += xmalloc.c + +EXTRA_DIST += xalloc.h + +## end gnulib module xalloc + +## begin gnulib module xalloc-die + +libgnu_a_SOURCES += xalloc-die.c + +EXTRA_DIST += xalloc.h + +## end gnulib module xalloc-die + +## begin gnulib module xalloc-oversized + + +EXTRA_DIST += xalloc-oversized.h + +## end gnulib module xalloc-oversized + +## begin gnulib module xmemdup0 + +libgnu_a_SOURCES += xmemdup0.h xmemdup0.c + +## end gnulib module xmemdup0 + +## begin gnulib module xsize + +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 \ + if test -n "$$dir" && test -d $$dir; then \ + echo "rmdir $$dir"; rmdir $$dir; \ + fi; \ + done; \ + : +distclean-local: distclean-gnulib-libobjs +distclean-gnulib-libobjs: + -rm -f @gl_LIBOBJDEPS@ +maintainer-clean-local: distclean-gnulib-libobjs diff --git a/lib/group-member.c b/lib/group-member.c new file mode 100644 index 0000000..480a126 --- /dev/null +++ b/lib/group-member.c @@ -0,0 +1,115 @@ +/* group-member.c -- determine whether group id is in calling user's group list + + Copyright (C) 1994, 1997-1998, 2003, 2005-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 . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#include "intprops.h" + +/* Most processes have no more than this many groups, and for these + processes we can avoid using malloc. */ +enum { GROUPBUF_SIZE = 100 }; + +struct group_info + { + gid_t *group; + gid_t groupbuf[GROUPBUF_SIZE]; + }; + +static void +free_group_info (struct group_info const *g) +{ + if (g->group != g->groupbuf) + free (g->group); +} + +static int +get_group_info (struct group_info *gi) +{ + int n_groups = getgroups (GROUPBUF_SIZE, gi->groupbuf); + gi->group = gi->groupbuf; + + if (n_groups < 0) + { + int n_group_slots = getgroups (0, NULL); + size_t nbytes; + if (! INT_MULTIPLY_WRAPV (n_group_slots, sizeof *gi->group, &nbytes)) + { + gi->group = malloc (nbytes); + if (gi->group) + n_groups = getgroups (n_group_slots, gi->group); + } + } + + /* In case of error, the user loses. */ + return n_groups; +} + +/* Return non-zero if GID is one that we have in our groups list. + Note that the groups list is not guaranteed to contain the current + or effective group ID, so they should generally be checked + separately. */ + +int +group_member (gid_t gid) +{ + int i; + int found; + struct group_info gi; + int n_groups = get_group_info (&gi); + + /* Search through the list looking for GID. */ + found = 0; + for (i = 0; i < n_groups; i++) + { + if (gid == gi.group[i]) + { + found = 1; + break; + } + } + + free_group_info (&gi); + + return found; +} + +#ifdef TEST + +int +main (int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) + { + gid_t gid; + + gid = atoi (argv[i]); + printf ("%d: %s\n", gid, group_member (gid) ? "yes" : "no"); + } + exit (0); +} + +#endif /* TEST */ diff --git a/lib/hard-locale.c b/lib/hard-locale.c new file mode 100644 index 0000000..f7fbc47 --- /dev/null +++ b/lib/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/lib/hard-locale.h b/lib/hard-locale.h new file mode 100644 index 0000000..6066f4e --- /dev/null +++ b/lib/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/lib/hash-pjw.c b/lib/hash-pjw.c new file mode 100644 index 0000000..8ba139d --- /dev/null +++ b/lib/hash-pjw.c @@ -0,0 +1,40 @@ +/* hash-pjw.c -- compute a hash value from a NUL-terminated string. + + Copyright (C) 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 . */ + +#include + +#include "hash-pjw.h" + +#include + +#define SIZE_BITS (sizeof (size_t) * CHAR_BIT) + +/* A hash function for NUL-terminated char* strings using + the method described by Bruno Haible. + See https://www.haible.de/bruno/hashfunc.html. */ + +size_t +hash_pjw (const void *x, size_t tablesize) +{ + const char *s; + size_t h = 0; + + for (s = x; *s; s++) + h = *s + ((h << 9) | (h >> (SIZE_BITS - 9))); + + return h % tablesize; +} diff --git a/lib/hash-pjw.h b/lib/hash-pjw.h new file mode 100644 index 0000000..cdf4da2 --- /dev/null +++ b/lib/hash-pjw.h @@ -0,0 +1,23 @@ +/* hash-pjw.h -- declaration for a simple hash function + Copyright (C) 2001, 2003, 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 + +/* Compute a hash code for a NUL-terminated string starting at X, + and return the hash code modulo TABLESIZE. + The result is platform dependent: it depends on the size of the 'size_t' + type and on the signedness of the 'char' type. */ +extern size_t hash_pjw (void const *x, size_t tablesize) _GL_ATTRIBUTE_PURE; diff --git a/lib/hash-triple-simple.c b/lib/hash-triple-simple.c new file mode 100644 index 0000000..b021f34 --- /dev/null +++ b/lib/hash-triple-simple.c @@ -0,0 +1,59 @@ +/* Hash functions for file-related triples: name, device, inode. + 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 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 */ + +#include + +/* Specification. */ +#include "hash-triple.h" + +#include +#include + +#include "hash-pjw.h" +#include "same-inode.h" + +#define STREQ(a, b) (strcmp (a, b) == 0) + +/* Hash an F_triple, and *do* consider the file name. */ +size_t +triple_hash (void const *x, size_t table_size) +{ + struct F_triple const *p = x; + size_t tmp = hash_pjw (p->name, table_size); + + /* Ignoring the device number here should be fine. */ + return (tmp ^ p->st_ino) % table_size; +} + +/* Compare two F_triple structs. */ +bool +triple_compare_ino_str (void const *x, void const *y) +{ + struct F_triple const *a = x; + struct F_triple const *b = y; + return (SAME_INODE (*a, *b) && STREQ (a->name, b->name)) ? true : false; +} + +/* Free an F_triple. */ +void +triple_free (void *x) +{ + struct F_triple *a = x; + free (a->name); + free (a); +} diff --git a/lib/hash-triple.h b/lib/hash-triple.h new file mode 100644 index 0000000..929995f --- /dev/null +++ b/lib/hash-triple.h @@ -0,0 +1,46 @@ +/* Hash functions for file-related (name, device, inode) triples. + 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 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, 2007. */ + +#ifndef HASH_TRIPLE_H +#define HASH_TRIPLE_H + +#include +#include +#include + +/* Describe a just-created or just-renamed destination file. */ +struct F_triple +{ + char *name; + ino_t st_ino; + dev_t st_dev; +}; + +/* Defined in module 'hash-triple-simple'. */ + +extern size_t triple_hash (void const *x, size_t table_size) _GL_ATTRIBUTE_PURE; +extern bool triple_compare_ino_str (void const *x, void const *y) + _GL_ATTRIBUTE_PURE; +extern void triple_free (void *x); + +/* Defined in module 'hash-triple'. */ +extern size_t triple_hash_no_name (void const *x, size_t table_size) + _GL_ATTRIBUTE_PURE; +extern bool triple_compare (void const *x, void const *y); + +#endif diff --git a/lib/hash.c b/lib/hash.c new file mode 100644 index 0000000..eb72341 --- /dev/null +++ b/lib/hash.c @@ -0,0 +1,1106 @@ +/* hash - hashing table processing. + + Copyright (C) 1998-2004, 2006-2007, 2009-2022 Free Software Foundation, Inc. + + Written by Jim Meyering, 1992. + + 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 . */ + +/* A generic hash table package. */ + +/* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead + of malloc. If you change USE_OBSTACK, you have to recompile! */ + +#include + +#include "hash.h" + +#include "bitrotate.h" +#include "xalloc-oversized.h" + +#include +#include +#include + +#if USE_OBSTACK +# include "obstack.h" +# ifndef obstack_chunk_alloc +# define obstack_chunk_alloc malloc +# endif +# ifndef obstack_chunk_free +# define obstack_chunk_free free +# endif +#endif + +struct hash_entry + { + void *data; + struct hash_entry *next; + }; + +struct hash_table + { + /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1, + for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets + are not empty, there are N_ENTRIES active entries in the table. */ + struct hash_entry *bucket; + struct hash_entry const *bucket_limit; + size_t n_buckets; + size_t n_buckets_used; + size_t n_entries; + + /* Tuning arguments, kept in a physically separate structure. */ + const Hash_tuning *tuning; + + /* Three functions are given to 'hash_initialize', see the documentation + block for this function. In a word, HASHER randomizes a user entry + into a number up from 0 up to some maximum minus 1; COMPARATOR returns + true if two user entries compare equally; and DATA_FREER is the cleanup + function for a user entry. */ + Hash_hasher hasher; + Hash_comparator comparator; + Hash_data_freer data_freer; + + /* A linked list of freed struct hash_entry structs. */ + struct hash_entry *free_entry_list; + +#if USE_OBSTACK + /* Whenever obstacks are used, it is possible to allocate all overflowed + entries into a single stack, so they all can be freed in a single + operation. It is not clear if the speedup is worth the trouble. */ + struct obstack entry_stack; +#endif + }; + +/* A hash table contains many internal entries, each holding a pointer to + some user-provided data (also called a user entry). An entry indistinctly + refers to both the internal entry and its associated user entry. A user + entry contents may be hashed by a randomization function (the hashing + function, or just "hasher" for short) into a number (or "slot") between 0 + and the current table size. At each slot position in the hash table, + starts a linked chain of entries for which the user data all hash to this + slot. A bucket is the collection of all entries hashing to the same slot. + + A good "hasher" function will distribute entries rather evenly in buckets. + In the ideal case, the length of each bucket is roughly the number of + entries divided by the table size. Finding the slot for a data is usually + done in constant time by the "hasher", and the later finding of a precise + entry is linear in time with the size of the bucket. Consequently, a + larger hash table size (that is, a larger number of buckets) is prone to + yielding shorter chains, *given* the "hasher" function behaves properly. + + Long buckets slow down the lookup algorithm. One might use big hash table + sizes in hope to reduce the average length of buckets, but this might + become inordinate, as unused slots in the hash table take some space. The + best bet is to make sure you are using a good "hasher" function (beware + that those are not that easy to write! :-), and to use a table size + larger than the actual number of entries. */ + +/* If an insertion makes the ratio of nonempty buckets to table size larger + than the growth threshold (a number between 0.0 and 1.0), then increase + the table size by multiplying by the growth factor (a number greater than + 1.0). The growth threshold defaults to 0.8, and the growth factor + defaults to 1.414, meaning that the table will have doubled its size + every second time 80% of the buckets get used. */ +#define DEFAULT_GROWTH_THRESHOLD 0.8f +#define DEFAULT_GROWTH_FACTOR 1.414f + +/* If a deletion empties a bucket and causes the ratio of used buckets to + table size to become smaller than the shrink threshold (a number between + 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a + number greater than the shrink threshold but smaller than 1.0). The shrink + threshold and factor default to 0.0 and 1.0, meaning that the table never + shrinks. */ +#define DEFAULT_SHRINK_THRESHOLD 0.0f +#define DEFAULT_SHRINK_FACTOR 1.0f + +/* Use this to initialize or reset a TUNING structure to + some sensible values. */ +static const Hash_tuning default_tuning = + { + DEFAULT_SHRINK_THRESHOLD, + DEFAULT_SHRINK_FACTOR, + DEFAULT_GROWTH_THRESHOLD, + DEFAULT_GROWTH_FACTOR, + false + }; + +/* Information and lookup. */ + +size_t +hash_get_n_buckets (const Hash_table *table) +{ + return table->n_buckets; +} + +size_t +hash_get_n_buckets_used (const Hash_table *table) +{ + return table->n_buckets_used; +} + +size_t +hash_get_n_entries (const Hash_table *table) +{ + return table->n_entries; +} + +size_t +hash_get_max_bucket_length (const Hash_table *table) +{ + struct hash_entry const *bucket; + size_t max_bucket_length = 0; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + struct hash_entry const *cursor = bucket; + size_t bucket_length = 1; + + while (cursor = cursor->next, cursor) + bucket_length++; + + if (bucket_length > max_bucket_length) + max_bucket_length = bucket_length; + } + } + + return max_bucket_length; +} + +bool +hash_table_ok (const Hash_table *table) +{ + struct hash_entry const *bucket; + size_t n_buckets_used = 0; + size_t n_entries = 0; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + struct hash_entry const *cursor = bucket; + + /* Count bucket head. */ + n_buckets_used++; + n_entries++; + + /* Count bucket overflow. */ + while (cursor = cursor->next, cursor) + n_entries++; + } + } + + if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries) + return true; + + return false; +} + +void +hash_print_statistics (const Hash_table *table, FILE *stream) +{ + size_t n_entries = hash_get_n_entries (table); + size_t n_buckets = hash_get_n_buckets (table); + size_t n_buckets_used = hash_get_n_buckets_used (table); + size_t max_bucket_length = hash_get_max_bucket_length (table); + + fprintf (stream, "# entries: %lu\n", (unsigned long int) n_entries); + fprintf (stream, "# buckets: %lu\n", (unsigned long int) n_buckets); + fprintf (stream, "# buckets used: %lu (%.2f%%)\n", + (unsigned long int) n_buckets_used, + (100.0 * n_buckets_used) / n_buckets); + fprintf (stream, "max bucket length: %lu\n", + (unsigned long int) max_bucket_length); +} + +/* Hash KEY and return a pointer to the selected bucket. + If TABLE->hasher misbehaves, abort. */ +static struct hash_entry * +safe_hasher (const Hash_table *table, const void *key) +{ + size_t n = table->hasher (key, table->n_buckets); + if (! (n < table->n_buckets)) + abort (); + return table->bucket + n; +} + +void * +hash_lookup (const Hash_table *table, const void *entry) +{ + struct hash_entry const *bucket = safe_hasher (table, entry); + struct hash_entry const *cursor; + + if (bucket->data == NULL) + return NULL; + + for (cursor = bucket; cursor; cursor = cursor->next) + if (entry == cursor->data || table->comparator (entry, cursor->data)) + return cursor->data; + + return NULL; +} + +/* Walking. */ + +void * +hash_get_first (const Hash_table *table) +{ + struct hash_entry const *bucket; + + if (table->n_entries == 0) + return NULL; + + for (bucket = table->bucket; ; bucket++) + if (! (bucket < table->bucket_limit)) + abort (); + else if (bucket->data) + return bucket->data; +} + +void * +hash_get_next (const Hash_table *table, const void *entry) +{ + struct hash_entry const *bucket = safe_hasher (table, entry); + struct hash_entry const *cursor; + + /* Find next entry in the same bucket. */ + cursor = bucket; + do + { + if (cursor->data == entry && cursor->next) + return cursor->next->data; + cursor = cursor->next; + } + while (cursor != NULL); + + /* Find first entry in any subsequent bucket. */ + while (++bucket < table->bucket_limit) + if (bucket->data) + return bucket->data; + + /* None found. */ + return NULL; +} + +size_t +hash_get_entries (const Hash_table *table, void **buffer, + size_t buffer_size) +{ + size_t counter = 0; + struct hash_entry const *bucket; + struct hash_entry const *cursor; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + for (cursor = bucket; cursor; cursor = cursor->next) + { + if (counter >= buffer_size) + return counter; + buffer[counter++] = cursor->data; + } + } + } + + return counter; +} + +size_t +hash_do_for_each (const Hash_table *table, Hash_processor processor, + void *processor_data) +{ + size_t counter = 0; + struct hash_entry const *bucket; + struct hash_entry const *cursor; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + for (cursor = bucket; cursor; cursor = cursor->next) + { + if (! processor (cursor->data, processor_data)) + return counter; + counter++; + } + } + } + + return counter; +} + +/* Allocation and clean-up. */ + +#if USE_DIFF_HASH + +/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see + B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, + Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash + algorithms tend to be domain-specific, so what's good for [diffutils'] io.c + may not be good for your application." */ + +size_t +hash_string (const char *string, size_t n_buckets) +{ +# define HASH_ONE_CHAR(Value, Byte) \ + ((Byte) + rotl_sz (Value, 7)) + + size_t value = 0; + unsigned char ch; + + for (; (ch = *string); string++) + value = HASH_ONE_CHAR (value, ch); + return value % n_buckets; + +# undef HASH_ONE_CHAR +} + +#else /* not USE_DIFF_HASH */ + +/* This one comes from 'recode', and performs a bit better than the above as + per a few experiments. It is inspired from a hashing routine found in the + very old Cyber 'snoop', itself written in typical Greg Mansfield style. + (By the way, what happened to this excellent man? Is he still alive?) */ + +size_t +hash_string (const char *string, size_t n_buckets) +{ + size_t value = 0; + unsigned char ch; + + for (; (ch = *string); string++) + value = (value * 31 + ch) % n_buckets; + return value; +} + +#endif /* not USE_DIFF_HASH */ + +/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd + number at least equal to 11. */ + +static bool _GL_ATTRIBUTE_CONST +is_prime (size_t candidate) +{ + size_t divisor = 3; + size_t square = divisor * divisor; + + while (square < candidate && (candidate % divisor)) + { + divisor++; + square += 4 * divisor; + divisor++; + } + + return (candidate % divisor ? true : false); +} + +/* Round a given CANDIDATE number up to the nearest prime, and return that + prime. Primes lower than 10 are merely skipped. */ + +static size_t _GL_ATTRIBUTE_CONST +next_prime (size_t candidate) +{ + /* Skip small primes. */ + if (candidate < 10) + candidate = 10; + + /* Make it definitely odd. */ + candidate |= 1; + + while (SIZE_MAX != candidate && !is_prime (candidate)) + candidate += 2; + + return candidate; +} + +void +hash_reset_tuning (Hash_tuning *tuning) +{ + *tuning = default_tuning; +} + +/* If the user passes a NULL hasher, we hash the raw pointer. */ +static size_t +raw_hasher (const void *data, size_t n) +{ + /* When hashing unique pointers, it is often the case that they were + generated by malloc and thus have the property that the low-order + bits are 0. As this tends to give poorer performance with small + tables, we rotate the pointer value before performing division, + in an attempt to improve hash quality. */ + size_t val = rotr_sz ((size_t) data, 3); + return val % n; +} + +/* If the user passes a NULL comparator, we use pointer comparison. */ +static bool +raw_comparator (const void *a, const void *b) +{ + return a == b; +} + + +/* For the given hash TABLE, check the user supplied tuning structure for + reasonable values, and return true if there is no gross error with it. + Otherwise, definitively reset the TUNING field to some acceptable default + in the hash table (that is, the user loses the right of further modifying + tuning arguments), and return false. */ + +static bool +check_tuning (Hash_table *table) +{ + const Hash_tuning *tuning = table->tuning; + float epsilon; + if (tuning == &default_tuning) + return true; + + /* Be a bit stricter than mathematics would require, so that + rounding errors in size calculations do not cause allocations to + fail to grow or shrink as they should. The smallest allocation + is 11 (due to next_prime's algorithm), so an epsilon of 0.1 + should be good enough. */ + epsilon = 0.1f; + + if (epsilon < tuning->growth_threshold + && tuning->growth_threshold < 1 - epsilon + && 1 + epsilon < tuning->growth_factor + && 0 <= tuning->shrink_threshold + && tuning->shrink_threshold + epsilon < tuning->shrink_factor + && tuning->shrink_factor <= 1 + && tuning->shrink_threshold + epsilon < tuning->growth_threshold) + return true; + + table->tuning = &default_tuning; + return false; +} + +/* Compute the size of the bucket array for the given CANDIDATE and + TUNING, or return 0 if there is no possible way to allocate that + many entries. */ + +static size_t _GL_ATTRIBUTE_PURE +compute_bucket_size (size_t candidate, const Hash_tuning *tuning) +{ + if (!tuning->is_n_buckets) + { + float new_candidate = candidate / tuning->growth_threshold; + if ((float) SIZE_MAX <= new_candidate) + return 0; + candidate = new_candidate; + } + candidate = next_prime (candidate); + if (xalloc_oversized (candidate, sizeof (struct hash_entry *))) + return 0; + return candidate; +} + +Hash_table * +hash_initialize (size_t candidate, const Hash_tuning *tuning, + Hash_hasher hasher, Hash_comparator comparator, + Hash_data_freer data_freer) +{ + Hash_table *table; + + if (hasher == NULL) + hasher = raw_hasher; + if (comparator == NULL) + comparator = raw_comparator; + + table = malloc (sizeof *table); + if (table == NULL) + return NULL; + + if (!tuning) + tuning = &default_tuning; + table->tuning = tuning; + if (!check_tuning (table)) + { + /* Fail if the tuning options are invalid. This is the only occasion + when the user gets some feedback about it. Once the table is created, + if the user provides invalid tuning options, we silently revert to + using the defaults, and ignore further request to change the tuning + options. */ + goto fail; + } + + table->n_buckets = compute_bucket_size (candidate, tuning); + if (!table->n_buckets) + goto fail; + + table->bucket = calloc (table->n_buckets, sizeof *table->bucket); + if (table->bucket == NULL) + goto fail; + table->bucket_limit = table->bucket + table->n_buckets; + table->n_buckets_used = 0; + table->n_entries = 0; + + table->hasher = hasher; + table->comparator = comparator; + table->data_freer = data_freer; + + table->free_entry_list = NULL; +#if USE_OBSTACK + obstack_init (&table->entry_stack); +#endif + return table; + + fail: + free (table); + return NULL; +} + +void +hash_clear (Hash_table *table) +{ + struct hash_entry *bucket; + + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + struct hash_entry *cursor; + struct hash_entry *next; + + /* Free the bucket overflow. */ + for (cursor = bucket->next; cursor; cursor = next) + { + if (table->data_freer) + table->data_freer (cursor->data); + cursor->data = NULL; + + next = cursor->next; + /* Relinking is done one entry at a time, as it is to be expected + that overflows are either rare or short. */ + cursor->next = table->free_entry_list; + table->free_entry_list = cursor; + } + + /* Free the bucket head. */ + if (table->data_freer) + table->data_freer (bucket->data); + bucket->data = NULL; + bucket->next = NULL; + } + } + + table->n_buckets_used = 0; + table->n_entries = 0; +} + +void +hash_free (Hash_table *table) +{ + struct hash_entry *bucket; + struct hash_entry *cursor; + struct hash_entry *next; + + /* Call the user data_freer function. */ + if (table->data_freer && table->n_entries) + { + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + if (bucket->data) + { + for (cursor = bucket; cursor; cursor = cursor->next) + table->data_freer (cursor->data); + } + } + } + +#if USE_OBSTACK + + obstack_free (&table->entry_stack, NULL); + +#else + + /* Free all bucket overflowed entries. */ + for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) + { + for (cursor = bucket->next; cursor; cursor = next) + { + next = cursor->next; + free (cursor); + } + } + + /* Also reclaim the internal list of previously freed entries. */ + for (cursor = table->free_entry_list; cursor; cursor = next) + { + next = cursor->next; + free (cursor); + } + +#endif + + /* Free the remainder of the hash table structure. */ + free (table->bucket); + free (table); +} + +/* Insertion and deletion. */ + +/* Get a new hash entry for a bucket overflow, possibly by recycling a + previously freed one. If this is not possible, allocate a new one. */ + +static struct hash_entry * +allocate_entry (Hash_table *table) +{ + struct hash_entry *new; + + if (table->free_entry_list) + { + new = table->free_entry_list; + table->free_entry_list = new->next; + } + else + { +#if USE_OBSTACK + new = obstack_alloc (&table->entry_stack, sizeof *new); +#else + new = malloc (sizeof *new); +#endif + } + + return new; +} + +/* Free a hash entry which was part of some bucket overflow, + saving it for later recycling. */ + +static void +free_entry (Hash_table *table, struct hash_entry *entry) +{ + entry->data = NULL; + entry->next = table->free_entry_list; + table->free_entry_list = entry; +} + +/* This private function is used to help with insertion and deletion. When + ENTRY matches an entry in the table, return a pointer to the corresponding + user data and set *BUCKET_HEAD to the head of the selected bucket. + Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in + the table, unlink the matching entry. */ + +static void * +hash_find_entry (Hash_table *table, const void *entry, + struct hash_entry **bucket_head, bool delete) +{ + struct hash_entry *bucket = safe_hasher (table, entry); + struct hash_entry *cursor; + + *bucket_head = bucket; + + /* Test for empty bucket. */ + if (bucket->data == NULL) + return NULL; + + /* See if the entry is the first in the bucket. */ + if (entry == bucket->data || table->comparator (entry, bucket->data)) + { + void *data = bucket->data; + + if (delete) + { + if (bucket->next) + { + struct hash_entry *next = bucket->next; + + /* Bump the first overflow entry into the bucket head, then save + the previous first overflow entry for later recycling. */ + *bucket = *next; + free_entry (table, next); + } + else + { + bucket->data = NULL; + } + } + + return data; + } + + /* Scan the bucket overflow. */ + for (cursor = bucket; cursor->next; cursor = cursor->next) + { + if (entry == cursor->next->data + || table->comparator (entry, cursor->next->data)) + { + void *data = cursor->next->data; + + if (delete) + { + struct hash_entry *next = cursor->next; + + /* Unlink the entry to delete, then save the freed entry for later + recycling. */ + cursor->next = next->next; + free_entry (table, next); + } + + return data; + } + } + + /* No entry found. */ + return NULL; +} + +/* Internal helper, to move entries from SRC to DST. Both tables must + share the same free entry list. If SAFE, only move overflow + entries, saving bucket heads for later, so that no allocations will + occur. Return false if the free entry list is exhausted and an + allocation fails. */ + +static bool +transfer_entries (Hash_table *dst, Hash_table *src, bool safe) +{ + struct hash_entry *bucket; + struct hash_entry *cursor; + struct hash_entry *next; + for (bucket = src->bucket; bucket < src->bucket_limit; bucket++) + if (bucket->data) + { + void *data; + struct hash_entry *new_bucket; + + /* Within each bucket, transfer overflow entries first and + then the bucket head, to minimize memory pressure. After + all, the only time we might allocate is when moving the + bucket head, but moving overflow entries first may create + free entries that can be recycled by the time we finally + get to the bucket head. */ + for (cursor = bucket->next; cursor; cursor = next) + { + data = cursor->data; + new_bucket = safe_hasher (dst, data); + + next = cursor->next; + + if (new_bucket->data) + { + /* Merely relink an existing entry, when moving from a + bucket overflow into a bucket overflow. */ + cursor->next = new_bucket->next; + new_bucket->next = cursor; + } + else + { + /* Free an existing entry, when moving from a bucket + overflow into a bucket header. */ + new_bucket->data = data; + dst->n_buckets_used++; + free_entry (dst, cursor); + } + } + /* Now move the bucket head. Be sure that if we fail due to + allocation failure that the src table is in a consistent + state. */ + data = bucket->data; + bucket->next = NULL; + if (safe) + continue; + new_bucket = safe_hasher (dst, data); + + if (new_bucket->data) + { + /* Allocate or recycle an entry, when moving from a bucket + header into a bucket overflow. */ + struct hash_entry *new_entry = allocate_entry (dst); + + if (new_entry == NULL) + return false; + + new_entry->data = data; + new_entry->next = new_bucket->next; + new_bucket->next = new_entry; + } + else + { + /* Move from one bucket header to another. */ + new_bucket->data = data; + dst->n_buckets_used++; + } + bucket->data = NULL; + src->n_buckets_used--; + } + return true; +} + +bool +hash_rehash (Hash_table *table, size_t candidate) +{ + Hash_table storage; + Hash_table *new_table; + size_t new_size = compute_bucket_size (candidate, table->tuning); + + if (!new_size) + return false; + if (new_size == table->n_buckets) + return true; + new_table = &storage; + new_table->bucket = calloc (new_size, sizeof *new_table->bucket); + if (new_table->bucket == NULL) + return false; + new_table->n_buckets = new_size; + new_table->bucket_limit = new_table->bucket + new_size; + new_table->n_buckets_used = 0; + new_table->n_entries = 0; + new_table->tuning = table->tuning; + new_table->hasher = table->hasher; + new_table->comparator = table->comparator; + new_table->data_freer = table->data_freer; + + /* In order for the transfer to successfully complete, we need + additional overflow entries when distinct buckets in the old + table collide into a common bucket in the new table. The worst + case possible is a hasher that gives a good spread with the old + size, but returns a constant with the new size; if we were to + guarantee table->n_buckets_used-1 free entries in advance, then + the transfer would be guaranteed to not allocate memory. + However, for large tables, a guarantee of no further allocation + introduces a lot of extra memory pressure, all for an unlikely + corner case (most rehashes reduce, rather than increase, the + number of overflow entries needed). So, we instead ensure that + the transfer process can be reversed if we hit a memory + allocation failure mid-transfer. */ + + /* Merely reuse the extra old space into the new table. */ +#if USE_OBSTACK + new_table->entry_stack = table->entry_stack; +#endif + new_table->free_entry_list = table->free_entry_list; + + if (transfer_entries (new_table, table, false)) + { + /* Entries transferred successfully; tie up the loose ends. */ + free (table->bucket); + table->bucket = new_table->bucket; + table->bucket_limit = new_table->bucket_limit; + table->n_buckets = new_table->n_buckets; + table->n_buckets_used = new_table->n_buckets_used; + table->free_entry_list = new_table->free_entry_list; + /* table->n_entries and table->entry_stack already hold their value. */ + return true; + } + + /* We've allocated new_table->bucket (and possibly some entries), + exhausted the free list, and moved some but not all entries into + new_table. We must undo the partial move before returning + failure. The only way to get into this situation is if new_table + uses fewer buckets than the old table, so we will reclaim some + free entries as overflows in the new table are put back into + distinct buckets in the old table. + + There are some pathological cases where a single pass through the + table requires more intermediate overflow entries than using two + passes. Two passes give worse cache performance and takes + longer, but at this point, we're already out of memory, so slow + and safe is better than failure. */ + table->free_entry_list = new_table->free_entry_list; + if (! (transfer_entries (table, new_table, true) + && transfer_entries (table, new_table, false))) + abort (); + /* table->n_entries already holds its value. */ + free (new_table->bucket); + return false; +} + +int +hash_insert_if_absent (Hash_table *table, void const *entry, + void const **matched_ent) +{ + void *data; + struct hash_entry *bucket; + + /* The caller cannot insert a NULL entry, since hash_lookup returns NULL + to indicate "not found", and hash_find_entry uses "bucket->data == NULL" + to indicate an empty bucket. */ + if (! entry) + abort (); + + /* If there's a matching entry already in the table, return that. */ + if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL) + { + if (matched_ent) + *matched_ent = data; + return 0; + } + + /* If the growth threshold of the buckets in use has been reached, increase + the table size and rehash. There's no point in checking the number of + entries: if the hashing function is ill-conditioned, rehashing is not + likely to improve it. */ + + if (table->n_buckets_used + > table->tuning->growth_threshold * table->n_buckets) + { + /* Check more fully, before starting real work. If tuning arguments + became invalid, the second check will rely on proper defaults. */ + check_tuning (table); + if (table->n_buckets_used + > table->tuning->growth_threshold * table->n_buckets) + { + const Hash_tuning *tuning = table->tuning; + float candidate = + (tuning->is_n_buckets + ? (table->n_buckets * tuning->growth_factor) + : (table->n_buckets * tuning->growth_factor + * tuning->growth_threshold)); + + if ((float) SIZE_MAX <= candidate) + return -1; + + /* If the rehash fails, arrange to return NULL. */ + if (!hash_rehash (table, candidate)) + return -1; + + /* Update the bucket we are interested in. */ + if (hash_find_entry (table, entry, &bucket, false) != NULL) + abort (); + } + } + + /* ENTRY is not matched, it should be inserted. */ + + if (bucket->data) + { + struct hash_entry *new_entry = allocate_entry (table); + + if (new_entry == NULL) + return -1; + + /* Add ENTRY in the overflow of the bucket. */ + + new_entry->data = (void *) entry; + new_entry->next = bucket->next; + bucket->next = new_entry; + table->n_entries++; + return 1; + } + + /* Add ENTRY right in the bucket head. */ + + bucket->data = (void *) entry; + table->n_entries++; + table->n_buckets_used++; + + return 1; +} + +void * +hash_insert (Hash_table *table, void const *entry) +{ + void const *matched_ent; + int err = hash_insert_if_absent (table, entry, &matched_ent); + return (err == -1 + ? NULL + : (void *) (err == 0 ? matched_ent : entry)); +} + +void * +hash_remove (Hash_table *table, const void *entry) +{ + void *data; + struct hash_entry *bucket; + + data = hash_find_entry (table, entry, &bucket, true); + if (!data) + return NULL; + + table->n_entries--; + if (!bucket->data) + { + table->n_buckets_used--; + + /* If the shrink threshold of the buckets in use has been reached, + rehash into a smaller table. */ + + if (table->n_buckets_used + < table->tuning->shrink_threshold * table->n_buckets) + { + /* Check more fully, before starting real work. If tuning arguments + became invalid, the second check will rely on proper defaults. */ + check_tuning (table); + if (table->n_buckets_used + < table->tuning->shrink_threshold * table->n_buckets) + { + const Hash_tuning *tuning = table->tuning; + size_t candidate = + (tuning->is_n_buckets + ? table->n_buckets * tuning->shrink_factor + : (table->n_buckets * tuning->shrink_factor + * tuning->growth_threshold)); + + if (!hash_rehash (table, candidate)) + { + /* Failure to allocate memory in an attempt to + shrink the table is not fatal. But since memory + is low, we can at least be kind and free any + spare entries, rather than keeping them tied up + in the free entry list. */ +#if ! USE_OBSTACK + struct hash_entry *cursor = table->free_entry_list; + struct hash_entry *next; + while (cursor) + { + next = cursor->next; + free (cursor); + cursor = next; + } + table->free_entry_list = NULL; +#endif + } + } + } + } + + return data; +} + +void * +hash_delete (Hash_table *table, const void *entry) +{ + return hash_remove (table, entry); +} + +/* Testing. */ + +#if TESTING + +void +hash_print (const Hash_table *table) +{ + struct hash_entry *bucket = (struct hash_entry *) table->bucket; + + for ( ; bucket < table->bucket_limit; bucket++) + { + struct hash_entry *cursor; + + if (bucket) + printf ("%lu:\n", (unsigned long int) (bucket - table->bucket)); + + for (cursor = bucket; cursor; cursor = cursor->next) + { + char const *s = cursor->data; + /* FIXME */ + if (s) + printf (" %s\n", s); + } + } +} + +#endif /* TESTING */ diff --git a/lib/hash.h b/lib/hash.h new file mode 100644 index 0000000..ebfc740 --- /dev/null +++ b/lib/hash.h @@ -0,0 +1,264 @@ +/* hash - hashing table processing. + Copyright (C) 1998-1999, 2001, 2003, 2009-2022 Free Software Foundation, + Inc. + Written by Jim Meyering , 1998. + + 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 . */ + +/* A generic hash table package. */ + +/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use + obstacks instead of malloc, and recompile 'hash.c' with same setting. */ + +#ifndef HASH_H_ +# define HASH_H_ + +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +struct hash_tuning + { + /* This structure is mainly used for 'hash_initialize', see the block + documentation of 'hash_reset_tuning' for more complete comments. */ + + float shrink_threshold; /* ratio of used buckets to trigger a shrink */ + float shrink_factor; /* ratio of new smaller size to original size */ + float growth_threshold; /* ratio of used buckets to trigger a growth */ + float growth_factor; /* ratio of new bigger size to original size */ + bool is_n_buckets; /* if CANDIDATE really means table size */ + }; + +typedef struct hash_tuning Hash_tuning; + +struct hash_table; + +typedef struct hash_table Hash_table; + +/* + * Information and lookup. + */ + +/* The following few functions provide information about the overall hash + table organization: the number of entries, number of buckets and maximum + length of buckets. */ + +/* Return the number of buckets in the hash table. The table size, the total + number of buckets (used plus unused), or the maximum number of slots, are + the same quantity. */ +extern size_t hash_get_n_buckets (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the number of slots in use (non-empty buckets). */ +extern size_t hash_get_n_buckets_used (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the number of active entries. */ +extern size_t hash_get_n_entries (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the length of the longest chain (bucket). */ +extern size_t hash_get_max_bucket_length (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Do a mild validation of a hash table, by traversing it and checking two + statistics. */ +extern bool hash_table_ok (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +extern void hash_print_statistics (const Hash_table *table, FILE *stream); + +/* If ENTRY matches an entry already in the hash table, return the + entry from the table. Otherwise, return NULL. */ +extern void *hash_lookup (const Hash_table *table, const void *entry); + +/* + * Walking. + */ + +/* The functions in this page traverse the hash table and process the + contained entries. For the traversal to work properly, the hash table + should not be resized nor modified while any particular entry is being + processed. In particular, entries should not be added, and an entry + may be removed only if there is no shrink threshold and the entry being + removed has already been passed to hash_get_next. */ + +/* Return the first data in the table, or NULL if the table is empty. */ +extern void *hash_get_first (const Hash_table *table) + _GL_ATTRIBUTE_PURE; + +/* Return the user data for the entry following ENTRY, where ENTRY has been + returned by a previous call to either 'hash_get_first' or 'hash_get_next'. + Return NULL if there are no more entries. */ +extern void *hash_get_next (const Hash_table *table, const void *entry); + +/* Fill BUFFER with pointers to active user entries in the hash table, then + return the number of pointers copied. Do not copy more than BUFFER_SIZE + pointers. */ +extern size_t hash_get_entries (const Hash_table *table, void **buffer, + size_t buffer_size); + +typedef bool (*Hash_processor) (void *entry, void *processor_data); + +/* Call a PROCESSOR function for each entry of a hash table, and return the + number of entries for which the processor function returned success. A + pointer to some PROCESSOR_DATA which will be made available to each call to + the processor function. The PROCESSOR accepts two arguments: the first is + the user entry being walked into, the second is the value of PROCESSOR_DATA + as received. The walking continue for as long as the PROCESSOR function + returns nonzero. When it returns zero, the walking is interrupted. */ +extern size_t hash_do_for_each (const Hash_table *table, + Hash_processor processor, void *processor_data); + +/* + * Allocation and clean-up. + */ + +/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1. + This is a convenience routine for constructing other hashing functions. */ +extern size_t hash_string (const char *string, size_t n_buckets) + _GL_ATTRIBUTE_PURE; + +extern void hash_reset_tuning (Hash_tuning *tuning); + +typedef size_t (*Hash_hasher) (const void *entry, size_t table_size); +typedef bool (*Hash_comparator) (const void *entry1, const void *entry2); +typedef void (*Hash_data_freer) (void *entry); + +/* Reclaim all storage associated with a hash table. If a data_freer + function has been supplied by the user when the hash table was created, + this function applies it to the data of each entry before freeing that + entry. */ +extern void hash_free (Hash_table *table); + +/* Allocate and return a new hash table, or NULL upon failure. The initial + number of buckets is automatically selected so as to _guarantee_ that you + may insert at least CANDIDATE different user entries before any growth of + the hash table size occurs. So, if have a reasonably tight a-priori upper + bound on the number of entries you intend to insert in the hash table, you + may save some table memory and insertion time, by specifying it here. If + the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE + argument has its meaning changed to the wanted number of buckets. + + TUNING points to a structure of user-supplied values, in case some fine + tuning is wanted over the default behavior of the hasher. If TUNING is + NULL, the default tuning parameters are used instead. If TUNING is + provided but the values requested are out of bounds or might cause + rounding errors, return NULL. + + The user-supplied HASHER function, when not NULL, accepts two + arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a + slot number for that entry which should be in the range 0..TABLE_SIZE-1. + This slot number is then returned. + + The user-supplied COMPARATOR function, when not NULL, accepts two + arguments pointing to user data, it then returns true for a pair of entries + that compare equal, or false otherwise. This function is internally called + on entries which are already known to hash to the same bucket index, + but which are distinct pointers. + + The user-supplied DATA_FREER function, when not NULL, may be later called + with the user data as an argument, just before the entry containing the + data gets freed. This happens from within 'hash_free' or 'hash_clear'. + You should specify this function only if you want these functions to free + all of your 'data' data. This is typically the case when your data is + simply an auxiliary struct that you have malloc'd to aggregate several + values. */ +_GL_ATTRIBUTE_NODISCARD +extern Hash_table *hash_initialize (size_t candidate, + const Hash_tuning *tuning, + Hash_hasher hasher, + Hash_comparator comparator, + Hash_data_freer data_freer) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (hash_free, 1); + +/* Same as hash_initialize, but invokes xalloc_die on memory exhaustion. */ +/* This function is defined by module 'xhash'. */ +_GL_ATTRIBUTE_NODISCARD +extern Hash_table *hash_xinitialize (size_t candidate, + const Hash_tuning *tuning, + Hash_hasher hasher, + Hash_comparator comparator, + Hash_data_freer data_freer) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (hash_free, 1) + _GL_ATTRIBUTE_RETURNS_NONNULL; + +/* Make all buckets empty, placing any chained entries on the free list. + Apply the user-specified function data_freer (if any) to the datas of any + affected entries. */ +extern void hash_clear (Hash_table *table); + +/* + * Insertion and deletion. + */ + +/* For an already existing hash table, change the number of buckets through + specifying CANDIDATE. The contents of the hash table are preserved. The + new number of buckets is automatically selected so as to _guarantee_ that + the table may receive at least CANDIDATE different user entries, including + those already in the table, before any other growth of the hash table size + occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the + exact number of buckets desired. Return true iff the rehash succeeded. */ +_GL_ATTRIBUTE_NODISCARD +extern bool hash_rehash (Hash_table *table, size_t candidate); + +/* If ENTRY matches an entry already in the hash table, return the pointer + to the entry from the table. Otherwise, insert ENTRY and return ENTRY. + Return NULL if the storage required for insertion cannot be allocated. + This implementation does not support duplicate entries or insertion of + NULL. */ +_GL_ATTRIBUTE_NODISCARD +extern void *hash_insert (Hash_table *table, const void *entry); + +/* Same as hash_insert, but invokes xalloc_die on memory exhaustion. */ +/* This function is defined by module 'xhash'. */ +extern void *hash_xinsert (Hash_table *table, const void *entry); + +/* Insert ENTRY into hash TABLE if there is not already a matching entry. + + Return -1 upon memory allocation failure. + Return 1 if insertion succeeded. + Return 0 if there is already a matching entry in the table, + and in that case, if MATCHED_ENT is non-NULL, set *MATCHED_ENT + to that entry. + + This interface is easier to use than hash_insert when you must + distinguish between the latter two cases. More importantly, + hash_insert is unusable for some types of ENTRY values. When using + hash_insert, the only way to distinguish those cases is to compare + the return value and ENTRY. That works only when you can have two + different ENTRY values that point to data that compares "equal". Thus, + when the ENTRY value is a simple scalar, you must use + hash_insert_if_absent. ENTRY must not be NULL. */ +extern int hash_insert_if_absent (Hash_table *table, const void *entry, + const void **matched_ent); + +/* If ENTRY is already in the table, remove it and return the just-deleted + data (the user may want to deallocate its storage). If ENTRY is not in the + table, don't modify the table and return NULL. */ +extern void *hash_remove (Hash_table *table, const void *entry); + +/* Same as hash_remove. This interface is deprecated. + FIXME: Remove in 2022. */ +_GL_ATTRIBUTE_DEPRECATED +extern void *hash_delete (Hash_table *table, const void *entry); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/lib/ialloc.c b/lib/ialloc.c new file mode 100644 index 0000000..43c1043 --- /dev/null +++ b/lib/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/lib/ialloc.h b/lib/ialloc.h new file mode 100644 index 0000000..37cf4bf --- /dev/null +++ b/lib/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/lib/iconv.in.h b/lib/iconv.in.h new file mode 100644 index 0000000..4c5a31c --- /dev/null +++ b/lib/iconv.in.h @@ -0,0 +1,127 @@ +/* A GNU-like . + + 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 . */ + +#ifndef _@GUARD_PREFIX@_ICONV_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_ICONV_H@ + +#ifndef _@GUARD_PREFIX@_ICONV_H +#define _@GUARD_PREFIX@_ICONV_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. */ + + +#if @GNULIB_ICONV@ +# if @REPLACE_ICONV_OPEN@ +/* An iconv_open wrapper that supports the IANA standardized encoding names + ("ISO-8859-1" etc.) as far as possible. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iconv_open rpl_iconv_open +# endif +_GL_FUNCDECL_RPL (iconv_open, iconv_t, + (const char *tocode, const char *fromcode) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (iconv_open, iconv_t, + (const char *tocode, const char *fromcode)); +# else +_GL_CXXALIAS_SYS (iconv_open, iconv_t, + (const char *tocode, const char *fromcode)); +# endif +_GL_CXXALIASWARN (iconv_open); +#elif defined GNULIB_POSIXCHECK +# undef iconv_open +# if HAVE_RAW_DECL_ICONV_OPEN +_GL_WARN_ON_USE (iconv_open, "iconv_open is not working correctly everywhere - " + "use gnulib module iconv for portability"); +# endif +#endif + +#if @REPLACE_ICONV_UTF@ +/* Special constants for supporting UTF-{16,32}{BE,LE} encodings. + Not public. */ +# define _ICONV_UTF8_UTF16BE (iconv_t)(-161) +# define _ICONV_UTF8_UTF16LE (iconv_t)(-162) +# define _ICONV_UTF8_UTF32BE (iconv_t)(-163) +# define _ICONV_UTF8_UTF32LE (iconv_t)(-164) +# define _ICONV_UTF16BE_UTF8 (iconv_t)(-165) +# define _ICONV_UTF16LE_UTF8 (iconv_t)(-166) +# define _ICONV_UTF32BE_UTF8 (iconv_t)(-167) +# define _ICONV_UTF32LE_UTF8 (iconv_t)(-168) +#endif + +#if @GNULIB_ICONV@ +# if @REPLACE_ICONV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iconv rpl_iconv +# endif +_GL_FUNCDECL_RPL (iconv, size_t, + (iconv_t cd, + @ICONV_CONST@ char **restrict inbuf, + size_t *restrict inbytesleft, + char **restrict outbuf, size_t *restrict outbytesleft)); +_GL_CXXALIAS_RPL (iconv, size_t, + (iconv_t cd, + @ICONV_CONST@ char **restrict inbuf, + size_t *restrict inbytesleft, + char **restrict outbuf, size_t *restrict outbytesleft)); +# else +/* Need to cast, because on some versions of Solaris, ICONV_CONST does + not have the right value for C++. */ +_GL_CXXALIAS_SYS_CAST (iconv, size_t, + (iconv_t cd, + @ICONV_CONST@ char **restrict inbuf, + size_t *restrict inbytesleft, + char **restrict outbuf, size_t *restrict outbytesleft)); +# endif +_GL_CXXALIASWARN (iconv); +# ifndef ICONV_CONST +# define ICONV_CONST @ICONV_CONST@ +# endif +#elif defined GNULIB_POSIXCHECK +# undef iconv +# if HAVE_RAW_DECL_ICONV +_GL_WARN_ON_USE (iconv, "iconv is not working correctly everywhere - " + "use gnulib module iconv for portability"); +# endif +#endif + +#if @GNULIB_ICONV@ +# if @REPLACE_ICONV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iconv_close rpl_iconv_close +# endif +_GL_FUNCDECL_RPL (iconv_close, int, (iconv_t cd)); +_GL_CXXALIAS_RPL (iconv_close, int, (iconv_t cd)); +# else +_GL_CXXALIAS_SYS (iconv_close, int, (iconv_t cd)); +# endif +_GL_CXXALIASWARN (iconv_close); +#endif + + +#endif /* _@GUARD_PREFIX@_ICONV_H */ +#endif /* _@GUARD_PREFIX@_ICONV_H */ diff --git a/lib/idx.h b/lib/idx.h new file mode 100644 index 0000000..c3669dd --- /dev/null +++ b/lib/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/lib/inet_ntop.c b/lib/inet_ntop.c new file mode 100644 index 0000000..2d401d2 --- /dev/null +++ b/lib/inet_ntop.c @@ -0,0 +1,260 @@ +/* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form + + Copyright (C) 2005-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 . */ + +/* + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include + +/* Specification. */ +#include + +/* Use this to suppress gcc's "...may be used before initialized" warnings. + Beware: The Code argument must not contain commas. */ +#ifndef IF_LINT +# if defined GCC_LINT || defined lint +# define IF_LINT(Code) Code +# else +# define IF_LINT(Code) /* empty */ +# endif +#endif + +#if HAVE_DECL_INET_NTOP + +# undef inet_ntop + +const char * +rpl_inet_ntop (int af, const void *restrict src, + char *restrict dst, socklen_t cnt) +{ + return inet_ntop (af, src, dst, cnt); +} + +#else + +# include +# include +# include + +# define NS_IN6ADDRSZ 16 +# define NS_INT16SZ 2 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ +typedef int verify_int_size[4 <= sizeof (int) ? 1 : -1]; + +static const char *inet_ntop4 (const unsigned char *src, char *dst, socklen_t size); +# if HAVE_IPV6 +static const char *inet_ntop6 (const unsigned char *src, char *dst, socklen_t size); +# endif + + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address ('dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop (int af, const void *restrict src, + char *restrict dst, socklen_t cnt) +{ + switch (af) + { +# if HAVE_IPV4 + case AF_INET: + return (inet_ntop4 (src, dst, cnt)); +# endif + +# if HAVE_IPV6 + case AF_INET6: + return (inet_ntop6 (src, dst, cnt)); +# endif + + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * 'dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4 (const unsigned char *src, char *dst, socklen_t size) +{ + char tmp[sizeof "255.255.255.255"]; + int len; + + len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); + if (len < 0) + return NULL; + + if (len > size) + { + errno = ENOSPC; + return NULL; + } + + return strcpy (dst, tmp); +} + +# if HAVE_IPV6 + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6 (const unsigned char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct + { + int base, len; + } best, cur; + unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset (words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i += 2) + words[i / 2] = (src[i] << 8) | src[i + 1]; + best.base = -1; + cur.base = -1; + IF_LINT(best.len = 0); + IF_LINT(cur.len = 0); + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) + { + if (words[i] == 0) + { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } + else + { + if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) + { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && i < (best.base + best.len)) + { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) + { + if (!inet_ntop4 (src + 12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen (tp); + break; + } + { + int len = sprintf (tp, "%x", words[i]); + if (len < 0) + return NULL; + tp += len; + } + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((socklen_t) (tp - tmp) > size) + { + errno = ENOSPC; + return NULL; + } + + return strcpy (dst, tmp); +} + +# endif + +#endif diff --git a/lib/intprops.h b/lib/intprops.h new file mode 100644 index 0000000..d4a917f --- /dev/null +++ b/lib/intprops.h @@ -0,0 +1,642 @@ +/* intprops.h -- properties of integer types + + 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_H +#define _GL_INTPROPS_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 arithmetic type T is an integer type. bool counts as + an integer. */ +#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) + +/* True if the real type T is signed. */ +#define 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 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 TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) + +/* The maximum and minimum values for the integer type T. */ +#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) + +/* The maximum and minimum values for the type of the expression E, + after integer promotion. E is not evaluated. */ +#define _GL_INT_MINIMUM(e) \ + (EXPR_SIGNED (e) \ + ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_CONVERT (e, 0)) +#define _GL_INT_MAXIMUM(e) \ + (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) << (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) TYPE_SIGNED (__typeof__ (t)) +#else +# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 +#endif + +/* Bound on length of the string representing an unsigned integer + value representable in B bits. log10 (2.0) < 146/485. The + smallest value of B where this bound is not tight is 2621. */ +#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 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 (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. 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 harder to use and may be less + efficient than the INT__WRAPV, INT__OK, and + INT__OVERFLOW macros described below. + + Example usage: + + long int i = ...; + long int j = ...; + if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) + printf ("multiply would overflow"); + else + printf ("product is %ld", i * j); + + Restrictions on *_RANGE_OVERFLOW macros: + + These macros do not check for all possible numerical problems or + undefined or unspecified behavior: they do not check for division + by zero, for bad shift counts, or for shifting negative numbers. + + These macros may evaluate their arguments zero or multiple times, + so the arguments should not have side effects. The arithmetic + arguments (including the MIN and MAX arguments) must be of the same + integer type after the usual arithmetic conversions, and the type + 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. */ + +/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? (a) < (min) - (b) \ + : (max) - (b) < (a)) + +/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? (max) + (b) < (a) \ + : (a) < (min) + (b)) + +/* 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)) + +/* 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 \ + ? (a) < (max) / (b) \ + : (b) == -1 \ + ? 0 \ + : (min) / (b) < (a)) \ + : (b) == 0 \ + ? 0 \ + : ((a) < 0 \ + ? (a) < (min) / (b) \ + : (max) / (b) < (a))) + +/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Do not check for division by zero. */ +#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ + ((min) < 0 && (b) == -1 && (a) < - (max)) + +/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Do not check for division by zero. + Mathematically, % should never overflow, but on x86-like hosts + INT_MIN % -1 traps, and the C standard permits this, so treat this + as an overflow too. */ +#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ + INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) + +/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Here, MIN and MAX are for A only, and B need + not be of the same type as the other arguments. The C standard says that + behavior is undefined for shifts unless 0 <= B < wordwidth, and that when + A is negative then A << B has undefined behavior and A >> B has + implementation-defined behavior, but do not check these other + restrictions. */ +#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ + ((a) < 0 \ + ? (a) < (min) >> (b) \ + : (max) >> (b) < (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 + +/* 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. */ +#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 \ + : (b) < 0 && (a) + (b) <= (a)) +#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ + : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) + +/* Return a nonzero value if A is a mathematical multiple of B, where + A is unsigned, B is negative, and MAX is the maximum value of A's + type. A's type must be the same as (A % B)'s type. Normally (A % + -B == 0) suffices, but things get tricky if -B would overflow. */ +#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ + (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ + ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ + ? (a) \ + : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ + : (a) % - (b)) \ + == 0) + +/* 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. + 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, assuming A and B are long int: + + if (INT_MULTIPLY_OVERFLOW (a, b)) + printf ("result would overflow\n"); + else + 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 + by zero, for bad shift counts, or for shifting negative numbers. + + These macros may evaluate their arguments zero or multiple times, so the + arguments should not have side effects. + + 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. + + Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, + A % B, and A << B would overflow, respectively. */ + +#define INT_ADD_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) +#define INT_SUBTRACT_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a) +#else +# define INT_NEGATE_OVERFLOW(a) \ + INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +#endif +#define INT_MULTIPLY_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) +#define INT_DIVIDE_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) +#define INT_REMAINDER_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) +#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ + INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ + _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) + +/* Return 1 if the expression A B would overflow, + where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, + assuming MIN and MAX are the minimum and maximum for the result type. + 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 (_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. */ +#if _GL_HAS_BUILTIN_ADD_OVERFLOW +# define INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r) +# define INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r) +#else +# define INT_ADD_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW) +# define 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 INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r) +# else + /* Work around GCC bug 91450. */ +# define INT_MULTIPLY_WRAPV(a, b, r) \ + ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && 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 +#else +# define 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. See above for restrictions. */ +#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. See above for restrictions. */ +# if _GL_HAVE___TYPEOF__ +# define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \ + (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) \ + ? (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) \ + ? (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)) \ + : (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) \ + (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 must be a signed integer 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 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 be integer expressions + without side effects. 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) \ + ? ((EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \ + && (a) < (tmin) - (b)) \ + : (a) <= -1 - (b)) \ + || ((EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \ + : (a) < 0 \ + ? (((tmin) \ + ? ((EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \ + && (b) < (tmin) - (a)) \ + : (b) <= -1 - (a)) \ + || ((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 \ + ? ((!EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \ + || (a) - (tmin) < (b)) \ + : ((! (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \ + && 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 \ + ? (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \ + ? (a) < (tmax) / (b) \ + : ((INT_NEGATE_OVERFLOW (b) \ + ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (+ (b)) - 1) \ + : (tmax) / -(b)) \ + <= -1 - (a))) \ + : INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \ + ? (EXPR_SIGNED (a) \ + ? 0 < (a) + (tmin) \ + : 0 < (a) && -1 - (tmin) < (a) - 1) \ + : (tmin) / (b) < (a)) \ + : (b) == 0 \ + ? 0 \ + : ((a) < 0 \ + ? (INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \ + ? (EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \ + : (tmin) / (a) < (b)) \ + : (tmax) / (b) < (a))) + +/* 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. + + 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/lib/inttypes.in.h b/lib/inttypes.in.h new file mode 100644 index 0000000..853eca0 --- /dev/null +++ b/lib/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/lib/ioctl.c b/lib/ioctl.c new file mode 100644 index 0000000..b1c7b2e --- /dev/null +++ b/lib/ioctl.c @@ -0,0 +1,92 @@ +/* ioctl.c --- wrappers for Windows ioctl function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#include + +#include + +#if HAVE_IOCTL + +/* Provide a wrapper with the POSIX prototype. */ +# undef ioctl +int +rpl_ioctl (int fd, int request, ... /* {void *,char *} arg */) +{ + void *buf; + va_list args; + + va_start (args, request); + buf = va_arg (args, void *); + va_end (args); + + /* Cast 'request' so that when the system's ioctl function takes a 64-bit + request argument, the value gets zero-extended, not sign-extended. */ + return ioctl (fd, (unsigned int) request, buf); +} + +#else /* mingw */ + +# include + +/* Get HANDLE. */ +# define WIN32_LEAN_AND_MEAN +# include + +# include "fd-hook.h" +/* Get _get_osfhandle. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +static int +primary_ioctl (int fd, int request, void *arg) +{ + /* We don't support FIONBIO on pipes here. If you want to make pipe + fds non-blocking, use the gnulib 'nonblocking' module, until + gnulib implements fcntl F_GETFL / F_SETFL with O_NONBLOCK. */ + + if ((HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE) + errno = ENOSYS; + else + errno = EBADF; + return -1; +} + +int +ioctl (int fd, int request, ... /* {void *,char *} arg */) +{ + void *arg; + va_list args; + + va_start (args, request); + arg = va_arg (args, void *); + va_end (args); + +# if WINDOWS_SOCKETS + return execute_all_ioctl_hooks (primary_ioctl, fd, request, arg); +# else + return primary_ioctl (fd, request, arg); +# endif +} + +#endif diff --git a/lib/isblank.c b/lib/isblank.c new file mode 100644 index 0000000..e354559 --- /dev/null +++ b/lib/isblank.c @@ -0,0 +1,33 @@ +/* Test whether a character is a blank. + + 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 . */ + +#include + +/* Specification. */ +#include + +int +isblank (int c) +{ + /* On all known platforms, in all predefined locales, isblank(c) is likely + equivalent with (c == ' ' || c == '\t'). Look at the glibc definition + (in glibc/localedata/locales/i18n): The "blank" characters are '\t', ' ', + U+1680, U+180E, U+2000..U+2006, U+2008..U+200A, U+205F, U+3000, and none + except the first two is present in a common 8-bit encoding. Therefore + the substitute for other platforms is not more complicated than this. */ + return (c == ' ' || c == '\t'); +} diff --git a/lib/iswblank.c b/lib/iswblank.c new file mode 100644 index 0000000..2e601f8 --- /dev/null +++ b/lib/iswblank.c @@ -0,0 +1,26 @@ +/* Test wide character for being blank. + 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 + +int +iswblank (wint_t wc) +{ + return wc == ' ' || wc == '\t'; +} diff --git a/lib/iswdigit.c b/lib/iswdigit.c new file mode 100644 index 0000000..780263f --- /dev/null +++ b/lib/iswdigit.c @@ -0,0 +1,26 @@ +/* Test wide character for being a digit. + Copyright (C) 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 . */ + +#include + +/* Specification. */ +#include + +int +iswdigit (wint_t wc) +{ + return wc >= '0' && wc <= '9'; +} diff --git a/lib/iswxdigit.c b/lib/iswxdigit.c new file mode 100644 index 0000000..f20b9b3 --- /dev/null +++ b/lib/iswxdigit.c @@ -0,0 +1,33 @@ +/* Test wide character for being a hexadecimal digit. + Copyright (C) 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 . */ + +#include + +/* Specification. */ +#include + +int +iswxdigit (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') +#if 'A' == 0x41 && 'a' == 0x61 + /* Optimization, assuming ASCII */ + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F') +#else + || (wc >= 'A' && wc <= 'F') || (wc >= 'a' && wc <= 'f') +#endif + ); +} diff --git a/lib/itold.c b/lib/itold.c new file mode 100644 index 0000000..fe4a384 --- /dev/null +++ b/lib/itold.c @@ -0,0 +1,28 @@ +/* Replacement for 'int' to 'long double' conversion routine. + Copyright (C) 2011-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 + +void +_Qp_itoq (long double *result, int a) +{ + /* Convert from 'int' to 'double', then from 'double' to 'long double'. */ + *result = (double) a; +} diff --git a/lib/langinfo.in.h b/lib/langinfo.in.h new file mode 100644 index 0000000..98aea6a --- /dev/null +++ b/lib/langinfo.in.h @@ -0,0 +1,222 @@ +/* Substitute for and wrapper around . + 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 for platforms that lack it or have an incomplete one. + * + */ + +#ifndef _@GUARD_PREFIX@_LANGINFO_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_LANGINFO_H@ +# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@ +#endif + +#ifndef _@GUARD_PREFIX@_LANGINFO_H +#define _@GUARD_PREFIX@_LANGINFO_H + + +#if !@HAVE_LANGINFO_H@ + +/* A platform that lacks . */ + +/* Assume that it also lacks and the nl_item type. */ +# if !GNULIB_defined_nl_item +typedef int nl_item; +# define GNULIB_defined_nl_item 1 +# endif + +/* nl_langinfo items of the LC_CTYPE category */ +# 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 +# define T_FMT 10005 +# define T_FMT_AMPM 10006 +# define AM_STR 10007 +# define PM_STR 10008 +# define DAY_1 10009 +# define DAY_2 (DAY_1 + 1) +# define DAY_3 (DAY_1 + 2) +# define DAY_4 (DAY_1 + 3) +# define DAY_5 (DAY_1 + 4) +# define DAY_6 (DAY_1 + 5) +# define DAY_7 (DAY_1 + 6) +# define ABDAY_1 10016 +# define ABDAY_2 (ABDAY_1 + 1) +# define ABDAY_3 (ABDAY_1 + 2) +# define ABDAY_4 (ABDAY_1 + 3) +# define ABDAY_5 (ABDAY_1 + 4) +# define ABDAY_6 (ABDAY_1 + 5) +# define ABDAY_7 (ABDAY_1 + 6) +# define MON_1 10023 +# define MON_2 (MON_1 + 1) +# define MON_3 (MON_1 + 2) +# define MON_4 (MON_1 + 3) +# define MON_5 (MON_1 + 4) +# define MON_6 (MON_1 + 5) +# define MON_7 (MON_1 + 6) +# define MON_8 (MON_1 + 7) +# define MON_9 (MON_1 + 8) +# 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) +# define ABMON_4 (ABMON_1 + 3) +# define ABMON_5 (ABMON_1 + 4) +# define ABMON_6 (ABMON_1 + 5) +# define ABMON_7 (ABMON_1 + 6) +# define ABMON_8 (ABMON_1 + 7) +# define ABMON_9 (ABMON_1 + 8) +# define ABMON_10 (ABMON_1 + 9) +# define ABMON_11 (ABMON_1 + 10) +# define ABMON_12 (ABMON_1 + 11) +# define ERA 10047 +# define ERA_D_FMT 10048 +# define ERA_D_T_FMT 10049 +# define ERA_T_FMT 10050 +# 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 + +#else + +/* A platform that has . */ + +# if !@HAVE_LANGINFO_CODESET@ +# define CODESET 10000 +# define GNULIB_defined_CODESET 1 +# endif + +# if !@HAVE_LANGINFO_T_FMT_AMPM@ +# define T_FMT_AMPM 10006 +# 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 +# define ERA_D_T_FMT 10049 +# define ERA_T_FMT 10050 +# define ALT_DIGITS 10051 +# define GNULIB_defined_ERA 1 +# endif + +# if !@HAVE_LANGINFO_YESEXPR@ +# define YESEXPR 10053 +# define NOEXPR 10054 +# define GNULIB_defined_YESEXPR 1 +# endif + +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Declare overridden functions. */ + + +/* Return a piece of locale dependent information. + Note: The difference between nl_langinfo (CODESET) and locale_charset () + is that the latter normalizes the encoding names to GNU conventions. */ + +#if @GNULIB_NL_LANGINFO@ +# if @REPLACE_NL_LANGINFO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef nl_langinfo +# define nl_langinfo rpl_nl_langinfo +# endif +_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item)); +_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item)); +# else +# if !@HAVE_NL_LANGINFO@ +_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item)); +# endif +_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item)); +# endif +_GL_CXXALIASWARN (nl_langinfo); +#elif defined GNULIB_POSIXCHECK +# undef nl_langinfo +# if HAVE_RAW_DECL_NL_LANGINFO +_GL_WARN_ON_USE (nl_langinfo, "nl_langinfo is not portable - " + "use gnulib module nl_langinfo for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_LANGINFO_H */ +#endif /* _@GUARD_PREFIX@_LANGINFO_H */ diff --git a/lib/lc-charset-dispatch.c b/lib/lc-charset-dispatch.c new file mode 100644 index 0000000..66d78fd --- /dev/null +++ b/lib/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/lib/lc-charset-dispatch.h b/lib/lc-charset-dispatch.h new file mode 100644 index 0000000..3867c32 --- /dev/null +++ b/lib/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/lib/libc-config.h b/lib/libc-config.h new file mode 100644 index 0000000..8fec489 --- /dev/null +++ b/lib/libc-config.h @@ -0,0 +1,191 @@ +/* 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_size__ +# undef __attribute_artificial__ +# undef __attribute_const__ +# undef __attribute_deprecated__ +# undef __attribute_deprecated_msg__ +# undef __attribute_format_arg__ +# undef __attribute_format_strfmon__ +# undef __attribute_malloc__ +# undef __attribute_noinline__ +# undef __attribute_nonstring__ +# undef __attribute_pure__ +# undef __attribute_returns_twice__ +# undef __attribute_used__ +# undef __attribute_warn_unused_result__ +# undef __bos +# undef __bos0 +# undef __errordecl +# undef __extension__ +# undef __extern_always_inline +# undef __extern_inline +# undef __flexarr +# undef __fortify_function +# undef __glibc_c99_flexarr_available +# undef __glibc_has_attribute +# undef __glibc_has_builtin +# undef __glibc_has_extension +# undef __glibc_macro_warning +# undef __glibc_macro_warning1 +# undef __glibc_objsize +# undef __glibc_objsize0 +# undef __glibc_unlikely +# undef __inline +# undef __ptr_t +# undef __restrict +# undef __restrict_arr +# undef __va_arg_pack +# undef __va_arg_pack_len +# undef __warnattr + +/* Include our copy of glibc . */ +# 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/lib/libunistring.valgrind b/lib/libunistring.valgrind new file mode 100644 index 0000000..630ded0 --- /dev/null +++ b/lib/libunistring.valgrind @@ -0,0 +1,32 @@ +# Suppress valgrind messages in an installed libunistring. + +# Copyright (C) 2010-2022 Free Software Foundation, Inc. +# +# This file is free software. +# It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". +# You can redistribute it and/or modify it under either +# - the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3, or (at your +# option) any later version, or +# - the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) +# any later version, or +# - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". +# +# 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 and the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License and of the GNU General Public License along with this +# program. If not, see . + +# Suppress a valgrind message about use of uninitialized memory in freea(). +# This use is OK because it provides only a speedup. +{ + libunistring_freea + Memcheck:Cond + fun:libunistring_freea +} diff --git a/lib/limits.in.h b/lib/limits.in.h new file mode 100644 index 0000000..b77bf75 --- /dev/null +++ b/lib/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/lib/link.c b/lib/link.c new file mode 100644 index 0000000..2023d75 --- /dev/null +++ b/lib/link.c @@ -0,0 +1,237 @@ +/* Emulate link on platforms that lack it, namely native Windows platforms. + + 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 . */ + +#include + +#include + +#include +#include +#include +#include + +#if !HAVE_LINK +# if defined _WIN32 && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN +# include + +/* Don't assume that UNICODE is not defined. */ +# undef GetModuleHandle +# define GetModuleHandle GetModuleHandleA +# undef CreateHardLink +# define CreateHardLink CreateHardLinkA + +# if !(_WIN32_WINNT >= _WIN32_WINNT_WINXP) + +/* Avoid warnings from gcc -Wcast-function-type. */ +# define GetProcAddress \ + (void *) GetProcAddress + +/* CreateHardLink was introduced only in Windows 2000. */ +typedef BOOL (WINAPI * CreateHardLinkFuncType) (LPCSTR lpFileName, + LPCSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes); +static CreateHardLinkFuncType CreateHardLinkFunc = NULL; +static BOOL initialized = FALSE; + +static void +initialize (void) +{ + HMODULE kernel32 = GetModuleHandle ("kernel32.dll"); + if (kernel32 != NULL) + { + CreateHardLinkFunc = + (CreateHardLinkFuncType) GetProcAddress (kernel32, "CreateHardLinkA"); + } + initialized = TRUE; +} + +# else + +# define CreateHardLinkFunc CreateHardLink + +# endif + +int +link (const char *file1, const char *file2) +{ + char *dir; + size_t len1 = strlen (file1); + size_t len2 = strlen (file2); + +# if !(_WIN32_WINNT >= _WIN32_WINNT_WINXP) + if (!initialized) + initialize (); +# endif + + if (CreateHardLinkFunc == NULL) + { + /* System does not support hard links. */ + errno = EPERM; + return -1; + } + /* Reject trailing slashes on non-directories; native Windows does not + support hard-linking directories. */ + if ((len1 && (file1[len1 - 1] == '/' || file1[len1 - 1] == '\\')) + || (len2 && (file2[len2 - 1] == '/' || file2[len2 - 1] == '\\'))) + { + /* If stat() fails, then link() should fail for the same reason. */ + struct stat st; + if (stat (file1, &st)) + { + if (errno == EOVERFLOW) + /* It's surely a file, not a directory (see stat-w32.c). */ + errno = ENOTDIR; + return -1; + } + if (!S_ISDIR (st.st_mode)) + errno = ENOTDIR; + else + errno = EPERM; + return -1; + } + /* CreateHardLink("b/.","a",NULL) creates file "b", so we must check + that dirname(file2) exists. */ + dir = strdup (file2); + if (!dir) + return -1; + { + struct stat st; + char *p = strchr (dir, '\0'); + while (dir < p && (*--p != '/' && *p != '\\')); + *p = '\0'; + if (p != dir && stat (dir, &st) != 0 && errno != EOVERFLOW) + { + free (dir); + return -1; + } + free (dir); + } + /* Now create the link. */ + if (CreateHardLinkFunc (file2, file1, NULL) == 0) + { + /* It is not documented which errors CreateHardLink() can produce. + * The following conversions are based on tests on a Windows XP SP2 + * system. */ + DWORD err = GetLastError (); + switch (err) + { + case ERROR_ACCESS_DENIED: + errno = EACCES; + break; + + case ERROR_INVALID_FUNCTION: /* fs does not support hard links */ + errno = EPERM; + break; + + case ERROR_NOT_SAME_DEVICE: + errno = EXDEV; + break; + + case ERROR_PATH_NOT_FOUND: + case ERROR_FILE_NOT_FOUND: + errno = ENOENT; + break; + + case ERROR_INVALID_PARAMETER: + errno = ENAMETOOLONG; + break; + + case ERROR_TOO_MANY_LINKS: + errno = EMLINK; + break; + + case ERROR_ALREADY_EXISTS: + errno = EEXIST; + break; + + default: + errno = EIO; + } + return -1; + } + + return 0; +} + +# else /* !Windows */ + +# error "This platform lacks a link function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib." + +# endif /* !Windows */ +#else /* HAVE_LINK */ + +# undef link + +/* Create a hard link from FILE1 to FILE2, working around platform bugs. */ +int +rpl_link (char const *file1, char const *file2) +{ + size_t len1; + size_t len2; + struct stat st; + + /* Don't allow IRIX to dereference dangling file2 symlink. */ + if (lstat (file2, &st) == 0 || errno == EOVERFLOW) + { + errno = EEXIST; + return -1; + } + + /* Reject trailing slashes on non-directories. */ + len1 = strlen (file1); + len2 = strlen (file2); + if ((len1 && file1[len1 - 1] == '/') + || (len2 && file2[len2 - 1] == '/')) + { + /* Let link() decide whether hard-linking directories is legal. + If stat() fails, then link() should fail for the same reason + (although on Solaris 9, link("file/","oops") mistakenly + succeeds); if stat() succeeds, require a directory. */ + if (stat (file1, &st)) + return -1; + if (!S_ISDIR (st.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } + else + { + /* Fix Cygwin 1.5.x bug where link("a","b/.") creates file "b". */ + char *dir = strdup (file2); + char *p; + if (!dir) + return -1; + /* We already know file2 does not end in slash. Strip off the + basename, then check that the dirname exists. */ + p = strrchr (dir, '/'); + if (p) + { + *p = '\0'; + if (stat (dir, &st) != 0 && errno != EOVERFLOW) + { + free (dir); + return -1; + } + } + free (dir); + } + return link (file1, file2); +} +#endif /* HAVE_LINK */ diff --git a/lib/listen.c b/lib/listen.c new file mode 100644 index 0000000..e67bdc9 --- /dev/null +++ b/lib/listen.c @@ -0,0 +1,49 @@ +/* listen.c --- wrappers for Windows listen function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef listen + +int +rpl_listen (int fd, int backlog) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = listen (sock, backlog); + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/localcharset.c b/lib/localcharset.c new file mode 100644 index 0000000..17a4a1e --- /dev/null +++ b/lib/localcharset.c @@ -0,0 +1,1159 @@ +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000-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 Bruno Haible . */ + +#include + +/* Specification. */ +#include "localcharset.h" + +#include +#include +#include +#include + +#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */ +#endif + +#if defined _WIN32 && !defined __CYGWIN__ +# define WINDOWS_NATIVE +# include +#endif + +#if defined __EMX__ +/* Assume EMX program runs on OS/2, even if compiled under DOS. */ +# ifndef OS2 +# define OS2 +# endif +#endif + +#if !defined WINDOWS_NATIVE +# if HAVE_LANGINFO_CODESET +# include +# else +# if 0 /* see comment regarding use of setlocale(), below */ +# include +# endif +# endif +# ifdef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# endif +#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 +# include +#endif + +/* For MB_CUR_MAX_L */ +#if defined DARWIN7 +# include +#endif + + +#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2 + +/* On these platforms, we use a mapping from non-canonical encoding name + to GNU canonical encoding name. */ + +/* 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__) + +struct table_entry +{ + 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 + }; + +# endif + +#else + +/* On these platforms, we use a mapping from locale name to GNU canonical + encoding name. */ + +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 __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 +# ifndef locale_table_defined + /* Just a dummy entry, to avoid a C syntax error. */ + { "", "" } +# endif + }; + +#endif + + +/* Determine the current locale's character encoding, and canonicalize it + 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. */ + +#ifdef STATIC +STATIC +#endif +const char * +locale_charset (void) +{ + const char *codeset; + + /* 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 + + /* Most systems support nl_langinfo (CODESET) nowadays. */ + codeset = nl_langinfo (CODESET); + +# ifdef __CYGWIN__ + /* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always + returns "US-ASCII". Return the suffix of the locale name from the + environment variables (if present) or the codepage as a number. */ + if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) + { + const char *locale; + static char resultbuf[2 + 10 + 1]; + + 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[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 (resultbuf)) + { + /* This way of filling resultbuf is multithread-safe. */ + memcpy (resultbuf, dot, modifier - dot); + resultbuf [modifier - dot] = '\0'; + return resultbuf; + } + } + } + + /* The Windows API has a function returning the locale's codepage as a + number: GetACP(). This encoding is used by Cygwin, unless the user + has set the environment variable CYGWIN=codepage:oem (which very few + people do). + Output directed to console windows needs to be converted (to + GetOEMCP() if the console is using a raster font, or to + GetConsoleOutputCP() if it is using a TrueType font). Cygwin does + this conversion transparently (see winsup/cygwin/fhandler_console.cc), + converting to GetConsoleOutputCP(). This leads to correct results, + except when SetConsoleOutputCP has been called and a raster font is + in use. */ + { + char buf[2 + 10 + 1]; + + sprintf (buf, "CP%u", GetACP ()); + strcpy (resultbuf, buf); + codeset = resultbuf; + } + } +# endif + + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + +# elif defined WINDOWS_NATIVE + + char buf[2 + 10 + 1]; + static char resultbuf[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, '.'); + + 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 + + const char *locale; + 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"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + 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 (resultbuf)) + { + /* This way of filling resultbuf is multithread-safe. */ + memcpy (resultbuf, dot, modifier - dot); + resultbuf [modifier - dot] = '\0'; + return resultbuf; + } + } + + /* For the POSIX locale, don't use the system's codepage. */ + if (strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0) + codeset = ""; + } + + 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]); + strcpy (resultbuf, buf); + codeset = resultbuf; + } + } + +# else + +# 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 + + /* 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) + { + /* 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 + } + } + +#endif + +#ifdef DARWIN7 + /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8" + (the default codeset) does not work when MB_CUR_MAX is 1. */ + if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1) + codeset = "ASCII"; +#endif + + return codeset; +} diff --git a/lib/localcharset.h b/lib/localcharset.h new file mode 100644 index 0000000..62efbf3 --- /dev/null +++ b/lib/localcharset.h @@ -0,0 +1,137 @@ +/* Determine a canonical name for the current locale's character encoding. + Copyright (C) 2000-2003, 2009-2022 Free Software Foundation, Inc. + This file is part of the GNU CHARSET 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 _LOCALCHARSET_H +#define _LOCALCHARSET_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Determine the current locale's character encoding, and canonicalize it + 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 +} +#endif + + +#endif /* _LOCALCHARSET_H */ diff --git a/lib/locale.in.h b/lib/locale.in.h new file mode 100644 index 0000000..4aef74d --- /dev/null +++ b/lib/locale.in.h @@ -0,0 +1,305 @@ +/* A POSIX . + 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if (defined _WIN32 && !defined __CYGWIN__ && defined __need_locale_t) \ + || defined _GL_ALREADY_INCLUDING_LOCALE_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@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_LOCALE_H + +#define _GL_ALREADY_INCLUDING_LOCALE_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_LOCALE_H@ + +#undef _GL_ALREADY_INCLUDING_LOCALE_H + +#ifndef _@GUARD_PREFIX@_LOCALE_H +#define _@GUARD_PREFIX@_LOCALE_H + +/* NetBSD 5.0 mis-defines NULL. */ +#include + +/* Mac OS X 10.5 defines the locale_t type in . */ +#if @HAVE_XLOCALE_H@ +# 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. */ + +/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C. + On systems that don't define it, use the same value as GNU libintl. */ +#if !defined LC_MESSAGES +# 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 +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; + /* Symbol used to separate groups of digits to the left of the decimal + point. */ + char *thousands_sep; + /* Definition of the size of groups of digits to the left of the decimal + point. */ + char *grouping; + + /* Members that depend on the LC_MONETARY category of the locale. See + */ + + /* Symbol used as decimal point. */ + char *mon_decimal_point; + /* Symbol used to separate groups of digits to the left of the decimal + point. */ + char *mon_thousands_sep; + /* Definition of the size of groups of digits to the left of the decimal + point. */ + char *mon_grouping; + /* Sign used to indicate a value >= 0. */ + char *positive_sign; + /* Sign used to indicate a value < 0. */ + char *negative_sign; + + /* For formatting local currency. */ + /* Currency symbol (3 characters) followed by separator (1 character). */ + char *currency_symbol; + /* Number of digits after the decimal point. */ + char frac_digits; + /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it + comes after the number. */ + char p_cs_precedes; + /* For values >= 0: Position of the sign. */ + char p_sign_posn; + /* For values >= 0: Placement of spaces between currency symbol, sign, and + number. */ + char p_sep_by_space; + /* For values < 0: 1 if the currency symbol precedes the number, 0 if it + comes after the number. */ + char n_cs_precedes; + /* For values < 0: Position of the sign. */ + char n_sign_posn; + /* For values < 0: Placement of spaces between currency symbol, sign, and + number. */ + char n_sep_by_space; + + /* For formatting international currency. */ + /* Currency symbol (3 characters) followed by separator (1 character). */ + char *int_curr_symbol; + /* Number of digits after the decimal point. */ + char int_frac_digits; + /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it + comes after the number. */ + char int_p_cs_precedes; + /* For values >= 0: Position of the sign. */ + char int_p_sign_posn; + /* For values >= 0: Placement of spaces between currency symbol, sign, and + number. */ + char int_p_sep_by_space; + /* For values < 0: 1 if the currency symbol precedes the number, 0 if it + comes after the number. */ + char int_n_cs_precedes; + /* For values < 0: Position of the sign. */ + char int_n_sign_posn; + /* For values < 0: Placement of spaces between currency symbol, sign, and + number. */ + char int_n_sep_by_space; +}; +#endif + +#if @GNULIB_LOCALECONV@ +# if @REPLACE_LOCALECONV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef localeconv +# define localeconv rpl_localeconv +# endif +_GL_FUNCDECL_RPL (localeconv, struct lconv *, (void)); +_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 +#elif defined GNULIB_POSIXCHECK +# undef localeconv +# if HAVE_RAW_DECL_LOCALECONV +_GL_WARN_ON_USE (localeconv, + "localeconv returns too few information on some platforms - " + "use gnulib module localeconv for portability"); +# endif +#endif + +#if @GNULIB_SETLOCALE@ +# if @REPLACE_SETLOCALE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setlocale +# define setlocale rpl_setlocale +# define GNULIB_defined_setlocale 1 +# endif +_GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale)); +_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 +_GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " + "use gnulib module setlocale for portability"); +# endif +#endif + +#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)); +# else +# if @HAVE_DUPLOCALE@ +_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale)); +# endif +# endif +# 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 +_GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - " + "use gnulib module duplocale for portability"); +# 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 /* _@GUARD_PREFIX@_LOCALE_H */ +#endif /* !(__need_locale_t || _GL_ALREADY_INCLUDING_LOCALE_H) */ diff --git a/lib/localeconv.c b/lib/localeconv.c new file mode 100644 index 0000000..ef26120 --- /dev/null +++ b/lib/localeconv.c @@ -0,0 +1,103 @@ +/* Query locale dependent information for formatting numbers. + 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 + +/* Specification. */ +#include + +#if HAVE_STRUCT_LCONV_DECIMAL_POINT + +/* Override for platforms where 'struct lconv' lacks the int_p_*, int_n_* + members. */ + +struct lconv * +localeconv (void) +{ + static struct lconv result; +# undef lconv +# undef localeconv + struct lconv *sys_result = localeconv (); + + result.decimal_point = sys_result->decimal_point; + result.thousands_sep = sys_result->thousands_sep; + result.grouping = sys_result->grouping; + result.mon_decimal_point = sys_result->mon_decimal_point; + result.mon_thousands_sep = sys_result->mon_thousands_sep; + result.mon_grouping = sys_result->mon_grouping; + result.positive_sign = sys_result->positive_sign; + result.negative_sign = sys_result->negative_sign; + result.currency_symbol = sys_result->currency_symbol; + result.frac_digits = sys_result->frac_digits; + result.p_cs_precedes = sys_result->p_cs_precedes; + result.p_sign_posn = sys_result->p_sign_posn; + result.p_sep_by_space = sys_result->p_sep_by_space; + result.n_cs_precedes = sys_result->n_cs_precedes; + result.n_sign_posn = sys_result->n_sign_posn; + result.n_sep_by_space = sys_result->n_sep_by_space; + result.int_curr_symbol = sys_result->int_curr_symbol; + result.int_frac_digits = sys_result->int_frac_digits; + result.int_p_cs_precedes = sys_result->p_cs_precedes; + result.int_p_sign_posn = sys_result->p_sign_posn; + result.int_p_sep_by_space = sys_result->p_sep_by_space; + result.int_n_cs_precedes = sys_result->n_cs_precedes; + result.int_n_sign_posn = sys_result->n_sign_posn; + result.int_n_sep_by_space = sys_result->n_sep_by_space; + + return &result; +} + +#else + +/* Override for platforms where 'struct lconv' is a dummy. */ + +# include + +struct lconv * +localeconv (void) +{ + static /*const*/ struct lconv result = + { + /* decimal_point */ ".", + /* thousands_sep */ "", + /* grouping */ "", + /* mon_decimal_point */ "", + /* mon_thousands_sep */ "", + /* mon_grouping */ "", + /* positive_sign */ "", + /* negative_sign */ "", + /* currency_symbol */ "", + /* frac_digits */ CHAR_MAX, + /* p_cs_precedes */ CHAR_MAX, + /* p_sign_posn */ CHAR_MAX, + /* p_sep_by_space */ CHAR_MAX, + /* n_cs_precedes */ CHAR_MAX, + /* n_sign_posn */ CHAR_MAX, + /* n_sep_by_space */ CHAR_MAX, + /* int_curr_symbol */ "", + /* int_frac_digits */ CHAR_MAX, + /* int_p_cs_precedes */ CHAR_MAX, + /* int_p_sign_posn */ CHAR_MAX, + /* int_p_sep_by_space */ CHAR_MAX, + /* int_n_cs_precedes */ CHAR_MAX, + /* int_n_sign_posn */ CHAR_MAX, + /* int_n_sep_by_space */ CHAR_MAX + }; + + return &result; +} + +#endif diff --git a/lib/lseek.c b/lib/lseek.c new file mode 100644 index 0000000..1a9c49b --- /dev/null +++ b/lib/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/lib/lstat.c b/lib/lstat.c new file mode 100644 index 0000000..472bfbc --- /dev/null +++ b/lib/lstat.c @@ -0,0 +1,104 @@ +/* Work around a bug of lstat on some systems + + Copyright (C) 1997-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 Jim Meyering */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_lstat doesn't recurse to + rpl_lstat. */ +#define __need_system_sys_stat_h +#include + +#if !HAVE_LSTAT +/* On systems that lack symlinks, our replacement already + defined lstat as stat, so there is nothing further to do other than + avoid an empty file. */ +typedef int dummy; +#else /* HAVE_LSTAT */ + +/* Get the original definition of lstat. It might be defined as a macro. */ +# include +# include +# undef __need_system_sys_stat_h + +static int +orig_lstat (const char *filename, struct stat *buf) +{ + return lstat (filename, buf); +} + +/* 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 + +/* lstat works differently on Linux and Solaris systems. POSIX (see + "pathname resolution" in the glossary) requires that programs like + 'ls' take into consideration the fact that FILE has a trailing slash + when FILE is a symbolic link. On Linux and Solaris 10 systems, the + lstat function already has the desired semantics (in treating + 'lstat ("symlink/", sbuf)' just like 'lstat ("symlink/.", sbuf)', + but on Solaris 9 and earlier it does not. + + If FILE has a trailing slash and specifies a symbolic link, + then use stat() to get more info on the referent of FILE. + If the referent is a non-directory, then set errno to ENOTDIR + and return -1. Otherwise, return stat's result. */ + +int +rpl_lstat (const char *file, struct stat *sbuf) +{ + int result = orig_lstat (file, sbuf); + + /* This replacement file can blindly check against '/' rather than + using the ISSLASH macro, because all platforms with '\\' either + lack symlinks (mingw) or have working lstat (cygwin) and thus do + not compile this file. 0 len should have already been filtered + out above, with a failure return of ENOENT. */ + if (result == 0) + { + if (S_ISDIR (sbuf->st_mode) || file[strlen (file) - 1] != '/') + result = stat_time_normalize (result, sbuf); + else + { + /* At this point, a trailing slash is permitted only on + symlink-to-dir; but it should have found information on the + directory, not the symlink. Call 'stat' to get info about the + link's referent. Our replacement stat guarantees valid results, + even if the symlink is not pointing to a directory. */ + if (!S_ISLNK (sbuf->st_mode)) + { + errno = ENOTDIR; + return -1; + } + result = stat (file, sbuf); + } + } + return result; +} + +#endif /* HAVE_LSTAT */ diff --git a/lib/malloc.c b/lib/malloc.c new file mode 100644 index 0000000..f334dd6 --- /dev/null +++ b/lib/malloc.c @@ -0,0 +1,51 @@ +/* malloc() function that is glibc compatible. + + Copyright (C) 1997-1998, 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 */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include + +#include + +#include + +#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) +{ + if (n == 0) + n = 1; + + if (xalloc_oversized (n, 1)) + { + errno = ENOMEM; + return NULL; + } + + void *result = malloc (n); + +#if !HAVE_MALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/lib/malloc/dynarray-skeleton.c b/lib/malloc/dynarray-skeleton.c new file mode 100644 index 0000000..bad548a --- /dev/null +++ b/lib/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/lib/malloc/dynarray.h b/lib/malloc/dynarray.h new file mode 100644 index 0000000..f16fd95 --- /dev/null +++ b/lib/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/lib/malloc/dynarray_at_failure.c b/lib/malloc/dynarray_at_failure.c new file mode 100644 index 0000000..062ab70 --- /dev/null +++ b/lib/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/lib/malloc/dynarray_emplace_enlarge.c b/lib/malloc/dynarray_emplace_enlarge.c new file mode 100644 index 0000000..0cff2e7 --- /dev/null +++ b/lib/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/lib/malloc/dynarray_finalize.c b/lib/malloc/dynarray_finalize.c new file mode 100644 index 0000000..3f360c3 --- /dev/null +++ b/lib/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/lib/malloc/dynarray_resize.c b/lib/malloc/dynarray_resize.c new file mode 100644 index 0000000..8d1922e --- /dev/null +++ b/lib/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/lib/malloc/dynarray_resize_clear.c b/lib/malloc/dynarray_resize_clear.c new file mode 100644 index 0000000..8cf1b0d --- /dev/null +++ b/lib/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/lib/malloc/scratch_buffer.h b/lib/malloc/scratch_buffer.h new file mode 100644 index 0000000..e4c5c8a --- /dev/null +++ b/lib/malloc/scratch_buffer.h @@ -0,0 +1,151 @@ +/* Variable-sized buffer with on-stack default allocation. + Copyright (C) 2015-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 _SCRATCH_BUFFER_H +#define _SCRATCH_BUFFER_H + +/* Scratch buffers with a default stack allocation and fallback to + heap allocation. It is expected that this function is used in this + way: + + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); + + while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) + if (!scratch_buffer_grow (&tmpbuf)) + return -1; + + scratch_buffer_free (&tmpbuf); + return 0; + + The allocation functions (scratch_buffer_grow, + scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make + sure that the heap allocation, if any, is freed, so that the code + above does not have a memory leak. The buffer still remains in a + state that can be deallocated using scratch_buffer_free, so a loop + like this is valid as well: + + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); + + while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) + if (!scratch_buffer_grow (&tmpbuf)) + break; + + scratch_buffer_free (&tmpbuf); + + scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed + to grow the buffer by at least 512 bytes. This means that when + using the scratch buffer as a backing store for a non-character + array whose element size, in bytes, is 512 or smaller, the scratch + buffer only has to grow once to make room for at least one more + element. +*/ + +#include +#include +#include + +/* Scratch buffer. Must be initialized with scratch_buffer_init + before its use. */ +struct scratch_buffer { + void *data; /* Pointer to the beginning of the scratch area. */ + size_t length; /* Allocated space at the data pointer, in bytes. */ + union { max_align_t __align; char __c[1024]; } __space; +}; + +/* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space + and BUFFER->length reflects the available space. */ +static inline void +scratch_buffer_init (struct scratch_buffer *buffer) +{ + buffer->data = buffer->__space.__c; + buffer->length = sizeof (buffer->__space); +} + +/* Deallocates *BUFFER (if it was heap-allocated). */ +static inline void +scratch_buffer_free (struct scratch_buffer *buffer) +{ + if (buffer->data != buffer->__space.__c) + free (buffer->data); +} + +/* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT + preserved. Return true on success, false on allocation failure (in + which case the old buffer is freed). On success, the new buffer is + larger than the previous size. On failure, *BUFFER is deallocated, + but remains in a free-able state, and errno is set. */ +bool __libc_scratch_buffer_grow (struct scratch_buffer *buffer); +libc_hidden_proto (__libc_scratch_buffer_grow) + +/* Alias for __libc_scratch_buffer_grow. */ +static __always_inline bool +scratch_buffer_grow (struct scratch_buffer *buffer) +{ + return __glibc_likely (__libc_scratch_buffer_grow (buffer)); +} + +/* Like __libc_scratch_buffer_grow, but preserve the old buffer + contents on success, as a prefix of the new buffer. */ +bool __libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer); +libc_hidden_proto (__libc_scratch_buffer_grow_preserve) + +/* Alias for __libc_scratch_buffer_grow_preserve. */ +static __always_inline bool +scratch_buffer_grow_preserve (struct scratch_buffer *buffer) +{ + return __glibc_likely (__libc_scratch_buffer_grow_preserve (buffer)); +} + +/* Grow *BUFFER so that it can store at least NELEM elements of SIZE + bytes. The buffer contents are NOT preserved. Both NELEM and SIZE + can be zero. Return true on success, false on allocation failure + (in which case the old buffer is freed, but *BUFFER remains in a + free-able state, and errno is set). It is unspecified whether this + function can reduce the array size. */ +bool __libc_scratch_buffer_set_array_size (struct scratch_buffer *buffer, + size_t nelem, size_t size); +libc_hidden_proto (__libc_scratch_buffer_set_array_size) + +/* Alias for __libc_scratch_set_array_size. */ +static __always_inline bool +scratch_buffer_set_array_size (struct scratch_buffer *buffer, + size_t nelem, size_t size) +{ + return __glibc_likely (__libc_scratch_buffer_set_array_size + (buffer, nelem, size)); +} + +/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block, + deallocating *BUFFER if it was heap-allocated. SIZE must be at + most *BUFFER's size. Return NULL (setting errno) on memory + exhaustion. */ +void *__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, + size_t size); +libc_hidden_proto (__libc_scratch_buffer_dupfree) + +/* Alias for __libc_scratch_dupfree. */ +static __always_inline void * +scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) +{ + void *r = __libc_scratch_buffer_dupfree (buffer, size); + return __glibc_likely (r != NULL) ? r : NULL; +} + +#endif /* _SCRATCH_BUFFER_H */ diff --git a/lib/malloc/scratch_buffer_dupfree.c b/lib/malloc/scratch_buffer_dupfree.c new file mode 100644 index 0000000..eb3b95c --- /dev/null +++ b/lib/malloc/scratch_buffer_dupfree.c @@ -0,0 +1,41 @@ +/* Variable-sized buffer with on-stack default allocation. + 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 _LIBC +# include +#endif + +#include +#include + +void * +__libc_scratch_buffer_dupfree (struct scratch_buffer *buffer, size_t size) +{ + void *data = buffer->data; + if (data == buffer->__space.__c) + { + void *copy = malloc (size); + return copy != NULL ? memcpy (copy, data, size) : NULL; + } + else + { + void *copy = realloc (data, size); + return copy != NULL ? copy : data; + } +} +libc_hidden_def (__libc_scratch_buffer_dupfree) diff --git a/lib/malloc/scratch_buffer_grow.c b/lib/malloc/scratch_buffer_grow.c new file mode 100644 index 0000000..9a5e4db --- /dev/null +++ b/lib/malloc/scratch_buffer_grow.c @@ -0,0 +1,56 @@ +/* Variable-sized buffer with on-stack default allocation. + Copyright (C) 2015-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_scratch_buffer_grow (struct scratch_buffer *buffer) +{ + void *new_ptr; + size_t new_length = buffer->length * 2; + + /* Discard old buffer. */ + scratch_buffer_free (buffer); + + /* Check for overflow. */ + if (__glibc_likely (new_length >= buffer->length)) + new_ptr = malloc (new_length); + else + { + __set_errno (ENOMEM); + new_ptr = NULL; + } + + if (__glibc_unlikely (new_ptr == NULL)) + { + /* Buffer must remain valid to free. */ + scratch_buffer_init (buffer); + return false; + } + + /* Install new heap-based buffer. */ + buffer->data = new_ptr; + buffer->length = new_length; + return true; +} +libc_hidden_def (__libc_scratch_buffer_grow) diff --git a/lib/malloc/scratch_buffer_grow_preserve.c b/lib/malloc/scratch_buffer_grow_preserve.c new file mode 100644 index 0000000..3fe5a07 --- /dev/null +++ b/lib/malloc/scratch_buffer_grow_preserve.c @@ -0,0 +1,67 @@ +/* Variable-sized buffer with on-stack default allocation. + Copyright (C) 2015-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_scratch_buffer_grow_preserve (struct scratch_buffer *buffer) +{ + size_t new_length = 2 * buffer->length; + void *new_ptr; + + if (buffer->data == buffer->__space.__c) + { + /* Move buffer to the heap. No overflow is possible because + buffer->length describes a small buffer on the stack. */ + new_ptr = malloc (new_length); + if (new_ptr == NULL) + return false; + memcpy (new_ptr, buffer->__space.__c, buffer->length); + } + else + { + /* Buffer was already on the heap. Check for overflow. */ + if (__glibc_likely (new_length >= buffer->length)) + new_ptr = realloc (buffer->data, new_length); + else + { + __set_errno (ENOMEM); + new_ptr = NULL; + } + + if (__glibc_unlikely (new_ptr == NULL)) + { + /* Deallocate, but buffer must remain valid to free. */ + free (buffer->data); + scratch_buffer_init (buffer); + return false; + } + } + + /* Install new heap-based buffer. */ + buffer->data = new_ptr; + buffer->length = new_length; + return true; +} +libc_hidden_def (__libc_scratch_buffer_grow_preserve) diff --git a/lib/malloc/scratch_buffer_set_array_size.c b/lib/malloc/scratch_buffer_set_array_size.c new file mode 100644 index 0000000..89c37a9 --- /dev/null +++ b/lib/malloc/scratch_buffer_set_array_size.c @@ -0,0 +1,64 @@ +/* Variable-sized buffer with on-stack default allocation. + Copyright (C) 2015-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_scratch_buffer_set_array_size (struct scratch_buffer *buffer, + size_t nelem, size_t size) +{ + size_t new_length = nelem * size; + + /* Avoid overflow check if both values are small. */ + if ((nelem | size) >> (sizeof (size_t) * CHAR_BIT / 2) != 0 + && nelem != 0 && size != new_length / nelem) + { + /* Overflow. Discard the old buffer, but it must remain valid + to free. */ + scratch_buffer_free (buffer); + scratch_buffer_init (buffer); + __set_errno (ENOMEM); + return false; + } + + if (new_length <= buffer->length) + return true; + + /* Discard old buffer. */ + scratch_buffer_free (buffer); + + char *new_ptr = malloc (new_length); + if (new_ptr == NULL) + { + /* Buffer must remain valid to free. */ + scratch_buffer_init (buffer); + return false; + } + + /* Install new heap-based buffer. */ + buffer->data = new_ptr; + buffer->length = new_length; + return true; +} +libc_hidden_def (__libc_scratch_buffer_set_array_size) diff --git a/lib/malloca.c b/lib/malloca.c new file mode 100644 index 0000000..e7beaaf --- /dev/null +++ b/lib/malloca.c @@ -0,0 +1,113 @@ +/* Safe automatic memory allocation. + Copyright (C) 2003, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003, 2018. + + 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 . */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include + +/* Specification. */ +#include "malloca.h" + +#include "idx.h" +#include "intprops.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. + 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, 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 (!INT_ADD_WRAPV (n, plus, &nplus) && !xalloc_oversized (nplus, 1)) + { + char *mem = (char *) malloc (nplus); + + if (mem != NULL) + { + uintptr_t umem = (uintptr_t)mem, umemplus; + /* The INT_ADD_WRAPV avoids signed integer overflow on + theoretical platforms where UINTPTR_MAX <= INT_MAX. */ + INT_ADD_WRAPV (umem, sizeof (small_t) + sa_alignment_max - 1, + &umemplus); + 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; + } + } + /* Out of memory. */ + return NULL; +#else +# if !MALLOC_0_IS_NONNULL + if (n == 0) + n = 1; +# endif + return malloc (n); +#endif +} + +#if HAVE_ALLOCA +void +freea (void *p) +{ + /* Check argument. */ + if ((uintptr_t) p & (sa_alignment_max - 1)) + { + /* 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/lib/malloca.h b/lib/malloca.h new file mode 100644 index 0000000..7ec235f --- /dev/null +++ b/lib/malloca.h @@ -0,0 +1,126 @@ +/* Safe automatic memory allocation. + Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + 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 _MALLOCA_H +#define _MALLOCA_H + +#include +#include +#include +#include + +#include "xalloc-oversized.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call + alloca(N); otherwise it returns NULL. It either returns N bytes of + memory allocated on the stack, that lasts until the function returns, + or NULL. + Use of safe_alloca should be avoided: + - inside arguments of function calls - undefined behaviour, + - in inline functions - the allocation may actually last until the + calling function returns. +*/ +#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. + This must be a macro, not a function. */ +# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL) +#else +# 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 - (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) + _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. N and S should be nonnegative and free of side effects. + The array must be freed using freea() before the function returns. */ +#define nmalloca(n, s) \ + (xalloc_oversized (n, s) ? NULL : malloca ((n) * (size_t) (s))) + + +#ifdef __cplusplus +} +#endif + + +/* ------------------- Auxiliary, non-public definitions ------------------- */ + +/* Determine the alignment of a type at compile time. */ +#if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__ +# define sa_alignof __alignof__ +#elif defined __cplusplus + template struct sa_alignof_helper { char __slot1; type __slot2; }; +# define sa_alignof(type) offsetof (sa_alignof_helper, __slot2) +#elif defined __hpux + /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof + values. */ +# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) +#elif defined _AIX + /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof + values. */ +# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) +#else +# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2) +#endif + +enum +{ +/* The desired alignment of memory allocations is the maximum alignment + among all elementary types. */ + sa_alignment_long = sa_alignof (long), + sa_alignment_double = sa_alignof (double), + sa_alignment_longlong = sa_alignof (long long), + sa_alignment_longdouble = sa_alignof (long double), + sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) + | (sa_alignment_longlong - 1) + | (sa_alignment_longdouble - 1) + ) + 1 +}; + +#endif /* _MALLOCA_H */ diff --git a/lib/mbchar.c b/lib/mbchar.c new file mode 100644 index 0000000..3d05f43 --- /dev/null +++ b/lib/mbchar.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2001, 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 . */ + + +#include + +#define MBCHAR_INLINE _GL_EXTERN_INLINE + +#include + +#include "mbchar.h" + +#if IS_BASIC_ASCII + +/* Bit table of characters in the ISO C "basic character set". */ +const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] = +{ + 0x00001a00, /* '\t' '\v' '\f' */ + 0xffffffef, /* ' '...'#' '%'...'?' */ + 0xfffffffe, /* 'A'...'Z' '[' '\\' ']' '^' '_' */ + 0x7ffffffe /* 'a'...'z' '{' '|' '}' '~' */ + /* The remaining bits are 0. */ +}; + +#endif /* IS_BASIC_ASCII */ diff --git a/lib/mbchar.h b/lib/mbchar.h new file mode 100644 index 0000000..9aeb044 --- /dev/null +++ b/lib/mbchar.h @@ -0,0 +1,353 @@ +/* Multibyte character data type. + Copyright (C) 2001, 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 Bruno Haible . */ + +/* A multibyte character is a short subsequence of a char* string, + representing a single wide character. + + We use multibyte characters instead of wide characters because of + the following goals: + 1) correct multibyte handling, i.e. operate according to the LC_CTYPE + locale, + 2) ease of maintenance, i.e. the maintainer needs not know all details + of the ISO C 99 standard, + 3) don't fail grossly if the input is not in the encoding set by the + locale, because often different encodings are in use in the same + countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), + 4) fast in the case of ASCII characters, + 5) portability, i.e. don't make unportable assumptions about wchar_t. + + Multibyte characters are only accessed through the mb* macros. + + mb_ptr (mbc) + return a pointer to the beginning of the multibyte sequence. + + mb_len (mbc) + returns the number of bytes occupied by the multibyte sequence. + Always > 0. + + mb_iseq (mbc, sc) + returns true if mbc is the standard ASCII character sc. + + mb_isnul (mbc) + returns true if mbc is the nul character. + + mb_cmp (mbc1, mbc2) + returns a positive, zero, or negative value depending on whether mbc1 + sorts after, same or before mbc2. + + mb_casecmp (mbc1, mbc2) + returns a positive, zero, or negative value depending on whether mbc1 + sorts after, same or before mbc2, modulo upper/lowercase conversion. + + mb_equal (mbc1, mbc2) + returns true if mbc1 and mbc2 are equal. + + mb_caseequal (mbc1, mbc2) + returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. + + mb_isalnum (mbc) + returns true if mbc is alphanumeric. + + mb_isalpha (mbc) + returns true if mbc is alphabetic. + + mb_isascii(mbc) + returns true if mbc is plain ASCII. + + mb_isblank (mbc) + returns true if mbc is a blank. + + mb_iscntrl (mbc) + returns true if mbc is a control character. + + mb_isdigit (mbc) + returns true if mbc is a decimal digit. + + mb_isgraph (mbc) + returns true if mbc is a graphic character. + + mb_islower (mbc) + returns true if mbc is lowercase. + + mb_isprint (mbc) + returns true if mbc is a printable character. + + mb_ispunct (mbc) + returns true if mbc is a punctuation character. + + mb_isspace (mbc) + returns true if mbc is a space character. + + mb_isupper (mbc) + returns true if mbc is uppercase. + + mb_isxdigit (mbc) + returns true if mbc is a hexadecimal digit. + + mb_width (mbc) + returns the number of columns on the output device occupied by mbc. + Always >= 0. + + mb_putc (mbc, stream) + outputs mbc on stream, a byte oriented FILE stream opened for output. + + mb_setascii (&mbc, sc) + assigns the standard ASCII character sc to mbc. + + mb_copy (&destmbc, &srcmbc) + copies srcmbc to destmbc. + + Here are the function prototypes of the macros. + + extern const char * mb_ptr (const mbchar_t mbc); + extern size_t mb_len (const mbchar_t mbc); + extern bool mb_iseq (const mbchar_t mbc, char sc); + extern bool mb_isnul (const mbchar_t mbc); + extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); + extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); + extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); + extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); + extern bool mb_isalnum (const mbchar_t mbc); + extern bool mb_isalpha (const mbchar_t mbc); + extern bool mb_isascii (const mbchar_t mbc); + extern bool mb_isblank (const mbchar_t mbc); + extern bool mb_iscntrl (const mbchar_t mbc); + extern bool mb_isdigit (const mbchar_t mbc); + extern bool mb_isgraph (const mbchar_t mbc); + extern bool mb_islower (const mbchar_t mbc); + extern bool mb_isprint (const mbchar_t mbc); + extern bool mb_ispunct (const mbchar_t mbc); + extern bool mb_isspace (const mbchar_t mbc); + extern bool mb_isupper (const mbchar_t mbc); + extern bool mb_isxdigit (const mbchar_t mbc); + extern int mb_width (const mbchar_t mbc); + extern void mb_putc (const mbchar_t mbc, FILE *stream); + extern void mb_setascii (mbchar_t *new, char sc); + extern void mb_copy (mbchar_t *new, const mbchar_t *old); + */ + +#ifndef _MBCHAR_H +#define _MBCHAR_H 1 + +#include +#include +#include +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef MBCHAR_INLINE +# define MBCHAR_INLINE _GL_INLINE +#endif + +#define MBCHAR_BUF_SIZE 24 + +struct mbchar +{ + const char *ptr; /* pointer to current character */ + size_t bytes; /* number of bytes of current character, > 0 */ + bool wc_valid; /* true if wc is a valid wide character */ + wchar_t wc; /* if wc_valid: the current character */ + char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ +}; + +/* EOF (not a real character) is represented with bytes = 0 and + wc_valid = false. */ + +typedef struct mbchar mbchar_t; + +/* Access the current character. */ +#define mb_ptr(mbc) ((mbc).ptr) +#define mb_len(mbc) ((mbc).bytes) + +/* Comparison of characters. */ +#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) +#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) +#define mb_cmp(mbc1, mbc2) \ + ((mbc1).wc_valid \ + ? ((mbc2).wc_valid \ + ? (int) (mbc1).wc - (int) (mbc2).wc \ + : -1) \ + : ((mbc2).wc_valid \ + ? 1 \ + : (mbc1).bytes == (mbc2).bytes \ + ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ + : (mbc1).bytes < (mbc2).bytes \ + ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ + : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) +#define mb_casecmp(mbc1, mbc2) \ + ((mbc1).wc_valid \ + ? ((mbc2).wc_valid \ + ? (int) towlower ((mbc1).wc) - (int) towlower ((mbc2).wc) \ + : -1) \ + : ((mbc2).wc_valid \ + ? 1 \ + : (mbc1).bytes == (mbc2).bytes \ + ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ + : (mbc1).bytes < (mbc2).bytes \ + ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ + : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) +#define mb_equal(mbc1, mbc2) \ + ((mbc1).wc_valid && (mbc2).wc_valid \ + ? (mbc1).wc == (mbc2).wc \ + : (mbc1).bytes == (mbc2).bytes \ + && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) +#define mb_caseequal(mbc1, mbc2) \ + ((mbc1).wc_valid && (mbc2).wc_valid \ + ? towlower ((mbc1).wc) == towlower ((mbc2).wc) \ + : (mbc1).bytes == (mbc2).bytes \ + && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) + +/* , classification. */ +#define mb_isascii(mbc) \ + ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) +#define mb_isalnum(mbc) ((mbc).wc_valid && iswalnum ((mbc).wc)) +#define mb_isalpha(mbc) ((mbc).wc_valid && iswalpha ((mbc).wc)) +#define mb_isblank(mbc) ((mbc).wc_valid && iswblank ((mbc).wc)) +#define mb_iscntrl(mbc) ((mbc).wc_valid && iswcntrl ((mbc).wc)) +#define mb_isdigit(mbc) ((mbc).wc_valid && iswdigit ((mbc).wc)) +#define mb_isgraph(mbc) ((mbc).wc_valid && iswgraph ((mbc).wc)) +#define mb_islower(mbc) ((mbc).wc_valid && iswlower ((mbc).wc)) +#define mb_isprint(mbc) ((mbc).wc_valid && iswprint ((mbc).wc)) +#define mb_ispunct(mbc) ((mbc).wc_valid && iswpunct ((mbc).wc)) +#define mb_isspace(mbc) ((mbc).wc_valid && iswspace ((mbc).wc)) +#define mb_isupper(mbc) ((mbc).wc_valid && iswupper ((mbc).wc)) +#define mb_isxdigit(mbc) ((mbc).wc_valid && iswxdigit ((mbc).wc)) + +/* Extra function. */ + +/* Unprintable characters appear as a small box of width 1. */ +#define MB_UNPRINTABLE_WIDTH 1 + +MBCHAR_INLINE int +mb_width_aux (wint_t wc) +{ + int w = wcwidth (wc); + /* For unprintable characters, arbitrarily return 0 for control characters + and MB_UNPRINTABLE_WIDTH otherwise. */ + return (w >= 0 ? w : iswcntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); +} + +#define mb_width(mbc) \ + ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) + +/* Output. */ +#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) + +/* Assignment. */ +#define mb_setascii(mbc, sc) \ + ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ + (mbc)->wc = (mbc)->buf[0] = (sc)) + +/* Copying a character. */ +MBCHAR_INLINE void +mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) +{ + if (old_mbc->ptr == &old_mbc->buf[0]) + { + memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); + new_mbc->ptr = &new_mbc->buf[0]; + } + else + new_mbc->ptr = old_mbc->ptr; + new_mbc->bytes = old_mbc->bytes; + if ((new_mbc->wc_valid = old_mbc->wc_valid)) + new_mbc->wc = old_mbc->wc; +} + + +/* is_basic(c) tests whether the single-byte character c is in the + ISO C "basic character set". + This is a convenience function, and is in this file only to share code + between mbiter_multi.h and mbfile_multi.h. */ +#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) +/* The character set is ISO-646, not EBCDIC. */ +# define IS_BASIC_ASCII 1 + +extern const unsigned int is_basic_table[]; + +MBCHAR_INLINE bool +is_basic (char c) +{ + return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31)) + & 1; +} + +#else + +MBCHAR_INLINE bool +is_basic (char c) +{ + switch (c) + { + case '\t': case '\v': case '\f': + case ' ': case '!': case '"': case '#': case '%': + case '&': case '\'': case '(': case ')': case '*': + case '+': case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': + case '?': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': + case 'Z': + case '[': case '\\': case ']': case '^': case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': + case 'z': case '{': case '|': case '}': case '~': + return 1; + default: + return 0; + } +} + +#endif + +_GL_INLINE_HEADER_END + +#endif /* _MBCHAR_H */ diff --git a/lib/mbiter.c b/lib/mbiter.c new file mode 100644 index 0000000..af7e91b --- /dev/null +++ b/lib/mbiter.c @@ -0,0 +1,21 @@ +/* Iterating through multibyte strings: macros for multi-byte encodings. + + 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 MBITER_INLINE _GL_EXTERN_INLINE +#include "mbiter.h" diff --git a/lib/mbiter.h b/lib/mbiter.h new file mode 100644 index 0000000..031fa92 --- /dev/null +++ b/lib/mbiter.h @@ -0,0 +1,218 @@ +/* Iterating through multibyte strings: macros for multi-byte encodings. + Copyright (C) 2001, 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 Bruno Haible . */ + +/* The macros in this file implement forward iteration through a + multi-byte string. + + With these macros, an iteration loop that looks like + + char *iter; + for (iter = buf; iter < buf + buflen; iter++) + { + do_something (*iter); + } + + becomes + + mbi_iterator_t iter; + for (mbi_init (iter, buf, buflen); mbi_avail (iter); mbi_advance (iter)) + { + do_something (mbi_cur_ptr (iter), mb_len (mbi_cur (iter))); + } + + The benefit of these macros over plain use of mbrtowc is: + - Handling of invalid multibyte sequences is possible without + making the code more complicated, while still preserving the + invalid multibyte sequences. + + mbi_iterator_t + is a type usable for variable declarations. + + mbi_init (iter, startptr, length) + initializes the iterator, starting at startptr and crossing length bytes. + + mbi_avail (iter) + returns true if there are more multibyte characters available before + the end of string is reached. In this case, mbi_cur (iter) is + initialized to the next multibyte character. + + mbi_advance (iter) + advances the iterator by one multibyte character. + + mbi_cur (iter) + returns the current multibyte character, of type mbchar_t. All the + macros defined in mbchar.h can be used on it. + + mbi_cur_ptr (iter) + return a pointer to the beginning of the current multibyte character. + + mbi_reloc (iter, ptrdiff) + relocates iterator when the string is moved by ptrdiff bytes. + + mbi_copy (&destiter, &srciter) + copies srciter to destiter. + + Here are the function prototypes of the macros. + + extern void mbi_init (mbi_iterator_t iter, + const char *startptr, size_t length); + extern bool mbi_avail (mbi_iterator_t iter); + extern void mbi_advance (mbi_iterator_t iter); + extern mbchar_t mbi_cur (mbi_iterator_t iter); + extern const char * mbi_cur_ptr (mbi_iterator_t iter); + extern void mbi_reloc (mbi_iterator_t iter, ptrdiff_t ptrdiff); + extern void mbi_copy (mbi_iterator_t *new, const mbi_iterator_t *old); + */ + +#ifndef _MBITER_H +#define _MBITER_H 1 + +#include +#include +#include +#include +#include + +#include "mbchar.h" + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef MBITER_INLINE +# define MBITER_INLINE _GL_INLINE +#endif + +struct mbiter_multi +{ + const char *limit; /* pointer to end of string */ + bool in_shift; /* true if next byte may not be interpreted as ASCII */ + mbstate_t state; /* if in_shift: current shift state */ + bool next_done; /* true if mbi_avail has already filled the following */ + struct mbchar cur; /* the current character: + const char *cur.ptr pointer to current character + The following are only valid after mbi_avail. + size_t cur.bytes number of bytes of current character + bool cur.wc_valid true if wc is a valid wide character + wchar_t cur.wc if wc_valid: the current character + */ +}; + +MBITER_INLINE void +mbiter_multi_next (struct mbiter_multi *iter) +{ + if (iter->next_done) + return; + if (iter->in_shift) + goto with_shift; + /* Handle most ASCII characters quickly, without calling mbrtowc(). */ + if (is_basic (*iter->cur.ptr)) + { + /* These characters are part of the basic character set. ISO C 99 + guarantees that their wide character code is identical to their + char code. */ + iter->cur.bytes = 1; + iter->cur.wc = *iter->cur.ptr; + iter->cur.wc_valid = true; + } + else + { + assert (mbsinit (&iter->state)); + iter->in_shift = true; + with_shift: + iter->cur.bytes = mbrtowc (&iter->cur.wc, iter->cur.ptr, + iter->limit - iter->cur.ptr, &iter->state); + if (iter->cur.bytes == (size_t) -1) + { + /* An invalid multibyte sequence was encountered. */ + iter->cur.bytes = 1; + iter->cur.wc_valid = false; + /* Whether to set iter->in_shift = false and reset iter->state + or not is not very important; the string is bogus anyway. */ + } + else if (iter->cur.bytes == (size_t) -2) + { + /* An incomplete multibyte character at the end. */ + iter->cur.bytes = iter->limit - iter->cur.ptr; + iter->cur.wc_valid = false; + /* Whether to set iter->in_shift = false and reset iter->state + or not is not important; the string end is reached anyway. */ + } + else + { + if (iter->cur.bytes == 0) + { + /* A null wide character was encountered. */ + iter->cur.bytes = 1; + assert (*iter->cur.ptr == '\0'); + assert (iter->cur.wc == 0); + } + iter->cur.wc_valid = true; + + /* When in the initial state, we can go back treating ASCII + characters more quickly. */ + if (mbsinit (&iter->state)) + iter->in_shift = false; + } + } + iter->next_done = true; +} + +MBITER_INLINE void +mbiter_multi_reloc (struct mbiter_multi *iter, ptrdiff_t ptrdiff) +{ + iter->cur.ptr += ptrdiff; + iter->limit += ptrdiff; +} + +MBITER_INLINE void +mbiter_multi_copy (struct mbiter_multi *new_iter, const struct mbiter_multi *old_iter) +{ + new_iter->limit = old_iter->limit; + if ((new_iter->in_shift = old_iter->in_shift)) + memcpy (&new_iter->state, &old_iter->state, sizeof (mbstate_t)); + else + memset (&new_iter->state, 0, sizeof (mbstate_t)); + new_iter->next_done = old_iter->next_done; + mb_copy (&new_iter->cur, &old_iter->cur); +} + +/* Iteration macros. */ +typedef struct mbiter_multi mbi_iterator_t; +#define mbi_init(iter, startptr, length) \ + ((iter).cur.ptr = (startptr), (iter).limit = (iter).cur.ptr + (length), \ + (iter).in_shift = false, memset (&(iter).state, '\0', sizeof (mbstate_t)), \ + (iter).next_done = false) +#define mbi_avail(iter) \ + ((iter).cur.ptr < (iter).limit && (mbiter_multi_next (&(iter)), true)) +#define mbi_advance(iter) \ + ((iter).cur.ptr += (iter).cur.bytes, (iter).next_done = false) + +/* Access to the current character. */ +#define mbi_cur(iter) (iter).cur +#define mbi_cur_ptr(iter) (iter).cur.ptr + +/* Relocation. */ +#define mbi_reloc(iter, ptrdiff) mbiter_multi_reloc (&iter, ptrdiff) + +/* Copying an iterator. */ +#define mbi_copy mbiter_multi_copy + +_GL_INLINE_HEADER_END + +#endif /* _MBITER_H */ diff --git a/lib/mbrtowc-impl-utf8.h b/lib/mbrtowc-impl-utf8.h new file mode 100644 index 0000000..8e5ac14 --- /dev/null +++ b/lib/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/lib/mbrtowc-impl.h b/lib/mbrtowc-impl.h new file mode 100644 index 0000000..65538e7 --- /dev/null +++ b/lib/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/lib/mbrtowc.c b/lib/mbrtowc.c new file mode 100644 index 0000000..4b164ed --- /dev/null +++ b/lib/mbrtowc.c @@ -0,0 +1,158 @@ +/* Convert multibyte character to wide character. + Copyright (C) 1999-2002, 2005-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 GNULIB_defined_mbstate_t +/* Implement mbrtowc() on top of mbtowc() for the non-UTF-8 locales + and directly for the UTF-8 locales. */ + +# include +# include +# include + +# 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 + +# include "attribute.h" +# include "verify.h" +# include "lc-charset-dispatch.h" +# include "mbtowc-lock.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) +{ +# 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) +{ + size_t ret; + wchar_t wc; + +# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } +# 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; + + /* Override mbrtowc's internal state. We cannot call mbsinit() on the + hidden internal state, but we can call it on our variable. */ + if (ps == NULL) + ps = &internal_state; + + if (!mbsinit (ps)) + { + /* Parse the rest of the multibyte character byte for byte. */ + size_t count = 0; + for (; n > 0; s++, n--) + { + ret = mbrtowc (&wc, s, 1, ps); + + if (ret == (size_t)(-1)) + return (size_t)(-1); + count++; + if (ret != (size_t)(-2)) + { + /* The multibyte character has been completed. */ + *pwc = wc; + return (wc == 0 ? 0 : count); + } + } + return (size_t)(-2); + } + } +# endif + +# if MBRTOWC_STORES_INCOMPLETE_BUG + ret = mbrtowc (&wc, s, n, ps); + if (ret < (size_t) -2 && pwc != NULL) + *pwc = wc; +# else + ret = mbrtowc (pwc, s, n, ps); +# endif + +# if MBRTOWC_NUL_RETVAL_BUG + if (ret < (size_t) -2 && !*pwc) + return 0; +# endif + +# 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/lib/mbsinit.c b/lib/mbsinit.c new file mode 100644 index 0000000..9621def --- /dev/null +++ b/lib/mbsinit.c @@ -0,0 +1,70 @@ +/* Test for initial conversion state. + 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 + +#include "verify.h" + +#if GNULIB_defined_mbstate_t + +/* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs() + and wcrtomb(), wcsrtombs(). + We assume that + - sizeof (mbstate_t) >= 4, + - only stateless encodings are supported (such as UTF-8 and EUC-JP, but + not ISO-2022 variants), + - for each encoding, the number of bytes for a wide character is <= 4. + (This maximum is attained for UTF-8, GB18030, EUC-TW.) + 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. */ + +verify (sizeof (mbstate_t) >= 4); + +int +mbsinit (const mbstate_t *ps) +{ + const char *pstate = (const char *)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/lib/mbsrtowcs-impl.h b/lib/mbsrtowcs-impl.h new file mode 100644 index 0000000..55dafe3 --- /dev/null +++ b/lib/mbsrtowcs-impl.h @@ -0,0 +1,122 @@ +/* Convert string to wide string. + 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 . */ + +size_t +FUNC (DCHAR_T *dest, const char **srcp, size_t len, mbstate_t *ps) +{ + if (ps == NULL) + ps = &INTERNAL_STATE; + { + const char *src = *srcp; + + if (dest != NULL) + { + DCHAR_T *destptr = dest; + + for (; len > 0; destptr++, len--) + { + size_t src_avail; + size_t ret; + + /* An optimized variant of + src_avail = strnlen1 (src, MB_LEN_MAX); */ + if (src[0] == '\0') + src_avail = 1; + else if (src[1] == '\0') + src_avail = 2; + else if (src[2] == '\0') + src_avail = 3; + else if (MB_LEN_MAX <= 4 || src[3] == '\0') + src_avail = 4; + else + src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); + + /* Parse the next multibyte character. */ + ret = MBRTOWC (destptr, src, src_avail, ps); + + if (ret == (size_t)(-2)) + /* Encountered a multibyte character that extends past a '\0' byte + or that is longer than MB_LEN_MAX bytes. Cannot happen. */ + abort (); + + if (ret == (size_t)(-1)) + goto bad_input; + if (ret == 0) + { + src = NULL; + /* Here mbsinit (ps). */ + break; + } + src += ret; + } + + *srcp = src; + return destptr - dest; + } + else + { + /* Ignore dest and len, don't store *srcp at the end, and + don't clobber *ps. */ + mbstate_t state = *ps; + size_t totalcount = 0; + + for (;; totalcount++) + { + size_t src_avail; + size_t ret; + + /* An optimized variant of + src_avail = strnlen1 (src, MB_LEN_MAX); */ + if (src[0] == '\0') + src_avail = 1; + else if (src[1] == '\0') + src_avail = 2; + else if (src[2] == '\0') + src_avail = 3; + else if (MB_LEN_MAX <= 4 || src[3] == '\0') + src_avail = 4; + else + src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); + + /* Parse the next multibyte character. */ + ret = MBRTOWC (NULL, src, src_avail, &state); + + if (ret == (size_t)(-2)) + /* Encountered a multibyte character that extends past a '\0' byte + or that is longer than MB_LEN_MAX bytes. Cannot happen. */ + abort (); + + if (ret == (size_t)(-1)) + goto bad_input2; + if (ret == 0) + { + /* Here mbsinit (&state). */ + break; + } + src += ret; + } + + return totalcount; + } + + bad_input: + *srcp = src; + bad_input2: + errno = EILSEQ; + return (size_t)(-1); + } +} diff --git a/lib/mbsrtowcs-state.c b/lib/mbsrtowcs-state.c new file mode 100644 index 0000000..55160a2 --- /dev/null +++ b/lib/mbsrtowcs-state.c @@ -0,0 +1,37 @@ +/* Convert string to wide string. + 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 + +#include + +/* Internal state used by the functions mbsrtowcs() and mbsnrtowcs(). */ +mbstate_t _gl_mbsrtowcs_state +/* The state must initially be in the "initial state"; so, zero-initialize it. + On most systems, putting it into BSS is sufficient. Not so on Mac OS X 10.3, + see . + When it needs an initializer, use 0 or {0} as initializer? 0 only works + when mbstate_t is a scalar type (such as when gnulib defines it, or on + AIX, IRIX, mingw). {0} works as an initializer in all cases: for a struct + or union type, but also for a scalar type (ISO C 99, 6.7.8.(11)). */ +#if defined __ELF__ + /* On ELF systems, variables in BSS behave well. */ +#else + /* Use braces, to be on the safe side. */ + = { 0 } +#endif + ; diff --git a/lib/mbsrtowcs.c b/lib/mbsrtowcs.c new file mode 100644 index 0000000..66019b0 --- /dev/null +++ b/lib/mbsrtowcs.c @@ -0,0 +1,36 @@ +/* Convert string to wide string. + 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 + +#include +#include +#include + +#include "strnlen1.h" + + +extern mbstate_t _gl_mbsrtowcs_state; + +#define FUNC mbsrtowcs +#define DCHAR_T wchar_t +#define INTERNAL_STATE _gl_mbsrtowcs_state +#define MBRTOWC mbrtowc +#include "mbsrtowcs-impl.h" diff --git a/lib/mbtowc-impl.h b/lib/mbtowc-impl.h new file mode 100644 index 0000000..2b27baf --- /dev/null +++ b/lib/mbtowc-impl.h @@ -0,0 +1,44 @@ +/* Convert multibyte character to wide character. + Copyright (C) 2011-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 . */ + +/* 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 + away. */ + +int +mbtowc (wchar_t *pwc, const char *s, size_t n) +{ + if (s == NULL) + return 0; + else + { + mbstate_t state; + wchar_t wc; + size_t result; + + memset (&state, 0, sizeof (mbstate_t)); + result = mbrtowc (&wc, s, n, &state); + if (result == (size_t)-1 || result == (size_t)-2) + { + errno = EILSEQ; + return -1; + } + if (pwc != NULL) + *pwc = wc; + return (wc == 0 ? 0 : result); + } +} diff --git a/lib/mbtowc-lock.c b/lib/mbtowc-lock.c new file mode 100644 index 0000000..06d3224 --- /dev/null +++ b/lib/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/lib/mbtowc-lock.h b/lib/mbtowc-lock.h new file mode 100644 index 0000000..ecfd44e --- /dev/null +++ b/lib/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/lib/mbtowc.c b/lib/mbtowc.c new file mode 100644 index 0000000..a9a7995 --- /dev/null +++ b/lib/mbtowc.c @@ -0,0 +1,26 @@ +/* Convert multibyte character to wide character. + Copyright (C) 2011-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 + +#include + +#include +#include +#include + +#include "mbtowc-impl.h" diff --git a/lib/md2-stream.c b/lib/md2-stream.c new file mode 100644 index 0000000..89b1fc5 --- /dev/null +++ b/lib/md2-stream.c @@ -0,0 +1,109 @@ +/* Functions to compute MD2 message digest of files or memory blocks. + according to the definition of MD2 in RFC 1319 from April 1992. + Copyright (C) 1995-1997, 1999-2003, 2005-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 . */ + +/* Adapted by Simon Josefsson from public domain Libtomcrypt 1.06 by + Tom St Denis. */ + +#include + +/* Specification. */ +#include "md2.h" + +#include + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#define BLOCKSIZE 32768 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* Compute MD2 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md2_stream (FILE *stream, void *resblock) +{ + struct md2_ctx ctx; + size_t sum; + + char *buffer = malloc (BLOCKSIZE + 72); + if (!buffer) + return 1; + + /* Initialize the computation context. */ + md2_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 + */ + md2_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + md2_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md2_finish_ctx (&ctx, resblock); + free (buffer); + return 0; +} diff --git a/lib/md2.c b/lib/md2.c new file mode 100644 index 0000000..8ca535c --- /dev/null +++ b/lib/md2.c @@ -0,0 +1,192 @@ +/* Functions to compute MD2 message digest of files or memory blocks. + according to the definition of MD2 in RFC 1319 from April 1992. + Copyright (C) 1995-1997, 1999-2003, 2005-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 . */ + +/* Adapted by Simon Josefsson from public domain Libtomcrypt 1.06 by + Tom St Denis. */ + +#include + +/* Specification. */ +#include "md2.h" + +#include +#include + +#include + +static void md2_update_chksum (struct md2_ctx *md); +static void md2_compress (struct md2_ctx *md); + +/* Initialize structure containing state of computation. + (RFC 1319, 3.3: Step 3) */ +void +md2_init_ctx (struct md2_ctx *ctx) +{ + memset (ctx->X, 0, sizeof (ctx->X)); + memset (ctx->chksum, 0, sizeof (ctx->chksum)); + memset (ctx->buf, 0, sizeof (ctx->buf)); + ctx->curlen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. */ +void * +md2_read_ctx (const struct md2_ctx *ctx, void *resbuf) +{ + memcpy (resbuf, ctx->X, 16); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. */ +void * +md2_finish_ctx (struct md2_ctx *ctx, void *resbuf) +{ + unsigned long i, k; + + /* pad the message */ + k = 16 - ctx->curlen; + for (i = ctx->curlen; i < 16; i++) + { + ctx->buf[i] = (unsigned char) k; + } + + /* hash and update */ + md2_compress (ctx); + md2_update_chksum (ctx); + + /* hash checksum */ + memcpy (ctx->buf, ctx->chksum, 16); + md2_compress (ctx); + + return md2_read_ctx (ctx, resbuf); +} + +/* Compute MD5 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. */ +void * +md2_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md2_ctx ctx; + + /* Initialize the computation context. */ + md2_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md2_process_block (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md2_finish_ctx (&ctx, resblock); +} + +void +md2_process_bytes (const void *buffer, size_t len, struct md2_ctx *ctx) +{ + const char *in = buffer; + unsigned long n; + + while (len > 0) + { + n = MIN (len, (16 - ctx->curlen)); + memcpy (ctx->buf + ctx->curlen, in, (size_t) n); + ctx->curlen += n; + in += n; + len -= n; + + /* is 16 bytes full? */ + if (ctx->curlen == 16) + { + md2_compress (ctx); + md2_update_chksum (ctx); + ctx->curlen = 0; + } + } +} + +static const unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +/* adds 16 bytes to the checksum */ +static void +md2_update_chksum (struct md2_ctx *ctx) +{ + int j; + unsigned char L; + + L = ctx->chksum[15]; + for (j = 0; j < 16; j++) + { + /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the + reference source code [and test vectors] say otherwise. */ + L = (ctx->chksum[j] ^= PI_SUBST[(int) (ctx->buf[j] ^ L)] & 255); + } +} + +static void +md2_compress (struct md2_ctx *ctx) +{ + size_t j, k; + unsigned char t; + + /* copy block */ + for (j = 0; j < 16; j++) + { + ctx->X[16 + j] = ctx->buf[j]; + ctx->X[32 + j] = ctx->X[j] ^ ctx->X[16 + j]; + } + + t = (unsigned char) 0; + + /* do 18 rounds */ + for (j = 0; j < 18; j++) + { + for (k = 0; k < 48; k++) + { + t = (ctx->X[k] ^= PI_SUBST[(int) (t & 255)]); + } + t = (t + (unsigned char) j) & 255; + } +} + +/* Process LEN bytes of BUFFER, accumulating context into CTX. */ +void +md2_process_block (const void *buffer, size_t len, struct md2_ctx *ctx) +{ + md2_process_bytes (buffer, len, ctx); +} diff --git a/lib/md2.h b/lib/md2.h new file mode 100644 index 0000000..92cbc46 --- /dev/null +++ b/lib/md2.h @@ -0,0 +1,87 @@ +/* Declarations of functions and data types used for MD2 sum + library functions. + Copyright (C) 2000-2001, 2003, 2005, 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 . */ + +#ifndef MD2_H +# define MD2_H 1 + +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# define MD2_DIGEST_SIZE 16 + +/* Structure to save state of computation between the single steps. */ +struct md2_ctx +{ + unsigned char chksum[16], X[48], buf[16]; + size_t curlen; +}; + + +/* Initialize structure containing state of computation. */ +extern void md2_init_ctx (struct md2_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md2_process_block (const void *buffer, size_t len, + struct md2_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md2_process_bytes (const void *buffer, size_t len, + struct md2_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 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 *md2_finish_ctx (struct md2_ctx *ctx, void *restrict resbuf); + + +/* Put result from CTX in first 16 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 *md2_read_ctx (const struct md2_ctx *ctx, void *restrict resbuf); + + +/* Compute MD2 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 *md2_buffer (const char *buffer, size_t len, + void *restrict resblock); + + +/* Compute MD2 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md2_stream (FILE *stream, void *resblock); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/lib/md4-stream.c b/lib/md4-stream.c new file mode 100644 index 0000000..8eae081 --- /dev/null +++ b/lib/md4-stream.c @@ -0,0 +1,109 @@ +/* Functions to compute MD4 message digest of files or memory blocks. + according to the definition of MD4 in RFC 1320 from April 1992. + Copyright (C) 1995-1997, 1999-2003, 2005-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 . */ + +/* Adapted by Simon Josefsson from gnulib md5.? and Libgcrypt + cipher/md4.c . */ + +#include + +/* Specification. */ +#include "md4.h" + +#include + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#define BLOCKSIZE 32768 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* Compute MD4 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md4_stream (FILE * stream, void *resblock) +{ + struct md4_ctx ctx; + size_t sum; + + char *buffer = malloc (BLOCKSIZE + 72); + if (!buffer) + return 1; + + /* Initialize the computation context. */ + md4_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 + */ + md4_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + md4_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md4_finish_ctx (&ctx, resblock); + free (buffer); + return 0; +} diff --git a/lib/md4.c b/lib/md4.c new file mode 100644 index 0000000..9355f18 --- /dev/null +++ b/lib/md4.c @@ -0,0 +1,300 @@ +/* Functions to compute MD4 message digest of files or memory blocks. + according to the definition of MD4 in RFC 1320 from April 1992. + Copyright (C) 1995-1997, 1999-2003, 2005-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 . */ + +/* Adapted by Simon Josefsson from gnulib md5.? and Libgcrypt + cipher/md4.c . */ + +#include + +/* Specification. */ +#include "md4.h" + +#include +#include +#include +#include + +#include +#ifdef WORDS_BIGENDIAN +# define SWAP(n) bswap_32 (n) +#else +# define SWAP(n) (n) +#endif + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1320, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1320, 3.3: Step 3) */ +void +md4_init_ctx (struct md4_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Copy the 4 byte value from v into the memory location pointed to by *cp, + If your architecture allows unaligned access this is equivalent to + * (uint32_t *) cp = v */ +static void +set_uint32 (char *cp, uint32_t v) +{ + memcpy (cp, &v, sizeof v); +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. */ +void * +md4_read_ctx (const struct md4_ctx *ctx, void *resbuf) +{ + char *r = resbuf; + set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A)); + set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B)); + set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C)); + set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D)); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. */ +void * +md4_finish_ctx (struct md4_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&((char*)ctx->buffer)[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3); + ctx->buffer[(bytes + pad) / 4 + 1] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + md4_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return md4_read_ctx (ctx, resbuf); +} + +/* Compute MD4 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. */ +void * +md4_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md4_ctx ctx; + + /* Initialize the computation context. */ + md4_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md4_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md4_finish_ctx (&ctx, resblock); +} + +void +md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char*)ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + md4_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#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) + { + md4_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + md4_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char*)ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + md4_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[16], left_over); + } + ctx->buflen = left_over; + } +} + +/* --- Code below is the primary difference between md5.c and md4.c --- */ + +/* MD4 round constants */ +#define K1 0x5a827999 +#define K2 0x6ed9eba1 + +/* Round functions. */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) +#define R1(a,b,c,d,k,s) a=rol(a+F(b,c,d)+x[k],s); +#define R2(a,b,c,d,k,s) a=rol(a+G(b,c,d)+x[k]+K1,s); +#define R3(a,b,c,d,k,s) a=rol(a+H(b,c,d)+x[k]+K2,s); + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx) +{ + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t x[16]; + uint32_t A = ctx->A; + uint32_t B = ctx->B; + uint32_t C = ctx->C; + uint32_t D = ctx->D; + uint32_t lolen = len; + + /* First increment the byte count. RFC 1320 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += lolen; + ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + int t; + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + /* Round 1. */ + R1 (A, B, C, D, 0, 3); + R1 (D, A, B, C, 1, 7); + R1 (C, D, A, B, 2, 11); + R1 (B, C, D, A, 3, 19); + R1 (A, B, C, D, 4, 3); + R1 (D, A, B, C, 5, 7); + R1 (C, D, A, B, 6, 11); + R1 (B, C, D, A, 7, 19); + R1 (A, B, C, D, 8, 3); + R1 (D, A, B, C, 9, 7); + R1 (C, D, A, B, 10, 11); + R1 (B, C, D, A, 11, 19); + R1 (A, B, C, D, 12, 3); + R1 (D, A, B, C, 13, 7); + R1 (C, D, A, B, 14, 11); + R1 (B, C, D, A, 15, 19); + + /* Round 2. */ + R2 (A, B, C, D, 0, 3); + R2 (D, A, B, C, 4, 5); + R2 (C, D, A, B, 8, 9); + R2 (B, C, D, A, 12, 13); + R2 (A, B, C, D, 1, 3); + R2 (D, A, B, C, 5, 5); + R2 (C, D, A, B, 9, 9); + R2 (B, C, D, A, 13, 13); + R2 (A, B, C, D, 2, 3); + R2 (D, A, B, C, 6, 5); + R2 (C, D, A, B, 10, 9); + R2 (B, C, D, A, 14, 13); + R2 (A, B, C, D, 3, 3); + R2 (D, A, B, C, 7, 5); + R2 (C, D, A, B, 11, 9); + R2 (B, C, D, A, 15, 13); + + /* Round 3. */ + R3 (A, B, C, D, 0, 3); + R3 (D, A, B, C, 8, 9); + R3 (C, D, A, B, 4, 11); + R3 (B, C, D, A, 12, 15); + R3 (A, B, C, D, 2, 3); + R3 (D, A, B, C, 10, 9); + R3 (C, D, A, B, 6, 11); + R3 (B, C, D, A, 14, 15); + R3 (A, B, C, D, 1, 3); + R3 (D, A, B, C, 9, 9); + R3 (C, D, A, B, 5, 11); + R3 (B, C, D, A, 13, 15); + R3 (A, B, C, D, 3, 3); + R3 (D, A, B, C, 11, 9); + R3 (C, D, A, B, 7, 11); + R3 (B, C, D, A, 15, 15); + + A = ctx->A += A; + B = ctx->B += B; + C = ctx->C += C; + D = ctx->D += D; + } +} diff --git a/lib/md4.h b/lib/md4.h new file mode 100644 index 0000000..356a0dc --- /dev/null +++ b/lib/md4.h @@ -0,0 +1,93 @@ +/* Declarations of functions and data types used for MD4 sum + library functions. + Copyright (C) 2000-2001, 2003, 2005, 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 . */ + +#ifndef MD4_H +# define MD4_H 1 + +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# define MD4_DIGEST_SIZE 16 + +/* Structure to save state of computation between the single steps. */ +struct md4_ctx +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + + uint32_t total[2]; + uint32_t buflen; + uint32_t buffer[32]; +}; + + +/* Initialize structure containing state of computation. */ +extern void md4_init_ctx (struct md4_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void md4_process_block (const void *buffer, size_t len, + struct md4_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md4_process_bytes (const void *buffer, size_t len, + struct md4_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 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 *md4_finish_ctx (struct md4_ctx *ctx, void *restrict resbuf); + + +/* Put result from CTX in first 16 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 *md4_read_ctx (const struct md4_ctx *ctx, void *restrict resbuf); + + +/* Compute MD4 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 *md4_buffer (const char *buffer, size_t len, + void *restrict resblock); + + +/* Compute MD4 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md4_stream (FILE * stream, void *resblock); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/lib/md5-stream.c b/lib/md5-stream.c new file mode 100644 index 0000000..07c639f --- /dev/null +++ b/lib/md5-stream.c @@ -0,0 +1,141 @@ +/* Functions to compute MD5 message digest of files or memory blocks. + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2022 Free Software + Foundation, Inc. + This file is part of 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 . */ + +/* Written by Ulrich Drepper , 1995. */ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_MD5 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "md5.h" + +#include + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#include "af_alg.h" + +#ifdef _LIBC +# include +# if __BYTE_ORDER == __BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +# endif +/* We need to keep the namespace clean so define the MD5 function + protected using leading __ . */ +# define md5_init_ctx __md5_init_ctx +# define md5_process_block __md5_process_block +# define md5_process_bytes __md5_process_bytes +# define md5_finish_ctx __md5_finish_ctx +# define md5_stream __md5_stream +#endif + +#define BLOCKSIZE 32768 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md5_stream (FILE *stream, void *resblock) +{ + switch (afalg_stream (stream, "md5", resblock, MD5_DIGEST_SIZE)) + { + case 0: return 0; + case -EIO: return 1; + } + + char *buffer = malloc (BLOCKSIZE + 72); + if (!buffer) + return 1; + + struct md5_ctx ctx; + md5_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 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block: + + /* Process any remaining bytes. */ + if (sum > 0) + md5_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md5_finish_ctx (&ctx, resblock); + free (buffer); + return 0; +} + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/md5.c b/lib/md5.c new file mode 100644 index 0000000..57489ed --- /dev/null +++ b/lib/md5.c @@ -0,0 +1,395 @@ +/* Functions to compute MD5 message digest of files or memory blocks. + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995-1997, 1999-2001, 2005-2006, 2008-2022 Free Software + Foundation, Inc. + This file is part of 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 . */ + +/* Written by Ulrich Drepper , 1995. */ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_MD5 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "md5.h" + +#include +#include +#include +#include + +#ifdef _LIBC +# include +# if __BYTE_ORDER == __BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +# endif +/* We need to keep the namespace clean so define the MD5 function + protected using leading __ . */ +# define md5_init_ctx __md5_init_ctx +# define md5_process_block __md5_process_block +# define md5_process_bytes __md5_process_bytes +# define md5_finish_ctx __md5_finish_ctx +# define md5_read_ctx __md5_read_ctx +# define md5_buffer __md5_buffer +#endif + +#include +#ifdef WORDS_BIGENDIAN +# define SWAP(n) bswap_32 (n) +#else +# define SWAP(n) (n) +#endif + +#if ! HAVE_OPENSSL_MD5 + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +void +md5_init_ctx (struct md5_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Copy the 4 byte value from v into the memory location pointed to by *cp, + If your architecture allows unaligned access this is equivalent to + * (uint32_t *) cp = v */ +static void +set_uint32 (char *cp, uint32_t v) +{ + memcpy (cp, &v, sizeof v); +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. */ +void * +md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) +{ + char *r = resbuf; + set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A)); + set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B)); + set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C)); + set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D)); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. */ +void * +md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3); + ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + + memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + + /* Process last bytes. */ + md5_process_block (ctx->buffer, size * 4, ctx); + + return md5_read_ctx (ctx, resbuf); +} + +/* Compute MD5 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. */ +void * +md5_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md5_ctx ctx; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md5_finish_ctx (&ctx, resblock); +} + + +void +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* 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); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#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) + { + md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + md5_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + md5_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; + } +} + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + uint32_t correct_words[16]; + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t A = ctx->A; + uint32_t B = ctx->B; + uint32_t C = ctx->C; + uint32_t D = ctx->D; + uint32_t lolen = len; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += lolen; + ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + uint32_t *cwp = correct_words; + uint32_t A_save = A; + uint32_t B_save = B; + uint32_t C_save = C; + uint32_t D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + + Here is an equivalent invocation using Perl: + + perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ + a += f (b, c, d) + correct_words[k] + T; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; +} + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/md5.h b/lib/md5.h new file mode 100644 index 0000000..5b92eac --- /dev/null +++ b/lib/md5.h @@ -0,0 +1,148 @@ +/* Declaration of functions and data types used for MD5 sum computing + library functions. + Copyright (C) 1995-1997, 1999-2001, 2004-2006, 2008-2022 Free Software + Foundation, Inc. + This file is part of 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 _MD5_H +#define _MD5_H 1 + +#include +#include + +# if HAVE_OPENSSL_MD5 +# include +# endif + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 + +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# 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 + +#ifndef _LIBC +# define __md5_buffer md5_buffer +# define __md5_finish_ctx md5_finish_ctx +# define __md5_init_ctx md5_init_ctx +# define __md5_process_block md5_process_block +# define __md5_process_bytes md5_process_bytes +# define __md5_read_ctx md5_read_ctx +# define __md5_stream md5_stream +#endif + +# ifdef __cplusplus +extern "C" { +# endif + +# if HAVE_OPENSSL_MD5 +# define GL_OPENSSL_NAME 5 +# include "gl_openssl.h" +# else +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + + uint32_t total[2]; + uint32_t buflen; /* ≥ 0, ≤ 128 */ + uint32_t buffer[32]; /* 128 bytes; the first buflen bytes are in use */ +}; + +/* + * The following three functions are build up the low level used in + * the functions 'md5_stream' and 'md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void __md5_process_block (const void *buffer, size_t len, + struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void __md5_process_bytes (const void *buffer, size_t len, + struct md5_ctx *ctx) __THROW; + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 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 *__md5_finish_ctx (struct md5_ctx *ctx, void *restrict resbuf) + __THROW; + + +/* Put result from CTX in first 16 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 *__md5_read_ctx (const struct md5_ctx *ctx, void *restrict resbuf) + __THROW; + + +/* Compute MD5 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 *__md5_buffer (const char *buffer, size_t len, + void *restrict resblock) __THROW; + +# endif + +/* Compute MD5 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 16 bytes + beginning at RESBLOCK. */ +extern int __md5_stream (FILE *stream, void *resblock) __THROW; + + +# ifdef __cplusplus +} +# endif + +#endif /* md5.h */ + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/memchr.c b/lib/memchr.c new file mode 100644 index 0000000..0ca7b30 --- /dev/null +++ b/lib/memchr.c @@ -0,0 +1,172 @@ +/* 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), + with help from Dan Sahlin (dan@sics.se) and + commentary by Jim Blandy (jimb@ai.mit.edu); + 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. + + 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 _LIBC +# include +#endif + +#include + +#include + +#if defined _LIBC +# include +#else +# define reg_char char +#endif + +#include + +#if HAVE_BP_SYM_H || defined _LIBC +# include +#else +# define BP_SYM(sym) sym +#endif + +#undef __memchr +#ifdef _LIBC +# undef memchr +#endif + +#ifndef weak_alias +# define __memchr memchr +#endif + +/* Search no more than N bytes of S for C. */ +void * +__memchr (void const *s, int c_in, size_t n) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned reg_char c; + + c = (unsigned char) c_in; + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + n > 0 && (size_t) char_ptr % sizeof (longword) != 0; + --n, ++char_ptr) + if (*char_ptr == c) + return (void *) char_ptr; + + longword_ptr = (const longword *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will test a + longword at a time. The tricky part is testing if *any of the four* + bytes in the longword in question are equal to c. We first use an xor + with repeated_c. This reduces the task to testing whether *any of the + four* bytes in longword1 is zero. + + We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + So, the test whether any byte in longword1 is zero is equivalent to + testing whether tmp is nonzero. */ + + while (n >= sizeof (longword)) + { + longword longword1 = *longword_ptr ^ repeated_c; + + if ((((longword1 - repeated_one) & ~longword1) + & (repeated_one << 7)) != 0) + break; + longword_ptr++; + n -= sizeof (longword); + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that either n < sizeof (longword), or one of the + sizeof (longword) bytes starting at char_ptr is == c. On little-endian + machines, we could determine the first such byte without any further + memory accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. Choose code + that works in both cases. */ + + for (; n > 0; --n, ++char_ptr) + { + if (*char_ptr == c) + return (void *) char_ptr; + } + + return NULL; +} +#ifdef weak_alias +weak_alias (__memchr, BP_SYM (memchr)) +#endif diff --git a/lib/memchr.valgrind b/lib/memchr.valgrind new file mode 100644 index 0000000..cb0f351 --- /dev/null +++ b/lib/memchr.valgrind @@ -0,0 +1,30 @@ +# 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. +{ + memchr-value4 + Memcheck:Value4 + fun:rpl_memchr +} +{ + memchr-value8 + Memcheck:Value8 + fun:rpl_memchr +} diff --git a/lib/mempcpy.c b/lib/mempcpy.c new file mode 100644 index 0000000..9aae418 --- /dev/null +++ b/lib/mempcpy.c @@ -0,0 +1,33 @@ +/* Copy memory area and return pointer after last written byte. + Copyright (C) 2003, 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 + +/* A function definition is only needed if HAVE_MEMPCPY is not defined. */ +#if !HAVE_MEMPCPY + +/* Copy N bytes of SRC to DEST, return pointer to bytes after the + last written byte. */ +void * +mempcpy (void *dest, const void *src, size_t n) +{ + return (char *) memcpy (dest, src, n) + n; +} + +#endif diff --git a/lib/memrchr.c b/lib/memrchr.c new file mode 100644 index 0000000..90fdb86 --- /dev/null +++ b/lib/memrchr.c @@ -0,0 +1,161 @@ +/* memrchr -- find the last occurrence of a byte in a memory block + + Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2022 Free Software + Foundation, Inc. + + Based on strlen implementation by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se) and + commentary by Jim Blandy (jimb@ai.mit.edu); + adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), + and implemented by Roland McGrath (roland@ai.mit.edu). + + 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 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 defined _LIBC +# include +#else +# include +# define reg_char char +#endif + +#include +#include + +#undef __memrchr +#ifdef _LIBC +# undef memrchr +#endif + +#ifndef weak_alias +# define __memrchr memrchr +#endif + +/* Search no more than N bytes of S for C. */ +void * +__memrchr (void const *s, int c_in, size_t n) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned reg_char c; + + c = (unsigned char) c_in; + + /* Handle the last few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s + n; + n > 0 && (size_t) char_ptr % sizeof (longword) != 0; + --n) + if (*--char_ptr == c) + return (void *) char_ptr; + + longword_ptr = (const void *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will test a + longword at a time. The tricky part is testing if *any of the four* + bytes in the longword in question are equal to c. We first use an xor + with repeated_c. This reduces the task to testing whether *any of the + four* bytes in longword1 is zero. + + We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + So, the test whether any byte in longword1 is zero is equivalent to + testing whether tmp is nonzero. */ + + while (n >= sizeof (longword)) + { + longword longword1 = *--longword_ptr ^ repeated_c; + + if ((((longword1 - repeated_one) & ~longword1) + & (repeated_one << 7)) != 0) + { + longword_ptr++; + break; + } + n -= sizeof (longword); + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that either n < sizeof (longword), or one of the + sizeof (longword) bytes starting at char_ptr is == c. On little-endian + machines, we could determine the first such byte without any further + memory accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. Choose code + that works in both cases. */ + + while (n-- > 0) + { + if (*--char_ptr == c) + return (void *) char_ptr; + } + + return NULL; +} +#ifdef weak_alias +weak_alias (__memrchr, memrchr) +#endif diff --git a/lib/minmax.h b/lib/minmax.h new file mode 100644 index 0000000..b4b1345 --- /dev/null +++ b/lib/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/lib/mkdir.c b/lib/mkdir.c new file mode 100644 index 0000000..4901701 --- /dev/null +++ b/lib/mkdir.c @@ -0,0 +1,93 @@ +/* On some systems, mkdir ("foo/", 0700) fails because of the trailing + slash. On those systems, this wrapper removes the trailing slash. + + Copyright (C) 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 Jim Meyering */ + +#include + +/* Specification. */ +#include + +#include +#include +#include +#include + +#include "dirname.h" + +/* Disable the definition of mkdir to rpl_mkdir (from the + substitute) in this file. Otherwise, we'd get an endless recursion. */ +#undef mkdir + +/* 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 in the override. */ +#if defined _WIN32 && ! defined __CYGWIN__ +# define mkdir(name,mode) _mkdir (name) +# define maybe_unused _GL_UNUSED +#else +# define maybe_unused /* empty */ +#endif + +/* This function is required at least for NetBSD 1.5.2. */ + +int +rpl_mkdir (char const *dir, maybe_unused mode_t mode) +{ + int ret_val; + char *tmp_dir; + size_t len = strlen (dir); + + if (len && dir[len - 1] == '/') + { + tmp_dir = strdup (dir); + if (!tmp_dir) + { + /* Rather than rely on strdup-posix, we set errno ourselves. */ + errno = ENOMEM; + return -1; + } + strip_trailing_slashes (tmp_dir); + } + else + { + tmp_dir = (char *) dir; + } +#if FUNC_MKDIR_DOT_BUG + /* Additionally, cygwin 1.5 mistakenly creates a directory "d/./". */ + { + char *last = last_component (tmp_dir); + if (*last == '.' && (last[1] == '\0' + || (last[1] == '.' && last[2] == '\0'))) + { + struct stat st; + if (stat (tmp_dir, &st) == 0 || errno == EOVERFLOW) + errno = EEXIST; + return -1; + } + } +#endif /* FUNC_MKDIR_DOT_BUG */ + + ret_val = mkdir (tmp_dir, mode); + + if (tmp_dir != dir) + free (tmp_dir); + + return ret_val; +} diff --git a/lib/mkostemp.c b/lib/mkostemp.c new file mode 100644 index 0000000..eae289a --- /dev/null +++ b/lib/mkostemp.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1998-1999, 2001, 2005-2007, 2009-2022 Free Software + Foundation, Inc. + This file is derived from the one in 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 . */ + +#if !_LIBC +# include +#endif + +#include + +#if !_LIBC +# include "tempname.h" +# define __gen_tempname gen_tempname +# ifndef __GTFILE +# define __GT_FILE GT_FILE +# endif +#endif + +#include + +#ifndef __GT_FILE +# define __GT_FILE 0 +#endif + +/* Generate a unique temporary file name from XTEMPLATE. + The last six characters of XTEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + Then open the file and return a fd. */ +int +mkostemp (char *xtemplate, int flags) +{ + return __gen_tempname (xtemplate, 0, flags, __GT_FILE); +} diff --git a/lib/mkstemp.c b/lib/mkstemp.c new file mode 100644 index 0000000..7e0a214 --- /dev/null +++ b/lib/mkstemp.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1998-1999, 2001, 2005-2007, 2009-2022 Free Software + Foundation, Inc. + This file is derived from the one in 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 . */ + +#if !_LIBC +# include +#endif + +#include + +#if !_LIBC +# include "tempname.h" +# define __gen_tempname gen_tempname +# ifndef __GT_FILE +# define __GT_FILE GT_FILE +# endif +#endif + +#include + +#ifndef __GT_FILE +# define __GT_FILE 0 +#endif + +/* Generate a unique temporary file name from XTEMPLATE. + The last six characters of XTEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + Then open the file and return a fd. + + If you are creating temporary files which will later be removed, + consider using the clean-temp module, which avoids several pitfalls + of using mkstemp directly. */ +int +mkstemp (char *xtemplate) +{ + return __gen_tempname (xtemplate, 0, 0, __GT_FILE); +} diff --git a/lib/mktime-internal.h b/lib/mktime-internal.h new file mode 100644 index 0000000..170764e --- /dev/null +++ b/lib/mktime-internal.h @@ -0,0 +1,79 @@ +/* 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/lib/mktime.c b/lib/mktime.c new file mode 100644 index 0000000..7dc9d67 --- /dev/null +++ b/lib/mktime.c @@ -0,0 +1,578 @@ +/* Convert a 'struct tm' to a time_t value. + 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 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 + . */ + +/* 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 +#endif + +/* Assume that leap seconds are possible, unless told otherwise. + If the host has a 'zic' command with a '-L leapsecondfilename' option, + then it supports leap seconds; otherwise it probably doesn't. */ +#ifndef LEAP_SECONDS_POSSIBLE +# define LEAP_SECONDS_POSSIBLE 1 +#endif + +#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" + +#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 + tzset (); +# endif +} +# undef __tzset +# define __tzset() my_tzset () +#endif + +#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. + + 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 (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. 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. */ + +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 (TM_YEAR_BASE % 100 == 0); + +/* 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. + Also, work even if YEAR is negative. */ + return + ((year & 3) == 0 + && (year % 100 != 0 + || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3))); +} + +/* How many days come before each month (0-12). */ +#ifndef _LIBC +static +#endif +const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; + + +/* 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); +} + +/* 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 timestamps. + + The YEAR values uses the same numbering as TP->tm_year. Values + 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. */ + +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 (-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 + (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 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. + 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 a long_int value corresponding to (YEAR-YDAY HOUR:MIN:SEC) + minus *TP seconds, assuming no clock adjustments occurred between + the two timestamps. + + 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) +{ + return ydhms_diff (year, yday, hour, min, sec, + tp->tm_year, tp->tm_yday, + tp->tm_hour, tp->tm_min, tp->tm_sec); +} + +/* 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) +{ + __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. + 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 __time64_t *, struct tm *), + long_int *t, struct tm *tp) +{ + long_int t1 = (*t < mktime_min ? mktime_min + : *t <= mktime_max ? *t : mktime_max); + struct tm *r = convert_time (convert, t1, tp); + if (r) + { + *t = t1; + return r; + } + if (errno != EOVERFLOW) + return NULL; + + long_int bad = t1; + long_int ok = 0; + struct tm oktm; oktm.tm_sec = -1; + + /* 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; + } + + if (oktm.tm_sec < 0) + return NULL; + *t = ok; + *tp = oktm; + return tp; +} + + +/* 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. */ +__time64_t +__mktime_internal (struct tm *tp, + struct tm *(*convert) (const __time64_t *, struct tm *), + mktime_offset_t *offset) +{ + struct tm tm; + + /* The maximum number of probes (calls to CONVERT) should be enough + to handle any combinations of time zone rule changes, solar time, + leap seconds, and oscillations around a spring-forward gap. + POSIX.1 prohibits leap seconds, but some hosts have them anyway. */ + int remaining_probes = 6; + + /* Time requested. Copy it in case CONVERT modifies *TP; this can + occur if TP is localtime's returned value and CONVERT is localtime. */ + int sec = tp->tm_sec; + int min = tp->tm_min; + int hour = tp->tm_hour; + int mday = tp->tm_mday; + int mon = tp->tm_mon; + int year_requested = tp->tm_year; + int isdst = tp->tm_isdst; + + /* 1 if the previous probe was DST. */ + int dst2 = 0; + + /* Ensure that mon is in range, and set year accordingly. */ + int mon_remainder = mon % 12; + int negative_mon_remainder = mon_remainder < 0; + int mon_years = mon / 12 - negative_mon_remainder; + long_int lyear_requested = year_requested; + long_int year = lyear_requested + mon_years; + + /* The other values need not be in range: + the remaining code handles overflows correctly. */ + + /* Calculate day of year from year, month, and day of month. + The result need not be in range. */ + int mon_yday = ((__mon_yday[leapyear (year)] + [mon_remainder + 12 * negative_mon_remainder]) + - 1); + long_int lmday = mday; + long_int yday = mon_yday + lmday; + + 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_diff assumes every minute has 60 seconds. */ + if (sec < 0) + sec = 0; + if (59 < sec) + sec = 59; + } + + /* Invert CONVERT by probing. First assume the same offset as last + time. */ + + 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. */ + + while (true) + { + 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) + { + __set_errno (EOVERFLOW); + 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. */ + if (isdst_differ (isdst, tm.tm_isdst)) + { + /* tm.tm_isdst has the wrong value. Look for a neighboring + time with the right value, and use its UTC offset. + + Heuristic: probe the adjacent timestamps in both directions, + 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 + (e.g., America/Recife starting 2000-10-08 01:00), and the + shortest period of non-DST surrounded by DST is 694800 + seconds (Africa/Tunis starting 1943-04-17 01:00). Use the + minimum of these two values, so we don't miss these short + periods when probing. */ + int stride = 601200; + + /* 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. */ + int delta_bound = duration_max / 2 + stride; + + int delta, direction; + + for (delta = stride; delta < delta_bound; delta += stride) + for (direction = -1; direction <= 1; direction += 2) + { + 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: + /* 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. */ + 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; + } + + *tp = tm; + return t; +} + +#endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */ + +#if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS + +/* Convert *TP to a __time64_t value. */ +__time64_t +__mktime64 (struct tm *tp) +{ + /* 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 (); + +# 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 */ + +#if defined _LIBC && __TIMESIZE != 64 + +libc_hidden_def (__mktime64) + +time_t +mktime (struct tm *tp) +{ + struct tm tm = *tp; + __time64_t t = __mktime64 (&tm); + if (in_time_t_range (t)) + { + *tp = tm; + return t; + } + else + { + __set_errno (EOVERFLOW); + return -1; + } +} + +#endif + +weak_alias (mktime, timelocal) +libc_hidden_def (mktime) +libc_hidden_weak (timelocal) diff --git a/lib/msvc-inval.c b/lib/msvc-inval.c new file mode 100644 index 0000000..d6651ca --- /dev/null +++ b/lib/msvc-inval.c @@ -0,0 +1,129 @@ +/* Invalid parameter handler for MSVC runtime libraries. + 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 . */ + +#include + +/* Specification. */ +#include "msvc-inval.h" + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \ + && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING) + +/* Get _invalid_parameter_handler type and _set_invalid_parameter_handler + declaration. */ +# include + +# if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING + +static void __cdecl +gl_msvc_invalid_parameter_handler (const wchar_t *expression, + const wchar_t *function, + const wchar_t *file, + unsigned int line, + uintptr_t dummy) +{ +} + +# else + +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include + +# if defined _MSC_VER + +static void __cdecl +gl_msvc_invalid_parameter_handler (const wchar_t *expression, + const wchar_t *function, + const wchar_t *file, + unsigned int line, + uintptr_t dummy) +{ + RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); +} + +# else + +/* An index to thread-local storage. */ +static DWORD tls_index; +static int tls_initialized /* = 0 */; + +/* Used as a fallback only. */ +static struct gl_msvc_inval_per_thread not_per_thread; + +struct gl_msvc_inval_per_thread * +gl_msvc_inval_current (void) +{ + if (!tls_initialized) + { + tls_index = TlsAlloc (); + tls_initialized = 1; + } + if (tls_index == TLS_OUT_OF_INDEXES) + /* TlsAlloc had failed. */ + return ¬_per_thread; + else + { + struct gl_msvc_inval_per_thread *pointer = + (struct gl_msvc_inval_per_thread *) TlsGetValue (tls_index); + if (pointer == NULL) + { + /* First call. Allocate a new 'struct gl_msvc_inval_per_thread'. */ + pointer = + (struct gl_msvc_inval_per_thread *) + malloc (sizeof (struct gl_msvc_inval_per_thread)); + if (pointer == NULL) + /* Could not allocate memory. Use the global storage. */ + pointer = ¬_per_thread; + TlsSetValue (tls_index, pointer); + } + return pointer; + } +} + +static void __cdecl +gl_msvc_invalid_parameter_handler (const wchar_t *expression, + const wchar_t *function, + const wchar_t *file, + unsigned int line, + uintptr_t dummy) +{ + struct gl_msvc_inval_per_thread *current = gl_msvc_inval_current (); + if (current->restart_valid) + longjmp (current->restart, 1); + else + /* An invalid parameter notification from outside the gnulib code. + Give the caller a chance to intervene. */ + RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); +} + +# endif + +# endif + +static int gl_msvc_inval_initialized /* = 0 */; + +void +gl_msvc_inval_ensure_handler (void) +{ + if (gl_msvc_inval_initialized == 0) + { + _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler); + gl_msvc_inval_initialized = 1; + } +} + +#endif diff --git a/lib/msvc-inval.h b/lib/msvc-inval.h new file mode 100644 index 0000000..1230b89 --- /dev/null +++ b/lib/msvc-inval.h @@ -0,0 +1,222 @@ +/* Invalid parameter handler for MSVC runtime libraries. + 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 . */ + +#ifndef _MSVC_INVAL_H +#define _MSVC_INVAL_H + +/* With MSVC runtime libraries with the "invalid parameter handler" concept, + functions like fprintf(), dup2(), or close() crash when the caller passes + an invalid argument. But POSIX wants error codes (such as EINVAL or EBADF) + instead. + This file defines macros that turn such an invalid parameter notification + into a non-local exit. An error code can then be produced at the target + of this exit. You can thus write code like + + TRY_MSVC_INVAL + { + + } + CATCH_MSVC_INVAL + { + + } + DONE_MSVC_INVAL; + + This entire block expands to a single statement. + + The handling of invalid parameters can be done in three ways: + + * The default way, which is reasonable for programs (not libraries): + AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [DEFAULT_HANDLING]) + + * The way for libraries that make "hairy" calls (like close(-1), or + fclose(fp) where fileno(fp) is closed, or simply getdtablesize()): + AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [HAIRY_LIBRARY_HANDLING]) + + * The way for libraries that make no "hairy" calls: + AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [SANE_LIBRARY_HANDLING]) + */ + +#define DEFAULT_HANDLING 0 +#define HAIRY_LIBRARY_HANDLING 1 +#define SANE_LIBRARY_HANDLING 2 + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \ + && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING) +/* A native Windows platform with the "invalid parameter handler" concept, + and either DEFAULT_HANDLING or HAIRY_LIBRARY_HANDLING. */ + +# if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING +/* Default handling. */ + +# ifdef __cplusplus +extern "C" { +# endif + +/* Ensure that the invalid parameter handler in installed that just returns. + Because we assume no other part of the program installs a different + invalid parameter handler, this solution is multithread-safe. */ +extern void gl_msvc_inval_ensure_handler (void); + +# ifdef __cplusplus +} +# endif + +# define TRY_MSVC_INVAL \ + do \ + { \ + gl_msvc_inval_ensure_handler (); \ + if (1) +# define CATCH_MSVC_INVAL \ + else +# define DONE_MSVC_INVAL \ + } \ + while (0) + +# else +/* Handling for hairy libraries. */ + +# include + +/* 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"), + - 0, 1, 2, ..., used to distinguish different status codes from the + same API. */ +# define STATUS_GNULIB_INVALID_PARAMETER (0xE0000000 + 0x474E550 + 0) + +# 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 +extern "C" { +# endif + +/* Ensure that the invalid parameter handler in installed that raises a + software exception with code STATUS_GNULIB_INVALID_PARAMETER. + Because we assume no other part of the program installs a different + invalid parameter handler, this solution is multithread-safe. */ +extern void gl_msvc_inval_ensure_handler (void); + +# ifdef __cplusplus +} +# endif + +# define TRY_MSVC_INVAL \ + do \ + { \ + gl_msvc_inval_ensure_handler (); \ + __try +# define CATCH_MSVC_INVAL \ + __except (GetExceptionCode () == STATUS_GNULIB_INVALID_PARAMETER \ + ? EXCEPTION_EXECUTE_HANDLER \ + : EXCEPTION_CONTINUE_SEARCH) +# define DONE_MSVC_INVAL \ + } \ + while (0) + +# else +/* Any compiler. + We can only use setjmp/longjmp. */ + +# include + +# ifdef __cplusplus +extern "C" { +# endif + +struct gl_msvc_inval_per_thread +{ + /* The restart that will resume execution at the code between + CATCH_MSVC_INVAL and DONE_MSVC_INVAL. It is enabled only between + TRY_MSVC_INVAL and CATCH_MSVC_INVAL. */ + jmp_buf restart; + + /* Tells whether the contents of restart is valid. */ + int restart_valid; +}; + +/* Ensure that the invalid parameter handler in installed that passes + control to the gl_msvc_inval_restart if it is valid, or raises a + software exception with code STATUS_GNULIB_INVALID_PARAMETER otherwise. + Because we assume no other part of the program installs a different + invalid parameter handler, this solution is multithread-safe. */ +extern void gl_msvc_inval_ensure_handler (void); + +/* Return a pointer to the per-thread data for the current thread. */ +extern struct gl_msvc_inval_per_thread *gl_msvc_inval_current (void); + +# ifdef __cplusplus +} +# endif + +# define TRY_MSVC_INVAL \ + do \ + { \ + struct gl_msvc_inval_per_thread *msvc_inval_current; \ + gl_msvc_inval_ensure_handler (); \ + msvc_inval_current = gl_msvc_inval_current (); \ + /* First, initialize gl_msvc_inval_restart. */ \ + if (setjmp (msvc_inval_current->restart) == 0) \ + { \ + /* Then, mark it as valid. */ \ + msvc_inval_current->restart_valid = 1; +# define CATCH_MSVC_INVAL \ + /* Execution completed. \ + Mark gl_msvc_inval_restart as invalid. */ \ + msvc_inval_current->restart_valid = 0; \ + } \ + else \ + { \ + /* Execution triggered an invalid parameter notification. \ + Mark gl_msvc_inval_restart as invalid. */ \ + msvc_inval_current->restart_valid = 0; +# define DONE_MSVC_INVAL \ + } \ + } \ + while (0) + +# endif + +# endif + +#else +/* A platform that does not need to the invalid parameter handler, + or when SANE_LIBRARY_HANDLING is desired. */ + +/* The braces here avoid GCC warnings like + "warning: suggest explicit braces to avoid ambiguous 'else'". */ +# define TRY_MSVC_INVAL \ + do \ + { \ + if (1) +# define CATCH_MSVC_INVAL \ + else +# define DONE_MSVC_INVAL \ + } \ + while (0) + +#endif + +#endif /* _MSVC_INVAL_H */ diff --git a/lib/msvc-nothrow.c b/lib/msvc-nothrow.c new file mode 100644 index 0000000..aa06964 --- /dev/null +++ b/lib/msvc-nothrow.c @@ -0,0 +1,51 @@ +/* Wrappers that don't throw invalid parameter notifications + with MSVC runtime libraries. + 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 . */ + +#include + +/* Specification. */ +#include "msvc-nothrow.h" + +/* 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 + +#undef _get_osfhandle + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +intptr_t +_gl_nothrow_get_osfhandle (int fd) +{ + intptr_t result; + + TRY_MSVC_INVAL + { + result = _get_osfhandle (fd); + } + CATCH_MSVC_INVAL + { + result = (intptr_t) INVALID_HANDLE_VALUE; + } + DONE_MSVC_INVAL; + + return result; +} +#endif diff --git a/lib/msvc-nothrow.h b/lib/msvc-nothrow.h new file mode 100644 index 0000000..5345155 --- /dev/null +++ b/lib/msvc-nothrow.h @@ -0,0 +1,43 @@ +/* Wrappers that don't throw invalid parameter notifications + with MSVC runtime libraries. + 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 . */ + +#ifndef _MSVC_NOTHROW_H +#define _MSVC_NOTHROW_H + +/* With MSVC runtime libraries with the "invalid parameter handler" concept, + functions like fprintf(), dup2(), or close() crash when the caller passes + an invalid argument. But POSIX wants error codes (such as EINVAL or EBADF) + instead. + This file defines wrappers that turn such an invalid parameter notification + into an error code. */ + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* Get original declaration of _get_osfhandle. */ +# include + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER + +/* Override _get_osfhandle. */ +extern intptr_t _gl_nothrow_get_osfhandle (int fd); +# define _get_osfhandle _gl_nothrow_get_osfhandle + +# endif + +#endif + +#endif /* _MSVC_NOTHROW_H */ diff --git a/lib/nanosleep.c b/lib/nanosleep.c new file mode 100644 index 0000000..446794e --- /dev/null +++ b/lib/nanosleep.c @@ -0,0 +1,195 @@ +/* Provide a replacement for the POSIX nanosleep function. + + Copyright (C) 1999-2000, 2002, 2004-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 for the native Windows part */ + +#include + +#include + +#include "intprops.h" +#include "verify.h" + +#include +#include +#include +#include +#include + +#include + +#include + + +enum { BILLION = 1000 * 1000 * 1000 }; + +#if HAVE_BUG_BIG_NANOSLEEP + +int +nanosleep (const struct timespec *requested_delay, + struct timespec *remaining_delay) +# undef nanosleep +{ + /* nanosleep mishandles large sleeps due to internal overflow problems. + The worst known case of this is Linux 2.6.9 with glibc 2.3.4, which + can't sleep more than 24.85 days (2^31 milliseconds). Similarly, + cygwin 1.5.x, which can't sleep more than 49.7 days (2^32 milliseconds). + Solve this by breaking the sleep up into smaller chunks. */ + + if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) + { + errno = EINVAL; + return -1; + } + + { + /* Verify that time_t is large enough. */ + verify (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60); + const time_t limit = 24 * 24 * 60 * 60; + time_t seconds = requested_delay->tv_sec; + struct timespec intermediate; + intermediate.tv_nsec = requested_delay->tv_nsec; + + while (limit < seconds) + { + int result; + intermediate.tv_sec = limit; + result = nanosleep (&intermediate, remaining_delay); + seconds -= limit; + if (result) + { + if (remaining_delay) + remaining_delay->tv_sec += seconds; + return result; + } + intermediate.tv_nsec = 0; + } + intermediate.tv_sec = seconds; + return nanosleep (&intermediate, remaining_delay); + } +} + +#elif defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows platforms. */ + +# define WIN32_LEAN_AND_MEAN +# include + +/* The Windows API function Sleep() has a resolution of about 15 ms and takes + at least 5 ms to execute. We use this function for longer time periods. + Additionally, we use busy-looping over short time periods, to get a + resolution of about 0.01 ms. In order to measure such short timespans, + we use the QueryPerformanceCounter() function. */ + +int +nanosleep (const struct timespec *requested_delay, + struct timespec *remaining_delay) +{ + static bool initialized; + /* Number of performance counter increments per nanosecond, + or zero if it could not be determined. */ + static double ticks_per_nanosecond; + + if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) + { + errno = EINVAL; + return -1; + } + + /* For requested delays of one second or more, 15ms resolution is + sufficient. */ + if (requested_delay->tv_sec == 0) + { + if (!initialized) + { + /* Initialize ticks_per_nanosecond. */ + LARGE_INTEGER ticks_per_second; + + if (QueryPerformanceFrequency (&ticks_per_second)) + ticks_per_nanosecond = + (double) ticks_per_second.QuadPart / 1000000000.0; + + initialized = true; + } + if (ticks_per_nanosecond) + { + /* QueryPerformanceFrequency worked. We can use + QueryPerformanceCounter. Use a combination of Sleep and + busy-looping. */ + /* Number of milliseconds to pass to the Sleep function. + Since Sleep can take up to 8 ms less or 8 ms more than requested + (or maybe more if the system is loaded), we subtract 10 ms. */ + int sleep_millis = (int) requested_delay->tv_nsec / 1000000 - 10; + /* Determine how many ticks to delay. */ + LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond; + /* Start. */ + LARGE_INTEGER counter_before; + if (QueryPerformanceCounter (&counter_before)) + { + /* Wait until the performance counter has reached this value. + We don't need to worry about overflow, because the performance + counter is reset at reboot, and with a frequency of 3.6E6 + ticks per second 63 bits suffice for over 80000 years. */ + LONGLONG wait_until = counter_before.QuadPart + wait_ticks; + /* Use Sleep for the longest part. */ + if (sleep_millis > 0) + Sleep (sleep_millis); + /* Busy-loop for the rest. */ + for (;;) + { + LARGE_INTEGER counter_after; + if (!QueryPerformanceCounter (&counter_after)) + /* QueryPerformanceCounter failed, but succeeded earlier. + Should not happen. */ + break; + if (counter_after.QuadPart >= wait_until) + /* The requested time has elapsed. */ + break; + } + goto done; + } + } + } + /* Implementation for long delays and as fallback. */ + Sleep (requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000); + + done: + /* Sleep is not interruptible. So there is no remaining delay. */ + if (remaining_delay != NULL) + { + remaining_delay->tv_sec = 0; + remaining_delay->tv_nsec = 0; + } + return 0; +} + +#else +/* Other platforms lacking nanosleep. + It's not clear whether these are still practical porting targets. + For now, just fall back on pselect. */ + +/* Suspend execution for at least *REQUESTED_DELAY seconds. The + *REMAINING_DELAY part isn't implemented yet. */ + +int +nanosleep (const struct timespec *requested_delay, + struct timespec *remaining_delay) +{ + return pselect (0, NULL, NULL, NULL, requested_delay, NULL); +} +#endif diff --git a/lib/netdb.in.h b/lib/netdb.in.h new file mode 100644 index 0000000..e05cf4b --- /dev/null +++ b/lib/netdb.in.h @@ -0,0 +1,295 @@ +/* Provide a netdb.h header file for systems lacking it (read: MinGW). + Copyright (C) 2008-2022 Free Software Foundation, Inc. + Written by Simon Josefsson. + + 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 . */ + +/* This file is supposed to be used on platforms that lack . + It is intended to provide definitions and prototypes needed by an + application. */ + +#ifndef _@GUARD_PREFIX@_NETDB_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if @HAVE_NETDB_H@ + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_NETDB_H@ + +#endif + +#ifndef _@GUARD_PREFIX@_NETDB_H +#define _@GUARD_PREFIX@_NETDB_H + +/* Get definitions such as 'socklen_t' on IRIX 6.5 and OSF/1 4.0 and + 'struct hostent' on MinGW. */ +#include + +/* 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. */ + +/* Declarations for a platform that lacks , or where it is + incomplete. */ + +#if @GNULIB_GETADDRINFO@ + +# if !@HAVE_STRUCT_ADDRINFO@ + +# ifdef __cplusplus +extern "C" { +# endif + +# if !GNULIB_defined_struct_addrinfo +/* Structure to contain information about address of a service provider. */ +struct addrinfo +{ + int ai_flags; /* Input flags. */ + int ai_family; /* Protocol family for socket. */ + int ai_socktype; /* Socket type. */ + int ai_protocol; /* Protocol for socket. */ + socklen_t ai_addrlen; /* Length of socket address. */ + struct sockaddr *ai_addr; /* Socket address for socket. */ + char *ai_canonname; /* Canonical name for service location. */ + struct addrinfo *ai_next; /* Pointer to next in list. */ +}; +# define GNULIB_defined_struct_addrinfo 1 +# endif + +# ifdef __cplusplus +} +# endif + +# endif + +/* Possible values for 'ai_flags' field in 'addrinfo' structure. */ +# ifndef AI_PASSIVE +# define AI_PASSIVE 0x0001 /* Socket address is intended for 'bind'. */ +# endif +# ifndef AI_CANONNAME +# define AI_CANONNAME 0x0002 /* Request for canonical name. */ +# endif +# ifndef AI_NUMERICSERV +# define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */ +# endif + +# if 0 +# define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */ +# endif + +/* These symbolic constants are required to be present by POSIX, but + our getaddrinfo replacement doesn't use them (yet). Setting them + to 0 on systems that doesn't have them avoids causing problems for + system getaddrinfo implementations that would be confused by + unknown values. */ +# ifndef AI_V4MAPPED +# define AI_V4MAPPED 0 /* 0x0008: IPv4 mapped addresses are acceptable. */ +# endif +# ifndef AI_ALL +# define AI_ALL 0 /* 0x0010: Return IPv4 mapped and IPv6 addresses. */ +# endif +# ifndef AI_ADDRCONFIG +# define AI_ADDRCONFIG 0 /* 0x0020: Use configuration of this host to choose + returned address type. */ +# endif + +/* Error values for 'getaddrinfo' function. */ +# ifndef EAI_BADFLAGS +# define EAI_BADFLAGS -1 /* Invalid value for 'ai_flags' field. */ +# define EAI_NONAME -2 /* NAME or SERVICE is unknown. */ +# define EAI_AGAIN -3 /* Temporary failure in name resolution. */ +# define EAI_FAIL -4 /* Non-recoverable failure in name res. */ +# define EAI_NODATA -5 /* No address associated with NAME. */ +# define EAI_FAMILY -6 /* 'ai_family' not supported. */ +# define EAI_SOCKTYPE -7 /* 'ai_socktype' not supported. */ +# define EAI_SERVICE -8 /* SERVICE not supported for 'ai_socktype'. */ +# define EAI_MEMORY -10 /* Memory allocation failure. */ +# endif + +/* Since EAI_NODATA is deprecated by RFC3493, some systems (at least + FreeBSD, which does define EAI_BADFLAGS) have removed the definition + in favor of EAI_NONAME. */ +# if !defined EAI_NODATA && defined EAI_NONAME +# define EAI_NODATA EAI_NONAME +# endif + +# ifndef EAI_OVERFLOW +/* Not defined on mingw32 and Haiku. */ +# define EAI_OVERFLOW -12 /* Argument buffer overflow. */ +# endif +# ifndef EAI_ADDRFAMILY +/* Not defined on mingw32. */ +# define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */ +# endif +# ifndef EAI_SYSTEM +/* Not defined on mingw32. */ +# define EAI_SYSTEM -11 /* System error returned in 'errno'. */ +# endif + +# if 0 +/* The commented out definitions below are not yet implemented in the + GNULIB getaddrinfo() replacement, so are not yet needed. + + If they are restored, be sure to protect the definitions with #ifndef. */ +# ifndef EAI_INPROGRESS +# define EAI_INPROGRESS -100 /* Processing request in progress. */ +# define EAI_CANCELED -101 /* Request canceled. */ +# define EAI_NOTCANCELED -102 /* Request not canceled. */ +# define EAI_ALLDONE -103 /* All requests done. */ +# define EAI_INTR -104 /* Interrupted by a signal. */ +# define EAI_IDN_ENCODE -105 /* IDN encoding failed. */ +# endif +# endif + +/* Translate name of a service location and/or a service name to set of + socket addresses. + 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 +_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); + +/* Free 'addrinfo' structure AI including associated storage. + 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 +_GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai)); +# endif +_GL_CXXALIASWARN (freeaddrinfo); + +# if @REPLACE_GAI_STRERROR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gai_strerror +# define gai_strerror rpl_gai_strerror +# endif +_GL_FUNCDECL_RPL (gai_strerror, const char *, (int ecode)); +_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: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:2008 specification + . */ +_GL_FUNCDECL_SYS (getnameinfo, int, + (const struct sockaddr *restrict sa, socklen_t salen, + char *restrict node, socklen_t nodelen, + char *restrict service, socklen_t servicelen, + int flags) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on glibc systems, the seventh parameter is + unsigned int flags. */ +_GL_CXXALIAS_SYS_CAST (getnameinfo, int, + (const struct sockaddr *restrict sa, socklen_t salen, + char *restrict node, socklen_t nodelen, + char *restrict service, socklen_t servicelen, + int flags)); +_GL_CXXALIASWARN (getnameinfo); + +/* Possible flags for getnameinfo. */ +# ifndef NI_NUMERICHOST +# define NI_NUMERICHOST 1 +# endif +# ifndef NI_NUMERICSERV +# define NI_NUMERICSERV 2 +# endif + +#elif defined GNULIB_POSIXCHECK + +# undef getaddrinfo +# if HAVE_RAW_DECL_GETADDRINFO +_GL_WARN_ON_USE (getaddrinfo, "getaddrinfo is unportable - " + "use gnulib module getaddrinfo for portability"); +# endif + +# undef freeaddrinfo +# if HAVE_RAW_DECL_FREEADDRINFO +_GL_WARN_ON_USE (freeaddrinfo, "freeaddrinfo is unportable - " + "use gnulib module getaddrinfo for portability"); +# endif + +# undef gai_strerror +# if HAVE_RAW_DECL_GAI_STRERROR +_GL_WARN_ON_USE (gai_strerror, "gai_strerror is unportable - " + "use gnulib module getaddrinfo for portability"); +# endif + +# undef getnameinfo +# if HAVE_RAW_DECL_GETNAMEINFO +_GL_WARN_ON_USE (getnameinfo, "getnameinfo is unportable - " + "use gnulib module getaddrinfo for portability"); +# endif + +#endif + +#endif /* _@GUARD_PREFIX@_NETDB_H */ +#endif /* _@GUARD_PREFIX@_NETDB_H */ diff --git a/lib/netinet_in.in.h b/lib/netinet_in.in.h new file mode 100644 index 0000000..e23807c --- /dev/null +++ b/lib/netinet_in.in.h @@ -0,0 +1,47 @@ +/* Substitute for . + 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 . */ + +#ifndef _@GUARD_PREFIX@_NETINET_IN_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if @HAVE_NETINET_IN_H@ + +/* On many platforms, assumes prior inclusion of + . */ +# include + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_NETINET_IN_H@ + +#endif + +#ifndef _@GUARD_PREFIX@_NETINET_IN_H +#define _@GUARD_PREFIX@_NETINET_IN_H + +#if !@HAVE_NETINET_IN_H@ + +/* A platform that lacks . */ + +# include + +#endif + +#endif /* _@GUARD_PREFIX@_NETINET_IN_H */ +#endif /* _@GUARD_PREFIX@_NETINET_IN_H */ diff --git a/lib/nl_langinfo-lock.c b/lib/nl_langinfo-lock.c new file mode 100644 index 0000000..c36882d --- /dev/null +++ b/lib/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/lib/nl_langinfo.c b/lib/nl_langinfo.c new file mode 100644 index 0000000..3fa4782 --- /dev/null +++ b/lib/nl_langinfo.c @@ -0,0 +1,572 @@ +/* nl_langinfo() replacement: query locale dependent information. + + 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 +#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. */ + +# 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) +{ + switch (item) + { +# if GNULIB_defined_CODESET + case CODESET: + return ctype_codeset (); +# endif +# if GNULIB_defined_T_FMT_AMPM + case T_FMT_AMPM: + 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 (char *) ""; + case ERA_D_FMT: + /* The %Ex conversion in strftime behaves like %x if the locale does not + have an alternative time format. */ + item = D_FMT; + break; + case ERA_D_T_FMT: + /* The %Ec conversion in strftime behaves like %c if the locale does not + have an alternative time format. */ + item = D_T_FMT; + break; + case ERA_T_FMT: + /* The %EX conversion in strftime behaves like %X if the locale does not + have an alternative time format. */ + item = T_FMT; + break; + case ALT_DIGITS: + /* The format is not standardized. In glibc it is a sequence of 10 + strings, appended in memory. */ + 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 (char *) "^[yY]"; + case NOEXPR: + return (char *) "^[nN]"; +# endif + default: + break; + } + return nl_langinfo_with_lock (item); +} + +#else + +/* Provide nl_langinfo from scratch, either for native MS-Windows, or + for old Unix platforms without locales, such as Linux libc5 or + BeOS. */ + +# 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: + { + char *codeset = ctype_codeset (); + if (*codeset) + return codeset; + } +# ifdef __BEOS__ + return (char *) "UTF-8"; +# else + 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 (char *) "%a %b %e %H:%M:%S %Y"; + case D_FMT: + case ERA_D_FMT: + return (char *) "%m/%d/%y"; + case T_FMT: + case ERA_T_FMT: + return (char *) "%H:%M:%S"; + case T_FMT_AMPM: + return (char *) "%I:%M:%S %p"; + case AM_STR: + { + static char result[80]; + if (!strftime (buf, sizeof result, "%p", &tmm)) + return (char *) "AM"; + strcpy (result, buf); + return result; + } + case PM_STR: + { + 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: + case DAY_2: + case DAY_3: + case DAY_4: + case DAY_5: + case DAY_6: + case DAY_7: + { + 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: + case ABDAY_2: + case ABDAY_3: + case ABDAY_4: + case ABDAY_5: + case ABDAY_6: + case ABDAY_7: + { + 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: + case ABMON_2: + case ABMON_3: + case ABMON_4: + case ABMON_5: + case ABMON_6: + case ABMON_7: + case ABMON_8: + case ABMON_9: + case ABMON_10: + case ABMON_11: + case ABMON_12: + { + 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 (char *) ""; + case ALT_DIGITS: + return (char *) "\0\0\0\0\0\0\0\0\0\0"; + /* nl_langinfo items of the LC_MONETARY category. */ + case CRNCYSTR: + 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 (char *) "^[yY]"; + case NOEXPR: + return (char *) "^[nN]"; + default: + return (char *) ""; + } +} + +#endif diff --git a/lib/open.c b/lib/open.c new file mode 100644 index 0000000..170bff1 --- /dev/null +++ b/lib/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/lib/openat-die.c b/lib/openat-die.c new file mode 100644 index 0000000..486d06c --- /dev/null +++ b/lib/openat-die.c @@ -0,0 +1,62 @@ +/* Report a save- or restore-cwd failure in our openat replacement and then exit. + + 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 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 + +#include "openat.h" + +#include + +#ifndef GNULIB_LIBPOSIX +# include "error.h" +#endif + +#include "exitfail.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +_Noreturn void +openat_save_fail (int errnum) +{ +#ifndef GNULIB_LIBPOSIX + error (exit_failure, errnum, + _("unable to record current working directory")); +#endif + /* _Noreturn cannot be applied to error, since it returns + when its first argument is 0. To help compilers understand that this + function does not return, call abort. Also, the abort is a + safety feature if exit_failure is 0 (which shouldn't happen). */ + abort (); +} + + +/* Exit with an error about failure to restore the working directory + during an openat emulation. The caller must ensure that fd 2 is + not a just-opened fd, even when openat_safer is not in use. */ + +_Noreturn void +openat_restore_fail (int errnum) +{ +#ifndef GNULIB_LIBPOSIX + error (exit_failure, errnum, + _("failed to return to initial working directory")); +#endif + + /* As above. */ + abort (); +} diff --git a/lib/openat-priv.h b/lib/openat-priv.h new file mode 100644 index 0000000..5d60810 --- /dev/null +++ b/lib/openat-priv.h @@ -0,0 +1,64 @@ +/* Internals for openat-like functions. + + 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 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 _GL_HEADER_OPENAT_PRIV +#define _GL_HEADER_OPENAT_PRIV + +#include +#include +#include + +/* Maximum number of bytes that it is safe to allocate as a single + array on the stack, and that is known as a compile-time constant. + The assumption is that we'll touch the array very quickly, or a + temporary very near the array, provoking an out-of-memory trap. On + some operating systems, there is only one guard page for the stack, + and a page size can be as small as 4096 bytes. Subtract 64 in the + hope that this will let the compiler touch a nearby temporary and + provoke a trap. */ +#define SAFER_ALLOCA_MAX (4096 - 64) + +#define SAFER_ALLOCA(m) ((m) < SAFER_ALLOCA_MAX ? (m) : SAFER_ALLOCA_MAX) + +#if defined PATH_MAX +# define OPENAT_BUFFER_SIZE SAFER_ALLOCA (PATH_MAX) +#elif defined _XOPEN_PATH_MAX +# define OPENAT_BUFFER_SIZE SAFER_ALLOCA (_XOPEN_PATH_MAX) +#else +# define OPENAT_BUFFER_SIZE SAFER_ALLOCA (1024) +#endif + +char *openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file); + +/* Trying to access a BUILD_PROC_NAME file will fail on systems without + /proc support, and even on systems *with* ProcFS support. Return + nonzero if the failure may be legitimate, e.g., because /proc is not + readable, or the particular .../fd/N directory is not present. */ +#define EXPECTED_ERRNO(Errno) \ + ((Errno) == ENOTDIR || (Errno) == ENOENT \ + || (Errno) == EPERM || (Errno) == EACCES \ + || (Errno) == ENOSYS /* Solaris 8 */ \ + || (Errno) == EOPNOTSUPP /* FreeBSD */) + +/* Wrapper function shared among linkat and renameat. */ +int at_func2 (int fd1, char const *file1, + int fd2, char const *file2, + int (*func) (char const *file1, char const *file2)); + +#endif /* _GL_HEADER_OPENAT_PRIV */ diff --git a/lib/openat-proc.c b/lib/openat-proc.c new file mode 100644 index 0000000..3bacf7d --- /dev/null +++ b/lib/openat-proc.c @@ -0,0 +1,135 @@ +/* Create /proc/self/fd-related names for subfiles of open directories. + + Copyright (C) 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 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 Paul Eggert. */ + +#include + +#include "openat-priv.h" + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef __KLIBC__ +# include +#endif + +#include "intprops.h" + +/* Set BUF to the name of the subfile of the directory identified by + FD, where the subfile is named FILE. If successful, return BUF if + the result fits in BUF, dynamically allocated memory otherwise. + Return NULL (setting errno) on error. */ +char * +openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) +{ + char *result = buf; + int dirlen; + + /* Make sure the caller gets ENOENT when appropriate. */ + if (!*file) + { + buf[0] = '\0'; + return buf; + } + +#ifndef __KLIBC__ +# define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/" + { + enum { + PROC_SELF_FD_DIR_SIZE_BOUND + = (sizeof PROC_SELF_FD_FORMAT - (sizeof "%d" - 1) + + INT_STRLEN_BOUND (int)) + }; + + static int proc_status = 0; + if (! proc_status) + { + /* Set PROC_STATUS to a positive value if /proc/self/fd is + reliable, and a negative value otherwise. Solaris 10 + /proc/self/fd mishandles "..", and any file name might expand + to ".." after symbolic link expansion, so avoid /proc/self/fd + if it mishandles "..". Solaris 10 has openat, but this + problem is exhibited on code that built on Solaris 8 and + running on Solaris 10. */ + + int proc_self_fd = + open ("/proc/self/fd", + O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK | O_CLOEXEC); + if (proc_self_fd < 0) + proc_status = -1; + else + { + /* Detect whether /proc/self/fd/%i/../fd exists, where %i is the + number of a file descriptor open on /proc/self/fd. On Linux, + that name resolves to /proc/self/fd, which was opened above. + However, on Solaris, it may resolve to /proc/self/fd/fd, which + cannot exist, since all names in /proc/self/fd are numeric. */ + char dotdot_buf[PROC_SELF_FD_DIR_SIZE_BOUND + sizeof "../fd" - 1]; + sprintf (dotdot_buf, PROC_SELF_FD_FORMAT "../fd", proc_self_fd); + proc_status = access (dotdot_buf, F_OK) ? -1 : 1; + close (proc_self_fd); + } + } + + if (proc_status < 0) + return NULL; + else + { + size_t bufsize = PROC_SELF_FD_DIR_SIZE_BOUND + strlen (file); + if (OPENAT_BUFFER_SIZE < bufsize) + { + result = malloc (bufsize); + if (! result) + return NULL; + } + + dirlen = sprintf (result, PROC_SELF_FD_FORMAT, fd); + } + } +#else + /* OS/2 kLIBC provides a function to retrieve a path from a fd. */ + { + char dir[_MAX_PATH]; + size_t bufsize; + + if (__libc_Back_ioFHToPath (fd, dir, sizeof dir)) + return NULL; + + dirlen = strlen (dir); + bufsize = dirlen + 1 + strlen (file) + 1; /* 1 for '/', 1 for null */ + if (OPENAT_BUFFER_SIZE < bufsize) + { + result = malloc (bufsize); + if (! result) + return NULL; + } + + strcpy (result, dir); + result[dirlen++] = '/'; + } +#endif + + strcpy (result + dirlen, file); + return result; +} diff --git a/lib/openat.c b/lib/openat.c new file mode 100644 index 0000000..52aab19 --- /dev/null +++ b/lib/openat.c @@ -0,0 +1,312 @@ +/* provide a replacement openat function + Copyright (C) 2004-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 */ + +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_openat doesn't recurse to + rpl_openat. */ +#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 + +#if HAVE_OPENAT +static int +orig_openat (int fd, char const *filename, int flags, mode_t mode) +{ + return openat (fd, filename, flags, mode); +} +#endif + +/* 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 "openat.h" + +#include "cloexec.h" + +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_OPENAT + +/* Like openat, but support O_CLOEXEC and work around Solaris 9 bugs + with trailing slash. */ +int +rpl_openat (int dfd, char const *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 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_openat (dfd, 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_openat (dfd, filename, flags & ~O_CLOEXEC, mode); + have_cloexec = -1; + } + } + if (have_cloexec < 0 && 0 <= fd) + set_cloexec_flag (fd, true); + } + + +# 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 + + return fd; +} + +#else /* !HAVE_OPENAT */ + +# include "filename.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ +# include "openat-priv.h" +# include "save-cwd.h" + +/* Replacement for Solaris' openat function. + + First, try to simulate it via open ("/proc/self/fd/FD/FILE"). + Failing that, simulate it by doing save_cwd/fchdir/open/restore_cwd. + If either the save_cwd or the restore_cwd fails (relatively unlikely), + then give a diagnostic and exit nonzero. + Otherwise, upon failure, set errno and return -1, as openat does. + Upon successful completion, return a file descriptor. */ +int +openat (int fd, char const *file, int flags, ...) +{ + mode_t 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); + } + + return openat_permissive (fd, file, flags, mode, NULL); +} + +/* Like openat (FD, FILE, FLAGS, MODE), but if CWD_ERRNO is + nonnull, set *CWD_ERRNO to an errno value if unable to save + or restore the initial working directory. This is needed only + the first time remove.c's remove_dir opens a command-line + directory argument. + + If a previous attempt to restore the current working directory + failed, then we must not even try to access a '.'-relative name. + It is the caller's responsibility not to call this function + in that case. */ + +int +openat_permissive (int fd, char const *file, int flags, mode_t mode, + int *cwd_errno) +{ + struct saved_cwd saved_cwd; + int saved_errno; + int err; + bool save_ok; + + if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) + return open (file, flags, mode); + + { + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, file); + if (proc_file) + { + int open_result = open (proc_file, flags, mode); + int open_errno = errno; + if (proc_file != buf) + free (proc_file); + /* If the syscall succeeds, or if it fails with an unexpected + errno value, then return right away. Otherwise, fall through + and resort to using save_cwd/restore_cwd. */ + if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) + { + errno = open_errno; + return open_result; + } + } + } + + save_ok = (save_cwd (&saved_cwd) == 0); + if (! save_ok) + { + if (! cwd_errno) + openat_save_fail (errno); + *cwd_errno = errno; + } + if (0 <= fd && fd == saved_cwd.desc) + { + /* If saving the working directory collides with the user's + requested fd, then the user's fd must have been closed to + begin with. */ + free_cwd (&saved_cwd); + errno = EBADF; + return -1; + } + + err = fchdir (fd); + saved_errno = errno; + + if (! err) + { + err = open (file, flags, mode); + saved_errno = errno; + if (save_ok && restore_cwd (&saved_cwd) != 0) + { + if (! cwd_errno) + { + /* Don't write a message to just-created fd 2. */ + saved_errno = errno; + if (err == STDERR_FILENO) + close (err); + openat_restore_fail (saved_errno); + } + *cwd_errno = errno; + } + } + + free_cwd (&saved_cwd); + errno = saved_errno; + return err; +} + +/* Return true if our openat implementation must resort to + using save_cwd and restore_cwd. */ +bool +openat_needs_fchdir (void) +{ + bool needs_fchdir = true; + int fd = open ("/", O_SEARCH | O_CLOEXEC); + + if (0 <= fd) + { + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) + { + needs_fchdir = false; + if (proc_file != buf) + free (proc_file); + } + close (fd); + } + + return needs_fchdir; +} + +#endif /* !HAVE_OPENAT */ diff --git a/lib/openat.h b/lib/openat.h new file mode 100644 index 0000000..5c8ff90 --- /dev/null +++ b/lib/openat.h @@ -0,0 +1,123 @@ +/* provide a replacement openat function + Copyright (C) 2004-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 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 _GL_HEADER_OPENAT +#define _GL_HEADER_OPENAT + +#include + +#include +#include +#include +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN + +#if !HAVE_OPENAT + +int openat_permissive (int fd, char const *file, int flags, mode_t mode, + int *cwd_errno); +bool openat_needs_fchdir (void); + +#else + +# define openat_permissive(Fd, File, Flags, Mode, Cwd_errno) \ + openat (Fd, File, Flags, Mode) +# define openat_needs_fchdir() false + +#endif + +_Noreturn void openat_restore_fail (int); +_Noreturn void openat_save_fail (int); + +/* Using these function names makes application code + slightly more readable than it would be with + fchownat (..., 0) or fchownat (..., AT_SYMLINK_NOFOLLOW). */ + +#if GNULIB_CHOWNAT + +# ifndef CHOWNAT_INLINE +# define CHOWNAT_INLINE _GL_INLINE +# endif + +CHOWNAT_INLINE int +chownat (int fd, char const *file, uid_t owner, gid_t group) +{ + return fchownat (fd, file, owner, group, 0); +} + +CHOWNAT_INLINE int +lchownat (int fd, char const *file, uid_t owner, gid_t group) +{ + return fchownat (fd, file, owner, group, AT_SYMLINK_NOFOLLOW); +} + +#endif + +#if GNULIB_CHMODAT + +# ifndef CHMODAT_INLINE +# define CHMODAT_INLINE _GL_INLINE +# endif + +CHMODAT_INLINE int +chmodat (int fd, char const *file, mode_t mode) +{ + return fchmodat (fd, file, mode, 0); +} + +CHMODAT_INLINE int +lchmodat (int fd, char const *file, mode_t mode) +{ + return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW); +} + +#endif + +#if GNULIB_STATAT + +# ifndef STATAT_INLINE +# define STATAT_INLINE _GL_INLINE +# endif + +STATAT_INLINE int +statat (int fd, char const *name, struct stat *st) +{ + return fstatat (fd, name, st, 0); +} + +STATAT_INLINE int +lstatat (int fd, char const *name, struct stat *st) +{ + return fstatat (fd, name, st, AT_SYMLINK_NOFOLLOW); +} + +#endif + +/* For now, there are no wrappers named laccessat or leuidaccessat, + since gnulib doesn't support faccessat(,AT_SYMLINK_NOFOLLOW) and + since access rights on symlinks are of limited utility. Likewise, + wrappers are not provided for accessat or euidaccessat, so as to + avoid dragging in -lgen on some platforms. */ + +_GL_INLINE_HEADER_END + +#endif /* _GL_HEADER_OPENAT */ diff --git a/lib/opendir.c b/lib/opendir.c new file mode 100644 index 0000000..fc6b455 --- /dev/null +++ b/lib/opendir.c @@ -0,0 +1,179 @@ +/* Start reading the entries of a directory. + 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#if HAVE_OPENDIR + +/* Override opendir(), to keep track of the open file descriptors. + Needed because there is a function dirfd(). */ + +#else + +# include + +# include "dirent-private.h" +# include "filename.h" + +#endif + +#if REPLACE_FCHDIR +# include +#endif + +#ifdef __KLIBC__ +# include +# include +#endif + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Don't assume that UNICODE is not defined. */ +# undef WIN32_FIND_DATA +# define WIN32_FIND_DATA WIN32_FIND_DATAA +# undef GetFullPathName +# define GetFullPathName GetFullPathNameA +# undef FindFirstFile +# define FindFirstFile FindFirstFileA +#endif + +DIR * +opendir (const char *dir_name) +{ +#if HAVE_OPENDIR +# undef opendir + DIR *dirp; + + dirp = opendir (dir_name); + if (dirp == NULL) + return NULL; + +# ifdef __KLIBC__ + { + int fd = open (dir_name, O_RDONLY); + if (fd == -1 || _gl_register_dirp_fd (fd, dirp)) + { + int saved_errno = errno; + + close (fd); + closedir (dirp); + + errno = saved_errno; + + return NULL; + } + } +# endif +#else + + char dir_name_mask[MAX_PATH + 1 + 1 + 1]; + int status; + HANDLE current; + WIN32_FIND_DATA entry; + struct gl_directory *dirp; + + if (dir_name[0] == '\0') + { + errno = ENOENT; + return NULL; + } + + /* Make the dir_name absolute, so that we continue reading the same + directory if the current directory changed between this opendir() + call and a subsequent rewinddir() call. */ + if (!GetFullPathName (dir_name, MAX_PATH, dir_name_mask, NULL)) + { + errno = EINVAL; + return NULL; + } + + /* Append the mask. + "*" and "*.*" appear to be equivalent. */ + { + char *p; + + p = dir_name_mask + strlen (dir_name_mask); + if (p > dir_name_mask && !ISSLASH (p[-1])) + *p++ = '\\'; + *p++ = '*'; + *p = '\0'; + } + + /* Start searching the directory. */ + status = -1; + current = FindFirstFile (dir_name_mask, &entry); + if (current == INVALID_HANDLE_VALUE) + { + switch (GetLastError ()) + { + case ERROR_FILE_NOT_FOUND: + status = -2; + break; + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + return NULL; + case ERROR_DIRECTORY: + errno = ENOTDIR; + return NULL; + case ERROR_ACCESS_DENIED: + errno = EACCES; + return NULL; + default: + errno = EIO; + return NULL; + } + } + + /* Allocate the result. */ + dirp = + (struct gl_directory *) + malloc (offsetof (struct gl_directory, dir_name_mask[0]) + + strlen (dir_name_mask) + 1); + if (dirp == NULL) + { + if (current != INVALID_HANDLE_VALUE) + FindClose (current); + errno = ENOMEM; + return NULL; + } + dirp->status = status; + dirp->current = current; + if (status == -1) + memcpy (&dirp->entry, &entry, sizeof (WIN32_FIND_DATA)); + strcpy (dirp->dir_name_mask, dir_name_mask); + +#endif + +#if REPLACE_FCHDIR + { + int fd = dirfd (dirp); + if (0 <= fd && _gl_register_fd (fd, dir_name) != fd) + { + int saved_errno = errno; + closedir (dirp); + errno = saved_errno; + return NULL; + } + } +#endif + + return dirp; +} diff --git a/lib/os2-spawn.c b/lib/os2-spawn.c new file mode 100644 index 0000000..b51c098 --- /dev/null +++ b/lib/os2-spawn.c @@ -0,0 +1,155 @@ +/* Auxiliary functions for the creation of subprocesses. OS/2 kLIBC API. + Copyright (C) 2001, 2003-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 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 "os2-spawn.h" + +/* Get _open_osfhandle(). */ +#include + +#include +#include +#include +#include +#include + +#include "cloexec.h" +#include "error.h" +#include "gettext.h" + +#define _(str) gettext (str) + + +/* Duplicates a file handle, making the copy uninheritable. + Returns -1 for a file handle that is equivalent to closed. */ +static int +dup_noinherit (int fd) +{ + fd = dup_cloexec (fd); + if (fd < 0 && errno == EMFILE) + error (EXIT_FAILURE, errno, _("_open_osfhandle failed")); + + return fd; +} + +/* Returns a file descriptor equivalent to FD, except that the resulting file + descriptor is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. + FD must be open and non-inheritable. The result will be non-inheritable as + well. + If FD < 0, FD itself is returned. */ +static int +fd_safer_noinherit (int fd) +{ + if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) + { + /* The recursion depth is at most 3. */ + int nfd = fd_safer_noinherit (dup_noinherit (fd)); + int saved_errno = errno; + close (fd); + errno = saved_errno; + return nfd; + } + return fd; +} + +int +dup_safer_noinherit (int fd) +{ + return fd_safer_noinherit (dup_noinherit (fd)); +} + +void +undup_safer_noinherit (int tempfd, int origfd) +{ + if (tempfd >= 0) + { + if (dup2 (tempfd, origfd) < 0) + error (EXIT_FAILURE, errno, _("cannot restore fd %d: dup2 failed"), + origfd); + close (tempfd); + } + else + { + /* origfd was closed or open to no handle at all. Set it to a closed + state. This is (nearly) equivalent to the original state. */ + close (origfd); + } +} + +const char ** +prepare_spawn (const char * const *argv, char **mem_to_free) +{ + size_t argc; + const char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = (const char **) malloc ((1 + argc + 1) * sizeof (const char *)); + if (new_argv == NULL) + return NULL; + + /* Add an element upfront that can be used when argv[0] turns out to be a + script, not a program. + On Unix, this would be "/bin/sh". */ + new_argv[0] = "sh.exe"; + + /* Put quoted arguments into the new argument vector. */ + size_t needed_size = 0; + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + const char *quoted_string = (string[0] == '\0' ? "\"\"" : string); + size_t length = strlen (quoted_string); + needed_size += length + 1; + } + + char *mem; + if (needed_size == 0) + mem = NULL; + else + { + mem = (char *) malloc (needed_size); + if (mem == NULL) + { + /* Memory allocation failure. */ + free (new_argv); + errno = ENOMEM; + return NULL; + } + } + *mem_to_free = mem; + + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + new_argv[1 + i] = mem; + const char *quoted_string = (string[0] == '\0' ? "\"\"" : string); + size_t length = strlen (quoted_string); + memcpy (mem, quoted_string, length + 1); + mem += length + 1; + } + new_argv[1 + argc] = NULL; + + return new_argv; +} diff --git a/lib/os2-spawn.h b/lib/os2-spawn.h new file mode 100644 index 0000000..8675a10 --- /dev/null +++ b/lib/os2-spawn.h @@ -0,0 +1,33 @@ +/* Auxiliary functions for the creation of subprocesses. OS/2 kLIBC API. + Copyright (C) 2001, 2003-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 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 _OS2_SPAWN_H +#define _OS2_SPAWN_H + +/* Duplicates a file handle, making the copy uninheritable and ensuring the + result is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. + Returns -1 for a file handle that is equivalent to closed. */ +extern int dup_safer_noinherit (int fd); + +/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD); */ +extern void undup_safer_noinherit (int tempfd, int origfd); + +/* Prepares an argument vector before calling spawn(). */ +extern const char ** prepare_spawn (const char * const *argv, + char **mem_to_free); + +#endif /* _OS2_SPAWN_H */ diff --git a/lib/pathmax.h b/lib/pathmax.h new file mode 100644 index 0000000..19b93d7 --- /dev/null +++ b/lib/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/lib/pipe-safer.c b/lib/pipe-safer.c new file mode 100644 index 0000000..22f8695 --- /dev/null +++ b/lib/pipe-safer.c @@ -0,0 +1,52 @@ +/* Invoke pipe, but avoid some glitches. + 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 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. */ + +#include + +#include "unistd-safer.h" + +#include +#include + +/* Like pipe, but ensure that neither of the file descriptors is + STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO. Fail with ENOSYS on + platforms that lack pipe. */ + +int +pipe_safer (int fd[2]) +{ + if (pipe (fd) == 0) + { + int i; + for (i = 0; i < 2; i++) + { + fd[i] = fd_safer (fd[i]); + if (fd[i] < 0) + { + int saved_errno = errno; + close (fd[1 - i]); + errno = saved_errno; + return -1; + } + } + + return 0; + } + + return -1; +} diff --git a/lib/pipe.c b/lib/pipe.c new file mode 100644 index 0000000..ce909b9 --- /dev/null +++ b/lib/pipe.c @@ -0,0 +1,50 @@ +/* Create a pipe. + 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 . */ + +#include + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows API. */ + +/* Get _pipe(). */ +# include + +/* Get _O_BINARY. */ +# include + +int +pipe (int fd[2]) +{ + /* Mingw changes fd to {-1,-1} on failure, but this violates + http://austingroupbugs.net/view.php?id=467 */ + int tmp[2]; + int result = _pipe (tmp, 4096, _O_BINARY); + if (!result) + { + fd[0] = tmp[0]; + fd[1] = tmp[1]; + } + return result; +} + +#else + +# error "This platform lacks a pipe function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib." + +#endif diff --git a/lib/pipe2-safer.c b/lib/pipe2-safer.c new file mode 100644 index 0000000..3a84c66 --- /dev/null +++ b/lib/pipe2-safer.c @@ -0,0 +1,52 @@ +/* Invoke pipe2, but avoid some glitches. + 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 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 Eric Blake. */ + +#include + +/* Specification. */ +#include "unistd-safer.h" + +#include +#include + +/* Like pipe2, but ensure that neither of the file descriptors is + STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO. */ + +int +pipe2_safer (int fd[2], int flags) +{ + /* This is a generalization of the pipe_safer implementation. */ + if (pipe2 (fd, flags) == 0) + { + int i; + for (i = 0; i < 2; i++) + { + fd[i] = fd_safer_flag (fd[i], flags); + if (fd[i] < 0) + { + int e = errno; + close (fd[1 - i]); + errno = e; + return -1; + } + } + + return 0; + } + return -1; +} diff --git a/lib/pipe2.c b/lib/pipe2.c new file mode 100644 index 0000000..400aff0 --- /dev/null +++ b/lib/pipe2.c @@ -0,0 +1,167 @@ +/* Create a pipe, with specific opening flags. + 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#include "binary-io.h" +#include "verify.h" + +#if GNULIB_defined_O_NONBLOCK +# include "nonblocking.h" +#endif + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows API. */ + +# include + +#endif + +int +pipe2 (int fd[2], int flags) +{ + /* Mingw _pipe() corrupts fd on failure; also, if we succeed at + creating the pipe but later fail at changing fcntl, we want + to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ + int tmp[2]; + tmp[0] = fd[0]; + tmp[1] = fd[1]; + +#if HAVE_PIPE2 +# undef pipe2 + /* Try the system call first, if it exists. (We may be running with a glibc + that has the function but with an older kernel that lacks it.) */ + { + /* Cache the information whether the system call really exists. */ + static int have_pipe2_really; /* 0 = unknown, 1 = yes, -1 = no */ + if (have_pipe2_really >= 0) + { + int result = pipe2 (fd, flags); + if (!(result < 0 && errno == ENOSYS)) + { + have_pipe2_really = 1; + return result; + } + have_pipe2_really = -1; + } + } +#endif + + /* Check the supported flags. */ + if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0) + { + errno = EINVAL; + return -1; + } + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows API. */ + + if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0) + { + fd[0] = tmp[0]; + fd[1] = tmp[1]; + return -1; + } + + /* O_NONBLOCK handling. + On native Windows platforms, O_NONBLOCK is defined by gnulib. Use the + functions defined by the gnulib module 'nonblocking'. */ +# if GNULIB_defined_O_NONBLOCK + if (flags & O_NONBLOCK) + { + if (set_nonblocking_flag (fd[0], true) != 0 + || set_nonblocking_flag (fd[1], true) != 0) + goto fail; + } +# else + { + verify (O_NONBLOCK == 0); + } +# endif + + return 0; + +#else +/* Unix API. */ + + if (pipe (fd) < 0) + return -1; + + /* POSIX + says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on + both fd[0] and fd[1]. */ + + /* O_NONBLOCK handling. + On Unix platforms, O_NONBLOCK is defined by the system. Use fcntl(). */ + if (flags & O_NONBLOCK) + { + int fcntl_flags; + + if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0 + || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1 + || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0 + || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1) + goto fail; + } + + if (flags & O_CLOEXEC) + { + int fcntl_flags; + + if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0 + || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1 + || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0 + || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) + goto fail; + } + +# if O_BINARY + if (flags & O_BINARY) + { + set_binary_mode (fd[1], O_BINARY); + set_binary_mode (fd[0], O_BINARY); + } + else if (flags & O_TEXT) + { + set_binary_mode (fd[1], O_TEXT); + set_binary_mode (fd[0], O_TEXT); + } +# endif + + return 0; + +#endif + +#if GNULIB_defined_O_NONBLOCK || !(defined _WIN32 && ! defined __CYGWIN__) + fail: + { + int saved_errno = errno; + close (fd[0]); + close (fd[1]); + fd[0] = tmp[0]; + fd[1] = tmp[1]; + errno = saved_errno; + return -1; + } +#endif +} diff --git a/lib/printf-args.c b/lib/printf-args.c new file mode 100644 index 0000000..669c24a --- /dev/null +++ b/lib/printf-args.c @@ -0,0 +1,183 @@ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 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 . */ + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + PRINTF_FETCHARGS Name of the function to be defined. + STATIC Set to 'static' to declare the function static. */ + +#ifndef PRINTF_FETCHARGS +# include +#endif + +/* Specification. */ +#ifndef PRINTF_FETCHARGS +# include "printf-args.h" +#endif + +#ifdef STATIC +STATIC +#endif +int +PRINTF_FETCHARGS (va_list args, arguments *a) +{ + size_t i; + argument *ap; + + for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++) + switch (ap->type) + { + case TYPE_SCHAR: + ap->a.a_schar = va_arg (args, /*signed char*/ int); + break; + case TYPE_UCHAR: + ap->a.a_uchar = va_arg (args, /*unsigned char*/ int); + break; + case TYPE_SHORT: + ap->a.a_short = va_arg (args, /*short*/ int); + break; + case TYPE_USHORT: + ap->a.a_ushort = va_arg (args, /*unsigned short*/ int); + break; + case TYPE_INT: + ap->a.a_int = va_arg (args, int); + break; + case TYPE_UINT: + ap->a.a_uint = va_arg (args, unsigned int); + break; + case TYPE_LONGINT: + ap->a.a_longint = va_arg (args, long int); + break; + case TYPE_ULONGINT: + ap->a.a_ulongint = va_arg (args, unsigned long int); + break; + 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; + case TYPE_DOUBLE: + ap->a.a_double = va_arg (args, double); + break; + case TYPE_LONGDOUBLE: + ap->a.a_longdouble = va_arg (args, long double); + break; + case TYPE_CHAR: + ap->a.a_char = va_arg (args, int); + break; +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: + /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by + default argument promotions", this is not the case in mingw32, + where wint_t is 'unsigned short'. */ + ap->a.a_wide_char = + (sizeof (wint_t) < sizeof (int) + ? (wint_t) va_arg (args, int) + : va_arg (args, wint_t)); + break; +#endif + case TYPE_STRING: + ap->a.a_string = va_arg (args, const char *); + /* A null pointer is an invalid argument for "%s", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_string == NULL) + ap->a.a_string = "(NULL)"; + break; +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: + ap->a.a_wide_string = va_arg (args, const wchar_t *); + /* A null pointer is an invalid argument for "%ls", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_wide_string == NULL) + { + static const wchar_t wide_null_string[] = + { + (wchar_t)'(', + (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', + (wchar_t)')', + (wchar_t)0 + }; + ap->a.a_wide_string = wide_null_string; + } + break; +#endif + case TYPE_POINTER: + ap->a.a_pointer = va_arg (args, void *); + break; + case TYPE_COUNT_SCHAR_POINTER: + ap->a.a_count_schar_pointer = va_arg (args, signed char *); + break; + case TYPE_COUNT_SHORT_POINTER: + ap->a.a_count_short_pointer = va_arg (args, short *); + break; + case TYPE_COUNT_INT_POINTER: + ap->a.a_count_int_pointer = va_arg (args, int *); + break; + case TYPE_COUNT_LONGINT_POINTER: + ap->a.a_count_longint_pointer = va_arg (args, long int *); + break; + case TYPE_COUNT_LONGLONGINT_POINTER: + ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); + break; +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case TYPE_U8_STRING: + ap->a.a_u8_string = va_arg (args, const uint8_t *); + /* A null pointer is an invalid argument for "%U", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u8_string == NULL) + { + static const uint8_t u8_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u8_string = u8_null_string; + } + break; + case TYPE_U16_STRING: + ap->a.a_u16_string = va_arg (args, const uint16_t *); + /* A null pointer is an invalid argument for "%lU", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u16_string == NULL) + { + static const uint16_t u16_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u16_string = u16_null_string; + } + break; + case TYPE_U32_STRING: + ap->a.a_u32_string = va_arg (args, const uint32_t *); + /* A null pointer is an invalid argument for "%llU", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u32_string == NULL) + { + static const uint32_t u32_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u32_string = u32_null_string; + } + break; +#endif + default: + /* Unknown type. */ + return -1; + } + return 0; +} diff --git a/lib/printf-args.h b/lib/printf-args.h new file mode 100644 index 0000000..553fe96 --- /dev/null +++ b/lib/printf-args.h @@ -0,0 +1,150 @@ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2006-2007, 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 . */ + +#ifndef _PRINTF_ARGS_H +#define _PRINTF_ARGS_H + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + PRINTF_FETCHARGS Name of the function to be declared. + STATIC Set to 'static' to declare the function static. */ + +/* Default parameters. */ +#ifndef PRINTF_FETCHARGS +# define PRINTF_FETCHARGS printf_fetchargs +#endif + +/* Get size_t. */ +#include + +/* Get wchar_t. */ +#if HAVE_WCHAR_T +# include +#endif + +/* Get wint_t. */ +#if HAVE_WINT_T +# include +#endif + +/* Get va_list. */ +#include + + +/* Argument types */ +typedef enum +{ + TYPE_NONE, + TYPE_SCHAR, + TYPE_UCHAR, + TYPE_SHORT, + TYPE_USHORT, + TYPE_INT, + TYPE_UINT, + TYPE_LONGINT, + TYPE_ULONGINT, + TYPE_LONGLONGINT, + TYPE_ULONGLONGINT, + TYPE_DOUBLE, + TYPE_LONGDOUBLE, + TYPE_CHAR, +#if HAVE_WINT_T + TYPE_WIDE_CHAR, +#endif + TYPE_STRING, +#if HAVE_WCHAR_T + TYPE_WIDE_STRING, +#endif + TYPE_POINTER, + TYPE_COUNT_SCHAR_POINTER, + TYPE_COUNT_SHORT_POINTER, + TYPE_COUNT_INT_POINTER, + TYPE_COUNT_LONGINT_POINTER, + TYPE_COUNT_LONGLONGINT_POINTER +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ +, TYPE_U8_STRING +, TYPE_U16_STRING +, TYPE_U32_STRING +#endif +} arg_type; + +/* Polymorphic argument */ +typedef struct +{ + arg_type type; + union + { + signed char a_schar; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long int a_longint; + unsigned long int a_ulongint; + long long int a_longlongint; + unsigned long long int a_ulonglongint; + float a_float; + double a_double; + long double a_longdouble; + int a_char; +#if HAVE_WINT_T + wint_t a_wide_char; +#endif + const char* a_string; +#if HAVE_WCHAR_T + const wchar_t* a_wide_string; +#endif + void* a_pointer; + signed char * a_count_schar_pointer; + short * a_count_short_pointer; + int * a_count_int_pointer; + long int * a_count_longint_pointer; + long long int * a_count_longlongint_pointer; +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + const uint8_t * a_u8_string; + const uint16_t * a_u16_string; + const uint32_t * a_u32_string; +#endif + } + a; +} +argument; + +/* Number of directly allocated arguments (no malloc() needed). */ +#define N_DIRECT_ALLOC_ARGUMENTS 7 + +typedef struct +{ + size_t count; + argument *arg; + argument direct_alloc_arg[N_DIRECT_ALLOC_ARGUMENTS]; +} +arguments; + + +/* Fetch the arguments, putting them into a. */ +#ifdef STATIC +STATIC +#else +extern +#endif +int PRINTF_FETCHARGS (va_list args, arguments *a); + +#endif /* _PRINTF_ARGS_H */ diff --git a/lib/printf-parse.c b/lib/printf-parse.c new file mode 100644 index 0000000..aab02dc --- /dev/null +++ b/lib/printf-parse.c @@ -0,0 +1,623 @@ +/* Formatted output to strings. + Copyright (C) 1999-2000, 2002-2003, 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 . */ + +/* This file can be parametrized with the following macros: + CHAR_T The element type of the format string. + CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters + in the format string are ASCII. + DIRECTIVE Structure denoting a format directive. + Depends on CHAR_T. + DIRECTIVES Structure denoting the set of format directives of a + format string. Depends on CHAR_T. + PRINTF_PARSE Function that parses a format string. + Depends on CHAR_T. + STATIC Set to 'static' to declare the function static. + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ + +#ifndef PRINTF_PARSE +# include +#endif + +/* Specification. */ +#ifndef PRINTF_PARSE +# include "printf-parse.h" +#endif + +/* Default parameters. */ +#ifndef PRINTF_PARSE +# define PRINTF_PARSE printf_parse +# define CHAR_T char +# define DIRECTIVE char_directive +# define DIRECTIVES char_directives +#endif + +/* Get size_t, NULL. */ +#include + +/* Get intmax_t. */ +#include + +/* malloc(), realloc(), free(). */ +#include + +/* memcpy(). */ +#include + +/* errno. */ +#include + +/* Checked size_t computations. */ +#include "xsize.h" + +#if CHAR_T_ONLY_ASCII +/* c_isascii(). */ +# include "c-ctype.h" +#endif + +#ifdef STATIC +STATIC +#endif +int +PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) +{ + const CHAR_T *cp = format; /* pointer into format */ + size_t arg_posn = 0; /* number of regular arguments consumed */ + size_t d_allocated; /* allocated elements of d->dir */ + size_t a_allocated; /* allocated elements of a->arg */ + size_t max_width_length = 0; + size_t max_precision_length = 0; + + d->count = 0; + d_allocated = N_DIRECT_ALLOC_DIRECTIVES; + d->dir = d->direct_alloc_dir; + + a->count = 0; + a_allocated = N_DIRECT_ALLOC_ARGUMENTS; + a->arg = a->direct_alloc_arg; + +#define REGISTER_ARG(_index_,_type_) \ + { \ + size_t n = (_index_); \ + if (n >= a_allocated) \ + { \ + size_t memory_size; \ + argument *memory; \ + \ + a_allocated = xtimes (a_allocated, 2); \ + if (a_allocated <= n) \ + a_allocated = xsum (n, 1); \ + memory_size = xtimes (a_allocated, sizeof (argument)); \ + if (size_overflow_p (memory_size)) \ + /* Overflow, would lead to out of memory. */ \ + goto out_of_memory; \ + memory = (argument *) (a->arg != a->direct_alloc_arg \ + ? realloc (a->arg, memory_size) \ + : malloc (memory_size)); \ + if (memory == NULL) \ + /* Out of memory. */ \ + goto out_of_memory; \ + if (a->arg == a->direct_alloc_arg) \ + memcpy (memory, a->arg, a->count * sizeof (argument)); \ + a->arg = memory; \ + } \ + while (a->count <= n) \ + a->arg[a->count++].type = TYPE_NONE; \ + if (a->arg[n].type == TYPE_NONE) \ + a->arg[n].type = (_type_); \ + else if (a->arg[n].type != (_type_)) \ + /* Ambiguous type for positional argument. */ \ + goto error; \ + } + + while (*cp != '\0') + { + CHAR_T c = *cp++; + if (c == '%') + { + size_t arg_index = ARG_NONE; + DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ + + /* Initialize the next directive. */ + dp->dir_start = cp - 1; + dp->flags = 0; + dp->width_start = NULL; + dp->width_end = NULL; + dp->width_arg_index = ARG_NONE; + dp->precision_start = NULL; + dp->precision_end = NULL; + dp->precision_arg_index = ARG_NONE; + dp->arg_index = ARG_NONE; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory later. */ + goto error; + arg_index = n - 1; + cp = np + 1; + } + } + + /* Read the flags. */ + for (;;) + { + if (*cp == '\'') + { + dp->flags |= FLAG_GROUP; + cp++; + } + else if (*cp == '-') + { + dp->flags |= FLAG_LEFT; + cp++; + } + else if (*cp == '+') + { + dp->flags |= FLAG_SHOWSIGN; + cp++; + } + else if (*cp == ' ') + { + dp->flags |= FLAG_SPACE; + cp++; + } + else if (*cp == '#') + { + dp->flags |= FLAG_ALT; + cp++; + } + else if (*cp == '0') + { + dp->flags |= FLAG_ZERO; + cp++; + } +#if __GLIBC__ >= 2 && !defined __UCLIBC__ + else if (*cp == 'I') + { + dp->flags |= FLAG_LOCALIZED; + cp++; + } +#endif + else + break; + } + + /* Parse the field width. */ + if (*cp == '*') + { + dp->width_start = cp; + cp++; + dp->width_end = cp; + if (max_width_length < 1) + max_width_length = 1; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory later. */ + goto error; + dp->width_arg_index = n - 1; + cp = np + 1; + } + } + if (dp->width_arg_index == ARG_NONE) + { + dp->width_arg_index = arg_posn++; + if (dp->width_arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->width_arg_index, TYPE_INT); + } + else if (*cp >= '0' && *cp <= '9') + { + size_t width_length; + + dp->width_start = cp; + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + dp->width_end = cp; + width_length = dp->width_end - dp->width_start; + if (max_width_length < width_length) + max_width_length = width_length; + } + + /* Parse the precision. */ + if (*cp == '.') + { + cp++; + if (*cp == '*') + { + dp->precision_start = cp - 1; + cp++; + dp->precision_end = cp; + if (max_precision_length < 2) + max_precision_length = 2; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory + later. */ + goto error; + dp->precision_arg_index = n - 1; + cp = np + 1; + } + } + if (dp->precision_arg_index == ARG_NONE) + { + dp->precision_arg_index = arg_posn++; + if (dp->precision_arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->precision_arg_index, TYPE_INT); + } + else + { + size_t precision_length; + + dp->precision_start = cp - 1; + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + dp->precision_end = cp; + precision_length = dp->precision_end - dp->precision_start; + if (max_precision_length < precision_length) + max_precision_length = precision_length; + } + } + + { + arg_type type; + + /* Parse argument type/size specifiers. */ + { + int flags = 0; + + for (;;) + { + if (*cp == 'h') + { + flags |= (1 << (flags & 1)); + cp++; + } + else if (*cp == 'L') + { + flags |= 4; + cp++; + } + else if (*cp == 'l') + { + flags += 8; + cp++; + } + else if (*cp == 'j') + { + if (sizeof (intmax_t) > sizeof (long)) + { + /* intmax_t = long long */ + flags += 16; + } + else if (sizeof (intmax_t) > sizeof (int)) + { + /* intmax_t = long */ + flags += 8; + } + cp++; + } + else if (*cp == 'z' || *cp == 'Z') + { + /* 'z' is standardized in ISO C 99, but glibc uses 'Z' + because the warning facility in gcc-2.95.2 understands + only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ + if (sizeof (size_t) > sizeof (long)) + { + /* size_t = long long */ + flags += 16; + } + else if (sizeof (size_t) > sizeof (int)) + { + /* size_t = long */ + flags += 8; + } + cp++; + } + else if (*cp == 't') + { + if (sizeof (ptrdiff_t) > sizeof (long)) + { + /* ptrdiff_t = long long */ + flags += 16; + } + else if (sizeof (ptrdiff_t) > sizeof (int)) + { + /* ptrdiff_t = long */ + flags += 8; + } + cp++; + } +#if defined __APPLE__ && defined __MACH__ + /* On Mac OS X 10.3, PRIdMAX is defined as "qd". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'q') + { + if (64 / 8 > sizeof (long)) + { + /* int64_t = long long */ + flags += 16; + } + else + { + /* int64_t = long */ + flags += 8; + } + cp++; + } +#endif +#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. */ + else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') + { + if (64 / 8 > sizeof (long)) + { + /* __int64 = long long */ + flags += 16; + } + else + { + /* __int64 = long */ + flags += 8; + } + cp += 3; + } +#endif + else + break; + } + + /* Read the conversion character. */ + c = *cp++; + switch (c) + { + case 'd': case 'i': + /* If 'long long' is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGLONGINT; + else + /* If 'long long' is the same as 'long', we parse "lld" into + TYPE_LONGINT. */ + if (flags >= 8) + type = TYPE_LONGINT; + else if (flags & 2) + type = TYPE_SCHAR; + else if (flags & 1) + type = TYPE_SHORT; + else + type = TYPE_INT; + break; + case 'o': case 'u': case 'x': case 'X': + /* If 'unsigned long long' is larger than 'unsigned long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_ULONGLONGINT; + else + /* 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) + type = TYPE_UCHAR; + else if (flags & 1) + type = TYPE_USHORT; + else + type = TYPE_UINT; + break; + case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': + case 'a': case 'A': + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGDOUBLE; + else + type = TYPE_DOUBLE; + break; + case 'c': + if (flags >= 8) +#if HAVE_WINT_T + type = TYPE_WIDE_CHAR; +#else + goto error; +#endif + else + type = TYPE_CHAR; + break; +#if HAVE_WINT_T + case 'C': + type = TYPE_WIDE_CHAR; + c = 'c'; + break; +#endif + case 's': + if (flags >= 8) +#if HAVE_WCHAR_T + type = TYPE_WIDE_STRING; +#else + goto error; +#endif + else + type = TYPE_STRING; + break; +#if HAVE_WCHAR_T + case 'S': + type = TYPE_WIDE_STRING; + c = 's'; + break; +#endif + case 'p': + type = TYPE_POINTER; + break; + case 'n': + /* If 'long long' is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_COUNT_LONGLONGINT_POINTER; + else + /* 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) + type = TYPE_COUNT_SCHAR_POINTER; + else if (flags & 1) + type = TYPE_COUNT_SHORT_POINTER; + else + type = TYPE_COUNT_INT_POINTER; + break; +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case 'U': + if (flags >= 16) + type = TYPE_U32_STRING; + else if (flags >= 8) + type = TYPE_U16_STRING; + else + type = TYPE_U8_STRING; + break; +#endif + case '%': + type = TYPE_NONE; + break; + default: + /* Unknown conversion character. */ + goto error; + } + } + + if (type != TYPE_NONE) + { + dp->arg_index = arg_index; + if (dp->arg_index == ARG_NONE) + { + dp->arg_index = arg_posn++; + if (dp->arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->arg_index, type); + } + dp->conversion = c; + dp->dir_end = cp; + } + + d->count++; + if (d->count >= d_allocated) + { + size_t memory_size; + DIRECTIVE *memory; + + d_allocated = xtimes (d_allocated, 2); + memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); + if (size_overflow_p (memory_size)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir + ? realloc (d->dir, memory_size) + : malloc (memory_size)); + if (memory == NULL) + /* Out of memory. */ + goto out_of_memory; + if (d->dir == d->direct_alloc_dir) + memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE)); + d->dir = memory; + } + } +#if CHAR_T_ONLY_ASCII + else if (!c_isascii (c)) + { + /* Non-ASCII character. Not supported. */ + goto error; + } +#endif + } + d->dir[d->count].dir_start = cp; + + d->max_width_length = max_width_length; + d->max_precision_length = max_precision_length; + return 0; + +error: + if (a->arg != a->direct_alloc_arg) + free (a->arg); + if (d->dir != d->direct_alloc_dir) + free (d->dir); + errno = EINVAL; + return -1; + +out_of_memory: + if (a->arg != a->direct_alloc_arg) + free (a->arg); + if (d->dir != d->direct_alloc_dir) + free (d->dir); + errno = ENOMEM; + return -1; +} + +#undef PRINTF_PARSE +#undef DIRECTIVES +#undef DIRECTIVE +#undef CHAR_T_ONLY_ASCII +#undef CHAR_T diff --git a/lib/printf-parse.h b/lib/printf-parse.h new file mode 100644 index 0000000..b12ccea --- /dev/null +++ b/lib/printf-parse.h @@ -0,0 +1,193 @@ +/* Parse printf format string. + Copyright (C) 1999, 2002-2003, 2005, 2007, 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 . */ + +#ifndef _PRINTF_PARSE_H +#define _PRINTF_PARSE_H + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + STATIC Set to 'static' to declare the function static. */ + +#if HAVE_FEATURES_H +# include /* for __GLIBC__, __UCLIBC__ */ +#endif + +#include "printf-args.h" + + +/* Flags */ +#define FLAG_GROUP 1 /* ' flag */ +#define FLAG_LEFT 2 /* - flag */ +#define FLAG_SHOWSIGN 4 /* + flag */ +#define FLAG_SPACE 8 /* space flag */ +#define FLAG_ALT 16 /* # flag */ +#define FLAG_ZERO 32 +#if __GLIBC__ >= 2 && !defined __UCLIBC__ +# define FLAG_LOCALIZED 64 /* I flag, uses localized digits */ +#endif + +/* arg_index value indicating that no argument is consumed. */ +#define ARG_NONE (~(size_t)0) + +/* xxx_directive: A parsed directive. + xxx_directives: A parsed format string. */ + +/* Number of directly allocated directives (no malloc() needed). */ +#define N_DIRECT_ALLOC_DIRECTIVES 7 + +/* A parsed directive. */ +typedef struct +{ + const char* dir_start; + const char* dir_end; + int flags; + const char* width_start; + const char* width_end; + size_t width_arg_index; + const char* precision_start; + const char* precision_end; + size_t precision_arg_index; + char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +char_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + char_directive *dir; + size_t max_width_length; + size_t max_precision_length; + char_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; +} +char_directives; + +#if ENABLE_UNISTDIO + +/* A parsed directive. */ +typedef struct +{ + const uint8_t* dir_start; + const uint8_t* dir_end; + int flags; + const uint8_t* width_start; + const uint8_t* width_end; + size_t width_arg_index; + const uint8_t* precision_start; + const uint8_t* precision_end; + size_t precision_arg_index; + uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u8_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u8_directive *dir; + size_t max_width_length; + size_t max_precision_length; + u8_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; +} +u8_directives; + +/* A parsed directive. */ +typedef struct +{ + const uint16_t* dir_start; + const uint16_t* dir_end; + int flags; + const uint16_t* width_start; + const uint16_t* width_end; + size_t width_arg_index; + const uint16_t* precision_start; + const uint16_t* precision_end; + size_t precision_arg_index; + uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u16_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u16_directive *dir; + size_t max_width_length; + size_t max_precision_length; + u16_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; +} +u16_directives; + +/* A parsed directive. */ +typedef struct +{ + const uint32_t* dir_start; + const uint32_t* dir_end; + int flags; + const uint32_t* width_start; + const uint32_t* width_end; + size_t width_arg_index; + const uint32_t* precision_start; + const uint32_t* precision_end; + size_t precision_arg_index; + uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u32_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u32_directive *dir; + size_t max_width_length; + size_t max_precision_length; + u32_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; +} +u32_directives; + +#endif + + +/* Parses the format string. Fills in the number N of directives, and fills + in directives[0], ..., directives[N-1], and sets directives[N].dir_start + to the end of the format string. Also fills in the arg_type fields of the + arguments and the needed count of arguments. */ +#if ENABLE_UNISTDIO +extern int + ulc_printf_parse (const char *format, char_directives *d, arguments *a); +extern int + u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a); +extern int + u16_printf_parse (const uint16_t *format, u16_directives *d, + arguments *a); +extern int + u32_printf_parse (const uint32_t *format, u32_directives *d, + arguments *a); +#else +# ifdef STATIC +STATIC +# else +extern +# endif +int printf_parse (const char *format, char_directives *d, arguments *a); +#endif + +#endif /* _PRINTF_PARSE_H */ diff --git a/lib/pselect.c b/lib/pselect.c new file mode 100644 index 0000000..a1eca0c --- /dev/null +++ b/lib/pselect.c @@ -0,0 +1,110 @@ +/* pselect - synchronous I/O multiplexing + + Copyright 2011-2022 Free Software Foundation, Inc. + + 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 . */ + +/* written by Paul Eggert */ + +#include + +#include + +#include +#include + +/* Examine the size-NFDS file descriptor sets in RFDS, WFDS, and XFDS + to see whether some of their descriptors are ready for reading, + ready for writing, or have exceptions pending. Wait for at most + TIMEOUT seconds, and use signal mask SIGMASK while waiting. A null + pointer parameter stands for no descriptors, an infinite timeout, + or an unaffected signal mask. */ + +#if !HAVE_PSELECT + +int +pselect (int nfds, fd_set *restrict rfds, + fd_set *restrict wfds, fd_set *restrict xfds, + struct timespec const *restrict timeout, + sigset_t const *restrict sigmask) +{ + int select_result; + sigset_t origmask; + struct timeval tv, *tvp; + + if (timeout) + { + if (! (0 <= timeout->tv_nsec && timeout->tv_nsec < 1000000000)) + { + errno = EINVAL; + return -1; + } + + tv.tv_sec = timeout->tv_sec; + tv.tv_usec = (timeout->tv_nsec + 999) / 1000; + tvp = &tv; + } + else + tvp = NULL; + + /* Signal mask munging should be atomic, but this is the best we can + do in this emulation. */ + if (sigmask) + pthread_sigmask (SIG_SETMASK, sigmask, &origmask); + + select_result = select (nfds, rfds, wfds, xfds, tvp); + + if (sigmask) + { + int select_errno = errno; + pthread_sigmask (SIG_SETMASK, &origmask, NULL); + errno = select_errno; + } + + return select_result; +} + +#else /* HAVE_PSELECT */ +# include +# undef pselect + +int +rpl_pselect (int nfds, fd_set *restrict rfds, + fd_set *restrict wfds, fd_set *restrict xfds, + struct timespec const *restrict timeout, + sigset_t const *restrict sigmask) +{ + int i; + + /* FreeBSD 8.2 has a bug: it does not always detect invalid fds. */ + if (nfds < 0 || nfds > FD_SETSIZE) + { + errno = EINVAL; + return -1; + } + for (i = 0; i < nfds; i++) + { + if (((rfds && FD_ISSET (i, rfds)) + || (wfds && FD_ISSET (i, wfds)) + || (xfds && FD_ISSET (i, xfds))) + && dup2 (i, i) != i) + return -1; + } + + return pselect (nfds, rfds, wfds, xfds, timeout, sigmask); +} + +#endif diff --git a/lib/pthread_sigmask.c b/lib/pthread_sigmask.c new file mode 100644 index 0000000..cd4eb80 --- /dev/null +++ b/lib/pthread_sigmask.c @@ -0,0 +1,92 @@ +/* POSIX compatible signal blocking for threads. + 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#if PTHREAD_SIGMASK_INEFFECTIVE +# include +#endif + +#if PTHREAD_SIGMASK_UNBLOCK_BUG +# include +#endif + +int +pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) +#undef pthread_sigmask +{ +#if HAVE_PTHREAD_SIGMASK + int ret; + +# if PTHREAD_SIGMASK_INEFFECTIVE + sigset_t omask, omask_copy; + sigset_t *old_mask_ptr = &omask; + sigemptyset (&omask); + /* Add a signal unlikely to be blocked, so that OMASK_COPY + is unlikely to match the actual mask. */ + sigaddset (&omask, SIGILL); + memcpy (&omask_copy, &omask, sizeof omask); +# else + sigset_t *old_mask_ptr = old_mask; +# endif + + ret = pthread_sigmask (how, new_mask, old_mask_ptr); + +# if PTHREAD_SIGMASK_INEFFECTIVE + if (ret == 0) + { + /* Detect whether pthread_sigmask is currently ineffective. + Don't cache the information: libpthread.so could be dynamically + loaded after the program started and after pthread_sigmask was + called for the first time. */ + if (memcmp (&omask_copy, &omask, sizeof omask) == 0 + && pthread_sigmask (1729, &omask_copy, NULL) == 0) + { + /* pthread_sigmask is currently ineffective. The program is not + linked to -lpthread. So use sigprocmask instead. */ + return (sigprocmask (how, new_mask, old_mask) < 0 ? errno : 0); + } + + if (old_mask) + memcpy (old_mask, &omask, sizeof omask); + } +# endif +# if PTHREAD_SIGMASK_FAILS_WITH_ERRNO + if (ret == -1) + return errno; +# endif +# if PTHREAD_SIGMASK_UNBLOCK_BUG + if (ret == 0 + && new_mask != NULL + && (how == SIG_UNBLOCK || how == SIG_SETMASK)) + { + /* Give the OS the opportunity to raise signals that were pending before + the pthread_sigmask call and have now been unblocked. */ + usleep (1); + } +# endif + return ret; +#else + int ret = sigprocmask (how, new_mask, old_mask); + return (ret < 0 ? errno : 0); +#endif +} diff --git a/lib/quote.h b/lib/quote.h new file mode 100644 index 0000000..0910ffd --- /dev/null +++ b/lib/quote.h @@ -0,0 +1,46 @@ +/* quote.h - prototypes for quote.c + + Copyright (C) 1998-2001, 2003, 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 . */ + +#ifndef QUOTE_H_ +# define QUOTE_H_ 1 + +# include + +/* The quoting options used by quote_n and quote. Its type is incomplete, + so it's useful only in expressions like '"e_quoting_options'. */ +extern struct quoting_options quote_quoting_options; + +/* Return an unambiguous printable representation of ARG (of size + ARGSIZE), allocated in slot N, suitable for diagnostics. If + ARGSIZE is SIZE_MAX, use the string length of the argument for + ARGSIZE. */ +char const *quote_n_mem (int n, char const *arg, size_t argsize); + +/* Return an unambiguous printable representation of ARG (of size + ARGSIZE), suitable for diagnostics. If ARGSIZE is SIZE_MAX, use + the string length of the argument for ARGSIZE. */ +char const *quote_mem (char const *arg, size_t argsize); + +/* Return an unambiguous printable representation of ARG, allocated in + slot N, suitable for diagnostics. */ +char const *quote_n (int n, char const *arg); + +/* Return an unambiguous printable representation of ARG, suitable for + diagnostics. */ +char const *quote (char const *arg); + +#endif /* !QUOTE_H_ */ diff --git a/lib/quotearg.c b/lib/quotearg.c new file mode 100644 index 0000000..9180d9a --- /dev/null +++ b/lib/quotearg.c @@ -0,0 +1,1081 @@ +/* quotearg.c - quote arguments for output + + Copyright (C) 1998-2002, 2004-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 Paul Eggert */ + +/* Without this pragma, gcc 4.7.0 20111124 mistakenly suggests that + the quoting_options_from_style function might be candidate for + attribute 'pure' */ +#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ +# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" +#endif + +#include + +#include "quotearg.h" +#include "quote.h" + +#include "attribute.h" +#include "minmax.h" +#include "xalloc.h" +#include "c-strcaseeq.h" +#include "localcharset.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +#define INT_BITS (sizeof (int) * CHAR_BIT) + +struct quoting_options +{ + /* Basic quoting style. */ + enum quoting_style style; + + /* Additional flags. Bitwise combination of enum quoting_flags. */ + int flags; + + /* Quote the characters indicated by this bit vector even if the + quoting style would not normally require them to be quoted. */ + unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; + + /* The left quote for custom_quoting_style. */ + char const *left_quote; + + /* The right quote for custom_quoting_style. */ + char const *right_quote; +}; + +/* Names of quoting styles. */ +char const *const quoting_style_args[] = +{ + "literal", + "shell", + "shell-always", + "shell-escape", + "shell-escape-always", + "c", + "c-maybe", + "escape", + "locale", + "clocale", + 0 +}; + +/* Correspondences to quoting style names. */ +enum quoting_style const quoting_style_vals[] = +{ + literal_quoting_style, + shell_quoting_style, + shell_always_quoting_style, + shell_escape_quoting_style, + shell_escape_always_quoting_style, + c_quoting_style, + c_maybe_quoting_style, + escape_quoting_style, + locale_quoting_style, + clocale_quoting_style +}; + +/* The default quoting options. */ +static struct quoting_options default_quoting_options; + +/* Allocate a new set of quoting options, with contents initially identical + to O if O is not null, or to the default if O is null. + It is the caller's responsibility to free the result. */ +struct quoting_options * +clone_quoting_options (struct quoting_options *o) +{ + int e = errno; + struct quoting_options *p = xmemdup (o ? o : &default_quoting_options, + sizeof *o); + errno = e; + return p; +} + +/* Get the value of O's quoting style. If O is null, use the default. */ +enum quoting_style +get_quoting_style (struct quoting_options const *o) +{ + return (o ? o : &default_quoting_options)->style; +} + +/* In O (or in the default if O is null), + set the value of the quoting style to S. */ +void +set_quoting_style (struct quoting_options *o, enum quoting_style s) +{ + (o ? o : &default_quoting_options)->style = s; +} + +/* In O (or in the default if O is null), + set the value of the quoting options for character C to I. + Return the old value. Currently, the only values defined for I are + 0 (the default) and 1 (which means to quote the character even if + it would not otherwise be quoted). */ +int +set_char_quoting (struct quoting_options *o, char c, int i) +{ + unsigned char uc = c; + unsigned int *p = + (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; + int shift = uc % INT_BITS; + int r = (*p >> shift) & 1; + *p ^= ((i & 1) ^ r) << shift; + return r; +} + +/* In O (or in the default if O is null), + set the value of the quoting options flag to I, which can be a + bitwise combination of enum quoting_flags, or 0 for default + behavior. Return the old value. */ +int +set_quoting_flags (struct quoting_options *o, int i) +{ + int r; + if (!o) + o = &default_quoting_options; + r = o->flags; + o->flags = i; + return r; +} + +void +set_custom_quoting (struct quoting_options *o, + char const *left_quote, char const *right_quote) +{ + if (!o) + o = &default_quoting_options; + o->style = custom_quoting_style; + if (!left_quote || !right_quote) + abort (); + o->left_quote = left_quote; + o->right_quote = right_quote; +} + +/* Return quoting options for STYLE, with no extra quoting. */ +static struct quoting_options /* NOT PURE!! */ +quoting_options_from_style (enum quoting_style style) +{ + struct quoting_options o = { literal_quoting_style, 0, { 0 }, NULL, NULL }; + if (style == custom_quoting_style) + abort (); + o.style = style; + return o; +} + +/* MSGID approximates a quotation mark. Return its translation if it + has one; otherwise, return either it or "\"", depending on S. + + S is either clocale_quoting_style or locale_quoting_style. */ +static char const * +gettext_quote (char const *msgid, enum quoting_style s) +{ + char const *translation = _(msgid); + char const *locale_code; + + if (translation != msgid) + return translation; + + /* For UTF-8 and GB-18030, use single quotes U+2018 and U+2019. + Here is a list of other locales that include U+2018 and U+2019: + + ISO-8859-7 0xA1 KOI8-T 0x91 + CP869 0x8B CP874 0x91 + CP932 0x81 0x65 CP936 0xA1 0xAE + CP949 0xA1 0xAE CP950 0xA1 0xA5 + CP1250 0x91 CP1251 0x91 + CP1252 0x91 CP1253 0x91 + CP1254 0x91 CP1255 0x91 + CP1256 0x91 CP1257 0x91 + EUC-JP 0xA1 0xC6 EUC-KR 0xA1 0xAE + EUC-TW 0xA1 0xE4 BIG5 0xA1 0xA5 + BIG5-HKSCS 0xA1 0xA5 EUC-CN 0xA1 0xAE + GBK 0xA1 0xAE Georgian-PS 0x91 + PT154 0x91 + + None of these is still in wide use; using iconv is overkill. */ + locale_code = locale_charset (); + if (STRCASEEQ (locale_code, "UTF-8", 'U','T','F','-','8',0,0,0,0)) + return msgid[0] == '`' ? "\xe2\x80\x98": "\xe2\x80\x99"; + if (STRCASEEQ (locale_code, "GB18030", 'G','B','1','8','0','3','0',0,0)) + return msgid[0] == '`' ? "\xa1\ae": "\xa1\xaf"; + + return (s == clocale_quoting_style ? "\"" : "'"); +} + +/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of + argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and + QUOTE_THESE_TOO to control quoting. + Terminate the output with a null character, and return the written + size of the output, not counting the terminating null. + If BUFFERSIZE is too small to store the output string, return the + value that would have been returned had BUFFERSIZE been large enough. + If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE. + + This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, + ARGSIZE, O), except it breaks O into its component pieces and is + not careful about errno. */ + +static size_t +quotearg_buffer_restyled (char *buffer, size_t buffersize, + char const *arg, size_t argsize, + enum quoting_style quoting_style, int flags, + unsigned int const *quote_these_too, + char const *left_quote, + char const *right_quote) +{ + size_t i; + size_t len = 0; + size_t orig_buffersize = 0; + char const *quote_string = 0; + size_t quote_string_len = 0; + bool backslash_escapes = false; + bool unibyte_locale = MB_CUR_MAX == 1; + bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0; + bool pending_shell_escape_end = false; + bool encountered_single_quote = false; + bool all_c_and_shell_quote_compat = true; + +#define STORE(c) \ + do \ + { \ + if (len < buffersize) \ + buffer[len] = (c); \ + len++; \ + } \ + while (0) + +#define START_ESC() \ + do \ + { \ + if (elide_outer_quotes) \ + goto force_outer_quoting_style; \ + escaping = true; \ + if (quoting_style == shell_always_quoting_style \ + && ! pending_shell_escape_end) \ + { \ + STORE ('\''); \ + STORE ('$'); \ + STORE ('\''); \ + pending_shell_escape_end = true; \ + } \ + STORE ('\\'); \ + } \ + while (0) + +#define END_ESC() \ + do \ + { \ + if (pending_shell_escape_end && ! escaping) \ + { \ + STORE ('\''); \ + STORE ('\''); \ + pending_shell_escape_end = false; \ + } \ + } \ + while (0) + + process_input: + + switch (quoting_style) + { + case c_maybe_quoting_style: + quoting_style = c_quoting_style; + elide_outer_quotes = true; + FALLTHROUGH; + case c_quoting_style: + if (!elide_outer_quotes) + STORE ('"'); + backslash_escapes = true; + quote_string = "\""; + quote_string_len = 1; + break; + + case escape_quoting_style: + backslash_escapes = true; + elide_outer_quotes = false; + break; + + case locale_quoting_style: + case clocale_quoting_style: + case custom_quoting_style: + { + if (quoting_style != custom_quoting_style) + { + /* TRANSLATORS: + Get translations for open and closing quotation marks. + The message catalog should translate "`" to a left + quotation mark suitable for the locale, and similarly for + "'". For example, a French Unicode local should translate + these to U+00AB (LEFT-POINTING DOUBLE ANGLE + QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE + QUOTATION MARK), respectively. + + If the catalog has no translation, we will try to + use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and + Unicode U+2019 (RIGHT SINGLE QUOTATION MARK). If the + current locale is not Unicode, locale_quoting_style + will quote 'like this', and clocale_quoting_style will + quote "like this". You should always include translations + for "`" and "'" even if U+2018 and U+2019 are appropriate + for your locale. + + If you don't know what to put here, please see + + and use glyphs suitable for your language. */ + left_quote = gettext_quote (N_("`"), quoting_style); + right_quote = gettext_quote (N_("'"), quoting_style); + } + if (!elide_outer_quotes) + for (quote_string = left_quote; *quote_string; quote_string++) + STORE (*quote_string); + backslash_escapes = true; + quote_string = right_quote; + quote_string_len = strlen (quote_string); + } + break; + + case shell_escape_quoting_style: + backslash_escapes = true; + FALLTHROUGH; + case shell_quoting_style: + elide_outer_quotes = true; + FALLTHROUGH; + case shell_escape_always_quoting_style: + if (!elide_outer_quotes) + backslash_escapes = true; + FALLTHROUGH; + case shell_always_quoting_style: + quoting_style = shell_always_quoting_style; + if (!elide_outer_quotes) + STORE ('\''); + quote_string = "'"; + quote_string_len = 1; + break; + + case literal_quoting_style: + elide_outer_quotes = false; + break; + + default: + abort (); + } + + for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++) + { + unsigned char c; + unsigned char esc; + bool is_right_quote = false; + bool escaping = false; + bool c_and_shell_quote_compat = false; + + if (backslash_escapes + && quoting_style != shell_always_quoting_style + && quote_string_len + && (i + quote_string_len + <= (argsize == SIZE_MAX && 1 < quote_string_len + /* Use strlen only if we must: when argsize is SIZE_MAX, + and when the quote string is more than 1 byte long. + If we do call strlen, save the result. */ + ? (argsize = strlen (arg)) : argsize)) + && memcmp (arg + i, quote_string, quote_string_len) == 0) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + is_right_quote = true; + } + + c = arg[i]; + switch (c) + { + case '\0': + if (backslash_escapes) + { + START_ESC (); + /* If quote_string were to begin with digits, we'd need to + test for the end of the arg as well. However, it's + hard to imagine any locale that would use digits in + quotes, and set_custom_quoting is documented not to + accept them. Use only a single \0 with shell-escape + as currently digits are not printed within $'...' */ + if (quoting_style != shell_always_quoting_style + && i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9') + { + STORE ('0'); + STORE ('0'); + } + c = '0'; + /* We don't have to worry that this last '0' will be + backslash-escaped because, again, quote_string should + not start with it and because quote_these_too is + documented as not accepting it. */ + } + else if (flags & QA_ELIDE_NULL_BYTES) + continue; + break; + + case '?': + switch (quoting_style) + { + case shell_always_quoting_style: + if (elide_outer_quotes) + goto force_outer_quoting_style; + break; + + case c_quoting_style: + if ((flags & QA_SPLIT_TRIGRAPHS) + && i + 2 < argsize && arg[i + 1] == '?') + switch (arg[i + 2]) + { + case '!': case '\'': + case '(': case ')': case '-': case '/': + case '<': case '=': case '>': + /* Escape the second '?' in what would otherwise be + a trigraph. */ + if (elide_outer_quotes) + goto force_outer_quoting_style; + c = arg[i + 2]; + i += 2; + STORE ('?'); + STORE ('"'); + STORE ('"'); + STORE ('?'); + break; + + default: + break; + } + break; + + default: + break; + } + break; + + case '\a': esc = 'a'; goto c_escape; + case '\b': esc = 'b'; goto c_escape; + case '\f': esc = 'f'; goto c_escape; + case '\n': esc = 'n'; goto c_and_shell_escape; + case '\r': esc = 'r'; goto c_and_shell_escape; + case '\t': esc = 't'; goto c_and_shell_escape; + case '\v': esc = 'v'; goto c_escape; + case '\\': esc = c; + /* Never need to escape '\' in shell case. */ + if (quoting_style == shell_always_quoting_style) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + goto store_c; + } + + /* No need to escape the escape if we are trying to elide + outer quotes and nothing else is problematic. */ + if (backslash_escapes && elide_outer_quotes && quote_string_len) + goto store_c; + + c_and_shell_escape: + if (quoting_style == shell_always_quoting_style + && elide_outer_quotes) + goto force_outer_quoting_style; + /* fall through */ + c_escape: + if (backslash_escapes) + { + c = esc; + goto store_escape; + } + break; + + case '{': case '}': /* sometimes special if isolated */ + if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1)) + break; + FALLTHROUGH; + case '#': case '~': + if (i != 0) + break; + FALLTHROUGH; + case ' ': + c_and_shell_quote_compat = true; + FALLTHROUGH; + case '!': /* special in bash */ + case '"': case '$': case '&': + case '(': case ')': case '*': case ';': + case '<': + case '=': /* sometimes special in 0th or (with "set -k") later args */ + case '>': case '[': + case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ + case '`': case '|': + /* A shell special character. In theory, '$' and '`' could + be the first bytes of multibyte characters, which means + we should check them with mbrtowc, but in practice this + doesn't happen so it's not worth worrying about. */ + if (quoting_style == shell_always_quoting_style + && elide_outer_quotes) + goto force_outer_quoting_style; + break; + + case '\'': + encountered_single_quote = true; + c_and_shell_quote_compat = true; + if (quoting_style == shell_always_quoting_style) + { + if (elide_outer_quotes) + goto force_outer_quoting_style; + + if (buffersize && ! orig_buffersize) + { + /* Just scan string to see if supports a more concise + representation, rather than writing a longer string + but returning the length of the more concise form. */ + orig_buffersize = buffersize; + buffersize = 0; + } + + STORE ('\''); + STORE ('\\'); + STORE ('\''); + pending_shell_escape_end = false; + } + break; + + case '%': case '+': case ',': case '-': case '.': case '/': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case ':': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': + case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': + /* These characters don't cause problems, no matter what the + quoting style is. They cannot start multibyte sequences. + A digit or a special letter would cause trouble if it + appeared at the beginning of quote_string because we'd then + escape by prepending a backslash. However, it's hard to + imagine any locale that would use digits or letters as + quotes, and set_custom_quoting is documented not to accept + them. Also, a digit or a special letter would cause + trouble if it appeared in quote_these_too, but that's also + documented as not accepting them. */ + c_and_shell_quote_compat = true; + break; + + default: + /* If we have a multibyte sequence, copy it until we reach + its end, find an error, or come back to the initial shift + state. For C-like styles, if the sequence has + unprintable characters, escape the whole sequence, since + we can't easily escape single characters within it. */ + { + /* Length of multibyte sequence found so far. */ + size_t m; + + bool printable; + + if (unibyte_locale) + { + m = 1; + printable = isprint (c) != 0; + } + else + { + mbstate_t mbstate; + memset (&mbstate, 0, sizeof mbstate); + + m = 0; + printable = true; + if (argsize == SIZE_MAX) + argsize = strlen (arg); + + do + { + wchar_t w; + size_t bytes = mbrtowc (&w, &arg[i + m], + argsize - (i + m), &mbstate); + if (bytes == 0) + break; + else if (bytes == (size_t) -1) + { + printable = false; + break; + } + else if (bytes == (size_t) -2) + { + printable = false; + while (i + m < argsize && arg[i + m]) + m++; + break; + } + else + { + /* Work around a bug with older shells that "see" a '\' + that is really the 2nd byte of a multibyte character. + In practice the problem is limited to ASCII + chars >= '@' that are shell special chars. */ + if ('[' == 0x5b && elide_outer_quotes + && quoting_style == shell_always_quoting_style) + { + size_t j; + for (j = 1; j < bytes; j++) + switch (arg[i + m + j]) + { + case '[': case '\\': case '^': + case '`': case '|': + goto force_outer_quoting_style; + + default: + break; + } + } + + if (! iswprint (w)) + printable = false; + m += bytes; + } + } + while (! mbsinit (&mbstate)); + } + + c_and_shell_quote_compat = printable; + + if (1 < m || (backslash_escapes && ! printable)) + { + /* Output a multibyte sequence, or an escaped + unprintable unibyte character. */ + size_t ilim = i + m; + + for (;;) + { + if (backslash_escapes && ! printable) + { + START_ESC (); + STORE ('0' + (c >> 6)); + STORE ('0' + ((c >> 3) & 7)); + c = '0' + (c & 7); + } + else if (is_right_quote) + { + STORE ('\\'); + is_right_quote = false; + } + if (ilim <= i + 1) + break; + END_ESC (); + STORE (c); + c = arg[++i]; + } + + goto store_c; + } + } + } + + if (! (((backslash_escapes && quoting_style != shell_always_quoting_style) + || elide_outer_quotes) + && quote_these_too + && quote_these_too[c / INT_BITS] >> (c % INT_BITS) & 1) + && !is_right_quote) + goto store_c; + + store_escape: + START_ESC (); + + store_c: + END_ESC (); + STORE (c); + + if (! c_and_shell_quote_compat) + all_c_and_shell_quote_compat = false; + } + + if (len == 0 && quoting_style == shell_always_quoting_style + && elide_outer_quotes) + goto force_outer_quoting_style; + + /* Single shell quotes (') are commonly enough used as an apostrophe, + that we attempt to minimize the quoting in this case. Note itʼs + better to use the apostrophe modifier "\u02BC" if possible, as that + renders better and works with the word match regex \W+ etc. */ + if (quoting_style == shell_always_quoting_style && ! elide_outer_quotes + && encountered_single_quote) + { + if (all_c_and_shell_quote_compat) + return quotearg_buffer_restyled (buffer, orig_buffersize, arg, argsize, + c_quoting_style, + flags, quote_these_too, + left_quote, right_quote); + else if (! buffersize && orig_buffersize) + { + /* Disable read-only scan, and reprocess to write quoted string. */ + buffersize = orig_buffersize; + len = 0; + goto process_input; + } + } + + if (quote_string && !elide_outer_quotes) + for (; *quote_string; quote_string++) + STORE (*quote_string); + + if (len < buffersize) + buffer[len] = '\0'; + return len; + + force_outer_quoting_style: + /* Don't reuse quote_these_too, since the addition of outer quotes + sufficiently quotes the specified characters. */ + if (quoting_style == shell_always_quoting_style && backslash_escapes) + quoting_style = shell_escape_always_quoting_style; + return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, + quoting_style, + flags & ~QA_ELIDE_OUTER_QUOTES, NULL, + left_quote, right_quote); +} + +/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of + argument ARG (of size ARGSIZE), using O to control quoting. + If O is null, use the default. + Terminate the output with a null character, and return the written + size of the output, not counting the terminating null. + If BUFFERSIZE is too small to store the output string, return the + value that would have been returned had BUFFERSIZE been large enough. + If ARGSIZE is SIZE_MAX, use the string length of the argument for + ARGSIZE. */ +size_t +quotearg_buffer (char *buffer, size_t buffersize, + char const *arg, size_t argsize, + struct quoting_options const *o) +{ + struct quoting_options const *p = o ? o : &default_quoting_options; + int e = errno; + size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize, + p->style, p->flags, p->quote_these_too, + p->left_quote, p->right_quote); + errno = e; + return r; +} + +char * +quotearg_alloc (char const *arg, size_t argsize, + struct quoting_options const *o) +{ + return quotearg_alloc_mem (arg, argsize, NULL, o); +} + +/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly + allocated storage containing the quoted string, and store the + resulting size into *SIZE, if non-NULL. The result can contain + embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not + NULL, and set_quoting_flags has not set the null byte elision + flag. */ +char * +quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size, + struct quoting_options const *o) +{ + struct quoting_options const *p = o ? o : &default_quoting_options; + int e = errno; + /* Elide embedded null bytes if we can't return a size. */ + int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES); + size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style, + flags, p->quote_these_too, + p->left_quote, + p->right_quote) + 1; + char *buf = xcharalloc (bufsize); + quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags, + p->quote_these_too, + p->left_quote, p->right_quote); + errno = e; + if (size) + *size = bufsize - 1; + return buf; +} + +/* A storage slot with size and pointer to a value. */ +struct slotvec +{ + size_t size; + char *val; +}; + +/* Preallocate a slot 0 buffer, so that the caller can always quote + one small component of a "memory exhausted" message in slot 0. */ +static char slot0[256]; +static int nslots = 1; +static struct slotvec slotvec0 = {sizeof slot0, slot0}; +static struct slotvec *slotvec = &slotvec0; + +void +quotearg_free (void) +{ + struct slotvec *sv = slotvec; + int i; + for (i = 1; i < nslots; i++) + free (sv[i].val); + if (sv[0].val != slot0) + { + free (sv[0].val); + slotvec0.size = sizeof slot0; + slotvec0.val = slot0; + } + if (sv != &slotvec0) + { + free (sv); + slotvec = &slotvec0; + } + nslots = 1; +} + +/* Use storage slot N to return a quoted version of argument ARG. + ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a + null-terminated string. + OPTIONS specifies the quoting options. + The returned value points to static storage that can be + reused by the next call to this function with the same value of N. + N must be nonnegative; it is typically small, and must be + less than MIN (INT_MAX, IDX_MAX). The type of N is signed + to allow for future extensions (using negative values). */ +static char * +quotearg_n_options (int n, char const *arg, size_t argsize, + struct quoting_options const *options) +{ + int e = errno; + + struct slotvec *sv = slotvec; + + int nslots_max = MIN (INT_MAX, IDX_MAX); + if (! (0 <= n && n < nslots_max)) + abort (); + + if (nslots <= n) + { + bool preallocated = (sv == &slotvec0); + idx_t new_nslots = nslots; + + slotvec = sv = xpalloc (preallocated ? NULL : sv, &new_nslots, + n - nslots + 1, nslots_max, sizeof *sv); + if (preallocated) + *sv = slotvec0; + memset (sv + nslots, 0, (new_nslots - nslots) * sizeof *sv); + nslots = new_nslots; + } + + { + size_t size = sv[n].size; + char *val = sv[n].val; + /* Elide embedded null bytes since we don't return a size. */ + int flags = options->flags | QA_ELIDE_NULL_BYTES; + size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize, + options->style, flags, + options->quote_these_too, + options->left_quote, + options->right_quote); + + if (size <= qsize) + { + sv[n].size = size = qsize + 1; + if (val != slot0) + free (val); + sv[n].val = val = xcharalloc (size); + quotearg_buffer_restyled (val, size, arg, argsize, options->style, + flags, options->quote_these_too, + options->left_quote, + options->right_quote); + } + + errno = e; + return val; + } +} + +char * +quotearg_n (int n, char const *arg) +{ + return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options); +} + +char * +quotearg_n_mem (int n, char const *arg, size_t argsize) +{ + return quotearg_n_options (n, arg, argsize, &default_quoting_options); +} + +char * +quotearg (char const *arg) +{ + return quotearg_n (0, arg); +} + +char * +quotearg_mem (char const *arg, size_t argsize) +{ + return quotearg_n_mem (0, arg, argsize); +} + +char * +quotearg_n_style (int n, enum quoting_style s, char const *arg) +{ + struct quoting_options const o = quoting_options_from_style (s); + return quotearg_n_options (n, arg, SIZE_MAX, &o); +} + +char * +quotearg_n_style_mem (int n, enum quoting_style s, + char const *arg, size_t argsize) +{ + struct quoting_options const o = quoting_options_from_style (s); + return quotearg_n_options (n, arg, argsize, &o); +} + +char * +quotearg_style (enum quoting_style s, char const *arg) +{ + return quotearg_n_style (0, s, arg); +} + +char * +quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize) +{ + return quotearg_n_style_mem (0, s, arg, argsize); +} + +char * +quotearg_char_mem (char const *arg, size_t argsize, char ch) +{ + struct quoting_options options; + options = default_quoting_options; + set_char_quoting (&options, ch, 1); + return quotearg_n_options (0, arg, argsize, &options); +} + +char * +quotearg_char (char const *arg, char ch) +{ + return quotearg_char_mem (arg, SIZE_MAX, ch); +} + +char * +quotearg_colon (char const *arg) +{ + return quotearg_char (arg, ':'); +} + +char * +quotearg_colon_mem (char const *arg, size_t argsize) +{ + return quotearg_char_mem (arg, argsize, ':'); +} + +char * +quotearg_n_style_colon (int n, enum quoting_style s, char const *arg) +{ + struct quoting_options options; + options = quoting_options_from_style (s); + set_char_quoting (&options, ':', 1); + return quotearg_n_options (n, arg, SIZE_MAX, &options); +} + +char * +quotearg_n_custom (int n, char const *left_quote, + char const *right_quote, char const *arg) +{ + return quotearg_n_custom_mem (n, left_quote, right_quote, arg, + SIZE_MAX); +} + +char * +quotearg_n_custom_mem (int n, char const *left_quote, + char const *right_quote, + char const *arg, size_t argsize) +{ + struct quoting_options o = default_quoting_options; + set_custom_quoting (&o, left_quote, right_quote); + return quotearg_n_options (n, arg, argsize, &o); +} + +char * +quotearg_custom (char const *left_quote, char const *right_quote, + char const *arg) +{ + return quotearg_n_custom (0, left_quote, right_quote, arg); +} + +char * +quotearg_custom_mem (char const *left_quote, char const *right_quote, + char const *arg, size_t argsize) +{ + return quotearg_n_custom_mem (0, left_quote, right_quote, arg, + argsize); +} + + +/* The quoting option used by the functions of quote.h. */ +struct quoting_options quote_quoting_options = + { + locale_quoting_style, + 0, + { 0 }, + NULL, NULL + }; + +char const * +quote_n_mem (int n, char const *arg, size_t argsize) +{ + return quotearg_n_options (n, arg, argsize, "e_quoting_options); +} + +char const * +quote_mem (char const *arg, size_t argsize) +{ + return quote_n_mem (0, arg, argsize); +} + +char const * +quote_n (int n, char const *arg) +{ + return quote_n_mem (n, arg, SIZE_MAX); +} + +char const * +quote (char const *arg) +{ + return quote_n (0, arg); +} + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/quotearg.h b/lib/quotearg.h new file mode 100644 index 0000000..2009fac --- /dev/null +++ b/lib/quotearg.h @@ -0,0 +1,431 @@ +/* quotearg.h - quote arguments for output + + Copyright (C) 1998-2002, 2004, 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 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 Paul Eggert */ + +#ifndef QUOTEARG_H_ +# define QUOTEARG_H_ 1 + +# include + +/* Basic quoting styles. For each style, an example is given on the + input strings "simple", "\0 \t\n'\"\033?""?/\\", and "a:b", using + quotearg_buffer, quotearg_mem, and quotearg_colon_mem with that + style and the default flags and quoted characters. Note that the + examples are shown here as valid C strings rather than what + displays on a terminal (with "??/" as a trigraph for "\\"). */ +enum quoting_style + { + /* Output names as-is (ls --quoting-style=literal). Can result in + embedded null bytes if QA_ELIDE_NULL_BYTES is not in + effect. + + quotearg_buffer: + "simple", "\0 \t\n'\"\033??/\\", "a:b" + quotearg: + "simple", " \t\n'\"\033??/\\", "a:b" + quotearg_colon: + "simple", " \t\n'\"\033??/\\", "a:b" + */ + literal_quoting_style, + + /* Quote names for the shell if they contain shell metacharacters + or would cause ambiguous output (ls --quoting-style=shell). + Can result in embedded null bytes if QA_ELIDE_NULL_BYTES is not + in effect. + + quotearg_buffer: + "simple", "'\0 \t\n'\\''\"\033??/\\'", "a:b" + quotearg: + "simple", "' \t\n'\\''\"\033??/\\'", "a:b" + quotearg_colon: + "simple", "' \t\n'\\''\"\033??/\\'", "'a:b'" + */ + shell_quoting_style, + + /* Quote names for the shell, even if they would normally not + require quoting (ls --quoting-style=shell-always). Can result + in embedded null bytes if QA_ELIDE_NULL_BYTES is not in effect. + Behaves like shell_quoting_style if QA_ELIDE_OUTER_QUOTES is in + effect. + + quotearg_buffer: + "'simple'", "'\0 \t\n'\\''\"\033??/\\'", "'a:b'" + quotearg: + "'simple'", "' \t\n'\\''\"\033??/\\'", "'a:b'" + quotearg_colon: + "'simple'", "' \t\n'\\''\"\033??/\\'", "'a:b'" + */ + shell_always_quoting_style, + + /* Quote names for the shell if they contain shell metacharacters + or other problematic characters (ls --quoting-style=shell-escape). + Non printable characters are quoted using the $'...' syntax, + which originated in ksh93 and is widely supported by most shells, + and proposed for inclusion in POSIX. + + quotearg_buffer: + "simple", "''$'\\0'' '$'\\t\\n'\\''\"'$'\\033''??/\\'", "a:b" + quotearg: + "simple", "''$'\\0'' '$'\\t\\n'\\''\"'$'\\033''??/\\'", "a:b" + quotearg_colon: + "simple", "''$'\\0'' '$'\\t\\n'\\''\"'$'\\033''??/\\'", "'a:b'" + */ + shell_escape_quoting_style, + + /* Quote names for the shell even if they would normally not + require quoting (ls --quoting-style=shell-escape). + Non printable characters are quoted using the $'...' syntax, + which originated in ksh93 and is widely supported by most shells, + and proposed for inclusion in POSIX. Behaves like + shell_escape_quoting_style if QA_ELIDE_OUTER_QUOTES is in effect. + + quotearg_buffer: + "simple", "''$'\\0'' '$'\\t\\n'\\''\"'$'\\033''??/\'", "a:b" + quotearg: + "simple", "''$'\\0'' '$'\\t\\n'\\''\"'$'\\033''??/\'", "a:b" + quotearg_colon: + "simple", "''$'\\0'' '$'\\t\\n'\\''\"'$'\\033''??/\'", "'a:b'" + */ + shell_escape_always_quoting_style, + + /* Quote names as for a C language string (ls --quoting-style=c). + Behaves like c_maybe_quoting_style if QA_ELIDE_OUTER_QUOTES is + in effect. Split into consecutive strings if + QA_SPLIT_TRIGRAPHS. + + quotearg_buffer: + "\"simple\"", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a:b\"" + quotearg: + "\"simple\"", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a:b\"" + quotearg_colon: + "\"simple\"", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a\\:b\"" + */ + c_quoting_style, + + /* Like c_quoting_style except omit the surrounding double-quote + characters if no quoted characters are encountered. + + quotearg_buffer: + "simple", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "a:b" + quotearg: + "simple", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "a:b" + quotearg_colon: + "simple", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a:b\"" + */ + c_maybe_quoting_style, + + /* Like c_quoting_style except always omit the surrounding + double-quote characters and ignore QA_SPLIT_TRIGRAPHS + (ls --quoting-style=escape). + + quotearg_buffer: + "simple", "\\0 \\t\\n'\"\\033??/\\\\", "a:b" + quotearg: + "simple", "\\0 \\t\\n'\"\\033??/\\\\", "a:b" + quotearg_colon: + "simple", "\\0 \\t\\n'\"\\033??/\\\\", "a\\:b" + */ + escape_quoting_style, + + /* Like clocale_quoting_style, but use single quotes in the + default C locale or if the program does not use gettext + (ls --quoting-style=locale). For UTF-8 locales, quote + characters will use Unicode. + + LC_MESSAGES=C + quotearg_buffer: + "`simple'", "`\\0 \\t\\n\\'\"\\033??/\\\\'", "`a:b'" + quotearg: + "`simple'", "`\\0 \\t\\n\\'\"\\033??/\\\\'", "`a:b'" + quotearg_colon: + "`simple'", "`\\0 \\t\\n\\'\"\\033??/\\\\'", "`a\\:b'" + + LC_MESSAGES=pt_PT.utf8 + quotearg_buffer: + "\302\253simple\302\273", + "\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a:b\302\273" + quotearg: + "\302\253simple\302\273", + "\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a:b\302\273" + quotearg_colon: + "\302\253simple\302\273", + "\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a\\:b\302\273" + */ + locale_quoting_style, + + /* Like c_quoting_style except use quotation marks appropriate for + the locale and ignore QA_SPLIT_TRIGRAPHS + (ls --quoting-style=clocale). + + LC_MESSAGES=C + quotearg_buffer: + "\"simple\"", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a:b\"" + quotearg: + "\"simple\"", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a:b\"" + quotearg_colon: + "\"simple\"", "\"\\0 \\t\\n'\\\"\\033??/\\\\\"", "\"a\\:b\"" + + LC_MESSAGES=pt_PT.utf8 + quotearg_buffer: + "\302\253simple\302\273", + "\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a:b\302\273" + quotearg: + "\302\253simple\302\273", + "\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a:b\302\273" + quotearg_colon: + "\302\253simple\302\273", + "\302\253\\0 \\t\\n'\"\\033??/\\\\\302\253", "\302\253a\\:b\302\273" + */ + clocale_quoting_style, + + /* Like clocale_quoting_style except use the custom quotation marks + set by set_custom_quoting. If custom quotation marks are not + set, the behavior is undefined. + + left_quote = right_quote = "'" + quotearg_buffer: + "'simple'", "'\\0 \\t\\n\\'\"\\033??/\\\\'", "'a:b'" + quotearg: + "'simple'", "'\\0 \\t\\n\\'\"\\033??/\\\\'", "'a:b'" + quotearg_colon: + "'simple'", "'\\0 \\t\\n\\'\"\\033??/\\\\'", "'a\\:b'" + + left_quote = "(" and right_quote = ")" + quotearg_buffer: + "(simple)", "(\\0 \\t\\n'\"\\033??/\\\\)", "(a:b)" + quotearg: + "(simple)", "(\\0 \\t\\n'\"\\033??/\\\\)", "(a:b)" + quotearg_colon: + "(simple)", "(\\0 \\t\\n'\"\\033??/\\\\)", "(a\\:b)" + + left_quote = ":" and right_quote = " " + quotearg_buffer: + ":simple ", ":\\0\\ \\t\\n'\"\\033??/\\\\ ", ":a:b " + quotearg: + ":simple ", ":\\0\\ \\t\\n'\"\\033??/\\\\ ", ":a:b " + quotearg_colon: + ":simple ", ":\\0\\ \\t\\n'\"\\033??/\\\\ ", ":a\\:b " + + left_quote = "\"'" and right_quote = "'\"" + Notice that this is treated as a single level of quotes or two + levels where the outer quote need not be escaped within the inner + quotes. For two levels where the outer quote must be escaped + within the inner quotes, you must use separate quotearg + invocations. + quotearg_buffer: + "\"'simple'\"", "\"'\\0 \\t\\n\\'\"\\033??/\\\\'\"", "\"'a:b'\"" + quotearg: + "\"'simple'\"", "\"'\\0 \\t\\n\\'\"\\033??/\\\\'\"", "\"'a:b'\"" + quotearg_colon: + "\"'simple'\"", "\"'\\0 \\t\\n\\'\"\\033??/\\\\'\"", "\"'a\\:b'\"" + */ + custom_quoting_style + }; + +/* Flags for use in set_quoting_flags. */ +enum quoting_flags + { + /* Always elide null bytes from styles that do not quote them, + even when the length of the result is available to the + caller. */ + QA_ELIDE_NULL_BYTES = 0x01, + + /* Omit the surrounding quote characters if no escaped characters + are encountered. Note that if no other character needs + escaping, then neither does the escape character. */ + QA_ELIDE_OUTER_QUOTES = 0x02, + + /* In the c_quoting_style and c_maybe_quoting_style, split ANSI + trigraph sequences into concatenated strings (for example, + "?""?/" rather than "??/", which could be confused with + "\\"). */ + QA_SPLIT_TRIGRAPHS = 0x04 + }; + +/* For now, --quoting-style=literal is the default, but this may change. */ +# ifndef DEFAULT_QUOTING_STYLE +# define DEFAULT_QUOTING_STYLE literal_quoting_style +# endif + +/* Names of quoting styles and their corresponding values. */ +extern char const *const quoting_style_args[]; +extern enum quoting_style const quoting_style_vals[]; + +struct quoting_options; + +/* The functions listed below set and use a hidden variable + that contains the default quoting style options. */ + +/* Allocate a new set of quoting options, with contents initially identical + to O if O is not null, or to the default if O is null. + It is the caller's responsibility to free the result. */ +struct quoting_options *clone_quoting_options (struct quoting_options *o) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; + +/* Get the value of O's quoting style. If O is null, use the default. */ +enum quoting_style get_quoting_style (struct quoting_options const *o); + +/* In O (or in the default if O is null), + set the value of the quoting style to S. */ +void set_quoting_style (struct quoting_options *o, enum quoting_style s); + +/* In O (or in the default if O is null), + set the value of the quoting options for character C to I. + Return the old value. Currently, the only values defined for I are + 0 (the default) and 1 (which means to quote the character even if + it would not otherwise be quoted). C must never be a digit or a + letter that has special meaning after a backslash (for example, "\t" + for tab). */ +int set_char_quoting (struct quoting_options *o, char c, int i); + +/* In O (or in the default if O is null), + set the value of the quoting options flag to I, which can be a + bitwise combination of enum quoting_flags, or 0 for default + behavior. Return the old value. */ +int set_quoting_flags (struct quoting_options *o, int i); + +/* In O (or in the default if O is null), + set the value of the quoting style to custom_quoting_style, + set the left quote to LEFT_QUOTE, and set the right quote to + RIGHT_QUOTE. Each of LEFT_QUOTE and RIGHT_QUOTE must be + null-terminated and can be the empty string. Because backslashes are + used for escaping, it does not make sense for RIGHT_QUOTE to contain + a backslash. RIGHT_QUOTE must not begin with a digit or a letter + that has special meaning after a backslash (for example, "\t" for + tab). */ +void set_custom_quoting (struct quoting_options *o, + char const *left_quote, + char const *right_quote); + +/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of + argument ARG (of size ARGSIZE), using O to control quoting. + If O is null, use the default. + Terminate the output with a null character, and return the written + size of the output, not counting the terminating null. + If BUFFERSIZE is too small to store the output string, return the + value that would have been returned had BUFFERSIZE been large enough. + If ARGSIZE is -1, use the string length of the argument for ARGSIZE. + On output, BUFFER might contain embedded null bytes if ARGSIZE was + not -1, the style of O does not use backslash escapes, and the + flags of O do not request elision of null bytes.*/ +size_t quotearg_buffer (char *restrict buffer, size_t buffersize, + char const *arg, size_t argsize, + struct quoting_options const *o); + +/* Like quotearg_buffer, except return the result in a newly allocated + buffer. It is the caller's responsibility to free the result. The + result will not contain embedded null bytes. */ +char *quotearg_alloc (char const *arg, size_t argsize, + struct quoting_options const *o) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; + +/* Like quotearg_alloc, except that the length of the result, + excluding the terminating null byte, is stored into SIZE if it is + non-NULL. The result might contain embedded null bytes if ARGSIZE + was not -1, SIZE was not NULL, the style of O does not use + backslash escapes, and the flags of O do not request elision of + null bytes.*/ +char *quotearg_alloc_mem (char const *arg, size_t argsize, + size_t *size, struct quoting_options const *o) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; + +/* Use storage slot N to return a quoted version of the string ARG. + Use the default quoting options. + The returned value points to static storage that can be + reused by the next call to this function with the same value of N. + N must be nonnegative. The output of all functions in the + quotearg_n family are guaranteed to not contain embedded null + bytes.*/ +char *quotearg_n (int n, char const *arg); + +/* Equivalent to quotearg_n (0, ARG). */ +char *quotearg (char const *arg); + +/* Use storage slot N to return a quoted version of the argument ARG + of size ARGSIZE. This is like quotearg_n (N, ARG), except it can + quote null bytes. */ +char *quotearg_n_mem (int n, char const *arg, size_t argsize); + +/* Equivalent to quotearg_n_mem (0, ARG, ARGSIZE). */ +char *quotearg_mem (char const *arg, size_t argsize); + +/* Use style S and storage slot N to return a quoted version of the string ARG. + This is like quotearg_n (N, ARG), except that it uses S with no other + options to specify the quoting method. */ +char *quotearg_n_style (int n, enum quoting_style s, char const *arg); + +/* Use style S and storage slot N to return a quoted version of the + argument ARG of size ARGSIZE. This is like quotearg_n_style + (N, S, ARG), except it can quote null bytes. */ +char *quotearg_n_style_mem (int n, enum quoting_style s, + char const *arg, size_t argsize); + +/* Equivalent to quotearg_n_style (0, S, ARG). */ +char *quotearg_style (enum quoting_style s, char const *arg); + +/* Equivalent to quotearg_n_style_mem (0, S, ARG, ARGSIZE). */ +char *quotearg_style_mem (enum quoting_style s, + char const *arg, size_t argsize); + +/* Like quotearg (ARG), except also quote any instances of CH. + See set_char_quoting for a description of acceptable CH values. */ +char *quotearg_char (char const *arg, char ch); + +/* Like quotearg_char (ARG, CH), except it can quote null bytes. */ +char *quotearg_char_mem (char const *arg, size_t argsize, char ch); + +/* Equivalent to quotearg_char (ARG, ':'). */ +char *quotearg_colon (char const *arg); + +/* Like quotearg_colon (ARG), except it can quote null bytes. */ +char *quotearg_colon_mem (char const *arg, size_t argsize); + +/* Like quotearg_n_style, except with ':' quoting enabled. */ +char *quotearg_n_style_colon (int n, enum quoting_style s, char const *arg); + +/* Like quotearg_n_style (N, S, ARG) but with S as custom_quoting_style + with left quote as LEFT_QUOTE and right quote as RIGHT_QUOTE. See + set_custom_quoting for a description of acceptable LEFT_QUOTE and + RIGHT_QUOTE values. */ +char *quotearg_n_custom (int n, char const *left_quote, + char const *right_quote, char const *arg); + +/* Like quotearg_n_custom (N, LEFT_QUOTE, RIGHT_QUOTE, ARG) except it + can quote null bytes. */ +char *quotearg_n_custom_mem (int n, char const *left_quote, + char const *right_quote, + char const *arg, size_t argsize); + +/* Equivalent to quotearg_n_custom (0, LEFT_QUOTE, RIGHT_QUOTE, ARG). */ +char *quotearg_custom (char const *left_quote, char const *right_quote, + char const *arg); + +/* Equivalent to quotearg_n_custom_mem (0, LEFT_QUOTE, RIGHT_QUOTE, ARG, + ARGSIZE). */ +char *quotearg_custom_mem (char const *left_quote, + char const *right_quote, + char const *arg, size_t argsize); + +/* Free any dynamically allocated memory. */ +void quotearg_free (void); + +#endif /* !QUOTEARG_H_ */ diff --git a/lib/raise.c b/lib/raise.c new file mode 100644 index 0000000..385ddd3 --- /dev/null +++ b/lib/raise.c @@ -0,0 +1,83 @@ +/* Provide a non-threads replacement for the POSIX raise function. + + Copyright (C) 2002-2003, 2005-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 Jim Meyering and Bruno Haible */ + +#include + +/* Specification. */ +#include + +#if HAVE_RAISE +/* Native Windows platform. */ + +# include + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +# endif + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +/* Forward declaration. */ +static int raise_nothrow (int sig); +# else +# define raise_nothrow raise +# endif + +#else +/* An old Unix platform. */ + +# include + +#endif + +int +raise (int sig) +#undef raise +{ +#if GNULIB_defined_signal_blocking && GNULIB_defined_SIGPIPE + if (sig == SIGPIPE) + return _gl_raise_SIGPIPE (); +#endif + +#if HAVE_RAISE + return raise_nothrow (sig); +#else + return kill (getpid (), sig); +#endif +} + +#if HAVE_RAISE && HAVE_MSVC_INVALID_PARAMETER_HANDLER +static int +raise_nothrow (int sig) +{ + int result; + + TRY_MSVC_INVAL + { + result = raise (sig); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EINVAL; + } + DONE_MSVC_INVAL; + + return result; +} +#endif diff --git a/lib/rawmemchr.c b/lib/rawmemchr.c new file mode 100644 index 0000000..ea68c1b --- /dev/null +++ b/lib/rawmemchr.c @@ -0,0 +1,125 @@ +/* Searching in a string. + 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 + +/* A function definition is only needed if HAVE_RAWMEMCHR is not defined. */ +#if !HAVE_RAWMEMCHR + +# include +# include +# include + +# include "verify.h" + +/* Find the first occurrence of C in S. */ +void * +rawmemchr (const void *s, int c_in) +{ + /* Change this typedef to experiment with performance. */ + typedef uintptr_t longword; + /* If you change the "uintptr_t", you should change UINTPTR_WIDTH to match. + This verifies that the type does not have padding bits. */ + verify (UINTPTR_WIDTH == UCHAR_WIDTH * sizeof (longword)); + + const unsigned char *char_ptr; + unsigned char c = c_in; + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + (uintptr_t) char_ptr % alignof (longword) != 0; + ++char_ptr) + if (*char_ptr == c) + return (void *) char_ptr; + + longword const *longword_ptr = s = char_ptr; + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + longword repeated_one = (longword) -1 / UCHAR_MAX; + longword repeated_c = repeated_one * c; + longword repeated_hibit = repeated_one * (UCHAR_MAX / 2 + 1); + + /* Instead of the traditional loop which tests each byte, we will + test a longword at a time. The tricky part is testing if any of + the bytes in the longword in question are equal to + c. We first use an xor with repeated_c. This reduces the task + to testing whether any of the bytes in longword1 is zero. + + (The following comments assume 8-bit bytes, as POSIX requires; + the code's use of UCHAR_MAX should work even if bytes have more + than 8 bits.) + + We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one * 0x80). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + The test whether any byte in longword1 is zero is equivalent + to testing whether tmp is nonzero. + + This test can read beyond the end of a string, depending on where + C_IN is encountered. However, this is considered safe since the + initialization phase ensured that the read will be aligned, + therefore, the read will not cross page boundaries and will not + cause a fault. */ + + while (1) + { + longword longword1 = *longword_ptr ^ repeated_c; + + if ((((longword1 - repeated_one) & ~longword1) & repeated_hibit) != 0) + break; + longword_ptr++; + } + + char_ptr = s = longword_ptr; + + /* At this point, we know that one of the sizeof (longword) bytes + starting at char_ptr is == c. If we knew endianness, we + could determine the first such byte without any further memory + accesses, just by looking at the tmp result from the last loop + iteration. However, the following simple and portable code does + not attempt this potential optimization. */ + + while (*char_ptr != c) + char_ptr++; + return (void *) char_ptr; +} + +#endif diff --git a/lib/rawmemchr.valgrind b/lib/rawmemchr.valgrind new file mode 100644 index 0000000..64cf86c --- /dev/null +++ b/lib/rawmemchr.valgrind @@ -0,0 +1,28 @@ +# Suppress a valgrind message about use of uninitialized memory in rawmemchr(). + +# 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 . + +# This use is OK because it provides only a speedup. +{ + rawmemchr-value4 + Memcheck:Value4 + fun:rawmemchr +} +{ + rawmemchr-value8 + Memcheck:Value8 + fun:rawmemchr +} diff --git a/lib/readdir.c b/lib/readdir.c new file mode 100644 index 0000000..8e841df --- /dev/null +++ b/lib/readdir.c @@ -0,0 +1,102 @@ +/* Read the next entry of a directory. + 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#include "dirent-private.h" + +/* Don't assume that UNICODE is not defined. */ +#undef FindNextFile +#define FindNextFile FindNextFileA + +struct dirent * +readdir (DIR *dirp) +{ + char type; + struct dirent *result; + + /* There is no need to add code to produce entries for "." and "..". + According to the POSIX:2008 section "4.12 Pathname Resolution" + + "." and ".." are syntactic entities. + POSIX also says: + "If entries for dot or dot-dot exist, one entry shall be returned + for dot and one entry shall be returned for dot-dot; otherwise, + they shall not be returned." */ + + switch (dirp->status) + { + case -2: + /* End of directory already reached. */ + return NULL; + case -1: + break; + case 0: + if (!FindNextFile (dirp->current, &dirp->entry)) + { + switch (GetLastError ()) + { + case ERROR_NO_MORE_FILES: + dirp->status = -2; + return NULL; + default: + errno = EIO; + return NULL; + } + } + break; + default: + errno = dirp->status; + return NULL; + } + + dirp->status = 0; + + if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + type = DT_DIR; + else if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + type = DT_LNK; + else if ((dirp->entry.dwFileAttributes + & ~(FILE_ATTRIBUTE_READONLY + | FILE_ATTRIBUTE_HIDDEN + | FILE_ATTRIBUTE_SYSTEM + | FILE_ATTRIBUTE_ARCHIVE + | FILE_ATTRIBUTE_NORMAL + | FILE_ATTRIBUTE_TEMPORARY + | FILE_ATTRIBUTE_SPARSE_FILE + | FILE_ATTRIBUTE_COMPRESSED + | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED + | FILE_ATTRIBUTE_ENCRYPTED)) == 0) + /* Devices like COM1, LPT1, NUL would also have the attributes 0x20 but + they cannot occur here. */ + type = DT_REG; + else + type = DT_UNKNOWN; + + /* Reuse the memory of dirp->entry for the result. */ + result = + (struct dirent *) + ((char *) dirp->entry.cFileName - offsetof (struct dirent, d_name[0])); + result->d_type = type; + + return result; +} diff --git a/lib/readlink.c b/lib/readlink.c new file mode 100644 index 0000000..ed03cc8 --- /dev/null +++ b/lib/readlink.c @@ -0,0 +1,104 @@ +/* Read the contents of a symbolic link. + Copyright (C) 2003-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 +#include + +#if !HAVE_READLINK + +/* readlink() substitute for systems that don't have a readlink() function, + such as DJGPP 2.03 and mingw32. */ + +ssize_t +readlink (char const *file, _GL_UNUSED char *buf, + _GL_UNUSED size_t bufsize) +{ + struct stat statbuf; + + /* In general we should use lstat() here, not stat(). But on platforms + without symbolic links, lstat() - if it exists - would be equivalent to + stat(), therefore we can use stat(). This saves us a configure check. */ + if (stat (file, &statbuf) >= 0) + errno = EINVAL; + return -1; +} + +#else /* HAVE_READLINK */ + +# undef readlink + +/* readlink() wrapper that uses correct types, for systems like cygwin + 1.5.x where readlink returns int, and which rejects trailing slash, + for Solaris 9. */ + +ssize_t +rpl_readlink (char const *file, char *buf, size_t bufsize) +{ +# if READLINK_TRAILING_SLASH_BUG + size_t file_len = strlen (file); + if (file_len && file[file_len - 1] == '/') + { + /* Even if FILE without the slash is a symlink to a directory, + both lstat() and stat() must resolve the trailing slash to + the directory rather than the symlink. We can therefore + safely use stat() to distinguish between EINVAL and + ENOTDIR/ENOENT, avoiding extra overhead of rpl_lstat(). */ + struct stat st; + if (stat (file, &st) == 0 || errno == EOVERFLOW) + errno = EINVAL; + return -1; + } +# endif /* READLINK_TRAILING_SLASH_BUG */ + + ssize_t r = readlink (file, buf, bufsize); + +# if READLINK_TRUNCATE_BUG + if (r < 0 && errno == ERANGE) + { + /* Try again with a bigger buffer. This is just for test cases; + real code invariably discards short reads. */ + char stackbuf[4032]; + r = readlink (file, stackbuf, sizeof stackbuf); + if (r < 0) + { + if (errno == ERANGE) + { + /* Clear the buffer, which is good enough for real code. + Thankfully, no test cases try short reads of enormous + symlinks and what would be the point anyway? */ + r = bufsize; + memset (buf, 0, r); + } + } + else + { + if (bufsize < r) + r = bufsize; + memcpy (buf, stackbuf, r); + } + } +# endif + + return r; +} + +#endif /* HAVE_READLINK */ diff --git a/lib/realloc.c b/lib/realloc.c new file mode 100644 index 0000000..c878381 --- /dev/null +++ b/lib/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/lib/reallocarray.c b/lib/reallocarray.c new file mode 100644 index 0000000..bc4cba4 --- /dev/null +++ b/lib/reallocarray.c @@ -0,0 +1,39 @@ +/* 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 "intprops.h" + +void * +reallocarray (void *ptr, size_t nmemb, size_t size) +{ + size_t nbytes; + if (INT_MULTIPLY_WRAPV (nmemb, size, &nbytes)) + { + errno = ENOMEM; + return NULL; + } + + /* Rely on the semantics of GNU realloc. */ + return realloc (ptr, nbytes); +} diff --git a/lib/recv.c b/lib/recv.c new file mode 100644 index 0000000..4910731 --- /dev/null +++ b/lib/recv.c @@ -0,0 +1,49 @@ +/* recv.c --- wrappers for Windows recv function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef recv + +ssize_t +rpl_recv (int fd, void *buf, size_t len, int flags) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = recv (sock, buf, len, flags); + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/regcomp.c b/lib/regcomp.c new file mode 100644 index 0000000..b607c85 --- /dev/null +++ b/lib/regcomp.c @@ -0,0 +1,3778 @@ +/* Extended regular expression matching and search library. + 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 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 + . */ + +#ifdef _LIBC +# include +#endif + +static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, + size_t length, reg_syntax_t syntax); +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); +static void free_charset (re_charset_t *cset); +static void free_workarea_compile (regex_t *preg); +static reg_errcode_t create_initial_state (re_dfa_t *dfa); +static void optimize_utf8 (re_dfa_t *dfa); +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 *)), + void *extra); +static reg_errcode_t postorder (bin_tree_t *root, + reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra); +static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node); +static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node); +static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg, + bin_tree_t *node); +static reg_errcode_t calc_first (void *extra, bin_tree_t *node); +static reg_errcode_t calc_next (void *extra, bin_tree_t *node); +static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node); +static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint); +static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node, + unsigned int constraint); +static reg_errcode_t calc_eclosure (re_dfa_t *dfa); +static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, + Idx node, bool root); +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); +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, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp, + re_dfa_t *dfa, re_token_t *token, + reg_syntax_t syntax, reg_errcode_t *err); +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); +static reg_errcode_t 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); +static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, + re_string_t *regexp, + re_token_t *token); +static reg_errcode_t build_equiv_class (bitset_t sbcset, + re_charset_t *mbcset, + Idx *equiv_class_alloc, + const unsigned char *name); +static reg_errcode_t 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); +static bin_tree_t *build_charclass_op (re_dfa_t *dfa, + RE_TRANSLATE_TYPE trans, + const char *class_name, + const char *extra, + bool non_match, reg_errcode_t *err); +static bin_tree_t *create_tree (re_dfa_t *dfa, + bin_tree_t *left, bin_tree_t *right, + re_token_type_t type); +static bin_tree_t *create_token_tree (re_dfa_t *dfa, + bin_tree_t *left, bin_tree_t *right, + const re_token_t *token); +static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa); +static void free_token (re_token_t *node); +static reg_errcode_t free_tree (void *extra, bin_tree_t *node); +static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node); + +/* This table gives an error message for each of the error codes listed + in regex.h. Obviously the order here has to be same as there. + POSIX doesn't require that we do anything for REG_NOERROR, + but why not be nice? */ + +static const char __re_error_msgid[] = + { +#define REG_NOERROR_IDX 0 + gettext_noop ("Success") /* REG_NOERROR */ + "\0" +#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success") + gettext_noop ("No match") /* REG_NOMATCH */ + "\0" +#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match") + gettext_noop ("Invalid regular expression") /* REG_BADPAT */ + "\0" +#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression") + gettext_noop ("Invalid collation character") /* REG_ECOLLATE */ + "\0" +#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character") + gettext_noop ("Invalid character class name") /* REG_ECTYPE */ + "\0" +#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name") + gettext_noop ("Trailing backslash") /* REG_EESCAPE */ + "\0" +#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash") + 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 */ + "\0" +#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 \\(") + gettext_noop ("Unmatched \\{") /* REG_EBRACE */ + "\0" +#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{") + gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */ + "\0" +#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}") + gettext_noop ("Invalid range end") /* REG_ERANGE */ + "\0" +#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end") + gettext_noop ("Memory exhausted") /* REG_ESPACE */ + "\0" +#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted") + gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */ + "\0" +#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression") + gettext_noop ("Premature end of regular expression") /* REG_EEND */ + "\0" +#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression") + gettext_noop ("Regular expression too big") /* REG_ESIZE */ + "\0" +#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big") + gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ + }; + +static const size_t __re_error_msgid_idx[] = + { + REG_NOERROR_IDX, + REG_NOMATCH_IDX, + REG_BADPAT_IDX, + REG_ECOLLATE_IDX, + REG_ECTYPE_IDX, + REG_EESCAPE_IDX, + REG_ESUBREG_IDX, + REG_EBRACK_IDX, + REG_EPAREN_IDX, + REG_EBRACE_IDX, + REG_BADBR_IDX, + REG_ERANGE_IDX, + REG_ESPACE_IDX, + REG_BADRPT_IDX, + REG_EEND_IDX, + REG_ESIZE_IDX, + REG_ERPAREN_IDX + }; + +/* Entry points for GNU code. */ + +/* re_compile_pattern is the GNU regular expression compiler: it + compiles PATTERN (of length LENGTH) and puts the result in BUFP. + Returns 0 if the pattern was valid, otherwise an error string. + + Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields + are set in BUFP on entry. */ + +const char * +re_compile_pattern (const char *pattern, size_t length, + struct re_pattern_buffer *bufp) +{ + reg_errcode_t ret; + + /* And GNU code determines whether or not to get register information + by passing null for the REGS argument to re_match, etc., not by + setting no_sub, unless RE_NO_SUB is set. */ + bufp->no_sub = !!(re_syntax_options & RE_NO_SUB); + + /* Match anchors at newline. */ + bufp->newline_anchor = 1; + + ret = re_compile_internal (bufp, pattern, length, re_syntax_options); + + if (!ret) + return NULL; + return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); +} +weak_alias (__re_compile_pattern, re_compile_pattern) + +/* Set by 're_set_syntax' to the current regexp syntax to recognize. Can + also be assigned to arbitrarily: each pattern buffer stores its own + syntax, so it can be changed between regex compilations. */ +/* This has no initializer because initialized variables in Emacs + become read-only after dumping. */ +reg_syntax_t re_syntax_options; + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit mask comprised of the various bits + defined in regex.h. We return the old syntax. */ + +reg_syntax_t +re_set_syntax (reg_syntax_t syntax) +{ + reg_syntax_t ret = re_syntax_options; + + re_syntax_options = syntax; + return ret; +} +weak_alias (__re_set_syntax, re_set_syntax) + +int +re_compile_fastmap (struct re_pattern_buffer *bufp) +{ + re_dfa_t *dfa = bufp->buffer; + char *fastmap = bufp->fastmap; + + memset (fastmap, '\0', sizeof (char) * SBC_MAX); + re_compile_fastmap_iter (bufp, dfa->init_state, fastmap); + if (dfa->init_state != dfa->init_state_word) + re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap); + if (dfa->init_state != dfa->init_state_nl) + re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap); + if (dfa->init_state != dfa->init_state_begbuf) + re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap); + bufp->fastmap_accurate = 1; + return 0; +} +weak_alias (__re_compile_fastmap, re_compile_fastmap) + +static __always_inline void +re_set_fastmap (char *fastmap, bool icase, int ch) +{ + fastmap[ch] = 1; + if (icase) + fastmap[tolower (ch)] = 1; +} + +/* Helper function for re_compile_fastmap. + Compile fastmap for the initial_state INIT_STATE. */ + +static void +re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, + char *fastmap) +{ + re_dfa_t *dfa = bufp->buffer; + Idx node_cnt; + bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); + for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) + { + Idx node = init_state->nodes.elems[node_cnt]; + re_token_type_t type = dfa->nodes[node].type; + + if (type == CHARACTER) + { + re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); + if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) + { + unsigned char buf[MB_LEN_MAX]; + unsigned char *p; + wchar_t wc; + mbstate_t state; + + p = buf; + *p++ = dfa->nodes[node].opr.c; + while (++node < dfa->nodes_len + && dfa->nodes[node].type == CHARACTER + && dfa->nodes[node].mb_partial) + *p++ = dfa->nodes[node].opr.c; + memset (&state, '\0', sizeof (state)); + if (__mbrtowc (&wc, (const char *) buf, p - buf, + &state) == p - buf + && (__wcrtomb ((char *) buf, __towlower (wc), &state) + != (size_t) -1)) + re_set_fastmap (fastmap, false, buf[0]); + } + } + else if (type == SIMPLE_BRACKET) + { + int i, ch; + for (i = 0, ch = 0; i < BITSET_WORDS; ++i) + { + int j; + bitset_word_t w = dfa->nodes[node].opr.sbcset[i]; + for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) + if (w & ((bitset_word_t) 1 << j)) + re_set_fastmap (fastmap, icase, ch); + } + } + else if (type == COMPLEX_BRACKET) + { + re_charset_t *cset = dfa->nodes[node].opr.mbcset; + Idx i; + +#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 + collation element, and don't catch 'b' since 'b' is + the only collation element which starts from 'b' (and + it is caught by SIMPLE_BRACKET). */ + if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0 + && (cset->ncoll_syms || cset->nranges)) + { + const int32_t *table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + for (i = 0; i < SBC_MAX; ++i) + if (table[i] < 0) + re_set_fastmap (fastmap, icase, i); + } +#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 + applies to multibyte character sets; for single byte character + sets, the SIMPLE_BRACKET again suffices. */ + if (dfa->mb_cur_max > 1 + && (cset->nchar_classes || cset->non_match || cset->nranges +#ifdef _LIBC + || cset->nequiv_classes +#endif /* _LIBC */ + )) + { + unsigned char c = 0; + do + { + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2) + re_set_fastmap (fastmap, false, (int) c); + } + while (++c != 0); + } + + else + { + /* ... Else catch all bytes which can start the mbchars. */ + for (i = 0; i < cset->nmbchars; ++i) + { + char buf[256]; + mbstate_t state; + memset (&state, '\0', sizeof (state)); + if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) + 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) + != (size_t) -1) + re_set_fastmap (fastmap, false, *(unsigned char *) buf); + } + } + } + } + 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) + bufp->can_be_null = 1; + return; + } + } +} + +/* Entry point for POSIX code. */ +/* regcomp takes a regular expression as a string and compiles it. + + PREG is a regex_t *. We do not expect any fields to be initialized, + since POSIX says we shouldn't. Thus, we set + + 'buffer' to the compiled pattern; + 'used' to the length of the compiled pattern; + 'syntax' to RE_SYNTAX_POSIX_EXTENDED if the + REG_EXTENDED bit in CFLAGS is set; otherwise, to + RE_SYNTAX_POSIX_BASIC; + 'newline_anchor' to REG_NEWLINE being set in CFLAGS; + 'fastmap' to an allocated space for the fastmap; + 'fastmap_accurate' to zero; + 're_nsub' to the number of subexpressions in PATTERN. + + PATTERN is the address of the pattern string. + + CFLAGS is a series of bits which affect compilation. + + If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we + use POSIX basic syntax. + + If REG_NEWLINE is set, then . and [^...] don't match newline. + Also, regexec will try a match beginning after every newline. + + If REG_ICASE is set, then we considers upper- and lowercase + versions of letters to be equivalent when matching. + + If REG_NOSUB is set, then when PREG is passed to regexec, that + routine will report only success or failure, and nothing about the + registers. + + It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for + the return codes and their meanings.) */ + +int +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 + : RE_SYNTAX_POSIX_BASIC); + + preg->buffer = NULL; + preg->allocated = 0; + preg->used = 0; + + /* Try to allocate space for the fastmap. */ + preg->fastmap = re_malloc (char, SBC_MAX); + if (__glibc_unlikely (preg->fastmap == NULL)) + return REG_ESPACE; + + syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0; + + /* If REG_NEWLINE is set, newlines are treated differently. */ + if (cflags & REG_NEWLINE) + { /* REG_NEWLINE implies neither . nor [^...] match newline. */ + syntax &= ~RE_DOT_NEWLINE; + syntax |= RE_HAT_LISTS_NOT_NEWLINE; + /* It also changes the matching behavior. */ + preg->newline_anchor = 1; + } + else + preg->newline_anchor = 0; + preg->no_sub = !!(cflags & REG_NOSUB); + preg->translate = NULL; + + ret = re_compile_internal (preg, pattern, strlen (pattern), syntax); + + /* POSIX doesn't distinguish between an unmatched open-group and an + unmatched close-group: both are REG_EPAREN. */ + if (ret == REG_ERPAREN) + ret = REG_EPAREN; + + /* We have already checked preg->fastmap != NULL. */ + 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); + else + { + /* Some error occurred while compiling the expression. */ + re_free (preg->fastmap); + preg->fastmap = NULL; + } + + return (int) ret; +} +libc_hidden_def (__regcomp) +weak_alias (__regcomp, regcomp) + +/* Returns a message corresponding to an error code, ERRCODE, returned + from either regcomp or regexec. We don't use PREG here. */ + +size_t +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 (__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. + Dump core so we can fix it. */ + abort (); + + msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); + + msg_size = strlen (msg) + 1; /* Includes the null. */ + + if (__glibc_likely (errbuf_size != 0)) + { + size_t cpy_size = msg_size; + if (__glibc_unlikely (msg_size > errbuf_size)) + { + cpy_size = errbuf_size - 1; + errbuf[cpy_size] = '\0'; + } + memcpy (errbuf, msg, cpy_size); + } + + return msg_size; +} +weak_alias (__regerror, regerror) + + +/* 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 + a worthwhile optimization. */ +static const bitset_t utf8_sb_map = +{ + /* Set the first 128 bits. */ +#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 + BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, +# elif 2 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, BITSET_WORD_MAX, +# elif 1 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, +# endif + (BITSET_WORD_MAX + >> (SBC_MAX % BITSET_WORD_BITS == 0 + ? 0 + : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) +#endif +}; + + +static void +free_dfa_content (re_dfa_t *dfa) +{ + Idx i, j; + + if (dfa->nodes) + for (i = 0; i < dfa->nodes_len; ++i) + free_token (dfa->nodes + i); + re_free (dfa->nexts); + for (i = 0; i < dfa->nodes_len; ++i) + { + if (dfa->eclosures != NULL) + re_node_set_free (dfa->eclosures + i); + if (dfa->inveclosures != NULL) + re_node_set_free (dfa->inveclosures + i); + if (dfa->edests != NULL) + re_node_set_free (dfa->edests + i); + } + re_free (dfa->edests); + re_free (dfa->eclosures); + re_free (dfa->inveclosures); + re_free (dfa->nodes); + + if (dfa->state_table) + for (i = 0; i <= dfa->state_hash_mask; ++i) + { + struct re_state_table_entry *entry = dfa->state_table + i; + for (j = 0; j < entry->num; ++j) + { + re_dfastate_t *state = entry->array[j]; + free_state (state); + } + re_free (entry->array); + } + re_free (dfa->state_table); + if (dfa->sb_char != utf8_sb_map) + re_free (dfa->sb_char); + re_free (dfa->subexp_map); +#ifdef DEBUG + re_free (dfa->re_str); +#endif + + re_free (dfa); +} + + +/* Free dynamically allocated space used by PREG. */ + +void +regfree (regex_t *preg) +{ + re_dfa_t *dfa = preg->buffer; + if (__glibc_likely (dfa != NULL)) + { + lock_fini (dfa->lock); + free_dfa_content (dfa); + } + preg->buffer = NULL; + preg->allocated = 0; + + re_free (preg->fastmap); + preg->fastmap = NULL; + + re_free (preg->translate); + preg->translate = NULL; +} +libc_hidden_def (__regfree) +weak_alias (__regfree, regfree) + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC + +/* BSD has one and only one pattern buffer. */ +static struct re_pattern_buffer re_comp_buf; + +char * +# ifdef _LIBC +/* Make these definitions weak in libc, so POSIX programs can redefine + these names if they don't use our functions, and still use + regcomp/regexec above without link errors. */ +weak_function +# endif +re_comp (const char *s) +{ + reg_errcode_t ret; + char *fastmap; + + if (!s) + { + if (!re_comp_buf.buffer) + return gettext ("No previous regular expression"); + return 0; + } + + if (re_comp_buf.buffer) + { + fastmap = re_comp_buf.fastmap; + re_comp_buf.fastmap = NULL; + __regfree (&re_comp_buf); + memset (&re_comp_buf, '\0', sizeof (re_comp_buf)); + re_comp_buf.fastmap = fastmap; + } + + if (re_comp_buf.fastmap == NULL) + { + 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]); + } + + /* Since 're_exec' always passes NULL for the 'regs' argument, we + don't need to initialize the pattern buffer fields which affect it. */ + + /* Match anchors at newlines. */ + re_comp_buf.newline_anchor = 1; + + ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options); + + if (!ret) + return NULL; + + /* Yes, we're discarding 'const' here if !HAVE_LIBINTL. */ + return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); +} + +#ifdef _LIBC +libc_freeres_fn (free_mem) +{ + __regfree (&re_comp_buf); +} +#endif + +#endif /* _REGEX_RE_COMP */ + +/* Internal entry point. + Compile the regular expression PATTERN, whose length is LENGTH. + SYNTAX indicate regular expression's syntax. */ + +static reg_errcode_t +re_compile_internal (regex_t *preg, const char * pattern, size_t length, + reg_syntax_t syntax) +{ + reg_errcode_t err = REG_NOERROR; + re_dfa_t *dfa; + re_string_t regexp; + + /* Initialize the pattern buffer. */ + preg->fastmap_accurate = 0; + preg->syntax = syntax; + preg->not_bol = preg->not_eol = 0; + preg->used = 0; + preg->re_nsub = 0; + preg->can_be_null = 0; + preg->regs_allocated = REGS_UNALLOCATED; + + /* Initialize the dfa. */ + dfa = preg->buffer; + 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 + that is the user's responsibility. If ->buffer is NULL this + is a simple allocation. */ + dfa = re_realloc (preg->buffer, re_dfa_t, 1); + if (dfa == NULL) + return REG_ESPACE; + preg->allocated = sizeof (re_dfa_t); + preg->buffer = dfa; + } + preg->used = sizeof (re_dfa_t); + + err = init_dfa (dfa, length); + if (__glibc_unlikely (err == REG_NOERROR && lock_init (dfa->lock) != 0)) + err = REG_ESPACE; + if (__glibc_unlikely (err != REG_NOERROR)) + { + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + return err; + } +#ifdef DEBUG + /* Note: length+1 will not overflow since it is checked in init_dfa. */ + dfa->re_str = re_malloc (char, length + 1); + strncpy (dfa->re_str, pattern, length + 1); +#endif + + err = re_string_construct (®exp, pattern, length, preg->translate, + (syntax & RE_ICASE) != 0, dfa); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_compile_internal_free_return: + free_workarea_compile (preg); + re_string_destruct (®exp); + lock_fini (dfa->lock); + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + return err; + } + + /* Parse the regular expression, and build a structure tree. */ + preg->re_nsub = 0; + dfa->str_tree = parse (®exp, preg, syntax, &err); + if (__glibc_unlikely (dfa->str_tree == NULL)) + goto re_compile_internal_free_return; + + /* Analyze the tree and create the nfa. */ + err = analyze (preg); + if (__glibc_unlikely (err != REG_NOERROR)) + goto re_compile_internal_free_return; + + /* 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); + + /* Then create the initial state of the dfa. */ + err = create_initial_state (dfa); + + /* Release work areas. */ + free_workarea_compile (preg); + re_string_destruct (®exp); + + if (__glibc_unlikely (err != REG_NOERROR)) + { + lock_fini (dfa->lock); + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + } + + return err; +} + +/* Initialize DFA. We use the length of the regular expression PAT_LEN + as the initial length of some arrays. */ + +static reg_errcode_t +init_dfa (re_dfa_t *dfa, size_t pat_len) +{ + __re_size_t table_size; +#ifndef _LIBC + const char *codeset_name; +#endif + size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); + size_t max_object_size = + MAX (sizeof (struct re_state_table_entry), + MAX (sizeof (re_token_t), + MAX (sizeof (re_node_set), + MAX (sizeof (regmatch_t), + max_i18n_object_size)))); + + memset (dfa, '\0', sizeof (re_dfa_t)); + + /* Force allocation of str_tree_storage the first time. */ + dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; + + /* Avoid overflows. The extra "/ 2" is for the table_size doubling + calculation below, and for similar doubling calculations + elsewhere. And it's <= rather than <, because some of the + doubling calculations add 1 afterwards. */ + if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 + <= pat_len)) + return REG_ESPACE; + + dfa->nodes_alloc = pat_len + 1; + dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc); + + /* table_size = 2 ^ ceil(log pat_len) */ + for (table_size = 1; ; table_size <<= 1) + if (table_size > pat_len) + break; + + dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); + dfa->state_hash_mask = table_size - 1; + + dfa->mb_cur_max = MB_CUR_MAX; +#ifdef _LIBC + if (dfa->mb_cur_max == 6 + && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0) + dfa->is_utf8 = 1; + dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) + != 0); +#else + codeset_name = nl_langinfo (CODESET); + if ((codeset_name[0] == 'U' || codeset_name[0] == 'u') + && (codeset_name[1] == 'T' || codeset_name[1] == 't') + && (codeset_name[2] == 'F' || codeset_name[2] == 'f') + && strcmp (codeset_name + 3 + (codeset_name[3] == '-'), "8") == 0) + dfa->is_utf8 = 1; + + /* We check exhaustively in the loop below if this charset is a + superset of ASCII. */ + dfa->map_notascii = 0; +#endif + + if (dfa->mb_cur_max > 1) + { + if (dfa->is_utf8) + dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map; + else + { + int i, j, ch; + + dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); + if (__glibc_unlikely (dfa->sb_char == NULL)) + return REG_ESPACE; + + /* Set the bits corresponding to single byte chars. */ + for (i = 0, ch = 0; i < BITSET_WORDS; ++i) + for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) + { + wint_t wch = __btowc (ch); + if (wch != WEOF) + dfa->sb_char[i] |= (bitset_word_t) 1 << j; +#ifndef _LIBC + if (isascii (ch) && wch != ch) + dfa->map_notascii = 1; +#endif + } + } + } + + if (__glibc_unlikely (dfa->nodes == NULL || dfa->state_table == NULL)) + return REG_ESPACE; + return REG_NOERROR; +} + +/* Initialize WORD_CHAR table, which indicate which character is + "word". In this case "word" means that it is the word construction + character used by some operators like "\<", "\>", etc. */ + +static void +init_word_char (re_dfa_t *dfa) +{ + int i = 0; + int j; + int ch = 0; + dfa->word_ops_used = 1; + if (__glibc_likely (dfa->map_notascii == 0)) + { + bitset_word_t bits0 = 0x00000000; + bitset_word_t bits1 = 0x03ff0000; + bitset_word_t bits2 = 0x87fffffe; + 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; + } + else if (BITSET_WORD_BITS == 32) + { + dfa->word_char[0] = bits0; + dfa->word_char[1] = bits1; + dfa->word_char[2] = bits2; + dfa->word_char[3] = bits3; + i = 4; + } + else + goto general_case; + ch = 128; + + if (__glibc_likely (dfa->is_utf8)) + { + memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8); + return; + } + } + + general_case: + for (; i < BITSET_WORDS; ++i) + for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) + if (isalnum (ch) || ch == '_') + dfa->word_char[i] |= (bitset_word_t) 1 << j; +} + +/* Free the work area which are only used while compiling. */ + +static void +free_workarea_compile (regex_t *preg) +{ + re_dfa_t *dfa = preg->buffer; + bin_tree_storage_t *storage, *next; + for (storage = dfa->str_tree_storage; storage; storage = next) + { + next = storage->next; + re_free (storage); + } + dfa->str_tree_storage = NULL; + dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; + dfa->str_tree = NULL; + re_free (dfa->org_indices); + dfa->org_indices = NULL; +} + +/* Create initial states for all contexts. */ + +static reg_errcode_t +create_initial_state (re_dfa_t *dfa) +{ + Idx first, i; + reg_errcode_t err; + re_node_set init_nodes; + + /* Initial states have the epsilon closure of the node which is + the first node of the regular expression. */ + first = dfa->str_tree->first->node_idx; + dfa->init_node = first; + err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + + /* The back-references which are in initial states can epsilon transit, + since in this case all of the subexpressions can be null. + Then we add epsilon closures of the nodes which are the next nodes of + the back-references. */ + if (dfa->nbackref > 0) + for (i = 0; i < init_nodes.nelem; ++i) + { + Idx node_idx = init_nodes.elems[i]; + re_token_type_t type = dfa->nodes[node_idx].type; + + Idx clexp_idx; + if (type != OP_BACK_REF) + continue; + for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx) + { + re_token_t *clexp_node; + clexp_node = dfa->nodes + init_nodes.elems[clexp_idx]; + if (clexp_node->type == OP_CLOSE_SUBEXP + && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx) + break; + } + if (clexp_idx == init_nodes.nelem) + continue; + + if (type == OP_BACK_REF) + { + Idx dest_idx = dfa->edests[node_idx].elems[0]; + if (!re_node_set_contains (&init_nodes, dest_idx)) + { + reg_errcode_t merge_err + = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); + if (merge_err != REG_NOERROR) + return merge_err; + i = 0; + } + } + } + + /* 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 (__glibc_unlikely (dfa->init_state == NULL)) + return err; + if (dfa->init_state->has_constraint) + { + dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, + CONTEXT_WORD); + dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes, + CONTEXT_NEWLINE); + dfa->init_state_begbuf = re_acquire_state_context (&err, dfa, + &init_nodes, + CONTEXT_NEWLINE + | CONTEXT_BEGBUF); + if (__glibc_unlikely (dfa->init_state_word == NULL + || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL)) + return err; + } + else + dfa->init_state_word = dfa->init_state_nl + = dfa->init_state_begbuf = dfa->init_state; + + re_node_set_free (&init_nodes); + return REG_NOERROR; +} + +/* 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. */ + +static void +optimize_utf8 (re_dfa_t *dfa) +{ + Idx node; + int i; + bool mb_chars = false; + bool has_period = false; + + for (node = 0; node < dfa->nodes_len; ++node) + switch (dfa->nodes[node].type) + { + case CHARACTER: + if (dfa->nodes[node].opr.c >= ASCII_CHARS) + mb_chars = true; + break; + case ANCHOR: + switch (dfa->nodes[node].opr.ctx_type) + { + case LINE_FIRST: + case LINE_LAST: + case BUF_FIRST: + case BUF_LAST: + break; + default: + /* Word anchors etc. cannot be handled. It's okay to test + opr.ctx_type since constraints (for all DFA nodes) are + created by ORing one or more opr.ctx_type values. */ + return; + } + break; + case OP_PERIOD: + has_period = true; + break; + case OP_BACK_REF: + case OP_ALT: + case END_OF_RE: + case OP_DUP_ASTERISK: + case OP_OPEN_SUBEXP: + case OP_CLOSE_SUBEXP: + break; + case COMPLEX_BRACKET: + return; + case SIMPLE_BRACKET: + /* Just double check. */ + { + int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0 + ? 0 + : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS); + for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) + { + if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0) + return; + rshift = 0; + } + } + break; + default: + abort (); + } + + if (mb_chars || has_period) + for (node = 0; node < dfa->nodes_len; ++node) + { + if (dfa->nodes[node].type == CHARACTER + && dfa->nodes[node].opr.c >= ASCII_CHARS) + dfa->nodes[node].mb_partial = 0; + else if (dfa->nodes[node].type == OP_PERIOD) + dfa->nodes[node].type = OP_UTF8_PERIOD; + } + + /* The search can be in single byte locale. */ + dfa->mb_cur_max = 1; + dfa->is_utf8 = 0; + dfa->has_mb_node = dfa->nbackref > 0 || has_period; +} + +/* Analyze the structure tree, and calculate "first", "next", "edest", + "eclosure", and "inveclosure". */ + +static reg_errcode_t +analyze (regex_t *preg) +{ + re_dfa_t *dfa = preg->buffer; + reg_errcode_t ret; + + /* Allocate arrays. */ + dfa->nexts = re_malloc (Idx, dfa->nodes_alloc); + 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 (__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); + if (dfa->subexp_map != NULL) + { + Idx i; + for (i = 0; i < preg->re_nsub; i++) + dfa->subexp_map[i] = i; + preorder (dfa->str_tree, optimize_subexps, dfa); + for (i = 0; i < preg->re_nsub; i++) + if (dfa->subexp_map[i] != i) + break; + if (i == preg->re_nsub) + { + re_free (dfa->subexp_map); + dfa->subexp_map = NULL; + } + } + + ret = postorder (dfa->str_tree, lower_subexps, preg); + if (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + ret = postorder (dfa->str_tree, calc_first, dfa); + 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 (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + ret = calc_eclosure (dfa); + if (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + + /* We only need this during the prune_impossible_nodes pass in regexec.c; + skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */ + if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match) + || dfa->nbackref) + { + dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); + if (__glibc_unlikely (dfa->inveclosures == NULL)) + return REG_ESPACE; + ret = calc_inveclosure (dfa); + } + + return ret; +} + +/* Our parse trees are very unbalanced, so we cannot use a stack to + implement parse tree visits. Instead, we use parent pointers and + some hairy code in these two functions. */ +static reg_errcode_t +postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra) +{ + bin_tree_t *node, *prev; + + for (node = root; ; ) + { + /* Descend down the tree, preferably to the left (or to the right + if that's the only child). */ + while (node->left || node->right) + if (node->left) + node = node->left; + else + node = node->right; + + do + { + reg_errcode_t err = fn (extra, node); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + if (node->parent == NULL) + return REG_NOERROR; + prev = node; + node = node->parent; + } + /* Go up while we have a node that is reached from the right. */ + while (node->right == prev || node->right == NULL); + node = node->right; + } +} + +static reg_errcode_t +preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra) +{ + bin_tree_t *node; + + for (node = root; ; ) + { + reg_errcode_t err = fn (extra, node); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + + /* Go to the left node, or up and to the right. */ + if (node->left) + node = node->left; + else + { + bin_tree_t *prev = NULL; + while (node->right == prev || node->right == NULL) + { + prev = node; + node = node->parent; + if (!node) + return REG_NOERROR; + } + node = node->right; + } + } +} + +/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell + re_search_internal to map the inner one's opr.idx to this one's. Adjust + backreferences as well. Requires a preorder visit. */ +static reg_errcode_t +optimize_subexps (void *extra, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) extra; + + if (node->token.type == OP_BACK_REF && dfa->subexp_map) + { + int idx = node->token.opr.idx; + node->token.opr.idx = dfa->subexp_map[idx]; + dfa->used_bkref_map |= 1 << node->token.opr.idx; + } + + else if (node->token.type == SUBEXP + && node->left && node->left->token.type == SUBEXP) + { + Idx other_idx = node->left->token.opr.idx; + + node->left = node->left->left; + if (node->left) + node->left->parent = node; + + dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; + if (other_idx < BITSET_WORD_BITS) + dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx); + } + + return REG_NOERROR; +} + +/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation + of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP. */ +static reg_errcode_t +lower_subexps (void *extra, bin_tree_t *node) +{ + regex_t *preg = (regex_t *) extra; + reg_errcode_t err = REG_NOERROR; + + if (node->left && node->left->token.type == SUBEXP) + { + node->left = lower_subexp (&err, preg, node->left); + if (node->left) + node->left->parent = node; + } + if (node->right && node->right->token.type == SUBEXP) + { + node->right = lower_subexp (&err, preg, node->right); + if (node->right) + node->right->parent = node; + } + + return err; +} + +static bin_tree_t * +lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) +{ + re_dfa_t *dfa = preg->buffer; + bin_tree_t *body = node->left; + bin_tree_t *op, *cls, *tree1, *tree; + + if (preg->no_sub + /* We do not optimize empty subexpressions, because otherwise we may + have bad CONCAT nodes with NULL children. This is obviously not + very common, so we do not lose much. An example that triggers + this case is the sed "script" /\(\)/x. */ + && node->left != NULL + && (node->token.opr.idx >= BITSET_WORD_BITS + || !(dfa->used_bkref_map + & ((bitset_word_t) 1 << node->token.opr.idx)))) + return node->left; + + /* Convert the SUBEXP node to the concatenation of an + OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP. */ + op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP); + 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 (__glibc_unlikely (tree == NULL || tree1 == NULL + || op == NULL || cls == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + + op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx; + op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp; + return tree; +} + +/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton + nodes. Requires a postorder visit. */ +static reg_errcode_t +calc_first (void *extra, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) extra; + if (node->token.type == CONCAT) + { + node->first = node->left->first; + node->node_idx = node->left->node_idx; + } + else + { + node->first = node; + node->node_idx = re_dfa_add_node (dfa, node->token); + 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; + } + return REG_NOERROR; +} + +/* Pass 2: compute NEXT on the tree. Preorder visit. */ +static reg_errcode_t +calc_next (void *extra, bin_tree_t *node) +{ + switch (node->token.type) + { + case OP_DUP_ASTERISK: + node->left->next = node; + break; + case CONCAT: + node->left->next = node->right->first; + node->right->next = node->next; + break; + default: + if (node->left) + node->left->next = node->next; + if (node->right) + node->right->next = node->next; + break; + } + return REG_NOERROR; +} + +/* Pass 3: link all DFA nodes to their NEXT node (any order will do). */ +static reg_errcode_t +link_nfa_nodes (void *extra, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) extra; + Idx idx = node->node_idx; + reg_errcode_t err = REG_NOERROR; + + switch (node->token.type) + { + case CONCAT: + break; + + case END_OF_RE: + DEBUG_ASSERT (node->next == NULL); + break; + + case OP_DUP_ASTERISK: + case OP_ALT: + { + Idx left, right; + dfa->has_plural_match = 1; + if (node->left != NULL) + left = node->left->first->node_idx; + else + left = node->next->node_idx; + if (node->right != NULL) + right = node->right->first->node_idx; + else + right = node->next->node_idx; + DEBUG_ASSERT (left > -1); + DEBUG_ASSERT (right > -1); + err = re_node_set_init_2 (dfa->edests + idx, left, right); + } + break; + + case ANCHOR: + case OP_OPEN_SUBEXP: + case OP_CLOSE_SUBEXP: + err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx); + break; + + case OP_BACK_REF: + dfa->nexts[idx] = node->next->node_idx; + if (node->token.type == OP_BACK_REF) + err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); + break; + + default: + DEBUG_ASSERT (!IS_EPSILON_NODE (node->token.type)); + dfa->nexts[idx] = node->next->node_idx; + break; + } + + return err; +} + +/* Duplicate the epsilon closure of the node ROOT_NODE. + Note that duplicated nodes have constraint INIT_CONSTRAINT in addition + to their own constraint. */ + +static reg_errcode_t +duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, + Idx root_node, unsigned int init_constraint) +{ + Idx org_node, clone_node; + bool ok; + unsigned int constraint = init_constraint; + for (org_node = top_org_node, clone_node = top_clone_node;;) + { + Idx org_dest, clone_dest; + if (dfa->nodes[org_node].type == OP_BACK_REF) + { + /* If the back reference epsilon-transit, its destination must + also have the constraint. Then duplicate the epsilon closure + of the destination of the back reference, and store it in + edests of the back reference. */ + org_dest = dfa->nexts[org_node]; + re_node_set_empty (dfa->edests + clone_node); + clone_dest = duplicate_node (dfa, org_dest, constraint); + 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 (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + else if (dfa->edests[org_node].nelem == 0) + { + /* In case of the node can't epsilon-transit, don't duplicate the + destination and store the original destination as the + destination of the node. */ + dfa->nexts[clone_node] = dfa->nexts[org_node]; + break; + } + else if (dfa->edests[org_node].nelem == 1) + { + /* In case of the node can epsilon-transit, and it has only one + destination. */ + org_dest = dfa->edests[org_node].elems[0]; + re_node_set_empty (dfa->edests + clone_node); + /* If the node is root_node itself, it means the epsilon closure + has a loop. Then tie it to the destination of the root_node. */ + if (org_node == root_node && clone_node != org_node) + { + ok = re_node_set_insert (dfa->edests + clone_node, org_dest); + 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 (__glibc_unlikely (clone_dest == -1)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + else /* dfa->edests[org_node].nelem == 2 */ + { + /* In case of the node can epsilon-transit, and it has two + destinations. In the bin_tree_t and DFA, that's '|' and '*'. */ + org_dest = dfa->edests[org_node].elems[0]; + 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 == -1) + { + /* There is no such duplicated node, create a new one. */ + reg_errcode_t err; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (__glibc_unlikely (clone_dest == -1)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + err = duplicate_node_closure (dfa, org_dest, clone_dest, + root_node, constraint); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + else + { + /* 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 (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + + org_dest = dfa->edests[org_node].elems[1]; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (__glibc_unlikely (clone_dest == -1)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + org_node = org_dest; + clone_node = clone_dest; + } + return REG_NOERROR; +} + +/* Search for a node which is duplicated from the node ORG_NODE, and + satisfies the constraint CONSTRAINT. */ + +static Idx +search_duplicated_node (const re_dfa_t *dfa, Idx org_node, + unsigned int constraint) +{ + Idx idx; + for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) + { + if (org_node == dfa->org_indices[idx] + && constraint == dfa->nodes[idx].constraint) + return idx; /* 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 -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 (__glibc_likely (dup_idx != -1)) + { + dfa->nodes[dup_idx].constraint = constraint; + dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint; + dfa->nodes[dup_idx].duplicated = 1; + + /* Store the index of the original node. */ + dfa->org_indices[dup_idx] = org_idx; + } + return dup_idx; +} + +static reg_errcode_t +calc_inveclosure (re_dfa_t *dfa) +{ + Idx src, idx; + bool ok; + for (idx = 0; idx < dfa->nodes_len; ++idx) + re_node_set_init_empty (dfa->inveclosures + idx); + + for (src = 0; src < dfa->nodes_len; ++src) + { + Idx *elems = dfa->eclosures[src].elems; + for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) + { + ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + } + + return REG_NOERROR; +} + +/* Calculate "eclosure" for all the node in DFA. */ + +static reg_errcode_t +calc_eclosure (re_dfa_t *dfa) +{ + Idx node_idx; + bool incomplete; + DEBUG_ASSERT (dfa->nodes_len > 0); + incomplete = false; + /* For each nodes, calculate epsilon closure. */ + for (node_idx = 0; ; ++node_idx) + { + reg_errcode_t err; + re_node_set eclosure_elem; + if (node_idx == dfa->nodes_len) + { + if (!incomplete) + break; + incomplete = false; + node_idx = 0; + } + + 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + + if (dfa->eclosures[node_idx].nelem == 0) + { + incomplete = true; + re_node_set_free (&eclosure_elem); + } + } + return REG_NOERROR; +} + +/* Calculate epsilon closure of NODE. */ + +static reg_errcode_t +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 incomplete = false; + err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); + 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 = -1; + + /* If the current node has constraints, duplicate all nodes + since they must inherit the constraints. */ + if (dfa->nodes[node].constraint + && dfa->edests[node].nelem + && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) + { + err = duplicate_node_closure (dfa, node, node, node, + dfa->nodes[node].constraint); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + + /* Expand each epsilon destination nodes. */ + if (IS_EPSILON_NODE(dfa->nodes[node].type)) + for (i = 0; i < dfa->edests[node].nelem; ++i) + { + re_node_set eclosure_elem; + 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 == -1) + { + incomplete = true; + continue; + } + /* If we haven't calculated the epsilon closure of 'edest' yet, + calculate now. Otherwise use calculated epsilon closure. */ + if (dfa->eclosures[edest].nelem == 0) + { + err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); + 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + /* If the epsilon closure of 'edest' is incomplete, + the epsilon closure of this node is also incomplete. */ + if (dfa->eclosures[edest].nelem == 0) + { + incomplete = true; + re_node_set_free (&eclosure_elem); + } + } + + if (incomplete && !root) + dfa->eclosures[node].nelem = 0; + else + dfa->eclosures[node] = eclosure; + *new_set = eclosure; + return REG_NOERROR; +} + +/* Functions for token which are used in the parser. */ + +/* Fetch a token from INPUT. + We must not use this function inside bracket expressions. */ + +static void +fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) +{ + re_string_skip_bytes (input, peek_token (result, input, syntax)); +} + +/* Peek a token from INPUT, and return the length of the token. + We must not use this function inside bracket expressions. */ + +static int +peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) +{ + unsigned char c; + + if (re_string_eoi (input)) + { + token->type = END_OF_RE; + return 0; + } + + c = re_string_peek_byte (input, 0); + token->opr.c = c; + + token->word_char = 0; + token->mb_partial = 0; + 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; + } + if (c == '\\') + { + unsigned char c2; + if (re_string_cur_idx (input) + 1 >= re_string_length (input)) + { + token->type = BACK_SLASH; + return 1; + } + + c2 = re_string_peek_byte_case (input, 1); + token->opr.c = c2; + token->type = CHARACTER; + if (input->mb_cur_max > 1) + { + wint_t wc = re_string_wchar_at (input, + re_string_cur_idx (input) + 1); + token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; + } + else + token->word_char = IS_WORD_CHAR (c2) != 0; + + switch (c2) + { + case '|': + if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR)) + token->type = OP_ALT; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + if (!(syntax & RE_NO_BK_REFS)) + { + token->type = OP_BACK_REF; + token->opr.idx = c2 - '1'; + } + break; + case '<': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = WORD_FIRST; + } + break; + case '>': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = WORD_LAST; + } + break; + case 'b': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = WORD_DELIM; + } + break; + case 'B': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = NOT_WORD_DELIM; + } + break; + case 'w': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_WORD; + break; + case 'W': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_NOTWORD; + break; + case 's': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_SPACE; + break; + case 'S': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_NOTSPACE; + break; + case '`': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = BUF_FIRST; + } + break; + case '\'': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = BUF_LAST; + } + break; + case '(': + if (!(syntax & RE_NO_BK_PARENS)) + token->type = OP_OPEN_SUBEXP; + break; + case ')': + if (!(syntax & RE_NO_BK_PARENS)) + token->type = OP_CLOSE_SUBEXP; + break; + case '+': + if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_PLUS; + break; + case '?': + if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_QUESTION; + break; + case '{': + if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) + token->type = OP_OPEN_DUP_NUM; + break; + case '}': + if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) + token->type = OP_CLOSE_DUP_NUM; + break; + default: + break; + } + return 2; + } + + token->type = CHARACTER; + 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 + token->word_char = IS_WORD_CHAR (token->opr.c); + + switch (c) + { + case '\n': + if (syntax & RE_NEWLINE_ALT) + token->type = OP_ALT; + break; + case '|': + if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR)) + token->type = OP_ALT; + break; + case '*': + token->type = OP_DUP_ASTERISK; + break; + case '+': + if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_PLUS; + break; + case '?': + if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_QUESTION; + break; + case '{': + if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + token->type = OP_OPEN_DUP_NUM; + break; + case '}': + if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + token->type = OP_CLOSE_DUP_NUM; + break; + case '(': + if (syntax & RE_NO_BK_PARENS) + token->type = OP_OPEN_SUBEXP; + break; + case ')': + if (syntax & RE_NO_BK_PARENS) + token->type = OP_CLOSE_SUBEXP; + break; + case '[': + token->type = OP_OPEN_BRACKET; + break; + case '.': + token->type = OP_PERIOD; + break; + case '^': + 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') + break; + } + token->type = ANCHOR; + token->opr.ctx_type = LINE_FIRST; + break; + case '$': + 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); + peek_token (&next, input, syntax); + re_string_skip_bytes (input, -1); + if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP) + break; + } + token->type = ANCHOR; + token->opr.ctx_type = LINE_LAST; + break; + default: + break; + } + return 1; +} + +/* Peek a token from INPUT, and return the length of the token. + We must not use this function out of bracket expressions. */ + +static int +peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) +{ + unsigned char c; + if (re_string_eoi (input)) + { + token->type = END_OF_RE; + return 0; + } + c = re_string_peek_byte (input, 0); + token->opr.c = c; + + if (input->mb_cur_max > 1 + && !re_string_first_byte (input, re_string_cur_idx (input))) + { + token->type = CHARACTER; + return 1; + } + + if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) + && re_string_cur_idx (input) + 1 < re_string_length (input)) + { + /* In this case, '\' escape a character. */ + unsigned char c2; + re_string_skip_bytes (input, 1); + c2 = re_string_peek_byte (input, 0); + token->opr.c = c2; + token->type = CHARACTER; + return 1; + } + if (c == '[') /* '[' is a special char in a bracket exps. */ + { + unsigned char c2; + int token_len; + if (re_string_cur_idx (input) + 1 < re_string_length (input)) + c2 = re_string_peek_byte (input, 1); + else + c2 = 0; + token->opr.c = c2; + token_len = 2; + switch (c2) + { + 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; + } + FALLTHROUGH; + default: + token->type = CHARACTER; + token->opr.c = c; + token_len = 1; + break; + } + return token_len; + } + switch (c) + { + case '-': + token->type = OP_CHARSET_RANGE; + break; + case ']': + token->type = OP_CLOSE_BRACKET; + break; + case '^': + token->type = OP_NON_MATCH_LIST; + break; + default: + token->type = CHARACTER; + } + return 1; +} + +/* Functions for parser. */ + +/* Entry point of the parser. + Parse the regular expression REGEXP and return the structure tree. + If an error occurs, ERR is set by error code, and return NULL. + This function build the following tree, from regular expression : + CAT + / \ + / \ + EOR + + CAT means concatenation. + EOR means end of regular expression. */ + +static bin_tree_t * +parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, + reg_errcode_t *err) +{ + re_dfa_t *dfa = preg->buffer; + bin_tree_t *tree, *eor, *root; + re_token_t current_token; + 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 (__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 (__glibc_unlikely (eor == NULL || root == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + return root; +} + +/* This function build the following tree, from regular expression + |: + ALT + / \ + / \ + + + ALT means alternative, which represents the operator '|'. */ + +static bin_tree_t * +parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + 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 (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) + return NULL; + + while (token->type == OP_ALT) + { + fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); + 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 (__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 (__glibc_unlikely (tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + } + return tree; +} + +/* This function build the following tree, from regular expression + : + CAT + / \ + / \ + + + CAT means concatenation. */ + +static bin_tree_t * +parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + bin_tree_t *tree, *expr; + re_dfa_t *dfa = preg->buffer; + tree = parse_expression (regexp, preg, token, syntax, nest, err); + 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 (__glibc_unlikely (*err != REG_NOERROR && expr == NULL)) + { + if (tree != NULL) + postorder (tree, free_tree, NULL); + return NULL; + } + if (tree != NULL && expr != NULL) + { + bin_tree_t *newtree = create_tree (dfa, tree, expr, CONCAT); + if (newtree == NULL) + { + postorder (expr, free_tree, NULL); + postorder (tree, free_tree, NULL); + *err = REG_ESPACE; + return NULL; + } + tree = newtree; + } + else if (tree == NULL) + tree = expr; + /* Otherwise expr == NULL, we don't need to create new tree. */ + } + return tree; +} + +/* This function build the following tree, from regular expression a*: + * + | + a +*/ + +static bin_tree_t * +parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + re_dfa_t *dfa = preg->buffer; + bin_tree_t *tree; + switch (token->type) + { + case CHARACTER: + tree = create_token_tree (dfa, NULL, NULL, token); + if (__glibc_unlikely (tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + if (dfa->mb_cur_max > 1) + { + while (!re_string_eoi (regexp) + && !re_string_first_byte (regexp, re_string_cur_idx (regexp))) + { + bin_tree_t *mbc_remain; + fetch_token (token, regexp, syntax); + mbc_remain = create_token_tree (dfa, NULL, NULL, token); + tree = create_tree (dfa, tree, mbc_remain, CONCAT); + if (__glibc_unlikely (mbc_remain == NULL || tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + } + } + break; + + case OP_OPEN_SUBEXP: + tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); + 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 (__glibc_unlikely (*err != REG_NOERROR && tree == NULL)) + return NULL; + break; + + case OP_BACK_REF: + 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 (__glibc_unlikely (tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + ++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; + case OP_DUP_ASTERISK: + case OP_DUP_PLUS: + case OP_DUP_QUESTION: + if (syntax & RE_CONTEXT_INVALID_OPS) + { + *err = REG_BADRPT; + return NULL; + } + else if (syntax & RE_CONTEXT_INDEP_OPS) + { + fetch_token (token, regexp, syntax); + return parse_expression (regexp, preg, token, syntax, nest, err); + } + FALLTHROUGH; + case OP_CLOSE_SUBEXP: + if ((token->type == OP_CLOSE_SUBEXP) + && !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) + { + *err = REG_ERPAREN; + return NULL; + } + FALLTHROUGH; + case OP_CLOSE_DUP_NUM: + /* We treat it as a normal character. */ + + /* Then we can these characters as normal characters. */ + token->type = CHARACTER; + /* mb_partial and word_char bits should be initialized already + by peek_token. */ + tree = create_token_tree (dfa, NULL, NULL, token); + 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)) + && dfa->word_ops_used == 0) + init_word_char (dfa); + if (token->opr.ctx_type == WORD_DELIM + || token->opr.ctx_type == NOT_WORD_DELIM) + { + bin_tree_t *tree_first, *tree_last; + if (token->opr.ctx_type == WORD_DELIM) + { + token->opr.ctx_type = WORD_FIRST; + tree_first = create_token_tree (dfa, NULL, NULL, token); + token->opr.ctx_type = WORD_LAST; + } + else + { + token->opr.ctx_type = INSIDE_WORD; + tree_first = create_token_tree (dfa, NULL, NULL, token); + token->opr.ctx_type = INSIDE_NOTWORD; + } + tree_last = create_token_tree (dfa, NULL, NULL, token); + tree = create_tree (dfa, tree_first, tree_last, OP_ALT); + if (__glibc_unlikely (tree_first == NULL || tree_last == NULL + || tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + } + else + { + tree = create_token_tree (dfa, NULL, NULL, token); + if (__glibc_unlikely (tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + } + /* We must return here, since ANCHORs can't be followed + by repetition operators. + eg. RE"^*" is invalid or "", + it must not be "". */ + fetch_token (token, regexp, syntax); + return tree; + + case OP_PERIOD: + tree = create_token_tree (dfa, NULL, NULL, token); + if (__glibc_unlikely (tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + 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 (__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 (__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? */ + DEBUG_ASSERT (false); + return NULL; + } + fetch_token (token, regexp, syntax); + + while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS + || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) + { + 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; + } + } + + return tree; +} + +/* This function build the following tree, from regular expression + (): + SUBEXP + | + +*/ + +static bin_tree_t * +parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + re_dfa_t *dfa = preg->buffer; + bin_tree_t *tree; + size_t cur_nsub; + cur_nsub = preg->re_nsub++; + + fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); + + /* The subexpression may be a null string. */ + if (token->type == OP_CLOSE_SUBEXP) + tree = NULL; + else + { + tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); + if (__glibc_unlikely (*err == REG_NOERROR + && token->type != OP_CLOSE_SUBEXP)) + { + if (tree != NULL) + postorder (tree, free_tree, NULL); + *err = REG_EPAREN; + } + if (__glibc_unlikely (*err != REG_NOERROR)) + return NULL; + } + + if (cur_nsub <= '9' - '1') + dfa->completed_bkref_map |= 1 << cur_nsub; + + tree = create_tree (dfa, tree, NULL, SUBEXP); + if (__glibc_unlikely (tree == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + tree->token.opr.idx = cur_nsub; + return tree; +} + +/* This function parse repetition operators like "*", "+", "{1,3}" etc. */ + +static bin_tree_t * +parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, + re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) +{ + bin_tree_t *tree = NULL, *old_tree = NULL; + Idx i, start, end, start_idx = re_string_cur_idx (regexp); + re_token_t start_token = *token; + + if (token->type == OP_OPEN_DUP_NUM) + { + end = 0; + start = fetch_number (regexp, token, syntax); + if (start == -1) + { + if (token->type == CHARACTER && token->opr.c == ',') + start = 0; /* We treat "{,m}" as "{0,m}". */ + else + { + *err = REG_BADBR; /* {} is invalid. */ + return NULL; + } + } + 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) : -2)); + } + if (__glibc_unlikely (start == -2 || end == -2)) + { + /* Invalid sequence. */ + if (__glibc_unlikely (!(syntax & RE_INVALID_INTERVAL_ORD))) + { + if (token->type == END_OF_RE) + *err = REG_EBRACE; + else + *err = REG_BADBR; + + return NULL; + } + + /* If the syntax bit is set, rollback. */ + re_string_set_index (regexp, start_idx); + *token = start_token; + token->type = CHARACTER; + /* mb_partial and word_char bits should be already initialized by + peek_token. */ + return elem; + } + + if (__glibc_unlikely ((end != -1 && start > end) + || token->type != OP_CLOSE_DUP_NUM)) + { + /* First number greater than second. */ + *err = REG_BADBR; + return NULL; + } + + if (__glibc_unlikely (RE_DUP_MAX < (end == -1 ? start : end))) + { + *err = REG_ESIZE; + return NULL; + } + } + else + { + start = (token->type == OP_DUP_PLUS) ? 1 : 0; + end = (token->type == OP_DUP_QUESTION) ? 1 : -1; + } + + fetch_token (token, regexp, syntax); + + if (__glibc_unlikely (elem == NULL)) + return NULL; + if (__glibc_unlikely (start == 0 && end == 0)) + { + postorder (elem, free_tree, NULL); + return NULL; + } + + /* Extract "{n,m}" to "...{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 (__glibc_unlikely (elem == NULL || tree == NULL)) + goto parse_dup_op_espace; + } + + if (start == end) + return tree; + + /* 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 + old_tree = NULL; + + if (elem->token.type == SUBEXP) + { + uintptr_t subidx = elem->token.opr.idx; + postorder (elem, mark_opt_subexp, (void *) subidx); + } + + tree = create_tree (dfa, elem, NULL, + (end == -1 ? OP_DUP_ASTERISK : OP_ALT)); + if (__glibc_unlikely (tree == NULL)) + goto parse_dup_op_espace; + + /* 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 != -1) + for (i = start + 2; i <= end; ++i) + { + elem = duplicate_tree (elem, dfa); + tree = create_tree (dfa, tree, elem, CONCAT); + if (__glibc_unlikely (elem == NULL || tree == NULL)) + goto parse_dup_op_espace; + + tree = create_tree (dfa, tree, NULL, OP_ALT); + if (__glibc_unlikely (tree == NULL)) + goto parse_dup_op_espace; + } + + if (old_tree) + tree = create_tree (dfa, old_tree, tree, CONCAT); + + return tree; + + parse_dup_op_espace: + *err = REG_ESPACE; + return NULL; +} + +/* Size of the names for collating symbol/equivalence_class/character_class. + I'm not sure, but maybe enough. */ +#define BRACKET_NAME_BUF_SIZE 32 + +#ifndef _LIBC + +/* 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 +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) +{ + /* 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; + + /* We can handle no multi character collating elements without libc + support. */ + 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; + + unsigned int + 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)); + wint_t + start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) + ? parse_byte (start_ch, dfa) : start_elem->opr.wch), + end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) + ? parse_byte (end_ch, dfa) : end_elem->opr.wch); + + 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; + + /* 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; + + /* +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); + } + + return REG_NOERROR; +} +#endif /* not _LIBC */ + +#ifndef _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 +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 void *symb_table, const unsigned char *extra) +{ + size_t name_len = strlen ((const char *) name); + if (__glibc_unlikely (name_len != 1)) + return REG_ECOLLATE; + else + { + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } +} +#endif /* not _LIBC */ + +#ifdef _LIBC +/* 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; + + 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. + 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 (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 (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) + { + int32_t elem, idx; + elem = seek_collating_symbol_entry (br_elem->opr.name, + sym_name_len, + symb_table, table_size, + extra); + 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]]; + } + } + 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. */ + +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, 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) + { + /* Check the space of the arrays. */ + if (__glibc_unlikely (*range_alloc == mbcset->nranges)) + { + /* There is not enough space, need realloc. */ + uint32_t *new_array_start; + uint32_t *new_array_end; + int 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 (__glibc_unlikely (new_array_start == NULL + || new_array_end == NULL)) + 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_collseq; + mbcset->range_ends[mbcset->nranges++] = end_collseq; + } + + /* 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; +} + +/* 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) + { + elem = seek_collating_symbol_entry (name, name_len, symb_table, + table_size, extra); + 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 (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms)) + { + /* 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; + } + 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; + re_charset_t *mbcset; + Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; + Idx equiv_class_alloc = 0, char_class_alloc = 0; + bool non_match = false; + bin_tree_t *work_tree; + int token_len; + bool first_round = true; +#ifdef _LIBC + collseqmb = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); + nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules) + { + /* + if (MB_CUR_MAX > 1) + */ + collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); + table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); + 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); + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); + if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) + { + re_free (sbcset); + re_free (mbcset); + *err = REG_ESPACE; + return NULL; + } + + token_len = peek_token_bracket (token, regexp, syntax); + if (__glibc_unlikely (token->type == END_OF_RE)) + { + *err = REG_BADPAT; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_NON_MATCH_LIST) + { + mbcset->non_match = 1; + 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 (__glibc_unlikely (token->type == END_OF_RE)) + { + *err = REG_BADPAT; + goto parse_bracket_exp_free_return; + } + } + + /* We treat the first ']' as a normal character. */ + if (token->type == OP_CLOSE_BRACKET) + token->type = CHARACTER; + + while (1) + { + bracket_elem_t start_elem, end_elem; + unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE]; + unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE]; + reg_errcode_t ret; + int token_len2 = 0; + bool is_range_exp = false; + 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 (__glibc_unlikely (ret != REG_NOERROR)) + { + *err = ret; + goto parse_bracket_exp_free_return; + } + first_round = false; + + /* Get information about the next token. We need it in any case. */ + token_len = peek_token_bracket (token, regexp, syntax); + + /* Do not check for ranges if we know they are not allowed. */ + if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) + { + if (__glibc_unlikely (token->type == END_OF_RE)) + { + *err = REG_EBRACK; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_CHARSET_RANGE) + { + re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ + token_len2 = peek_token_bracket (&token2, regexp, syntax); + if (__glibc_unlikely (token2.type == END_OF_RE)) + { + *err = REG_EBRACK; + goto parse_bracket_exp_free_return; + } + if (token2.type == OP_CLOSE_BRACKET) + { + /* We treat the last '-' as a normal character. */ + re_string_skip_bytes (regexp, -token_len); + token->type = CHARACTER; + } + else + is_range_exp = true; + } + } + + 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 (__glibc_unlikely (ret != REG_NOERROR)) + { + *err = ret; + goto parse_bracket_exp_free_return; + } + + token_len = peek_token_bracket (token, regexp, syntax); + + *err = build_range_exp (sbcset, mbcset, &range_alloc, + &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 + { + switch (start_elem.type) + { + case SB_CHAR: + bitset_set (sbcset, start_elem.opr.ch); + break; + case MB_CHAR: + /* Check whether the array has enough space. */ + if (__glibc_unlikely (mbchar_alloc == mbcset->nmbchars)) + { + wchar_t *new_mbchars; + /* Not enough, realloc it. */ + /* +1 in case of mbcset->nmbchars is 0. */ + mbchar_alloc = 2 * mbcset->nmbchars + 1; + /* Use realloc since array is NULL if *alloc == 0. */ + new_mbchars = re_realloc (mbcset->mbchars, wchar_t, + mbchar_alloc); + if (__glibc_unlikely (new_mbchars == NULL)) + goto parse_bracket_exp_espace; + mbcset->mbchars = new_mbchars; + } + mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; + break; + case EQUIV_CLASS: + *err = build_equiv_class (sbcset, + mbcset, &equiv_class_alloc, + start_elem.opr.name); + if (__glibc_unlikely (*err != REG_NOERROR)) + goto parse_bracket_exp_free_return; + break; + case COLL_SYM: + *err = build_collating_symbol (sbcset, + mbcset, &coll_sym_alloc, + 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, + mbcset, &char_class_alloc, + (const char *) start_elem.opr.name, + syntax); + if (__glibc_unlikely (*err != REG_NOERROR)) + goto parse_bracket_exp_free_return; + break; + default: + DEBUG_ASSERT (false); + break; + } + } + if (__glibc_unlikely (token->type == END_OF_RE)) + { + *err = REG_EBRACK; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_CLOSE_BRACKET) + break; + } + + re_string_skip_bytes (regexp, token_len); /* Skip a token. */ + + /* If it is non-matching list. */ + if (non_match) + bitset_not (sbcset); + + /* Ensure only single byte characters are set. */ + if (dfa->mb_cur_max > 1) + bitset_mask (sbcset, dfa->sb_char); + + if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes + || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes + || mbcset->non_match))) + { + bin_tree_t *mbc_tree; + int sbc_idx; + /* Build a tree for complex bracket. */ + dfa->has_mb_node = 1; + br_token.type = COMPLEX_BRACKET; + br_token.opr.mbcset = mbcset; + mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); + 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]) + break; + /* If there are no bits set in sbcset, there is no point + of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */ + if (sbc_idx < BITSET_WORDS) + { + /* 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 (__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 (__glibc_unlikely (work_tree == NULL)) + goto parse_bracket_exp_espace; + } + else + { + re_free (sbcset); + work_tree = mbc_tree; + } + } + else + { + free_charset (mbcset); + /* 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 (__glibc_unlikely (work_tree == NULL)) + goto parse_bracket_exp_espace; + } + return work_tree; + + parse_bracket_exp_espace: + *err = REG_ESPACE; + parse_bracket_exp_free_return: + re_free (sbcset); + free_charset (mbcset); + return NULL; +} + +/* Parse an element in the bracket expression. */ + +static reg_errcode_t +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) +{ + int cur_char_size; + cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); + if (cur_char_size > 1) + { + elem->type = MB_CHAR; + elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp)); + re_string_skip_bytes (regexp, cur_char_size); + return REG_NOERROR; + } + 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 (__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. */ + re_token_t token2; + (void) peek_token_bracket (&token2, regexp, syntax); + if (token2.type != OP_CLOSE_BRACKET) + /* The actual error value is not standardized since this whole + case is undefined. But ERANGE makes good sense. */ + return REG_ERANGE; + } + elem->type = SB_CHAR; + elem->opr.ch = token->opr.c; + return REG_NOERROR; +} + +/* Parse a bracket symbol in the bracket expression. Bracket symbols are + such as [::], [..], and + [==]. */ + +static reg_errcode_t +parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, + re_token_t *token) +{ + unsigned char ch, delim = token->opr.c; + int i = 0; + if (re_string_eoi(regexp)) + return REG_EBRACK; + for (;; ++i) + { + if (i >= BRACKET_NAME_BUF_SIZE) + return REG_EBRACK; + if (token->type == OP_OPEN_CHAR_CLASS) + ch = re_string_fetch_byte_case (regexp); + else + ch = re_string_fetch_byte (regexp); + if (re_string_eoi(regexp)) + return REG_EBRACK; + if (ch == delim && re_string_peek_byte (regexp, 0) == ']') + break; + elem->opr.name[i] = ch; + } + re_string_skip_bytes (regexp, 1); + elem->opr.name[i] = '\0'; + switch (token->type) + { + case OP_OPEN_COLL_ELEM: + elem->type = COLL_SYM; + break; + case OP_OPEN_EQUIV_CLASS: + elem->type = EQUIV_CLASS; + break; + case OP_OPEN_CHAR_CLASS: + elem->type = CHAR_CLASS; + break; + default: + break; + } + return REG_NOERROR; +} + + /* Helper function for parse_bracket_exp. + Build the equivalence class which is represented by NAME. + The result are written to MBCSET and SBCSET. + EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes, + is a pointer argument since we may update it. */ + +static reg_errcode_t +build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, + Idx *equiv_class_alloc, const unsigned char *name) +{ +#ifdef _LIBC + uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules != 0) + { + const int32_t *table, *indirect; + const unsigned char *weights, *extra, *cp; + unsigned char char_buf[2]; + int32_t idx1, idx2; + unsigned int ch; + size_t len; + /* Calculate the index for equivalence class. */ + cp = name; + table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_INDIRECTMB); + idx1 = findidx (table, indirect, extra, &cp, -1); + if (__glibc_unlikely (idx1 == 0 || *cp != '\0')) + /* This isn't a valid character. */ + return REG_ECOLLATE; + + /* Build single byte matching table for this equivalence class. */ + len = weights[idx1 & 0xffffff]; + for (ch = 0; ch < SBC_MAX; ++ch) + { + char_buf[0] = ch; + cp = char_buf; + idx2 = findidx (table, indirect, extra, &cp, 1); +/* + idx2 = table[ch]; +*/ + if (idx2 == 0) + /* This isn't a valid character. */ + continue; + /* Compare only if the length matches and the collation rule + index is the same. */ + 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 (__glibc_unlikely (*equiv_class_alloc == mbcset->nequiv_classes)) + { + /* Not enough, realloc it. */ + /* +1 in case of mbcset->nequiv_classes is 0. */ + Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1; + /* Use realloc since the array is NULL if *alloc == 0. */ + int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, + int32_t, + new_equiv_class_alloc); + if (__glibc_unlikely (new_equiv_classes == NULL)) + return REG_ESPACE; + mbcset->equiv_classes = new_equiv_classes; + *equiv_class_alloc = new_equiv_class_alloc; + } + mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1; + } + else +#endif /* _LIBC */ + { + if (__glibc_unlikely (strlen ((const char *) name) != 1)) + return REG_ECOLLATE; + bitset_set (sbcset, *name); + } + return REG_NOERROR; +} + + /* Helper function for parse_bracket_exp. + Build the character class which is represented by NAME. + The result are written to MBCSET and SBCSET. + CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes, + is a pointer argument since we may update it. */ + +static reg_errcode_t +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) +{ + int i; + const char *name = class_name; + + /* In case of REG_ICASE "upper" and "lower" match the both of + upper and lower cases. */ + if ((syntax & RE_ICASE) + && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0)) + name = "alpha"; + + /* Check the space of the arrays. */ + if (__glibc_unlikely (*char_class_alloc == mbcset->nchar_classes)) + { + /* Not enough, realloc it. */ + /* +1 in case of mbcset->nchar_classes is 0. */ + Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1; + /* 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 (__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); + +#define BUILD_CHARCLASS_LOOP(ctype_func) \ + do { \ + if (__glibc_unlikely (trans != NULL)) \ + { \ + for (i = 0; i < SBC_MAX; ++i) \ + if (ctype_func (i)) \ + bitset_set (sbcset, trans[i]); \ + } \ + else \ + { \ + for (i = 0; i < SBC_MAX; ++i) \ + if (ctype_func (i)) \ + bitset_set (sbcset, i); \ + } \ + } while (0) + + if (strcmp (name, "alnum") == 0) + BUILD_CHARCLASS_LOOP (isalnum); + else if (strcmp (name, "cntrl") == 0) + BUILD_CHARCLASS_LOOP (iscntrl); + else if (strcmp (name, "lower") == 0) + BUILD_CHARCLASS_LOOP (islower); + else if (strcmp (name, "space") == 0) + BUILD_CHARCLASS_LOOP (isspace); + else if (strcmp (name, "alpha") == 0) + BUILD_CHARCLASS_LOOP (isalpha); + else if (strcmp (name, "digit") == 0) + BUILD_CHARCLASS_LOOP (isdigit); + else if (strcmp (name, "print") == 0) + BUILD_CHARCLASS_LOOP (isprint); + else if (strcmp (name, "upper") == 0) + BUILD_CHARCLASS_LOOP (isupper); + else if (strcmp (name, "blank") == 0) + BUILD_CHARCLASS_LOOP (isblank); + else if (strcmp (name, "graph") == 0) + BUILD_CHARCLASS_LOOP (isgraph); + else if (strcmp (name, "punct") == 0) + BUILD_CHARCLASS_LOOP (ispunct); + else if (strcmp (name, "xdigit") == 0) + BUILD_CHARCLASS_LOOP (isxdigit); + else + return REG_ECTYPE; + + return REG_NOERROR; +} + +static bin_tree_t * +build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, + const char *class_name, + const char *extra, bool non_match, + reg_errcode_t *err) +{ + re_bitset_ptr_t sbcset; + re_charset_t *mbcset; + Idx alloc = 0; + reg_errcode_t ret; + bin_tree_t *tree; + + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); + if (__glibc_unlikely (sbcset == NULL)) + { + *err = REG_ESPACE; + return NULL; + } + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); + if (__glibc_unlikely (mbcset == NULL)) + { + 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, mbcset, &alloc, class_name, 0); + + if (__glibc_unlikely (ret != REG_NOERROR)) + { + re_free (sbcset); + free_charset (mbcset); + *err = ret; + return NULL; + } + /* \w match '_' also. */ + for (; *extra; extra++) + bitset_set (sbcset, *extra); + + /* If it is non-matching list. */ + if (non_match) + bitset_not (sbcset); + + /* Ensure only single byte characters are set. */ + if (dfa->mb_cur_max > 1) + bitset_mask (sbcset, dfa->sb_char); + + /* Build a tree for simple bracket. */ + re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset }; + tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (__glibc_unlikely (tree == NULL)) + goto build_word_op_espace; + + if (dfa->mb_cur_max > 1) + { + bin_tree_t *mbc_tree; + /* Build a tree for complex bracket. */ + br_token.type = COMPLEX_BRACKET; + br_token.opr.mbcset = mbcset; + dfa->has_mb_node = 1; + mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); + 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 (__glibc_likely (mbc_tree != NULL)) + return tree; + } + else + { + free_charset (mbcset); + return tree; + } + + build_word_op_espace: + re_free (sbcset); + free_charset (mbcset); + *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 -1 if the number field is empty like "{,1}". + Return RE_DUP_MAX + 1 if the number field is too large. + Return -2 if an error occurred. */ + +static Idx +fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) +{ + Idx num = -1; + unsigned char c; + while (1) + { + fetch_token (token, input, syntax); + c = token->opr.c; + 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 == -2) + ? -2 + : num == -1 + ? c - '0' + : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); + } + return num; +} + +static void +free_charset (re_charset_t *cset) +{ + re_free (cset->mbchars); +#ifdef _LIBC + re_free (cset->coll_syms); + re_free (cset->equiv_classes); +#endif + re_free (cset->range_starts); + re_free (cset->range_ends); + re_free (cset->char_classes); + re_free (cset); +} + +/* Functions for binary tree operation. */ + +/* Create a tree node. */ + +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 = { .type = type }; + return create_token_tree (dfa, left, right, &t); +} + +static bin_tree_t * +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 (__glibc_unlikely (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE)) + { + bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); + + if (storage == NULL) + return NULL; + storage->next = dfa->str_tree_storage; + dfa->str_tree_storage = storage; + dfa->str_tree_storage_idx = 0; + } + tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++]; + + tree->parent = NULL; + tree->left = left; + tree->right = right; + tree->token = *token; + tree->token.duplicated = 0; + tree->token.opt_subexp = 0; + tree->first = NULL; + tree->next = NULL; + tree->node_idx = -1; + + if (left != NULL) + left->parent = tree; + if (right != NULL) + right->parent = tree; + return tree; +} + +/* Mark the tree SRC as an optional subexpression. + To be called from preorder or postorder. */ + +static reg_errcode_t +mark_opt_subexp (void *extra, bin_tree_t *node) +{ + Idx idx = (uintptr_t) extra; + if (node->token.type == SUBEXP && node->token.opr.idx == idx) + node->token.opt_subexp = 1; + + return REG_NOERROR; +} + +/* Free the allocated memory inside NODE. */ + +static void +free_token (re_token_t *node) +{ + if (node->type == COMPLEX_BRACKET && node->duplicated == 0) + free_charset (node->opr.mbcset); + 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 + and its children. */ + +static reg_errcode_t +free_tree (void *extra, bin_tree_t *node) +{ + free_token (&node->token); + return REG_NOERROR; +} + + +/* Duplicate the node SRC, and return new node. This is a preorder + visit similar to the one implemented by the generic visitor, but + we need more infrastructure to maintain two parallel trees --- so, + it's easier to duplicate. */ + +static bin_tree_t * +duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) +{ + const bin_tree_t *node; + bin_tree_t *dup_root; + bin_tree_t **p_new = &dup_root, *dup_node = root->parent; + + for (node = root; ; ) + { + /* Create a new tree and link it back to the current parent. */ + *p_new = create_token_tree (dfa, NULL, NULL, &node->token); + if (*p_new == NULL) + return NULL; + (*p_new)->parent = dup_node; + (*p_new)->token.duplicated = 1; + dup_node = *p_new; + + /* Go to the left node, or up and to the right. */ + if (node->left) + { + node = node->left; + p_new = &dup_node->left; + } + else + { + const bin_tree_t *prev = NULL; + while (node->right == prev || node->right == NULL) + { + prev = node; + node = node->parent; + dup_node = dup_node->parent; + if (!node) + return dup_root; + } + node = node->right; + p_new = &dup_node->right; + } + } +} diff --git a/lib/regex.c b/lib/regex.c new file mode 100644 index 0000000..ff11767 --- /dev/null +++ b/lib/regex.c @@ -0,0 +1,84 @@ +/* Extended regular expression matching and search library. + 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 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 + . */ + +#define __STDC_WANT_IEC_60559_BFP_EXT__ + +#ifndef _LIBC +# include + +# if __GNUC_PREREQ (4, 6) +# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" +# pragma GCC diagnostic ignored "-Wvla" +# endif +# if __GNUC_PREREQ (4, 3) +# pragma GCC diagnostic ignored "-Wold-style-definition" +# pragma GCC diagnostic ignored "-Wtype-limits" +# endif +#endif + +/* Make sure no one compiles this code with a C++ compiler. */ +#if defined __cplusplus && defined _LIBC +# error "This is C code, use a C compiler" +#endif + +#ifdef _LIBC +/* We have to keep the namespace clean. */ +# define regfree(preg) __regfree (preg) +# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) +# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) +# define regerror(errcode, preg, errbuf, errbuf_size) \ + __regerror(errcode, preg, errbuf, errbuf_size) +# define re_set_registers(bu, re, nu, st, en) \ + __re_set_registers (bu, re, nu, st, en) +# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ + __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) +# define re_match(bufp, string, size, pos, regs) \ + __re_match (bufp, string, size, pos, regs) +# define re_search(bufp, string, size, startpos, range, regs) \ + __re_search (bufp, string, size, startpos, range, regs) +# define re_compile_pattern(pattern, length, bufp) \ + __re_compile_pattern (pattern, length, bufp) +# define re_set_syntax(syntax) __re_set_syntax (syntax) +# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ + __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) +# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) + +# include "../locale/localeinfo.h" +#endif + +/* On some systems, limits.h sets RE_DUP_MAX to a lower value than + GNU regex allows. Include it before , which correctly + #undefs RE_DUP_MAX and sets it to the right value. */ +#include + +#include +#include "regex_internal.h" + +#include "regex_internal.c" +#include "regcomp.c" +#include "regexec.c" + +/* Binary backward compatibility. */ +#if _LIBC +# include +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) +link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.") +int re_max_failures = 2000; +# endif +#endif diff --git a/lib/regex.h b/lib/regex.h new file mode 100644 index 0000000..a7e0bd0 --- /dev/null +++ b/lib/regex.h @@ -0,0 +1,699 @@ +/* Definitions for data structures and routines for the regular + expression library. + 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 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 _REGEX_H +#define _REGEX_H 1 + +#include + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Define __USE_GNU to declare GNU extensions that violate the + POSIX name space rules. */ +#ifdef _GNU_SOURCE +# define __USE_GNU 1 +#endif + +#ifdef _REGEX_LARGE_OFFSETS + +/* Use types and values that are wide enough to represent signed and + unsigned byte offsets in memory. This currently works only when + the regex code is used outside of the GNU C library; it is not yet + supported within glibc itself, and glibc users should not define + _REGEX_LARGE_OFFSETS. */ + +/* The type of object sizes. */ +typedef size_t __re_size_t; + +/* The type of object sizes, in places where the traditional code + uses unsigned long int. */ +typedef size_t __re_long_size_t; + +#else + +/* The traditional GNU regex implementation mishandles strings longer + than INT_MAX. */ +typedef unsigned int __re_size_t; +typedef unsigned long int __re_long_size_t; + +#endif + +/* The following two types have to be signed and unsigned integer type + wide enough to hold a value of a pointer. For most ANSI compilers + ptrdiff_t and size_t should be likely OK. Still size of these two + types is 2 for Microsoft C. Ugh... */ +typedef long int s_reg_t; +typedef unsigned long int active_reg_t; + +/* The following bits are used to determine the regexp syntax we + recognize. The set/not-set meanings are chosen so that Emacs syntax + remains the value 0. The bits are given in alphabetical order, and + the definitions shifted by one from the previous bit; thus, when we + add or remove a bit, only one other definition need change. */ +typedef unsigned long int reg_syntax_t; + +#ifdef __USE_GNU +/* If this bit is not set, then \ inside a bracket expression is literal. + If set, then such a \ quotes the following character. */ +# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) + +/* If this bit is not set, then + and ? are operators, and \+ and \? are + literals. + If set, then \+ and \? are operators and + and ? are literals. */ +# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) + +/* If this bit is set, then character classes are supported. They are: + [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], + [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. + If not set, then character classes are not supported. */ +# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) + +/* If this bit is set, then ^ and $ are always anchors (outside bracket + expressions, of course). + If this bit is not set, then it depends: + ^ is an anchor if it is at the beginning of a regular + expression or after an open-group or an alternation operator; + $ is an anchor if it is at the end of a regular expression, or + before a close-group or an alternation operator. + + This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because + POSIX draft 11.2 says that * etc. in leading positions is undefined. + We already implemented a previous draft which made those constructs + invalid, though, so we haven't changed the code back. */ +# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) + +/* If this bit is set, then special characters are always special + regardless of where they are in the pattern. + If this bit is not set, then special characters are special only in + some contexts; otherwise they are ordinary. Specifically, + * + ? and intervals are only special when not after the beginning, + open-group, or alternation operator. */ +# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) + +/* If this bit is set, then *, +, ?, and { cannot be first in an re or + immediately after an alternation or begin-group operator. */ +# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) + +/* If this bit is set, then . matches newline. + If not set, then it doesn't. */ +# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) + +/* If this bit is set, then . doesn't match NUL. + If not set, then it does. */ +# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) + +/* If this bit is set, nonmatching lists [^...] do not match newline. + If not set, they do. */ +# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) + +/* If this bit is set, either \{...\} or {...} defines an + interval, depending on RE_NO_BK_BRACES. + If not set, \{, \}, {, and } are literals. */ +# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) + +/* If this bit is set, +, ? and | aren't recognized as operators. + If not set, they are. */ +# define RE_LIMITED_OPS (RE_INTERVALS << 1) + +/* If this bit is set, newline is an alternation operator. + If not set, newline is literal. */ +# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) + +/* If this bit is set, then '{...}' defines an interval, and \{ and \} + are literals. + If not set, then '\{...\}' defines an interval. */ +# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) + +/* If this bit is set, (...) defines a group, and \( and \) are literals. + If not set, \(...\) defines a group, and ( and ) are literals. */ +# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) + +/* If this bit is set, then \ matches . + If not set, then \ is a back-reference. */ +# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) + +/* If this bit is set, then | is an alternation operator, and \| is literal. + If not set, then \| is an alternation operator, and | is literal. */ +# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) + +/* If this bit is set, then an ending range point collating higher + than the starting range point, as in [z-a], is invalid. + If not set, then when ending range point collates higher than the + starting range point, the range is ignored. */ +# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) + +/* If this bit is set, then an unmatched ) is ordinary. + If not set, then an unmatched ) is invalid. */ +# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) + +/* If this bit is set, succeed as soon as we match the whole pattern, + without further backtracking. */ +# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) + +/* If this bit is set, do not process the GNU regex operators. + If not set, then the GNU regex operators are recognized. */ +# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) + +/* If this bit is set, turn on internal regex debugging. + If not set, and debugging was on, turn it off. + This only works if regex.c is compiled -DDEBUG. + We define this bit always, so that all that's needed to turn on + debugging is to recompile regex.c; the calling code can always have + this bit set, and it won't affect anything in the normal case. */ +# define RE_DEBUG (RE_NO_GNU_OPS << 1) + +/* If this bit is set, a syntactically invalid interval is treated as + a string of ordinary characters. For example, the ERE 'a{1' is + treated as 'a\{1'. */ +# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) + +/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only + for ^, because it is difficult to scan the regex backwards to find + whether ^ should be special. */ +# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1) + +/* If this bit is set, then \{ cannot be first in a regex or + immediately after an alternation, open-group or \} operator. */ +# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1) + +/* If this bit is set, then no_sub will be set to 1 during + re_compile_pattern. */ +# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1) +#endif + +/* This global variable defines the particular regexp syntax to use (for + some interfaces). When a regexp is compiled, the syntax used is + stored in the pattern buffer, so changing this does not affect + already-compiled regexps. */ +extern reg_syntax_t re_syntax_options; + +#ifdef __USE_GNU +/* Define combinations of the above bits for the standard possibilities. + (The [[[ comments delimit what gets put into the Texinfo file, so + don't delete them!) */ +/* [[[begin syntaxes]]] */ +# define RE_SYNTAX_EMACS 0 + +# define RE_SYNTAX_AWK \ + (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CHAR_CLASSES \ + | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) + +# define RE_SYNTAX_GNU_AWK \ + ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ + | RE_INVALID_INTERVAL_ORD) \ + & ~(RE_DOT_NOT_NULL | RE_CONTEXT_INDEP_OPS \ + | RE_CONTEXT_INVALID_OPS )) + +# define RE_SYNTAX_POSIX_AWK \ + (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ + | RE_INTERVALS | RE_NO_GNU_OPS \ + | RE_INVALID_INTERVAL_ORD) + +# define RE_SYNTAX_GREP \ + ((RE_SYNTAX_POSIX_BASIC | RE_NEWLINE_ALT) \ + & ~(RE_CONTEXT_INVALID_DUP | RE_DOT_NOT_NULL)) + +# define RE_SYNTAX_EGREP \ + ((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 + +/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ +# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC + +# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC + +/* Syntax bits common to both basic and extended POSIX regex syntax. */ +# define _RE_SYNTAX_POSIX_COMMON \ + (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ + | RE_INTERVALS | RE_NO_EMPTY_RANGES) + +# define RE_SYNTAX_POSIX_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP) + +/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes + RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this + isn't minimal, since other operators, such as \`, aren't disabled. */ +# define RE_SYNTAX_POSIX_MINIMAL_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) + +# define RE_SYNTAX_POSIX_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ + | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) + +/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is + removed and RE_NO_BK_REFS is added. */ +# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) +/* [[[end syntaxes]]] */ + +/* Maximum number of duplicates an interval can allow. POSIX-conforming + systems might define this in , but we want our + value, so remove any previous define. */ +# ifdef _REGEX_INCLUDE_LIMITS_H +# include +# endif +# ifdef RE_DUP_MAX +# undef RE_DUP_MAX +# endif + +/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored + the counter as a 2-byte signed integer. This is no longer true, so + RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to + ((SIZE_MAX - 9) / 10) if _REGEX_LARGE_OFFSETS is defined. + However, there would be a huge performance problem if someone + actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains + its historical value. */ +# define RE_DUP_MAX (0x7fff) +#endif + + +/* POSIX 'cflags' bits (i.e., information for 'regcomp'). */ + +/* If this bit is set, then use extended regular expression syntax. + If not set, then use basic regular expression syntax. */ +#define REG_EXTENDED 1 + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +#define REG_ICASE (1 << 1) + +/* If this bit is set, then anchors do not match at newline + characters in the string. + If not set, then anchors do match at newlines. */ +#define REG_NEWLINE (1 << 2) + +/* If this bit is set, then report only success or fail in regexec. + If not set, then returns differ between not matching and errors. */ +#define REG_NOSUB (1 << 3) + + +/* POSIX 'eflags' bits (i.e., information for regexec). */ + +/* If this bit is set, then the beginning-of-line operator doesn't match + the beginning of the string (presumably because it's not the + beginning of a line). + If not set, then the beginning-of-line operator does match the + beginning of the string. */ +#define REG_NOTBOL 1 + +/* Like REG_NOTBOL, except for the end-of-line. */ +#define REG_NOTEOL (1 << 1) + +/* Use PMATCH[0] to delimit the start and end of the search in the + buffer. */ +#define REG_STARTEND (1 << 2) + + +/* If any error codes are removed, changed, or added, update the + '__re_error_msgid' table in regcomp.c. */ + +typedef enum +{ + _REG_ENOSYS = -1, /* This will never happen for this implementation. */ + _REG_NOERROR = 0, /* Success. */ + _REG_NOMATCH, /* Didn't find a match (for regexec). */ + + /* POSIX regcomp return error codes. (In the order listed in the + standard.) */ + _REG_BADPAT, /* Invalid pattern. */ + _REG_ECOLLATE, /* Invalid collating element. */ + _REG_ECTYPE, /* Invalid character class name. */ + _REG_EESCAPE, /* Trailing backslash. */ + _REG_ESUBREG, /* Invalid back reference. */ + _REG_EBRACK, /* Unmatched left bracket. */ + _REG_EPAREN, /* Parenthesis imbalance. */ + _REG_EBRACE, /* Unmatched \{. */ + _REG_BADBR, /* Invalid contents of \{\}. */ + _REG_ERANGE, /* Invalid range end. */ + _REG_ESPACE, /* Ran out of memory. */ + _REG_BADRPT, /* No preceding re for repetition op. */ + + /* Error codes we've added. */ + _REG_EEND, /* Premature end. */ + _REG_ESIZE, /* Too large (e.g., repeat count too large). */ + _REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ +} reg_errcode_t; + +#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K +# define REG_ENOSYS _REG_ENOSYS +#endif +#define REG_NOERROR _REG_NOERROR +#define REG_NOMATCH _REG_NOMATCH +#define REG_BADPAT _REG_BADPAT +#define REG_ECOLLATE _REG_ECOLLATE +#define REG_ECTYPE _REG_ECTYPE +#define REG_EESCAPE _REG_EESCAPE +#define REG_ESUBREG _REG_ESUBREG +#define REG_EBRACK _REG_EBRACK +#define REG_EPAREN _REG_EPAREN +#define REG_EBRACE _REG_EBRACE +#define REG_BADBR _REG_BADBR +#define REG_ERANGE _REG_ERANGE +#define REG_ESPACE _REG_ESPACE +#define REG_BADRPT _REG_BADRPT +#define REG_EEND _REG_EEND +#define REG_ESIZE _REG_ESIZE +#define REG_ERPAREN _REG_ERPAREN + +/* This data structure represents a compiled pattern. Before calling + the pattern compiler, the fields 'buffer', 'allocated', 'fastmap', + and 'translate' can be set. After the pattern has been compiled, + the fields 're_nsub', 'not_bol' and 'not_eol' are available. All + other fields are private to the regex routines. */ + +#ifndef RE_TRANSLATE_TYPE +# define __RE_TRANSLATE_TYPE unsigned char * +# ifdef __USE_GNU +# define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE +# endif +#endif + +#ifdef __USE_GNU +# define __REPB_PREFIX(name) name +#else +# define __REPB_PREFIX(name) __##name +#endif + +struct re_pattern_buffer +{ + /* Space that holds the compiled pattern. The type + 'struct re_dfa_t' is private and is not declared here. */ + struct re_dfa_t *__REPB_PREFIX(buffer); + + /* Number of bytes to which 'buffer' points. */ + __re_long_size_t __REPB_PREFIX(allocated); + + /* Number of bytes actually used in 'buffer'. */ + __re_long_size_t __REPB_PREFIX(used); + + /* Syntax setting with which the pattern was compiled. */ + reg_syntax_t __REPB_PREFIX(syntax); + + /* Pointer to a fastmap, if any, otherwise zero. re_search uses the + fastmap, if there is one, to skip over impossible starting points + for matches. */ + char *__REPB_PREFIX(fastmap); + + /* Either a translate table to apply to all characters before + comparing them, or zero for no translation. The translation is + applied to a pattern when it is compiled and to a string when it + is matched. */ + __RE_TRANSLATE_TYPE __REPB_PREFIX(translate); + + /* Number of subexpressions found by the compiler. */ + size_t re_nsub; + + /* Zero if this pattern cannot match the empty string, one else. + Well, in truth it's used only in 're_search_2', to see whether or + not we should use the fastmap, so we don't set this absolutely + perfectly; see 're_compile_fastmap' (the "duplicate" case). */ + unsigned __REPB_PREFIX(can_be_null) : 1; + + /* If REGS_UNALLOCATED, allocate space in the 'regs' structure + for 'max (RE_NREGS, re_nsub + 1)' groups. + If REGS_REALLOCATE, reallocate space if necessary. + If REGS_FIXED, use what's there. */ +#ifdef __USE_GNU +# define REGS_UNALLOCATED 0 +# define REGS_REALLOCATE 1 +# define REGS_FIXED 2 +#endif + unsigned __REPB_PREFIX(regs_allocated) : 2; + + /* Set to zero when 're_compile_pattern' compiles a pattern; set to + one by 're_compile_fastmap' if it updates the fastmap. */ + unsigned __REPB_PREFIX(fastmap_accurate) : 1; + + /* If set, 're_match_2' does not return information about + subexpressions. */ + unsigned __REPB_PREFIX(no_sub) : 1; + + /* If set, a beginning-of-line anchor doesn't match at the beginning + of the string. */ + unsigned __REPB_PREFIX(not_bol) : 1; + + /* Similarly for an end-of-line anchor. */ + unsigned __REPB_PREFIX(not_eol) : 1; + + /* If true, an anchor at a newline matches. */ + unsigned __REPB_PREFIX(newline_anchor) : 1; +}; + +typedef struct re_pattern_buffer regex_t; + +/* Type for byte offsets within the string. POSIX mandates this. */ +#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. ptrdiff_t is not + visible here, so use ssize_t. */ +typedef ssize_t regoff_t; +#else +/* The traditional GNU regex implementation mishandles strings longer + than INT_MAX. */ +typedef int regoff_t; +#endif + + +#ifdef __USE_GNU +/* This is the structure we store register match data in. See + regex.texinfo for a full description of what registers match. */ +struct re_registers +{ + __re_size_t num_regs; + regoff_t *start; + regoff_t *end; +}; + + +/* If 'regs_allocated' is REGS_UNALLOCATED in the pattern buffer, + 're_match_2' returns information about at least this many registers + the first time a 'regs' structure is passed. */ +# ifndef RE_NREGS +# define RE_NREGS 30 +# endif +#endif + + +/* POSIX specification for registers. Aside from the different names than + 're_registers', POSIX uses an array of structures, instead of a + structure of arrays. */ +typedef struct +{ + regoff_t rm_so; /* Byte offset from string's start to substring's start. */ + regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ +} regmatch_t; + +/* 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. */ +extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); + +/* Compile the regular expression PATTERN, with length LENGTH + and syntax given by the global 're_syntax_options', into the buffer + 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 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) + _Attr_access_ ((__read_only__, 1, 2)); + + +/* Compile a fastmap for the compiled pattern in BUFFER; used to + accelerate searches. Return 0 if successful and -2 if was an + internal error. */ +extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); + + +/* Search in the string STRING (with length LENGTH) for the pattern + compiled into BUFFER. Start searching at position START, for RANGE + characters. Return the starting position of the match, -1 for no + 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, 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, regoff_t __length1, + const char *__string2, regoff_t __length2, + regoff_t __start, regoff_t __range, + struct re_registers *__regs, + 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, 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, 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 + ENDS. Subsequent matches using BUFFER and REGS will use this memory + for recording register information. STARTS and ENDS must be + allocated with malloc, and must each be at least 'NUM_REGS * sizeof + (regoff_t)' bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + BUFFER will allocate its own register data, without + freeing the old data. */ +extern void re_set_registers (struct re_pattern_buffer *__buffer, + struct re_registers *__regs, + __re_size_t __num_regs, + regoff_t *__starts, regoff_t *__ends); +#endif /* Use GNU */ + +#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 + +/* 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 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 +/* 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_ +# 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_ +# endif +#endif + +/* POSIX compatibility. */ +extern int regcomp (regex_t *_Restrict_ __preg, + const char *_Restrict_ __pattern, + int __cflags); + +extern int regexec (const regex_t *_Restrict_ __preg, + 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) + _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 +} +#endif /* C++ */ + +#endif /* regex.h */ diff --git a/lib/regex_internal.c b/lib/regex_internal.c new file mode 100644 index 0000000..3945ee7 --- /dev/null +++ b/lib/regex_internal.c @@ -0,0 +1,1713 @@ +/* Extended regular expression matching and search library. + 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 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 + . */ + +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); +static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, + const re_node_set *nodes, + 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); +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. */ + +/* This function allocate the buffers. It is necessary to call + re_string_reconstruct before using the object. */ + +static reg_errcode_t +__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) +{ + reg_errcode_t ret; + Idx init_buf_len; + + /* Ensure at least one character fits into the buffers. */ + if (init_len < dfa->mb_cur_max) + init_len = dfa->mb_cur_max; + init_buf_len = (len + 1 < init_len) ? len + 1: init_len; + re_string_construct_common (str, len, pstr, trans, icase, dfa); + + ret = re_string_realloc_buffers (pstr, init_buf_len); + if (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + + pstr->word_char = dfa->word_char; + pstr->word_ops_used = dfa->word_ops_used; + pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; + pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len; + pstr->valid_raw_len = pstr->valid_len; + return REG_NOERROR; +} + +/* This function allocate the buffers, and initialize them. */ + +static reg_errcode_t +__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) +{ + reg_errcode_t ret; + memset (pstr, '\0', sizeof (re_string_t)); + re_string_construct_common (str, len, pstr, trans, icase, dfa); + + if (len > 0) + { + ret = re_string_realloc_buffers (pstr, len + 1); + if (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + } + pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; + + if (icase) + { + if (dfa->mb_cur_max > 1) + { + while (1) + { + ret = build_wcs_upper_buffer (pstr); + 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 (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + } + } + else + build_upper_buffer (pstr); + } + else + { + if (dfa->mb_cur_max > 1) + build_wcs_buffer (pstr); + else + { + if (trans != NULL) + re_string_translate_buffer (pstr); + else + { + pstr->valid_len = pstr->bufs_len; + pstr->valid_raw_len = pstr->bufs_len; + } + } + } + + return REG_NOERROR; +} + +/* Helper functions for re_string_allocate, and re_string_construct. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) +{ + 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 (__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 (__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 (__glibc_unlikely (new_offsets == NULL)) + return REG_ESPACE; + pstr->offsets = new_offsets; + } + } + if (pstr->mbs_allocated) + { + unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, + new_buf_len); + if (__glibc_unlikely (new_mbs == NULL)) + return REG_ESPACE; + pstr->mbs = new_mbs; + } + pstr->bufs_len = new_buf_len; + return REG_NOERROR; +} + + +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) +{ + pstr->raw_mbs = (const unsigned char *) str; + pstr->len = len; + pstr->raw_len = len; + pstr->trans = trans; + pstr->icase = icase; + pstr->mbs_allocated = (trans != NULL || icase); + pstr->mb_cur_max = dfa->mb_cur_max; + pstr->is_utf8 = dfa->is_utf8; + pstr->map_notascii = dfa->map_notascii; + pstr->stop = pstr->len; + pstr->raw_stop = pstr->stop; +} + + +/* Build wide character buffer PSTR->WCS. + If the byte sequence of the string are: + (0), (1), (0), (1), + Then wide character buffer will be: + , WEOF , , WEOF , + We use WEOF for padding, they indicate that the position isn't + a first byte of a multibyte character. + + Note that this function assumes PSTR->VALID_LEN elements are already + built and starts from PSTR->VALID_LEN. */ + +static void +build_wcs_buffer (re_string_t *pstr) +{ +#ifdef _LIBC + unsigned char buf[MB_LEN_MAX]; + DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max); +#else + unsigned char buf[64]; +#endif + mbstate_t prev_st; + Idx byte_idx, end_idx, remain_len; + size_t mbclen; + + /* Build the buffers from pstr->valid_len to either pstr->len or + pstr->bufs_len. */ + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + for (byte_idx = pstr->valid_len; byte_idx < end_idx;) + { + wchar_t wc; + const char *p; + + remain_len = end_idx - byte_idx; + prev_st = pstr->cur_state; + /* Apply the translation if we need. */ + if (__glibc_unlikely (pstr->trans != NULL)) + { + int i, ch; + + for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) + { + ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i]; + buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch]; + } + p = (const char *) buf; + } + else + p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; + mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); + 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 (__glibc_unlikely (pstr->trans != NULL)) + wc = pstr->trans[wc]; + pstr->cur_state = prev_st; + } + else if (__glibc_unlikely (mbclen == (size_t) -2)) + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + + /* Write wide character and padding. */ + pstr->wcs[byte_idx++] = wc; + /* Write paddings. */ + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } + pstr->valid_len = byte_idx; + pstr->valid_raw_len = byte_idx; +} + +/* Build wide character buffer PSTR->WCS like build_wcs_buffer, + but for REG_ICASE. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +build_wcs_upper_buffer (re_string_t *pstr) +{ + mbstate_t prev_st; + Idx src_idx, byte_idx, end_idx, remain_len; + size_t mbclen; +#ifdef _LIBC + char buf[MB_LEN_MAX]; + DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX); +#else + char buf[64]; +#endif + + byte_idx = pstr->valid_len; + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + + /* The following optimization assumes that ASCII characters can be + mapped to wide characters with a simple cast. */ + if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed) + { + while (byte_idx < end_idx) + { + wchar_t wc; + unsigned char ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; + + if (isascii (ch) && mbsinit (&pstr->cur_state)) + { + /* The next step uses the assumption that wchar_t is encoded + ASCII-safe: all ASCII values can be converted like this. */ + 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; + prev_st = pstr->cur_state; + mbclen = __mbrtowc (&wc, + ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx + + byte_idx), remain_len, &pstr->cur_state); + if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2)) + { + wchar_t wcu = __towupper (wc); + if (wcu != wc) + { + size_t mbcdlen; + + mbcdlen = __wcrtomb (buf, wcu, &prev_st); + if (__glibc_likely (mbclen == mbcdlen)) + memcpy (pstr->mbs + byte_idx, buf, mbclen); + else + { + src_idx = byte_idx; + goto offsets_needed; + } + } + else + memcpy (pstr->mbs + byte_idx, + pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen); + pstr->wcs[byte_idx++] = wcu; + /* Write paddings. */ + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } + else if (mbclen == (size_t) -1 || mbclen == 0 + || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) + { + /* It is an invalid character, an incomplete character + at the end of the string, or '\0'. Just use the byte. */ + pstr->mbs[byte_idx] = ch; + /* And also cast it to wide char. */ + pstr->wcs[byte_idx++] = (wchar_t) ch; + if (__glibc_unlikely (mbclen == (size_t) -1)) + pstr->cur_state = prev_st; + } + else + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + } + pstr->valid_len = byte_idx; + pstr->valid_raw_len = byte_idx; + return REG_NOERROR; + } + else + for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;) + { + wchar_t wc; + const char *p; + offsets_needed: + remain_len = end_idx - byte_idx; + prev_st = pstr->cur_state; + if (__glibc_unlikely (pstr->trans != NULL)) + { + int i, ch; + + for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) + { + ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i]; + buf[i] = pstr->trans[ch]; + } + p = (const char *) buf; + } + else + p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; + mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); + if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2)) + { + wchar_t wcu = __towupper (wc); + if (wcu != wc) + { + size_t mbcdlen; + + 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) + { + size_t i; + + if (byte_idx + mbcdlen > pstr->bufs_len) + { + pstr->cur_state = prev_st; + break; + } + + if (pstr->offsets == NULL) + { + pstr->offsets = re_malloc (Idx, pstr->bufs_len); + + if (pstr->offsets == NULL) + return REG_ESPACE; + } + if (!pstr->offsets_needed) + { + for (i = 0; i < (size_t) byte_idx; ++i) + pstr->offsets[i] = i; + pstr->offsets_needed = 1; + } + + memcpy (pstr->mbs + byte_idx, buf, mbcdlen); + pstr->wcs[byte_idx] = wcu; + pstr->offsets[byte_idx] = src_idx; + for (i = 1; i < mbcdlen; ++i) + { + pstr->offsets[byte_idx + i] + = src_idx + (i < mbclen ? i : mbclen - 1); + pstr->wcs[byte_idx + i] = WEOF; + } + pstr->len += mbcdlen - mbclen; + if (pstr->raw_stop > src_idx) + pstr->stop += mbcdlen - mbclen; + end_idx = (pstr->bufs_len > pstr->len) + ? pstr->len : pstr->bufs_len; + byte_idx += mbcdlen; + src_idx += mbclen; + continue; + } + else + memcpy (pstr->mbs + byte_idx, p, mbclen); + } + else + memcpy (pstr->mbs + byte_idx, p, mbclen); + + if (__glibc_unlikely (pstr->offsets_needed != 0)) + { + size_t i; + for (i = 0; i < mbclen; ++i) + pstr->offsets[byte_idx + i] = src_idx + i; + } + src_idx += mbclen; + + pstr->wcs[byte_idx++] = wcu; + /* Write paddings. */ + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } + else if (mbclen == (size_t) -1 || mbclen == 0 + || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) + { + /* It is an invalid character or '\0'. Just use the byte. */ + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; + + if (__glibc_unlikely (pstr->trans != NULL)) + ch = pstr->trans [ch]; + pstr->mbs[byte_idx] = ch; + + 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 (__glibc_unlikely (mbclen == (size_t) -1)) + pstr->cur_state = prev_st; + } + else + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + } + pstr->valid_len = byte_idx; + pstr->valid_raw_len = src_idx; + return REG_NOERROR; +} + +/* Skip characters until the index becomes greater than NEW_RAW_IDX. + Return the index. */ + +static Idx +re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) +{ + mbstate_t prev_st; + Idx rawbuf_idx; + size_t mbclen; + wint_t wc = WEOF; + + /* Skip the characters which are not necessary to check. */ + for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; + rawbuf_idx < new_raw_idx;) + { + wchar_t wc2; + Idx remain_len = pstr->raw_len - rawbuf_idx; + prev_st = pstr->cur_state; + mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, + remain_len, &pstr->cur_state); + 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) + wc = L'\0'; + else + wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx); + mbclen = 1; + pstr->cur_state = prev_st; + } + else + wc = wc2; + /* Then proceed the next character. */ + rawbuf_idx += mbclen; + } + *last_wc = wc; + return rawbuf_idx; +} + +/* Build the buffer PSTR->MBS, and apply the translation if we need. + This function is used in case of REG_ICASE. */ + +static void +build_upper_buffer (re_string_t *pstr) +{ + Idx char_idx, end_idx; + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + + for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) + { + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; + if (__glibc_unlikely (pstr->trans != NULL)) + ch = pstr->trans[ch]; + pstr->mbs[char_idx] = toupper (ch); + } + pstr->valid_len = char_idx; + pstr->valid_raw_len = char_idx; +} + +/* Apply TRANS to the buffer in PSTR. */ + +static void +re_string_translate_buffer (re_string_t *pstr) +{ + Idx buf_idx, end_idx; + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + + for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) + { + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx]; + pstr->mbs[buf_idx] = pstr->trans[ch]; + } + + pstr->valid_len = buf_idx; + pstr->valid_raw_len = buf_idx; +} + +/* This function re-construct the buffers. + Concretely, convert to wide character in case of pstr->mb_cur_max > 1, + convert to upper case in case of REG_ICASE, apply translation. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) +{ + Idx offset; + + if (__glibc_unlikely (pstr->raw_mbs_idx <= idx)) + offset = idx - pstr->raw_mbs_idx; + else + { + /* Reset buffer. */ + if (pstr->mb_cur_max > 1) + memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); + pstr->len = pstr->raw_len; + pstr->stop = pstr->raw_stop; + pstr->valid_len = 0; + pstr->raw_mbs_idx = 0; + pstr->valid_raw_len = 0; + pstr->offsets_needed = 0; + pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF + : CONTEXT_NEWLINE | CONTEXT_BEGBUF); + if (!pstr->mbs_allocated) + pstr->mbs = (unsigned char *) pstr->raw_mbs; + offset = idx; + } + + if (__glibc_likely (offset != 0)) + { + /* Should the already checked characters be kept? */ + if (__glibc_likely (offset < pstr->valid_raw_len)) + { + /* Yes, move them to the front of the buffer. */ + if (__glibc_unlikely (pstr->offsets_needed)) + { + Idx low = 0, high = pstr->valid_len, mid; + do + { + mid = (high + low) / 2; + if (pstr->offsets[mid] > offset) + high = mid; + else if (pstr->offsets[mid] < offset) + low = mid + 1; + else + break; + } + while (low < high); + if (pstr->offsets[mid] < offset) + ++mid; + pstr->tip_context = re_string_context_at (pstr, mid - 1, + eflags); + /* This can be quite complicated, so handle specially + only the common and easy case where the character with + different length representation of lower and upper + case is present at or after offset. */ + if (pstr->valid_len > offset + && mid == offset && pstr->offsets[mid] == offset) + { + memmove (pstr->wcs, pstr->wcs + offset, + (pstr->valid_len - offset) * sizeof (wint_t)); + memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset); + pstr->valid_len -= offset; + pstr->valid_raw_len -= offset; + for (low = 0; low < pstr->valid_len; low++) + pstr->offsets[low] = pstr->offsets[low + offset] - offset; + } + else + { + /* Otherwise, just find out how long the partial multibyte + character at offset is and fill it with WEOF/255. */ + pstr->len = pstr->raw_len - idx + offset; + pstr->stop = pstr->raw_stop - idx + offset; + pstr->offsets_needed = 0; + while (mid > 0 && pstr->offsets[mid - 1] == offset) + --mid; + while (mid < pstr->valid_len) + if (pstr->wcs[mid] != WEOF) + break; + else + ++mid; + if (mid == pstr->valid_len) + pstr->valid_len = 0; + else + { + pstr->valid_len = pstr->offsets[mid] - offset; + if (pstr->valid_len) + { + for (low = 0; low < pstr->valid_len; ++low) + pstr->wcs[low] = WEOF; + memset (pstr->mbs, 255, pstr->valid_len); + } + } + pstr->valid_raw_len = pstr->valid_len; + } + } + else + { + pstr->tip_context = re_string_context_at (pstr, offset - 1, + eflags); + if (pstr->mb_cur_max > 1) + memmove (pstr->wcs, pstr->wcs + offset, + (pstr->valid_len - offset) * sizeof (wint_t)); + 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; + DEBUG_ASSERT (pstr->valid_len > 0); + } + } + else + { + /* No, skip all characters until IDX. */ + Idx prev_valid_len = pstr->valid_len; + + if (__glibc_unlikely (pstr->offsets_needed)) + { + pstr->len = pstr->raw_len - idx + offset; + pstr->stop = pstr->raw_stop - idx + offset; + pstr->offsets_needed = 0; + } + pstr->valid_len = 0; + if (pstr->mb_cur_max > 1) + { + Idx wcs_idx; + wint_t wc = WEOF; + + if (pstr->is_utf8) + { + const unsigned char *raw, *p, *end; + + /* Special case UTF-8. Multi-byte chars start with any + byte other than 0x80 - 0xbf. */ + raw = pstr->raw_mbs + pstr->raw_mbs_idx; + end = raw + (offset - pstr->mb_cur_max); + if (end < pstr->raw_mbs) + end = pstr->raw_mbs; + p = raw + offset - 1; +#ifdef _LIBC + /* We know the wchar_t encoding is UCS4, so for the simple + case, ASCII characters, skip the conversion step. */ + if (isascii (*p) && __glibc_likely (pstr->trans == NULL)) + { + memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); + /* pstr->valid_len = 0; */ + wc = (wchar_t) *p; + } + else +#endif + for (; p >= end; --p) + if ((*p & 0xc0) != 0x80) + { + mbstate_t cur_state; + wchar_t wc2; + Idx mlen = raw + pstr->len - p; + unsigned char buf[6]; + size_t mbclen; + + const unsigned char *pp = p; + if (__glibc_unlikely (pstr->trans != NULL)) + { + int i = mlen < 6 ? mlen : 6; + while (--i >= 0) + buf[i] = pstr->trans[p[i]]; + pp = buf; + } + /* XXX Don't use mbrtowc, we know which conversion + to use (UTF-8 -> UCS4). */ + memset (&cur_state, 0, sizeof (cur_state)); + mbclen = __mbrtowc (&wc2, (const char *) pp, mlen, + &cur_state); + if (raw + offset - p <= mbclen + && mbclen < (size_t) -2) + { + memset (&pstr->cur_state, '\0', + sizeof (mbstate_t)); + pstr->valid_len = mbclen - (raw + offset - p); + wc = wc2; + } + break; + } + } + + if (wc == WEOF) + pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx; + if (wc == WEOF) + pstr->tip_context + = re_string_context_at (pstr, prev_valid_len - 1, eflags); + else + 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 (__glibc_unlikely (pstr->valid_len)) + { + for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) + pstr->wcs[wcs_idx] = WEOF; + if (pstr->mbs_allocated) + memset (pstr->mbs, 255, pstr->valid_len); + } + pstr->valid_raw_len = pstr->valid_len; + } + else + { + int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; + pstr->valid_raw_len = 0; + if (pstr->trans) + c = pstr->trans[c]; + pstr->tip_context = (bitset_contain (pstr->word_char, c) + ? CONTEXT_WORD + : ((IS_NEWLINE (c) && pstr->newline_anchor) + ? CONTEXT_NEWLINE : 0)); + } + } + if (!__glibc_unlikely (pstr->mbs_allocated)) + pstr->mbs += offset; + } + pstr->raw_mbs_idx = idx; + pstr->len -= offset; + pstr->stop -= offset; + + /* Then build the buffers. */ + if (pstr->mb_cur_max > 1) + { + if (pstr->icase) + { + reg_errcode_t ret = build_wcs_upper_buffer (pstr); + if (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + } + else + build_wcs_buffer (pstr); + } + else + if (__glibc_unlikely (pstr->mbs_allocated)) + { + if (pstr->icase) + build_upper_buffer (pstr); + else if (pstr->trans != NULL) + re_string_translate_buffer (pstr); + } + else + pstr->valid_len = pstr->len; + + pstr->cur_idx = 0; + return REG_NOERROR; +} + +static unsigned char +__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 (__glibc_likely (!pstr->mbs_allocated)) + return re_string_peek_byte (pstr, idx); + + if (pstr->mb_cur_max > 1 + && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) + return re_string_peek_byte (pstr, idx); + + off = pstr->cur_idx + idx; + if (pstr->offsets_needed) + off = pstr->offsets[off]; + + ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; + + /* 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); + + return ch; +} + +static unsigned char +re_string_fetch_byte_case (re_string_t *pstr) +{ + if (__glibc_likely (!pstr->mbs_allocated)) + return re_string_fetch_byte (pstr); + + if (pstr->offsets_needed) + { + Idx off; + int ch; + + /* For tr_TR.UTF-8 [[:islower:]] there is + [[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip + in that case the whole multi-byte character and return + the original letter. On the other side, with + [[: DOTLESS SMALL LETTER I return [[:I, as doing + anything else would complicate things too much. */ + + if (!re_string_first_byte (pstr, pstr->cur_idx)) + return re_string_fetch_byte (pstr); + + off = pstr->offsets[pstr->cur_idx]; + ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; + + if (! isascii (ch)) + return re_string_fetch_byte (pstr); + + re_string_skip_bytes (pstr, + re_string_char_size_at (pstr, pstr->cur_idx)); + return ch; + } + + return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; +} + +static void +re_string_destruct (re_string_t *pstr) +{ + re_free (pstr->wcs); + re_free (pstr->offsets); + if (pstr->mbs_allocated) + re_free (pstr->mbs); +} + +/* Return the context at IDX in INPUT. */ + +static unsigned int +re_string_context_at (const re_string_t *input, Idx idx, int eflags) +{ + int c; + 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 (__glibc_unlikely (idx == input->len)) + return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF + : CONTEXT_NEWLINE | CONTEXT_ENDBUF); + if (input->mb_cur_max > 1) + { + wint_t wc; + Idx wc_idx = idx; + while(input->wcs[wc_idx] == WEOF) + { + DEBUG_ASSERT (wc_idx >= 0); + --wc_idx; + if (wc_idx < 0) + return input->tip_context; + } + wc = input->wcs[wc_idx]; + 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 + { + c = re_string_byte_at (input, idx); + if (bitset_contain (input->word_char, c)) + return CONTEXT_WORD; + return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0; + } +} + +/* Functions for set operation. */ + +static reg_errcode_t +__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 (__glibc_unlikely (set->elems == NULL) + && (MALLOC_0_IS_NONNULL || size != 0)) + return REG_ESPACE; + return REG_NOERROR; +} + +static reg_errcode_t +__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 (__glibc_unlikely (set->elems == NULL)) + { + set->alloc = set->nelem = 0; + return REG_ESPACE; + } + set->elems[0] = elem; + return REG_NOERROR; +} + +static reg_errcode_t +__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 (__glibc_unlikely (set->elems == NULL)) + return REG_ESPACE; + if (elem1 == elem2) + { + set->nelem = 1; + set->elems[0] = elem1; + } + else + { + set->nelem = 2; + if (elem1 < elem2) + { + set->elems[0] = elem1; + set->elems[1] = elem2; + } + else + { + set->elems[0] = elem2; + set->elems[1] = elem1; + } + } + return REG_NOERROR; +} + +static reg_errcode_t +__attribute_warn_unused_result__ +re_node_set_init_copy (re_node_set *dest, const re_node_set *src) +{ + dest->nelem = src->nelem; + if (src->nelem > 0) + { + dest->alloc = dest->nelem; + dest->elems = re_malloc (Idx, dest->alloc); + if (__glibc_unlikely (dest->elems == NULL)) + { + dest->alloc = dest->nelem = 0; + return REG_ESPACE; + } + memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); + } + else + re_node_set_init_empty (dest); + return REG_NOERROR; +} + +/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to + DEST. Return value indicate the error code or REG_NOERROR if succeeded. + Note: We assume dest->elems is NULL, when dest->alloc is 0. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, + const re_node_set *src2) +{ + Idx i1, i2, is, id, delta, sbase; + if (src1->nelem == 0 || src2->nelem == 0) + return REG_NOERROR; + + /* We need dest->nelem + 2 * elems_in_intersection; this is a + conservative estimate. */ + if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) + { + Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; + Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); + if (__glibc_unlikely (new_elems == NULL)) + return REG_ESPACE; + dest->elems = new_elems; + dest->alloc = new_alloc; + } + + /* Find the items in the intersection of SRC1 and SRC2, and copy + into the top of DEST those that are not already in DEST itself. */ + sbase = dest->nelem + src1->nelem + src2->nelem; + i1 = src1->nelem - 1; + i2 = src2->nelem - 1; + id = dest->nelem - 1; + for (;;) + { + if (src1->elems[i1] == src2->elems[i2]) + { + /* Try to find the item in DEST. Maybe we could binary search? */ + while (id >= 0 && dest->elems[id] > src1->elems[i1]) + --id; + + if (id < 0 || dest->elems[id] != src1->elems[i1]) + dest->elems[--sbase] = src1->elems[i1]; + + if (--i1 < 0 || --i2 < 0) + break; + } + + /* Lower the highest of the two items. */ + else if (src1->elems[i1] < src2->elems[i2]) + { + if (--i2 < 0) + break; + } + else + { + if (--i1 < 0) + break; + } + } + + id = dest->nelem - 1; + is = dest->nelem + src1->nelem + src2->nelem - 1; + delta = is - sbase + 1; + + /* Now copy. When DELTA becomes zero, the remaining + 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 && id >= 0) + for (;;) + { + if (dest->elems[is] > dest->elems[id]) + { + /* Copy from the top. */ + dest->elems[id + delta--] = dest->elems[is--]; + if (delta == 0) + break; + } + else + { + /* Slide from the bottom. */ + dest->elems[id + delta] = dest->elems[id]; + if (--id < 0) + break; + } + } + + /* Copy remaining SRC elements. */ + memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx)); + + return REG_NOERROR; +} + +/* Calculate the union set of the sets SRC1 and SRC2. And store it to + DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +re_node_set_init_union (re_node_set *dest, const re_node_set *src1, + const re_node_set *src2) +{ + Idx i1, i2, id; + if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) + { + dest->alloc = src1->nelem + src2->nelem; + dest->elems = re_malloc (Idx, dest->alloc); + if (__glibc_unlikely (dest->elems == NULL)) + return REG_ESPACE; + } + else + { + if (src1 != NULL && src1->nelem > 0) + return re_node_set_init_copy (dest, src1); + else if (src2 != NULL && src2->nelem > 0) + return re_node_set_init_copy (dest, src2); + else + re_node_set_init_empty (dest); + return REG_NOERROR; + } + for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) + { + if (src1->elems[i1] > src2->elems[i2]) + { + dest->elems[id++] = src2->elems[i2++]; + continue; + } + if (src1->elems[i1] == src2->elems[i2]) + ++i2; + dest->elems[id++] = src1->elems[i1++]; + } + if (i1 < src1->nelem) + { + memcpy (dest->elems + id, src1->elems + i1, + (src1->nelem - i1) * sizeof (Idx)); + id += src1->nelem - i1; + } + else if (i2 < src2->nelem) + { + memcpy (dest->elems + id, src2->elems + i2, + (src2->nelem - i2) * sizeof (Idx)); + id += src2->nelem - i2; + } + dest->nelem = id; + return REG_NOERROR; +} + +/* Calculate the union set of the sets DEST and SRC. And store it to + DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +re_node_set_merge (re_node_set *dest, const re_node_set *src) +{ + Idx is, id, sbase, delta; + if (src == NULL || src->nelem == 0) + return REG_NOERROR; + if (dest->alloc < 2 * src->nelem + dest->nelem) + { + Idx new_alloc = 2 * (src->nelem + dest->alloc); + Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); + if (__glibc_unlikely (new_buffer == NULL)) + return REG_ESPACE; + dest->elems = new_buffer; + dest->alloc = new_alloc; + } + + 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; + } + + /* 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; is >= 0 && id >= 0; ) + { + if (dest->elems[id] == src->elems[is]) + is--, id--; + else if (dest->elems[id] < src->elems[is]) + dest->elems[--sbase] = src->elems[is--]; + else /* if (dest->elems[id] > src->elems[is]) */ + --id; + } + + if (is >= 0) + { + /* If DEST is exhausted, the remaining items of SRC must be unique. */ + sbase -= is + 1; + memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx)); + } + + id = dest->nelem - 1; + is = dest->nelem + 2 * src->nelem - 1; + delta = is - sbase + 1; + if (delta == 0) + return REG_NOERROR; + + /* Now copy. When DELTA becomes zero, the remaining + DEST elements are already in place. */ + dest->nelem += delta; + for (;;) + { + if (dest->elems[is] > dest->elems[id]) + { + /* Copy from the top. */ + dest->elems[id + delta--] = dest->elems[is--]; + if (delta == 0) + break; + } + else + { + /* Slide from the bottom. */ + dest->elems[id + delta] = dest->elems[id]; + if (--id < 0) + { + /* Copy remaining SRC elements. */ + memcpy (dest->elems, dest->elems + sbase, + delta * sizeof (Idx)); + break; + } + } + } + + return REG_NOERROR; +} + +/* Insert the new element ELEM to the re_node_set* SET. + SET should not already have ELEM. + Return true if successful. */ + +static bool +__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 __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR); + + if (__glibc_unlikely (set->nelem) == 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; + } + + /* Realloc if we need. */ + if (set->alloc == set->nelem) + { + Idx *new_elems; + set->alloc = set->alloc * 2; + new_elems = re_realloc (set->elems, Idx, set->alloc); + if (__glibc_unlikely (new_elems == NULL)) + return false; + set->elems = new_elems; + } + + /* Move the elements which follows the new element. Test the + first element separately to skip a check in the inner loop. */ + if (elem < set->elems[0]) + { + for (idx = set->nelem; idx > 0; idx--) + set->elems[idx] = set->elems[idx - 1]; + } + else + { + 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. */ + set->elems[idx] = elem; + ++set->nelem; + return true; +} + +/* Insert the new element ELEM to the re_node_set* SET. + SET should not already have any element greater than or equal to ELEM. + Return true if successful. */ + +static bool +__attribute_warn_unused_result__ +re_node_set_insert_last (re_node_set *set, Idx elem) +{ + /* Realloc if we need. */ + if (set->alloc == set->nelem) + { + Idx *new_elems; + set->alloc = (set->alloc + 1) * 2; + new_elems = re_realloc (set->elems, Idx, set->alloc); + if (__glibc_unlikely (new_elems == NULL)) + return false; + set->elems = new_elems; + } + + /* Insert the new element. */ + set->elems[set->nelem++] = elem; + return true; +} + +/* Compare two node sets SET1 and SET2. + Return true if SET1 and SET2 are equivalent. */ + +static bool +__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 ; --i >= 0 ; ) + if (set1->elems[i] != set2->elems[i]) + return false; + return true; +} + +/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ + +static Idx +__attribute__ ((pure)) +re_node_set_contains (const re_node_set *set, Idx elem) +{ + __re_size_t idx, right, mid; + if (set->nelem <= 0) + return 0; + + /* Binary search the element. */ + idx = 0; + right = set->nelem - 1; + while (idx < right) + { + mid = (idx + right) / 2; + if (set->elems[mid] < elem) + idx = mid + 1; + else + right = mid; + } + return set->elems[idx] == elem ? idx + 1 : 0; +} + +static void +re_node_set_remove_at (re_node_set *set, Idx idx) +{ + if (idx < 0 || idx >= set->nelem) + return; + --set->nelem; + for (; idx < set->nelem; idx++) + set->elems[idx] = set->elems[idx + 1]; +} + + +/* Add the token TOKEN to dfa->nodes, and return the index of the token. + Or return -1 if an error occurred. */ + +static Idx +re_dfa_add_node (re_dfa_t *dfa, re_token_t token) +{ + if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc)) + { + size_t new_nodes_alloc = dfa->nodes_alloc * 2; + Idx *new_nexts, *new_indices; + re_node_set *new_edests, *new_eclosures; + re_token_t *new_nodes; + + /* Avoid overflows in realloc. */ + const size_t max_object_size = MAX (sizeof (re_token_t), + MAX (sizeof (re_node_set), + sizeof (Idx))); + 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 (__glibc_unlikely (new_nodes == NULL)) + return -1; + dfa->nodes = new_nodes; + new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); + new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); + new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); + new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); + if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL + || new_edests == NULL || new_eclosures == NULL)) + { + re_free (new_nexts); + re_free (new_indices); + re_free (new_edests); + re_free (new_eclosures); + return -1; + } + dfa->nexts = new_nexts; + dfa->org_indices = new_indices; + dfa->edests = new_edests; + dfa->eclosures = new_eclosures; + dfa->nodes_alloc = new_nodes_alloc; + } + dfa->nodes[dfa->nodes_len] = token; + dfa->nodes[dfa->nodes_len].constraint = 0; + dfa->nodes[dfa->nodes_len].accept_mb = + ((token.type == OP_PERIOD && dfa->mb_cur_max > 1) + || token.type == COMPLEX_BRACKET); + 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 +calc_state_hash (const re_node_set *nodes, unsigned int context) +{ + re_hashval_t hash = nodes->nelem + context; + Idx i; + for (i = 0 ; i < nodes->nelem ; i++) + hash += nodes->elems[i]; + return hash; +} + +/* Search for the state whose node_set is equivalent to NODES. + Return the pointer to the state, if we found it in the DFA. + Otherwise create the new one and return it. In case of an error + return NULL and set the error code in ERR. + Note: - We assume NULL as the invalid state, then it is possible that + return value is NULL and ERR is REG_NOERROR. + - We never return non-NULL value in case of any errors, it is for + optimization. */ + +static re_dfastate_t * +__attribute_warn_unused_result__ +re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, + const re_node_set *nodes) +{ + re_hashval_t hash; + re_dfastate_t *new_state; + struct re_state_table_entry *spot; + Idx i; +#if defined GCC_LINT || defined lint + /* Suppress bogus uninitialized-variable warnings. */ + *err = REG_NOERROR; +#endif + if (__glibc_unlikely (nodes->nelem == 0)) + { + *err = REG_NOERROR; + return NULL; + } + hash = calc_state_hash (nodes, 0); + spot = dfa->state_table + (hash & dfa->state_hash_mask); + + for (i = 0 ; i < spot->num ; i++) + { + re_dfastate_t *state = spot->array[i]; + if (hash != state->hash) + continue; + if (re_node_set_compare (&state->nodes, nodes)) + return state; + } + + /* There are no appropriate state in the dfa, create the new one. */ + new_state = create_ci_newstate (dfa, nodes, hash); + if (__glibc_unlikely (new_state == NULL)) + *err = REG_ESPACE; + + return new_state; +} + +/* Search for the state whose node_set is equivalent to NODES and + whose context is equivalent to CONTEXT. + Return the pointer to the state, if we found it in the DFA. + Otherwise create the new one and return it. In case of an error + return NULL and set the error code in ERR. + Note: - We assume NULL as the invalid state, then it is possible that + return value is NULL and ERR is REG_NOERROR. + - We never return non-NULL value in case of any errors, it is for + optimization. */ + +static re_dfastate_t * +__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) +{ + re_hashval_t hash; + re_dfastate_t *new_state; + struct re_state_table_entry *spot; + Idx i; +#if defined GCC_LINT || defined lint + /* Suppress bogus uninitialized-variable warnings. */ + *err = REG_NOERROR; +#endif + if (nodes->nelem == 0) + { + *err = REG_NOERROR; + return NULL; + } + hash = calc_state_hash (nodes, context); + spot = dfa->state_table + (hash & dfa->state_hash_mask); + + for (i = 0 ; i < spot->num ; i++) + { + re_dfastate_t *state = spot->array[i]; + if (state->hash == hash + && state->context == context + && re_node_set_compare (state->entrance_nodes, nodes)) + return state; + } + /* There are no appropriate state in 'dfa', create the new one. */ + new_state = create_cd_newstate (dfa, nodes, context, hash); + if (__glibc_unlikely (new_state == NULL)) + *err = REG_ESPACE; + + return new_state; +} + +/* Finish initialization of the new state NEWSTATE, and using its hash value + HASH put in the appropriate bucket of DFA's state table. Return value + indicates the error code if failed. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, + re_hashval_t hash) +{ + struct re_state_table_entry *spot; + reg_errcode_t err; + Idx i; + + newstate->hash = hash; + err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); + if (__glibc_unlikely (err != REG_NOERROR)) + return REG_ESPACE; + for (i = 0; i < newstate->nodes.nelem; i++) + { + Idx elem = newstate->nodes.elems[i]; + if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) + if (! re_node_set_insert_last (&newstate->non_eps_nodes, elem)) + return REG_ESPACE; + } + + spot = dfa->state_table + (hash & dfa->state_hash_mask); + 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 (__glibc_unlikely (new_array == NULL)) + return REG_ESPACE; + spot->array = new_array; + spot->alloc = new_alloc; + } + spot->array[spot->num++] = newstate; + return REG_NOERROR; +} + +static void +free_state (re_dfastate_t *state) +{ + re_node_set_free (&state->non_eps_nodes); + re_node_set_free (&state->inveclosure); + if (state->entrance_nodes != &state->nodes) + { + re_node_set_free (state->entrance_nodes); + re_free (state->entrance_nodes); + } + re_node_set_free (&state->nodes); + re_free (state->word_trtable); + re_free (state->trtable); + re_free (state); +} + +/* Create the new state which is independent of contexts. + Return the new state if succeeded, otherwise return NULL. */ + +static re_dfastate_t * +__attribute_warn_unused_result__ +create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, + re_hashval_t hash) +{ + Idx i; + reg_errcode_t err; + re_dfastate_t *newstate; + + newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); + if (__glibc_unlikely (newstate == NULL)) + return NULL; + err = re_node_set_init_copy (&newstate->nodes, nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_free (newstate); + return NULL; + } + + newstate->entrance_nodes = &newstate->nodes; + for (i = 0 ; i < nodes->nelem ; i++) + { + re_token_t *node = dfa->nodes + nodes->elems[i]; + re_token_type_t type = node->type; + if (type == CHARACTER && !node->constraint) + continue; + newstate->accept_mb |= node->accept_mb; + + /* If the state has the halt node, the state is a halt state. */ + if (type == END_OF_RE) + newstate->halt = 1; + else if (type == OP_BACK_REF) + newstate->has_backref = 1; + else if (type == ANCHOR || node->constraint) + newstate->has_constraint = 1; + } + err = register_state (dfa, newstate, hash); + if (__glibc_unlikely (err != REG_NOERROR)) + { + free_state (newstate); + newstate = NULL; + } + return newstate; +} + +/* Create the new state which is depend on the context CONTEXT. + Return the new state if succeeded, otherwise return NULL. */ + +static re_dfastate_t * +__attribute_warn_unused_result__ +create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, + unsigned int context, re_hashval_t hash) +{ + Idx i, nctx_nodes = 0; + reg_errcode_t err; + re_dfastate_t *newstate; + + newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); + if (__glibc_unlikely (newstate == NULL)) + return NULL; + err = re_node_set_init_copy (&newstate->nodes, nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_free (newstate); + return NULL; + } + + newstate->context = context; + newstate->entrance_nodes = &newstate->nodes; + + for (i = 0 ; i < nodes->nelem ; i++) + { + re_token_t *node = dfa->nodes + nodes->elems[i]; + re_token_type_t type = node->type; + unsigned int constraint = node->constraint; + + if (type == CHARACTER && !constraint) + continue; + newstate->accept_mb |= node->accept_mb; + + /* If the state has the halt node, the state is a halt state. */ + if (type == END_OF_RE) + newstate->halt = 1; + else if (type == OP_BACK_REF) + newstate->has_backref = 1; + + if (constraint) + { + if (newstate->entrance_nodes == &newstate->nodes) + { + 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) + { + free_state (newstate); + return NULL; + } + nctx_nodes = 0; + newstate->has_constraint = 1; + } + + if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context)) + { + re_node_set_remove_at (&newstate->nodes, i - nctx_nodes); + ++nctx_nodes; + } + } + } + err = register_state (dfa, newstate, hash); + if (__glibc_unlikely (err != REG_NOERROR)) + { + free_state (newstate); + newstate = NULL; + } + return newstate; +} diff --git a/lib/regex_internal.h b/lib/regex_internal.h new file mode 100644 index 0000000..57a455b --- /dev/null +++ b/lib/regex_internal.h @@ -0,0 +1,835 @@ +/* Extended regular expression matching and search library. + 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 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 _REGEX_INTERNAL_H +#define _REGEX_INTERNAL_H 1 + +#include +#include +#include +#include + +#include +#include +#include +#include +#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 +# define lock_define(name) __libc_lock_define (, name) +# define lock_init(lock) (__libc_lock_init (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 && !defined GNULIB_REGEX_SINGLE_THREAD +# include "glthread/lock.h" +# 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 && !defined GNULIB_REGEX_SINGLE_THREAD +# include +# define lock_define(name) pthread_mutex_t name; +# define lock_init(lock) pthread_mutex_init (&(lock), 0) +# define lock_fini(lock) pthread_mutex_destroy (&(lock)) +# define lock_lock(lock) pthread_mutex_lock (&(lock)) +# define lock_unlock(lock) pthread_mutex_unlock (&(lock)) +#else +# define lock_define(name) +# define lock_init(lock) 0 +# define lock_fini(lock) ((void) 0) + /* The 'dfa' avoids an "unused variable 'dfa'" warning from GCC. */ +# define lock_lock(lock) ((void) dfa) +# define lock_unlock(lock) ((void) 0) +#endif + +/* In case that the system doesn't have isblank(). */ +#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) +# 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 +# endif +#endif + +/* This is for other GNU distributions with internationalized messages. */ +#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifdef _LIBC +# undef gettext +# define gettext(msgid) \ + __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) +# endif +#else +# undef gettext +# define gettext(msgid) (msgid) +#endif + +#ifndef gettext_noop +/* This define is so xgettext can find the internationalizable + strings. */ +# define gettext_noop(String) String +#endif + +/* Number of ASCII characters. */ +#define ASCII_CHARS 0x80 + +/* Number of single byte characters. */ +#define SBC_MAX (UCHAR_MAX + 1) + +#define COLL_ELEM_LEN_MAX 8 + +/* The character which represents newline. */ +#define NEWLINE_CHAR '\n' +#define WIDE_NEWLINE_CHAR L'\n' + +/* 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 +#endif /* not _LIBC */ + +/* 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. */ + +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif +#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 + +/* 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 IDX_MAX SSIZE_MAX +#else +# define IDX_MAX INT_MAX +#endif + +/* A hash value, suitable for computing hash tables. */ +typedef __re_size_t re_hashval_t; + +/* An integer used to represent a set of bits. It must be unsigned, + and must be at least as wide as unsigned int. */ +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. */ +#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) + +typedef bitset_word_t bitset_t[BITSET_WORDS]; +typedef bitset_word_t *re_bitset_ptr_t; +typedef const bitset_word_t *re_const_bitset_ptr_t; + +#define PREV_WORD_CONSTRAINT 0x0001 +#define PREV_NOTWORD_CONSTRAINT 0x0002 +#define NEXT_WORD_CONSTRAINT 0x0004 +#define NEXT_NOTWORD_CONSTRAINT 0x0008 +#define PREV_NEWLINE_CONSTRAINT 0x0010 +#define NEXT_NEWLINE_CONSTRAINT 0x0020 +#define PREV_BEGBUF_CONSTRAINT 0x0040 +#define NEXT_ENDBUF_CONSTRAINT 0x0080 +#define WORD_DELIM_CONSTRAINT 0x0100 +#define NOT_WORD_DELIM_CONSTRAINT 0x0200 + +typedef enum +{ + INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, + WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, + WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, + INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, + LINE_FIRST = PREV_NEWLINE_CONSTRAINT, + LINE_LAST = NEXT_NEWLINE_CONSTRAINT, + BUF_FIRST = PREV_BEGBUF_CONSTRAINT, + BUF_LAST = NEXT_ENDBUF_CONSTRAINT, + WORD_DELIM = WORD_DELIM_CONSTRAINT, + NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT +} re_context_type; + +typedef struct +{ + Idx alloc; + Idx nelem; + Idx *elems; +} re_node_set; + +typedef enum +{ + NON_TYPE = 0, + + /* Node type, These are used by token, node, tree. */ + CHARACTER = 1, + END_OF_RE = 2, + SIMPLE_BRACKET = 3, + OP_BACK_REF = 4, + OP_PERIOD = 5, + COMPLEX_BRACKET = 6, + OP_UTF8_PERIOD = 7, + + /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used + when the debugger shows values of this enum type. */ +#define EPSILON_BIT 8 + OP_OPEN_SUBEXP = EPSILON_BIT | 0, + OP_CLOSE_SUBEXP = EPSILON_BIT | 1, + OP_ALT = EPSILON_BIT | 2, + OP_DUP_ASTERISK = EPSILON_BIT | 3, + ANCHOR = EPSILON_BIT | 4, + + /* Tree type, these are used only by tree. */ + CONCAT = 16, + SUBEXP = 17, + + /* Token type, these are used only by token. */ + OP_DUP_PLUS = 18, + OP_DUP_QUESTION, + OP_OPEN_BRACKET, + OP_CLOSE_BRACKET, + OP_CHARSET_RANGE, + OP_OPEN_DUP_NUM, + OP_CLOSE_DUP_NUM, + OP_NON_MATCH_LIST, + OP_OPEN_COLL_ELEM, + OP_CLOSE_COLL_ELEM, + OP_OPEN_EQUIV_CLASS, + OP_CLOSE_EQUIV_CLASS, + OP_OPEN_CHAR_CLASS, + OP_CLOSE_CHAR_CLASS, + OP_WORD, + OP_NOTWORD, + OP_SPACE, + OP_NOTSPACE, + BACK_SLASH + +} re_token_type_t; + +typedef struct +{ + /* Multibyte characters. */ + wchar_t *mbchars; + +#ifdef _LIBC + /* Collating symbols. */ + int32_t *coll_syms; +#endif + +#ifdef _LIBC + /* Equivalence classes. */ + int32_t *equiv_classes; +#endif + + /* Range expressions. */ +#ifdef _LIBC + uint32_t *range_starts; + uint32_t *range_ends; +#else + wchar_t *range_starts; + wchar_t *range_ends; +#endif + + /* Character classes. */ + wctype_t *char_classes; + + /* If this character set is the non-matching list. */ + unsigned int non_match : 1; + + /* # of multibyte characters. */ + Idx nmbchars; + + /* # of collating symbols. */ + Idx ncoll_syms; + + /* # of equivalence classes. */ + Idx nequiv_classes; + + /* # of range expressions. */ + Idx nranges; + + /* # of character classes. */ + Idx nchar_classes; +} re_charset_t; + +typedef struct +{ + union + { + unsigned char c; /* for CHARACTER */ + re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ + re_charset_t *mbcset; /* for COMPLEX_BRACKET */ + Idx idx; /* for BACK_REF */ + re_context_type ctx_type; /* for ANCHOR */ + } opr; +#if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__ + re_token_type_t type : 8; +#else + re_token_type_t type; +#endif + unsigned int constraint : 10; /* context constraint */ + unsigned int duplicated : 1; + unsigned int opt_subexp : 1; + 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; + unsigned int word_char : 1; +} re_token_t; + +#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT) + +struct re_string_t +{ + /* Indicate the raw buffer which is the original string passed as an + argument of regexec(), re_search(), etc.. */ + const unsigned char *raw_mbs; + /* Store the multibyte string. In case of "case insensitive mode" like + REG_ICASE, upper cases of the string are stored, otherwise MBS points + the same address that RAW_MBS points. */ + unsigned char *mbs; + /* Store the wide character string which is corresponding to MBS. */ + wint_t *wcs; + Idx *offsets; + mbstate_t cur_state; + /* Index in RAW_MBS. Each character mbs[i] corresponds to + raw_mbs[raw_mbs_idx + i]. */ + Idx raw_mbs_idx; + /* The length of the valid characters in the buffers. */ + Idx valid_len; + /* The corresponding number of bytes in raw_mbs array. */ + Idx valid_raw_len; + /* The length of the buffers MBS and WCS. */ + Idx bufs_len; + /* The index in MBS, which is updated by re_string_fetch_byte. */ + Idx cur_idx; + /* length of RAW_MBS array. */ + Idx raw_len; + /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */ + Idx len; + /* End of the buffer may be shorter than its length in the cases such + as re_match_2, re_search_2. Then, we use STOP for end of the buffer + instead of LEN. */ + Idx raw_stop; + /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */ + Idx stop; + + /* The context of mbs[0]. We store the context independently, since + the context of mbs[0] may be different from raw_mbs[0], which is + the beginning of the input string. */ + unsigned int tip_context; + /* The translation passed as a part of an argument of re_compile_pattern. */ + RE_TRANSLATE_TYPE trans; + /* Copy of re_dfa_t's word_char. */ + re_const_bitset_ptr_t word_char; + /* true if REG_ICASE. */ + unsigned char icase; + unsigned char is_utf8; + unsigned char map_notascii; + unsigned char mbs_allocated; + unsigned char offsets_needed; + unsigned char newline_anchor; + unsigned char word_ops_used; + int mb_cur_max; +}; +typedef struct re_string_t re_string_t; + + +struct re_dfa_t; +typedef struct re_dfa_t re_dfa_t; + +#ifndef _LIBC +# define IS_IN(libc) false +#endif + +#define re_string_peek_byte(pstr, offset) \ + ((pstr)->mbs[(pstr)->cur_idx + offset]) +#define re_string_fetch_byte(pstr) \ + ((pstr)->mbs[(pstr)->cur_idx++]) +#define re_string_first_byte(pstr, idx) \ + ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF) +#define re_string_is_single_byte_char(pstr, idx) \ + ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \ + || (pstr)->wcs[(idx) + 1] != WEOF)) +#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx) +#define re_string_cur_idx(pstr) ((pstr)->cur_idx) +#define re_string_get_buffer(pstr) ((pstr)->mbs) +#define re_string_length(pstr) ((pstr)->len) +#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx]) +#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) +#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) + +#ifdef _LIBC +# define MALLOC_0_IS_NONNULL 1 +#elif !defined MALLOC_0_IS_NONNULL +# define MALLOC_0_IS_NONNULL 0 +#endif + +#ifndef MAX +# define MAX(a,b) ((a) < (b) ? (b) : (a)) +#endif +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) +#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) +#define re_free(p) free (p) + +struct bin_tree_t +{ + struct bin_tree_t *parent; + struct bin_tree_t *left; + struct bin_tree_t *right; + struct bin_tree_t *first; + struct bin_tree_t *next; + + re_token_t token; + + /* 'node_idx' is the index in dfa->nodes, if 'type' == 0. + Otherwise 'type' indicate the type of this node. */ + Idx node_idx; +}; +typedef struct bin_tree_t bin_tree_t; + +#define BIN_TREE_STORAGE_SIZE \ + ((1024 - sizeof (void *)) / sizeof (bin_tree_t)) + +struct bin_tree_storage_t +{ + struct bin_tree_storage_t *next; + bin_tree_t data[BIN_TREE_STORAGE_SIZE]; +}; +typedef struct bin_tree_storage_t bin_tree_storage_t; + +#define CONTEXT_WORD 1 +#define CONTEXT_NEWLINE (CONTEXT_WORD << 1) +#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1) +#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1) + +#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD) +#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE) +#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF) +#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF) +#define IS_ORDINARY_CONTEXT(c) ((c) == 0) + +#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_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) + +#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ + ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ + || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ + || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\ + || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context))) + +#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \ + ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ + || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ + || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \ + || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context))) + +struct re_dfastate_t +{ + re_hashval_t hash; + re_node_set nodes; + re_node_set non_eps_nodes; + re_node_set inveclosure; + re_node_set *entrance_nodes; + struct re_dfastate_t **trtable, **word_trtable; + unsigned int context : 4; + unsigned int halt : 1; + /* If this state can accept "multi byte". + Note that we refer to multibyte characters, and multi character + collating elements as "multi byte". */ + unsigned int accept_mb : 1; + /* If this state has backreference node(s). */ + unsigned int has_backref : 1; + unsigned int has_constraint : 1; +}; +typedef struct re_dfastate_t re_dfastate_t; + +struct re_state_table_entry +{ + Idx num; + Idx alloc; + re_dfastate_t **array; +}; + +/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */ + +typedef struct +{ + Idx next_idx; + Idx alloc; + re_dfastate_t **array; +} state_array_t; + +/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */ + +typedef struct +{ + Idx node; + Idx str_idx; /* The position NODE match at. */ + state_array_t path; +} re_sub_match_last_t; + +/* Store information about the node NODE whose type is OP_OPEN_SUBEXP. + And information about the node, whose type is OP_CLOSE_SUBEXP, + corresponding to NODE is stored in LASTS. */ + +typedef struct +{ + Idx str_idx; + Idx node; + state_array_t *path; + Idx alasts; /* Allocation size of LASTS. */ + Idx nlasts; /* The number of LASTS. */ + re_sub_match_last_t **lasts; +} re_sub_match_top_t; + +struct re_backref_cache_entry +{ + Idx node; + Idx str_idx; + Idx subexp_from; + Idx subexp_to; + bitset_word_t eps_reachable_subexps_map; + char more; +}; + +typedef struct +{ + /* The string object corresponding to the input string. */ + re_string_t input; + const re_dfa_t *const dfa; + /* EFLAGS of the argument of regexec. */ + int eflags; + /* Where the matching ends. */ + Idx match_last; + Idx last_node; + /* The state log used by the matcher. */ + re_dfastate_t **state_log; + Idx state_log_top; + /* Back reference cache. */ + Idx nbkref_ents; + Idx abkref_ents; + struct re_backref_cache_entry *bkref_ents; + int max_mb_elem_len; + Idx nsub_tops; + Idx asub_tops; + re_sub_match_top_t **sub_tops; +} re_match_context_t; + +typedef struct +{ + re_dfastate_t **sifted_states; + re_dfastate_t **limited_states; + Idx last_node; + Idx last_str_idx; + re_node_set limits; +} re_sift_context_t; + +struct re_fail_stack_ent_t +{ + Idx idx; + Idx node; + regmatch_t *regs; + re_node_set eps_via_nodes; +}; + +struct re_fail_stack_t +{ + Idx num; + Idx alloc; + struct re_fail_stack_ent_t *stack; +}; + +struct re_dfa_t +{ + re_token_t *nodes; + size_t nodes_alloc; + size_t nodes_len; + Idx *nexts; + Idx *org_indices; + re_node_set *edests; + re_node_set *eclosures; + re_node_set *inveclosures; + struct re_state_table_entry *state_table; + re_dfastate_t *init_state; + re_dfastate_t *init_state_word; + re_dfastate_t *init_state_nl; + re_dfastate_t *init_state_begbuf; + bin_tree_t *str_tree; + bin_tree_storage_t *str_tree_storage; + re_bitset_ptr_t sb_char; + int str_tree_storage_idx; + + /* number of subexpressions 're_nsub' is in regex_t. */ + re_hashval_t state_hash_mask; + Idx init_node; + Idx nbackref; /* The number of backreference in this dfa. */ + + /* Bitmap expressing which backreference is used. */ + bitset_word_t used_bkref_map; + bitset_word_t completed_bkref_map; + + unsigned int has_plural_match : 1; + /* If this dfa has "multibyte node", which is a backreference or + a node which can accept multibyte character or multi character + collating element. */ + unsigned int has_mb_node : 1; + unsigned int is_utf8 : 1; + unsigned int map_notascii : 1; + unsigned int word_ops_used : 1; + int mb_cur_max; + bitset_t word_char; + reg_syntax_t syntax; + Idx *subexp_map; +#ifdef DEBUG + char* re_str; +#endif + lock_define (lock) +}; + +#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) +#define re_node_set_remove(set,id) \ + (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) +#define re_node_set_empty(p) ((p)->nelem = 0) +#define re_node_set_free(set) re_free ((set)->elems) + + +typedef enum +{ + SB_CHAR, + MB_CHAR, + EQUIV_CLASS, + COLL_SYM, + CHAR_CLASS +} bracket_elem_type; + +typedef struct +{ + bracket_elem_type type; + union + { + unsigned char ch; + unsigned char *name; + wchar_t wch; + } opr; +} bracket_elem_t; + + +/* Functions for bitset_t operation. */ + +static inline void +bitset_set (bitset_t set, Idx i) +{ + set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; +} + +static inline void +bitset_clear (bitset_t set, Idx i) +{ + set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); +} + +static inline bool +bitset_contain (const bitset_t set, Idx i) +{ + return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; +} + +static inline void +bitset_empty (bitset_t set) +{ + memset (set, '\0', sizeof (bitset_t)); +} + +static inline void +bitset_set_all (bitset_t set) +{ + memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); + if (SBC_MAX % BITSET_WORD_BITS != 0) + set[BITSET_WORDS - 1] = + ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; +} + +static inline void +bitset_copy (bitset_t dest, const bitset_t src) +{ + memcpy (dest, src, sizeof (bitset_t)); +} + +static inline void +bitset_not (bitset_t set) +{ + int bitset_i; + for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i) + set[bitset_i] = ~set[bitset_i]; + if (SBC_MAX % BITSET_WORD_BITS != 0) + set[BITSET_WORDS - 1] = + ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1) + & ~set[BITSET_WORDS - 1]); +} + +static inline void +bitset_merge (bitset_t dest, const bitset_t src) +{ + int bitset_i; + for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) + dest[bitset_i] |= src[bitset_i]; +} + +static inline void +bitset_mask (bitset_t dest, const bitset_t src) +{ + int bitset_i; + for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) + dest[bitset_i] &= src[bitset_i]; +} + +/* Functions for re_string. */ +static int +__attribute__ ((pure, unused)) +re_string_char_size_at (const re_string_t *pstr, Idx idx) +{ + int byte_idx; + if (pstr->mb_cur_max == 1) + return 1; + for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) + if (pstr->wcs[idx + byte_idx] != WEOF) + break; + return byte_idx; +} + +static wint_t +__attribute__ ((pure, unused)) +re_string_wchar_at (const re_string_t *pstr, Idx idx) +{ + if (pstr->mb_cur_max == 1) + return (wint_t) pstr->mbs[idx]; + return (wint_t) pstr->wcs[idx]; +} + +#ifdef _LIBC +# include +#endif + +static int +__attribute__ ((pure, unused)) +re_string_elem_size_at (const re_string_t *pstr, Idx idx) +{ +#ifdef _LIBC + const unsigned char *p, *extra; + const int32_t *table, *indirect; + uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + + if (nrules != 0) + { + table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_INDIRECTMB); + p = pstr->mbs + idx; + findidx (table, indirect, extra, &p, pstr->len - idx); + return p - pstr->mbs - idx; + } +#endif /* _LIBC */ + + return 1; +} + +#ifdef _LIBC +# if __GNUC__ >= 7 +# define FALLTHROUGH __attribute__ ((__fallthrough__)) +# else +# define FALLTHROUGH ((void) 0) +# endif +#else +# include "attribute.h" +#endif + +#endif /* _REGEX_INTERNAL_H */ diff --git a/lib/regexec.c b/lib/regexec.c new file mode 100644 index 0000000..aea1e7d --- /dev/null +++ b/lib/regexec.c @@ -0,0 +1,4220 @@ +/* Extended regular expression matching and search library. + 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 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 + . */ + +static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, + 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); +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); +static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, + 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); +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); +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); +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); +static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, + 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); +static Idx check_halt_state_context (const re_match_context_t *mctx, + 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); +static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, + Idx str_idx, Idx dest_node, Idx nregs, + 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); +static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs); + +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); +static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, + 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); +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); +static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, + re_node_set *dest_nodes, + 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); +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); +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); +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); +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); +static reg_errcode_t merge_state_array (const re_dfa_t *dfa, + re_dfastate_t **dst, + re_dfastate_t **src, Idx num); +static re_dfastate_t *find_recover_state (reg_errcode_t *err, + re_match_context_t *mctx); +static re_dfastate_t *transit_state (reg_errcode_t *err, + re_match_context_t *mctx, + 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); +static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, + re_node_set *cur_nodes, + 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); +#endif +static reg_errcode_t transit_state_mb (re_match_context_t *mctx, + re_dfastate_t *pstate); +static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, + const re_node_set *nodes); +static reg_errcode_t get_subexp (re_match_context_t *mctx, + 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); +static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + 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); +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); +static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, + re_node_set *cur_nodes, + 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); +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); +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); +#ifdef _LIBC +static unsigned int find_collation_sequence_value (const unsigned char *mbs, + 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); +static bool check_node_accept (const re_match_context_t *mctx, + 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. */ + +/* regexec searches for a given pattern, specified by PREG, in the + string STRING. + + If NMATCH is zero or REG_NOSUB was set in the cflags argument to + 'regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at + least NMATCH elements, and we set them to the offsets of the + corresponding matched substrings. + + EFLAGS specifies "execution flags" which affect matching: if + 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. + + Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if + EFLAGS is invalid. */ + +int +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; + re_dfa_t *dfa = preg->buffer; + + if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) + return REG_BADPAT; + + if (eflags & REG_STARTEND) + { + start = pmatch[0].rm_so; + length = pmatch[0].rm_eo; + } + else + { + start = 0; + length = strlen (string); + } + + lock_lock (dfa->lock); + if (preg->no_sub) + err = re_search_internal (preg, string, length, start, length, + length, 0, NULL, eflags); + else + err = re_search_internal (preg, string, length, start, length, + length, nmatch, pmatch, eflags); + lock_unlock (dfa->lock); + return err != REG_NOERROR; +} + +#ifdef _LIBC +libc_hidden_def (__regexec) + +# include +versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) +__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[_REGEX_NELTS (nmatch)], int eflags) +{ + return regexec (preg, string, nmatch, pmatch, + eflags & (REG_NOTBOL | REG_NOTEOL)); +} +compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); +# endif +#endif + +/* Entry points for GNU code. */ + +/* re_match, re_search, re_match_2, re_search_2 + + The former two functions operate on STRING with length LENGTH, + while the later two operate on concatenation of STRING1 and STRING2 + with lengths LENGTH1 and LENGTH2, respectively. + + re_match() matches the compiled pattern in BUFP against the string, + starting at index START. + + re_search() first tries matching at index START, then it tries to match + starting from index START + 1, and so on. The last start position tried + is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same + way as re_match().) + + The parameter STOP of re_{match,search}_2 specifies that no match exceeding + the first STOP characters of the concatenation of the strings should be + concerned. + + If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match + and all groups is stored in REGS. (For the "_2" variants, the offsets are + computed relative to the concatenation, not relative to the individual + strings.) + + On success, re_match* functions return the length of the match, re_search* + return the position of the start of the match. They return -1 on + match failure, -2 on error. */ + +regoff_t +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); +} +#ifdef _LIBC +weak_alias (__re_match, re_match) +#endif + +regoff_t +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); +} +#ifdef _LIBC +weak_alias (__re_search, re_search) +#endif + +regoff_t +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); +} +#ifdef _LIBC +weak_alias (__re_match_2, re_match_2) +#endif + +regoff_t +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); +} +#ifdef _LIBC +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, + Idx stop, bool ret_len) +{ + const char *str; + regoff_t rval; + Idx len; + char *s = NULL; + + if (__glibc_unlikely ((length1 < 0 || length2 < 0 || stop < 0 + || INT_ADD_WRAPV (length1, length2, &len)))) + return -2; + + /* Concatenate the strings. */ + if (length2 > 0) + if (length1 > 0) + { + s = re_malloc (char, len); + + if (__glibc_unlikely (s == NULL)) + return -2; +#ifdef _LIBC + memcpy (__mempcpy (s, string1, length1), string2, length2); +#else + memcpy (s, string1, length1); + memcpy (s + length1, string2, length2); +#endif + str = s; + } + else + str = string2; + else + str = string1; + + rval = re_search_stub (bufp, str, len, start, range, stop, regs, + ret_len); + re_free (s); + return rval; +} + +/* The parameters have the same meaning as those of re_search. + Additional parameters: + If RET_LEN is true the length of the match is returned (re_match style); + otherwise the position of the match is returned. */ + +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) +{ + reg_errcode_t result; + regmatch_t *pmatch; + Idx nregs; + regoff_t rval; + int eflags = 0; + re_dfa_t *dfa = bufp->buffer; + Idx last_start = start + range; + + /* Check for out-of-range. */ + if (__glibc_unlikely (start < 0 || start > length)) + return -1; + if (__glibc_unlikely (length < last_start + || (0 <= range && last_start < start))) + last_start = length; + else if (__glibc_unlikely (last_start < 0 + || (range < 0 && start <= last_start))) + last_start = 0; + + lock_lock (dfa->lock); + + eflags |= (bufp->not_bol) ? REG_NOTBOL : 0; + eflags |= (bufp->not_eol) ? REG_NOTEOL : 0; + + /* Compile fastmap if we haven't yet. */ + if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate) + re_compile_fastmap (bufp); + + if (__glibc_unlikely (bufp->no_sub)) + regs = NULL; + + /* We need at least 1 register. */ + if (regs == NULL) + nregs = 1; + else if (__glibc_unlikely (bufp->regs_allocated == REGS_FIXED + && regs->num_regs <= bufp->re_nsub)) + { + nregs = regs->num_regs; + if (__glibc_unlikely (nregs < 1)) + { + /* Nothing can be copied to regs. */ + regs = NULL; + nregs = 1; + } + } + else + nregs = bufp->re_nsub + 1; + pmatch = re_malloc (regmatch_t, nregs); + if (__glibc_unlikely (pmatch == NULL)) + { + rval = -2; + goto out; + } + + result = re_search_internal (bufp, string, length, start, last_start, stop, + nregs, pmatch, eflags); + + rval = 0; + + /* I hope we needn't fill their regs with -1's when no match was found. */ + if (result != REG_NOERROR) + rval = result == REG_NOMATCH ? -1 : -2; + else if (regs != NULL) + { + /* If caller wants register contents data back, copy them. */ + bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs, + bufp->regs_allocated); + if (__glibc_unlikely (bufp->regs_allocated == REGS_UNALLOCATED)) + rval = -2; + } + + if (__glibc_likely (rval == 0)) + { + if (ret_len) + { + DEBUG_ASSERT (pmatch[0].rm_so == start); + rval = pmatch[0].rm_eo - start; + } + else + rval = pmatch[0].rm_so; + } + re_free (pmatch); + out: + lock_unlock (dfa->lock); + return rval; +} + +static unsigned +re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, + int regs_allocated) +{ + int rval = REGS_REALLOCATE; + Idx i; + Idx need_regs = nregs + 1; + /* We need one extra element beyond 'num_regs' for the '-1' marker GNU code + uses. */ + + /* Have the register data arrays been allocated? */ + if (regs_allocated == REGS_UNALLOCATED) + { /* No. So allocate them with malloc. */ + regs->start = re_malloc (regoff_t, need_regs); + if (__glibc_unlikely (regs->start == NULL)) + return REGS_UNALLOCATED; + regs->end = re_malloc (regoff_t, need_regs); + if (__glibc_unlikely (regs->end == NULL)) + { + re_free (regs->start); + return REGS_UNALLOCATED; + } + regs->num_regs = need_regs; + } + else if (regs_allocated == REGS_REALLOCATE) + { /* Yes. If we need more elements than were already + allocated, reallocate them. If we need fewer, just + leave it alone. */ + 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 (__glibc_unlikely (new_start == NULL)) + return REGS_UNALLOCATED; + new_end = re_realloc (regs->end, regoff_t, need_regs); + if (__glibc_unlikely (new_end == NULL)) + { + re_free (new_start); + return REGS_UNALLOCATED; + } + regs->start = new_start; + regs->end = new_end; + regs->num_regs = need_regs; + } + } + else + { + DEBUG_ASSERT (regs_allocated == REGS_FIXED); + /* This function may not be called with REGS_FIXED and nregs too big. */ + DEBUG_ASSERT (nregs <= regs->num_regs); + rval = REGS_FIXED; + } + + /* Copy the regs. */ + for (i = 0; i < nregs; ++i) + { + regs->start[i] = pmatch[i].rm_so; + regs->end[i] = pmatch[i].rm_eo; + } + for ( ; i < regs->num_regs; ++i) + regs->start[i] = regs->end[i] = -1; + + return rval; +} + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use + this memory for recording register information. STARTS and ENDS + must be allocated using the malloc library routine, and must each + be at least NUM_REGS * sizeof (regoff_t) bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ + +void +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) + { + bufp->regs_allocated = REGS_REALLOCATE; + regs->num_regs = num_regs; + regs->start = starts; + regs->end = ends; + } + else + { + bufp->regs_allocated = REGS_UNALLOCATED; + regs->num_regs = 0; + regs->start = regs->end = NULL; + } +} +#ifdef _LIBC +weak_alias (__re_set_registers, re_set_registers) +#endif + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC +int +# ifdef _LIBC +weak_function +# endif +re_exec (const char *s) +{ + return 0 == regexec (&re_comp_buf, s, 0, NULL, 0); +} +#endif /* _REGEX_RE_COMP */ + +/* Internal entry point. */ + +/* Searches for a compiled pattern PREG in the string STRING, whose + length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same + meaning as with regexec. LAST_START is START + RANGE, where + START and RANGE have the same meaning as with re_search. + Return REG_NOERROR if we find a match, and REG_NOMATCH if not, + otherwise return the error code. + Note: We assume front end functions already check ranges. + (0 <= LAST_START && LAST_START <= LENGTH) */ + +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) +{ + reg_errcode_t err; + const re_dfa_t *dfa = preg->buffer; + Idx left_lim, right_lim; + int incr; + bool fl_longest_match; + int match_kind; + Idx match_first; + Idx match_last = -1; + Idx extra_nmatch; + bool sb; + int ch; + re_match_context_t mctx = { .dfa = dfa }; + char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate + && start != last_start && !preg->can_be_null) + ? preg->fastmap : NULL); + RE_TRANSLATE_TYPE t = preg->translate; + + extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; + nmatch -= extra_nmatch; + + /* Check if the DFA haven't been compiled. */ + 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; + + /* We assume front-end functions already check them. */ + 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, + we'll never use init_state_nl, so do not check it. */ + if (dfa->init_state->nodes.nelem == 0 + && dfa->init_state_word->nodes.nelem == 0 + && (dfa->init_state_nl->nodes.nelem == 0 + || !preg->newline_anchor)) + { + if (start != 0 && last_start != 0) + return REG_NOMATCH; + start = last_start = 0; + } + + /* We must check the longest matching, if nmatch > 0. */ + fl_longest_match = (nmatch != 0 || dfa->nbackref); + + err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, + preg->translate, (preg->syntax & RE_ICASE) != 0, + dfa); + 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 (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + + /* We will log all the DFA states through which the dfa pass, + if nmatch > 1, or this dfa has "multibyte node", which is a + back-reference or a node which can accept multibyte character or + multi character collating element. */ + if (nmatch > 1 || dfa->has_mb_node) + { + /* Avoid overflow. */ + 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 (__glibc_unlikely (mctx.state_log == NULL)) + { + err = REG_ESPACE; + goto free_return; + } + } + + match_first = start; + mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF + : CONTEXT_NEWLINE | CONTEXT_BEGBUF; + + /* Check incrementally whether the input string matches. */ + incr = (last_start < start) ? -1 : 1; + left_lim = (last_start < start) ? last_start : start; + right_lim = (last_start < start) ? start : last_start; + sb = dfa->mb_cur_max == 1; + match_kind = + (fastmap + ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0) + | (start <= last_start ? 2 : 0) + | (t != NULL ? 1 : 0)) + : 8); + + for (;; match_first += incr) + { + err = REG_NOMATCH; + if (match_first < left_lim || right_lim < match_first) + goto free_return; + + /* Advance as rapidly as possible through the string, until we + find a plausible place to start matching. This may be done + with varying efficiency, so there are various possibilities: + only the most common of them are specialized, in order to + save on code size. We use a switch statement for speed. */ + switch (match_kind) + { + case 8: + /* No fastmap. */ + break; + + case 7: + /* Fastmap with single-byte translation, match forward. */ + 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 (__glibc_likely (match_first < right_lim) + && !fastmap[(unsigned char) string[match_first]]) + ++match_first; + + forward_match_found_start_or_reached_end: + if (__glibc_unlikely (match_first == right_lim)) + { + ch = match_first >= length + ? 0 : (unsigned char) string[match_first]; + if (!fastmap[t ? t[ch] : ch]) + goto free_return; + } + break; + + case 4: + case 5: + /* Fastmap without multi-byte translation, match backwards. */ + while (match_first >= left_lim) + { + ch = match_first >= length + ? 0 : (unsigned char) string[match_first]; + if (fastmap[t ? t[ch] : ch]) + break; + --match_first; + } + if (match_first < left_lim) + goto free_return; + break; + + default: + /* In this case, we can't determine easily the current byte, + since it might be a component byte of a multibyte + character. Then we use the constructed buffer instead. */ + for (;;) + { + /* If MATCH_FIRST is out of the valid range, reconstruct the + buffers. */ + __re_size_t offset = match_first - mctx.input.raw_mbs_idx; + if (__glibc_unlikely (offset + >= (__re_size_t) mctx.input.valid_raw_len)) + { + err = re_string_reconstruct (&mctx.input, match_first, + eflags); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + + offset = match_first - mctx.input.raw_mbs_idx; + } + /* 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; + if (match_first < left_lim || match_first > right_lim) + { + err = REG_NOMATCH; + goto free_return; + } + } + break; + } + + /* 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 (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + + /* 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; + + /* 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 != -1) + { + if (__glibc_unlikely (match_last == -2)) + { + err = REG_ESPACE; + goto free_return; + } + else + { + mctx.match_last = match_last; + if ((!preg->no_sub && nmatch > 1) || dfa->nbackref) + { + re_dfastate_t *pstate = mctx.state_log[match_last]; + mctx.last_node = check_halt_state_context (&mctx, pstate, + match_last); + } + if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match) + || dfa->nbackref) + { + err = prune_impossible_nodes (&mctx); + if (err == REG_NOERROR) + break; + if (__glibc_unlikely (err != REG_NOMATCH)) + goto free_return; + match_last = -1; + } + else + break; /* We found a match. */ + } + } + + match_ctx_clean (&mctx); + } + + DEBUG_ASSERT (match_last != -1); + DEBUG_ASSERT (err == REG_NOERROR); + + /* Set pmatch[] if we need. */ + if (nmatch > 0) + { + Idx reg_idx; + + /* Initialize registers. */ + for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) + pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; + + /* Set the points where matching start/end. */ + pmatch[0].rm_so = 0; + pmatch[0].rm_eo = mctx.match_last; + /* FIXME: This function should fail if mctx.match_last exceeds + the maximum possible regoff_t value. We need a new error + code REG_OVERFLOW. */ + + if (!preg->no_sub && nmatch > 1) + { + err = set_regs (preg, &mctx, nmatch, pmatch, + dfa->has_plural_match && dfa->nbackref > 0); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + } + + /* At last, add the offset to each register, since we slid + the buffers so that we could assume that the matching starts + from 0. */ + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) + if (pmatch[reg_idx].rm_so != -1) + { + if (__glibc_unlikely (mctx.input.offsets_needed != 0)) + { + pmatch[reg_idx].rm_so = + (pmatch[reg_idx].rm_so == mctx.input.valid_len + ? mctx.input.valid_raw_len + : mctx.input.offsets[pmatch[reg_idx].rm_so]); + pmatch[reg_idx].rm_eo = + (pmatch[reg_idx].rm_eo == mctx.input.valid_len + ? mctx.input.valid_raw_len + : mctx.input.offsets[pmatch[reg_idx].rm_eo]); + } + pmatch[reg_idx].rm_so += match_first; + pmatch[reg_idx].rm_eo += match_first; + } + for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx) + { + pmatch[nmatch + reg_idx].rm_so = -1; + pmatch[nmatch + reg_idx].rm_eo = -1; + } + + if (dfa->subexp_map) + for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) + if (dfa->subexp_map[reg_idx] != reg_idx) + { + pmatch[reg_idx + 1].rm_so + = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; + pmatch[reg_idx + 1].rm_eo + = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; + } + } + + free_return: + re_free (mctx.state_log); + if (dfa->nbackref) + match_ctx_free (&mctx); + re_string_destruct (&mctx.input); + return err; +} + +static reg_errcode_t +__attribute_warn_unused_result__ +prune_impossible_nodes (re_match_context_t *mctx) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx halt_node, match_last; + reg_errcode_t ret; + re_dfastate_t **sifted_states; + re_dfastate_t **lim_states = NULL; + re_sift_context_t sctx; + DEBUG_ASSERT (mctx->state_log != NULL); + match_last = mctx->match_last; + halt_node = mctx->last_node; + + /* Avoid overflow. */ + 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 (__glibc_unlikely (sifted_states == NULL)) + { + ret = REG_ESPACE; + goto free_return; + } + if (dfa->nbackref) + { + lim_states = re_malloc (re_dfastate_t *, match_last + 1); + if (__glibc_unlikely (lim_states == NULL)) + { + ret = REG_ESPACE; + goto free_return; + } + while (1) + { + memset (lim_states, '\0', + sizeof (re_dfastate_t *) * (match_last + 1)); + 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 (__glibc_unlikely (ret != REG_NOERROR)) + goto free_return; + if (sifted_states[0] != NULL || lim_states[0] != NULL) + break; + do + { + --match_last; + if (match_last < 0) + { + ret = REG_NOMATCH; + goto free_return; + } + } while (mctx->state_log[match_last] == NULL + || !mctx->state_log[match_last]->halt); + halt_node = check_halt_state_context (mctx, + mctx->state_log[match_last], + match_last); + } + ret = merge_state_array (dfa, sifted_states, lim_states, + match_last + 1); + re_free (lim_states); + lim_states = NULL; + if (__glibc_unlikely (ret != REG_NOERROR)) + goto free_return; + } + else + { + 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 (__glibc_unlikely (ret != REG_NOERROR)) + goto free_return; + if (sifted_states[0] == NULL) + { + ret = REG_NOMATCH; + goto free_return; + } + } + re_free (mctx->state_log); + mctx->state_log = sifted_states; + sifted_states = NULL; + mctx->last_node = halt_node; + mctx->match_last = match_last; + ret = REG_NOERROR; + free_return: + re_free (sifted_states); + re_free (lim_states); + return ret; +} + +/* Acquire an initial state and return it. + We must select appropriate initial state depending on the context, + since initial states may have constraints like "\<", "^", etc.. */ + +static __always_inline re_dfastate_t * +acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, + Idx idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + if (dfa->init_state->has_constraint) + { + unsigned int context; + context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags); + if (IS_WORD_CONTEXT (context)) + return dfa->init_state_word; + else if (IS_ORDINARY_CONTEXT (context)) + return dfa->init_state; + else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context)) + return dfa->init_state_begbuf; + else if (IS_NEWLINE_CONTEXT (context)) + return dfa->init_state_nl; + else if (IS_BEGBUF_CONTEXT (context)) + { + /* It is relatively rare case, then calculate on demand. */ + return re_acquire_state_context (err, dfa, + dfa->init_state->entrance_nodes, + context); + } + else + /* Must not happen? */ + return dfa->init_state; + } + else + return dfa->init_state; +} + +/* Check whether the regular expression match input string INPUT or not, + 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. + Note that the matcher assumes that the matching starts from the current + index of the buffer. */ + +static Idx +__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 = -1; + Idx cur_str_idx = re_string_cur_idx (&mctx->input); + re_dfastate_t *cur_state; + bool at_init_state = p_match_first != NULL; + Idx next_start_idx = cur_str_idx; + + err = REG_NOERROR; + cur_state = acquire_init_state_context (&err, mctx, cur_str_idx); + /* An initial state must not be NULL (invalid). */ + if (__glibc_unlikely (cur_state == NULL)) + { + DEBUG_ASSERT (err == REG_ESPACE); + return -2; + } + + if (mctx->state_log != NULL) + { + mctx->state_log[cur_str_idx] = cur_state; + + /* Check OP_OPEN_SUBEXP in the initial state in case that we use them + later. E.g. Processing back references. */ + if (__glibc_unlikely (dfa->nbackref)) + { + at_init_state = false; + err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + + if (cur_state->has_backref) + { + err = transit_state_bkref (mctx, &cur_state->nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + } + } + + /* If the RE accepts NULL string. */ + if (__glibc_unlikely (cur_state->halt)) + { + if (!cur_state->has_constraint + || check_halt_state_context (mctx, cur_state, cur_str_idx)) + { + if (!fl_longest_match) + return cur_str_idx; + else + { + match_last = cur_str_idx; + match = 1; + } + } + } + + while (!re_string_eoi (&mctx->input)) + { + re_dfastate_t *old_state = cur_state; + Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1; + + if ((__glibc_unlikely (next_char_idx >= mctx->input.bufs_len) + && mctx->input.bufs_len < mctx->input.len) + || (__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 (__glibc_unlikely (err != REG_NOERROR)) + { + DEBUG_ASSERT (err == REG_ESPACE); + return -2; + } + } + + cur_state = transit_state (&err, mctx, cur_state); + if (mctx->state_log != NULL) + cur_state = merge_state_with_log (&err, mctx, cur_state); + + if (cur_state == NULL) + { + /* 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 (__glibc_unlikely (err != REG_NOERROR)) + return -2; + + if (mctx->state_log == NULL + || (match && !fl_longest_match) + || (cur_state = find_recover_state (&err, mctx)) == NULL) + break; + } + + if (__glibc_unlikely (at_init_state)) + { + if (old_state == cur_state) + next_start_idx = next_char_idx; + else + at_init_state = false; + } + + if (cur_state->halt) + { + /* Reached a halt state. + Check the halt state can satisfy the current context. */ + if (!cur_state->has_constraint + || check_halt_state_context (mctx, cur_state, + re_string_cur_idx (&mctx->input))) + { + /* We found an appropriate halt state. */ + match_last = re_string_cur_idx (&mctx->input); + match = 1; + + /* We found a match, do not modify match_first below. */ + p_match_first = NULL; + if (!fl_longest_match) + break; + } + } + } + + if (p_match_first) + *p_match_first += next_start_idx; + + return match_last; +} + +/* Check NODE match the current context. */ + +static bool +check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) +{ + re_token_type_t type = dfa->nodes[node].type; + unsigned int constraint = dfa->nodes[node].constraint; + if (type != END_OF_RE) + return false; + if (!constraint) + return true; + if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context)) + return false; + return true; +} + +/* Check the halt state STATE match the current context. + Return 0 if not match, if the node, STATE has, is a halt node and + match the context, return the node. */ + +static Idx +check_halt_state_context (const re_match_context_t *mctx, + const re_dfastate_t *state, Idx idx) +{ + Idx i; + unsigned int context; + 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)) + return state->nodes.elems[i]; + return 0; +} + +/* 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 -1 on match failure, -2 on error. */ + +static Idx +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; + 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]; + + 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 == -1) + dest_node = candidate; + + else + { + /* In order to avoid infinite loop like "(a*)*", return the second + epsilon-transition if the first was already considered. */ + if (re_node_set_contains (eps_via_nodes, dest_node)) + return candidate; + + /* Otherwise, push the second epsilon-transition on the fail stack. */ + else if (fs != NULL + && push_fail_stack (fs, *pidx, candidate, nregs, regs, + prevregs, eps_via_nodes)) + return -2; + + /* We know we are going to exit. */ + break; + } + } + return dest_node; + } + else + { + Idx naccepted = 0; + re_token_type_t type = dfa->nodes[node].type; + + if (dfa->nodes[node].accept_mb) + naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); + else if (type == OP_BACK_REF) + { + Idx subexp_idx = dfa->nodes[node].opr.idx + 1; + if (subexp_idx < nregs) + naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; + if (fs != NULL) + { + 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 (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; + 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)) + return dest_node; + } + } + + if (naccepted != 0 + || check_node_accept (mctx, dfa->nodes + node, *pidx)) + { + Idx dest_node = dfa->nexts[node]; + *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted; + if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL + || !re_node_set_contains (&mctx->state_log[*pidx]->nodes, + dest_node))) + return -1; + re_node_set_empty (eps_via_nodes); + return dest_node; + } + } + return -1; +} + +static reg_errcode_t +__attribute_warn_unused_result__ +push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, + 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) + { + struct re_fail_stack_ent_t *new_array; + 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; + fs->stack = new_array; + } + fs->stack[num].idx = str_idx; + fs->stack[num].node = dest_node; + fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs); + if (fs->stack[num].regs == NULL) + return REG_ESPACE; + 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 +pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, + regmatch_t *regs, regmatch_t *prevregs, + re_node_set *eps_via_nodes) +{ + if (fs == NULL || fs->num == 0) + return -1; + Idx num = --fs->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 +__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) +{ + const re_dfa_t *dfa = preg->buffer; + Idx idx, cur_node; + re_node_set eps_via_nodes; + struct re_fail_stack_t *fs; + struct re_fail_stack_t fs_body = { 0, 2, NULL }; + struct regmatch_list prev_match; + regmatch_list_init (&prev_match); + + DEBUG_ASSERT (nmatch > 1); + DEBUG_ASSERT (mctx->state_log != NULL); + if (fl_backtrack) + { + fs = &fs_body; + fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc); + if (fs->stack == NULL) + return REG_ESPACE; + } + else + fs = NULL; + + cur_node = dfa->init_node; + re_node_set_init_empty (&eps_via_nodes); + + if (!regmatch_list_resize (&prev_match, nmatch)) + { + 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) + || (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) + { + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + prev_idx_match, &eps_via_nodes); + break; + } + } + if (cur_node < 0) + { + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); + return free_fail_stack_return (fs); + } + } + + /* Proceed to next node. */ + cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match, + &idx, cur_node, + &eps_via_nodes, fs); + + if (__glibc_unlikely (cur_node < 0)) + { + if (__glibc_unlikely (cur_node == -2)) + { + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); + free_fail_stack_return (fs); + return REG_ESPACE; + } + 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); + regmatch_list_free (&prev_match); + free_fail_stack_return (fs); + return REG_NOMATCH; + } + } + } + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); + return free_fail_stack_return (fs); +} + +static reg_errcode_t +free_fail_stack_return (struct re_fail_stack_t *fs) +{ + if (fs) + { + Idx fs_idx; + for (fs_idx = 0; fs_idx < fs->num; ++fs_idx) + { + re_node_set_free (&fs->stack[fs_idx].eps_via_nodes); + re_free (fs->stack[fs_idx].regs); + } + re_free (fs->stack); + } + return REG_NOERROR; +} + +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) +{ + int type = dfa->nodes[cur_node].type; + if (type == OP_OPEN_SUBEXP) + { + Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; + + /* We are at the first node of this sub expression. */ + if (reg_num < nmatch) + { + pmatch[reg_num].rm_so = cur_idx; + pmatch[reg_num].rm_eo = -1; + } + } + 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) + { + if (pmatch[reg_num].rm_so < cur_idx) + { + pmatch[reg_num].rm_eo = cur_idx; + /* This is a non-empty match or we are not inside an optional + subexpression. Accept this right away. */ + memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); + } + else + { + if (dfa->nodes[cur_node].opt_subexp + && prev_idx_match[reg_num].rm_so != -1) + /* We transited through an empty match for an optional + subexpression, like (a?)*, and this is not the subexp's + first match. Copy back the old content of the registers + so that matches of an inner subexpression are undone as + well, like in ((a?))*. */ + memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch); + else + /* We completed a subexpression, but it may be part of + an optional one, so do not update PREV_IDX_MATCH. */ + pmatch[reg_num].rm_eo = cur_idx; + } + } + } +} + +/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0 + and sift the nodes in each states according to the following rules. + Updated state_log will be wrote to STATE_LOG. + + Rules: We throw away the Node 'a' in the STATE_LOG[STR_IDX] if... + 1. When STR_IDX == MATCH_LAST(the last index in the state_log): + If 'a' isn't the LAST_NODE and 'a' can't epsilon transit to + the LAST_NODE, we throw away the node 'a'. + 2. When 0 <= STR_IDX < MATCH_LAST and 'a' accepts + string 's' and transit to 'b': + i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw + away the node 'a'. + ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is + thrown away, we throw away the node 'a'. + 3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b': + i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the + node 'a'. + ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away, + we throw away the node 'a'. */ + +#define STATE_NODE_CONTAINS(state,node) \ + ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) + +static reg_errcode_t +sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) +{ + reg_errcode_t err; + int null_cnt = 0; + Idx str_idx = sctx->last_str_idx; + re_node_set cur_dest; + + 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + + /* Then check each states in the state_log. */ + while (str_idx > 0) + { + /* Update counters. */ + null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0; + if (null_cnt > mctx->max_mb_elem_len) + { + memset (sctx->sifted_states, '\0', + sizeof (re_dfastate_t *) * str_idx); + re_node_set_free (&cur_dest); + return REG_NOERROR; + } + re_node_set_empty (&cur_dest); + --str_idx; + + if (mctx->state_log[str_idx]) + { + err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + } + + /* Add all the nodes which satisfy the following conditions: + - It can epsilon transit to a node in CUR_DEST. + - It is in CUR_SRC. + And update state_log. */ + err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + } + err = REG_NOERROR; + free_return: + re_node_set_free (&cur_dest); + return err; +} + +static reg_errcode_t +__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) +{ + const re_dfa_t *const dfa = mctx->dfa; + const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes; + Idx i; + + /* Then build the next sifted state. + We build the next sifted state on 'cur_dest', and update + 'sifted_states[str_idx]' with 'cur_dest'. + Note: + 'cur_dest' is the sifted state from 'state_log[str_idx + 1]'. + 'cur_src' points the node_set of the old 'state_log[str_idx]' + (with the epsilon nodes pre-filtered out). */ + for (i = 0; i < cur_src->nelem; i++) + { + Idx prev_node = cur_src->elems[i]; + int naccepted = 0; + bool ok; + DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[prev_node].type)); + + /* 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); + + /* We don't check backreferences here. + See update_cur_sifted_state(). */ + if (!naccepted + && check_node_accept (mctx, dfa->nodes + prev_node, str_idx) + && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1], + dfa->nexts[prev_node])) + naccepted = 1; + + if (naccepted == 0) + continue; + + if (sctx->limits.nelem) + { + Idx to_idx = str_idx + naccepted; + if (check_dst_limits (mctx, &sctx->limits, + dfa->nexts[prev_node], to_idx, + prev_node, str_idx)) + continue; + } + ok = re_node_set_insert (cur_dest, prev_node); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + + return REG_NOERROR; +} + +/* Helper functions. */ + +static reg_errcode_t +clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) +{ + Idx top = mctx->state_log_top; + + if ((next_state_log_idx >= mctx->input.bufs_len + && mctx->input.bufs_len < mctx->input.len) + || (next_state_log_idx >= mctx->input.valid_len + && mctx->input.valid_len < mctx->input.len)) + { + reg_errcode_t err; + err = extend_buffers (mctx, next_state_log_idx + 1); + 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; + } + return REG_NOERROR; +} + +static reg_errcode_t +merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, + re_dfastate_t **src, Idx num) +{ + Idx st_idx; + reg_errcode_t err; + for (st_idx = 0; st_idx < num; ++st_idx) + { + if (dst[st_idx] == NULL) + dst[st_idx] = src[st_idx]; + else if (src[st_idx] != NULL) + { + re_node_set merged_set; + err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes, + &src[st_idx]->nodes); + 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + } + return REG_NOERROR; +} + +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) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err = REG_NOERROR; + const re_node_set *candidates; + candidates = ((mctx->state_log[str_idx] == NULL) ? NULL + : &mctx->state_log[str_idx]->nodes); + + if (dest_nodes->nelem == 0) + sctx->sifted_states[str_idx] = NULL; + else + { + if (candidates) + { + /* 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + + /* Then, check the limitations in the current sift_context. */ + if (sctx->limits.nelem) + { + err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits, + mctx->bkref_ents, str_idx); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + } + + sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); + 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + return REG_NOERROR; +} + +static reg_errcode_t +__attribute_warn_unused_result__ +add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, + const re_node_set *candidates) +{ + reg_errcode_t err = REG_NOERROR; + Idx i; + + re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + + if (!state->inveclosure.alloc) + { + err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); + 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 (__glibc_unlikely (err != REG_NOERROR)) + return REG_ESPACE; + } + } + return re_node_set_add_intersect (dest_nodes, candidates, + &state->inveclosure); +} + +static reg_errcode_t +sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, + const re_node_set *candidates) +{ + Idx ecl_idx; + reg_errcode_t err; + re_node_set *inv_eclosure = dfa->inveclosures + node; + re_node_set except_nodes; + re_node_set_init_empty (&except_nodes); + for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) + { + Idx cur_node = inv_eclosure->elems[ecl_idx]; + if (cur_node == node) + continue; + if (IS_EPSILON_NODE (dfa->nodes[cur_node].type)) + { + Idx edst1 = dfa->edests[cur_node].elems[0]; + Idx edst2 = ((dfa->edests[cur_node].nelem > 1) + ? dfa->edests[cur_node].elems[1] : -1); + if ((!re_node_set_contains (inv_eclosure, edst1) + && re_node_set_contains (dest_nodes, edst1)) + || (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 (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&except_nodes); + return err; + } + } + } + } + for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) + { + Idx cur_node = inv_eclosure->elems[ecl_idx]; + if (!re_node_set_contains (&except_nodes, cur_node)) + { + Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1; + re_node_set_remove_at (dest_nodes, idx); + } + } + re_node_set_free (&except_nodes); + return REG_NOERROR; +} + +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) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx lim_idx, src_pos, dst_pos; + + Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx); + Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx); + for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) + { + Idx subexp_idx; + struct re_backref_cache_entry *ent; + ent = mctx->bkref_ents + limits->elems[lim_idx]; + subexp_idx = dfa->nodes[ent->node].opr.idx; + + dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], + subexp_idx, dst_node, dst_idx, + dst_bkref_idx); + src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], + subexp_idx, src_node, src_idx, + src_bkref_idx); + + /* In case of: + ( ) + ( ) + ( ) */ + if (src_pos == dst_pos) + continue; /* This is unrelated limitation. */ + else + return true; + } + return false; +} + +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) +{ + const re_dfa_t *const dfa = mctx->dfa; + const re_node_set *eclosures = dfa->eclosures + from_node; + Idx node_idx; + + /* Else, we are on the boundary: examine the nodes on the epsilon + closure. */ + for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx) + { + Idx node = eclosures->elems[node_idx]; + switch (dfa->nodes[node].type) + { + case OP_BACK_REF: + if (bkref_idx != -1) + { + struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; + do + { + Idx dst; + int cpos; + + if (ent->node != node) + continue; + + if (subexp_idx < BITSET_WORD_BITS + && !(ent->eps_reachable_subexps_map + & ((bitset_word_t) 1 << subexp_idx))) + continue; + + /* Recurse trying to reach the OP_OPEN_SUBEXP and + OP_CLOSE_SUBEXP cases below. But, if the + destination node is the same node as the source + node, don't recurse because it would cause an + infinite loop: a regex that exhibits this behavior + is ()\1*\1* */ + dst = dfa->edests[node].elems[0]; + if (dst == from_node) + { + if (boundaries & 1) + return -1; + else /* if (boundaries & 2) */ + return 0; + } + + cpos = + check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, + dst, bkref_idx); + if (cpos == -1 /* && (boundaries & 1) */) + return -1; + if (cpos == 0 && (boundaries & 2)) + return 0; + + if (subexp_idx < BITSET_WORD_BITS) + ent->eps_reachable_subexps_map + &= ~((bitset_word_t) 1 << subexp_idx); + } + while (ent++->more); + } + break; + + case OP_OPEN_SUBEXP: + if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx) + return -1; + break; + + case OP_CLOSE_SUBEXP: + if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx) + return 0; + break; + + default: + break; + } + } + + return (boundaries & 2) ? 1 : 0; +} + +static int +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) +{ + struct re_backref_cache_entry *lim = mctx->bkref_ents + limit; + int boundaries; + + /* If we are outside the range of the subexpression, return -1 or 1. */ + if (str_idx < lim->subexp_from) + return -1; + + if (lim->subexp_to < str_idx) + return 1; + + /* If we are within the subexpression, return 0. */ + boundaries = (str_idx == lim->subexp_from); + boundaries |= (str_idx == lim->subexp_to) << 1; + if (boundaries == 0) + return 0; + + /* Else, examine epsilon closure. */ + return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, + from_node, bkref_idx); +} + +/* Check the limitations of sub expressions LIMITS, and remove the nodes + which are against limitations from DEST_NODES. */ + +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) +{ + reg_errcode_t err; + Idx node_idx, lim_idx; + + for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) + { + Idx subexp_idx; + struct re_backref_cache_entry *ent; + ent = bkref_ents + limits->elems[lim_idx]; + + if (str_idx <= ent->subexp_from || ent->str_idx < str_idx) + continue; /* This is unrelated limitation. */ + + subexp_idx = dfa->nodes[ent->node].opr.idx; + if (ent->subexp_to == str_idx) + { + 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]; + re_token_type_t type = dfa->nodes[node].type; + if (type == OP_OPEN_SUBEXP + && subexp_idx == dfa->nodes[node].opr.idx) + ops_node = node; + else if (type == OP_CLOSE_SUBEXP + && subexp_idx == dfa->nodes[node].opr.idx) + cls_node = node; + } + + /* Check the limitation of the open subexpression. */ + /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */ + if (ops_node >= 0) + { + err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, + candidates); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + + /* Check the limitation of the close subexpression. */ + if (cls_node >= 0) + for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) + { + Idx node = dest_nodes->elems[node_idx]; + if (!re_node_set_contains (dfa->inveclosures + node, + cls_node) + && !re_node_set_contains (dfa->eclosures + node, + cls_node)) + { + /* It is against this limitation. + Remove it form the current sifted state. */ + err = sub_epsilon_src_nodes (dfa, node, dest_nodes, + candidates); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + --node_idx; + } + } + } + else /* (ent->subexp_to != str_idx) */ + { + for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) + { + Idx node = dest_nodes->elems[node_idx]; + re_token_type_t type = dfa->nodes[node].type; + if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP) + { + if (subexp_idx != dfa->nodes[node].opr.idx) + continue; + /* It is against this limitation. + Remove it form the current sifted state. */ + err = sub_epsilon_src_nodes (dfa, node, dest_nodes, + candidates); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + } + } + } + return REG_NOERROR; +} + +static reg_errcode_t +__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) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx node_idx, node; + re_sift_context_t local_sctx; + Idx first_idx = search_cur_bkref_entry (mctx, str_idx); + + if (first_idx == -1) + return REG_NOERROR; + + local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */ + + for (node_idx = 0; node_idx < candidates->nelem; ++node_idx) + { + Idx enabled_idx; + re_token_type_t type; + struct re_backref_cache_entry *entry; + node = candidates->elems[node_idx]; + type = dfa->nodes[node].type; + /* Avoid infinite loop for the REs like "()\1+". */ + if (node == sctx->last_node && str_idx == sctx->last_str_idx) + continue; + if (type != OP_BACK_REF) + continue; + + entry = mctx->bkref_ents + first_idx; + enabled_idx = first_idx; + do + { + Idx subexp_len; + Idx to_idx; + Idx dst_node; + bool ok; + re_dfastate_t *cur_state; + + if (entry->node != node) + continue; + subexp_len = entry->subexp_to - entry->subexp_from; + to_idx = str_idx + subexp_len; + dst_node = (subexp_len ? dfa->nexts[node] + : dfa->edests[node].elems[0]); + + if (to_idx > sctx->last_str_idx + || sctx->sifted_states[to_idx] == NULL + || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node) + || check_dst_limits (mctx, &sctx->limits, node, + str_idx, dst_node, to_idx)) + continue; + + if (local_sctx.sifted_states == NULL) + { + local_sctx = *sctx; + err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits); + 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 (__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 (__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 (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + } + local_sctx.sifted_states[str_idx] = cur_state; + re_node_set_remove (&local_sctx.limits, enabled_idx); + + /* mctx->bkref_ents may have changed, reload the pointer. */ + entry = mctx->bkref_ents + enabled_idx; + } + while (enabled_idx++, entry++->more); + } + err = REG_NOERROR; + free_return: + if (local_sctx.sifted_states != NULL) + { + re_node_set_free (&local_sctx.limits); + } + + return err; +} + + +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) +{ + const re_dfa_t *const dfa = mctx->dfa; + 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])) + /* The node can't accept the "multi byte", or the + destination was already thrown away, then the node + couldn't accept the current input "multi byte". */ + naccepted = 0; + /* Otherwise, it is sure that the node could accept + 'naccepted' bytes input. */ + return naccepted; +} + +/* 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 * +__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; + + /* If the current state can accept multibyte. */ + if (__glibc_unlikely (state->accept_mb)) + { + *err = transit_state_mb (mctx, state); + if (__glibc_unlikely (*err != REG_NOERROR)) + return NULL; + } + + /* Then decide the next state with the single byte. */ +#if 0 + if (0) + /* don't use transition table */ + return transit_state_sb (err, mctx, state); +#endif + + /* Use transition table */ + ch = re_string_fetch_byte (&mctx->input); + for (;;) + { + trtable = state->trtable; + if (__glibc_likely (trtable != NULL)) + return trtable[ch]; + + trtable = state->word_trtable; + if (__glibc_likely (trtable != NULL)) + { + unsigned int context; + context + = re_string_context_at (&mctx->input, + re_string_cur_idx (&mctx->input) - 1, + mctx->eflags); + if (IS_WORD_CONTEXT (context)) + return trtable[ch + SBC_MAX]; + else + return trtable[ch]; + } + + if (!build_trtable (mctx->dfa, state)) + { + *err = REG_ESPACE; + return NULL; + } + + /* Retry, we now have a transition table. */ + } +} + +/* Update the state_log if we need */ +static re_dfastate_t * +merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, + re_dfastate_t *next_state) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx cur_idx = re_string_cur_idx (&mctx->input); + + if (cur_idx > mctx->state_log_top) + { + mctx->state_log[cur_idx] = next_state; + mctx->state_log_top = cur_idx; + } + else if (mctx->state_log[cur_idx] == 0) + { + mctx->state_log[cur_idx] = next_state; + } + else + { + re_dfastate_t *pstate; + unsigned int context; + re_node_set next_nodes, *log_nodes, *table_nodes = NULL; + /* If (state_log[cur_idx] != 0), it implies that cur_idx is + the destination of a multibyte char/collating element/ + back reference. Then the next state is the union set of + these destinations and the results of the transition table. */ + pstate = mctx->state_log[cur_idx]; + log_nodes = pstate->entrance_nodes; + if (next_state != NULL) + { + table_nodes = next_state->entrance_nodes; + *err = re_node_set_init_union (&next_nodes, table_nodes, + log_nodes); + if (__glibc_unlikely (*err != REG_NOERROR)) + return NULL; + } + else + next_nodes = *log_nodes; + /* Note: We already add the nodes of the initial state, + then we don't need to add them here. */ + + context = re_string_context_at (&mctx->input, + re_string_cur_idx (&mctx->input) - 1, + mctx->eflags); + next_state = mctx->state_log[cur_idx] + = re_acquire_state_context (err, dfa, &next_nodes, context); + /* We don't need to check errors here, since the return value of + this function is next_state and ERR is already set. */ + + if (table_nodes != NULL) + re_node_set_free (&next_nodes); + } + + 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 (__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 (__glibc_unlikely (*err != REG_NOERROR)) + return NULL; + next_state = mctx->state_log[cur_idx]; + } + } + + return next_state; +} + +/* Skip bytes in the input that correspond to part of a + multi-byte match, then look in the log for a state + from which to restart matching. */ +static re_dfastate_t * +find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) +{ + re_dfastate_t *cur_state; + do + { + Idx max = mctx->state_log_top; + Idx cur_str_idx = re_string_cur_idx (&mctx->input); + + do + { + if (++cur_str_idx > max) + return NULL; + re_string_skip_bytes (&mctx->input, 1); + } + while (mctx->state_log[cur_str_idx] == NULL); + + cur_state = merge_state_with_log (err, mctx, NULL); + } + while (*err == REG_NOERROR && cur_state == NULL); + return cur_state; +} + +/* Helper functions for transit_state. */ + +/* From the node set CUR_NODES, pick up the nodes whose types are + OP_OPEN_SUBEXP and which have corresponding back references in the regular + expression. And register them to use them later for evaluating the + corresponding back references. */ + +static reg_errcode_t +check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, + Idx str_idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx node_idx; + reg_errcode_t err; + + /* TODO: This isn't efficient. + Because there might be more than one nodes whose types are + OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all + nodes. + E.g. RE: (a){2} */ + for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx) + { + Idx node = cur_nodes->elems[node_idx]; + if (dfa->nodes[node].type == OP_OPEN_SUBEXP + && dfa->nodes[node].opr.idx < BITSET_WORD_BITS + && (dfa->used_bkref_map + & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) + { + err = match_ctx_add_subtop (mctx, node, str_idx); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + } + return REG_NOERROR; +} + +#if 0 +/* Return the next state to which the current state STATE will transit by + 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, + re_dfastate_t *state) +{ + const re_dfa_t *const dfa = mctx->dfa; + re_node_set next_nodes; + re_dfastate_t *next_state; + Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input); + unsigned int context; + + *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1); + if (__glibc_unlikely (*err != REG_NOERROR)) + return NULL; + for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt) + { + Idx cur_node = state->nodes.elems[node_cnt]; + if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx)) + { + *err = re_node_set_merge (&next_nodes, + dfa->eclosures + dfa->nexts[cur_node]); + if (__glibc_unlikely (*err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return NULL; + } + } + } + context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags); + next_state = re_acquire_state_context (err, dfa, &next_nodes, context); + /* We don't need to check errors here, since the return value of + this function is next_state and ERR is already set. */ + + re_node_set_free (&next_nodes); + re_string_skip_bytes (&mctx->input, 1); + return next_state; +} +#endif + +static reg_errcode_t +transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx i; + + for (i = 0; i < pstate->nodes.nelem; ++i) + { + re_node_set dest_nodes, *new_nodes; + Idx cur_node_idx = pstate->nodes.elems[i]; + int naccepted; + Idx dest_idx; + unsigned int context; + re_dfastate_t *dest_state; + + if (!dfa->nodes[cur_node_idx].accept_mb) + continue; + + if (dfa->nodes[cur_node_idx].constraint) + { + context = re_string_context_at (&mctx->input, + re_string_cur_idx (&mctx->input), + mctx->eflags); + if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint, + context)) + continue; + } + + /* How many bytes the node can accept? */ + naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input, + re_string_cur_idx (&mctx->input)); + if (naccepted == 0) + continue; + + /* The node can accepts 'naccepted' bytes. */ + dest_idx = re_string_cur_idx (&mctx->input) + naccepted; + 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + DEBUG_ASSERT (dfa->nexts[cur_node_idx] != -1); + new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx]; + + dest_state = mctx->state_log[dest_idx]; + if (dest_state == NULL) + dest_nodes = *new_nodes; + else + { + err = re_node_set_init_union (&dest_nodes, + dest_state->entrance_nodes, new_nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + context = re_string_context_at (&mctx->input, dest_idx - 1, + mctx->eflags); + mctx->state_log[dest_idx] + = re_acquire_state_context (&err, dfa, &dest_nodes, context); + if (dest_state != NULL) + re_node_set_free (&dest_nodes); + if (__glibc_unlikely (mctx->state_log[dest_idx] == NULL + && err != REG_NOERROR)) + return err; + } + return REG_NOERROR; +} + +static reg_errcode_t +transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx i; + Idx cur_str_idx = re_string_cur_idx (&mctx->input); + + for (i = 0; i < nodes->nelem; ++i) + { + Idx dest_str_idx, prev_nelem, bkc_idx; + Idx node_idx = nodes->elems[i]; + unsigned int context; + const re_token_t *node = dfa->nodes + node_idx; + re_node_set *new_dest_nodes; + + /* Check whether 'node' is a backreference or not. */ + if (node->type != OP_BACK_REF) + continue; + + if (node->constraint) + { + context = re_string_context_at (&mctx->input, cur_str_idx, + mctx->eflags); + if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) + continue; + } + + /* 'node' is a backreference. + Check the substring which the substring matched. */ + bkc_idx = mctx->nbkref_ents; + err = get_subexp (mctx, node_idx, cur_str_idx); + 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. */ + DEBUG_ASSERT (dfa->nexts[node_idx] != -1); + for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) + { + Idx subexp_len; + re_dfastate_t *dest_state; + struct re_backref_cache_entry *bkref_ent; + bkref_ent = mctx->bkref_ents + bkc_idx; + if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx) + continue; + subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from; + new_dest_nodes = (subexp_len == 0 + ? dfa->eclosures + dfa->edests[node_idx].elems[0] + : dfa->eclosures + dfa->nexts[node_idx]); + dest_str_idx = (cur_str_idx + bkref_ent->subexp_to + - bkref_ent->subexp_from); + context = re_string_context_at (&mctx->input, dest_str_idx - 1, + mctx->eflags); + dest_state = mctx->state_log[dest_str_idx]; + prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0 + : mctx->state_log[cur_str_idx]->nodes.nelem); + /* Add 'new_dest_node' to state_log. */ + if (dest_state == NULL) + { + mctx->state_log[dest_str_idx] + = re_acquire_state_context (&err, dfa, new_dest_nodes, + context); + if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR)) + goto free_return; + } + else + { + re_node_set dest_nodes; + err = re_node_set_init_union (&dest_nodes, + dest_state->entrance_nodes, + new_dest_nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&dest_nodes); + goto free_return; + } + mctx->state_log[dest_str_idx] + = re_acquire_state_context (&err, dfa, &dest_nodes, context); + re_node_set_free (&dest_nodes); + 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 + transit. */ + if (subexp_len == 0 + && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem) + { + err = check_subexp_matching_top (mctx, new_dest_nodes, + cur_str_idx); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + err = transit_state_bkref (mctx, new_dest_nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + goto free_return; + } + } + } + err = REG_NOERROR; + free_return: + return err; +} + +/* Enumerate all the candidates which the backreference BKREF_NODE can match + at BKREF_STR_IDX, and register them by match_ctx_add_entry(). + Note that we might collect inappropriate candidates here. + However, the cost of checking them strictly here is too high, then we + delay these checking for prune_impossible_nodes(). */ + +static reg_errcode_t +__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; + Idx subexp_num, sub_top_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 != -1) + { + const struct re_backref_cache_entry *entry + = mctx->bkref_ents + cache_idx; + do + if (entry->node == bkref_node) + return REG_NOERROR; /* We already checked it. */ + while (entry++->more); + } + + subexp_num = dfa->nodes[bkref_node].opr.idx; + + /* For each sub expression */ + for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx) + { + reg_errcode_t err; + re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx]; + re_sub_match_last_t *sub_last; + Idx sub_last_idx, sl_str, bkref_str_off; + + if (dfa->nodes[sub_top->node].opr.idx != subexp_num) + continue; /* It isn't related. */ + + sl_str = sub_top->str_idx; + bkref_str_off = bkref_str_idx; + /* At first, check the last node of sub expressions we already + evaluated. */ + for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx) + { + regoff_t sl_str_diff; + sub_last = sub_top->lasts[sub_last_idx]; + sl_str_diff = sub_last->str_idx - sl_str; + /* The matched string by the sub expression match with the substring + at the back reference? */ + if (sl_str_diff > 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) + break; + + err = clean_state_log_if_needed (mctx, + bkref_str_off + + sl_str_diff); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + buf = (const char *) re_string_get_buffer (&mctx->input); + } + if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0) + /* We don't need to search this sub expression any more. */ + break; + } + bkref_str_off += sl_str_diff; + sl_str += sl_str_diff; + err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, + bkref_str_idx); + + /* Reload buf, since the preceding call might have reallocated + the buffer. */ + buf = (const char *) re_string_get_buffer (&mctx->input); + + if (err == REG_NOMATCH) + continue; + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + + if (sub_last_idx < sub_top->nlasts) + continue; + if (sub_last_idx > 0) + ++sl_str; + /* Then, search for the other last nodes of the sub expression. */ + for (; sl_str <= bkref_str_idx; ++sl_str) + { + Idx cls_node; + regoff_t sl_str_off; + const re_node_set *nodes; + sl_str_off = sl_str - sub_top->str_idx; + /* The matched string by the sub expression match with the substring + at the back reference? */ + if (sl_str_off > 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 (__glibc_unlikely (err != REG_NOERROR)) + return err; + + buf = (const char *) re_string_get_buffer (&mctx->input); + } + if (buf [bkref_str_off++] != buf[sl_str - 1]) + break; /* We don't need to search this sub expression + any more. */ + } + if (mctx->state_log[sl_str] == NULL) + continue; + /* Does this state have a ')' of the sub expression? */ + nodes = &mctx->state_log[sl_str]->nodes; + cls_node = find_subexp_node (dfa, nodes, subexp_num, + OP_CLOSE_SUBEXP); + if (cls_node == -1) + continue; /* No. */ + if (sub_top->path == NULL) + { + sub_top->path = calloc (sizeof (state_array_t), + sl_str - sub_top->str_idx + 1); + if (sub_top->path == NULL) + return REG_ESPACE; + } + /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node + in the current context? */ + err = check_arrival (mctx, sub_top->path, sub_top->node, + sub_top->str_idx, cls_node, sl_str, + OP_CLOSE_SUBEXP); + if (err == REG_NOMATCH) + continue; + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); + 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; +} + +/* Helper functions for get_subexp(). */ + +/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR. + If it can arrive, register the sub expression expressed with SUB_TOP + and SUB_LAST. */ + +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) +{ + reg_errcode_t err; + Idx to_idx; + /* Can the subexpression arrive the back reference? */ + err = check_arrival (mctx, &sub_last->path, sub_last->node, + sub_last->str_idx, bkref_node, bkref_str, + OP_OPEN_SUBEXP); + if (err != REG_NOERROR) + return err; + err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx, + sub_last->str_idx); + 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); +} + +/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX. + Search '(' if FL_OPEN, or search ')' otherwise. + TODO: This function isn't efficient... + Because there might be more than one nodes whose types are + OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all + nodes. + E.g. RE: (a){2} */ + +static Idx +find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + Idx subexp_idx, int type) +{ + Idx cls_idx; + for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx) + { + Idx cls_node = nodes->elems[cls_idx]; + const re_token_t *node = dfa->nodes + cls_node; + if (node->type == type + && node->opr.idx == subexp_idx) + return cls_node; + } + 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, REG_NOMATCH if it cannot, + REG_ESPACE if memory is exhausted. */ + +static reg_errcode_t +__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) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err = REG_NOERROR; + Idx subexp_num, backup_cur_idx, str_idx, null_cnt; + re_dfastate_t *cur_state = NULL; + re_node_set *cur_nodes, next_nodes; + re_dfastate_t **backup_state_log; + unsigned int context; + + subexp_num = dfa->nodes[top_node].opr.idx; + /* Extend the buffer if we need. */ + 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 (__glibc_unlikely (IDX_MAX - old_alloc < incr_alloc)) + return REG_ESPACE; + new_alloc = old_alloc + incr_alloc; + 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 (__glibc_unlikely (new_array == NULL)) + return REG_ESPACE; + path->array = new_array; + path->alloc = new_alloc; + memset (new_array + old_alloc, '\0', + sizeof (re_dfastate_t *) * (path->alloc - old_alloc)); + } + + str_idx = path->next_idx ? path->next_idx : top_str; + + /* Temporary modify MCTX. */ + backup_state_log = mctx->state_log; + backup_cur_idx = mctx->input.cur_idx; + mctx->state_log = path->array; + mctx->input.cur_idx = str_idx; + + /* Setup initial node set. */ + context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); + if (str_idx == top_str) + { + err = re_node_set_init_1 (&next_nodes, top_node); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return err; + } + } + else + { + cur_state = mctx->state_log[str_idx]; + if (cur_state && cur_state->has_backref) + { + err = re_node_set_init_copy (&next_nodes, &cur_state->nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + else + re_node_set_init_empty (&next_nodes); + } + if (str_idx == top_str || (cur_state && cur_state->has_backref)) + { + if (next_nodes.nelem) + { + err = expand_bkref_cache (mctx, &next_nodes, str_idx, + subexp_num, type); + 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 (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return err; + } + mctx->state_log[str_idx] = cur_state; + } + + for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) + { + re_node_set_empty (&next_nodes); + if (mctx->state_log[str_idx + 1]) + { + err = re_node_set_merge (&next_nodes, + &mctx->state_log[str_idx + 1]->nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return err; + } + } + if (cur_state) + { + err = check_arrival_add_next_nodes (mctx, str_idx, + &cur_state->non_eps_nodes, + &next_nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return err; + } + } + ++str_idx; + if (next_nodes.nelem) + { + err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); + 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 (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return err; + } + } + context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); + cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); + if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR)) + { + re_node_set_free (&next_nodes); + return err; + } + mctx->state_log[str_idx] = cur_state; + null_cnt = cur_state == NULL ? null_cnt + 1 : 0; + } + re_node_set_free (&next_nodes); + cur_nodes = (mctx->state_log[last_str] == NULL ? NULL + : &mctx->state_log[last_str]->nodes); + path->next_idx = str_idx; + + /* Fix MCTX. */ + mctx->state_log = backup_state_log; + mctx->input.cur_idx = backup_cur_idx; + + /* Then check the current node set has the node LAST_NODE. */ + if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node)) + return REG_NOERROR; + + return REG_NOMATCH; +} + +/* Helper functions for check_arrival. */ + +/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them + to NEXT_NODES. + TODO: This function is similar to the functions transit_state*(), + however this function has many additional works. + Can't we unify them? */ + +static reg_errcode_t +__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; + reg_errcode_t err = REG_NOERROR; + 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]; + DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[cur_node].type)); + + /* If the node may accept "multi byte". */ + if (dfa->nodes[cur_node].accept_mb) + { + naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input, + str_idx); + if (naccepted > 1) + { + re_dfastate_t *dest_state; + Idx next_node = dfa->nexts[cur_node]; + Idx next_idx = str_idx + naccepted; + dest_state = mctx->state_log[next_idx]; + re_node_set_empty (&union_set); + if (dest_state) + { + err = re_node_set_merge (&union_set, &dest_state->nodes); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&union_set); + return err; + } + } + ok = re_node_set_insert (&union_set, next_node); + 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 (__glibc_unlikely (mctx->state_log[next_idx] == NULL + && err != REG_NOERROR)) + { + re_node_set_free (&union_set); + return err; + } + } + } + + if (naccepted + || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) + { + ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); + if (__glibc_unlikely (! ok)) + { + re_node_set_free (&union_set); + return REG_ESPACE; + } + } + } + re_node_set_free (&union_set); + return REG_NOERROR; +} + +/* For all the nodes in CUR_NODES, add the epsilon closures of them to + CUR_NODES, however exclude the nodes which are: + - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN. + - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN. +*/ + +static reg_errcode_t +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; + DEBUG_ASSERT (cur_nodes->nelem); + err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); + 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. */ + + for (idx = 0; idx < cur_nodes->nelem; ++idx) + { + 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 == -1) + { + /* There are no problematic nodes, just merge them. */ + err = re_node_set_merge (&new_nodes, eclosure); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&new_nodes); + return err; + } + } + else + { + /* There are problematic nodes, re-calculate incrementally. */ + err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node, + ex_subexp, type); + if (__glibc_unlikely (err != REG_NOERROR)) + { + re_node_set_free (&new_nodes); + return err; + } + } + } + re_node_set_free (cur_nodes); + *cur_nodes = new_nodes; + return REG_NOERROR; +} + +/* Helper function for check_arrival_expand_ecl. + Check incrementally the epsilon closure of TARGET, and if it isn't + problematic append it to DST_NODES. */ + +static reg_errcode_t +__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) +{ + Idx cur_node; + for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);) + { + bool ok; + + if (dfa->nodes[cur_node].type == type + && dfa->nodes[cur_node].opr.idx == ex_subexp) + { + if (type == OP_CLOSE_SUBEXP) + { + ok = re_node_set_insert (dst_nodes, cur_node); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + } + break; + } + ok = re_node_set_insert (dst_nodes, cur_node); + if (__glibc_unlikely (! ok)) + return REG_ESPACE; + if (dfa->edests[cur_node].nelem == 0) + break; + if (dfa->edests[cur_node].nelem == 2) + { + reg_errcode_t err; + err = check_arrival_expand_ecl_sub (dfa, dst_nodes, + dfa->edests[cur_node].elems[1], + ex_subexp, type); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + } + cur_node = dfa->edests[cur_node].elems[0]; + } + return REG_NOERROR; +} + + +/* For all the back references in the current state, calculate the + destination of the back references by the appropriate entry + in MCTX->BKREF_ENTS. */ + +static reg_errcode_t +__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) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str); + struct re_backref_cache_entry *ent; + + if (cache_idx_start == -1) + return REG_NOERROR; + + restart: + ent = mctx->bkref_ents + cache_idx_start; + do + { + Idx to_idx, next_node; + + /* Is this entry ENT is appropriate? */ + if (!re_node_set_contains (cur_nodes, ent->node)) + continue; /* No. */ + + to_idx = cur_str + ent->subexp_to - ent->subexp_from; + /* Calculate the destination of the back reference, and append it + to MCTX->STATE_LOG. */ + if (to_idx == cur_str) + { + /* The backreference did epsilon transit, we must re-check all the + node in the current state. */ + re_node_set new_dests; + reg_errcode_t err2, err3; + next_node = dfa->edests[ent->node].elems[0]; + if (re_node_set_contains (cur_nodes, next_node)) + continue; + err = re_node_set_init_1 (&new_dests, next_node); + 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 (__glibc_unlikely (err != REG_NOERROR || err2 != REG_NOERROR + || err3 != REG_NOERROR)) + { + err = (err != REG_NOERROR ? err + : (err2 != REG_NOERROR ? err2 : err3)); + return err; + } + /* TODO: It is still inefficient... */ + goto restart; + } + else + { + re_node_set union_set; + next_node = dfa->nexts[ent->node]; + if (mctx->state_log[to_idx]) + { + bool ok; + if (re_node_set_contains (&mctx->state_log[to_idx]->nodes, + next_node)) + continue; + err = re_node_set_init_copy (&union_set, + &mctx->state_log[to_idx]->nodes); + ok = re_node_set_insert (&union_set, next_node); + if (__glibc_unlikely (err != REG_NOERROR || ! ok)) + { + re_node_set_free (&union_set); + err = err != REG_NOERROR ? err : REG_ESPACE; + return err; + } + } + else + { + err = re_node_set_init_1 (&union_set, next_node); + 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 (__glibc_unlikely (mctx->state_log[to_idx] == NULL + && err != REG_NOERROR)) + return err; + } + } + while (ent++->more); + return REG_NOERROR; +} + +/* Build transition table for the state. + Return true if successful. */ + +static bool __attribute_noinline__ +build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) +{ + reg_errcode_t err; + Idx i, j; + int ch; + bool need_word_trtable = false; + bitset_word_t elem, mask; + Idx ndests; /* Number of the destination states from 'state'. */ + re_dfastate_t **trtable; + 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; + + /* 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. */ + re_node_set dests_node[SBC_MAX]; + bitset_t dests_ch[SBC_MAX]; + + /* Initialize transition table. */ + state->word_trtable = state->trtable = NULL; + + /* At first, group all nodes belonging to 'state' into several + destinations. */ + ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); + if (__glibc_unlikely (ndests <= 0)) + { + /* 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 (__glibc_unlikely (state->trtable == NULL)) + return false; + return true; + } + return false; + } + + err = re_node_set_alloc (&follows, ndests + 1); + if (__glibc_unlikely (err != REG_NOERROR)) + { + out_free: + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + return false; + } + + bitset_empty (acceptable); + + /* Then build the states for all destinations. */ + for (i = 0; i < ndests; ++i) + { + Idx next_node; + re_node_set_empty (&follows); + /* Merge the follows of this destination states. */ + for (j = 0; j < dests_node[i].nelem; ++j) + { + next_node = dfa->nexts[dests_node[i].elems[j]]; + if (next_node != -1) + { + err = re_node_set_merge (&follows, dfa->eclosures + next_node); + if (__glibc_unlikely (err != REG_NOERROR)) + goto out_free; + } + } + dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 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. */ + if (dest_states[i]->has_constraint) + { + dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, + CONTEXT_WORD); + 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) + need_word_trtable = true; + + dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, + CONTEXT_NEWLINE); + if (__glibc_unlikely (dest_states_nl[i] == NULL && err != REG_NOERROR)) + goto out_free; + } + else + { + dest_states_word[i] = dest_states[i]; + dest_states_nl[i] = dest_states[i]; + } + bitset_merge (acceptable, dests_ch[i]); + } + + 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 + discern by looking at the character code: allocate a + 256-entry transition table. */ + trtable = state->trtable = + (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); + if (__glibc_unlikely (trtable == NULL)) + goto out_free; + + /* For all characters ch...: */ + for (i = 0; i < BITSET_WORDS; ++i) + for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; + elem; + mask <<= 1, elem >>= 1, ++ch) + if (__glibc_unlikely (elem & 1)) + { + /* There must be exactly one destination which accepts + character ch. See group_nodes_into_DFAstates. */ + for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) + ; + + /* j-th destination accepts the word character ch. */ + if (dfa->word_char[i] & mask) + trtable[ch] = dest_states_word[j]; + else + trtable[ch] = dest_states[j]; + } + } + else + { + /* We care about whether the following character is a word + character, and we are in a multi-byte character set: discern + by looking at the character code: build two 256-entry + transition tables, one starting at trtable[0] and one + starting at trtable[SBC_MAX]. */ + trtable = state->word_trtable = + (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); + if (__glibc_unlikely (trtable == NULL)) + goto out_free; + + /* For all characters ch...: */ + for (i = 0; i < BITSET_WORDS; ++i) + for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; + elem; + mask <<= 1, elem >>= 1, ++ch) + if (__glibc_unlikely (elem & 1)) + { + /* There must be exactly one destination which accepts + character ch. See group_nodes_into_DFAstates. */ + for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) + ; + + /* j-th destination accepts the word character ch. */ + trtable[ch] = dest_states[j]; + trtable[ch + SBC_MAX] = dest_states_word[j]; + } + } + + /* new line */ + if (bitset_contain (acceptable, NEWLINE_CHAR)) + { + /* The current state accepts newline character. */ + for (j = 0; j < ndests; ++j) + if (bitset_contain (dests_ch[j], NEWLINE_CHAR)) + { + /* k-th destination accepts newline character. */ + trtable[NEWLINE_CHAR] = dest_states_nl[j]; + if (need_word_trtable) + trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j]; + /* There must be only one destination which accepts + newline. See group_nodes_into_DFAstates. */ + break; + } + } + + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + 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]. Return the number of destinations if successful, + -1 on internal error. */ + +static Idx +group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + re_node_set *dests_node, bitset_t *dests_ch) +{ + reg_errcode_t err; + bool ok; + Idx i, j, k; + Idx ndests; /* Number of the destinations from 'state'. */ + bitset_t accepts; /* Characters a node can accept. */ + const re_node_set *cur_nodes = &state->nodes; + bitset_empty (accepts); + ndests = 0; + + /* For all the nodes belonging to 'state', */ + for (i = 0; i < cur_nodes->nelem; ++i) + { + re_token_t *node = &dfa->nodes[cur_nodes->elems[i]]; + re_token_type_t type = node->type; + unsigned int constraint = node->constraint; + + /* Enumerate all single byte character this node can accept. */ + if (type == CHARACTER) + bitset_set (accepts, node->opr.c); + else if (type == SIMPLE_BRACKET) + { + bitset_merge (accepts, node->opr.sbcset); + } + else if (type == OP_PERIOD) + { + if (dfa->mb_cur_max > 1) + bitset_merge (accepts, dfa->sb_char); + else + 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'); + } + else if (type == OP_UTF8_PERIOD) + { + if (ASCII_CHARS % BITSET_WORD_BITS == 0) + memset (accepts, -1, ASCII_CHARS / CHAR_BIT); + else + bitset_merge (accepts, utf8_sb_map); + if (!(dfa->syntax & RE_DOT_NEWLINE)) + bitset_clear (accepts, '\n'); + if (dfa->syntax & RE_DOT_NOT_NULL) + bitset_clear (accepts, '\0'); + } + else + continue; + + /* Check the 'accepts' and sift the characters which are not + match it the context. */ + if (constraint) + { + if (constraint & NEXT_NEWLINE_CONSTRAINT) + { + bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR); + bitset_empty (accepts); + if (accepts_newline) + bitset_set (accepts, NEWLINE_CHAR); + else + continue; + } + if (constraint & NEXT_ENDBUF_CONSTRAINT) + { + bitset_empty (accepts); + continue; + } + + if (constraint & NEXT_WORD_CONSTRAINT) + { + bitset_word_t any_set = 0; + if (type == CHARACTER && !node->word_char) + { + bitset_empty (accepts); + continue; + } + 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 + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= dfa->word_char[j]); + if (!any_set) + continue; + } + if (constraint & NEXT_NOTWORD_CONSTRAINT) + { + bitset_word_t any_set = 0; + if (type == CHARACTER && node->word_char) + { + bitset_empty (accepts); + continue; + } + 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 + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= ~dfa->word_char[j]); + if (!any_set) + continue; + } + } + + /* Then divide 'accepts' into DFA states, or create a new + state. Above, we make sure that accepts is not empty. */ + for (j = 0; j < ndests; ++j) + { + bitset_t intersec; /* Intersection sets, see below. */ + bitset_t remains; + /* Flags, see below. */ + bitset_word_t has_intersec, not_subset, not_consumed; + + /* Optimization, skip if this state doesn't accept the character. */ + if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c)) + continue; + + /* Enumerate the intersection set of this state and 'accepts'. */ + has_intersec = 0; + for (k = 0; k < BITSET_WORDS; ++k) + has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k]; + /* And skip if the intersection set is empty. */ + if (!has_intersec) + continue; + + /* Then check if this state is a subset of 'accepts'. */ + not_subset = not_consumed = 0; + for (k = 0; k < BITSET_WORDS; ++k) + { + not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k]; + not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k]; + } + + /* If this state isn't a subset of 'accepts', create a + new group state, which has the 'remains'. */ + if (not_subset) + { + 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 (__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 (__glibc_unlikely (! ok)) + goto error_return; + + /* If all characters are consumed, go to next node. */ + if (!not_consumed) + break; + } + /* Some characters remain, create a new group. */ + if (j == ndests) + { + bitset_copy (dests_ch[ndests], accepts); + err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]); + 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 -1; +} + +/* 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. + + This function handles the nodes which can accept one character, or + one collating element like '.', '[a-z]', opposite to the other nodes + can only accept one byte. */ + +#ifdef _LIBC +# include +#endif + +static int +check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + const re_string_t *input, Idx str_idx) +{ + const re_token_t *node = dfa->nodes + node_idx; + int char_len, elem_len; + Idx i; + + if (__glibc_unlikely (node->type == OP_UTF8_PERIOD)) + { + unsigned char c = re_string_byte_at (input, str_idx), d; + if (__glibc_likely (c < 0xc2)) + return 0; + + if (str_idx + 2 > input->len) + return 0; + + d = re_string_byte_at (input, str_idx + 1); + if (c < 0xe0) + return (d < 0x80 || d > 0xbf) ? 0 : 2; + else if (c < 0xf0) + { + char_len = 3; + if (c == 0xe0 && d < 0xa0) + return 0; + } + else if (c < 0xf8) + { + char_len = 4; + if (c == 0xf0 && d < 0x90) + return 0; + } + else if (c < 0xfc) + { + char_len = 5; + if (c == 0xf8 && d < 0x88) + return 0; + } + else if (c < 0xfe) + { + char_len = 6; + if (c == 0xfc && d < 0x84) + return 0; + } + else + return 0; + + if (str_idx + char_len > input->len) + return 0; + + for (i = 1; i < char_len; ++i) + { + d = re_string_byte_at (input, str_idx + i); + if (d < 0x80 || d > 0xbf) + return 0; + } + return char_len; + } + + char_len = re_string_char_size_at (input, str_idx); + if (node->type == OP_PERIOD) + { + if (char_len <= 1) + return 0; + /* 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')) + return 0; + return char_len; + } + + elem_len = re_string_elem_size_at (input, str_idx); + if ((elem_len <= 1 && char_len <= 1) || char_len == 0) + return 0; + + if (node->type == COMPLEX_BRACKET) + { + const re_charset_t *cset = node->opr.mbcset; +#ifdef _LIBC + const unsigned char *pin + = ((const unsigned char *) re_string_get_buffer (input) + str_idx); + Idx j; + uint32_t nrules; +#endif + int match_len = 0; + wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) + ? re_string_wchar_at (input, str_idx) : 0); + + /* match with multibyte character? */ + for (i = 0; i < cset->nmbchars; ++i) + if (wc == cset->mbchars[i]) + { + match_len = char_len; + goto check_node_accept_bytes_match; + } + /* match with character_class? */ + for (i = 0; i < cset->nchar_classes; ++i) + { + wctype_t wt = cset->char_classes[i]; + if (__iswctype (wc, wt)) + { + match_len = char_len; + goto check_node_accept_bytes_match; + } + } + +#ifdef _LIBC + nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules != 0) + { + unsigned int in_collseq = 0; + const int32_t *table, *indirect; + const unsigned char *weights, *extra; + const char *collseqwc; + + /* match with collating_symbol? */ + if (cset->ncoll_syms) + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); + for (i = 0; i < cset->ncoll_syms; ++i) + { + const unsigned char *coll_sym = extra + cset->coll_syms[i]; + /* Compare the length of input collating element and + the length of current collating element. */ + if (*coll_sym != elem_len) + continue; + /* Compare each bytes. */ + for (j = 0; j < *coll_sym; j++) + if (pin[j] != coll_sym[1 + j]) + break; + if (j == *coll_sym) + { + /* Match if every bytes is equal. */ + match_len = j; + goto check_node_accept_bytes_match; + } + } + + if (cset->nranges) + { + if (elem_len <= char_len) + { + collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); + in_collseq = __collseq_table_lookup (collseqwc, wc); + } + else + in_collseq = find_collation_sequence_value (pin, elem_len); + } + /* match with range expression? */ + /* FIXME: Implement rational ranges here, too. */ + for (i = 0; i < cset->nranges; ++i) + if (cset->range_starts[i] <= in_collseq + && in_collseq <= cset->range_ends[i]) + { + match_len = elem_len; + goto check_node_accept_bytes_match; + } + + /* match with equivalence_class? */ + if (cset->nequiv_classes) + { + const unsigned char *cp = pin; + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); + int32_t idx = findidx (table, indirect, extra, &cp, elem_len); + int32_t rule = idx >> 24; + idx &= 0xffffff; + if (idx > 0) + { + 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 */ + { + /* match with range expression? */ + for (i = 0; i < cset->nranges; ++i) + { + if (cset->range_starts[i] <= wc && wc <= cset->range_ends[i]) + { + match_len = char_len; + goto check_node_accept_bytes_match; + } + } + } + check_node_accept_bytes_match: + if (!cset->non_match) + return match_len; + else + { + if (match_len > 0) + return 0; + else + return (elem_len > char_len) ? elem_len : char_len; + } + } + return 0; +} + +#ifdef _LIBC +static unsigned int +find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) +{ + uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules == 0) + { + if (mbs_len == 1) + { + /* No valid character. Match it as a single byte character. */ + const unsigned char *collseq = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); + return collseq[mbs[0]]; + } + return UINT_MAX; + } + else + { + int32_t idx; + const unsigned char *extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); + int32_t extrasize = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra; + + for (idx = 0; idx < extrasize;) + { + int mbs_cnt; + bool found = false; + int32_t elem_mbs_len; + /* Skip the name of collating element name. */ + idx = idx + extra[idx] + 1; + elem_mbs_len = extra[idx++]; + if (mbs_len == elem_mbs_len) + { + for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt) + if (extra[idx + mbs_cnt] != mbs[mbs_cnt]) + break; + if (mbs_cnt == elem_mbs_len) + /* Found the entry. */ + found = true; + } + /* Skip the byte sequence of the collating element. */ + idx += elem_mbs_len; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + /* Skip the collation sequence value. */ + idx += sizeof (uint32_t); + /* Skip the wide char sequence of the collating element. */ + idx = idx + sizeof (uint32_t) * (*(int32_t *) (extra + idx) + 1); + /* If we found the entry, return the sequence value. */ + if (found) + return *(uint32_t *) (extra + idx); + /* Skip the collation sequence value. */ + idx += sizeof (uint32_t); + } + return UINT_MAX; + } +} +#endif /* _LIBC */ + +/* Check whether the node accepts the byte which is IDX-th + byte of the INPUT. */ + +static bool +check_node_accept (const re_match_context_t *mctx, const re_token_t *node, + Idx idx) +{ + unsigned char ch; + ch = re_string_byte_at (&mctx->input, idx); + switch (node->type) + { + case CHARACTER: + if (node->opr.c != ch) + return false; + break; + + case SIMPLE_BRACKET: + if (!bitset_contain (node->opr.sbcset, ch)) + return false; + break; + + case OP_UTF8_PERIOD: + if (ch >= ASCII_CHARS) + return false; + FALLTHROUGH; + case OP_PERIOD: + if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE)) + || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL))) + return false; + break; + + default: + return false; + } + + if (node->constraint) + { + /* The node has constraints. Check whether the current context + satisfies the constraints. */ + unsigned int context = re_string_context_at (&mctx->input, idx, + mctx->eflags); + if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) + return false; + } + + return true; +} + +/* Extend the buffers, if the buffers have run out. */ + +static reg_errcode_t +__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 (__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 (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + + if (mctx->state_log != NULL) + { + /* And double the length of state_log. */ + /* XXX We have no indication of the size of this buffer. If this + allocation fail we have no indication that the state_log array + does not have the right size. */ + re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *, + pstr->bufs_len + 1); + if (__glibc_unlikely (new_array == NULL)) + return REG_ESPACE; + mctx->state_log = new_array; + } + + /* Then reconstruct the buffers. */ + if (pstr->icase) + { + if (pstr->mb_cur_max > 1) + { + ret = build_wcs_upper_buffer (pstr); + if (__glibc_unlikely (ret != REG_NOERROR)) + return ret; + } + else + build_upper_buffer (pstr); + } + else + { + if (pstr->mb_cur_max > 1) + build_wcs_buffer (pstr); + else + { + if (pstr->trans != NULL) + re_string_translate_buffer (pstr); + } + } + return REG_NOERROR; +} + + +/* Functions for matching context. */ + +/* Initialize MCTX. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) +{ + mctx->eflags = eflags; + 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 (__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 (__glibc_unlikely (mctx->bkref_ents == NULL || mctx->sub_tops == NULL)) + return REG_ESPACE; + } + /* Already zero-ed by the caller. + else + mctx->bkref_ents = NULL; + mctx->nbkref_ents = 0; + mctx->nsub_tops = 0; */ + mctx->abkref_ents = n; + mctx->max_mb_elem_len = 1; + mctx->asub_tops = n; + return REG_NOERROR; +} + +/* Clean the entries which depend on the current input in MCTX. + This function must be invoked when the matcher changes the start index + of the input, or changes the input string. */ + +static void +match_ctx_clean (re_match_context_t *mctx) +{ + Idx st_idx; + for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx) + { + Idx sl_idx; + re_sub_match_top_t *top = mctx->sub_tops[st_idx]; + for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx) + { + re_sub_match_last_t *last = top->lasts[sl_idx]; + re_free (last->path.array); + re_free (last); + } + re_free (top->lasts); + if (top->path) + { + re_free (top->path->array); + re_free (top->path); + } + re_free (top); + } + + mctx->nsub_tops = 0; + mctx->nbkref_ents = 0; +} + +/* Free all the memory associated with MCTX. */ + +static void +match_ctx_free (re_match_context_t *mctx) +{ + /* First, free all the memory associated with MCTX->SUB_TOPS. */ + match_ctx_clean (mctx); + re_free (mctx->sub_tops); + re_free (mctx->bkref_ents); +} + +/* Add a new backreference entry to MCTX. + Note that we assume that caller never call this function with duplicate + entry, and call with STR_IDX which isn't smaller than any existing entry. +*/ + +static reg_errcode_t +__attribute_warn_unused_result__ +match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, + Idx to) +{ + if (mctx->nbkref_ents >= mctx->abkref_ents) + { + struct re_backref_cache_entry* new_entry; + new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry, + mctx->abkref_ents * 2); + if (__glibc_unlikely (new_entry == NULL)) + { + re_free (mctx->bkref_ents); + return REG_ESPACE; + } + mctx->bkref_ents = new_entry; + memset (mctx->bkref_ents + mctx->nbkref_ents, '\0', + sizeof (struct re_backref_cache_entry) * mctx->abkref_ents); + mctx->abkref_ents *= 2; + } + if (mctx->nbkref_ents > 0 + && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx) + mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1; + + mctx->bkref_ents[mctx->nbkref_ents].node = node; + mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx; + mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from; + mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to; + + /* This is a cache that saves negative results of check_dst_limits_calc_pos. + If bit N is clear, means that this entry won't epsilon-transition to + an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If + it is set, check_dst_limits_calc_pos_1 will recurse and try to find one + such node. + + A backreference does not epsilon-transition unless it is empty, so set + to all zeros if FROM != TO. */ + mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map + = (from == to ? -1 : 0); + + mctx->bkref_ents[mctx->nbkref_ents++].more = 0; + if (mctx->max_mb_elem_len < to - from) + mctx->max_mb_elem_len = to - from; + return REG_NOERROR; +} + +/* 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 +search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) +{ + Idx left, right, mid, last; + last = right = mctx->nbkref_ents; + for (left = 0; left < right;) + { + mid = (left + right) / 2; + if (mctx->bkref_ents[mid].str_idx < str_idx) + left = mid + 1; + else + right = mid; + } + if (left < last && mctx->bkref_ents[left].str_idx == str_idx) + return left; + else + return -1; +} + +/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches + at STR_IDX. */ + +static reg_errcode_t +__attribute_warn_unused_result__ +match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) +{ + 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 (__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 (__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; + return REG_NOERROR; +} + +/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches + 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 * +match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) +{ + re_sub_match_last_t *new_entry; + 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 (__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 (__glibc_likely (new_entry != NULL)) + { + subtop->lasts[subtop->nlasts] = new_entry; + new_entry->node = node; + new_entry->str_idx = str_idx; + ++subtop->nlasts; + } + return new_entry; +} + +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) +{ + sctx->sifted_states = sifted_sts; + sctx->limited_states = limited_sts; + sctx->last_node = last_node; + sctx->last_str_idx = last_str_idx; + re_node_set_init_empty (&sctx->limits); +} diff --git a/lib/rename.c b/lib/rename.c new file mode 100644 index 0000000..119abe5 --- /dev/null +++ b/lib/rename.c @@ -0,0 +1,477 @@ +/* Work around rename bugs in some systems. + + Copyright (C) 2001-2003, 2005-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 Volker Borchert, Eric Blake. */ + +#include + +#include + +#undef rename + +#if defined _WIN32 && ! defined __CYGWIN__ +/* The mingw rename has problems with trailing slashes; it also + requires use of native Windows calls to allow atomic renames over + existing files. */ + +# include +# include +# include +# include +# include + +# define WIN32_LEAN_AND_MEAN +# include + +# include "dirname.h" + +/* Don't assume that UNICODE is not defined. */ +# undef MoveFileEx +# define MoveFileEx MoveFileExA + +/* Rename the file SRC to DST. This replacement is necessary on + Windows, on which the system rename function will not replace + an existing DST. */ +int +rpl_rename (char const *src, char const *dst) +{ + int error; + size_t src_len = strlen (src); + size_t dst_len = strlen (dst); + char *src_base = last_component (src); + char *dst_base = last_component (dst); + bool src_slash; + bool dst_slash; + bool dst_exists; + struct stat src_st; + struct stat dst_st; + + /* Filter out dot as last component. */ + if (!src_len || !dst_len) + { + errno = ENOENT; + return -1; + } + if (*src_base == '.') + { + size_t len = base_len (src_base); + if (len == 1 || (len == 2 && src_base[1] == '.')) + { + errno = EINVAL; + return -1; + } + } + if (*dst_base == '.') + { + size_t len = base_len (dst_base); + if (len == 1 || (len == 2 && dst_base[1] == '.')) + { + errno = EINVAL; + return -1; + } + } + + /* Presence of a trailing slash requires directory semantics. If + the source does not exist, or if the destination cannot be turned + into a directory, give up now. Otherwise, strip trailing slashes + before calling rename. There are no symlinks on mingw, so stat + works instead of lstat. */ + src_slash = ISSLASH (src[src_len - 1]); + dst_slash = ISSLASH (dst[dst_len - 1]); + if (stat (src, &src_st)) + return -1; + if (stat (dst, &dst_st)) + { + if (errno != ENOENT || (!S_ISDIR (src_st.st_mode) && dst_slash)) + return -1; + dst_exists = false; + } + else + { + if (S_ISDIR (dst_st.st_mode) != S_ISDIR (src_st.st_mode)) + { + errno = S_ISDIR (dst_st.st_mode) ? EISDIR : ENOTDIR; + return -1; + } + dst_exists = true; + } + + /* There are no symlinks, so if a file existed with a trailing + slash, it must be a directory, and we don't have to worry about + stripping strip trailing slash. However, mingw refuses to + replace an existing empty directory, so we have to help it out. + And canonicalize_file_name is not yet ported to mingw; however, + for directories, getcwd works as a viable alternative. Ensure + that we can get back to where we started before using it; later + attempts to return are fatal. Note that we can end up losing a + directory if rename then fails, but it was empty, so not much + damage was done. */ + if (dst_exists && S_ISDIR (dst_st.st_mode)) + { + char *cwd = getcwd (NULL, 0); + char *src_temp; + char *dst_temp; + if (!cwd || chdir (cwd)) + return -1; + if (IS_ABSOLUTE_FILE_NAME (src)) + { + dst_temp = chdir (dst) ? NULL : getcwd (NULL, 0); + src_temp = chdir (src) ? NULL : getcwd (NULL, 0); + } + else + { + src_temp = chdir (src) ? NULL : getcwd (NULL, 0); + if (!IS_ABSOLUTE_FILE_NAME (dst) && chdir (cwd)) + abort (); + dst_temp = chdir (dst) ? NULL : getcwd (NULL, 0); + } + if (chdir (cwd)) + abort (); + free (cwd); + if (!src_temp || !dst_temp) + { + free (src_temp); + free (dst_temp); + errno = ENOMEM; + return -1; + } + src_len = strlen (src_temp); + if (strncmp (src_temp, dst_temp, src_len) == 0 + && (ISSLASH (dst_temp[src_len]) || dst_temp[src_len] == '\0')) + { + error = dst_temp[src_len]; + free (src_temp); + free (dst_temp); + if (error) + { + errno = EINVAL; + return -1; + } + return 0; + } + if (rmdir (dst)) + { + free (src_temp); + free (dst_temp); + return -1; + } + free (src_temp); + free (dst_temp); + } + + /* MoveFileEx works if SRC is a directory without any flags, but + fails with MOVEFILE_REPLACE_EXISTING, so try without flags first. + Thankfully, MoveFileEx handles hard links correctly, even though + rename() does not. */ + if (MoveFileEx (src, dst, 0)) + return 0; + + /* Retry with MOVEFILE_REPLACE_EXISTING if the move failed + due to the destination already existing. */ + error = GetLastError (); + if (error == ERROR_FILE_EXISTS || error == ERROR_ALREADY_EXISTS) + { + if (MoveFileEx (src, dst, MOVEFILE_REPLACE_EXISTING)) + return 0; + + error = GetLastError (); + } + + switch (error) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_BAD_PATHNAME: + case ERROR_DIRECTORY: + errno = ENOENT; + break; + + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + errno = EACCES; + break; + + case ERROR_OUTOFMEMORY: + errno = ENOMEM; + break; + + case ERROR_CURRENT_DIRECTORY: + errno = EBUSY; + break; + + case ERROR_NOT_SAME_DEVICE: + errno = EXDEV; + 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_HANDLE_DISK_FULL: + case ERROR_DISK_FULL: + case ERROR_DISK_TOO_FRAGMENTED: + errno = ENOSPC; + break; + + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + errno = EEXIST; + break; + + case ERROR_BUFFER_OVERFLOW: + case ERROR_FILENAME_EXCED_RANGE: + errno = ENAMETOOLONG; + break; + + case ERROR_INVALID_NAME: + case ERROR_DELETE_PENDING: + errno = EPERM; /* ? */ + break; + +# ifndef ERROR_FILE_TOO_LARGE +/* This value is documented but not defined in all versions of windows.h. */ +# define ERROR_FILE_TOO_LARGE 223 +# endif + case ERROR_FILE_TOO_LARGE: + errno = EFBIG; + break; + + default: + errno = EINVAL; + break; + } + + return -1; +} + +#else /* ! W32 platform */ + +# include +# include +# include +# include +# include +# include + +# include "dirname.h" +# include "same-inode.h" + +/* Rename the file SRC to DST, fixing any trailing slash bugs. */ + +int +rpl_rename (char const *src, char const *dst) +{ + size_t src_len = strlen (src); + size_t dst_len = strlen (dst); + char *src_temp = (char *) src; + char *dst_temp = (char *) dst; + bool src_slash; + bool dst_slash; + _GL_UNUSED bool dst_exists; + int ret_val = -1; + int rename_errno = ENOTDIR; + struct stat src_st; + struct stat dst_st; + + if (!src_len || !dst_len) + return rename (src, dst); /* Let strace see the ENOENT failure. */ + +# if RENAME_DEST_EXISTS_BUG + { + char *src_base = last_component (src); + char *dst_base = last_component (dst); + if (*src_base == '.') + { + size_t len = base_len (src_base); + if (len == 1 || (len == 2 && src_base[1] == '.')) + { + errno = EINVAL; + return -1; + } + } + if (*dst_base == '.') + { + size_t len = base_len (dst_base); + if (len == 1 || (len == 2 && dst_base[1] == '.')) + { + errno = EINVAL; + return -1; + } + } + } +# endif /* RENAME_DEST_EXISTS_BUG */ + + src_slash = src[src_len - 1] == '/'; + dst_slash = dst[dst_len - 1] == '/'; + +# if !RENAME_HARD_LINK_BUG && !RENAME_DEST_EXISTS_BUG + /* If there are no trailing slashes, then trust the native + implementation unless we also suspect issues with hard link + detection or file/directory conflicts. */ + if (!src_slash && !dst_slash) + return rename (src, dst); +# endif /* !RENAME_HARD_LINK_BUG && !RENAME_DEST_EXISTS_BUG */ + + /* Presence of a trailing slash requires directory semantics. If + the source does not exist, or if the destination cannot be turned + into a directory, give up now. Otherwise, strip trailing slashes + before calling rename. */ + if (lstat (src, &src_st)) + return -1; + if (lstat (dst, &dst_st)) + { + if (errno != ENOENT || (!S_ISDIR (src_st.st_mode) && dst_slash)) + return -1; + dst_exists = false; + } + else + { + if (S_ISDIR (dst_st.st_mode) != S_ISDIR (src_st.st_mode)) + { + errno = S_ISDIR (dst_st.st_mode) ? EISDIR : ENOTDIR; + return -1; + } +# if RENAME_HARD_LINK_BUG + if (SAME_INODE (src_st, dst_st)) + return 0; +# endif /* RENAME_HARD_LINK_BUG */ + dst_exists = true; + } + +# if (RENAME_TRAILING_SLASH_SOURCE_BUG || RENAME_DEST_EXISTS_BUG \ + || RENAME_HARD_LINK_BUG) + /* If the only bug was that a trailing slash was allowed on a + non-existing file destination, as in Solaris 10, then we've + already covered that situation. But if there is any problem with + a trailing slash on an existing source or destination, as in + Solaris 9, or if a directory can overwrite a symlink, as on + Cygwin 1.5, or if directories cannot be created with trailing + slash, as on NetBSD 1.6, then we must strip the offending slash + and check that we have not encountered a symlink instead of a + directory. + + Stripping a trailing slash interferes with POSIX semantics, where + rename behavior on a symlink with a trailing slash operates on + the corresponding target directory. We prefer the GNU semantics + of rejecting any use of a symlink with trailing slash, but do not + enforce them, since Solaris 10 is able to obey POSIX semantics + and there might be clients expecting it, as counter-intuitive as + those semantics are. + + Technically, we could also follow the POSIX behavior by chasing a + readlink trail, but that is harder to implement. */ + if (src_slash) + { + src_temp = strdup (src); + if (!src_temp) + { + /* Rather than rely on strdup-posix, we set errno ourselves. */ + rename_errno = ENOMEM; + goto out; + } + strip_trailing_slashes (src_temp); + if (lstat (src_temp, &src_st)) + { + rename_errno = errno; + goto out; + } + if (S_ISLNK (src_st.st_mode)) + goto out; + } + if (dst_slash) + { + dst_temp = strdup (dst); + if (!dst_temp) + { + rename_errno = ENOMEM; + goto out; + } + strip_trailing_slashes (dst_temp); + if (lstat (dst_temp, &dst_st)) + { + if (errno != ENOENT) + { + rename_errno = errno; + goto out; + } + } + else if (S_ISLNK (dst_st.st_mode)) + goto out; + } +# endif /* RENAME_TRAILING_SLASH_SOURCE_BUG || RENAME_DEST_EXISTS_BUG + || RENAME_HARD_LINK_BUG */ + +# if RENAME_DEST_EXISTS_BUG + /* Cygwin 1.5 sometimes behaves oddly when moving a non-empty + directory on top of an empty one (the old directory name can + reappear if the new directory tree is removed). Work around this + by removing the target first, but don't remove the target if it + is a subdirectory of the source. Note that we can end up losing + a directory if rename then fails, but it was empty, so not much + damage was done. */ + if (dst_exists && S_ISDIR (dst_st.st_mode)) + { + if (src_st.st_dev != dst_st.st_dev) + { + rename_errno = EXDEV; + goto out; + } + if (src_temp != src) + free (src_temp); + src_temp = canonicalize_file_name (src); + if (dst_temp != dst) + free (dst_temp); + dst_temp = canonicalize_file_name (dst); + if (!src_temp || !dst_temp) + { + rename_errno = ENOMEM; + goto out; + } + src_len = strlen (src_temp); + if (strncmp (src_temp, dst_temp, src_len) == 0 + && dst_temp[src_len] == '/') + { + rename_errno = EINVAL; + goto out; + } + if (rmdir (dst)) + { + rename_errno = errno; + goto out; + } + } +# endif /* RENAME_DEST_EXISTS_BUG */ + + ret_val = rename (src_temp, dst_temp); + rename_errno = errno; + + out: _GL_UNUSED_LABEL; + + if (src_temp != src) + free (src_temp); + if (dst_temp != dst) + free (dst_temp); + errno = rename_errno; + return ret_val; +} +#endif /* ! W32 platform */ diff --git a/lib/rewinddir.c b/lib/rewinddir.c new file mode 100644 index 0000000..b07aaf9 --- /dev/null +++ b/lib/rewinddir.c @@ -0,0 +1,53 @@ +/* Restart reading the entries of a directory from the beginning. + 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 3 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 "dirent-private.h" + +/* Don't assume that UNICODE is not defined. */ +#undef FindFirstFile +#define FindFirstFile FindFirstFileA + +void +rewinddir (DIR *dirp) +{ + /* Like in closedir(). */ + if (dirp->current != INVALID_HANDLE_VALUE) + FindClose (dirp->current); + + /* Like in opendir(). */ + dirp->status = -1; + dirp->current = FindFirstFile (dirp->dir_name_mask, &dirp->entry); + if (dirp->current == INVALID_HANDLE_VALUE) + { + switch (GetLastError ()) + { + case ERROR_FILE_NOT_FOUND: + dirp->status = -2; + break; + default: + /* Save the error code for the next readdir() call. */ + dirp->status = ENOENT; + break; + } + } +} diff --git a/lib/rmdir.c b/lib/rmdir.c new file mode 100644 index 0000000..8c8b75e --- /dev/null +++ b/lib/rmdir.c @@ -0,0 +1,56 @@ +/* Work around rmdir bugs. + + Copyright (C) 1988, 1990, 1999, 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 . */ + +#include + +#include + +#include +#include + +#include "filename.h" + +#undef rmdir +#if defined _WIN32 && !defined __CYGWIN__ +# define rmdir _rmdir +#endif + +/* Remove directory DIR. + Return 0 if successful, -1 if not. */ + +int +rpl_rmdir (char const *dir) +{ + /* Work around cygwin 1.5.x bug where rmdir("dir/./") succeeds. */ + size_t len = strlen (dir); + int result; + while (len && ISSLASH (dir[len - 1])) + len--; + if (len && dir[len - 1] == '.' && (1 == len || ISSLASH (dir[len - 2]))) + { + errno = EINVAL; + return -1; + } + result = rmdir (dir); + /* Work around mingw bug, where rmdir("file/") fails with EINVAL + instead of ENOTDIR. We've already filtered out trailing ., the + only reason allowed by POSIX for EINVAL. */ + if (result == -1 && errno == EINVAL) + errno = ENOTDIR; + return result; +} diff --git a/lib/same-inode.h b/lib/same-inode.h new file mode 100644 index 0000000..f65f3d0 --- /dev/null +++ b/lib/same-inode.h @@ -0,0 +1,47 @@ +/* Determine whether two stat buffers are known to refer to the same file. + + Copyright (C) 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 SAME_INODE_H +# define SAME_INODE_H 1 + +# include + +# if defined __VMS && __CRTL_VER < 80200000 +# define SAME_INODE(a, b) \ + ((a).st_ino[0] == (b).st_ino[0] \ + && (a).st_ino[1] == (b).st_ino[1] \ + && (a).st_ino[2] == (b).st_ino[2] \ + && (a).st_dev == (b).st_dev) +# elif defined _WIN32 && ! defined __CYGWIN__ + /* Native Windows. */ +# if _GL_WINDOWS_STAT_INODES + /* stat() and fstat() set st_dev and st_ino to 0 if information about + the inode is not available. */ +# define SAME_INODE(a, b) \ + (!((a).st_ino == 0 && (a).st_dev == 0) \ + && (a).st_ino == (b).st_ino && (a).st_dev == (b).st_dev) +# else + /* stat() and fstat() set st_ino to 0 always. */ +# define SAME_INODE(a, b) 0 +# endif +# else +# define SAME_INODE(a, b) \ + ((a).st_ino == (b).st_ino \ + && (a).st_dev == (b).st_dev) +# endif + +#endif diff --git a/lib/save-cwd.c b/lib/save-cwd.c new file mode 100644 index 0000000..ea487a4 --- /dev/null +++ b/lib/save-cwd.c @@ -0,0 +1,97 @@ +/* save-cwd.c -- Save and restore current working directory. + + Copyright (C) 1995, 1997-1998, 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 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. */ + +#include + +#include "save-cwd.h" + +#include +#include +#include +#include +#include + +#include "chdir-long.h" +#include "unistd--.h" + +#if GNULIB_FCNTL_SAFER +# include "fcntl--.h" +#else +# define GNULIB_FCNTL_SAFER 0 +#endif + +/* Record the location of the current working directory in CWD so that + the program may change to other directories and later use restore_cwd + to return to the recorded location. This function may allocate + space using malloc (via getcwd) or leave a file descriptor open; + use free_cwd to perform the necessary free or close. Upon failure, + no memory is allocated, any locally opened file descriptors are + closed; return non-zero -- in that case, free_cwd need not be + called, but doing so is ok. Otherwise, return zero. + + The _raison d'etre_ for this interface is that the working directory + is sometimes inaccessible, and getcwd is not robust or as efficient. + So, we prefer to use the open/fchdir approach, but fall back on + getcwd if necessary. This module works for most cases with just + the getcwd-lgpl module, but to be truly robust, use the getcwd module. + + Some systems lack fchdir altogether: e.g., OS/2, pre-2001 Cygwin, + SCO Xenix. Also, SunOS 4 and Irix 5.3 provide the function, yet it + doesn't work for partitions on which auditing is enabled. If + you're still using an obsolete system with these problems, please + send email to the maintainer of this code. */ + +int +save_cwd (struct saved_cwd *cwd) +{ + cwd->name = NULL; + + cwd->desc = open (".", O_SEARCH | O_CLOEXEC); + if (!GNULIB_FCNTL_SAFER) + cwd->desc = fd_safer_flag (cwd->desc, O_CLOEXEC); + if (cwd->desc < 0) + { + cwd->name = getcwd (NULL, 0); + return cwd->name ? 0 : -1; + } + + return 0; +} + +/* Change to recorded location, CWD, in directory hierarchy. + Upon failure, return -1 (errno is set by chdir or fchdir). + Upon success, return zero. */ + +int +restore_cwd (const struct saved_cwd *cwd) +{ + if (0 <= cwd->desc) + return fchdir (cwd->desc); + else + return chdir_long (cwd->name); +} + +void +free_cwd (struct saved_cwd *cwd) +{ + if (cwd->desc >= 0) + close (cwd->desc); + free (cwd->name); +} diff --git a/lib/save-cwd.h b/lib/save-cwd.h new file mode 100644 index 0000000..90e8a07 --- /dev/null +++ b/lib/save-cwd.h @@ -0,0 +1,34 @@ +/* Save and restore current working directory. + + Copyright (C) 1995, 1997-1998, 2003, 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 SAVE_CWD_H +# define SAVE_CWD_H 1 + +struct saved_cwd + { + int desc; + char *name; + }; + +int save_cwd (struct saved_cwd *cwd); +int restore_cwd (const struct saved_cwd *cwd); +void free_cwd (struct saved_cwd *cwd); + +#endif /* SAVE_CWD_H */ diff --git a/lib/sched.in.h b/lib/sched.in.h new file mode 100644 index 0000000..d19c502 --- /dev/null +++ b/lib/sched.in.h @@ -0,0 +1,99 @@ +/* A GNU-like . + 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 . */ + +#ifndef _@GUARD_PREFIX@_SCHED_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_SCHED_H@ +# if @HAVE_SYS_CDEFS_H@ +# include +# endif +# @INCLUDE_NEXT@ @NEXT_SCHED_H@ +#endif + +#ifndef _@GUARD_PREFIX@_SCHED_H +#define _@GUARD_PREFIX@_SCHED_H + +/* Get pid_t. + This is needed on glibc 2.11 (see + glibc bug ) + and Mac OS X 10.5. */ +#include + +#ifdef __KLIBC__ +/* On OS/2 kLIBC, struct sched_param is in spawn.h. */ +# include +#endif + +#ifdef __VMS +/* On OpenVMS, struct sched_param is in . */ +# include +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +#if !@HAVE_STRUCT_SCHED_PARAM@ + +# if !GNULIB_defined_struct_sched_param +struct sched_param +{ + int sched_priority; +}; +# define GNULIB_defined_struct_sched_param 1 +# endif + +#endif + +#if !(defined SCHED_FIFO && defined SCHED_RR && defined SCHED_OTHER) +# define SCHED_FIFO 1 +# define SCHED_RR 2 +# define SCHED_OTHER 0 +#endif + +#if @GNULIB_SCHED_YIELD@ +# if @REPLACE_SCHED_YIELD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef sched_yield +# define sched_yield rpl_sched_yield +# endif +_GL_FUNCDECL_RPL (sched_yield, int, (void)); +_GL_CXXALIAS_RPL (sched_yield, int, (void)); +# else +# if !@HAVE_SCHED_YIELD@ +_GL_FUNCDECL_SYS (sched_yield, int, (void)); +# endif +_GL_CXXALIAS_SYS (sched_yield, int, (void)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (sched_yield); +# endif +#elif defined GNULIB_POSIXCHECK +# undef sched_yield +# if HAVE_RAW_DECL_SCHED_YIELD +_GL_WARN_ON_USE (sched_yield, "sched_yield is not portable - " + "use gnulib module sched_yield for portability"); +# endif +#endif + +#endif /* _@GUARD_PREFIX@_SCHED_H */ +#endif /* _@GUARD_PREFIX@_SCHED_H */ diff --git a/lib/scratch_buffer.h b/lib/scratch_buffer.h new file mode 100644 index 0000000..f4fe5e8 --- /dev/null +++ b/lib/scratch_buffer.h @@ -0,0 +1,127 @@ +/* Variable-sized buffer with on-stack default allocation. + 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 Paul Eggert, 2017. */ + +#ifndef _GL_SCRATCH_BUFFER_H +#define _GL_SCRATCH_BUFFER_H + +/* Scratch buffers with a default stack allocation and fallback to + heap allocation. It is expected that this function is used in this + way: + + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); + + while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) + if (!scratch_buffer_grow (&tmpbuf)) + return -1; + + scratch_buffer_free (&tmpbuf); + return 0; + + The allocation functions (scratch_buffer_grow, + scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make + sure that the heap allocation, if any, is freed, so that the code + above does not have a memory leak. The buffer still remains in a + state that can be deallocated using scratch_buffer_free, so a loop + like this is valid as well: + + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); + + while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) + if (!scratch_buffer_grow (&tmpbuf)) + break; + + scratch_buffer_free (&tmpbuf); + + scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed + to grow the buffer by at least 512 bytes. This means that when + using the scratch buffer as a backing store for a non-character + array whose element size, in bytes, is 512 or smaller, the scratch + buffer only has to grow once to make room for at least one more + element. +*/ + +/* Scratch buffer. Must be initialized with scratch_buffer_init + before its use. */ +struct scratch_buffer; + +/* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space + and BUFFER->length reflects the available space. */ +#if 0 +extern void scratch_buffer_init (struct scratch_buffer *buffer); +#endif + +/* Deallocates *BUFFER (if it was heap-allocated). */ +#if 0 +extern void scratch_buffer_free (struct scratch_buffer *buffer); +#endif + +/* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT + preserved. Return true on success, false on allocation failure (in + which case the old buffer is freed). On success, the new buffer is + larger than the previous size. On failure, *BUFFER is deallocated, + but remains in a free-able state, and errno is set. */ +#if 0 +extern bool scratch_buffer_grow (struct scratch_buffer *buffer); +#endif + +/* Like scratch_buffer_grow, but preserve the old buffer + contents on success, as a prefix of the new buffer. */ +#if 0 +extern bool scratch_buffer_grow_preserve (struct scratch_buffer *buffer); +#endif + +/* Grow *BUFFER so that it can store at least NELEM elements of SIZE + bytes. The buffer contents are NOT preserved. Both NELEM and SIZE + can be zero. Return true on success, false on allocation failure + (in which case the old buffer is freed, but *BUFFER remains in a + free-able state, and errno is set). It is unspecified whether this + function can reduce the array size. */ +#if 0 +extern bool scratch_buffer_set_array_size (struct scratch_buffer *buffer, + size_t nelem, size_t size); +#endif + +/* Return a copy of *BUFFER's first SIZE bytes as a heap-allocated block, + deallocating *BUFFER if it was heap-allocated. SIZE must be at + most *BUFFER's size. Return NULL (setting errno) on memory + exhaustion. */ +#if 0 +extern void *scratch_buffer_dupfree (struct scratch_buffer *buffer, + size_t size); +#endif + + +/* The implementation is imported from glibc. */ + +/* Avoid possible conflicts with symbols exported by the GNU libc. */ +#define __libc_scratch_buffer_dupfree gl_scratch_buffer_dupfree +#define __libc_scratch_buffer_grow gl_scratch_buffer_grow +#define __libc_scratch_buffer_grow_preserve gl_scratch_buffer_grow_preserve +#define __libc_scratch_buffer_set_array_size gl_scratch_buffer_set_array_size + +#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 + +#include + +#endif /* _GL_SCRATCH_BUFFER_H */ diff --git a/lib/secure_getenv.c b/lib/secure_getenv.c new file mode 100644 index 0000000..4e4ebc9 --- /dev/null +++ b/lib/secure_getenv.c @@ -0,0 +1,54 @@ +/* Look up an environment variable, returning NULL in insecure situations. + + Copyright 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 . */ + +#include + +#include + +#if !HAVE___SECURE_GETENV +# if HAVE_ISSETUGID || (HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID) +# include +# endif +#endif + +char * +secure_getenv (char const *name) +{ +#if HAVE___SECURE_GETENV /* glibc */ + return __secure_getenv (name); +#elif HAVE_ISSETUGID /* OS X, FreeBSD, NetBSD, OpenBSD */ + if (issetugid ()) + return NULL; + return getenv (name); +#elif HAVE_GETUID && HAVE_GETEUID && HAVE_GETGID && HAVE_GETEGID /* other Unix */ + if (geteuid () != getuid () || getegid () != getgid ()) + return NULL; + return getenv (name); +#elif defined _WIN32 && ! defined __CYGWIN__ /* native Windows */ + /* On native Windows, there is no such concept as setuid or setgid binaries. + - Programs launched as system services have high privileges, but they don't + inherit environment variables from a user. + - Programs launched by a user with "Run as Administrator" have high + privileges and use the environment variables, but the user has been asked + whether he agrees. + - Programs launched by a user without "Run as Administrator" cannot gain + high privileges, therefore there is no risk. */ + return getenv (name); +#else + return NULL; +#endif +} diff --git a/lib/select.c b/lib/select.c new file mode 100644 index 0000000..c242498 --- /dev/null +++ b/lib/select.c @@ -0,0 +1,598 @@ +/* Emulation for select(2) + Contributed by Paolo Bonzini. + + Copyright 2008-2022 Free Software Foundation, Inc. + + 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 . */ + +#include + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows. */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Get the overridden 'struct timeval'. */ +#include + +#if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +#else +# include +#endif + +#undef select + +/* Don't assume that UNICODE is not defined. */ +#undef GetModuleHandle +#define GetModuleHandle GetModuleHandleA +#undef PeekConsoleInput +#define PeekConsoleInput PeekConsoleInputA +#undef CreateEvent +#define CreateEvent CreateEventA +#undef PeekMessage +#define PeekMessage PeekMessageA +#undef DispatchMessage +#define DispatchMessage DispatchMessageA + +/* Avoid warnings from gcc -Wcast-function-type. */ +#define GetProcAddress \ + (void *) GetProcAddress + +struct bitset { + unsigned char in[FD_SETSIZE / CHAR_BIT]; + unsigned char out[FD_SETSIZE / CHAR_BIT]; +}; + +/* Declare data structures for ntdll functions. */ +typedef struct _FILE_PIPE_LOCAL_INFORMATION { + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; + +typedef struct _IO_STATUS_BLOCK +{ + union { + DWORD Status; + PVOID Pointer; + } u; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +typedef enum _FILE_INFORMATION_CLASS { + FilePipeLocalInformation = 24 +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + +typedef DWORD (WINAPI *PNtQueryInformationFile) + (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS); + +#ifndef PIPE_BUF +#define PIPE_BUF 512 +#endif + +static BOOL IsConsoleHandle (HANDLE h) +{ + DWORD mode; + return GetConsoleMode (h, &mode) != 0; +} + +static BOOL +IsSocketHandle (HANDLE h) +{ + WSANETWORKEVENTS ev; + + if (IsConsoleHandle (h)) + return FALSE; + + /* Under Wine, it seems that getsockopt returns 0 for pipes too. + WSAEnumNetworkEvents instead distinguishes the two correctly. */ + ev.lNetworkEvents = 0xDEADBEEF; + WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); + return ev.lNetworkEvents != 0xDEADBEEF; +} + +/* Compute output fd_sets for libc descriptor FD (whose Windows handle is + H). */ + +static int +windows_poll_handle (HANDLE h, int fd, + struct bitset *rbits, + struct bitset *wbits, + struct bitset *xbits) +{ + BOOL read, write, except; + int i, ret; + INPUT_RECORD *irbuffer; + DWORD avail, nbuffer; + BOOL bRet; + IO_STATUS_BLOCK iosb; + FILE_PIPE_LOCAL_INFORMATION fpli; + static PNtQueryInformationFile NtQueryInformationFile; + static BOOL once_only; + + read = write = except = FALSE; + switch (GetFileType (h)) + { + case FILE_TYPE_DISK: + read = TRUE; + write = TRUE; + break; + + case FILE_TYPE_PIPE: + if (!once_only) + { + NtQueryInformationFile = (PNtQueryInformationFile) + GetProcAddress (GetModuleHandle ("ntdll.dll"), + "NtQueryInformationFile"); + once_only = TRUE; + } + + if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0) + { + if (avail) + read = TRUE; + } + else if (GetLastError () == ERROR_BROKEN_PIPE) + ; + + else + { + /* It was the write-end of the pipe. Check if it is writable. + If NtQueryInformationFile fails, optimistically assume the pipe is + writable. This could happen on Windows 9x, where + NtQueryInformationFile is not available, or if we inherit a pipe + that doesn't permit FILE_READ_ATTRIBUTES access on the write end + (I think this should not happen since Windows XP SP2; WINE seems + fine too). Otherwise, ensure that enough space is available for + atomic writes. */ + memset (&iosb, 0, sizeof (iosb)); + memset (&fpli, 0, sizeof (fpli)); + + if (!NtQueryInformationFile + || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli), + FilePipeLocalInformation) + || fpli.WriteQuotaAvailable >= PIPE_BUF + || (fpli.OutboundQuota < PIPE_BUF && + fpli.WriteQuotaAvailable == fpli.OutboundQuota)) + write = TRUE; + } + break; + + case FILE_TYPE_CHAR: + write = TRUE; + if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1))))) + break; + + ret = WaitForSingleObject (h, 0); + if (ret == WAIT_OBJECT_0) + { + if (!IsConsoleHandle (h)) + { + read = TRUE; + break; + } + + nbuffer = avail = 0; + bRet = GetNumberOfConsoleInputEvents (h, &nbuffer); + + /* Screen buffers handles are filtered earlier. */ + assert (bRet); + if (nbuffer == 0) + { + except = TRUE; + break; + } + + irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD)); + bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail); + if (!bRet || avail == 0) + { + except = TRUE; + break; + } + + for (i = 0; i < avail; i++) + if (irbuffer[i].EventType == KEY_EVENT) + read = TRUE; + } + break; + + default: + ret = WaitForSingleObject (h, 0); + write = TRUE; + if (ret == WAIT_OBJECT_0) + read = TRUE; + + break; + } + + ret = 0; + if (read && (rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1))))) + { + rbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1))); + ret++; + } + + if (write && (wbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1))))) + { + wbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1))); + ret++; + } + + if (except && (xbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1))))) + { + xbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1))); + ret++; + } + + return ret; +} + +int +rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, + struct timeval *timeout) +#undef timeval +{ + static struct timeval tv0; + static HANDLE hEvent; + HANDLE h, handle_array[FD_SETSIZE + 2]; + fd_set handle_rfds, handle_wfds, handle_xfds; + struct bitset rbits, wbits, xbits; + unsigned char anyfds_in[FD_SETSIZE / CHAR_BIT]; + DWORD ret, wait_timeout, nhandles, nsock, nbuffer; + MSG msg; + int i, fd, rc; + clock_t tend; + + if (nfds > FD_SETSIZE) + nfds = FD_SETSIZE; + + if (!timeout) + wait_timeout = INFINITE; + else + { + wait_timeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; + + /* select is also used as a portable usleep. */ + if (!rfds && !wfds && !xfds) + { + Sleep (wait_timeout); + return 0; + } + } + + if (!hEvent) + hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + + handle_array[0] = hEvent; + nhandles = 1; + nsock = 0; + + /* Copy descriptors to bitsets. At the same time, eliminate + bits in the "wrong" direction for console input buffers + and screen buffers, because screen buffers are waitable + and they will block until a character is available. */ + memset (&rbits, 0, sizeof (rbits)); + memset (&wbits, 0, sizeof (wbits)); + memset (&xbits, 0, sizeof (xbits)); + memset (anyfds_in, 0, sizeof (anyfds_in)); + if (rfds) + for (i = 0; i < rfds->fd_count; i++) + { + fd = rfds->fd_array[i]; + h = (HANDLE) _get_osfhandle (fd); + if (IsConsoleHandle (h) + && !GetNumberOfConsoleInputEvents (h, &nbuffer)) + continue; + + rbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1)); + anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1)); + } + else + rfds = (fd_set *) alloca (sizeof (fd_set)); + + if (wfds) + for (i = 0; i < wfds->fd_count; i++) + { + fd = wfds->fd_array[i]; + h = (HANDLE) _get_osfhandle (fd); + if (IsConsoleHandle (h) + && GetNumberOfConsoleInputEvents (h, &nbuffer)) + continue; + + wbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1)); + anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1)); + } + else + wfds = (fd_set *) alloca (sizeof (fd_set)); + + if (xfds) + for (i = 0; i < xfds->fd_count; i++) + { + fd = xfds->fd_array[i]; + xbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1)); + anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1)); + } + else + xfds = (fd_set *) alloca (sizeof (fd_set)); + + /* Zero all the fd_sets, including the application's. */ + FD_ZERO (rfds); + FD_ZERO (wfds); + FD_ZERO (xfds); + FD_ZERO (&handle_rfds); + FD_ZERO (&handle_wfds); + FD_ZERO (&handle_xfds); + + /* Classify handles. Create fd sets for sockets, poll the others. */ + for (i = 0; i < nfds; i++) + { + if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0) + continue; + + h = (HANDLE) _get_osfhandle (i); + if (!h) + { + errno = EBADF; + return -1; + } + + if (IsSocketHandle (h)) + { + int requested = FD_CLOSE; + + /* See above; socket handles are mapped onto select, but we + need to map descriptors to handles. */ + if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + { + requested |= FD_READ | FD_ACCEPT; + FD_SET ((SOCKET) h, rfds); + FD_SET ((SOCKET) h, &handle_rfds); + } + if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + { + requested |= FD_WRITE | FD_CONNECT; + FD_SET ((SOCKET) h, wfds); + FD_SET ((SOCKET) h, &handle_wfds); + } + if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + { + requested |= FD_OOB; + FD_SET ((SOCKET) h, xfds); + FD_SET ((SOCKET) h, &handle_xfds); + } + + WSAEventSelect ((SOCKET) h, hEvent, requested); + nsock++; + } + else + { + handle_array[nhandles++] = h; + + /* Poll now. If we get an event, do not wait below. */ + if (wait_timeout != 0 + && windows_poll_handle (h, i, &rbits, &wbits, &xbits)) + wait_timeout = 0; + } + } + + /* Place a sentinel at the end of the array. */ + handle_array[nhandles] = NULL; + + /* When will the waiting period expire? */ + if (wait_timeout != INFINITE) + tend = clock () + wait_timeout; + +restart: + if (wait_timeout == 0 || nsock == 0) + rc = 0; + else + { + /* See if we need to wait in the loop below. If any select is ready, + do MsgWaitForMultipleObjects anyway to dispatch messages, but + no need to call select again. */ + rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0); + if (rc == 0) + { + /* Restore the fd_sets for the other select we do below. */ + memcpy (&handle_rfds, rfds, sizeof (fd_set)); + memcpy (&handle_wfds, wfds, sizeof (fd_set)); + memcpy (&handle_xfds, xfds, sizeof (fd_set)); + } + else + wait_timeout = 0; + } + + /* How much is left to wait? */ + if (wait_timeout != INFINITE) + { + clock_t tnow = clock (); + if (tend >= tnow) + wait_timeout = tend - tnow; + else + wait_timeout = 0; + } + + for (;;) + { + ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE, + wait_timeout, QS_ALLINPUT); + + if (ret == WAIT_OBJECT_0 + nhandles) + { + /* new input of some other kind */ + BOOL bRet; + while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + else + break; + } + + /* If we haven't done it yet, check the status of the sockets. */ + if (rc == 0 && nsock > 0) + rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0); + + if (nhandles > 1) + { + /* Count results that are not counted in the return value of select. */ + nhandles = 1; + for (i = 0; i < nfds; i++) + { + if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0) + continue; + + h = (HANDLE) _get_osfhandle (i); + if (h == handle_array[nhandles]) + { + /* Not a socket. */ + nhandles++; + windows_poll_handle (h, i, &rbits, &wbits, &xbits); + if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))) + || wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))) + || xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + rc++; + } + } + + if (rc == 0 + && (wait_timeout == INFINITE + /* If NHANDLES > 1, but no bits are set, it means we've + been told incorrectly that some handle was signaled. + This happens with anonymous pipes, which always cause + MsgWaitForMultipleObjects to exit immediately, but no + data is found ready to be read by windows_poll_handle. + To avoid a total failure (whereby we return zero and + don't wait at all), let's poll in a more busy loop. */ + || (wait_timeout != 0 && nhandles > 1))) + { + /* Sleep 1 millisecond to avoid busy wait and retry with the + original fd_sets. */ + memcpy (&handle_rfds, rfds, sizeof (fd_set)); + memcpy (&handle_wfds, wfds, sizeof (fd_set)); + memcpy (&handle_xfds, xfds, sizeof (fd_set)); + SleepEx (1, TRUE); + goto restart; + } + if (timeout && wait_timeout == 0 && rc == 0) + timeout->tv_sec = timeout->tv_usec = 0; + } + + /* Now fill in the results. */ + FD_ZERO (rfds); + FD_ZERO (wfds); + FD_ZERO (xfds); + nhandles = 1; + for (i = 0; i < nfds; i++) + { + if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0) + continue; + + h = (HANDLE) _get_osfhandle (i); + if (h != handle_array[nhandles]) + { + /* Perform handle->descriptor mapping. */ + SOCKET s = (SOCKET) h; + WSAEventSelect (s, NULL, 0); + if (FD_ISSET (s, &handle_rfds)) + FD_SET (i, rfds); + if (FD_ISSET (s, &handle_wfds)) + FD_SET (i, wfds); + if (FD_ISSET (s, &handle_xfds)) + FD_SET (i, xfds); + } + else + { + /* Not a socket. */ + nhandles++; + if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + FD_SET (i, rfds); + if (wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + FD_SET (i, wfds); + if (xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) + FD_SET (i, xfds); + } + } + + return rc; +} + +#else /* ! Native Windows. */ + +#include /* NULL */ +#include +#include + +#undef select + +int +rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, + struct timeval *timeout) +{ + int i; + + /* FreeBSD 8.2 has a bug: it does not always detect invalid fds. */ + if (nfds < 0 || nfds > FD_SETSIZE) + { + errno = EINVAL; + return -1; + } + for (i = 0; i < nfds; i++) + { + if (((rfds && FD_ISSET (i, rfds)) + || (wfds && FD_ISSET (i, wfds)) + || (xfds && FD_ISSET (i, xfds))) + && dup2 (i, i) != i) + return -1; + } + + /* Interix 3.5 has a bug: it does not support nfds == 0. */ + if (nfds == 0) + { + nfds = 1; + rfds = NULL; + wfds = NULL; + xfds = NULL; + } + return select (nfds, rfds, wfds, xfds, timeout); +} + +#endif diff --git a/lib/send.c b/lib/send.c new file mode 100644 index 0000000..5510c0c --- /dev/null +++ b/lib/send.c @@ -0,0 +1,49 @@ +/* send.c --- wrappers for Windows send function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef send + +ssize_t +rpl_send (int fd, const void *buf, size_t len, int flags) +{ + SOCKET sock = FD_TO_SOCKET (fd); + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + int r = send (sock, buf, len, flags); + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/setlocale-lock.c b/lib/setlocale-lock.c new file mode 100644 index 0000000..4e7540e --- /dev/null +++ b/lib/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/lib/setlocale_null.c b/lib/setlocale_null.c new file mode 100644 index 0000000..778429b --- /dev/null +++ b/lib/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/lib/setlocale_null.h b/lib/setlocale_null.h new file mode 100644 index 0000000..d1921b0 --- /dev/null +++ b/lib/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/lib/setsockopt.c b/lib/setsockopt.c new file mode 100644 index 0000000..2811c19 --- /dev/null +++ b/lib/setsockopt.c @@ -0,0 +1,65 @@ +/* setsockopt.c --- wrappers for Windows setsockopt function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get struct timeval. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#undef setsockopt + +int +rpl_setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen) +{ + SOCKET sock = FD_TO_SOCKET (fd); + int r; + + if (sock == INVALID_SOCKET) + { + errno = EBADF; + return -1; + } + else + { + if (level == SOL_SOCKET + && (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) + { + const struct timeval *tv = optval; + int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000; + optval = &milliseconds; + r = setsockopt (sock, level, optname, optval, sizeof (int)); + } + else + { + r = setsockopt (sock, level, optname, optval, optlen); + } + + if (r < 0) + set_winsock_errno (); + + return r; + } +} diff --git a/lib/sha1-stream.c b/lib/sha1-stream.c new file mode 100644 index 0000000..0ba0435 --- /dev/null +++ b/lib/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/lib/sha1.c b/lib/sha1.c new file mode 100644 index 0000000..79e50ba --- /dev/null +++ b/lib/sha1.c @@ -0,0 +1,361 @@ +/* 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 +#include +#include + +#include +#ifdef WORDS_BIGENDIAN +# define SWAP(n) (n) +#else +# define SWAP(n) bswap_32 (n) +#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) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Take a pointer to a 160 bit block of data (five 32 bit ints) and + initialize it to the start constants of the SHA1 algorithm. This + must be called before using hash in the call to sha1_hash. */ +void +sha1_init_ctx (struct sha1_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + ctx->E = 0xc3d2e1f0; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Copy the 4 byte value from v into the memory location pointed to by *cp, + If your architecture allows unaligned access this is equivalent to + * (uint32_t *) cp = v */ +static void +set_uint32 (char *cp, uint32_t v) +{ + memcpy (cp, &v, sizeof v); +} + +/* Put result from CTX in first 20 bytes following RESBUF. The result + must be in little endian byte order. */ +void * +sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) +{ + char *r = resbuf; + set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A)); + set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B)); + set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C)); + set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D)); + set_uint32 (r + 4 * sizeof ctx->E, SWAP (ctx->E)); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. */ +void * +sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3); + + memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + + /* Process last bytes. */ + sha1_process_block (ctx->buffer, size * 4, ctx); + + return sha1_read_ctx (ctx, resbuf); +} + +/* 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. */ +void * +sha1_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha1_ctx ctx; + + /* Initialize the computation context. */ + sha1_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + sha1_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha1_finish_ctx (&ctx, resblock); +} + +void +sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* 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); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#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) + { + sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + sha1_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + 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; + } +} + +/* --- Code below is the primary difference between md5.c and sha1.c --- */ + +/* SHA1 round constants */ +#define K1 0x5a827999 +#define K2 0x6ed9eba1 +#define K3 0x8f1bbcdc +#define K4 0xca62c1d6 + +/* Round functions. Note that F2 is the same as F4. */ +#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) +#define F2(B,C,D) (B ^ C ^ D) +#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) +#define F4(B,C,D) (B ^ C ^ D) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. + Most of this code comes from GnuPG's cipher/sha1.c. */ + +void +sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) +{ + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t x[16]; + uint32_t a = ctx->A; + uint32_t b = ctx->B; + uint32_t c = ctx->C; + uint32_t d = ctx->D; + uint32_t e = ctx->E; + uint32_t lolen = len; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += lolen; + ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); + +#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) + +#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ + ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ + , (x[I&0x0f] = rol(tm, 1)) ) + +#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ + + F( B, C, D ) \ + + K \ + + M; \ + B = rol( B, 30 ); \ + } while(0) + + while (words < endp) + { + uint32_t tm; + int t; + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + R( a, b, c, d, e, F1, K1, x[ 0] ); + R( e, a, b, c, d, F1, K1, x[ 1] ); + R( d, e, a, b, c, F1, K1, x[ 2] ); + R( c, d, e, a, b, F1, K1, x[ 3] ); + R( b, c, d, e, a, F1, K1, x[ 4] ); + R( a, b, c, d, e, F1, K1, x[ 5] ); + R( e, a, b, c, d, F1, K1, x[ 6] ); + R( d, e, a, b, c, F1, K1, x[ 7] ); + R( c, d, e, a, b, F1, K1, x[ 8] ); + R( b, c, d, e, a, F1, K1, x[ 9] ); + R( a, b, c, d, e, F1, K1, x[10] ); + R( e, a, b, c, d, F1, K1, x[11] ); + R( d, e, a, b, c, F1, K1, x[12] ); + R( c, d, e, a, b, F1, K1, x[13] ); + R( b, c, d, e, a, F1, K1, x[14] ); + R( a, b, c, d, e, F1, K1, x[15] ); + R( e, a, b, c, d, F1, K1, M(16) ); + R( d, e, a, b, c, F1, K1, M(17) ); + R( c, d, e, a, b, F1, K1, M(18) ); + R( b, c, d, e, a, F1, K1, M(19) ); + R( a, b, c, d, e, F2, K2, M(20) ); + R( e, a, b, c, d, F2, K2, M(21) ); + R( d, e, a, b, c, F2, K2, M(22) ); + R( c, d, e, a, b, F2, K2, M(23) ); + R( b, c, d, e, a, F2, K2, M(24) ); + R( a, b, c, d, e, F2, K2, M(25) ); + R( e, a, b, c, d, F2, K2, M(26) ); + R( d, e, a, b, c, F2, K2, M(27) ); + R( c, d, e, a, b, F2, K2, M(28) ); + R( b, c, d, e, a, F2, K2, M(29) ); + R( a, b, c, d, e, F2, K2, M(30) ); + R( e, a, b, c, d, F2, K2, M(31) ); + R( d, e, a, b, c, F2, K2, M(32) ); + R( c, d, e, a, b, F2, K2, M(33) ); + R( b, c, d, e, a, F2, K2, M(34) ); + R( a, b, c, d, e, F2, K2, M(35) ); + R( e, a, b, c, d, F2, K2, M(36) ); + R( d, e, a, b, c, F2, K2, M(37) ); + R( c, d, e, a, b, F2, K2, M(38) ); + R( b, c, d, e, a, F2, K2, M(39) ); + R( a, b, c, d, e, F3, K3, M(40) ); + R( e, a, b, c, d, F3, K3, M(41) ); + R( d, e, a, b, c, F3, K3, M(42) ); + R( c, d, e, a, b, F3, K3, M(43) ); + R( b, c, d, e, a, F3, K3, M(44) ); + R( a, b, c, d, e, F3, K3, M(45) ); + R( e, a, b, c, d, F3, K3, M(46) ); + R( d, e, a, b, c, F3, K3, M(47) ); + R( c, d, e, a, b, F3, K3, M(48) ); + R( b, c, d, e, a, F3, K3, M(49) ); + R( a, b, c, d, e, F3, K3, M(50) ); + R( e, a, b, c, d, F3, K3, M(51) ); + R( d, e, a, b, c, F3, K3, M(52) ); + R( c, d, e, a, b, F3, K3, M(53) ); + R( b, c, d, e, a, F3, K3, M(54) ); + R( a, b, c, d, e, F3, K3, M(55) ); + R( e, a, b, c, d, F3, K3, M(56) ); + R( d, e, a, b, c, F3, K3, M(57) ); + R( c, d, e, a, b, F3, K3, M(58) ); + R( b, c, d, e, a, F3, K3, M(59) ); + R( a, b, c, d, e, F4, K4, M(60) ); + R( e, a, b, c, d, F4, K4, M(61) ); + R( d, e, a, b, c, F4, K4, M(62) ); + R( c, d, e, a, b, F4, K4, M(63) ); + R( b, c, d, e, a, F4, K4, M(64) ); + R( a, b, c, d, e, F4, K4, M(65) ); + R( e, a, b, c, d, F4, K4, M(66) ); + R( d, e, a, b, c, F4, K4, M(67) ); + R( c, d, e, a, b, F4, K4, M(68) ); + R( b, c, d, e, a, F4, K4, M(69) ); + R( a, b, c, d, e, F4, K4, M(70) ); + R( e, a, b, c, d, F4, K4, M(71) ); + R( d, e, a, b, c, F4, K4, M(72) ); + R( c, d, e, a, b, F4, K4, M(73) ); + R( b, c, d, e, a, F4, K4, M(74) ); + R( a, b, c, d, e, F4, K4, M(75) ); + R( e, a, b, c, d, F4, K4, M(76) ); + R( d, e, a, b, c, F4, K4, M(77) ); + R( c, d, e, a, b, F4, K4, M(78) ); + R( b, c, d, e, a, F4, K4, M(79) ); + + a = ctx->A += a; + b = ctx->B += b; + c = ctx->C += c; + d = ctx->D += d; + e = ctx->E += e; + } +} + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sha1.h b/lib/sha1.h new file mode 100644 index 0000000..098678d --- /dev/null +++ b/lib/sha1.h @@ -0,0 +1,112 @@ +/* Declarations of functions and data types used for SHA1 sum + library functions. + Copyright (C) 2000-2001, 2003, 2005-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 . */ + +#ifndef SHA1_H +# define SHA1_H 1 + +# include +# include + +# if HAVE_OPENSSL_SHA1 +# include +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +# 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 +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + uint32_t E; + + uint32_t total[2]; + 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); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void sha1_process_block (const void *buffer, size_t len, + struct sha1_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void sha1_process_bytes (const void *buffer, size_t len, + struct sha1_ctx *ctx); + +/* Process the remaining bytes in the buffer and 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_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 *restrict resbuf); + + +/* 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 *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/lib/sha256-stream.c b/lib/sha256-stream.c new file mode 100644 index 0000000..c2e6398 --- /dev/null +++ b/lib/sha256-stream.c @@ -0,0 +1,145 @@ +/* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or + memory blocks according to the NIST specification FIPS-180-2. + + Copyright (C) 2005-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 David Madore, considerably copypasting from + Scott G. Miller's sha1.c +*/ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_SHA256 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "sha256.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 message digest for bytes read from STREAM using algorithm ALG. + Write the message digest into RESBLOCK, which contains HASHLEN bytes. + The initial and finishing operations are INIT_CTX and FINISH_CTX. + Return zero if and only if successful. */ +static int +shaxxx_stream (FILE *stream, char const *alg, void *resblock, + ssize_t hashlen, void (*init_ctx) (struct sha256_ctx *), + void *(*finish_ctx) (struct sha256_ctx *, void *)) +{ + switch (afalg_stream (stream, alg, resblock, hashlen)) + { + case 0: return 0; + case -EIO: return 1; + } + + char *buffer = malloc (BLOCKSIZE + 72); + if (!buffer) + return 1; + + struct sha256_ctx ctx; + 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 + */ + sha256_process_block (buffer, BLOCKSIZE, &ctx); + } + + process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + sha256_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + finish_ctx (&ctx, resblock); + free (buffer); + return 0; +} + +int +sha256_stream (FILE *stream, void *resblock) +{ + return shaxxx_stream (stream, "sha256", resblock, SHA256_DIGEST_SIZE, + sha256_init_ctx, sha256_finish_ctx); +} + +int +sha224_stream (FILE *stream, void *resblock) +{ + return shaxxx_stream (stream, "sha224", resblock, SHA224_DIGEST_SIZE, + sha224_init_ctx, sha224_finish_ctx); +} + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sha256.c b/lib/sha256.c new file mode 100644 index 0000000..c9ca618 --- /dev/null +++ b/lib/sha256.c @@ -0,0 +1,433 @@ +/* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or + memory blocks according to the NIST specification FIPS-180-2. + + Copyright (C) 2005-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 David Madore, considerably copypasting from + Scott G. Miller's sha1.c +*/ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_SHA256 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "sha256.h" + +#include +#include +#include + +#include +#ifdef WORDS_BIGENDIAN +# define SWAP(n) (n) +#else +# define SWAP(n) bswap_32 (n) +#endif + +#if ! HAVE_OPENSSL_SHA256 + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* + Takes a pointer to a 256 bit block of data (eight 32 bit ints) and + initializes it to the start constants of the SHA256 algorithm. This + must be called before using hash in the call to sha256_hash +*/ +void +sha256_init_ctx (struct sha256_ctx *ctx) +{ + ctx->state[0] = 0x6a09e667UL; + ctx->state[1] = 0xbb67ae85UL; + ctx->state[2] = 0x3c6ef372UL; + ctx->state[3] = 0xa54ff53aUL; + ctx->state[4] = 0x510e527fUL; + ctx->state[5] = 0x9b05688cUL; + ctx->state[6] = 0x1f83d9abUL; + ctx->state[7] = 0x5be0cd19UL; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +void +sha224_init_ctx (struct sha256_ctx *ctx) +{ + ctx->state[0] = 0xc1059ed8UL; + ctx->state[1] = 0x367cd507UL; + ctx->state[2] = 0x3070dd17UL; + ctx->state[3] = 0xf70e5939UL; + ctx->state[4] = 0xffc00b31UL; + ctx->state[5] = 0x68581511UL; + ctx->state[6] = 0x64f98fa7UL; + ctx->state[7] = 0xbefa4fa4UL; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Copy the value from v into the memory location pointed to by *CP, + If your architecture allows unaligned access, this is equivalent to + * (__typeof__ (v) *) cp = v */ +static void +set_uint32 (char *cp, uint32_t v) +{ + memcpy (cp, &v, sizeof v); +} + +/* Put result from CTX in first 32 bytes following RESBUF. + The result must be in little endian byte order. */ +void * +sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf) +{ + int i; + char *r = resbuf; + + for (i = 0; i < 8; i++) + set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + + return resbuf; +} + +void * +sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf) +{ + int i; + char *r = resbuf; + + for (i = 0; i < 7; i++) + set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. */ +static void +sha256_conclude_ctx (struct sha256_ctx *ctx) +{ + /* Take yet unprocessed bytes into account. */ + size_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + /* Put the 64-bit file length in *bits* at the end of the buffer. + Use set_uint32 rather than a simple assignment, to avoid risk of + unaligned access. */ + set_uint32 ((char *) &ctx->buffer[size - 2], + SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29))); + set_uint32 ((char *) &ctx->buffer[size - 1], + SWAP (ctx->total[0] << 3)); + + memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); + + /* Process last bytes. */ + sha256_process_block (ctx->buffer, size * 4, ctx); +} + +void * +sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) +{ + sha256_conclude_ctx (ctx); + return sha256_read_ctx (ctx, resbuf); +} + +void * +sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf) +{ + sha256_conclude_ctx (ctx); + return sha224_read_ctx (ctx, resbuf); +} + +/* Compute SHA256 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. */ +void * +sha256_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha256_ctx ctx; + + /* Initialize the computation context. */ + sha256_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + sha256_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha256_finish_ctx (&ctx, resblock); +} + +void * +sha224_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha256_ctx ctx; + + /* Initialize the computation context. */ + sha224_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + sha256_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha224_finish_ctx (&ctx, resblock); +} + +void +sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* 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); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#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) + { + sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + sha256_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + sha256_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; + } +} + +/* --- Code below is the primary difference between sha1.c and sha256.c --- */ + +/* SHA256 round constants */ +#define K(I) sha256_round_constants[I] +static const uint32_t sha256_round_constants[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, +}; + +/* Round functions. */ +#define F2(A,B,C) ( ( A & B ) | ( C & ( A | B ) ) ) +#define F1(E,F,G) ( G ^ ( E & ( F ^ G ) ) ) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. + Most of this code comes from GnuPG's cipher/sha1.c. */ + +void +sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) +{ + const uint32_t *words = buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t x[16]; + uint32_t a = ctx->state[0]; + uint32_t b = ctx->state[1]; + uint32_t c = ctx->state[2]; + uint32_t d = ctx->state[3]; + uint32_t e = ctx->state[4]; + uint32_t f = ctx->state[5]; + uint32_t g = ctx->state[6]; + uint32_t h = ctx->state[7]; + uint32_t lolen = len; + + /* First increment the byte count. FIPS PUB 180-2 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += lolen; + ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen); + +#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define S0(x) (rol(x,25)^rol(x,14)^(x>>3)) +#define S1(x) (rol(x,15)^rol(x,13)^(x>>10)) +#define SS0(x) (rol(x,30)^rol(x,19)^rol(x,10)) +#define SS1(x) (rol(x,26)^rol(x,21)^rol(x,7)) + +#define M(I) ( tm = S1(x[(I-2)&0x0f]) + x[(I-7)&0x0f] \ + + S0(x[(I-15)&0x0f]) + x[I&0x0f] \ + , x[I&0x0f] = tm ) + +#define R(A,B,C,D,E,F,G,H,K,M) do { t0 = SS0(A) + F2(A,B,C); \ + t1 = H + SS1(E) \ + + F1(E,F,G) \ + + K \ + + M; \ + D += t1; H = t0 + t1; \ + } while(0) + + while (words < endp) + { + uint32_t tm; + uint32_t t0, t1; + int t; + /* FIXME: see sha1.c for a better implementation. */ + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + R( a, b, c, d, e, f, g, h, K( 0), x[ 0] ); + R( h, a, b, c, d, e, f, g, K( 1), x[ 1] ); + R( g, h, a, b, c, d, e, f, K( 2), x[ 2] ); + R( f, g, h, a, b, c, d, e, K( 3), x[ 3] ); + R( e, f, g, h, a, b, c, d, K( 4), x[ 4] ); + R( d, e, f, g, h, a, b, c, K( 5), x[ 5] ); + R( c, d, e, f, g, h, a, b, K( 6), x[ 6] ); + R( b, c, d, e, f, g, h, a, K( 7), x[ 7] ); + R( a, b, c, d, e, f, g, h, K( 8), x[ 8] ); + R( h, a, b, c, d, e, f, g, K( 9), x[ 9] ); + R( g, h, a, b, c, d, e, f, K(10), x[10] ); + R( f, g, h, a, b, c, d, e, K(11), x[11] ); + R( e, f, g, h, a, b, c, d, K(12), x[12] ); + R( d, e, f, g, h, a, b, c, K(13), x[13] ); + R( c, d, e, f, g, h, a, b, K(14), x[14] ); + R( b, c, d, e, f, g, h, a, K(15), x[15] ); + R( a, b, c, d, e, f, g, h, K(16), M(16) ); + R( h, a, b, c, d, e, f, g, K(17), M(17) ); + R( g, h, a, b, c, d, e, f, K(18), M(18) ); + R( f, g, h, a, b, c, d, e, K(19), M(19) ); + R( e, f, g, h, a, b, c, d, K(20), M(20) ); + R( d, e, f, g, h, a, b, c, K(21), M(21) ); + R( c, d, e, f, g, h, a, b, K(22), M(22) ); + R( b, c, d, e, f, g, h, a, K(23), M(23) ); + R( a, b, c, d, e, f, g, h, K(24), M(24) ); + R( h, a, b, c, d, e, f, g, K(25), M(25) ); + R( g, h, a, b, c, d, e, f, K(26), M(26) ); + R( f, g, h, a, b, c, d, e, K(27), M(27) ); + R( e, f, g, h, a, b, c, d, K(28), M(28) ); + R( d, e, f, g, h, a, b, c, K(29), M(29) ); + R( c, d, e, f, g, h, a, b, K(30), M(30) ); + R( b, c, d, e, f, g, h, a, K(31), M(31) ); + R( a, b, c, d, e, f, g, h, K(32), M(32) ); + R( h, a, b, c, d, e, f, g, K(33), M(33) ); + R( g, h, a, b, c, d, e, f, K(34), M(34) ); + R( f, g, h, a, b, c, d, e, K(35), M(35) ); + R( e, f, g, h, a, b, c, d, K(36), M(36) ); + R( d, e, f, g, h, a, b, c, K(37), M(37) ); + R( c, d, e, f, g, h, a, b, K(38), M(38) ); + R( b, c, d, e, f, g, h, a, K(39), M(39) ); + R( a, b, c, d, e, f, g, h, K(40), M(40) ); + R( h, a, b, c, d, e, f, g, K(41), M(41) ); + R( g, h, a, b, c, d, e, f, K(42), M(42) ); + R( f, g, h, a, b, c, d, e, K(43), M(43) ); + R( e, f, g, h, a, b, c, d, K(44), M(44) ); + R( d, e, f, g, h, a, b, c, K(45), M(45) ); + R( c, d, e, f, g, h, a, b, K(46), M(46) ); + R( b, c, d, e, f, g, h, a, K(47), M(47) ); + R( a, b, c, d, e, f, g, h, K(48), M(48) ); + R( h, a, b, c, d, e, f, g, K(49), M(49) ); + R( g, h, a, b, c, d, e, f, K(50), M(50) ); + R( f, g, h, a, b, c, d, e, K(51), M(51) ); + R( e, f, g, h, a, b, c, d, K(52), M(52) ); + R( d, e, f, g, h, a, b, c, K(53), M(53) ); + R( c, d, e, f, g, h, a, b, K(54), M(54) ); + R( b, c, d, e, f, g, h, a, K(55), M(55) ); + R( a, b, c, d, e, f, g, h, K(56), M(56) ); + R( h, a, b, c, d, e, f, g, K(57), M(57) ); + R( g, h, a, b, c, d, e, f, K(58), M(58) ); + R( f, g, h, a, b, c, d, e, K(59), M(59) ); + R( e, f, g, h, a, b, c, d, K(60), M(60) ); + R( d, e, f, g, h, a, b, c, K(61), M(61) ); + R( c, d, e, f, g, h, a, b, K(62), M(62) ); + R( b, c, d, e, f, g, h, a, K(63), M(63) ); + + a = ctx->state[0] += a; + b = ctx->state[1] += b; + c = ctx->state[2] += c; + d = ctx->state[3] += d; + e = ctx->state[4] += e; + f = ctx->state[5] += f; + g = ctx->state[6] += g; + h = ctx->state[7] += h; + } +} + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sha256.h b/lib/sha256.h new file mode 100644 index 0000000..dc9d87e --- /dev/null +++ b/lib/sha256.h @@ -0,0 +1,118 @@ +/* Declarations of functions and data types used for SHA256 and SHA224 sum + library functions. + Copyright (C) 2005-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 . */ + +#ifndef SHA256_H +# define SHA256_H 1 + +# include +# include + +# if HAVE_OPENSSL_SHA256 +# include +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +enum { SHA224_DIGEST_SIZE = 224 / 8 }; +enum { SHA256_DIGEST_SIZE = 256 / 8 }; + +# if HAVE_OPENSSL_SHA256 +# define GL_OPENSSL_NAME 224 +# include "gl_openssl.h" +# define GL_OPENSSL_NAME 256 +# include "gl_openssl.h" +# else +/* Structure to save state of computation between the single steps. */ +struct sha256_ctx +{ + uint32_t state[8]; + + uint32_t total[2]; + size_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 sha256_init_ctx (struct sha256_ctx *ctx); +extern void sha224_init_ctx (struct sha256_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void sha256_process_block (const void *buffer, size_t len, + struct sha256_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void sha256_process_bytes (const void *buffer, size_t len, + struct sha256_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 32 (28) 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 *sha256_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf); +extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf); + + +/* Put result from CTX in first 32 (28) 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 *sha256_read_ctx (const struct sha256_ctx *ctx, + void *restrict resbuf); +extern void *sha224_read_ctx (const struct sha256_ctx *ctx, + void *restrict resbuf); + + +/* Compute SHA256 (SHA224) 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 *sha256_buffer (const char *buffer, size_t len, + void *restrict resblock); +extern void *sha224_buffer (const char *buffer, size_t len, + void *restrict resblock); + +# endif + +/* Compute SHA256 (SHA224) 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 32 (28) bytes + beginning at RESBLOCK. */ +extern int sha256_stream (FILE *stream, void *resblock); +extern int sha224_stream (FILE *stream, void *resblock); + + +# ifdef __cplusplus +} +# endif + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sha512-stream.c b/lib/sha512-stream.c new file mode 100644 index 0000000..78fa081 --- /dev/null +++ b/lib/sha512-stream.c @@ -0,0 +1,145 @@ +/* sha512.c - Functions to compute SHA512 and SHA384 message digest of files or + memory blocks according to the NIST specification FIPS-180-2. + + Copyright (C) 2005-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 David Madore, considerably copypasting from + Scott G. Miller's sha1.c +*/ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_SHA512 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "sha512.h" + +#include + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#include "af_alg.h" + +#define BLOCKSIZE 32768 +#if BLOCKSIZE % 128 != 0 +# error "invalid BLOCKSIZE" +#endif + +/* Compute message digest for bytes read from STREAM using algorithm ALG. + Write the message digest into RESBLOCK, which contains HASHLEN bytes. + The initial and finishing operations are INIT_CTX and FINISH_CTX. + Return zero if and only if successful. */ +static int +shaxxx_stream (FILE *stream, char const *alg, void *resblock, + ssize_t hashlen, void (*init_ctx) (struct sha512_ctx *), + void *(*finish_ctx) (struct sha512_ctx *, void *)) +{ + switch (afalg_stream (stream, alg, resblock, hashlen)) + { + case 0: return 0; + case -EIO: return 1; + } + + char *buffer = malloc (BLOCKSIZE + 72); + if (!buffer) + return 1; + + struct sha512_ctx ctx; + 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 % 128 == 0 + */ + sha512_process_block (buffer, BLOCKSIZE, &ctx); + } + + process_partial_block:; + + /* Process any remaining bytes. */ + if (sum > 0) + sha512_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + finish_ctx (&ctx, resblock); + free (buffer); + return 0; +} + +int +sha512_stream (FILE *stream, void *resblock) +{ + return shaxxx_stream (stream, "sha512", resblock, SHA512_DIGEST_SIZE, + sha512_init_ctx, sha512_finish_ctx); +} + +int +sha384_stream (FILE *stream, void *resblock) +{ + return shaxxx_stream (stream, "sha384", resblock, SHA384_DIGEST_SIZE, + sha384_init_ctx, sha384_finish_ctx); +} + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sha512.c b/lib/sha512.c new file mode 100644 index 0000000..6776bb4 --- /dev/null +++ b/lib/sha512.c @@ -0,0 +1,478 @@ +/* sha512.c - Functions to compute SHA512 and SHA384 message digest of files or + memory blocks according to the NIST specification FIPS-180-2. + + Copyright (C) 2005-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 David Madore, considerably copypasting from + Scott G. Miller's sha1.c +*/ + +#include + +/* Specification. */ +#if HAVE_OPENSSL_SHA512 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif +#include "sha512.h" + +#include +#include +#include + +#include +#ifdef WORDS_BIGENDIAN +# define SWAP(n) (n) +#else +# define SWAP(n) bswap_64 (n) +#endif + +#if ! HAVE_OPENSSL_SHA512 + +/* This array contains the bytes used to pad the buffer to the next + 128-byte boundary. */ +static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* + Takes a pointer to a 512 bit block of data (eight 64 bit ints) and + initializes it to the start constants of the SHA512 algorithm. This + must be called before using hash in the call to sha512_hash +*/ +void +sha512_init_ctx (struct sha512_ctx *ctx) +{ + ctx->state[0] = u64hilo (0x6a09e667, 0xf3bcc908); + ctx->state[1] = u64hilo (0xbb67ae85, 0x84caa73b); + ctx->state[2] = u64hilo (0x3c6ef372, 0xfe94f82b); + ctx->state[3] = u64hilo (0xa54ff53a, 0x5f1d36f1); + ctx->state[4] = u64hilo (0x510e527f, 0xade682d1); + ctx->state[5] = u64hilo (0x9b05688c, 0x2b3e6c1f); + ctx->state[6] = u64hilo (0x1f83d9ab, 0xfb41bd6b); + ctx->state[7] = u64hilo (0x5be0cd19, 0x137e2179); + + ctx->total[0] = ctx->total[1] = u64lo (0); + ctx->buflen = 0; +} + +void +sha384_init_ctx (struct sha512_ctx *ctx) +{ + ctx->state[0] = u64hilo (0xcbbb9d5d, 0xc1059ed8); + ctx->state[1] = u64hilo (0x629a292a, 0x367cd507); + ctx->state[2] = u64hilo (0x9159015a, 0x3070dd17); + ctx->state[3] = u64hilo (0x152fecd8, 0xf70e5939); + ctx->state[4] = u64hilo (0x67332667, 0xffc00b31); + ctx->state[5] = u64hilo (0x8eb44a87, 0x68581511); + ctx->state[6] = u64hilo (0xdb0c2e0d, 0x64f98fa7); + ctx->state[7] = u64hilo (0x47b5481d, 0xbefa4fa4); + + ctx->total[0] = ctx->total[1] = u64lo (0); + ctx->buflen = 0; +} + +/* Copy the value from V into the memory location pointed to by *CP, + If your architecture allows unaligned access, this is equivalent to + * (__typeof__ (v) *) cp = v */ +static void +set_uint64 (char *cp, u64 v) +{ + memcpy (cp, &v, sizeof v); +} + +/* Put result from CTX in first 64 bytes following RESBUF. + The result must be in little endian byte order. */ +void * +sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf) +{ + int i; + char *r = resbuf; + + for (i = 0; i < 8; i++) + set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + + return resbuf; +} + +void * +sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf) +{ + int i; + char *r = resbuf; + + for (i = 0; i < 6; i++) + set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i])); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. */ +static void +sha512_conclude_ctx (struct sha512_ctx *ctx) +{ + /* Take yet unprocessed bytes into account. */ + size_t bytes = ctx->buflen; + size_t size = (bytes < 112) ? 128 / 8 : 128 * 2 / 8; + + /* Now count remaining bytes. */ + ctx->total[0] = u64plus (ctx->total[0], u64lo (bytes)); + if (u64lt (ctx->total[0], u64lo (bytes))) + ctx->total[1] = u64plus (ctx->total[1], u64lo (1)); + + /* Put the 128-bit file length in *bits* at the end of the buffer. + Use set_uint64 rather than a simple assignment, to avoid risk of + unaligned access. */ + set_uint64 ((char *) &ctx->buffer[size - 2], + SWAP (u64or (u64shl (ctx->total[1], 3), + u64shr (ctx->total[0], 61)))); + set_uint64 ((char *) &ctx->buffer[size - 1], + SWAP (u64shl (ctx->total[0], 3))); + + memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 8 - bytes); + + /* Process last bytes. */ + sha512_process_block (ctx->buffer, size * 8, ctx); +} + +void * +sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) +{ + sha512_conclude_ctx (ctx); + return sha512_read_ctx (ctx, resbuf); +} + +void * +sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf) +{ + sha512_conclude_ctx (ctx); + return sha384_read_ctx (ctx, resbuf); +} + +/* Compute SHA512 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. */ +void * +sha512_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha512_ctx ctx; + + /* Initialize the computation context. */ + sha512_init_ctx (&ctx); + + /* Process whole buffer but last len % 128 bytes. */ + sha512_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha512_finish_ctx (&ctx, resblock); +} + +void * +sha384_buffer (const char *buffer, size_t len, void *resblock) +{ + struct sha512_ctx ctx; + + /* Initialize the computation context. */ + sha384_init_ctx (&ctx); + + /* Process whole buffer but last len % 128 bytes. */ + sha512_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return sha384_finish_ctx (&ctx, resblock); +} + +void +sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 256 - left_over > len ? len : 256 - left_over; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 128) + { + sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx); + + ctx->buflen &= 127; + /* The regions in the following copy operation cannot overlap, + because ctx->buflen < 128 ≤ (left_over + add) & ~127. */ + memcpy (ctx->buffer, + &((char *) ctx->buffer)[(left_over + add) & ~127], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 128) + { +#if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned) +# define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (u64) != 0) + if (UNALIGNED_P (buffer)) + while (len > 128) + { + sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, ctx); + buffer = (const char *) buffer + 128; + len -= 128; + } + else +#endif + { + sha512_process_block (buffer, len & ~127, ctx); + buffer = (const char *) buffer + (len & ~127); + len &= 127; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 128) + { + sha512_process_block (ctx->buffer, 128, ctx); + left_over -= 128; + /* The regions in the following copy operation cannot overlap, + because left_over ≤ 128. */ + memcpy (ctx->buffer, &ctx->buffer[16], left_over); + } + ctx->buflen = left_over; + } +} + +/* --- Code below is the primary difference between sha1.c and sha512.c --- */ + +/* SHA512 round constants */ +#define K(I) sha512_round_constants[I] +static u64 const sha512_round_constants[80] = { + u64init (0x428a2f98, 0xd728ae22), u64init (0x71374491, 0x23ef65cd), + u64init (0xb5c0fbcf, 0xec4d3b2f), u64init (0xe9b5dba5, 0x8189dbbc), + u64init (0x3956c25b, 0xf348b538), u64init (0x59f111f1, 0xb605d019), + u64init (0x923f82a4, 0xaf194f9b), u64init (0xab1c5ed5, 0xda6d8118), + u64init (0xd807aa98, 0xa3030242), u64init (0x12835b01, 0x45706fbe), + u64init (0x243185be, 0x4ee4b28c), u64init (0x550c7dc3, 0xd5ffb4e2), + u64init (0x72be5d74, 0xf27b896f), u64init (0x80deb1fe, 0x3b1696b1), + u64init (0x9bdc06a7, 0x25c71235), u64init (0xc19bf174, 0xcf692694), + u64init (0xe49b69c1, 0x9ef14ad2), u64init (0xefbe4786, 0x384f25e3), + u64init (0x0fc19dc6, 0x8b8cd5b5), u64init (0x240ca1cc, 0x77ac9c65), + u64init (0x2de92c6f, 0x592b0275), u64init (0x4a7484aa, 0x6ea6e483), + u64init (0x5cb0a9dc, 0xbd41fbd4), u64init (0x76f988da, 0x831153b5), + u64init (0x983e5152, 0xee66dfab), u64init (0xa831c66d, 0x2db43210), + u64init (0xb00327c8, 0x98fb213f), u64init (0xbf597fc7, 0xbeef0ee4), + u64init (0xc6e00bf3, 0x3da88fc2), u64init (0xd5a79147, 0x930aa725), + u64init (0x06ca6351, 0xe003826f), u64init (0x14292967, 0x0a0e6e70), + u64init (0x27b70a85, 0x46d22ffc), u64init (0x2e1b2138, 0x5c26c926), + u64init (0x4d2c6dfc, 0x5ac42aed), u64init (0x53380d13, 0x9d95b3df), + u64init (0x650a7354, 0x8baf63de), u64init (0x766a0abb, 0x3c77b2a8), + u64init (0x81c2c92e, 0x47edaee6), u64init (0x92722c85, 0x1482353b), + u64init (0xa2bfe8a1, 0x4cf10364), u64init (0xa81a664b, 0xbc423001), + u64init (0xc24b8b70, 0xd0f89791), u64init (0xc76c51a3, 0x0654be30), + u64init (0xd192e819, 0xd6ef5218), u64init (0xd6990624, 0x5565a910), + u64init (0xf40e3585, 0x5771202a), u64init (0x106aa070, 0x32bbd1b8), + u64init (0x19a4c116, 0xb8d2d0c8), u64init (0x1e376c08, 0x5141ab53), + u64init (0x2748774c, 0xdf8eeb99), u64init (0x34b0bcb5, 0xe19b48a8), + u64init (0x391c0cb3, 0xc5c95a63), u64init (0x4ed8aa4a, 0xe3418acb), + u64init (0x5b9cca4f, 0x7763e373), u64init (0x682e6ff3, 0xd6b2b8a3), + u64init (0x748f82ee, 0x5defb2fc), u64init (0x78a5636f, 0x43172f60), + u64init (0x84c87814, 0xa1f0ab72), u64init (0x8cc70208, 0x1a6439ec), + u64init (0x90befffa, 0x23631e28), u64init (0xa4506ceb, 0xde82bde9), + u64init (0xbef9a3f7, 0xb2c67915), u64init (0xc67178f2, 0xe372532b), + u64init (0xca273ece, 0xea26619c), u64init (0xd186b8c7, 0x21c0c207), + u64init (0xeada7dd6, 0xcde0eb1e), u64init (0xf57d4f7f, 0xee6ed178), + u64init (0x06f067aa, 0x72176fba), u64init (0x0a637dc5, 0xa2c898a6), + u64init (0x113f9804, 0xbef90dae), u64init (0x1b710b35, 0x131c471b), + u64init (0x28db77f5, 0x23047d84), u64init (0x32caab7b, 0x40c72493), + u64init (0x3c9ebe0a, 0x15c9bebc), u64init (0x431d67c4, 0x9c100d4c), + u64init (0x4cc5d4be, 0xcb3e42b6), u64init (0x597f299c, 0xfc657e2a), + u64init (0x5fcb6fab, 0x3ad6faec), u64init (0x6c44198c, 0x4a475817), +}; + +/* Round functions. */ +#define F2(A, B, C) u64or (u64and (A, B), u64and (C, u64or (A, B))) +#define F1(E, F, G) u64xor (G, u64and (E, u64xor (F, G))) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 128 == 0. + Most of this code comes from GnuPG's cipher/sha1.c. */ + +void +sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) +{ + u64 const *words = buffer; + u64 const *endp = words + len / sizeof (u64); + u64 x[16]; + u64 a = ctx->state[0]; + u64 b = ctx->state[1]; + u64 c = ctx->state[2]; + u64 d = ctx->state[3]; + u64 e = ctx->state[4]; + u64 f = ctx->state[5]; + u64 g = ctx->state[6]; + u64 h = ctx->state[7]; + u64 lolen = u64size (len); + + /* First increment the byte count. FIPS PUB 180-2 specifies the possible + length of the file up to 2^128 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] = u64plus (ctx->total[0], lolen); + ctx->total[1] = u64plus (ctx->total[1], + u64plus (u64size (len >> 31 >> 31 >> 2), + u64lo (u64lt (ctx->total[0], lolen)))); + +#define S0(x) u64xor (u64rol(x, 63), u64xor (u64rol (x, 56), u64shr (x, 7))) +#define S1(x) u64xor (u64rol (x, 45), u64xor (u64rol (x, 3), u64shr (x, 6))) +#define SS0(x) u64xor (u64rol (x, 36), u64xor (u64rol (x, 30), u64rol (x, 25))) +#define SS1(x) u64xor (u64rol(x, 50), u64xor (u64rol (x, 46), u64rol (x, 23))) + +#define M(I) (x[(I) & 15] \ + = u64plus (x[(I) & 15], \ + u64plus (S1 (x[((I) - 2) & 15]), \ + u64plus (x[((I) - 7) & 15], \ + S0 (x[((I) - 15) & 15]))))) + +#define R(A, B, C, D, E, F, G, H, K, M) \ + do \ + { \ + u64 t0 = u64plus (SS0 (A), F2 (A, B, C)); \ + u64 t1 = \ + u64plus (H, u64plus (SS1 (E), \ + u64plus (F1 (E, F, G), u64plus (K, M)))); \ + D = u64plus (D, t1); \ + H = u64plus (t0, t1); \ + } \ + while (0) + + while (words < endp) + { + int t; + /* FIXME: see sha1.c for a better implementation. */ + for (t = 0; t < 16; t++) + { + x[t] = SWAP (*words); + words++; + } + + R( a, b, c, d, e, f, g, h, K( 0), x[ 0] ); + R( h, a, b, c, d, e, f, g, K( 1), x[ 1] ); + R( g, h, a, b, c, d, e, f, K( 2), x[ 2] ); + R( f, g, h, a, b, c, d, e, K( 3), x[ 3] ); + R( e, f, g, h, a, b, c, d, K( 4), x[ 4] ); + R( d, e, f, g, h, a, b, c, K( 5), x[ 5] ); + R( c, d, e, f, g, h, a, b, K( 6), x[ 6] ); + R( b, c, d, e, f, g, h, a, K( 7), x[ 7] ); + R( a, b, c, d, e, f, g, h, K( 8), x[ 8] ); + R( h, a, b, c, d, e, f, g, K( 9), x[ 9] ); + R( g, h, a, b, c, d, e, f, K(10), x[10] ); + R( f, g, h, a, b, c, d, e, K(11), x[11] ); + R( e, f, g, h, a, b, c, d, K(12), x[12] ); + R( d, e, f, g, h, a, b, c, K(13), x[13] ); + R( c, d, e, f, g, h, a, b, K(14), x[14] ); + R( b, c, d, e, f, g, h, a, K(15), x[15] ); + R( a, b, c, d, e, f, g, h, K(16), M(16) ); + R( h, a, b, c, d, e, f, g, K(17), M(17) ); + R( g, h, a, b, c, d, e, f, K(18), M(18) ); + R( f, g, h, a, b, c, d, e, K(19), M(19) ); + R( e, f, g, h, a, b, c, d, K(20), M(20) ); + R( d, e, f, g, h, a, b, c, K(21), M(21) ); + R( c, d, e, f, g, h, a, b, K(22), M(22) ); + R( b, c, d, e, f, g, h, a, K(23), M(23) ); + R( a, b, c, d, e, f, g, h, K(24), M(24) ); + R( h, a, b, c, d, e, f, g, K(25), M(25) ); + R( g, h, a, b, c, d, e, f, K(26), M(26) ); + R( f, g, h, a, b, c, d, e, K(27), M(27) ); + R( e, f, g, h, a, b, c, d, K(28), M(28) ); + R( d, e, f, g, h, a, b, c, K(29), M(29) ); + R( c, d, e, f, g, h, a, b, K(30), M(30) ); + R( b, c, d, e, f, g, h, a, K(31), M(31) ); + R( a, b, c, d, e, f, g, h, K(32), M(32) ); + R( h, a, b, c, d, e, f, g, K(33), M(33) ); + R( g, h, a, b, c, d, e, f, K(34), M(34) ); + R( f, g, h, a, b, c, d, e, K(35), M(35) ); + R( e, f, g, h, a, b, c, d, K(36), M(36) ); + R( d, e, f, g, h, a, b, c, K(37), M(37) ); + R( c, d, e, f, g, h, a, b, K(38), M(38) ); + R( b, c, d, e, f, g, h, a, K(39), M(39) ); + R( a, b, c, d, e, f, g, h, K(40), M(40) ); + R( h, a, b, c, d, e, f, g, K(41), M(41) ); + R( g, h, a, b, c, d, e, f, K(42), M(42) ); + R( f, g, h, a, b, c, d, e, K(43), M(43) ); + R( e, f, g, h, a, b, c, d, K(44), M(44) ); + R( d, e, f, g, h, a, b, c, K(45), M(45) ); + R( c, d, e, f, g, h, a, b, K(46), M(46) ); + R( b, c, d, e, f, g, h, a, K(47), M(47) ); + R( a, b, c, d, e, f, g, h, K(48), M(48) ); + R( h, a, b, c, d, e, f, g, K(49), M(49) ); + R( g, h, a, b, c, d, e, f, K(50), M(50) ); + R( f, g, h, a, b, c, d, e, K(51), M(51) ); + R( e, f, g, h, a, b, c, d, K(52), M(52) ); + R( d, e, f, g, h, a, b, c, K(53), M(53) ); + R( c, d, e, f, g, h, a, b, K(54), M(54) ); + R( b, c, d, e, f, g, h, a, K(55), M(55) ); + R( a, b, c, d, e, f, g, h, K(56), M(56) ); + R( h, a, b, c, d, e, f, g, K(57), M(57) ); + R( g, h, a, b, c, d, e, f, K(58), M(58) ); + R( f, g, h, a, b, c, d, e, K(59), M(59) ); + R( e, f, g, h, a, b, c, d, K(60), M(60) ); + R( d, e, f, g, h, a, b, c, K(61), M(61) ); + R( c, d, e, f, g, h, a, b, K(62), M(62) ); + R( b, c, d, e, f, g, h, a, K(63), M(63) ); + R( a, b, c, d, e, f, g, h, K(64), M(64) ); + R( h, a, b, c, d, e, f, g, K(65), M(65) ); + R( g, h, a, b, c, d, e, f, K(66), M(66) ); + R( f, g, h, a, b, c, d, e, K(67), M(67) ); + R( e, f, g, h, a, b, c, d, K(68), M(68) ); + R( d, e, f, g, h, a, b, c, K(69), M(69) ); + R( c, d, e, f, g, h, a, b, K(70), M(70) ); + R( b, c, d, e, f, g, h, a, K(71), M(71) ); + R( a, b, c, d, e, f, g, h, K(72), M(72) ); + R( h, a, b, c, d, e, f, g, K(73), M(73) ); + R( g, h, a, b, c, d, e, f, K(74), M(74) ); + R( f, g, h, a, b, c, d, e, K(75), M(75) ); + R( e, f, g, h, a, b, c, d, K(76), M(76) ); + R( d, e, f, g, h, a, b, c, K(77), M(77) ); + R( c, d, e, f, g, h, a, b, K(78), M(78) ); + R( b, c, d, e, f, g, h, a, K(79), M(79) ); + + a = ctx->state[0] = u64plus (ctx->state[0], a); + b = ctx->state[1] = u64plus (ctx->state[1], b); + c = ctx->state[2] = u64plus (ctx->state[2], c); + d = ctx->state[3] = u64plus (ctx->state[3], d); + e = ctx->state[4] = u64plus (ctx->state[4], e); + f = ctx->state[5] = u64plus (ctx->state[5], f); + g = ctx->state[6] = u64plus (ctx->state[6], g); + h = ctx->state[7] = u64plus (ctx->state[7], h); + } +} + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sha512.h b/lib/sha512.h new file mode 100644 index 0000000..f38819f --- /dev/null +++ b/lib/sha512.h @@ -0,0 +1,121 @@ +/* Declarations of functions and data types used for SHA512 and SHA384 sum + library functions. + Copyright (C) 2005-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 . */ + +#ifndef SHA512_H +# define SHA512_H 1 + +# include +# include "u64.h" + +# if HAVE_OPENSSL_SHA512 +# include +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +enum { SHA384_DIGEST_SIZE = 384 / 8 }; +enum { SHA512_DIGEST_SIZE = 512 / 8 }; + +# if HAVE_OPENSSL_SHA512 +# define GL_OPENSSL_NAME 384 +# include "gl_openssl.h" +# define GL_OPENSSL_NAME 512 +# include "gl_openssl.h" +# else +/* Structure to save state of computation between the single steps. */ +struct sha512_ctx +{ + u64 state[8]; + + u64 total[2]; + size_t buflen; /* ≥ 0, ≤ 256 */ + u64 buffer[32]; /* 256 bytes; the first buflen bytes are in use */ +}; + +/* Initialize structure containing state of computation. */ +extern void sha512_init_ctx (struct sha512_ctx *ctx); +extern void sha384_init_ctx (struct sha512_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 128!!! */ +extern void sha512_process_block (const void *buffer, size_t len, + struct sha512_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 128. */ +extern void sha512_process_bytes (const void *buffer, size_t len, + struct sha512_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 64 (48) 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 *sha512_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); +extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); + + +/* Put result from CTX in first 64 (48) 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. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *sha512_read_ctx (const struct sha512_ctx *ctx, + void *restrict resbuf); +extern void *sha384_read_ctx (const struct sha512_ctx *ctx, + void *restrict resbuf); + + +/* Compute SHA512 (SHA384) 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 *sha512_buffer (const char *buffer, size_t len, + void *restrict resblock); +extern void *sha384_buffer (const char *buffer, size_t len, + void *restrict resblock); + +# endif + +/* Compute SHA512 (SHA384) 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 64 (48) bytes + beginning at RESBLOCK. */ +extern int sha512_stream (FILE *stream, void *resblock); +extern int sha384_stream (FILE *stream, void *resblock); + + +# ifdef __cplusplus +} +# endif + +#endif + +/* + * Hey Emacs! + * Local Variables: + * coding: utf-8 + * End: + */ diff --git a/lib/sig-handler.c b/lib/sig-handler.c new file mode 100644 index 0000000..0ab63ec --- /dev/null +++ b/lib/sig-handler.c @@ -0,0 +1,21 @@ +/* Convenience declarations when working with . + + 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 SIG_HANDLER_INLINE _GL_EXTERN_INLINE +#include "sig-handler.h" diff --git a/lib/sig-handler.h b/lib/sig-handler.h new file mode 100644 index 0000000..1ca8d54 --- /dev/null +++ b/lib/sig-handler.h @@ -0,0 +1,51 @@ +/* Convenience declarations when working with . + + 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 . */ + +#ifndef _GL_SIG_HANDLER_H +#define _GL_SIG_HANDLER_H + +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef SIG_HANDLER_INLINE +# define SIG_HANDLER_INLINE _GL_INLINE +#endif + +/* Convenience type when working with signal handlers. */ +typedef void (*sa_handler_t) (int); + +/* Return the handler of a signal, as a sa_handler_t value regardless + of its true type. The resulting function can be compared to + special values like SIG_IGN but it is not portable to call it. */ +SIG_HANDLER_INLINE sa_handler_t _GL_ATTRIBUTE_PURE +get_handler (struct sigaction const *a) +{ + /* POSIX says that special values like SIG_IGN can only occur when + action.sa_flags does not contain SA_SIGINFO. But in Linux 2.4, + for example, sa_sigaction and sa_handler are aliases and a signal + is ignored if sa_sigaction (after casting) equals SIG_IGN. In + this case, this implementation relies on the fact that the two + are aliases, and simply returns sa_handler. */ + return a->sa_handler; +} + +_GL_INLINE_HEADER_END + +#endif /* _GL_SIG_HANDLER_H */ diff --git a/lib/sigaction.c b/lib/sigaction.c new file mode 100644 index 0000000..953a6ca --- /dev/null +++ b/lib/sigaction.c @@ -0,0 +1,204 @@ +/* POSIX compatible signal blocking. + Copyright (C) 2008-2022 Free Software Foundation, Inc. + Written by Eric Blake , 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 + +#include +#include +#include + +/* This implementation of sigaction is tailored to native Windows behavior: + signal() has SysV semantics (ie. the handler is uninstalled before + it is invoked). This is an inherent data race if an asynchronous + signal is sent twice in a row before we can reinstall our handler, + but there's nothing we can do about it. Meanwhile, sigprocmask() + is not present, and while we can use the gnulib replacement to + provide critical sections, it too suffers from potential data races + in the face of an ill-timed asynchronous signal. And we compound + the situation by reading static storage in a signal handler, which + POSIX warns is not generically async-signal-safe. Oh well. + + Additionally: + - We don't implement SA_NOCLDSTOP or SA_NOCLDWAIT, because SIGCHLD + is not defined. + - We don't implement SA_ONSTACK, because sigaltstack() is not present. + - We ignore SA_RESTART, because blocking native Windows API calls are + not interrupted anyway when an asynchronous signal occurs, and the + MSVCRT runtime never sets errno to EINTR. + - We don't implement SA_SIGINFO because it is impossible to do so + portably. + + POSIX states that an application should not mix signal() and + sigaction(). We support the use of signal() within the gnulib + sigprocmask() substitute, but all other application code linked + with this module should stick with only sigaction(). */ + +/* Check some of our assumptions. */ +#if defined SIGCHLD || defined HAVE_SIGALTSTACK || defined HAVE_SIGINTERRUPT +# error "Revisit the assumptions made in the sigaction module" +#endif + +/* Out-of-range substitutes make a good fallback for uncatchable + signals. */ +#ifndef SIGKILL +# define SIGKILL (-1) +#endif +#ifndef SIGSTOP +# define SIGSTOP (-1) +#endif + +/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias + for the signal SIGABRT. Only one signal handler is stored for both + SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */ +#if defined _WIN32 && ! defined __CYGWIN__ +# undef SIGABRT_COMPAT +# define SIGABRT_COMPAT 6 +#endif + +/* A signal handler. */ +typedef void (*handler_t) (int signal); + +/* Set of current actions. If sa_handler for an entry is NULL, then + that signal is not currently handled by the sigaction handler. */ +static struct sigaction volatile action_array[NSIG] /* = 0 */; + +/* Signal handler that is installed for signals. */ +static void +sigaction_handler (int sig) +{ + handler_t handler; + sigset_t mask; + sigset_t oldmask; + int saved_errno = errno; + if (sig < 0 || NSIG <= sig || !action_array[sig].sa_handler) + { + /* Unexpected situation; be careful to avoid recursive abort. */ + if (sig == SIGABRT) + signal (SIGABRT, SIG_DFL); + abort (); + } + + /* Reinstall the signal handler when required; otherwise update the + bookkeeping so that the user's handler may call sigaction and get + accurate results. We know the signal isn't currently blocked, or + we wouldn't be in its handler, therefore we know that we are not + interrupting a sigaction() call. There is a race where any + asynchronous instance of the same signal occurring before we + reinstall the handler will trigger the default handler; oh + well. */ + handler = action_array[sig].sa_handler; + if ((action_array[sig].sa_flags & SA_RESETHAND) == 0) + signal (sig, sigaction_handler); + else + action_array[sig].sa_handler = NULL; + + /* Block appropriate signals. */ + mask = action_array[sig].sa_mask; + if ((action_array[sig].sa_flags & SA_NODEFER) == 0) + sigaddset (&mask, sig); + sigprocmask (SIG_BLOCK, &mask, &oldmask); + + /* Invoke the user's handler, then restore prior mask. */ + errno = saved_errno; + handler (sig); + saved_errno = errno; + sigprocmask (SIG_SETMASK, &oldmask, NULL); + errno = saved_errno; +} + +/* Change and/or query the action that will be taken on delivery of + signal SIG. If not NULL, ACT describes the new behavior. If not + NULL, OACT is set to the prior behavior. Return 0 on success, or + set errno and return -1 on failure. */ +int +sigaction (int sig, const struct sigaction *restrict act, + struct sigaction *restrict oact) +{ + sigset_t mask; + sigset_t oldmask; + int saved_errno; + + if (sig < 0 || NSIG <= sig || sig == SIGKILL || sig == SIGSTOP + || (act && act->sa_handler == SIG_ERR)) + { + errno = EINVAL; + return -1; + } + +#ifdef SIGABRT_COMPAT + if (sig == SIGABRT_COMPAT) + sig = SIGABRT; +#endif + + /* POSIX requires sigaction() to be async-signal-safe. In other + words, if an asynchronous signal can occur while we are anywhere + inside this function, the user's handler could then call + sigaction() recursively and expect consistent results. We meet + this rule by using sigprocmask to block all signals before + modifying any data structure that could be read from a signal + handler; this works since we know that the gnulib sigprocmask + replacement does not try to use sigaction() from its handler. */ + if (!act && !oact) + return 0; + sigfillset (&mask); + sigprocmask (SIG_BLOCK, &mask, &oldmask); + if (oact) + { + if (action_array[sig].sa_handler) + *oact = action_array[sig]; + else + { + /* Safe to change the handler at will here, since all + signals are currently blocked. */ + oact->sa_handler = signal (sig, SIG_DFL); + if (oact->sa_handler == SIG_ERR) + goto failure; + signal (sig, oact->sa_handler); + oact->sa_flags = SA_RESETHAND | SA_NODEFER; + sigemptyset (&oact->sa_mask); + } + } + + if (act) + { + /* Safe to install the handler before updating action_array, + since all signals are currently blocked. */ + if (act->sa_handler == SIG_DFL || act->sa_handler == SIG_IGN) + { + if (signal (sig, act->sa_handler) == SIG_ERR) + goto failure; + action_array[sig].sa_handler = NULL; + } + else + { + if (signal (sig, sigaction_handler) == SIG_ERR) + goto failure; + action_array[sig] = *act; + } + } + sigprocmask (SIG_SETMASK, &oldmask, NULL); + return 0; + + failure: + saved_errno = errno; + sigprocmask (SIG_SETMASK, &oldmask, NULL); + errno = saved_errno; + return -1; +} diff --git a/lib/signal.in.h b/lib/signal.in.h new file mode 100644 index 0000000..640b502 --- /dev/null +++ b/lib/signal.in.h @@ -0,0 +1,487 @@ +/* A GNU-like . + + 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_sig_atomic_t || defined __need_sigset_t || defined _GL_ALREADY_INCLUDING_SIGNAL_H || (defined _SIGNAL_H && !defined __SIZEOF_PTHREAD_MUTEX_T) +/* Special invocation convention: + - Inside glibc header files. + - On glibc systems we have a sequence of nested includes + -> -> . + In this situation, the functions are not yet declared, therefore we cannot + provide the C++ aliases. + - On glibc systems with GCC 4.3 we have a sequence of nested includes + -> -> -> . + In this situation, some of the functions are not yet declared, therefore + we cannot provide the C++ aliases. */ + +# @INCLUDE_NEXT@ @NEXT_SIGNAL_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_SIGNAL_H + +#define _GL_ALREADY_INCLUDING_SIGNAL_H + +/* Define pid_t, uid_t. + Also, mingw defines sigset_t not in , but in . + On Solaris 10, includes , which eventually includes + us; so include now, before the second inclusion guard. */ +#include + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_SIGNAL_H@ + +#undef _GL_ALREADY_INCLUDING_SIGNAL_H + +#ifndef _@GUARD_PREFIX@_SIGNAL_H +#define _@GUARD_PREFIX@_SIGNAL_H + +/* Mac OS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6, Android, + OS/2 kLIBC declare pthread_sigmask in , not in . + But avoid namespace pollution on glibc systems.*/ +#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \ + && ((defined __APPLE__ && defined __MACH__) \ + || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ \ + || defined __sun || defined __ANDROID__ || defined __KLIBC__) \ + && ! defined __GLIBC__ +# 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. */ + +/* On AIX, sig_atomic_t already includes volatile. C99 requires that + 'volatile sig_atomic_t' ignore the extra modifier, but C89 did not. + Hence, redefine this to a non-volatile type as needed. */ +#if ! @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@ +# if !GNULIB_defined_sig_atomic_t +typedef int rpl_sig_atomic_t; +# undef sig_atomic_t +# define sig_atomic_t rpl_sig_atomic_t +# define GNULIB_defined_sig_atomic_t 1 +# endif +#endif + +/* A set or mask of signals. */ +#if !@HAVE_SIGSET_T@ +# if !GNULIB_defined_sigset_t +typedef unsigned int sigset_t; +# define GNULIB_defined_sigset_t 1 +# endif +#endif + +/* Define sighandler_t, the type of signal handlers. A GNU extension. */ +#if !@HAVE_SIGHANDLER_T@ +# ifdef __cplusplus +extern "C" { +# endif +# if !GNULIB_defined_sighandler_t +typedef void (*sighandler_t) (int); +# define GNULIB_defined_sighandler_t 1 +# endif +# ifdef __cplusplus +} +# endif +#endif + + +#if @GNULIB_SIGNAL_H_SIGPIPE@ +# ifndef SIGPIPE +/* Define SIGPIPE to a value that does not overlap with other signals. */ +# define SIGPIPE 13 +# define GNULIB_defined_SIGPIPE 1 +/* To actually use SIGPIPE, you also need the gnulib modules 'sigprocmask', + 'write', 'stdio'. */ +# endif +#endif + + +/* Maximum signal number + 1. */ +#ifndef NSIG +# if defined __TANDEM +# define NSIG 32 +# endif +#endif + + +#if @GNULIB_PTHREAD_SIGMASK@ +# if @REPLACE_PTHREAD_SIGMASK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef pthread_sigmask +# define pthread_sigmask rpl_pthread_sigmask +# endif +_GL_FUNCDECL_RPL (pthread_sigmask, int, + (int how, + const sigset_t *restrict new_mask, + sigset_t *restrict old_mask)); +_GL_CXXALIAS_RPL (pthread_sigmask, int, + (int how, + const sigset_t *restrict new_mask, + sigset_t *restrict old_mask)); +# else +# if !(@HAVE_PTHREAD_SIGMASK@ || defined pthread_sigmask) +_GL_FUNCDECL_SYS (pthread_sigmask, int, + (int how, + const sigset_t *restrict new_mask, + sigset_t *restrict old_mask)); +# endif +_GL_CXXALIAS_SYS (pthread_sigmask, int, + (int how, + const sigset_t *restrict new_mask, + sigset_t *restrict old_mask)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (pthread_sigmask); +# endif +#elif defined GNULIB_POSIXCHECK +# undef pthread_sigmask +# if HAVE_RAW_DECL_PTHREAD_SIGMASK +_GL_WARN_ON_USE (pthread_sigmask, "pthread_sigmask is not portable - " + "use gnulib module pthread_sigmask for portability"); +# endif +#endif + + +#if @GNULIB_RAISE@ +# if @REPLACE_RAISE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef raise +# define raise rpl_raise +# endif +_GL_FUNCDECL_RPL (raise, int, (int sig)); +_GL_CXXALIAS_RPL (raise, int, (int sig)); +# else +# if !@HAVE_RAISE@ +_GL_FUNCDECL_SYS (raise, int, (int sig)); +# endif +_GL_CXXALIAS_SYS (raise, int, (int sig)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (raise); +# endif +#elif defined GNULIB_POSIXCHECK +# undef raise +/* Assume raise is always declared. */ +_GL_WARN_ON_USE (raise, "raise can crash on native Windows - " + "use gnulib module raise for portability"); +#endif + + +#if @GNULIB_SIGPROCMASK@ +# if !@HAVE_POSIX_SIGNALBLOCKING@ + +# ifndef GNULIB_defined_signal_blocking +# define GNULIB_defined_signal_blocking 1 +# endif + +/* Maximum signal number + 1. */ +# ifndef NSIG +# define NSIG 32 +# endif + +/* This code supports only 32 signals. */ +# if !GNULIB_defined_verify_NSIG_constraint +typedef int verify_NSIG_constraint[NSIG <= 32 ? 1 : -1]; +# define GNULIB_defined_verify_NSIG_constraint 1 +# endif + +# endif + +/* 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 __i386__ || defined __x86_64__)) +# undef sigaddset +# undef sigdelset +# undef sigemptyset +# undef sigfillset +# undef sigismember +#endif + +/* Test whether a given signal is contained in a signal set. */ +# if @HAVE_POSIX_SIGNALBLOCKING@ +/* This function is defined as a macro on Mac OS X. */ +# if defined __cplusplus && defined GNULIB_NAMESPACE +# undef sigismember +# endif +# else +_GL_FUNCDECL_SYS (sigismember, int, (const sigset_t *set, int sig) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (sigismember, int, (const sigset_t *set, int sig)); +_GL_CXXALIASWARN (sigismember); + +/* Initialize a signal set to the empty set. */ +# if @HAVE_POSIX_SIGNALBLOCKING@ +/* This function is defined as a macro on Mac OS X. */ +# if defined __cplusplus && defined GNULIB_NAMESPACE +# undef sigemptyset +# endif +# else +_GL_FUNCDECL_SYS (sigemptyset, int, (sigset_t *set) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (sigemptyset, int, (sigset_t *set)); +_GL_CXXALIASWARN (sigemptyset); + +/* Add a signal to a signal set. */ +# if @HAVE_POSIX_SIGNALBLOCKING@ +/* This function is defined as a macro on Mac OS X. */ +# if defined __cplusplus && defined GNULIB_NAMESPACE +# undef sigaddset +# endif +# else +_GL_FUNCDECL_SYS (sigaddset, int, (sigset_t *set, int sig) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (sigaddset, int, (sigset_t *set, int sig)); +_GL_CXXALIASWARN (sigaddset); + +/* Remove a signal from a signal set. */ +# if @HAVE_POSIX_SIGNALBLOCKING@ +/* This function is defined as a macro on Mac OS X. */ +# if defined __cplusplus && defined GNULIB_NAMESPACE +# undef sigdelset +# endif +# else +_GL_FUNCDECL_SYS (sigdelset, int, (sigset_t *set, int sig) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (sigdelset, int, (sigset_t *set, int sig)); +_GL_CXXALIASWARN (sigdelset); + +/* Fill a signal set with all possible signals. */ +# if @HAVE_POSIX_SIGNALBLOCKING@ +/* This function is defined as a macro on Mac OS X. */ +# if defined __cplusplus && defined GNULIB_NAMESPACE +# undef sigfillset +# endif +# else +_GL_FUNCDECL_SYS (sigfillset, int, (sigset_t *set) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (sigfillset, int, (sigset_t *set)); +_GL_CXXALIASWARN (sigfillset); + +/* Return the set of those blocked signals that are pending. */ +# if !@HAVE_POSIX_SIGNALBLOCKING@ +_GL_FUNCDECL_SYS (sigpending, int, (sigset_t *set) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (sigpending, int, (sigset_t *set)); +_GL_CXXALIASWARN (sigpending); + +/* If OLD_SET is not NULL, put the current set of blocked signals in *OLD_SET. + Then, if SET is not NULL, affect the current set of blocked signals by + combining it with *SET as indicated in OPERATION. + In this implementation, you are not allowed to change a signal handler + while the signal is blocked. */ +# if !@HAVE_POSIX_SIGNALBLOCKING@ +# define SIG_BLOCK 0 /* blocked_set = blocked_set | *set; */ +# define SIG_SETMASK 1 /* blocked_set = *set; */ +# define SIG_UNBLOCK 2 /* blocked_set = blocked_set & ~*set; */ +_GL_FUNCDECL_SYS (sigprocmask, int, + (int operation, + const sigset_t *restrict set, + sigset_t *restrict old_set)); +# endif +_GL_CXXALIAS_SYS (sigprocmask, int, + (int operation, + const sigset_t *restrict set, + sigset_t *restrict old_set)); +_GL_CXXALIASWARN (sigprocmask); + +/* Install the handler FUNC for signal SIG, and return the previous + handler. */ +# ifdef __cplusplus +extern "C" { +# endif +# if !GNULIB_defined_function_taking_int_returning_void_t +typedef void (*_gl_function_taking_int_returning_void_t) (int); +# define GNULIB_defined_function_taking_int_returning_void_t 1 +# endif +# ifdef __cplusplus +} +# endif +# if !@HAVE_POSIX_SIGNALBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define signal rpl_signal +# endif +_GL_FUNCDECL_RPL (signal, _gl_function_taking_int_returning_void_t, + (int sig, _gl_function_taking_int_returning_void_t func)); +_GL_CXXALIAS_RPL (signal, _gl_function_taking_int_returning_void_t, + (int sig, _gl_function_taking_int_returning_void_t func)); +# else +/* On OpenBSD, the declaration of 'signal' may not be present at this point, + because it occurs in , not directly. */ +# if defined __OpenBSD__ +_GL_FUNCDECL_SYS (signal, _gl_function_taking_int_returning_void_t, + (int sig, _gl_function_taking_int_returning_void_t func)); +# endif +_GL_CXXALIAS_SYS (signal, _gl_function_taking_int_returning_void_t, + (int sig, _gl_function_taking_int_returning_void_t func)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (signal); +# endif + +# if !@HAVE_POSIX_SIGNALBLOCKING@ && GNULIB_defined_SIGPIPE +/* Raise signal SIGPIPE. */ +_GL_EXTERN_C int _gl_raise_SIGPIPE (void); +# endif + +#elif defined GNULIB_POSIXCHECK +# undef sigaddset +# if HAVE_RAW_DECL_SIGADDSET +_GL_WARN_ON_USE (sigaddset, "sigaddset is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +# undef sigdelset +# if HAVE_RAW_DECL_SIGDELSET +_GL_WARN_ON_USE (sigdelset, "sigdelset is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +# undef sigemptyset +# if HAVE_RAW_DECL_SIGEMPTYSET +_GL_WARN_ON_USE (sigemptyset, "sigemptyset is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +# undef sigfillset +# if HAVE_RAW_DECL_SIGFILLSET +_GL_WARN_ON_USE (sigfillset, "sigfillset is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +# undef sigismember +# if HAVE_RAW_DECL_SIGISMEMBER +_GL_WARN_ON_USE (sigismember, "sigismember is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +# undef sigpending +# if HAVE_RAW_DECL_SIGPENDING +_GL_WARN_ON_USE (sigpending, "sigpending is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +# undef sigprocmask +# if HAVE_RAW_DECL_SIGPROCMASK +_GL_WARN_ON_USE (sigprocmask, "sigprocmask is unportable - " + "use the gnulib module sigprocmask for portability"); +# endif +#endif /* @GNULIB_SIGPROCMASK@ */ + + +#if @GNULIB_SIGACTION@ +# if !@HAVE_SIGACTION@ + +# if !@HAVE_SIGINFO_T@ + +# if !GNULIB_defined_siginfo_types + +/* Present to allow compilation, but unsupported by gnulib. */ +union sigval +{ + int sival_int; + void *sival_ptr; +}; + +/* Present to allow compilation, but unsupported by gnulib. */ +struct siginfo_t +{ + int si_signo; + int si_code; + int si_errno; + pid_t si_pid; + uid_t si_uid; + void *si_addr; + int si_status; + long si_band; + union sigval si_value; +}; +typedef struct siginfo_t siginfo_t; + +# define GNULIB_defined_siginfo_types 1 +# endif + +# endif /* !@HAVE_SIGINFO_T@ */ + +/* We assume that platforms which lack the sigaction() function also lack + the 'struct sigaction' type, and vice versa. */ + +# if !GNULIB_defined_struct_sigaction + +struct sigaction +{ + union + { + void (*_sa_handler) (int); + /* Present to allow compilation, but unsupported by gnulib. POSIX + says that implementations may, but not must, make sa_sigaction + overlap with sa_handler, but we know of no implementation where + they do not overlap. */ + void (*_sa_sigaction) (int, siginfo_t *, void *); + } _sa_func; + sigset_t sa_mask; + /* Not all POSIX flags are supported. */ + int sa_flags; +}; +# define sa_handler _sa_func._sa_handler +# define sa_sigaction _sa_func._sa_sigaction +/* Unsupported flags are not present. */ +# define SA_RESETHAND 1 +# define SA_NODEFER 2 +# define SA_RESTART 4 + +# define GNULIB_defined_struct_sigaction 1 +# endif + +_GL_FUNCDECL_SYS (sigaction, int, (int, const struct sigaction *restrict, + struct sigaction *restrict)); + +# elif !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@ + +# define sa_sigaction sa_handler + +# endif /* !@HAVE_SIGACTION@, !@HAVE_STRUCT_SIGACTION_SA_SIGACTION@ */ + +_GL_CXXALIAS_SYS (sigaction, int, (int, const struct sigaction *restrict, + struct sigaction *restrict)); +_GL_CXXALIASWARN (sigaction); + +#elif defined GNULIB_POSIXCHECK +# undef sigaction +# if HAVE_RAW_DECL_SIGACTION +_GL_WARN_ON_USE (sigaction, "sigaction is unportable - " + "use the gnulib module sigaction for portability"); +# endif +#endif + +/* Some systems don't have SA_NODEFER. */ +#ifndef SA_NODEFER +# define SA_NODEFER 0 +#endif + + +#endif /* _@GUARD_PREFIX@_SIGNAL_H */ +#endif /* _@GUARD_PREFIX@_SIGNAL_H */ +#endif diff --git a/lib/sigprocmask.c b/lib/sigprocmask.c new file mode 100644 index 0000000..a805da6 --- /dev/null +++ b/lib/sigprocmask.c @@ -0,0 +1,349 @@ +/* POSIX compatible signal blocking. + Copyright (C) 2006-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2006. + + 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 +#include + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +#endif + +/* We assume that a platform without POSIX signal blocking functions + also does not have the POSIX sigaction() function, only the + signal() function. We also assume signal() has SysV semantics, + where any handler is uninstalled prior to being invoked. This is + true for native Windows platforms. */ + +/* We use raw signal(), but also provide a wrapper rpl_signal() so + that applications can query or change a blocked signal. */ +#undef signal + +/* Provide invalid signal numbers as fallbacks if the uncatchable + signals are not defined. */ +#ifndef SIGKILL +# define SIGKILL (-1) +#endif +#ifndef SIGSTOP +# define SIGSTOP (-1) +#endif + +/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias + for the signal SIGABRT. Only one signal handler is stored for both + SIGABRT and SIGABRT_COMPAT. SIGABRT_COMPAT is not a signal of its own. */ +#if defined _WIN32 && ! defined __CYGWIN__ +# undef SIGABRT_COMPAT +# define SIGABRT_COMPAT 6 +#endif +#ifdef SIGABRT_COMPAT +# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT) +#else +# define SIGABRT_COMPAT_MASK 0 +#endif + +typedef void (*handler_t) (int); + +#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static handler_t +signal_nothrow (int sig, handler_t handler) +{ + handler_t result; + + TRY_MSVC_INVAL + { + result = signal (sig, handler); + } + CATCH_MSVC_INVAL + { + result = SIG_ERR; + errno = EINVAL; + } + DONE_MSVC_INVAL; + + return result; +} +# define signal signal_nothrow +#endif + +/* Handling of gnulib defined signals. */ + +#if GNULIB_defined_SIGPIPE +static handler_t SIGPIPE_handler = SIG_DFL; +#endif + +#if GNULIB_defined_SIGPIPE +static handler_t +ext_signal (int sig, handler_t handler) +{ + switch (sig) + { + case SIGPIPE: + { + handler_t old_handler = SIGPIPE_handler; + SIGPIPE_handler = handler; + return old_handler; + } + default: /* System defined signal */ + return signal (sig, handler); + } +} +# undef signal +# define signal ext_signal +#endif + +int +sigismember (const sigset_t *set, int sig) +{ + if (sig >= 0 && sig < NSIG) + { + #ifdef SIGABRT_COMPAT + if (sig == SIGABRT_COMPAT) + sig = SIGABRT; + #endif + + return (*set >> sig) & 1; + } + else + return 0; +} + +int +sigemptyset (sigset_t *set) +{ + *set = 0; + return 0; +} + +int +sigaddset (sigset_t *set, int sig) +{ + if (sig >= 0 && sig < NSIG) + { + #ifdef SIGABRT_COMPAT + if (sig == SIGABRT_COMPAT) + sig = SIGABRT; + #endif + + *set |= 1U << sig; + return 0; + } + else + { + errno = EINVAL; + return -1; + } +} + +int +sigdelset (sigset_t *set, int sig) +{ + if (sig >= 0 && sig < NSIG) + { + #ifdef SIGABRT_COMPAT + if (sig == SIGABRT_COMPAT) + sig = SIGABRT; + #endif + + *set &= ~(1U << sig); + return 0; + } + else + { + errno = EINVAL; + return -1; + } +} + + +int +sigfillset (sigset_t *set) +{ + *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK; + return 0; +} + +/* Set of currently blocked signals. */ +static volatile sigset_t blocked_set /* = 0 */; + +/* Set of currently blocked and pending signals. */ +static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */; + +/* Signal handler that is installed for blocked signals. */ +static void +blocked_handler (int sig) +{ + /* Reinstall the handler, in case the signal occurs multiple times + while blocked. There is an inherent race where an asynchronous + signal in between when the kernel uninstalled the handler and + when we reinstall it will trigger the default handler; oh + well. */ + signal (sig, blocked_handler); + if (sig >= 0 && sig < NSIG) + pending_array[sig] = 1; +} + +int +sigpending (sigset_t *set) +{ + sigset_t pending = 0; + int sig; + + for (sig = 0; sig < NSIG; sig++) + if (pending_array[sig]) + pending |= 1U << sig; + *set = pending; + return 0; +} + +/* The previous signal handlers. + Only the array elements corresponding to blocked signals are relevant. */ +static volatile handler_t old_handlers[NSIG]; + +int +sigprocmask (int operation, const sigset_t *set, sigset_t *old_set) +{ + if (old_set != NULL) + *old_set = blocked_set; + + if (set != NULL) + { + sigset_t new_blocked_set; + sigset_t to_unblock; + sigset_t to_block; + + switch (operation) + { + case SIG_BLOCK: + new_blocked_set = blocked_set | *set; + break; + case SIG_SETMASK: + new_blocked_set = *set; + break; + case SIG_UNBLOCK: + new_blocked_set = blocked_set & ~*set; + break; + default: + errno = EINVAL; + return -1; + } + to_unblock = blocked_set & ~new_blocked_set; + to_block = new_blocked_set & ~blocked_set; + + if (to_block != 0) + { + int sig; + + for (sig = 0; sig < NSIG; sig++) + if ((to_block >> sig) & 1) + { + pending_array[sig] = 0; + if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR) + blocked_set |= 1U << sig; + } + } + + if (to_unblock != 0) + { + sig_atomic_t received[NSIG]; + int sig; + + for (sig = 0; sig < NSIG; sig++) + if ((to_unblock >> sig) & 1) + { + if (signal (sig, old_handlers[sig]) != blocked_handler) + /* The application changed a signal handler while the signal + was blocked, bypassing our rpl_signal replacement. + We don't support this. */ + abort (); + received[sig] = pending_array[sig]; + blocked_set &= ~(1U << sig); + pending_array[sig] = 0; + } + else + received[sig] = 0; + + for (sig = 0; sig < NSIG; sig++) + if (received[sig]) + raise (sig); + } + } + return 0; +} + +/* Install the handler FUNC for signal SIG, and return the previous + handler. */ +handler_t +rpl_signal (int sig, handler_t handler) +{ + /* We must provide a wrapper, so that a user can query what handler + they installed even if that signal is currently blocked. */ + if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP + && handler != SIG_ERR) + { + #ifdef SIGABRT_COMPAT + if (sig == SIGABRT_COMPAT) + sig = SIGABRT; + #endif + + if (blocked_set & (1U << sig)) + { + /* POSIX states that sigprocmask and signal are both + async-signal-safe. This is not true of our + implementation - there is a slight data race where an + asynchronous interrupt on signal A can occur after we + install blocked_handler but before we have updated + old_handlers for signal B, such that handler A can see + stale information if it calls signal(B). Oh well - + signal handlers really shouldn't try to manipulate the + installed handlers of unrelated signals. */ + handler_t result = old_handlers[sig]; + old_handlers[sig] = handler; + return result; + } + else + return signal (sig, handler); + } + else + { + errno = EINVAL; + return SIG_ERR; + } +} + +#if GNULIB_defined_SIGPIPE +/* Raise the signal SIGPIPE. */ +int +_gl_raise_SIGPIPE (void) +{ + if (blocked_set & (1U << SIGPIPE)) + pending_array[SIGPIPE] = 1; + else + { + handler_t handler = SIGPIPE_handler; + if (handler == SIG_DFL) + exit (128 + SIGPIPE); + else if (handler != SIG_IGN) + (*handler) (SIGPIPE); + } + return 0; +} +#endif diff --git a/lib/size_max.h b/lib/size_max.h new file mode 100644 index 0000000..dee2b8e --- /dev/null +++ b/lib/size_max.h @@ -0,0 +1,30 @@ +/* size_max.h -- declare SIZE_MAX through system headers + Copyright (C) 2005-2006, 2009-2022 Free Software Foundation, Inc. + Written by Simon Josefsson. + + 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 GNULIB_SIZE_MAX_H +#define GNULIB_SIZE_MAX_H + +/* Get SIZE_MAX declaration on systems like Solaris 7/8/9. */ +# include +/* Get SIZE_MAX declaration on systems like glibc 2. */ +# if HAVE_STDINT_H +# include +# endif +/* On systems where these include files don't define it, SIZE_MAX is defined + in config.h. */ + +#endif /* GNULIB_SIZE_MAX_H */ diff --git a/lib/snprintf.c b/lib/snprintf.c new file mode 100644 index 0000000..3d87854 --- /dev/null +++ b/lib/snprintf.c @@ -0,0 +1,71 @@ +/* Formatted output to strings. + Copyright (C) 2004, 2006-2022 Free Software Foundation, Inc. + Written by Simon Josefsson and Paul Eggert. + + 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 +#include +#include +#include + +#include "vasnprintf.h" + +/* Print formatted output to string STR. Similar to sprintf, but + additional length SIZE limit how much is written into STR. Returns + string length of formatted string (which may be larger than SIZE). + STR may be NULL, in which case nothing will be written. On error, + return a negative value. */ +int +snprintf (char *str, size_t size, const char *format, ...) +{ + char *output; + size_t len; + size_t lenbuf = size; + va_list args; + + va_start (args, format); + output = vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + va_end (args); + + if (!output) + return -1; + + if (output != str) + { + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); + } + + if (INT_MAX < len) + { + errno = EOVERFLOW; + return -1; + } + + return len; +} diff --git a/lib/socket.c b/lib/socket.c new file mode 100644 index 0000000..49e013c --- /dev/null +++ b/lib/socket.c @@ -0,0 +1,53 @@ +/* socket.c --- wrappers for Windows socket function + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +#define WIN32_LEAN_AND_MEAN +/* Get winsock2.h. */ +#include + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +#include "w32sock.h" + +#include "sockets.h" + +/* Don't assume that UNICODE is defined. */ +#undef WSASocket +#define WSASocket WSASocketW + +int +rpl_socket (int domain, int type, int protocol) +{ + SOCKET fh; + + gl_sockets_startup (SOCKETS_1_1); + + /* We have to use WSASocket() to create non-overlapped IO sockets. + Overlapped IO sockets cannot be used with read/write. */ + fh = WSASocket (domain, type, protocol, NULL, 0, 0); + + if (fh == INVALID_SOCKET) + { + set_winsock_errno (); + return -1; + } + else + return SOCKET_TO_FD (fh); +} diff --git a/lib/sockets.c b/lib/sockets.c new file mode 100644 index 0000000..31b4302 --- /dev/null +++ b/lib/sockets.c @@ -0,0 +1,161 @@ +/* sockets.c --- wrappers for Windows socket functions + + 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 . */ + +/* Written by Simon Josefsson */ + +#include + +/* Specification. */ +#include "sockets.h" + +#if WINDOWS_SOCKETS + +/* This includes winsock2.h on MinGW. */ +# include + +# include "fd-hook.h" +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +/* Get set_winsock_errno, FD_TO_SOCKET etc. */ +# include "w32sock.h" + +static int +close_fd_maybe_socket (const struct fd_hook *remaining_list, + gl_close_fn primary, + int fd) +{ + /* Note about multithread-safety: There is a race condition where, between + our calls to closesocket() and the primary close(), some other thread + could make system calls that allocate precisely the same HANDLE value + as sock; then the primary close() would call CloseHandle() on it. */ + SOCKET sock; + WSANETWORKEVENTS ev; + + /* Test whether fd refers to a socket. */ + sock = FD_TO_SOCKET (fd); + ev.lNetworkEvents = 0xDEADBEEF; + WSAEnumNetworkEvents (sock, NULL, &ev); + if (ev.lNetworkEvents != 0xDEADBEEF) + { + /* fd refers to a socket. */ + /* FIXME: other applications, like squid, use an undocumented + _free_osfhnd free function. But this is not enough: The 'osfile' + flags for fd also needs to be cleared, but it is hard to access it. + Instead, here we just close twice the file descriptor. */ + if (closesocket (sock)) + { + set_winsock_errno (); + return -1; + } + else + { + /* This call frees the file descriptor and does a + CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails. */ + _close (fd); + return 0; + } + } + else + /* Some other type of file descriptor. */ + return execute_close_hooks (remaining_list, primary, fd); +} + +static int +ioctl_fd_maybe_socket (const struct fd_hook *remaining_list, + gl_ioctl_fn primary, + int fd, int request, void *arg) +{ + SOCKET sock; + WSANETWORKEVENTS ev; + + /* Test whether fd refers to a socket. */ + sock = FD_TO_SOCKET (fd); + ev.lNetworkEvents = 0xDEADBEEF; + WSAEnumNetworkEvents (sock, NULL, &ev); + if (ev.lNetworkEvents != 0xDEADBEEF) + { + /* fd refers to a socket. */ + if (ioctlsocket (sock, request, arg) < 0) + { + set_winsock_errno (); + return -1; + } + else + return 0; + } + else + /* Some other type of file descriptor. */ + return execute_ioctl_hooks (remaining_list, primary, fd, request, arg); +} + +static struct fd_hook fd_sockets_hook; + +static int initialized_sockets_version /* = 0 */; + +#endif /* WINDOWS_SOCKETS */ + +int +gl_sockets_startup (_GL_UNUSED int version) +{ +#if WINDOWS_SOCKETS + if (version > initialized_sockets_version) + { + WSADATA data; + int err; + + err = WSAStartup (version, &data); + if (err != 0) + return 1; + + if (data.wVersion != version) + { + WSACleanup (); + return 2; + } + + if (initialized_sockets_version == 0) + register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket, + &fd_sockets_hook); + + initialized_sockets_version = version; + } +#endif + + return 0; +} + +int +gl_sockets_cleanup (void) +{ +#if WINDOWS_SOCKETS + int err; + + initialized_sockets_version = 0; + + unregister_fd_hook (&fd_sockets_hook); + + err = WSACleanup (); + if (err != 0) + return 1; +#endif + + return 0; +} diff --git a/lib/sockets.h b/lib/sockets.h new file mode 100644 index 0000000..75e49fc --- /dev/null +++ b/lib/sockets.h @@ -0,0 +1,66 @@ +/* sockets.h - wrappers for Windows socket functions + + 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 . */ + +/* Written by Simon Josefsson */ + +#ifndef SOCKETS_H +#define SOCKETS_H 1 + +#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) +#ifndef WINDOWS_SOCKETS + _GL_ATTRIBUTE_CONST +#endif + ; + +int gl_sockets_cleanup (void) +#ifndef WINDOWS_SOCKETS + _GL_ATTRIBUTE_CONST +#endif + ; + +/* 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. */ +#ifdef WINDOWS_SOCKETS + +# include + +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +static inline SOCKET +gl_fd_to_handle (int fd) +{ + return _get_osfhandle (fd); +} + +#else + +# define gl_fd_to_handle(x) (x) + +#endif /* WINDOWS_SOCKETS */ + +#endif /* SOCKETS_H */ diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c new file mode 100644 index 0000000..f132624 --- /dev/null +++ b/lib/spawn-pipe.c @@ -0,0 +1,673 @@ +/* Creation of subprocesses, communicating via pipes. + Copyright (C) 2001-2004, 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 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 . */ + + +/* Tell clang not to warn about the 'child' variable, below. */ +#if defined __clang__ +# pragma clang diagnostic ignored "-Wconditional-uninitialized" +#endif + +#include + +/* Specification. */ +#include "spawn-pipe.h" + +#include +#include +#include +#include +#include + +#include "canonicalize.h" +#include "error.h" +#include "fatal-signal.h" +#include "filename.h" +#include "findprog.h" +#include "unistd-safer.h" +#include "wait-process.h" +#include "xalloc.h" +#include "gettext.h" + +#define _(str) gettext (str) + + +/* Choice of implementation for native Windows. + - Define to 0 to use the posix_spawn facility (modules 'posix_spawn' and + 'posix_spawnp'), that is based on the module 'windows-spawn'. + - Define to 1 to use the older code, that uses the module 'windows-spawn' + directly. + You can set this macro from a Makefile or at configure time, from the + CPPFLAGS. */ +#ifndef SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN +# define SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN 0 +#endif + + +#if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN + +/* Native Windows API. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif +# include +# include "windows-spawn.h" + +#elif defined __KLIBC__ + +/* OS/2 kLIBC API. */ +# include +# include "os2-spawn.h" + +#else + +/* Unix API. */ +# include + +#endif + + +#ifdef EINTR + +/* EINTR handling for close(). + These functions can return -1/EINTR even though we don't have any + signal handlers set up, namely when we get interrupted via SIGSTOP. */ + +static int +nonintr_close (int fd) +{ + int retval; + + do + retval = close (fd); + while (retval < 0 && errno == EINTR); + + return retval; +} +#undef close /* avoid warning related to gnulib module unistd */ +#define close nonintr_close + +#if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN +static int +nonintr_open (const char *pathname, int oflag, mode_t mode) +{ + int retval; + + do + retval = open (pathname, oflag, mode); + while (retval < 0 && errno == EINTR); + + return retval; +} +# undef open /* avoid warning on VMS */ +# define open nonintr_open +#endif + +#endif + + +/* Open a pipe connected to a child process. + * + * write system read + * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin + * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout + * read system write + * + * At least one of pipe_stdin, pipe_stdout must be true. + * pipe_stdin and prog_stdin together determine the child's standard input. + * pipe_stdout and prog_stdout together determine the child's standard output. + * If pipe_stdin is true, prog_stdin is ignored. + * If pipe_stdout is true, prog_stdout is ignored. + */ +static pid_t +create_pipe (const char *progname, + const char *prog_path, + const char * const *prog_argv, + const char *directory, + bool pipe_stdin, bool pipe_stdout, + const char *prog_stdin, const char *prog_stdout, + bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[2]) +{ + int saved_errno; + char *prog_path_to_free = NULL; + + if (directory != NULL) + { + /* If a change of directory is requested, make sure PROG_PATH is absolute + before we do so. This is needed because + - posix_spawn and posix_spawnp are required to resolve a relative + PROG_PATH *after* changing the directory. See + : + "if this pathname does not start with a it shall be + interpreted relative to the working directory of the child + process _after_ all file_actions have been performed." + But this would be a surprising application behaviour, possibly + even security relevant. + - For the Windows CreateProcess() function, it is unspecified whether + a relative file name is interpreted to the parent's current + directory or to the specified directory. See + */ + if (! IS_ABSOLUTE_FILE_NAME (prog_path)) + { + const char *resolved_prog = + find_in_given_path (prog_path, getenv ("PATH"), NULL, false); + if (resolved_prog == NULL) + goto fail_with_errno; + if (resolved_prog != prog_path) + prog_path_to_free = (char *) resolved_prog; + prog_path = resolved_prog; + + if (! IS_ABSOLUTE_FILE_NAME (prog_path)) + { + char *absolute_prog = + canonicalize_filename_mode (prog_path, CAN_MISSING | CAN_NOLINKS); + if (absolute_prog == NULL) + { + free (prog_path_to_free); + goto fail_with_errno; + } + free (prog_path_to_free); + prog_path_to_free = absolute_prog; + prog_path = absolute_prog; + + if (! IS_ABSOLUTE_FILE_NAME (prog_path)) + abort (); + } + } + } + +#if ((defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN) || defined __KLIBC__ + + /* Native Windows API. + This uses _pipe(), dup2(), and _spawnv(). It could also be implemented + using the low-level functions CreatePipe(), DuplicateHandle(), + CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp + and cvs source code. */ + char *argv_mem_to_free; + int ifd[2]; + int ofd[2]; + int child; + int nulloutfd; + int stdinfd; + int stdoutfd; + + const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free); + if (argv == NULL) + xalloc_die (); + + if (pipe_stdout) + if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0) + error (EXIT_FAILURE, errno, _("cannot create pipe")); + if (pipe_stdin) + if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0) + error (EXIT_FAILURE, errno, _("cannot create pipe")); +/* Data flow diagram: + * + * write system read + * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin + * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout + * read system write + * + */ + + child = -1; + +# if (defined _WIN32 && !defined __CYGWIN__) && SPAWN_PIPE_IMPL_AVOID_POSIX_SPAWN + bool must_close_ifd1 = pipe_stdout; + bool must_close_ofd0 = pipe_stdin; + + /* Create standard file handles of child process. */ + HANDLE stdin_handle = INVALID_HANDLE_VALUE; + HANDLE stdout_handle = INVALID_HANDLE_VALUE; + nulloutfd = -1; + stdinfd = -1; + stdoutfd = -1; + if ((!null_stderr + || (nulloutfd = open ("NUL", O_RDWR, 0)) >= 0) + && (pipe_stdin + || prog_stdin == NULL + || (stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0) + && (pipe_stdout + || prog_stdout == NULL + || (stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0)) + /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1], + but it inherits the three STD*_FILENO for which we pass the handles. */ + /* Pass the environment explicitly. This is needed if the program has + modified the environment using putenv() or [un]setenv(). On Windows, + processes have two environments, one in the "environment block" of the + process and managed through SetEnvironmentVariable(), and one inside the + process, in the location retrieved by the 'environ' macro. If we were + to pass NULL, the child process would inherit a copy of the environment + block - ignoring the effects of putenv() and [un]setenv(). */ + { + stdin_handle = + (HANDLE) _get_osfhandle (pipe_stdin ? ofd[0] : + prog_stdin == NULL ? STDIN_FILENO : stdinfd); + if (pipe_stdin) + { + HANDLE curr_process = GetCurrentProcess (); + HANDLE duplicate; + if (!DuplicateHandle (curr_process, stdin_handle, + curr_process, &duplicate, + 0, TRUE, DUPLICATE_SAME_ACCESS)) + { + errno = EBADF; /* arbitrary */ + goto failed; + } + must_close_ofd0 = false; + close (ofd[0]); /* implies CloseHandle (stdin_handle); */ + stdin_handle = duplicate; + } + stdout_handle = + (HANDLE) _get_osfhandle (pipe_stdout ? ifd[1] : + prog_stdout == NULL ? STDOUT_FILENO : stdoutfd); + if (pipe_stdout) + { + HANDLE curr_process = GetCurrentProcess (); + HANDLE duplicate; + if (!DuplicateHandle (curr_process, stdout_handle, + curr_process, &duplicate, + 0, TRUE, DUPLICATE_SAME_ACCESS)) + { + errno = EBADF; /* arbitrary */ + goto failed; + } + must_close_ifd1 = false; + close (ifd[1]); /* implies CloseHandle (stdout_handle); */ + stdout_handle = duplicate; + } + HANDLE stderr_handle = + (HANDLE) _get_osfhandle (null_stderr ? nulloutfd : STDERR_FILENO); + + child = spawnpvech (P_NOWAIT, prog_path, argv + 1, + (const char * const *) environ, directory, + stdin_handle, stdout_handle, stderr_handle); +# if 0 /* Executing arbitrary files as shell scripts is unsecure. */ + if (child == -1 && errno == ENOEXEC) + { + /* prog is not a native executable. Try to execute it as a + shell script. Note that prepare_spawn() has already prepended + a hidden element "sh.exe" to argv. */ + argv[1] = prog_path; + child = spawnpvech (P_NOWAIT, argv[0], argv, + (const char * const *) environ, directory, + stdin_handle, stdout_handle, stderr_handle); + } +# endif + } + failed: + if (child == -1) + saved_errno = errno; + if (stdinfd >= 0) + close (stdinfd); + if (stdoutfd >= 0) + close (stdoutfd); + if (nulloutfd >= 0) + close (nulloutfd); + + if (pipe_stdin) + { + if (must_close_ofd0) + close (ofd[0]); + else + if (stdin_handle != INVALID_HANDLE_VALUE) + CloseHandle (stdin_handle); + } + if (pipe_stdout) + { + if (must_close_ifd1) + close (ifd[1]); + else + if (stdout_handle != INVALID_HANDLE_VALUE) + CloseHandle (stdout_handle); + } + +# else /* __KLIBC__ */ + if (!(directory == NULL || strcmp (directory, ".") == 0)) + { + /* A directory argument is not supported in this implementation. */ + saved_errno = EINVAL; + goto fail_with_saved_errno; + } + + int orig_stdin; + int orig_stdout; + int orig_stderr; + + /* Save standard file handles of parent process. */ + if (pipe_stdin || prog_stdin != NULL) + orig_stdin = dup_safer_noinherit (STDIN_FILENO); + if (pipe_stdout || prog_stdout != NULL) + orig_stdout = dup_safer_noinherit (STDOUT_FILENO); + if (null_stderr) + orig_stderr = dup_safer_noinherit (STDERR_FILENO); + + /* Create standard file handles of child process. */ + nulloutfd = -1; + stdinfd = -1; + stdoutfd = -1; + if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0) + && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0) + && (!null_stderr + || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0 + && (nulloutfd == STDERR_FILENO + || (dup2 (nulloutfd, STDERR_FILENO) >= 0 + && close (nulloutfd) >= 0)))) + && (pipe_stdin + || prog_stdin == NULL + || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0 + && (stdinfd == STDIN_FILENO + || (dup2 (stdinfd, STDIN_FILENO) >= 0 + && close (stdinfd) >= 0)))) + && (pipe_stdout + || prog_stdout == NULL + || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0 + && (stdoutfd == STDOUT_FILENO + || (dup2 (stdoutfd, STDOUT_FILENO) >= 0 + && close (stdoutfd) >= 0))))) + /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1], + but it inherits all open()ed or dup2()ed file handles (which is what + we want in the case of STD*_FILENO). */ + { + child = _spawnvpe (P_NOWAIT, prog_path, argv + 1, + (const char **) environ); +# if 0 /* Executing arbitrary files as shell scripts is unsecure. */ + if (child == -1 && errno == ENOEXEC) + { + /* prog is not a native executable. Try to execute it as a + shell script. Note that prepare_spawn() has already prepended + a hidden element "sh.exe" to argv. */ + child = _spawnvpe (P_NOWAIT, argv[0], argv, + (const char **) environ); + } +# endif + } + if (child == -1) + saved_errno = errno; + if (stdinfd >= 0) + close (stdinfd); + if (stdoutfd >= 0) + close (stdoutfd); + if (nulloutfd >= 0) + close (nulloutfd); + + /* Restore standard file handles of parent process. */ + if (null_stderr) + undup_safer_noinherit (orig_stderr, STDERR_FILENO); + if (pipe_stdout || prog_stdout != NULL) + undup_safer_noinherit (orig_stdout, STDOUT_FILENO); + if (pipe_stdin || prog_stdin != NULL) + undup_safer_noinherit (orig_stdin, STDIN_FILENO); + + if (pipe_stdin) + close (ofd[0]); + if (pipe_stdout) + close (ifd[1]); +# endif + + free (argv); + free (argv_mem_to_free); + free (prog_path_to_free); + + if (child == -1) + { + if (pipe_stdout) + close (ifd[0]); + if (pipe_stdin) + close (ofd[1]); + goto fail_with_saved_errno; + } + + if (pipe_stdout) + fd[0] = ifd[0]; + if (pipe_stdin) + fd[1] = ofd[1]; + return child; + +#else + + /* Unix API. */ + int ifd[2]; + int ofd[2]; + sigset_t blocked_signals; + posix_spawn_file_actions_t actions; + bool actions_allocated; + posix_spawnattr_t attrs; + bool attrs_allocated; + int err; + pid_t child; + + if (pipe_stdout) + if (pipe_safer (ifd) < 0) + error (EXIT_FAILURE, errno, _("cannot create pipe")); + if (pipe_stdin) + if (pipe_safer (ofd) < 0) + error (EXIT_FAILURE, errno, _("cannot create pipe")); +/* Data flow diagram: + * + * write system read + * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin + * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout + * read system write + * + */ + + if (slave_process) + { + sigprocmask (SIG_SETMASK, NULL, &blocked_signals); + block_fatal_signals (); + } + actions_allocated = false; + attrs_allocated = false; + if ((err = posix_spawn_file_actions_init (&actions)) != 0 + || (actions_allocated = true, + (pipe_stdin + && (err = posix_spawn_file_actions_adddup2 (&actions, + ofd[0], STDIN_FILENO)) + != 0) + || (pipe_stdout + && (err = posix_spawn_file_actions_adddup2 (&actions, + ifd[1], STDOUT_FILENO)) + != 0) + || (pipe_stdin + && (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) + != 0) + || (pipe_stdout + && (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) + != 0) + || (pipe_stdin + && (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) + != 0) + || (pipe_stdout + && (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) + != 0) + || (null_stderr + && (err = posix_spawn_file_actions_addopen (&actions, + STDERR_FILENO, + "/dev/null", O_RDWR, + 0)) + != 0) + || (!pipe_stdin + && prog_stdin != NULL + && (err = posix_spawn_file_actions_addopen (&actions, + STDIN_FILENO, + prog_stdin, O_RDONLY, + 0)) + != 0) + || (!pipe_stdout + && prog_stdout != NULL + && (err = posix_spawn_file_actions_addopen (&actions, + STDOUT_FILENO, + prog_stdout, O_WRONLY, + 0)) + != 0) + || (directory != NULL + && (err = posix_spawn_file_actions_addchdir (&actions, + directory))) + || (slave_process + && ((err = posix_spawnattr_init (&attrs)) != 0 + || (attrs_allocated = true, +# if defined _WIN32 && !defined __CYGWIN__ + (err = posix_spawnattr_setpgroup (&attrs, 0)) != 0 + || (err = posix_spawnattr_setflags (&attrs, + POSIX_SPAWN_SETPGROUP)) + != 0 +# else + (err = posix_spawnattr_setsigmask (&attrs, + &blocked_signals)) + != 0 + || (err = posix_spawnattr_setflags (&attrs, + POSIX_SPAWN_SETSIGMASK)) + != 0 +# endif + ) ) ) + || (err = (directory != NULL + ? posix_spawn (&child, prog_path, &actions, + attrs_allocated ? &attrs : NULL, + (char * const *) prog_argv, environ) + : posix_spawnp (&child, prog_path, &actions, + attrs_allocated ? &attrs : NULL, + (char * const *) prog_argv, environ))) + != 0)) + { + if (actions_allocated) + posix_spawn_file_actions_destroy (&actions); + if (attrs_allocated) + posix_spawnattr_destroy (&attrs); + if (slave_process) + unblock_fatal_signals (); + if (pipe_stdout) + { + close (ifd[0]); + close (ifd[1]); + } + if (pipe_stdin) + { + close (ofd[0]); + close (ofd[1]); + } + free (prog_path_to_free); + saved_errno = err; + goto fail_with_saved_errno; + } + posix_spawn_file_actions_destroy (&actions); + if (attrs_allocated) + posix_spawnattr_destroy (&attrs); + if (slave_process) + { + register_slave_subprocess (child); + unblock_fatal_signals (); + } + if (pipe_stdin) + close (ofd[0]); + if (pipe_stdout) + close (ifd[1]); + free (prog_path_to_free); + + if (pipe_stdout) + fd[0] = ifd[0]; + if (pipe_stdin) + fd[1] = ofd[1]; + return child; + +#endif + + fail_with_errno: + saved_errno = errno; + fail_with_saved_errno: + if (exit_on_error || !null_stderr) + error (exit_on_error ? EXIT_FAILURE : 0, saved_errno, + _("%s subprocess failed"), progname); + errno = saved_errno; + return -1; +} + +/* Open a bidirectional pipe. + * + * write system read + * parent -> fd[1] -> STDIN_FILENO -> child + * parent <- fd[0] <- STDOUT_FILENO <- child + * read system write + * + */ +pid_t +create_pipe_bidi (const char *progname, + const char *prog_path, const char * const *prog_argv, + const char *directory, + bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[2]) +{ + pid_t result = create_pipe (progname, prog_path, prog_argv, directory, + true, true, NULL, NULL, + null_stderr, slave_process, exit_on_error, + fd); + return result; +} + +/* Open a pipe for input from a child process. + * The child's stdin comes from a file. + * + * read system write + * parent <- fd[0] <- STDOUT_FILENO <- child + * + */ +pid_t +create_pipe_in (const char *progname, + const char *prog_path, const char * const *prog_argv, + const char *directory, + const char *prog_stdin, bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[1]) +{ + int iofd[2]; + pid_t result = create_pipe (progname, prog_path, prog_argv, directory, + false, true, prog_stdin, NULL, + null_stderr, slave_process, exit_on_error, + iofd); + if (result != -1) + fd[0] = iofd[0]; + return result; +} + +/* Open a pipe for output to a child process. + * The child's stdout goes to a file. + * + * write system read + * parent -> fd[0] -> STDIN_FILENO -> child + * + */ +pid_t +create_pipe_out (const char *progname, + const char *prog_path, const char * const *prog_argv, + const char *directory, + const char *prog_stdout, bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[1]) +{ + int iofd[2]; + pid_t result = create_pipe (progname, prog_path, prog_argv, directory, + true, false, NULL, prog_stdout, + null_stderr, slave_process, exit_on_error, + iofd); + if (result != -1) + fd[0] = iofd[1]; + return result; +} diff --git a/lib/spawn-pipe.h b/lib/spawn-pipe.h new file mode 100644 index 0000000..9ab1ea8 --- /dev/null +++ b/lib/spawn-pipe.h @@ -0,0 +1,166 @@ +/* Creation of subprocesses, communicating via pipes. + Copyright (C) 2001-2003, 2006, 2008-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 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 _SPAWN_PIPE_H +#define _SPAWN_PIPE_H + +/* Get pid_t. */ +#include +#include +#include + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* All these functions create a subprocess and don't wait for its termination. + They return the process id of the subprocess. They also return in fd[] + one or two file descriptors for communication with the subprocess. + If the subprocess creation fails: if exit_on_error is true, the main + process exits with an error message; otherwise, an error message is given + if null_stderr is false, then -1 is returned, with errno set, and fd[] + remain uninitialized. + + After finishing communication, the caller should call wait_subprocess() + to get rid of the subprocess in the process table. + + progname is the name of the program to be executed by the subprocess, used + for error messages. + prog_path is the file name of the program to be executed by the subprocess. + If it contains no slashes, a search is conducted in $PATH. An operating + system dependent suffix is added, if necessary. + prog_argv is the array of strings that the subprocess shall receive in + argv[]. It is a NULL-terminated array. prog_argv[0] should normally be + identical to prog_path. + + If directory is not NULL, the subprocess is started in that directory. If + prog_path is a relative file name, it resolved before changing to that + directory. The current directory of the current process remains unchanged. + + If slave_process is true, the child process will be terminated when its + creator receives a catchable fatal signal or exits normally. If + slave_process is false, the child process will continue running in this + case, until it is lucky enough to attempt to communicate with its creator + and thus get a SIGPIPE signal. + + If exit_on_error is false, a child process id of -1 should be treated the + same way as a subprocess which accepts no input, produces no output and + terminates with exit code 127. Why? Some errors during posix_spawnp() + cause the function posix_spawnp() to return an error code; some other + errors cause the subprocess to exit with return code 127. It is + implementation dependent which error is reported which way. The caller + must treat both cases as equivalent. + + It is recommended that no signal is blocked or ignored (i.e. have a + signal handler with value SIG_IGN) while any of these functions is called. + The reason is that child processes inherit the mask of blocked signals + from their parent (both through posix_spawn() and fork()/exec()); + likewise, signals ignored in the parent are also ignored in the child + (except possibly for SIGCHLD). And POSIX:2001 says [in the description + of exec()]: + "it should be noted that many existing applications wrongly + assume that they start with certain signals set to the default + action and/or unblocked. In particular, applications written + with a simpler signal model that does not include blocking of + signals, such as the one in the ISO C standard, may not behave + properly if invoked with some signals blocked. Therefore, it is + best not to block or ignore signals across execs without explicit + reason to do so, and especially not to block signals across execs + of arbitrary (not closely co-operating) programs." */ + +/* Open a pipe for output to a child process. + * The child's stdout goes to a file. + * + * write system read + * parent -> fd[0] -> STDIN_FILENO -> child + * + * Note: When writing to a child process, it is useful to ignore the SIGPIPE + * signal and the EPIPE error code. + */ +extern pid_t create_pipe_out (const char *progname, + const char *prog_path, + const char * const *prog_argv, + const char *directory, + const char *prog_stdout, bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[1]); + +/* Open a pipe for input from a child process. + * The child's stdin comes from a file. + * + * read system write + * parent <- fd[0] <- STDOUT_FILENO <- child + * + */ +extern pid_t create_pipe_in (const char *progname, + const char *prog_path, + const char * const *prog_argv, + const char *directory, + const char *prog_stdin, bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[1]); + +/* Open a bidirectional pipe. + * + * write system read + * parent -> fd[1] -> STDIN_FILENO -> child + * parent <- fd[0] <- STDOUT_FILENO <- child + * read system write + * + * Note: When writing to a child process, it is useful to ignore the SIGPIPE + * signal and the EPIPE error code. + * + * Note: The parent process must be careful to avoid deadlock. + * 1) If you write more than PIPE_MAX bytes or, more generally, if you write + * more bytes than the subprocess can handle at once, the subprocess + * may write its data and wait on you to read it, but you are currently + * busy writing. + * 2) When you don't know ahead of time how many bytes the subprocess + * will produce, the usual technique of calling read (fd, buf, BUFSIZ) + * with a fixed BUFSIZ will, on Linux 2.2.17 and on BSD systems, cause + * the read() call to block until *all* of the buffer has been filled. + * But the subprocess cannot produce more data until you gave it more + * input. But you are currently busy reading from it. + */ +extern pid_t create_pipe_bidi (const char *progname, + const char *prog_path, + const char * const *prog_argv, + const char *directory, + bool null_stderr, + bool slave_process, bool exit_on_error, + int fd[2]); + +/* The name of the "always silent" device. */ +#if defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows API. */ +# define DEV_NULL "NUL" +#else +/* Unix API. */ +# define DEV_NULL "/dev/null" +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* _SPAWN_PIPE_H */ diff --git a/lib/spawn.c b/lib/spawn.c new file mode 100644 index 0000000..bb2308d --- /dev/null +++ b/lib/spawn.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include "spawn_int.h" + +/* Spawn a new process executing PATH with the attributes describes in *ATTRP. + Before running the process perform the actions described in FILE-ACTIONS. */ +int +posix_spawn (pid_t *pid, const char *path, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t *attrp, char *const argv[], + char *const envp[]) +{ + return __spawni (pid, path, file_actions, attrp, + (const char * const *) argv, (const char * const *) envp, 0); +} diff --git a/lib/spawn.in.h b/lib/spawn.in.h new file mode 100644 index 0000000..c1acf60 --- /dev/null +++ b/lib/spawn.in.h @@ -0,0 +1,992 @@ +/* Definitions for POSIX spawn interface. + Copyright (C) 2000, 2003-2004, 2008-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined _GL_ALREADY_INCLUDING_SPAWN_H +/* Special invocation convention: + On OS/2 kLIBC, includes . Then -> + -> -> are included by GNULIB. + In this situation, struct sched_param is not yet defined. */ + +#@INCLUDE_NEXT@ @NEXT_SPAWN_H@ + +#else + +#ifndef _@GUARD_PREFIX@_SPAWN_H +/* Normal invocation convention. */ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_SPAWN_H@ + +# define _GL_ALREADY_INCLUDING_SPAWN_H + +# @INCLUDE_NEXT@ @NEXT_SPAWN_H@ + +# define _GL_ALREADY_INCLUDING_SPAWN_H + +#endif + +#ifndef _@GUARD_PREFIX@_SPAWN_H +#define _@GUARD_PREFIX@_SPAWN_H + +/* Get definitions of 'struct sched_param' and 'sigset_t'. + But avoid namespace pollution on glibc systems. */ +#if !(defined __GLIBC__ && !defined __UCLIBC__) +# include +# include +#endif + +#include + +#ifndef __THROW +# define __THROW +#endif + +/* 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 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 +/* 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_ +# 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_ +# 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. */ + + +/* Data structure to contain attributes for thread creation. */ +#if @REPLACE_POSIX_SPAWN@ || (@HAVE_POSIX_SPAWNATTR_T@ && !@HAVE_POSIX_SPAWN@) +# define posix_spawnattr_t rpl_posix_spawnattr_t +#endif +#if @REPLACE_POSIX_SPAWN@ || !@HAVE_POSIX_SPAWNATTR_T@ || !@HAVE_POSIX_SPAWN@ +# if !GNULIB_defined_posix_spawnattr_t +typedef struct +{ + short int _flags; + pid_t _pgrp; + sigset_t _sd; + sigset_t _ss; + struct sched_param _sp; + int _policy; + int __pad[16]; +} posix_spawnattr_t; +# define GNULIB_defined_posix_spawnattr_t 1 +# endif +#endif + + +/* Data structure to contain information about the actions to be + performed in the new process with respect to file descriptors. */ +#if @REPLACE_POSIX_SPAWN@ || (@HAVE_POSIX_SPAWN_FILE_ACTIONS_T@ && !@HAVE_POSIX_SPAWN@) +# define posix_spawn_file_actions_t rpl_posix_spawn_file_actions_t +#endif +#if @REPLACE_POSIX_SPAWN@ || !@HAVE_POSIX_SPAWN_FILE_ACTIONS_T@ || !@HAVE_POSIX_SPAWN@ +# if !GNULIB_defined_posix_spawn_file_actions_t +typedef struct +{ + int _allocated; + int _used; + struct __spawn_action *_actions; + int __pad[16]; +} posix_spawn_file_actions_t; +# define GNULIB_defined_posix_spawn_file_actions_t 1 +# endif +#endif + + +/* Flags to be set in the 'posix_spawnattr_t'. */ +#if @HAVE_POSIX_SPAWN@ +/* Use the values from the system, but provide the missing ones. */ +# ifndef POSIX_SPAWN_SETSCHEDPARAM +# define POSIX_SPAWN_SETSCHEDPARAM 0 +# endif +# ifndef POSIX_SPAWN_SETSCHEDULER +# define POSIX_SPAWN_SETSCHEDULER 0 +# endif +#else +# if @REPLACE_POSIX_SPAWN@ +/* Use the values from the system, for better compatibility. */ +/* But this implementation does not support AIX extensions. */ +# undef POSIX_SPAWN_FORK_HANDLERS +# else +# define POSIX_SPAWN_RESETIDS 0x01 +# define POSIX_SPAWN_SETPGROUP 0x02 +# define POSIX_SPAWN_SETSIGDEF 0x04 +# define POSIX_SPAWN_SETSIGMASK 0x08 +# define POSIX_SPAWN_SETSCHEDPARAM 0x10 +# define POSIX_SPAWN_SETSCHEDULER 0x20 +# endif +#endif +/* A GNU extension. Use the next free bit position. */ +#ifndef POSIX_SPAWN_USEVFORK +# define POSIX_SPAWN_USEVFORK \ + ((POSIX_SPAWN_RESETIDS | (POSIX_SPAWN_RESETIDS - 1) \ + | POSIX_SPAWN_SETPGROUP | (POSIX_SPAWN_SETPGROUP - 1) \ + | POSIX_SPAWN_SETSIGDEF | (POSIX_SPAWN_SETSIGDEF - 1) \ + | POSIX_SPAWN_SETSIGMASK | (POSIX_SPAWN_SETSIGMASK - 1) \ + | POSIX_SPAWN_SETSCHEDPARAM \ + | (POSIX_SPAWN_SETSCHEDPARAM > 0 ? POSIX_SPAWN_SETSCHEDPARAM - 1 : 0) \ + | POSIX_SPAWN_SETSCHEDULER \ + | (POSIX_SPAWN_SETSCHEDULER > 0 ? POSIX_SPAWN_SETSCHEDULER - 1 : 0)) \ + + 1) +#endif +#if !GNULIB_defined_verify_POSIX_SPAWN_USEVFORK_no_overlap +typedef int verify_POSIX_SPAWN_USEVFORK_no_overlap + [(((POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP + | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK + | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER) + & POSIX_SPAWN_USEVFORK) + == 0) + ? 1 : -1]; +# define GNULIB_defined_verify_POSIX_SPAWN_USEVFORK_no_overlap 1 +#endif + + +#if @GNULIB_POSIX_SPAWN@ +/* Spawn a new process executing PATH with the attributes describes in *ATTRP. + Before running the process perform the actions described in FILE-ACTIONS. + + This function is a possible cancellation points and therefore not + marked with __THROW. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn rpl_posix_spawn +# endif +_GL_FUNCDECL_RPL (posix_spawn, int, + (pid_t *_Restrict_ __pid, + const char *_Restrict_ __path, + const posix_spawn_file_actions_t *_Restrict_ __file_actions, + const posix_spawnattr_t *_Restrict_ __attrp, + char *const argv[_Restrict_arr_], + char *const envp[_Restrict_arr_]) + _GL_ARG_NONNULL ((2, 5, 6))); +_GL_CXXALIAS_RPL (posix_spawn, int, + (pid_t *_Restrict_ __pid, + const char *_Restrict_ __path, + const posix_spawn_file_actions_t *_Restrict_ __file_actions, + const posix_spawnattr_t *_Restrict_ __attrp, + char *const argv[_Restrict_arr_], + char *const envp[_Restrict_arr_])); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawn, int, + (pid_t *_Restrict_ __pid, + const char *_Restrict_ __path, + const posix_spawn_file_actions_t *_Restrict_ __file_actions, + const posix_spawnattr_t *_Restrict_ __attrp, + char *const argv[_Restrict_arr_], + char *const envp[_Restrict_arr_]) + _GL_ARG_NONNULL ((2, 5, 6))); +# endif +_GL_CXXALIAS_SYS (posix_spawn, int, + (pid_t *_Restrict_ __pid, + const char *_Restrict_ __path, + const posix_spawn_file_actions_t *_Restrict_ __file_actions, + const posix_spawnattr_t *_Restrict_ __attrp, + char *const argv[_Restrict_arr_], + char *const envp[_Restrict_arr_])); +# endif +_GL_CXXALIASWARN (posix_spawn); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn +# if HAVE_RAW_DECL_POSIX_SPAWN +_GL_WARN_ON_USE (posix_spawn, "posix_spawn is unportable - " + "use gnulib module posix_spawn for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNP@ +/* Similar to 'posix_spawn' but search for FILE in the PATH. + + This function is a possible cancellation points and therefore not + marked with __THROW. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnp rpl_posix_spawnp +# endif +_GL_FUNCDECL_RPL (posix_spawnp, int, + (pid_t *__pid, const char *__file, + const posix_spawn_file_actions_t *__file_actions, + const posix_spawnattr_t *__attrp, + char *const argv[], char *const envp[]) + _GL_ARG_NONNULL ((2, 5, 6))); +_GL_CXXALIAS_RPL (posix_spawnp, int, + (pid_t *__pid, const char *__file, + const posix_spawn_file_actions_t *__file_actions, + const posix_spawnattr_t *__attrp, + char *const argv[], char *const envp[])); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnp, int, + (pid_t *__pid, const char *__file, + const posix_spawn_file_actions_t *__file_actions, + const posix_spawnattr_t *__attrp, + char *const argv[], char *const envp[]) + _GL_ARG_NONNULL ((2, 5, 6))); +# endif +_GL_CXXALIAS_SYS (posix_spawnp, int, + (pid_t *__pid, const char *__file, + const posix_spawn_file_actions_t *__file_actions, + const posix_spawnattr_t *__attrp, + char *const argv[], char *const envp[])); +# endif +_GL_CXXALIASWARN (posix_spawnp); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnp +# if HAVE_RAW_DECL_POSIX_SPAWNP +_GL_WARN_ON_USE (posix_spawnp, "posix_spawnp is unportable - " + "use gnulib module posix_spawnp for portability"); +# endif +#endif + + +#if @GNULIB_POSIX_SPAWNATTR_INIT@ +/* Initialize data structure with attributes for 'spawn' to default values. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_init rpl_posix_spawnattr_init +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_init, int, (posix_spawnattr_t *__attr) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawnattr_init, int, (posix_spawnattr_t *__attr)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_init, int, (posix_spawnattr_t *__attr) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_init, int, (posix_spawnattr_t *__attr)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_init); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_init +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_INIT +_GL_WARN_ON_USE (posix_spawnattr_init, "posix_spawnattr_init is unportable - " + "use gnulib module posix_spawnattr_init for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_DESTROY@ +/* Free resources associated with ATTR. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_destroy rpl_posix_spawnattr_destroy +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_destroy, int, (posix_spawnattr_t *__attr)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_destroy); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_destroy +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_DESTROY +_GL_WARN_ON_USE (posix_spawnattr_destroy, + "posix_spawnattr_destroy is unportable - " + "use gnulib module posix_spawnattr_destroy for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@ +/* Store signal mask for signals with default handling from ATTR in + SIGDEFAULT. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_getsigdefault rpl_posix_spawnattr_getsigdefault +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_getsigdefault, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigdefault) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_getsigdefault, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigdefault)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_getsigdefault, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigdefault) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_getsigdefault, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigdefault)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_getsigdefault); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_getsigdefault +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSIGDEFAULT +_GL_WARN_ON_USE (posix_spawnattr_getsigdefault, + "posix_spawnattr_getsigdefault is unportable - " + "use gnulib module posix_spawnattr_getsigdefault for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@ +/* Set signal mask for signals with default handling in ATTR to SIGDEFAULT. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_setsigdefault rpl_posix_spawnattr_setsigdefault +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_setsigdefault, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigdefault) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_setsigdefault, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigdefault)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_setsigdefault, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigdefault) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_setsigdefault, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigdefault)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_setsigdefault); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_setsigdefault +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSIGDEFAULT +_GL_WARN_ON_USE (posix_spawnattr_setsigdefault, + "posix_spawnattr_setsigdefault is unportable - " + "use gnulib module posix_spawnattr_setsigdefault for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_GETSIGMASK@ +/* Store signal mask for the new process from ATTR in SIGMASK. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_getsigmask rpl_posix_spawnattr_getsigmask +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_getsigmask, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigmask) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_getsigmask, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigmask)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_getsigmask, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigmask) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_getsigmask, int, + (const posix_spawnattr_t *_Restrict_ __attr, + sigset_t *_Restrict_ __sigmask)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_getsigmask); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_getsigmask +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSIGMASK +_GL_WARN_ON_USE (posix_spawnattr_getsigmask, + "posix_spawnattr_getsigmask is unportable - " + "use gnulib module posix_spawnattr_getsigmask for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_SETSIGMASK@ +/* Set signal mask for the new process in ATTR to SIGMASK. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_setsigmask rpl_posix_spawnattr_setsigmask +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_setsigmask, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigmask) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_setsigmask, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigmask)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_setsigmask, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigmask) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_setsigmask, int, + (posix_spawnattr_t *_Restrict_ __attr, + const sigset_t *_Restrict_ __sigmask)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_setsigmask); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_setsigmask +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSIGMASK +_GL_WARN_ON_USE (posix_spawnattr_setsigmask, + "posix_spawnattr_setsigmask is unportable - " + "use gnulib module posix_spawnattr_setsigmask for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_GETFLAGS@ +/* Get flag word from the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_getflags rpl_posix_spawnattr_getflags +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_getflags, int, + (const posix_spawnattr_t *_Restrict_ __attr, + short int *_Restrict_ __flags) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_getflags, int, + (const posix_spawnattr_t *_Restrict_ __attr, + short int *_Restrict_ __flags)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_getflags, int, + (const posix_spawnattr_t *_Restrict_ __attr, + short int *_Restrict_ __flags) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_getflags, int, + (const posix_spawnattr_t *_Restrict_ __attr, + short int *_Restrict_ __flags)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_getflags); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_getflags +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETFLAGS +_GL_WARN_ON_USE (posix_spawnattr_getflags, + "posix_spawnattr_getflags is unportable - " + "use gnulib module posix_spawnattr_getflags for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_SETFLAGS@ +/* Store flags in the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_setflags rpl_posix_spawnattr_setflags +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_setflags, int, + (posix_spawnattr_t *__attr, short int __flags) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawnattr_setflags, int, + (posix_spawnattr_t *__attr, short int __flags)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_setflags, int, + (posix_spawnattr_t *__attr, short int __flags) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_setflags, int, + (posix_spawnattr_t *__attr, short int __flags)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_setflags); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_setflags +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETFLAGS +_GL_WARN_ON_USE (posix_spawnattr_setflags, + "posix_spawnattr_setflags is unportable - " + "use gnulib module posix_spawnattr_setflags for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_GETPGROUP@ +/* Get process group ID from the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_getpgroup rpl_posix_spawnattr_getpgroup +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_getpgroup, int, + (const posix_spawnattr_t *_Restrict_ __attr, + pid_t *_Restrict_ __pgroup) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_getpgroup, int, + (const posix_spawnattr_t *_Restrict_ __attr, + pid_t *_Restrict_ __pgroup)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_getpgroup, int, + (const posix_spawnattr_t *_Restrict_ __attr, + pid_t *_Restrict_ __pgroup) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_getpgroup, int, + (const posix_spawnattr_t *_Restrict_ __attr, + pid_t *_Restrict_ __pgroup)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_getpgroup); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_getpgroup +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETPGROUP +_GL_WARN_ON_USE (posix_spawnattr_getpgroup, + "posix_spawnattr_getpgroup is unportable - " + "use gnulib module posix_spawnattr_getpgroup for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_SETPGROUP@ +/* Store process group ID in the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_setpgroup rpl_posix_spawnattr_setpgroup +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_setpgroup, int, + (posix_spawnattr_t *__attr, pid_t __pgroup) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawnattr_setpgroup, int, + (posix_spawnattr_t *__attr, pid_t __pgroup)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawnattr_setpgroup, int, + (posix_spawnattr_t *__attr, pid_t __pgroup) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_setpgroup, int, + (posix_spawnattr_t *__attr, pid_t __pgroup)); +# endif +_GL_CXXALIASWARN (posix_spawnattr_setpgroup); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_setpgroup +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETPGROUP +_GL_WARN_ON_USE (posix_spawnattr_setpgroup, + "posix_spawnattr_setpgroup is unportable - " + "use gnulib module posix_spawnattr_setpgroup for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@ +/* Get scheduling policy from the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_getschedpolicy rpl_posix_spawnattr_getschedpolicy +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_getschedpolicy, int, + (const posix_spawnattr_t *_Restrict_ __attr, + int *_Restrict_ __schedpolicy) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_getschedpolicy, int, + (const posix_spawnattr_t *_Restrict_ __attr, + int *_Restrict_ __schedpolicy)); +# else +# if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDULER == 0 +_GL_FUNCDECL_SYS (posix_spawnattr_getschedpolicy, int, + (const posix_spawnattr_t *_Restrict_ __attr, + int *_Restrict_ __schedpolicy) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_getschedpolicy, int, + (const posix_spawnattr_t *_Restrict_ __attr, + int *_Restrict_ __schedpolicy)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawnattr_getschedpolicy); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_getschedpolicy +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSCHEDPOLICY +_GL_WARN_ON_USE (posix_spawnattr_getschedpolicy, + "posix_spawnattr_getschedpolicy is unportable - " + "use gnulib module posix_spawnattr_getschedpolicy for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@ +/* Store scheduling policy in the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_setschedpolicy rpl_posix_spawnattr_setschedpolicy +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_setschedpolicy, int, + (posix_spawnattr_t *__attr, int __schedpolicy) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawnattr_setschedpolicy, int, + (posix_spawnattr_t *__attr, int __schedpolicy)); +# else +# if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDULER == 0 +_GL_FUNCDECL_SYS (posix_spawnattr_setschedpolicy, int, + (posix_spawnattr_t *__attr, int __schedpolicy) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_setschedpolicy, int, + (posix_spawnattr_t *__attr, int __schedpolicy)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawnattr_setschedpolicy); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_setschedpolicy +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSCHEDPOLICY +_GL_WARN_ON_USE (posix_spawnattr_setschedpolicy, + "posix_spawnattr_setschedpolicy is unportable - " + "use gnulib module posix_spawnattr_setschedpolicy for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@ +/* Get scheduling parameters from the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_getschedparam rpl_posix_spawnattr_getschedparam +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_getschedparam, int, + (const posix_spawnattr_t *_Restrict_ __attr, + struct sched_param *_Restrict_ __schedparam) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_getschedparam, int, + (const posix_spawnattr_t *_Restrict_ __attr, + struct sched_param *_Restrict_ __schedparam)); +# else +# if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDPARAM == 0 +_GL_FUNCDECL_SYS (posix_spawnattr_getschedparam, int, + (const posix_spawnattr_t *_Restrict_ __attr, + struct sched_param *_Restrict_ __schedparam) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_getschedparam, int, + (const posix_spawnattr_t *_Restrict_ __attr, + struct sched_param *_Restrict_ __schedparam)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawnattr_getschedparam); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_getschedparam +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_GETSCHEDPARAM +_GL_WARN_ON_USE (posix_spawnattr_getschedparam, + "posix_spawnattr_getschedparam is unportable - " + "use gnulib module posix_spawnattr_getschedparam for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@ +/* Store scheduling parameters in the attribute structure. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawnattr_setschedparam rpl_posix_spawnattr_setschedparam +# endif +_GL_FUNCDECL_RPL (posix_spawnattr_setschedparam, int, + (posix_spawnattr_t *_Restrict_ __attr, + const struct sched_param *_Restrict_ __schedparam) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawnattr_setschedparam, int, + (posix_spawnattr_t *_Restrict_ __attr, + const struct sched_param *_Restrict_ __schedparam)); +# else +# if !@HAVE_POSIX_SPAWN@ || POSIX_SPAWN_SETSCHEDPARAM == 0 +_GL_FUNCDECL_SYS (posix_spawnattr_setschedparam, int, + (posix_spawnattr_t *_Restrict_ __attr, + const struct sched_param *_Restrict_ __schedparam) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawnattr_setschedparam, int, + (posix_spawnattr_t *_Restrict_ __attr, + const struct sched_param *_Restrict_ __schedparam)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawnattr_setschedparam); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawnattr_setschedparam +# if HAVE_RAW_DECL_POSIX_SPAWNATTR_SETSCHEDPARAM +_GL_WARN_ON_USE (posix_spawnattr_setschedparam, + "posix_spawnattr_setschedparam is unportable - " + "use gnulib module posix_spawnattr_setschedparam for portability"); +# endif +#endif + + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@ +/* Initialize data structure for file attribute for 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_init rpl_posix_spawn_file_actions_init +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_init, int, + (posix_spawn_file_actions_t *__file_actions) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_init, int, + (posix_spawn_file_actions_t *__file_actions)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_init, int, + (posix_spawn_file_actions_t *__file_actions) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_init, int, + (posix_spawn_file_actions_t *__file_actions)); +# endif +_GL_CXXALIASWARN (posix_spawn_file_actions_init); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_init +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_INIT +_GL_WARN_ON_USE (posix_spawn_file_actions_init, + "posix_spawn_file_actions_init is unportable - " + "use gnulib module posix_spawn_file_actions_init for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@ +/* Free resources associated with FILE-ACTIONS. */ +# if @REPLACE_POSIX_SPAWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_destroy rpl_posix_spawn_file_actions_destroy +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_destroy, int, + (posix_spawn_file_actions_t *__file_actions) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_destroy, int, + (posix_spawn_file_actions_t *__file_actions)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_destroy, int, + (posix_spawn_file_actions_t *__file_actions) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_destroy, int, + (posix_spawn_file_actions_t *__file_actions)); +# endif +_GL_CXXALIASWARN (posix_spawn_file_actions_destroy); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_destroy +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_DESTROY +_GL_WARN_ON_USE (posix_spawn_file_actions_destroy, + "posix_spawn_file_actions_destroy is unportable - " + "use gnulib module posix_spawn_file_actions_destroy for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@ +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'open' for the given file during the 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_addopen rpl_posix_spawn_file_actions_addopen +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_addopen, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd, + const char *_Restrict_ __path, int __oflag, mode_t __mode) + __THROW _GL_ARG_NONNULL ((1, 3))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_addopen, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd, + const char *_Restrict_ __path, int __oflag, mode_t __mode)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_addopen, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd, + const char *_Restrict_ __path, int __oflag, mode_t __mode) + __THROW _GL_ARG_NONNULL ((1, 3))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_addopen, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd, + const char *_Restrict_ __path, int __oflag, mode_t __mode)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawn_file_actions_addopen); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_addopen +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN +_GL_WARN_ON_USE (posix_spawn_file_actions_addopen, + "posix_spawn_file_actions_addopen is unportable - " + "use gnulib module posix_spawn_file_actions_addopen for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@ +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'close' for the given file descriptor during the 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_addclose rpl_posix_spawn_file_actions_addclose +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_addclose, int, + (posix_spawn_file_actions_t *__file_actions, int __fd) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_addclose, int, + (posix_spawn_file_actions_t *__file_actions, int __fd)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_addclose, int, + (posix_spawn_file_actions_t *__file_actions, int __fd) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_addclose, int, + (posix_spawn_file_actions_t *__file_actions, int __fd)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawn_file_actions_addclose); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_addclose +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE +_GL_WARN_ON_USE (posix_spawn_file_actions_addclose, + "posix_spawn_file_actions_addclose is unportable - " + "use gnulib module posix_spawn_file_actions_addclose for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'dup2' for the given file descriptors during the 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_adddup2 rpl_posix_spawn_file_actions_adddup2 +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_adddup2, int, + (posix_spawn_file_actions_t *__file_actions, + int __fd, int __newfd) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_adddup2, int, + (posix_spawn_file_actions_t *__file_actions, + int __fd, int __newfd)); +# else +# if !@HAVE_POSIX_SPAWN@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_adddup2, int, + (posix_spawn_file_actions_t *__file_actions, + int __fd, int __newfd) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_adddup2, int, + (posix_spawn_file_actions_t *__file_actions, + int __fd, int __newfd)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (posix_spawn_file_actions_adddup2); +# endif +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_adddup2 +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 +_GL_WARN_ON_USE (posix_spawn_file_actions_adddup2, + "posix_spawn_file_actions_adddup2 is unportable - " + "use gnulib module posix_spawn_file_actions_adddup2 for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'chdir' to the given directory during the 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_addchdir rpl_posix_spawn_file_actions_addchdir +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_addchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + const char *_Restrict_ __path) + __THROW _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_addchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + const char *_Restrict_ __path)); +# else +# if !@HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_addchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + const char *_Restrict_ __path) + __THROW _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_addchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + const char *_Restrict_ __path)); +# endif +_GL_CXXALIASWARN (posix_spawn_file_actions_addchdir); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_addchdir +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR +_GL_WARN_ON_USE (posix_spawn_file_actions_addchdir, + "posix_spawn_file_actions_addchdir is unportable - " + "use gnulib module posix_spawn_file_actions_addchdir for portability"); +# endif +#endif + +#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'fchdir' to the given directory during the 'spawn' call. */ +# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define posix_spawn_file_actions_addfchdir rpl_posix_spawn_file_actions_addfchdir +# endif +_GL_FUNCDECL_RPL (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd) + __THROW _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd)); +# else +# if !@HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@ +_GL_FUNCDECL_SYS (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd) + __THROW _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (posix_spawn_file_actions_addfchdir, int, + (posix_spawn_file_actions_t *_Restrict_ __file_actions, + int __fd)); +# endif +_GL_CXXALIASWARN (posix_spawn_file_actions_addfchdir); +#elif defined GNULIB_POSIXCHECK +# undef posix_spawn_file_actions_addfchdir +# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR +_GL_WARN_ON_USE (posix_spawn_file_actions_addfchdir, + "posix_spawn_file_actions_addfchdir is unportable - " + "use gnulib module posix_spawn_file_actions_addfchdir for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SPAWN_H */ +#endif /* _@GUARD_PREFIX@_SPAWN_H */ +#endif diff --git a/lib/spawn_faction_addchdir.c b/lib/spawn_faction_addchdir.c new file mode 100644 index 0000000..d798769 --- /dev/null +++ b/lib/spawn_faction_addchdir.c @@ -0,0 +1,70 @@ +/* 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'chdir' to the given directory during the 'spawn' call. */ +int +posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions, + const char *path) +#undef posix_spawn_file_actions_addchdir +{ +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_addchdir_np (file_actions, path); +#else + { + /* Copy PATH, because the caller may free it before calling posix_spawn() + or posix_spawnp(). */ + char *path_copy = strdup (path); + if (path_copy == NULL) + return ENOMEM; + + /* Allocate more memory if needed. */ + if (file_actions->_used == file_actions->_allocated + && __posix_spawn_file_actions_realloc (file_actions) != 0) + { + /* This can only mean we ran out of memory. */ + free (path_copy); + return ENOMEM; + } + + { + struct __spawn_action *rec; + + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_chdir; + rec->action.chdir_action.path = path_copy; + + /* Account for the new entry. */ + ++file_actions->_used; + + return 0; + } + } +#endif +} diff --git a/lib/spawn_faction_addclose.c b/lib/spawn_faction_addclose.c new file mode 100644 index 0000000..7e7cd6c --- /dev/null +++ b/lib/spawn_faction_addclose.c @@ -0,0 +1,69 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#if !_LIBC +# define __sysconf(open_max) getdtablesize () +#endif + +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'close' for the given file descriptor during the 'spawn' call. */ +int +posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions, + int fd) +#undef posix_spawn_file_actions_addclose +{ + int maxfd = __sysconf (_SC_OPEN_MAX); + + /* Test for the validity of the file descriptor. */ + if (fd < 0 || fd >= maxfd) + return EBADF; + +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_addclose (file_actions, fd); +#else + /* Allocate more memory if needed. */ + if (file_actions->_used == file_actions->_allocated + && __posix_spawn_file_actions_realloc (file_actions) != 0) + /* This can only mean we ran out of memory. */ + return ENOMEM; + + { + struct __spawn_action *rec; + + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_close; + rec->action.open_action.fd = fd; + + /* Account for the new entry. */ + ++file_actions->_used; + + return 0; + } +#endif +} diff --git a/lib/spawn_faction_adddup2.c b/lib/spawn_faction_adddup2.c new file mode 100644 index 0000000..8d257ae --- /dev/null +++ b/lib/spawn_faction_adddup2.c @@ -0,0 +1,70 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#if !_LIBC +# define __sysconf(open_max) getdtablesize () +#endif + +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'dup2' for the given file descriptors during the 'spawn' call. */ +int +posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions, + int fd, int newfd) +#undef posix_spawn_file_actions_adddup2 +{ + int maxfd = __sysconf (_SC_OPEN_MAX); + + /* Test for the validity of the file descriptor. */ + if (fd < 0 || newfd < 0 || fd >= maxfd || newfd >= maxfd) + return EBADF; + +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_adddup2 (file_actions, fd, newfd); +#else + /* Allocate more memory if needed. */ + if (file_actions->_used == file_actions->_allocated + && __posix_spawn_file_actions_realloc (file_actions) != 0) + /* This can only mean we ran out of memory. */ + return ENOMEM; + + { + struct __spawn_action *rec; + + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_dup2; + rec->action.dup2_action.fd = fd; + rec->action.dup2_action.newfd = newfd; + + /* Account for the new entry. */ + ++file_actions->_used; + + return 0; + } +#endif +} diff --git a/lib/spawn_faction_addopen.c b/lib/spawn_faction_addopen.c new file mode 100644 index 0000000..8ae9b95 --- /dev/null +++ b/lib/spawn_faction_addopen.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include +#include + +#if !_LIBC +# define __sysconf(open_max) getdtablesize () +#endif + +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + +/* Add an action to FILE-ACTIONS which tells the implementation to call + 'open' for the given file during the 'spawn' call. */ +int +posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions, + int fd, const char *path, int oflag, + mode_t mode) +#undef posix_spawn_file_actions_addopen +{ + int maxfd = __sysconf (_SC_OPEN_MAX); + + /* Test for the validity of the file descriptor. */ + if (fd < 0 || fd >= maxfd) + return EBADF; + +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_addopen (file_actions, fd, path, oflag, mode); +#else + { + /* Copy PATH, because the caller may free it before calling posix_spawn() + or posix_spawnp(). */ + char *path_copy = strdup (path); + if (path_copy == NULL) + return ENOMEM; + + /* Allocate more memory if needed. */ + if (file_actions->_used == file_actions->_allocated + && __posix_spawn_file_actions_realloc (file_actions) != 0) + { + /* This can only mean we ran out of memory. */ + free (path_copy); + return ENOMEM; + } + + { + struct __spawn_action *rec; + + /* Add the new value. */ + rec = &file_actions->_actions[file_actions->_used]; + rec->tag = spawn_do_open; + rec->action.open_action.fd = fd; + rec->action.open_action.path = path_copy; + rec->action.open_action.oflag = oflag; + rec->action.open_action.mode = mode; + + /* Account for the new entry. */ + ++file_actions->_used; + + return 0; + } + } +#endif +} diff --git a/lib/spawn_faction_destroy.c b/lib/spawn_faction_destroy.c new file mode 100644 index 0000000..7ede0a8 --- /dev/null +++ b/lib/spawn_faction_destroy.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include + +#if REPLACE_POSIX_SPAWN +# include "spawn_int.h" +#endif + +/* Initialize data structure for file attribute for 'spawn' call. */ +int +posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions) +#undef posix_spawn_file_actions_destroy +{ +#if !REPLACE_POSIX_SPAWN + return posix_spawn_file_actions_destroy (file_actions); +#else + int i; + + /* Free the paths in the open actions. */ + for (i = 0; i < file_actions->_used; ++i) + { + struct __spawn_action *sa = &file_actions->_actions[i]; + switch (sa->tag) + { + case spawn_do_open: + free (sa->action.open_action.path); + break; + case spawn_do_chdir: + free (sa->action.chdir_action.path); + break; + default: + /* No cleanup required. */ + break; + } + } + + /* Free the array of actions. */ + free (file_actions->_actions); + + return 0; +#endif +} diff --git a/lib/spawn_faction_init.c b/lib/spawn_faction_init.c new file mode 100644 index 0000000..502540c --- /dev/null +++ b/lib/spawn_faction_init.c @@ -0,0 +1,56 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#include "spawn_int.h" + + +/* Function used to increase the size of the allocated array. This + function is called from the 'add'-functions. */ +int +__posix_spawn_file_actions_realloc (posix_spawn_file_actions_t *file_actions) +{ + int newalloc = file_actions->_allocated + 8; + void *newmem = realloc (file_actions->_actions, + newalloc * sizeof (struct __spawn_action)); + + if (newmem == NULL) + /* Not enough memory. */ + return ENOMEM; + + file_actions->_actions = (struct __spawn_action *) newmem; + file_actions->_allocated = newalloc; + + return 0; +} + + +/* Initialize data structure for file attribute for 'spawn' call. */ +int +posix_spawn_file_actions_init (posix_spawn_file_actions_t *file_actions) +{ + /* Simply clear all the elements. */ + memset (file_actions, '\0', sizeof (*file_actions)); + return 0; +} diff --git a/lib/spawn_int.h b/lib/spawn_int.h new file mode 100644 index 0000000..93f2b75 --- /dev/null +++ b/lib/spawn_int.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2000, 2008-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Data structure to contain the action information. */ +struct __spawn_action +{ + enum + { + spawn_do_close, + spawn_do_dup2, + spawn_do_open, + spawn_do_chdir, + spawn_do_fchdir + } tag; + + union + { + struct + { + int fd; + } close_action; + struct + { + int fd; + int newfd; + } dup2_action; + struct + { + int fd; + char *path; + int oflag; + mode_t mode; + } open_action; + struct + { + char *path; + } chdir_action; + struct + { + int fd; + } fchdir_action; + } action; +}; + +#if !_LIBC +# define __posix_spawn_file_actions_realloc gl_posix_spawn_file_actions_realloc +#endif +extern int __posix_spawn_file_actions_realloc (posix_spawn_file_actions_t * + file_actions); + +#if !_LIBC +# define __spawni gl_posix_spawn_internal +#endif +extern int __spawni (pid_t *pid, const char *path, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t *attrp, const char *const argv[], + const char *const envp[], int use_path); diff --git a/lib/spawnattr_destroy.c b/lib/spawnattr_destroy.c new file mode 100644 index 0000000..50552c8 --- /dev/null +++ b/lib/spawnattr_destroy.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +/* Initialize data structure for file attribute for 'spawn' call. */ +int +posix_spawnattr_destroy (posix_spawnattr_t *attr) +{ + /* Nothing to do in the moment. */ + return 0; +} diff --git a/lib/spawnattr_init.c b/lib/spawnattr_init.c new file mode 100644 index 0000000..0ff8eaa --- /dev/null +++ b/lib/spawnattr_init.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include + +/* Initialize data structure for file attribute for 'spawn' call. */ +int +posix_spawnattr_init (posix_spawnattr_t *attr) +{ + /* All elements have to be initialized to the default values which + is generally zero. */ + memset (attr, '\0', sizeof (*attr)); + + return 0; +} diff --git a/lib/spawnattr_setflags.c b/lib/spawnattr_setflags.c new file mode 100644 index 0000000..9ddcf62 --- /dev/null +++ b/lib/spawnattr_setflags.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2000, 2004, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#define ALL_FLAGS (POSIX_SPAWN_RESETIDS \ + | POSIX_SPAWN_SETPGROUP \ + | POSIX_SPAWN_SETSIGDEF \ + | POSIX_SPAWN_SETSIGMASK \ + | POSIX_SPAWN_SETSCHEDPARAM \ + | POSIX_SPAWN_SETSCHEDULER \ + | POSIX_SPAWN_USEVFORK) + +/* Store flags in the attribute structure. */ +int +posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags) +{ + /* Check no invalid bits are set. */ + if (flags & ~ALL_FLAGS) + return EINVAL; + + /* Store the flag word. */ + attr->_flags = flags; + + return 0; +} diff --git a/lib/spawnattr_setpgroup.c b/lib/spawnattr_setpgroup.c new file mode 100644 index 0000000..78d7b93 --- /dev/null +++ b/lib/spawnattr_setpgroup.c @@ -0,0 +1,32 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include + +/* Store process group ID in the attribute structure. */ +int +posix_spawnattr_setpgroup (posix_spawnattr_t *attr, pid_t pgroup) +{ + /* Store the process group ID. */ + attr->_pgrp = pgroup; + + return 0; +} diff --git a/lib/spawnattr_setsigmask.c b/lib/spawnattr_setsigmask.c new file mode 100644 index 0000000..ea05b34 --- /dev/null +++ b/lib/spawnattr_setsigmask.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include + +/* Set signal mask for the new process in ATTR to SIGMASK. */ +int +posix_spawnattr_setsigmask (posix_spawnattr_t *attr, + const sigset_t *sigmask) +{ + /* Copy the sigset_t data to the user buffer. */ + memcpy (&attr->_ss, sigmask, sizeof (sigset_t)); + + return 0; +} diff --git a/lib/spawni.c b/lib/spawni.c new file mode 100644 index 0000000..9bca200 --- /dev/null +++ b/lib/spawni.c @@ -0,0 +1,965 @@ +/* Guts of POSIX spawn interface. Generic POSIX.1 version. + Copyright (C) 2000-2006, 2008-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include +#include "spawn_int.h" + +#include +#include + +#include +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif + +#if _LIBC || HAVE_PATHS_H +# include +#else +# define _PATH_BSHELL BOURNE_SHELL +#endif + +#include +#include +#include +#include + +#if _LIBC +# include +#else +# define close_not_cancel close +# define open_not_cancel open +#endif + +#if _LIBC +# include +#else +# if !HAVE_SETEUID +# define seteuid(id) setresuid (-1, id, -1) +# endif +# if !HAVE_SETEGID +# define setegid(id) setresgid (-1, id, -1) +# endif +# define local_seteuid(id) seteuid (id) +# define local_setegid(id) setegid (id) +#endif + +#if _LIBC +# define alloca __alloca +# define execve __execve +# define dup2 __dup2 +# define fork __fork +# define getgid __getgid +# define getuid __getuid +# define sched_setparam __sched_setparam +# define sched_setscheduler __sched_setscheduler +# define setpgid __setpgid +# define sigaction __sigaction +# define sigismember __sigismember +# define sigprocmask __sigprocmask +# define strchrnul __strchrnul +# define vfork __vfork +#endif + + +/* The Unix standard contains a long explanation of the way to signal + an error after the fork() was successful. Since no new wait status + was wanted there is no way to signal an error using one of the + available methods. The committee chose to signal an error by a + normal program exit with the exit code 127. */ +#define SPAWN_ERROR 127 + + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Native Windows API. */ + +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include + +# include +# include + +# include "filename.h" +# include "concat-filename.h" +# include "findprog.h" +# include "malloca.h" +# include "windows-spawn.h" + +/* Don't assume that UNICODE is not defined. */ +# undef CreateFile +# define CreateFile CreateFileA +# undef STARTUPINFO +# define STARTUPINFO STARTUPINFOA +# undef CreateProcess +# define CreateProcess CreateProcessA + +/* Grows inh_handles->count so that it becomes > newfd. + Returns 0 upon success. In case of failure, -1 is returned, with errno set. + */ +static int +grow_inheritable_handles (struct inheritable_handles *inh_handles, int newfd) +{ + if (inh_handles->allocated <= newfd) + { + size_t new_allocated = 2 * inh_handles->allocated + 1; + if (new_allocated <= newfd) + new_allocated = newfd + 1; + HANDLE *new_handles_array = + (HANDLE *) + realloc (inh_handles->handles, new_allocated * sizeof (HANDLE)); + if (new_handles_array == NULL) + { + errno = ENOMEM; + return -1; + } + unsigned char *new_flags_array = + (unsigned char *) + realloc (inh_handles->flags, new_allocated * sizeof (unsigned char)); + if (new_flags_array == NULL) + { + free (new_handles_array); + errno = ENOMEM; + return -1; + } + inh_handles->allocated = new_allocated; + inh_handles->handles = new_handles_array; + inh_handles->flags = new_flags_array; + } + + HANDLE *handles = inh_handles->handles; + + for (; inh_handles->count <= newfd; inh_handles->count++) + handles[inh_handles->count] = INVALID_HANDLE_VALUE; + + return 0; +} + +/* Reduces inh_handles->count to the minimum needed. */ +static void +shrink_inheritable_handles (struct inheritable_handles *inh_handles) +{ + HANDLE *handles = inh_handles->handles; + + while (inh_handles->count > 3 + && handles[inh_handles->count - 1] == INVALID_HANDLE_VALUE) + inh_handles->count--; +} + +/* Closes all handles in inh_handles. */ +static void +close_inheritable_handles (struct inheritable_handles *inh_handles) +{ + HANDLE *handles = inh_handles->handles; + size_t handles_count = inh_handles->count; + unsigned int fd; + + for (fd = 0; fd < handles_count; fd++) + { + HANDLE handle = handles[fd]; + + if (handle != INVALID_HANDLE_VALUE) + CloseHandle (handle); + } +} + +/* Tests whether a memory region, starting at P and N bytes long, contains only + zeroes. */ +static bool +memiszero (const void *p, size_t n) +{ + const char *cp = p; + for (; n > 0; cp++, n--) + if (*cp != 0) + return 0; + return 1; +} + +/* Tests whether *S contains no signals. */ +static bool +sigisempty (const sigset_t *s) +{ + return memiszero (s, sizeof (sigset_t)); +} + +/* Opens a HANDLE to a file. + Upon failure, returns INVALID_HANDLE_VALUE with errno set. */ +static HANDLE +open_handle (const char *name, int flags, mode_t mode) +{ + /* To ease portability. Like in open.c. */ + if (strcmp (name, "/dev/null") == 0) + name = "NUL"; + + /* 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 INVALID_HANDLE_VALUE; + } + + /* Handle '\\'. */ + if (rlen == 1 && ISSLASH (name[0]) && len >= 2) + { + errno = ENOENT; + return INVALID_HANDLE_VALUE; + } + + 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 INVALID_HANDLE_VALUE; + } + memcpy (malloca_rname, name, rlen); + malloca_rname[rlen] = '\0'; + rname = malloca_rname; + } + + /* For the meaning of the flags, see + */ + /* Open a handle to the file. + CreateFile + + */ + HANDLE handle = + CreateFile (rname, + ((flags & (O_WRONLY | O_RDWR)) != 0 + ? GENERIC_READ | GENERIC_WRITE + : GENERIC_READ), + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + ((flags & O_CREAT) != 0 + ? ((flags & O_EXCL) != 0 + ? CREATE_NEW + : ((flags & O_TRUNC) != 0 ? CREATE_ALWAYS : OPEN_ALWAYS)) + : ((flags & O_TRUNC) != 0 + ? TRUNCATE_EXISTING + : OPEN_EXISTING)), + /* FILE_FLAG_BACKUP_SEMANTICS is useful for opening directories, + which is out-of-scope here. */ + /* 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 */ + FILE_ATTRIBUTE_NORMAL + | ((flags & O_TEMPORARY) != 0 ? FILE_FLAG_DELETE_ON_CLOSE : 0) + | ((flags & O_SEQUENTIAL ) != 0 ? FILE_FLAG_SEQUENTIAL_SCAN : 0) + | ((flags & O_RANDOM) != 0 ? FILE_FLAG_RANDOM_ACCESS : 0), + NULL); + if (handle == INVALID_HANDLE_VALUE) + switch (GetLastError ()) + { + /* 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_NETPATH: /* rname is such as '\\nonexistentserver\share'. */ + 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'. */ + /* 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; + } + + if (malloca_rname != NULL) + { + int saved_errno = errno; + freea (malloca_rname); + errno = saved_errno; + } + return handle; +} + +/* Executes an 'open' action. + Returns 0 upon success. In case of failure, -1 is returned, with errno set. + */ +static int +do_open (struct inheritable_handles *inh_handles, int newfd, + const char *filename, const char *directory, + int flags, mode_t mode, HANDLE curr_process) +{ + if (!(newfd >= 0 && newfd < _getmaxstdio ())) + { + errno = EBADF; + return -1; + } + if (grow_inheritable_handles (inh_handles, newfd) < 0) + return -1; + if (inh_handles->handles[newfd] != INVALID_HANDLE_VALUE + && !CloseHandle (inh_handles->handles[newfd])) + { + errno = EIO; + return -1; + } + if (filename == NULL) + { + errno = EINVAL; + return -1; + } + char *filename_to_free = NULL; + if (directory != NULL && IS_RELATIVE_FILE_NAME (filename)) + { + char *real_filename = concatenated_filename (directory, filename, NULL); + if (real_filename == NULL) + { + errno = ENOMEM; + return -1; + } + filename = real_filename; + filename_to_free = real_filename; + } + HANDLE handle = open_handle (filename, flags, mode); + if (handle == INVALID_HANDLE_VALUE) + { + free (filename_to_free); + return -1; + } + free (filename_to_free); + /* Duplicate the handle, so that it becomes inheritable. */ + if (!DuplicateHandle (curr_process, handle, + curr_process, &inh_handles->handles[newfd], + 0, TRUE, + DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) + { + errno = EBADF; /* arbitrary */ + return -1; + } + inh_handles->flags[newfd] = ((flags & O_APPEND) != 0 ? 32 : 0); + return 0; +} + +/* Executes a 'dup2' action. + Returns 0 upon success. In case of failure, -1 is returned, with errno set. + */ +static int +do_dup2 (struct inheritable_handles *inh_handles, int oldfd, int newfd, + HANDLE curr_process) +{ + if (!(oldfd >= 0 && oldfd < inh_handles->count + && inh_handles->handles[oldfd] != INVALID_HANDLE_VALUE)) + { + errno = EBADF; + return -1; + } + if (!(newfd >= 0 && newfd < _getmaxstdio ())) + { + errno = EBADF; + return -1; + } + if (newfd != oldfd) + { + if (grow_inheritable_handles (inh_handles, newfd) < 0) + return -1; + if (inh_handles->handles[newfd] != INVALID_HANDLE_VALUE + && !CloseHandle (inh_handles->handles[newfd])) + { + errno = EIO; + return -1; + } + /* Duplicate the handle, so that it a forthcoming do_close action on oldfd + has no effect on newfd. */ + if (!DuplicateHandle (curr_process, inh_handles->handles[oldfd], + curr_process, &inh_handles->handles[newfd], + 0, TRUE, DUPLICATE_SAME_ACCESS)) + { + errno = EBADF; /* arbitrary */ + return -1; + } + inh_handles->flags[newfd] = 0; + } + return 0; +} + +/* Executes a 'close' action. + Returns 0 upon success. In case of failure, -1 is returned, with errno set. + */ +static int +do_close (struct inheritable_handles *inh_handles, int fd) +{ + if (!(fd >= 0 && fd < inh_handles->count + && inh_handles->handles[fd] != INVALID_HANDLE_VALUE)) + { + errno = EBADF; + return -1; + } + if (!CloseHandle (inh_handles->handles[fd])) + { + errno = EIO; + return -1; + } + inh_handles->handles[fd] = INVALID_HANDLE_VALUE; + return 0; +} + +int +__spawni (pid_t *pid, const char *prog_filename, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t *attrp, const char *const prog_argv[], + const char *const envp[], int use_path) +{ + /* Validate the arguments. */ + if (prog_filename == NULL + || (attrp != NULL + && ((attrp->_flags & ~POSIX_SPAWN_SETPGROUP) != 0 + || attrp->_pgrp != 0 + || ! sigisempty (&attrp->_sd) + || ! sigisempty (&attrp->_ss) + || attrp->_sp.sched_priority != 0 + || attrp->_policy != 0))) + return EINVAL; + + /* Process group handling: + Native Windows does not have the concept of process group, but it has the + concept of a console attached to a process. + So, we interpret the three cases as follows: + - Flag POSIX_SPAWN_SETPGROUP not set: Means, the child process is in the + same process group as the parent process. We interpret this as a + request to reuse the same console. + - Flag POSIX_SPAWN_SETPGROUP set with attrp->_pgrp == 0: Means the child + process starts a process group of its own. See + + + We interpret this as a request to detach from the current console. + - Flag POSIX_SPAWN_SETPGROUP set with attrp->_pgrp != 0: Means the child + process joins another, existing process group. See + + + We don't support this case; it produces error EINVAL above. */ + /* */ + DWORD process_creation_flags = + (attrp != NULL && (attrp->_flags & POSIX_SPAWN_SETPGROUP) != 0 ? DETACHED_PROCESS : 0); + + char *argv_mem_to_free; + const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free); + if (argv == NULL) + return errno; /* errno is set here */ + argv++; + + /* Compose the command. */ + char *command = compose_command (argv); + if (command == NULL) + { + free (argv_mem_to_free); + return ENOMEM; + } + + /* Copy *ENVP into a contiguous block of memory. */ + char *envblock; + if (envp == NULL) + envblock = NULL; + else + { + envblock = compose_envblock (envp); + if (envblock == NULL) + { + free (command); + free (argv_mem_to_free); + return ENOMEM; + } + } + + /* Set up the array of handles to inherit. + Duplicate each handle, so that a spawn_do_close action (below) has no + effect on the file descriptors of the current process. Alternatively, + we could store, for each handle, a bit that tells whether it is shared + with the current process. But this is simpler. */ + struct inheritable_handles inh_handles; + if (init_inheritable_handles (&inh_handles, true) < 0) + goto failed_1; + + /* Directory in which to execute the new process. */ + const char *directory = NULL; + + /* Execute the file_actions, modifying the inh_handles instead of the + file descriptors of the current process. */ + if (file_actions != NULL) + { + HANDLE curr_process = GetCurrentProcess (); + int cnt; + + for (cnt = 0; cnt < file_actions->_used; ++cnt) + { + struct __spawn_action *action = &file_actions->_actions[cnt]; + + switch (action->tag) + { + case spawn_do_close: + { + int fd = action->action.close_action.fd; + if (do_close (&inh_handles, fd) < 0) + goto failed_2; + } + break; + + case spawn_do_open: + { + int newfd = action->action.open_action.fd; + const char *filename = action->action.open_action.path; + int flags = action->action.open_action.oflag; + mode_t mode = action->action.open_action.mode; + if (do_open (&inh_handles, newfd, filename, directory, + flags, mode, curr_process) + < 0) + goto failed_2; + } + break; + + case spawn_do_dup2: + { + int oldfd = action->action.dup2_action.fd; + int newfd = action->action.dup2_action.newfd; + if (do_dup2 (&inh_handles, oldfd, newfd, curr_process) < 0) + goto failed_2; + } + break; + + case spawn_do_chdir: + { + char *newdir = action->action.chdir_action.path; + if (directory != NULL && IS_RELATIVE_FILE_NAME (newdir)) + { + newdir = concatenated_filename (directory, newdir, NULL); + if (newdir == NULL) + { + errno = ENOMEM; + goto failed_2; + } + } + directory = newdir; + } + break; + + case spawn_do_fchdir: + /* Not supported in this implementation. */ + errno = EINVAL; + goto failed_2; + } + } + } + + /* Reduce inh_handles.count to the minimum needed. */ + shrink_inheritable_handles (&inh_handles); + + /* CreateProcess + */ + /* STARTUPINFO + */ + STARTUPINFO sinfo; + sinfo.cb = sizeof (STARTUPINFO); + sinfo.lpReserved = NULL; + sinfo.lpDesktop = NULL; + sinfo.lpTitle = NULL; + if (compose_handles_block (&inh_handles, &sinfo) < 0) + goto failed_2; + + /* Perform the PATH search now, considering the final DIRECTORY. */ + char *resolved_prog_filename_to_free = NULL; + { + const char *resolved_prog_filename = + find_in_given_path (prog_filename, use_path ? getenv ("PATH") : "", + directory, false); + if (resolved_prog_filename == NULL) + goto failed_3; + if (resolved_prog_filename != prog_filename) + resolved_prog_filename_to_free = (char *) resolved_prog_filename; + prog_filename = resolved_prog_filename; + } + + PROCESS_INFORMATION pinfo; + if (!CreateProcess (prog_filename, command, NULL, NULL, TRUE, + process_creation_flags, envblock, directory, &sinfo, + &pinfo)) + { + DWORD error = GetLastError (); + + free (resolved_prog_filename_to_free); + free (sinfo.lpReserved2); + close_inheritable_handles (&inh_handles); + free_inheritable_handles (&inh_handles); + free (envblock); + free (command); + free (argv_mem_to_free); + + return convert_CreateProcess_error (error); + } + + if (pinfo.hThread) + CloseHandle (pinfo.hThread); + + free (resolved_prog_filename_to_free); + free (sinfo.lpReserved2); + close_inheritable_handles (&inh_handles); + free_inheritable_handles (&inh_handles); + free (envblock); + free (command); + free (argv_mem_to_free); + + if (pid != NULL) + *pid = (intptr_t) pinfo.hProcess; + return 0; + + failed_3: + { + int saved_errno = errno; + free (sinfo.lpReserved2); + close_inheritable_handles (&inh_handles); + free_inheritable_handles (&inh_handles); + free (envblock); + free (command); + free (argv_mem_to_free); + return saved_errno; + } + + failed_2: + { + int saved_errno = errno; + close_inheritable_handles (&inh_handles); + free_inheritable_handles (&inh_handles); + free (envblock); + free (command); + free (argv_mem_to_free); + return saved_errno; + } + + failed_1: + free (envblock); + free (command); + free (argv_mem_to_free); + return errno; +} + +#else + + +/* Spawn a new process executing PATH with the attributes describes in *ATTRP. + Before running the process perform the actions described in FILE-ACTIONS. */ +int +__spawni (pid_t *pid, const char *file, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t *attrp, const char *const argv[], + const char *const envp[], int use_path) +{ + pid_t new_pid; + char *path, *p, *name; + size_t len; + size_t pathlen; + + /* Do this once. */ + short int flags = attrp == NULL ? 0 : attrp->_flags; + + /* Avoid gcc warning + "variable 'flags' might be clobbered by 'longjmp' or 'vfork'" */ + (void) &flags; + + /* Generate the new process. */ +#if HAVE_VFORK + if ((flags & POSIX_SPAWN_USEVFORK) != 0 + /* If no major work is done, allow using vfork. Note that we + might perform the path searching. But this would be done by + a call to execvp(), too, and such a call must be OK according + to POSIX. */ + || ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF + | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER + | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0 + && file_actions == NULL)) + new_pid = vfork (); + else +#endif + new_pid = fork (); + + if (new_pid != 0) + { + if (new_pid < 0) + return errno; + + /* The call was successful. Store the PID if necessary. */ + if (pid != NULL) + *pid = new_pid; + + return 0; + } + + /* Set signal mask. */ + if ((flags & POSIX_SPAWN_SETSIGMASK) != 0 + && sigprocmask (SIG_SETMASK, &attrp->_ss, NULL) != 0) + _exit (SPAWN_ERROR); + + /* Set signal default action. */ + if ((flags & POSIX_SPAWN_SETSIGDEF) != 0) + { + /* We have to iterate over all signals. This could possibly be + done better but it requires system specific solutions since + the sigset_t data type can be very different on different + architectures. */ + int sig; + struct sigaction sa; + + memset (&sa, '\0', sizeof (sa)); + sa.sa_handler = SIG_DFL; + + for (sig = 1; sig <= NSIG; ++sig) + if (sigismember (&attrp->_sd, sig) != 0 + && sigaction (sig, &sa, NULL) != 0) + _exit (SPAWN_ERROR); + + } + +#if (_LIBC ? defined _POSIX_PRIORITY_SCHEDULING : HAVE_SCHED_SETPARAM && HAVE_SCHED_SETSCHEDULER) + /* Set the scheduling algorithm and parameters. */ + if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER)) + == POSIX_SPAWN_SETSCHEDPARAM) + { + if (sched_setparam (0, &attrp->_sp) == -1) + _exit (SPAWN_ERROR); + } + else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0) + { + if (sched_setscheduler (0, attrp->_policy, + (flags & POSIX_SPAWN_SETSCHEDPARAM) != 0 + ? &attrp->_sp : NULL) == -1) + _exit (SPAWN_ERROR); + } +#endif + + /* Set the process group ID. */ + if ((flags & POSIX_SPAWN_SETPGROUP) != 0 + && setpgid (0, attrp->_pgrp) != 0) + _exit (SPAWN_ERROR); + + /* Set the effective user and group IDs. */ + if ((flags & POSIX_SPAWN_RESETIDS) != 0 + && (local_seteuid (getuid ()) != 0 + || local_setegid (getgid ()) != 0)) + _exit (SPAWN_ERROR); + + /* Execute the file actions. */ + if (file_actions != NULL) + { + int cnt; + + for (cnt = 0; cnt < file_actions->_used; ++cnt) + { + struct __spawn_action *action = &file_actions->_actions[cnt]; + + switch (action->tag) + { + case spawn_do_close: + if (close_not_cancel (action->action.close_action.fd) != 0) + /* Signal the error. */ + _exit (SPAWN_ERROR); + break; + + case spawn_do_open: + { + int new_fd = open_not_cancel (action->action.open_action.path, + action->action.open_action.oflag + | O_LARGEFILE, + action->action.open_action.mode); + + if (new_fd == -1) + /* The 'open' call failed. */ + _exit (SPAWN_ERROR); + + /* Make sure the desired file descriptor is used. */ + if (new_fd != action->action.open_action.fd) + { + if (dup2 (new_fd, action->action.open_action.fd) + != action->action.open_action.fd) + /* The 'dup2' call failed. */ + _exit (SPAWN_ERROR); + + if (close_not_cancel (new_fd) != 0) + /* The 'close' call failed. */ + _exit (SPAWN_ERROR); + } + } + break; + + case spawn_do_dup2: + if (dup2 (action->action.dup2_action.fd, + action->action.dup2_action.newfd) + != action->action.dup2_action.newfd) + /* The 'dup2' call failed. */ + _exit (SPAWN_ERROR); + break; + + case spawn_do_chdir: + if (chdir (action->action.chdir_action.path) < 0) + /* The 'chdir' call failed. */ + _exit (SPAWN_ERROR); + break; + + case spawn_do_fchdir: + if (fchdir (action->action.fchdir_action.fd) < 0) + /* The 'fchdir' call failed. */ + _exit (SPAWN_ERROR); + break; + } + } + } + + if (! use_path || strchr (file, '/') != NULL) + { + /* The FILE parameter is actually a path. */ + execve (file, (char * const *) argv, (char * const *) envp); + + /* Oh, oh. 'execve' returns. This is bad. */ + _exit (SPAWN_ERROR); + } + + /* We have to search for FILE on the path. */ + path = getenv ("PATH"); + if (path == NULL) + { +#if HAVE_CONFSTR + /* There is no 'PATH' in the environment. + The default search path is the current directory + followed by the path 'confstr' returns for '_CS_PATH'. */ + len = confstr (_CS_PATH, (char *) NULL, 0); + path = (char *) alloca (1 + len); + path[0] = ':'; + (void) confstr (_CS_PATH, path + 1, len); +#else + /* Pretend that the PATH contains only the current directory. */ + path = ""; +#endif + } + + len = strlen (file) + 1; + pathlen = strlen (path); + name = alloca (pathlen + len + 1); + /* Copy the file name at the top. */ + name = (char *) memcpy (name + pathlen + 1, file, len); + /* And add the slash. */ + *--name = '/'; + + p = path; + do + { + char *startp; + + path = p; + p = strchrnul (path, ':'); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + of 'PATH' means to search the current directory. */ + startp = name + 1; + else + startp = (char *) memcpy (name - (p - path), path, p - path); + + /* Try to execute this name. If it works, execv will not return. */ + execve (startp, (char * const *) argv, (char * const *) envp); + + switch (errno) + { + case EACCES: + case ENOENT: + case ESTALE: + case ENOTDIR: + /* Those errors indicate the file is missing or not executable + by us, in which case we want to just try the next path + directory. */ + break; + + default: + /* Some other error means we found an executable file, but + something went wrong executing it; return the error to our + caller. */ + _exit (SPAWN_ERROR); + } + } + while (*p++ != '\0'); + + /* Return with an error. */ + _exit (SPAWN_ERROR); +} + +#endif diff --git a/lib/spawnp.c b/lib/spawnp.c new file mode 100644 index 0000000..27d9e16 --- /dev/null +++ b/lib/spawnp.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2000, 2009-2022 Free Software Foundation, Inc. + This file is part of 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 . */ + +#include + +/* Specification. */ +#include + +#include "spawn_int.h" + +/* Spawn a new process executing FILE with the attributes describes in *ATTRP. + Before running the process perform the actions described in FILE-ACTIONS. */ +int +posix_spawnp (pid_t *pid, const char *file, + const posix_spawn_file_actions_t *file_actions, + const posix_spawnattr_t *attrp, char *const argv[], + char *const envp[]) +{ + return __spawni (pid, file, file_actions, attrp, + (const char * const *) argv, (const char * const *) envp, 1); +} diff --git a/lib/stat-time.c b/lib/stat-time.c new file mode 100644 index 0000000..3d48a2b --- /dev/null +++ b/lib/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/lib/stat-time.h b/lib/stat-time.h new file mode 100644 index 0000000..6b0088e --- /dev/null +++ b/lib/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/lib/stat-w32.c b/lib/stat-w32.c new file mode 100644 index 0000000..c1a2923 --- /dev/null +++ b/lib/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/lib/stat-w32.h b/lib/stat-w32.h new file mode 100644 index 0000000..0f79d61 --- /dev/null +++ b/lib/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/lib/stat.c b/lib/stat.c new file mode 100644 index 0000000..574489a --- /dev/null +++ b/lib/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/lib/stdalign.in.h b/lib/stdalign.in.h new file mode 100644 index 0000000..3b117df --- /dev/null +++ b/lib/stdalign.in.h @@ -0,0 +1,127 @@ +/* A substitute for ISO C11 . + + Copyright 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 . */ + +/* Written by Paul Eggert and Bruno Haible. */ + +#ifndef _GL_STDALIGN_H +#define _GL_STDALIGN_H + +/* ISO C11 for platforms that lack it. + + References: + ISO C11 (latest free draft + ) + sections 6.5.3.4, 6.7.5, 7.15. + C++11 (latest free draft + ) + section 18.10. */ + +/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment + 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 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. + + Include for offsetof. */ +#include + +/* FreeBSD 9.1 , included by and lots of other + standard headers, defines conflicting implementations of _Alignas + and _Alignof that are no better than ours; override them. */ +#undef _Alignas +#undef _Alignof + +/* 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) +# else + template struct __alignof_helper { char __a; __t __b; }; +# define _Alignof(type) offsetof (__alignof_helper, __b) +# endif +# else +# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) +# endif +#endif +#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 + to the alignment A, where A is an integer constant expression. For + example: + + int alignas (8) foo; + struct s { int a; int alignas (8) bar; }; + + aligns the address of FOO and the offset of BAR to be multiples of 8. + + A should be a power of two that is at least the type's alignment + and at most the implementation's alignment limit. This limit is + 2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable + to MSVC through at least version 10.0, A should be an integer + constant, as MSVC does not support expressions such as 1 << 3. + To be portable to Sun C 5.11, do not align auto variables to + anything stricter than their default alignment. + + The following C11 requirements are not supported here: + + - If A is zero, alignas has no effect. + - alignas can be used multiple times; the strictest one wins. + - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). + + */ + +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 +# if defined __cplusplus && 201103 <= __cplusplus +# define _Alignas(a) alignas (a) +# 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 __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 + +#endif /* _GL_STDALIGN_H */ diff --git a/lib/stdbool.in.h b/lib/stdbool.in.h new file mode 100644 index 0000000..03840f1 --- /dev/null +++ b/lib/stdbool.in.h @@ -0,0 +1,132 @@ +/* Copyright (C) 2001-2003, 2006-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + 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_STDBOOL_H +#define _GL_STDBOOL_H + +/* ISO C 99 for platforms that lack it. */ + +/* Usage suggestions: + + Programs that use should be aware of some limitations + and standards compliance issues. + + Standards compliance: + + - must be #included before 'bool', 'false', 'true' + can be used. + + - You cannot assume that sizeof (bool) == 1. + + - Programs should not undefine the macros bool, true, and false, + as C99 lists that as an "obsolescent feature". + + Limitations of this substitute, when used in a C89 environment: + + - must be #included before the '_Bool' type can be used. + + - You cannot assume that _Bool is a typedef; it might be a macro. + + - Bit-fields of type 'bool' are not supported. Portable code + should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'. + + - In C99, casts and automatic conversions to '_Bool' or 'bool' are + performed in such a way that every nonzero value gets converted + to 'true', and zero gets converted to 'false'. This doesn't work + with this substitute. With this substitute, only the values 0 and 1 + give the expected result when converted to _Bool' or 'bool'. + + - C99 allows the use of (_Bool)0.0 in constant expressions, but + this substitute cannot always provide this property. + + Also, it is suggested that programs use 'bool' rather than '_Bool'; + this isn't required, but 'bool' is more common. */ + + +/* 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 @HAVE__BOOL@: + Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when + the built-in _Bool type is used. See + 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. + If !@HAVE__BOOL@: + Need to define _Bool ourselves. As 'signed char' or as an enum type? + Use of a typedef, with SunPRO C, leads to a stupid + "warning: _Bool is a keyword in ISO C99". + Use of an enum type, with IRIX cc, leads to a stupid + "warning(1185): enumerated type mixed with another type". + Even the existence of an enum type, without a typedef, + "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 + /* With this compiler, trust the _Bool type if the compiler has it. */ +# 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 + typedef enum { false = 0, true = 1 } _Bool; + so that gdb prints values of type 'bool' symbolically. But then + values of type '_Bool' might promote to 'int' or 'unsigned int' + (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' + (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 +#endif + +/* The other macros must be usable in preprocessor directives. */ +#ifdef __cplusplus +# define false false +# define true true +#else +# define false 0 +# define true 1 +#endif + +#define __bool_true_false_are_defined 1 + +#endif /* _GL_STDBOOL_H */ diff --git a/lib/stddef.in.h b/lib/stddef.in.h new file mode 100644 index 0000000..5c9a747 --- /dev/null +++ b/lib/stddef.in.h @@ -0,0 +1,147 @@ +/* A substitute for POSIX 2008 , for platforms that have issues. + + 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. */ + +/* + * POSIX 2008 for platforms that have issues. + * + */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_wchar_t || defined __need_size_t \ + || defined __need_ptrdiff_t || defined __need_NULL \ + || defined __need_wint_t +/* Special invocation convention inside gcc header files. In + particular, gcc provides a version of that blindly + redefines NULL even when __need_wint_t was defined, even though + wint_t is not normally provided by . Hence, we must + remember if special invocation has ever been used to obtain wint_t, + in which case we need to clean up NULL yet again. */ + +# if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T) +# ifdef __need_wint_t +# 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 +/* Normal invocation convention. */ + +# 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@ + +/* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ +# 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 + /* 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 +# 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/lib/stdint.in.h b/lib/stdint.in.h new file mode 100644 index 0000000..eaa7874 --- /dev/null +++ b/lib/stdint.in.h @@ -0,0 +1,740 @@ +/* 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 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. + * + */ + +#ifndef _@GUARD_PREFIX@_STDINT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* When including a system file that in turn includes , + use the system , not our substitute. This avoids + problems with (for example) VMS, whose includes + . */ +#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* On Android (Bionic libc), includes this file before + having defined 'time_t'. Therefore in this case avoid including + 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 _GL_INCLUDING_SYS_TYPES_H +# @INCLUDE_NEXT@ @NEXT_STDINT_H@ +#else + +/* Get those types that are already defined in other system include + files, so that we can "#define int8_t signed char" below without + worrying about a later system include file containing a "typedef + signed char int8_t;" that will get messed up by our macro. Our + macros should all be consistent with the system versions, except + for the "fast" types and macros, which we recommend against using + in public interfaces due to compiler differences. */ + +#if @HAVE_STDINT_H@ +# if defined __sgi && ! defined __c99 + /* Bypass IRIX's if in C89 mode, since it merely annoys users + with "This header file is to be used only for c99 mode compilations" + diagnostics. */ +# define __STDINT_H__ +# endif + + /* Some pre-C++11 implementations need this. */ +# ifdef __cplusplus +# ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS 1 +# endif +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS 1 +# endif +# endif + + /* Other systems may have an incomplete or buggy . + Include it before , since any "#include " + in would reinclude us, skipping our contents because + _@GUARD_PREFIX@_STDINT_H is defined. + The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_STDINT_H@ +#endif + +#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 + +# 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@ + /* Solaris 7 has the types except the *_fast*_t types, and + the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +# include +# endif + +# 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 + +# 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. */ + +/* 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) \ + (((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) + +#if !GNULIB_defined_stdint_types + +/* 7.18.1.1. Exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +# 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 + +# 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 + +# 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 + +/* 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 + int, the code below won't mistakenly define it to be a 64-bit long + 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 +/* 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 +typedef long int gl_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 +# else +# undef int64_t +typedef long long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +# 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 +# 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 +# else +# undef uint64_t +typedef unsigned long long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# endif +# endif + +/* Avoid collision with Solaris 2.5.1 etc. */ +# define _UINT8_T +# define _UINT32_T +# define _UINT64_T + + +/* 7.18.1.2. Minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + 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 + +/* 7.18.1.3. Fastest minimum-width integer types */ + +/* Note: Other substitutes may define these types differently. + It is not recommended to use these types in public header files. */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. The following code normally + 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 +typedef signed char gl_int_fast8_t; +typedef unsigned char gl_uint_fast8_t; + +# 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 +typedef long int gl_int_fast32_t; +typedef unsigned long int gl_uint_fast32_t; +# 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 + +/* 7.18.1.4. Integer types capable of holding object pointers */ + +/* 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; +# endif +# define intptr_t gl_intptr_t +# define uintptr_t gl_uintptr_t +# endif + +/* 7.18.1.5. Greatest-width integer types */ + +/* Note: These types are compiler dependent. It may be unwise to use them in + public header files. */ + +/* If the system defines INTMAX_MAX, assume that intmax_t works, and + 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 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 +typedef long int gl_intmax_t; +# define intmax_t gl_intmax_t +# endif +# endif + +# 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 +typedef unsigned long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +# 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 + to be found in the autoconf macros. */ +typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) + ? 1 : -1]; + +# define GNULIB_defined_stdint_types 1 +# endif /* !GNULIB_defined_stdint_types */ + +/* 7.18.2. Limits of specified-width integer types */ + +/* 7.18.2.1. Limits of exact-width integer types */ + +/* 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 +/* 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 + +# 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 */ + +/* Here we assume a standard architecture where the hardware integer + 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 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 */ + +/* Here we assume a standard architecture where the hardware integer + 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_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 + +/* 7.18.2.4. Limits of integer types capable of holding object pointers */ + +# 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 +# endif +# endif + +# ifndef UINTMAX_MAX +# ifdef UINT64_MAX +# define UINTMAX_MAX UINT64_MAX +# else +# define UINTMAX_MAX UINT32_MAX +# 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_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_SIGNED_MIN (@BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +# define PTRDIFF_MAX \ + _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +# endif + +/* sig_atomic_t limits */ +# 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) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# endif +# else +# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) +# endif + +/* wchar_t limits */ +/* Get WCHAR_MIN, WCHAR_MAX. + This include is not on the top, above, because on OSF/1 4.0 we have a + 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) +# 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 */ +/* 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 */ + +/* 7.18.4.1. Macros for minimum-width integer constants */ +/* According to ISO C 99 Technical Corrigendum 1 */ + +/* 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 +# else +# 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 +# else +# define UINT64_C(x) x##ULL +# 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__ && ...) */ +#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h new file mode 100644 index 0000000..ed32e69 --- /dev/null +++ b/lib/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/lib/stdio-read.c b/lib/stdio-read.c new file mode 100644 index 0000000..85efa0d --- /dev/null +++ b/lib/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/lib/stdio-write.c b/lib/stdio-write.c new file mode 100644 index 0000000..82facf5 --- /dev/null +++ b/lib/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/lib/stdio.in.h b/lib/stdio.in.h new file mode 100644 index 0000000..7b36dac --- /dev/null +++ b/lib/stdio.in.h @@ -0,0 +1,1711 @@ +/* A GNU-like . + + Copyright (C) 2004, 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_FILE || defined __need___FILE || defined _GL_ALREADY_INCLUDING_STDIO_H +/* Special invocation convention: + - Inside glibc header files. + - On OSF/1 5.1 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_STDIO_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_STDIO_H + +#define _GL_ALREADY_INCLUDING_STDIO_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDIO_H@ + +#undef _GL_ALREADY_INCLUDING_STDIO_H + +#ifndef _@GUARD_PREFIX@_STDIO_H +#define _@GUARD_PREFIX@_STDIO_H + +/* Get va_list. Needed on many systems, including glibc 2.8. */ +#include + +#include + +/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 + and eglibc 2.11.2. + 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. */ +#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_SPEC_PRINTF_STANDARD __printf__ +#endif + +/* 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. */ +#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_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 ((_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, + 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_SCANF(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((__gnu_scanf__, formatstring_parameter, first_argument)) +#else +# define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) +#endif + +/* _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_SCANF, + except that it indicates to GCC that the supported format string directives + are the ones of the system scanf(), rather than the ones standardized by + ISO C99 and POSIX. */ +#define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) + +/* 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. */ + +/* Macros for stringification. */ +#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 *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *restrict format, ...)); +# else +# if !@HAVE_DPRINTF@ +_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 *restrict format, ...)); +# endif +_GL_CXXALIASWARN (dprintf); +#elif defined GNULIB_POSIXCHECK +# undef dprintf +# if HAVE_RAW_DECL_DPRINTF +_GL_WARN_ON_USE (dprintf, "dprintf is unportable - " + "use gnulib module dprintf for portability"); +# endif +#endif + +#if @GNULIB_FCLOSE@ +/* Close STREAM and its underlying file descriptor. */ +# if @REPLACE_FCLOSE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fclose rpl_fclose +# endif +_GL_FUNCDECL_RPL (fclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); +_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. */ +_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_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); +#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@ +/* Flush all pending data on STREAM according to POSIX rules. Both + output and seekable input streams are supported. + Note! LOSS OF DATA can occur if fflush is applied on an input stream + that is _not_seekable_ or on an update stream that is _not_seekable_ + and in which the most recent operation was input. Seekability can + be tested with lseek(fileno(fp),0,SEEK_CUR). */ +# if @REPLACE_FFLUSH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fflush rpl_fflush +# endif +_GL_FUNCDECL_RPL (fflush, int, (FILE *gl_stream)); +_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. */ +_GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " + "use gnulib module fflush for portable POSIX compliance"); +#endif + +#if @GNULIB_FGETC@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fgetc +# define fgetc rpl_fgetc +# endif +_GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); +_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@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fgets +# define fgets rpl_fgets +# endif +_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 *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 (@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 *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 +# 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); +# 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@ +# if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \ + || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fprintf rpl_fprintf +# endif +# define GNULIB_overrides_fprintf 1 +# if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ +_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 *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 *restrict fp, const char *restrict format, ...)); +# else +_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 +# undef fprintf +# endif +/* Assume fprintf is always declared. */ +_GL_WARN_ON_USE (fprintf, "fprintf is not always POSIX compliant - " + "use gnulib module fprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_FPURGE@ +/* Discard all pending buffered I/O data on STREAM. + STREAM must not be wide-character oriented. + When discarding pending output, the file position is set back to where it + was before the write calls. When discarding pending input, the file + position is advanced to match the end of the previously read input. + Return 0 if successful. Upon error, return -1 and set errno. */ +# if @REPLACE_FPURGE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fpurge rpl_fpurge +# endif +_GL_FUNCDECL_RPL (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (fpurge, int, (FILE *gl_stream)); +# else +# if !@HAVE_DECL_FPURGE@ +_GL_FUNCDECL_SYS (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (fpurge, int, (FILE *gl_stream)); +# endif +_GL_CXXALIASWARN (fpurge); +#elif defined GNULIB_POSIXCHECK +# undef fpurge +# if HAVE_RAW_DECL_FPURGE +_GL_WARN_ON_USE (fpurge, "fpurge is not always present - " + "use gnulib module fpurge for portability"); +# endif +#endif + +#if @GNULIB_FPUTC@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fputc +# define fputc rpl_fputc +# endif +_GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); +_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@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fputs +# define fputs rpl_fputs +# endif +_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 *restrict string, FILE *restrict stream)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (fputs); +# endif +#endif + +#if @GNULIB_FREAD@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fread +# define fread rpl_fread +# endif +_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 *restrict ptr, size_t s, size_t n, + FILE *restrict stream)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (fread); +# endif +#endif + +#if @GNULIB_FREOPEN@ +# if @REPLACE_FREOPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef freopen +# define freopen rpl_freopen +# endif +_GL_FUNCDECL_RPL (freopen, FILE *, + (const char *restrict filename, const char *restrict mode, + FILE *restrict stream) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (freopen, FILE *, + (const char *restrict filename, const char *restrict mode, + FILE *restrict stream)); +# else +_GL_CXXALIAS_SYS (freopen, FILE *, + (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. */ +_GL_WARN_ON_USE (freopen, + "freopen on native Windows platforms is not POSIX compliant - " + "use gnulib module freopen for portability"); +#endif + +#if @GNULIB_FSCANF@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fscanf +# define fscanf rpl_fscanf +# endif +_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 *restrict stream, const char *restrict format, ...)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (fscanf); +# endif +#endif + + +/* Set up the following warnings, based on which modules are in use. + GNU Coding Standards discourage the use of fseek, since it imposes + an arbitrary limitation on some 32-bit hosts. Remember that the + fseek module depends on the fseeko module, so we only have three + cases to consider: + + 1. The developer is not using either module. Issue a warning under + GNULIB_POSIXCHECK for both functions, to remind them that both + functions have bugs on some systems. _GL_NO_LARGE_FILES has no + impact on this warning. + + 2. The developer is using both modules. They may be unaware of the + arbitrary limitations of fseek, so issue a warning under + GNULIB_POSIXCHECK. On the other hand, they may be using both + modules intentionally, so the developer can define + _GL_NO_LARGE_FILES in the compilation units where the use of fseek + is safe, to silence the warning. + + 3. The developer is using the fseeko module, but not fseek. Gnulib + guarantees that fseek will still work around platform bugs in that + case, but we presume that the developer is aware of the pitfalls of + fseek and was trying to avoid it, so issue a warning even when + GNULIB_POSIXCHECK is undefined. Again, _GL_NO_LARGE_FILES can be + defined to silence the warning in particular compilation units. + In C++ compilations with GNULIB_NAMESPACE, in order to avoid that + fseek gets defined as a macro, it is recommended that the developer + uses the fseek module, even if he is not calling the fseek function. + + Most gnulib clients that perform stream operations should fall into + category 3. */ + +#if @GNULIB_FSEEK@ +# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES +# define _GL_FSEEK_WARN /* Category 2, above. */ +# undef fseek +# endif +# if @REPLACE_FSEEK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fseek +# define fseek rpl_fseek +# endif +_GL_FUNCDECL_RPL (fseek, int, (FILE *fp, long offset, int whence) + _GL_ARG_NONNULL ((1))); +_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@ +# if !@GNULIB_FSEEK@ && !defined _GL_NO_LARGE_FILES +# define _GL_FSEEK_WARN /* Category 3, above. */ +# undef fseek +# endif +# if @REPLACE_FSEEKO@ +/* Provide an fseeko function that is aware of a preceding fflush(), and which + detects pipes. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fseeko +# define fseeko rpl_fseeko +# endif +_GL_FUNCDECL_RPL (fseeko, int, (FILE *fp, off_t offset, int whence) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (fseeko, int, (FILE *fp, off_t offset, int whence)); +# else +# if ! @HAVE_DECL_FSEEKO@ +_GL_FUNCDECL_SYS (fseeko, int, (FILE *fp, off_t offset, int whence) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (fseeko, int, (FILE *fp, off_t offset, int whence)); +# endif +_GL_CXXALIASWARN (fseeko); +#elif defined GNULIB_POSIXCHECK +# define _GL_FSEEK_WARN /* Category 1, above. */ +# undef fseek +# undef fseeko +# if HAVE_RAW_DECL_FSEEKO +_GL_WARN_ON_USE (fseeko, "fseeko is unportable - " + "use gnulib module fseeko for portability"); +# endif +#endif + +#ifdef _GL_FSEEK_WARN +# undef _GL_FSEEK_WARN +/* Here, either fseek is undefined (but C89 guarantees that it is + declared), or it is defined as rpl_fseek (declared above). */ +_GL_WARN_ON_USE (fseek, "fseek cannot handle files larger than 4 GB " + "on 32-bit platforms - " + "use fseeko function for handling of large files"); +#endif + + +/* ftell, ftello. See the comments on fseek/fseeko. */ + +#if @GNULIB_FTELL@ +# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES +# define _GL_FTELL_WARN /* Category 2, above. */ +# undef ftell +# endif +# if @REPLACE_FTELL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ftell +# define ftell rpl_ftell +# endif +_GL_FUNCDECL_RPL (ftell, long, (FILE *fp) _GL_ARG_NONNULL ((1))); +_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@ +# if !@GNULIB_FTELL@ && !defined _GL_NO_LARGE_FILES +# define _GL_FTELL_WARN /* Category 3, above. */ +# undef ftell +# endif +# if @REPLACE_FTELLO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ftello +# define ftello rpl_ftello +# endif +_GL_FUNCDECL_RPL (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (ftello, off_t, (FILE *fp)); +# else +# if ! @HAVE_DECL_FTELLO@ +_GL_FUNCDECL_SYS (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (ftello, off_t, (FILE *fp)); +# endif +_GL_CXXALIASWARN (ftello); +#elif defined GNULIB_POSIXCHECK +# define _GL_FTELL_WARN /* Category 1, above. */ +# undef ftell +# undef ftello +# if HAVE_RAW_DECL_FTELLO +_GL_WARN_ON_USE (ftello, "ftello is unportable - " + "use gnulib module ftello for portability"); +# endif +#endif + +#ifdef _GL_FTELL_WARN +# undef _GL_FTELL_WARN +/* Here, either ftell is undefined (but C89 guarantees that it is + declared), or it is defined as rpl_ftell (declared above). */ +_GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " + "on 32-bit platforms - " + "use ftello function for handling of large files"); +#endif + + +#if @GNULIB_FWRITE@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fwrite +# define fwrite rpl_fwrite +# endif +_GL_FUNCDECL_RPL (fwrite, size_t, + (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 *restrict ptr, size_t s, size_t n, + FILE *restrict stream)); +# else +_GL_CXXALIAS_SYS (fwrite, size_t, + (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++. */ +# if (0 < __USE_FORTIFY_LEVEL \ + && __GLIBC__ == 2 && 4 <= __GLIBC_MINOR__ && __GLIBC_MINOR__ <= 15 \ + && 3 < __GNUC__ + (4 <= __GNUC_MINOR__) \ + && !defined __cplusplus) +# undef fwrite +# undef fwrite_unlocked +extern size_t __REDIRECT (rpl_fwrite, + (const void *__restrict, size_t, size_t, + FILE *__restrict), + fwrite); +extern size_t __REDIRECT (rpl_fwrite_unlocked, + (const void *__restrict, size_t, size_t, + FILE *__restrict), + fwrite_unlocked); +# define fwrite rpl_fwrite +# define fwrite_unlocked rpl_fwrite_unlocked +# endif +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (fwrite); +# endif +#endif + +#if @GNULIB_GETC@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getc +# define getc rpl_fgetc +# endif +_GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); +_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@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getchar +# define getchar rpl_getchar +# endif +_GL_FUNCDECL_RPL (getchar, int, (void)); +_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@ +/* Read input, up to (and including) the next occurrence of DELIMITER, from + STREAM, store it in *LINEPTR (and NUL-terminate it). + *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE + bytes of space. It is realloc'd as necessary. + Return the number of bytes read and stored at *LINEPTR (not including the + NUL terminator), or -1 on error or EOF. */ +# if @REPLACE_GETDELIM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getdelim +# define getdelim rpl_getdelim +# endif +_GL_FUNCDECL_RPL (getdelim, ssize_t, + (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 **restrict lineptr, size_t *restrict linesize, + int delimiter, + FILE *restrict stream)); +# else +# if !@HAVE_DECL_GETDELIM@ +_GL_FUNCDECL_SYS (getdelim, ssize_t, + (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 **restrict lineptr, size_t *restrict linesize, + int delimiter, + FILE *restrict stream)); +# endif +_GL_CXXALIASWARN (getdelim); +#elif defined GNULIB_POSIXCHECK +# undef getdelim +# if HAVE_RAW_DECL_GETDELIM +_GL_WARN_ON_USE (getdelim, "getdelim is unportable - " + "use gnulib module getdelim for portability"); +# endif +#endif + +#if @GNULIB_GETLINE@ +/* Read a line, up to (and including) the next newline, from STREAM, store it + in *LINEPTR (and NUL-terminate it). + *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE + bytes of space. It is realloc'd as necessary. + Return the number of bytes read and stored at *LINEPTR (not including the + NUL terminator), or -1 on error or EOF. */ +# if @REPLACE_GETLINE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getline +# define getline rpl_getline +# endif +_GL_FUNCDECL_RPL (getline, ssize_t, + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream) + _GL_ARG_NONNULL ((1, 2, 3))); +_GL_CXXALIAS_RPL (getline, ssize_t, + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream)); +# else +# if !@HAVE_DECL_GETLINE@ +_GL_FUNCDECL_SYS (getline, ssize_t, + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream) + _GL_ARG_NONNULL ((1, 2, 3))); +# endif +_GL_CXXALIAS_SYS (getline, ssize_t, + (char **restrict lineptr, size_t *restrict linesize, + FILE *restrict stream)); +# endif +# if @HAVE_DECL_GETLINE@ +_GL_CXXALIASWARN (getline); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getline +# if HAVE_RAW_DECL_GETLINE +_GL_WARN_ON_USE (getline, "getline is unportable - " + "use gnulib module getline for portability"); +# endif +#endif + +/* It is very rare that the developer ever has full control of stdin, + so any use of gets warrants an unconditional warning; besides, C11 + removed it. */ +#undef 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; +/* Grow an obstack with formatted output. Return the number of + bytes added to OBS. No trailing nul byte is added, and the + object should be closed with obstack_finish before use. Upon + memory allocation error, call obstack_alloc_failed_handler. Upon + other error, return -1. */ +# if @REPLACE_OBSTACK_PRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define obstack_printf rpl_obstack_printf +# endif +_GL_FUNCDECL_RPL (obstack_printf, int, + (struct obstack *obs, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (obstack_printf, int, + (struct obstack *obs, const char *format, ...)); +# else +# if !@HAVE_DECL_OBSTACK_PRINTF@ +_GL_FUNCDECL_SYS (obstack_printf, int, + (struct obstack *obs, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (obstack_printf, int, + (struct obstack *obs, const char *format, ...)); +# endif +_GL_CXXALIASWARN (obstack_printf); +# if @REPLACE_OBSTACK_PRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define obstack_vprintf rpl_obstack_vprintf +# endif +_GL_FUNCDECL_RPL (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args) + _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)); +# else +# if !@HAVE_DECL_OBSTACK_PRINTF@ +_GL_FUNCDECL_SYS (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (obstack_vprintf); +#endif + +#if @GNULIB_PCLOSE@ +# if !@HAVE_PCLOSE@ +_GL_FUNCDECL_SYS (pclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (pclose, int, (FILE *stream)); +_GL_CXXALIASWARN (pclose); +#elif defined GNULIB_POSIXCHECK +# undef pclose +# if HAVE_RAW_DECL_PCLOSE +_GL_WARN_ON_USE (pclose, "pclose is unportable - " + "use gnulib module pclose for more portability"); +# endif +#endif + +#if @GNULIB_PERROR@ +/* Print a message to standard error, describing the value of ERRNO, + (if STRING is not NULL and not empty) prefixed with STRING and ": ", + and terminated with a newline. */ +# if @REPLACE_PERROR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define perror rpl_perror +# endif +_GL_FUNCDECL_RPL (perror, void, (const char *string)); +_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. */ +_GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - " + "use gnulib module perror for portability"); +#endif + +#if @GNULIB_POPEN@ +# if @REPLACE_POPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef popen +# define popen rpl_popen +# endif +_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@ || __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); +#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__ || 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 *restrict format, ...) + __asm__ (@ASM_SYMBOL_PREFIX@ + _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) + _GL_ARG_NONNULL ((1))); +# else +_GL_FUNCDECL_RPL_1 (__printf__, int, + (const char *restrict format, ...) + __asm__ (@ASM_SYMBOL_PREFIX@ + _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...)); +# else +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define printf rpl_printf +# endif +_GL_FUNCDECL_RPL (printf, int, + (const char *restrict format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (printf, int, (const char *restrict format, ...)); +# endif +# define GNULIB_overrides_printf 1 +# else +_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 +# undef printf +# endif +/* Assume printf is always declared. */ +_GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - " + "use gnulib module printf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_PUTC@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putc +# define putc rpl_fputc +# endif +_GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); +_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@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putchar +# define putchar rpl_putchar +# endif +_GL_FUNCDECL_RPL (putchar, int, (int c)); +_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@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef puts +# define puts rpl_puts +# endif +_GL_FUNCDECL_RPL (puts, int, (const char *string) _GL_ARG_NONNULL ((1))); +_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@ +# if @REPLACE_REMOVE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef remove +# define remove rpl_remove +# endif +_GL_FUNCDECL_RPL (remove, int, (const char *name) _GL_ARG_NONNULL ((1))); +_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. */ +_GL_WARN_ON_USE (remove, "remove cannot handle directories on some platforms - " + "use gnulib module remove for more portability"); +#endif + +#if @GNULIB_RENAME@ +# if @REPLACE_RENAME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef rename +# define rename rpl_rename +# endif +_GL_FUNCDECL_RPL (rename, int, + (const char *old_filename, const char *new_filename) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (rename, int, + (const char *old_filename, const char *new_filename)); +# else +_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. */ +_GL_WARN_ON_USE (rename, "rename is buggy on some platforms - " + "use gnulib module rename for more portability"); +#endif + +#if @GNULIB_RENAMEAT@ +# if @REPLACE_RENAMEAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef renameat +# define renameat rpl_renameat +# endif +_GL_FUNCDECL_RPL (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2) + _GL_ARG_NONNULL ((2, 4))); +_GL_CXXALIAS_RPL (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2)); +# else +# if !@HAVE_RENAMEAT@ +_GL_FUNCDECL_SYS (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2) + _GL_ARG_NONNULL ((2, 4))); +# endif +_GL_CXXALIAS_SYS (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2)); +# endif +_GL_CXXALIASWARN (renameat); +#elif defined GNULIB_POSIXCHECK +# undef renameat +# if HAVE_RAW_DECL_RENAMEAT +_GL_WARN_ON_USE (renameat, "renameat is not portable - " + "use gnulib module renameat for portability"); +# endif +#endif + +#if @GNULIB_SCANF@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# 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 *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 *restrict format, ...)); +# else +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef scanf +# define scanf rpl_scanf +# endif +_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 *restrict format, ...)); +# endif +# else +_GL_CXXALIAS_SYS (scanf, int, (const char *restrict format, ...)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (scanf); +# endif +#endif + +#if @GNULIB_SNPRINTF@ +# if @REPLACE_SNPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define snprintf rpl_snprintf +# endif +# define GNULIB_overrides_snprintf 1 +_GL_FUNCDECL_RPL (snprintf, int, + (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 *restrict str, size_t size, + const char *restrict format, ...)); +# else +# if !@HAVE_DECL_SNPRINTF@ +_GL_FUNCDECL_SYS (snprintf, int, + (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 *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 +_GL_WARN_ON_USE (snprintf, "snprintf is unportable - " + "use gnulib module snprintf for portability"); +# endif +#endif + +/* Some people would argue that all sprintf uses should be warned about + (for example, OpenBSD issues a link warning for it), + since it can cause security holes due to buffer overruns. + However, we believe that sprintf can be used safely, and is more + efficient than snprintf in those safe cases; and as proof of our + belief, we use sprintf in several gnulib modules. So this header + intentionally avoids adding a warning to sprintf except when + GNULIB_POSIXCHECK is defined. */ + +#if @GNULIB_SPRINTF_POSIX@ +# if @REPLACE_SPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define sprintf rpl_sprintf +# endif +# 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 *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. */ +_GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - " + "use gnulib module sprintf-posix for portable " + "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_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); +# 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 + +#if @GNULIB_VASPRINTF@ +/* Write formatted output to a string dynamically allocated with malloc(). + If the memory allocation succeeds, store the address of the string in + *RESULT and return the number of resulting bytes, excluding the trailing + NUL. Upon memory allocation error, or some other error, return -1. */ +# if @REPLACE_VASPRINTF@ +# 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_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (asprintf, int, + (char **result, const char *format, ...)); +# else +# if !@HAVE_VASPRINTF@ +_GL_FUNCDECL_SYS (asprintf, int, + (char **result, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (asprintf, int, + (char **result, const char *format, ...)); +# endif +_GL_CXXALIASWARN (asprintf); +# if @REPLACE_VASPRINTF@ +# 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_STANDARD (2, 0) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (vasprintf, int, + (char **result, const char *format, va_list args)); +# else +# if !@HAVE_VASPRINTF@ +_GL_FUNCDECL_SYS (vasprintf, int, + (char **result, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (vasprintf, int, + (char **result, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vasprintf); +#endif + +#if @GNULIB_VDPRINTF@ +# if @REPLACE_VDPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vdprintf rpl_vdprintf +# endif +_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 *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 *restrict format, va_list args)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (vdprintf); +# endif +#elif defined GNULIB_POSIXCHECK +# undef vdprintf +# if HAVE_RAW_DECL_VDPRINTF +_GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " + "use gnulib module vdprintf for portability"); +# endif +#endif + +#if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@ +# if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \ + || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vfprintf rpl_vfprintf +# endif +# define GNULIB_overrides_vfprintf 1 +# if @GNULIB_VFPRINTF_POSIX@ +_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 *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 *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 *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 +# undef vfprintf +# endif +/* Assume vfprintf is always declared. */ +_GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " + "use gnulib module vfprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_VFSCANF@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef vfscanf +# define vfscanf rpl_vfscanf +# endif +_GL_FUNCDECL_RPL (vfscanf, int, + (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 *restrict stream, + const char *restrict format, va_list args)); +# else +_GL_CXXALIAS_SYS (vfscanf, int, + (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@ +# if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ + || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vprintf rpl_vprintf +# endif +# define GNULIB_overrides_vprintf 1 +# if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ +_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 *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) + _GL_ARG_NONNULL ((1))); +# endif +_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 *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 +# undef vprintf +# endif +/* Assume vprintf is always declared. */ +_GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " + "use gnulib module vprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_VSCANF@ +# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef vscanf +# define vscanf rpl_vscanf +# endif +_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 *restrict format, va_list args)); +# else +_GL_CXXALIAS_SYS (vscanf, int, (const char *restrict format, va_list args)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (vscanf); +# endif +#endif + +#if @GNULIB_VSNPRINTF@ +# if @REPLACE_VSNPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vsnprintf rpl_vsnprintf +# endif +# define GNULIB_overrides_vsnprintf 1 +_GL_FUNCDECL_RPL (vsnprintf, int, + (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 *restrict str, size_t size, + const char *restrict format, va_list args)); +# else +# if !@HAVE_DECL_VSNPRINTF@ +_GL_FUNCDECL_SYS (vsnprintf, int, + (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 *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 +_GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " + "use gnulib module vsnprintf for portability"); +# endif +#endif + +#if @GNULIB_VSPRINTF_POSIX@ +# if @REPLACE_VSPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vsprintf rpl_vsprintf +# endif +# define GNULIB_overrides_vsprintf 1 +_GL_FUNCDECL_RPL (vsprintf, int, + (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 *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 *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. */ +_GL_WARN_ON_USE (vsprintf, "vsprintf is not always POSIX compliant - " + "use gnulib module vsprintf-posix for portable " + "POSIX compliance"); +#endif + +#endif /* _@GUARD_PREFIX@_STDIO_H */ +#endif /* _@GUARD_PREFIX@_STDIO_H */ +#endif diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h new file mode 100644 index 0000000..d52c2f7 --- /dev/null +++ b/lib/stdlib.in.h @@ -0,0 +1,1555 @@ +/* A GNU-like . + + Copyright (C) 1995, 2001-2004, 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined __need_system_stdlib_h || defined __need_malloc_and_calloc +/* Special invocation conventions inside some gnulib header files, + and inside some glibc header files, respectively. */ + +#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_STDLIB_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +#ifndef _@GUARD_PREFIX@_STDLIB_H +#define _@GUARD_PREFIX@_STDLIB_H + +/* NetBSD 5.0 mis-defines NULL. */ +#include + +/* MirBSD 10 defines WEXITSTATUS in , not in . */ +#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS +# include +#endif + +/* 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 defined _WIN32 && !defined __CYGWIN__ +# include +#endif + +#if @GNULIB_RANDOM_R@ + +/* OSF/1 5.1 declares 'struct random_data' in , which is included + from if _REENTRANT is defined. Include it whenever we need + 'struct random_data'. */ +# if @HAVE_RANDOM_H@ +# include +# endif + +# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@ +# include +# endif + +# if !@HAVE_STRUCT_RANDOM_DATA@ +/* Define 'struct random_data'. + But allow multiple gnulib generated replacements to coexist. */ +# if !GNULIB_defined_struct_random_data +struct random_data +{ + int32_t *fptr; /* Front pointer. */ + int32_t *rptr; /* Rear pointer. */ + int32_t *state; /* Array of state values. */ + int rand_type; /* Type of random number generator. */ + int rand_deg; /* Degree of random number generator. */ + int rand_sep; /* Distance between front and rear. */ + int32_t *end_ptr; /* Pointer behind state table. */ +}; +# define GNULIB_defined_struct_random_data 1 +# endif +# endif +#endif + +#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. */ +#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. */ + +/* 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. */ + + +/* Some systems do not define EXIT_*, despite otherwise supporting C89. */ +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif +/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere + with proper operation of xargs. */ +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +#elif EXIT_FAILURE != 1 +# undef EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif + + +#if @GNULIB__EXIT@ +/* Terminate the current process with the given return code, without running + the 'atexit' handlers. */ +# if !@HAVE__EXIT@ +_GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status)); +# endif +_GL_CXXALIAS_SYS (_Exit, void, (int status)); +_GL_CXXALIASWARN (_Exit); +#elif defined GNULIB_POSIXCHECK +# undef _Exit +# if HAVE_RAW_DECL__EXIT +_GL_WARN_ON_USE (_Exit, "_Exit is unportable - " + "use gnulib module _Exit for portability"); +# endif +#endif + + +#if @GNULIB_FREE_POSIX@ +# if @REPLACE_FREE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef free +# define free rpl_free +# endif +_GL_FUNCDECL_RPL (free, void, (void *ptr)); +_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. */ +# if !@HAVE_ATOLL@ +_GL_FUNCDECL_SYS (atoll, long long, (const char *string) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (atoll, long long, (const char *string)); +_GL_CXXALIASWARN (atoll); +#elif defined GNULIB_POSIXCHECK +# undef atoll +# if HAVE_RAW_DECL_ATOLL +_GL_WARN_ON_USE (atoll, "atoll is unportable - " + "use gnulib module atoll for portability"); +# endif +#endif + +#if @GNULIB_CALLOC_POSIX@ +# 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_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); +# 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@ +# if @REPLACE_CANONICALIZE_FILE_NAME@ +# 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_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); +# else +# 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); +#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 + +#if @GNULIB_GETLOADAVG@ +/* Store max(NELEM,3) load average numbers in LOADAVG[]. + The three numbers are the load average of the last 1 minute, the last 5 + minutes, and the last 15 minutes, respectively. + LOADAVG is an array of NELEM numbers. */ +# if !@HAVE_DECL_GETLOADAVG@ +_GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem)); +_GL_CXXALIASWARN (getloadavg); +#elif defined GNULIB_POSIXCHECK +# undef getloadavg +# if HAVE_RAW_DECL_GETLOADAVG +_GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - " + "use gnulib module getloadavg for portability"); +# endif +#endif + +#if @GNULIB_GETSUBOPT@ +/* Assuming *OPTIONP is a comma separated list of elements of the form + "token" or "token=value", getsubopt parses the first of these elements. + If the first element refers to a "token" that is member of the given + NULL-terminated array of tokens: + - It replaces the comma with a NUL byte, updates *OPTIONP to point past + the first option and the comma, sets *VALUEP to the value of the + 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 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) + _GL_ARG_NONNULL ((1, 2, 3))); +# endif +_GL_CXXALIAS_SYS (getsubopt, int, + (char **optionp, char *const *tokens, char **valuep)); +_GL_CXXALIASWARN (getsubopt); +#elif defined GNULIB_POSIXCHECK +# undef getsubopt +# if HAVE_RAW_DECL_GETSUBOPT +_GL_WARN_ON_USE (getsubopt, "getsubopt is unportable - " + "use gnulib module getsubopt for portability"); +# endif +#endif + +#if @GNULIB_GRANTPT@ +/* Change the ownership and access permission of the slave side of the + pseudo-terminal whose master side is specified by FD. */ +# if !@HAVE_GRANTPT@ +_GL_FUNCDECL_SYS (grantpt, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (grantpt, int, (int fd)); +_GL_CXXALIASWARN (grantpt); +#elif defined GNULIB_POSIXCHECK +# undef grantpt +# if HAVE_RAW_DECL_GRANTPT +_GL_WARN_ON_USE (grantpt, "grantpt is not portable - " + "use gnulib module grantpt for portability"); +# endif +#endif + +/* If _GL_USE_STDLIB_ALLOC is nonzero, the including module does not + rely on GNU or POSIX semantics for malloc and realloc (for example, + by never specifying a zero size), so it does not need malloc or + realloc to be redefined. */ +#if @GNULIB_MALLOC_POSIX@ +# 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_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); +# 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. */ +#if @GNULIB_MBTOWC@ +# if @REPLACE_MBTOWC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbtowc +# define mbtowc rpl_mbtowc +# endif +_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 +# 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@ +/* Create a unique temporary directory from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the directory name unique. + Returns TEMPLATE, or a null pointer if it cannot get a unique name. + The directory is created mode 700. */ +# if !@HAVE_MKDTEMP@ +_GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/)); +_GL_CXXALIASWARN (mkdtemp); +#elif defined GNULIB_POSIXCHECK +# undef mkdtemp +# if HAVE_RAW_DECL_MKDTEMP +_GL_WARN_ON_USE (mkdtemp, "mkdtemp is unportable - " + "use gnulib module mkdtemp for portability"); +# endif +#endif + +#if @GNULIB_MKOSTEMP@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + The file is then created, with the specified flags, ensuring it didn't exist + before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if !@HAVE_MKOSTEMP@ +_GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)); +_GL_CXXALIASWARN (mkostemp); +#elif defined GNULIB_POSIXCHECK +# undef mkostemp +# if HAVE_RAW_DECL_MKOSTEMP +_GL_WARN_ON_USE (mkostemp, "mkostemp is unportable - " + "use gnulib module mkostemp for portability"); +# endif +#endif + +#if @GNULIB_MKOSTEMPS@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE before a suffix of length + SUFFIXLEN must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + The file is then created, with the specified flags, ensuring it didn't exist + before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if !@HAVE_MKOSTEMPS@ +_GL_FUNCDECL_SYS (mkostemps, int, + (char * /*template*/, int /*suffixlen*/, int /*flags*/) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkostemps, int, + (char * /*template*/, int /*suffixlen*/, int /*flags*/)); +_GL_CXXALIASWARN (mkostemps); +#elif defined GNULIB_POSIXCHECK +# undef mkostemps +# if HAVE_RAW_DECL_MKOSTEMPS +_GL_WARN_ON_USE (mkostemps, "mkostemps is unportable - " + "use gnulib module mkostemps for portability"); +# endif +#endif + +#if @GNULIB_MKSTEMP@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The file is then created, ensuring it didn't exist before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if @REPLACE_MKSTEMP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mkstemp rpl_mkstemp +# endif +_GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/)); +# else +# if ! @HAVE_MKSTEMP@ +_GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/)); +# endif +_GL_CXXALIASWARN (mkstemp); +#elif defined GNULIB_POSIXCHECK +# undef mkstemp +# if HAVE_RAW_DECL_MKSTEMP +_GL_WARN_ON_USE (mkstemp, "mkstemp is unportable - " + "use gnulib module mkstemp for portability"); +# endif +#endif + +#if @GNULIB_MKSTEMPS@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE prior to a suffix of length + SUFFIXLEN must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The file is then created, ensuring it didn't exist before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if !@HAVE_MKSTEMPS@ +_GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)); +_GL_CXXALIASWARN (mkstemps); +#elif defined GNULIB_POSIXCHECK +# undef mkstemps +# if HAVE_RAW_DECL_MKSTEMPS +_GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - " + "use gnulib module mkstemps for portability"); +# 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. */ +# if !@HAVE_POSIX_OPENPT@ +_GL_FUNCDECL_SYS (posix_openpt, int, (int flags)); +# endif +_GL_CXXALIAS_SYS (posix_openpt, int, (int flags)); +_GL_CXXALIASWARN (posix_openpt); +#elif defined GNULIB_POSIXCHECK +# undef posix_openpt +# if HAVE_RAW_DECL_POSIX_OPENPT +_GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - " + "use gnulib module posix_openpt for portability"); +# endif +#endif + +#if @GNULIB_PTSNAME@ +/* Return the pathname of the pseudo-terminal slave associated with + the master FD is open on, or NULL on errors. */ +# if @REPLACE_PTSNAME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ptsname +# define ptsname rpl_ptsname +# endif +_GL_FUNCDECL_RPL (ptsname, char *, (int fd)); +_GL_CXXALIAS_RPL (ptsname, char *, (int fd)); +# else +# if !@HAVE_PTSNAME@ +_GL_FUNCDECL_SYS (ptsname, char *, (int fd)); +# endif +_GL_CXXALIAS_SYS (ptsname, char *, (int fd)); +# endif +_GL_CXXALIASWARN (ptsname); +#elif defined GNULIB_POSIXCHECK +# undef ptsname +# if HAVE_RAW_DECL_PTSNAME +_GL_WARN_ON_USE (ptsname, "ptsname is not portable - " + "use gnulib module ptsname for portability"); +# endif +#endif + +#if @GNULIB_PTSNAME_R@ +/* Set the pathname of the pseudo-terminal slave associated with + the master FD is open on and return 0, or set errno and return + non-zero on errors. */ +# if @REPLACE_PTSNAME_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ptsname_r +# define ptsname_r rpl_ptsname_r +# endif +_GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); +_GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); +# else +# if !@HAVE_PTSNAME_R@ +_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 +# if HAVE_RAW_DECL_PTSNAME_R +_GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - " + "use gnulib module ptsname_r for portability"); +# endif +#endif + +#if @GNULIB_PUTENV@ +# if @REPLACE_PUTENV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putenv +# define putenv rpl_putenv +# 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@ +# ifndef RAND_MAX +# define RAND_MAX 2147483647 +# endif +# endif +#endif + + +#if @GNULIB_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_CXXALIASWARN (random); +#elif defined GNULIB_POSIXCHECK +# undef random +# if HAVE_RAW_DECL_RANDOM +_GL_WARN_ON_USE (random, "random is unportable - " + "use gnulib module random for portability"); +# endif +#endif + +#if @GNULIB_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_CXXALIASWARN (srandom); +#elif defined GNULIB_POSIXCHECK +# undef srandom +# if HAVE_RAW_DECL_SRANDOM +_GL_WARN_ON_USE (srandom, "srandom is unportable - " + "use gnulib module random for portability"); +# endif +#endif + +#if @GNULIB_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_CXXALIASWARN (initstate); +#elif defined GNULIB_POSIXCHECK +# undef initstate +# 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 @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_CXXALIASWARN (setstate); +#elif defined GNULIB_POSIXCHECK +# undef setstate +# if HAVE_RAW_DECL_SETSTATE +_GL_WARN_ON_USE (setstate, "setstate is unportable - " + "use gnulib module random for portability"); +# endif +#endif + + +#if @GNULIB_RANDOM_R@ +# if @REPLACE_RANDOM_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef random_r +# define random_r rpl_random_r +# endif +_GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result)); +# else +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result)); +# endif +_GL_CXXALIASWARN (random_r); +#elif defined GNULIB_POSIXCHECK +# undef random_r +# if HAVE_RAW_DECL_RANDOM_R +_GL_WARN_ON_USE (random_r, "random_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if @REPLACE_RANDOM_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef srandom_r +# define srandom_r rpl_srandom_r +# endif +_GL_FUNCDECL_RPL (srandom_r, int, + (unsigned int seed, struct random_data *rand_state) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (srandom_r, int, + (unsigned int seed, struct random_data *rand_state)); +# else +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (srandom_r, int, + (unsigned int seed, struct random_data *rand_state) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (srandom_r, int, + (unsigned int seed, struct random_data *rand_state)); +# endif +_GL_CXXALIASWARN (srandom_r); +#elif defined GNULIB_POSIXCHECK +# undef srandom_r +# if HAVE_RAW_DECL_SRANDOM_R +_GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if @REPLACE_RANDOM_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef initstate_r +# define initstate_r rpl_initstate_r +# endif +_GL_FUNCDECL_RPL (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state) + _GL_ARG_NONNULL ((2, 4))); +_GL_CXXALIAS_RPL (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state)); +# else +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state) + _GL_ARG_NONNULL ((2, 4))); +# endif +/* 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 +# undef initstate_r +# if HAVE_RAW_DECL_INITSTATE_R +_GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if @REPLACE_RANDOM_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setstate_r +# define setstate_r rpl_setstate_r +# endif +_GL_FUNCDECL_RPL (setstate_r, int, + (char *arg_state, struct random_data *rand_state) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (setstate_r, int, + (char *arg_state, struct random_data *rand_state)); +# else +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (setstate_r, int, + (char *arg_state, struct random_data *rand_state) + _GL_ARG_NONNULL ((1, 2))); +# endif +/* 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 +# undef setstate_r +# if HAVE_RAW_DECL_SETSTATE_R +_GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + + +#if @GNULIB_REALLOC_POSIX@ +# 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_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); +# 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@ +# if @REPLACE_REALPATH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define realpath rpl_realpath +# endif +_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 *restrict name, char *restrict resolved) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (realpath, char *, + (const char *restrict name, char *restrict resolved)); +# endif +_GL_CXXALIASWARN (realpath); +#elif defined GNULIB_POSIXCHECK +# undef realpath +# if HAVE_RAW_DECL_REALPATH +_GL_WARN_ON_USE (realpath, "realpath is unportable - use gnulib module " + "canonicalize or canonicalize-lgpl for portability"); +# endif +#endif + +#if @GNULIB_RPMATCH@ +/* Test a user response to a question. + Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */ +# if !@HAVE_RPMATCH@ +_GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (rpmatch, int, (const char *response)); +_GL_CXXALIASWARN (rpmatch); +#elif defined GNULIB_POSIXCHECK +# undef rpmatch +# if HAVE_RAW_DECL_RPMATCH +_GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - " + "use gnulib module rpmatch for portability"); +# endif +#endif + +#if @GNULIB_SECURE_GETENV@ +/* Look up NAME in the environment, returning 0 in insecure situations. */ +# if !@HAVE_SECURE_GETENV@ +_GL_FUNCDECL_SYS (secure_getenv, char *, + (char const *name) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name)); +_GL_CXXALIASWARN (secure_getenv); +#elif defined GNULIB_POSIXCHECK +# undef secure_getenv +# if HAVE_RAW_DECL_SECURE_GETENV +_GL_WARN_ON_USE (secure_getenv, "secure_getenv is unportable - " + "use gnulib module secure_getenv for portability"); +# endif +#endif + +#if @GNULIB_SETENV@ +/* Set NAME to VALUE in the environment. + If REPLACE is nonzero, overwrite an existing value. */ +# if @REPLACE_SETENV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setenv +# define setenv rpl_setenv +# endif +_GL_FUNCDECL_RPL (setenv, int, + (const char *name, const char *value, int replace) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (setenv, int, + (const char *name, const char *value, int replace)); +# else +# if !@HAVE_DECL_SETENV@ +_GL_FUNCDECL_SYS (setenv, int, + (const char *name, const char *value, int replace) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (setenv, int, + (const char *name, const char *value, int replace)); +# endif +# if !(@REPLACE_SETENV@ && !@HAVE_DECL_SETENV@) +_GL_CXXALIASWARN (setenv); +# endif +#elif defined GNULIB_POSIXCHECK +# undef setenv +# if HAVE_RAW_DECL_SETENV +_GL_WARN_ON_USE (setenv, "setenv is unportable - " + "use gnulib module setenv for portability"); +# endif +#endif + +#if @GNULIB_STRTOD@ + /* Parse a double from STRING, updating ENDP if appropriate. */ +# if @REPLACE_STRTOD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtod rpl_strtod +# endif +# 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 *restrict str, char **restrict endp) + _GL_ARG_NONNULL ((1))); +# endif +_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 +_GL_WARN_ON_USE (strtod, "strtod is unportable - " + "use gnulib module strtod for portability"); +# 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, + 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 LLONG_MAX or LLONG_MIN, and errno is set + to ERANGE. */ +# 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 *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoll, long long, + (const char *restrict string, char **restrict endptr, + int base)); +# endif +_GL_CXXALIASWARN (strtoll); +#elif defined GNULIB_POSIXCHECK +# undef strtoll +# if HAVE_RAW_DECL_STRTOLL +_GL_WARN_ON_USE (strtoll, "strtoll is unportable - " + "use gnulib module strtoll for portability"); +# 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, + 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 ULLONG_MAX, and errno is set to + ERANGE. */ +# 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 *restrict string, char **restrict endptr, + int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoull, unsigned long long, + (const char *restrict string, char **restrict endptr, + int base)); +# endif +_GL_CXXALIASWARN (strtoull); +#elif defined GNULIB_POSIXCHECK +# undef strtoull +# if HAVE_RAW_DECL_STRTOULL +_GL_WARN_ON_USE (strtoull, "strtoull is unportable - " + "use gnulib module strtoull for portability"); +# endif +#endif + +#if @GNULIB_UNLOCKPT@ +/* Unlock the slave side of the pseudo-terminal whose master side is specified + by FD, so that it can be opened. */ +# if !@HAVE_UNLOCKPT@ +_GL_FUNCDECL_SYS (unlockpt, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (unlockpt, int, (int fd)); +_GL_CXXALIASWARN (unlockpt); +#elif defined GNULIB_POSIXCHECK +# undef unlockpt +# if HAVE_RAW_DECL_UNLOCKPT +_GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - " + "use gnulib module unlockpt for portability"); +# endif +#endif + +#if @GNULIB_UNSETENV@ +/* Remove the variable NAME from the environment. */ +# if @REPLACE_UNSETENV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unsetenv +# define unsetenv rpl_unsetenv +# endif +_GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (unsetenv, int, (const char *name)); +# else +# if !@HAVE_DECL_UNSETENV@ +_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (unsetenv, int, (const char *name)); +# endif +# if !(@REPLACE_UNSETENV@ && !@HAVE_DECL_UNSETENV@) +_GL_CXXALIASWARN (unsetenv); +# endif +#elif defined GNULIB_POSIXCHECK +# undef unsetenv +# if HAVE_RAW_DECL_UNSETENV +_GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - " + "use gnulib module unsetenv for portability"); +# endif +#endif + +/* Convert a wide character to a multibyte character. */ +#if @GNULIB_WCTOMB@ +# if @REPLACE_WCTOMB@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wctomb +# define wctomb rpl_wctomb +# endif +_GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc)); +_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 + + +#endif /* _@GUARD_PREFIX@_STDLIB_H */ +#endif /* _@GUARD_PREFIX@_STDLIB_H */ +#endif diff --git a/lib/stpcpy.c b/lib/stpcpy.c new file mode 100644 index 0000000..434f84a --- /dev/null +++ b/lib/stpcpy.c @@ -0,0 +1,49 @@ +/* stpcpy.c -- copy a string and return pointer to end of new string + Copyright (C) 1992, 1995, 1997-1998, 2006, 2009-2022 Free Software + Foundation, Inc. + + 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 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 + +#undef __stpcpy +#ifdef _LIBC +# undef stpcpy +#endif + +#ifndef weak_alias +# define __stpcpy stpcpy +#endif + +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +char * +__stpcpy (char *dest, const char *src) +{ + register char *d = dest; + register const char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +} +#ifdef weak_alias +weak_alias (__stpcpy, stpcpy) +#endif diff --git a/lib/str-two-way.h b/lib/str-two-way.h new file mode 100644 index 0000000..7ee344a --- /dev/null +++ b/lib/str-two-way.h @@ -0,0 +1,452 @@ +/* Byte-wise substring search, using the Two-Way algorithm. + Copyright (C) 2008-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Eric Blake , 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 . */ + +/* Before including this file, you need to include and + , and define: + 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]. + H is 'unsigned char *', H_L, J, and N_L + are 'size_t'; H_L is an lvalue. For + NUL-terminated searches, H_L can be + modified each iteration to avoid having + to compute the end of H up front. + + For case-insensitivity, you may optionally define: + CMP_FUNC(p1, p2, l) A macro that returns 0 iff the first L + characters of P1 and P2 are equal. + CANON_ELEMENT(c) A macro that canonicalizes an element right after + it has been fetched from one of the two strings. + The argument is an 'unsigned char'; the result + must be an 'unsigned char' as well. + + This file undefines the macros documented above, and defines + LONG_NEEDLE_THRESHOLD. +*/ + +#include +#include + +/* We use the Two-Way string matching algorithm (also known as + Chrochemore-Perrin), which guarantees linear complexity with + constant space. Additionally, for long needles, we also use a bad + character shift table similar to the Boyer-Moore algorithm to + achieve improved (potentially sub-linear) performance. + + 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 + worthwhile. Small needles should not compute a table, since it + adds (1 << CHAR_BIT) + NEEDLE_LEN computations of preparation for a + speedup no greater than a factor of NEEDLE_LEN. The larger the + needle, the better the potential performance gain. On the other + hand, on non-POSIX systems with CHAR_BIT larger than eight, the + memory required for the table is prohibitive. */ +#if CHAR_BIT < 10 +# define LONG_NEEDLE_THRESHOLD 32U +#else +# define LONG_NEEDLE_THRESHOLD SIZE_MAX +#endif + +#ifndef MAX +# define MAX(a, b) ((a < b) ? (b) : (a)) +#endif + +#ifndef CANON_ELEMENT +# define CANON_ELEMENT(c) c +#endif +#ifndef CMP_FUNC +# define CMP_FUNC memcmp +#endif + +/* Perform a critical factorization of NEEDLE, of length NEEDLE_LEN. + Return the index of the first byte in the right half, and set + *PERIOD to the global period of the right half. + + The global period of a string is the smallest index (possibly its + length) at which all remaining bytes in the string are repetitions + of the prefix (the last repetition may be a subset of the prefix). + + When NEEDLE is factored into two halves, a local period is the + length of the smallest word that shares a suffix with the left half + and shares a prefix with the right half. All factorizations of a + non-empty NEEDLE have a local period of at least 1 and no greater + than NEEDLE_LEN. + + A critical factorization has the property that the local period + equals the global period. All strings have at least one critical + factorization with the left half smaller than the global period. + And while some strings have more than one critical factorization, + it is provable that with an ordered alphabet, at least one of the + critical factorizations corresponds to a maximal suffix. + + Given an ordered alphabet, a critical factorization can be computed + in linear time, with 2 * NEEDLE_LEN comparisons, by computing the + shorter of two ordered maximal suffixes. The ordered maximal + suffixes are determined by lexicographic comparison while tracking + periodicity. */ +static size_t +critical_factorization (const unsigned char *needle, size_t needle_len, + size_t *period) +{ + /* Index of last byte of left half, or SIZE_MAX. */ + size_t max_suffix, max_suffix_rev; + size_t j; /* Index into NEEDLE for current candidate suffix. */ + size_t k; /* Offset into current period. */ + size_t p; /* Intermediate period. */ + unsigned char a, b; /* Current comparison bytes. */ + + /* Special case NEEDLE_LEN of 1 or 2 (all callers already filtered + out 0-length needles. */ + if (needle_len < 3) + { + *period = 1; + return needle_len - 1; + } + + /* Invariants: + 0 <= j < NEEDLE_LEN - 1 + -1 <= max_suffix{,_rev} < j (treating SIZE_MAX as if it were signed) + min(max_suffix, max_suffix_rev) < global period of NEEDLE + 1 <= p <= global period of NEEDLE + p == global period of the substring NEEDLE[max_suffix{,_rev}+1...j] + 1 <= k <= p + */ + + /* Perform lexicographic search. */ + max_suffix = SIZE_MAX; + j = 0; + k = p = 1; + while (j + k < needle_len) + { + a = CANON_ELEMENT (needle[j + k]); + b = CANON_ELEMENT (needle[max_suffix + k]); + if (a < b) + { + /* Suffix is smaller, period is entire prefix so far. */ + j += k; + k = 1; + p = j - max_suffix; + } + else if (a == b) + { + /* Advance through repetition of the current period. */ + if (k != p) + ++k; + else + { + j += p; + k = 1; + } + } + else /* b < a */ + { + /* Suffix is larger, start over from current location. */ + max_suffix = j++; + k = p = 1; + } + } + *period = p; + + /* Perform reverse lexicographic search. */ + max_suffix_rev = SIZE_MAX; + j = 0; + k = p = 1; + while (j + k < needle_len) + { + a = CANON_ELEMENT (needle[j + k]); + b = CANON_ELEMENT (needle[max_suffix_rev + k]); + if (b < a) + { + /* Suffix is smaller, period is entire prefix so far. */ + j += k; + k = 1; + p = j - max_suffix_rev; + } + else if (a == b) + { + /* Advance through repetition of the current period. */ + if (k != p) + ++k; + else + { + j += p; + k = 1; + } + } + else /* a < b */ + { + /* Suffix is larger, start over from current location. */ + max_suffix_rev = j++; + k = p = 1; + } + } + + /* Choose the shorter suffix. Return the index of the first byte of + the right half, rather than the last byte of the left half. + + For some examples, 'banana' has two critical factorizations, both + exposed by the two lexicographic extreme suffixes of 'anana' and + 'nana', where both suffixes have a period of 2. On the other + hand, with 'aab' and 'bba', both strings have a single critical + factorization of the last byte, with the suffix having a period + of 1. While the maximal lexicographic suffix of 'aab' is 'b', + the maximal lexicographic suffix of 'bba' is 'ba', which is not a + critical factorization. Conversely, the maximal reverse + lexicographic suffix of 'a' works for 'bba', but not 'ab' for + 'aab'. The shorter suffix of the two will always be a critical + factorization. */ + if (max_suffix_rev + 1 < max_suffix + 1) + return max_suffix + 1; + *period = p; + return max_suffix_rev + 1; +} + +/* Return the first location of non-empty NEEDLE within HAYSTACK, or + NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This + method is optimized for NEEDLE_LEN < LONG_NEEDLE_THRESHOLD. + Performance is guaranteed to be linear, with an initialization cost + of 2 * NEEDLE_LEN comparisons. + + If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at + 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 +two_way_short_needle (const unsigned char *haystack, size_t haystack_len, + const unsigned char *needle, size_t needle_len) +{ + size_t i; /* Index into current byte of NEEDLE. */ + size_t j; /* Index into current window of HAYSTACK. */ + size_t period; /* The period of the right half of needle. */ + size_t suffix; /* The index of the right half of needle. */ + + /* Factor the needle into two halves, such that the left half is + smaller than the global period, and the right half is + periodic (with a period as large as NEEDLE_LEN - suffix). */ + suffix = critical_factorization (needle, needle_len, &period); + + /* Perform the search. Each iteration compares the right half + first. */ + if (CMP_FUNC (needle, needle + period, suffix) == 0) + { + /* Entire needle is periodic; a mismatch in the left half can + only advance by the period, so use memory to avoid rescanning + known occurrences of the period in the right half. */ + size_t memory = 0; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Scan for matches in right half. */ + i = MAX (suffix, memory); + while (i < needle_len && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (memory < i + 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i + 1 < memory + 1) + return (RETURN_TYPE) (haystack + j); + /* No match, so remember how many repetitions of period + on the right half were scanned. */ + j += period; + memory = needle_len - period; + } + else + { + j += i - suffix + 1; + memory = 0; + } + } + } + else + { + /* The two halves of needle are distinct; no extra memory is + required, and any mismatch results in a maximal shift. */ + period = MAX (suffix, needle_len - suffix) + 1; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Scan for matches in right half. */ + i = suffix; + while (i < needle_len && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (i != SIZE_MAX && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i == SIZE_MAX) + return (RETURN_TYPE) (haystack + j); + j += period; + } + else + j += i - suffix + 1; + } + } + return NULL; +} + +/* Return the first location of non-empty NEEDLE within HAYSTACK, or + NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This + method is optimized for LONG_NEEDLE_THRESHOLD <= NEEDLE_LEN. + Performance is guaranteed to be linear, with an initialization cost + of 3 * NEEDLE_LEN + (1 << CHAR_BIT) operations. + + If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at + most 2 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, + and sublinear performance O(HAYSTACK_LEN / NEEDLE_LEN) is possible. + 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 +two_way_long_needle (const unsigned char *haystack, size_t haystack_len, + const unsigned char *needle, size_t needle_len) +{ + size_t i; /* Index into current byte of NEEDLE. */ + size_t j; /* Index into current window of HAYSTACK. */ + size_t period; /* The period of the right half of needle. */ + size_t suffix; /* The index of the right half of needle. */ + size_t shift_table[1U << CHAR_BIT]; /* See below. */ + + /* Factor the needle into two halves, such that the left half is + smaller than the global period, and the right half is + periodic (with a period as large as NEEDLE_LEN - suffix). */ + suffix = critical_factorization (needle, needle_len, &period); + + /* Populate shift_table. For each possible byte value c, + shift_table[c] is the distance from the last occurrence of c to + the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE. + shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0. */ + for (i = 0; i < 1U << CHAR_BIT; i++) + shift_table[i] = needle_len; + for (i = 0; i < needle_len; i++) + shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1; + + /* Perform the search. Each iteration compares the right half + first. */ + if (CMP_FUNC (needle, needle + period, suffix) == 0) + { + /* Entire needle is periodic; a mismatch in the left half can + only advance by the period, so use memory to avoid rescanning + known occurrences of the period in the right half. */ + size_t memory = 0; + size_t shift; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Check the last byte first; if it does not match, then + shift to the next possible match location. */ + shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])]; + if (0 < shift) + { + if (memory && shift < period) + { + /* Since needle is periodic, but the last period has + a byte out of place, there can be no match until + after the mismatch. */ + shift = needle_len - period; + } + memory = 0; + j += shift; + continue; + } + /* Scan for matches in right half. The last byte has + already been matched, by virtue of the shift table. */ + i = MAX (suffix, memory); + while (i < needle_len - 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len - 1 <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (memory < i + 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i + 1 < memory + 1) + return (RETURN_TYPE) (haystack + j); + /* No match, so remember how many repetitions of period + on the right half were scanned. */ + j += period; + memory = needle_len - period; + } + else + { + j += i - suffix + 1; + memory = 0; + } + } + } + else + { + /* The two halves of needle are distinct; no extra memory is + required, and any mismatch results in a maximal shift. */ + size_t shift; + period = MAX (suffix, needle_len - suffix) + 1; + j = 0; + while (AVAILABLE (haystack, haystack_len, j, needle_len)) + { + /* Check the last byte first; if it does not match, then + shift to the next possible match location. */ + shift = shift_table[CANON_ELEMENT (haystack[j + needle_len - 1])]; + if (0 < shift) + { + j += shift; + continue; + } + /* Scan for matches in right half. The last byte has + already been matched, by virtue of the shift table. */ + i = suffix; + while (i < needle_len - 1 && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + ++i; + if (needle_len - 1 <= i) + { + /* Scan for matches in left half. */ + i = suffix - 1; + while (i != SIZE_MAX && (CANON_ELEMENT (needle[i]) + == CANON_ELEMENT (haystack[i + j]))) + --i; + if (i == SIZE_MAX) + return (RETURN_TYPE) (haystack + j); + j += period; + } + else + j += i - suffix + 1; + } + } + return NULL; +} + +#undef AVAILABLE +#undef CANON_ELEMENT +#undef CMP_FUNC +#undef MAX +#undef RETURN_TYPE diff --git a/lib/strcasecmp.c b/lib/strcasecmp.c new file mode 100644 index 0000000..a85a2b1 --- /dev/null +++ b/lib/strcasecmp.c @@ -0,0 +1,62 @@ +/* Case-insensitive string comparison function. + Copyright (C) 1998-1999, 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. + Note: This function does not work with multibyte strings! */ + +int +strcasecmp (const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = TOLOWER (*p1); + c2 = TOLOWER (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* 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 _GL_CMP (c1, c2); +} diff --git a/lib/strchrnul.c b/lib/strchrnul.c new file mode 100644 index 0000000..2141b3e --- /dev/null +++ b/lib/strchrnul.c @@ -0,0 +1,142 @@ +/* Searching in a string. + Copyright (C) 2003, 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 + +/* Find the first occurrence of C in S or the final NUL byte. */ +char * +strchrnul (const char *s, int c_in) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned char c; + + c = (unsigned char) c_in; + if (!c) + return rawmemchr (s, 0); + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + (size_t) char_ptr % sizeof (longword) != 0; + ++char_ptr) + if (!*char_ptr || *char_ptr == c) + return (char *) char_ptr; + + longword_ptr = (const longword *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will + test a longword at a time. The tricky part is testing if *any of + the four* bytes in the longword in question are equal to NUL or + c. We first use an xor with repeated_c. This reduces the task + to testing whether *any of the four* bytes in longword1 or + longword2 is zero. + + Let's consider longword1. We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + The test whether any byte in longword1 or longword2 is zero is equivalent + to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine + this into a single test, whether (tmp1 | tmp2) is nonzero. + + This test can read more than one byte beyond the end of a string, + depending on where the terminating NUL is encountered. However, + this is considered safe since the initialization phase ensured + that the read will be aligned, therefore, the read will not cross + page boundaries and will not cause a fault. */ + + while (1) + { + longword longword1 = *longword_ptr ^ repeated_c; + longword longword2 = *longword_ptr; + + if (((((longword1 - repeated_one) & ~longword1) + | ((longword2 - repeated_one) & ~longword2)) + & (repeated_one << 7)) != 0) + break; + longword_ptr++; + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that one of the sizeof (longword) bytes + starting at char_ptr is == 0 or == c. On little-endian machines, + we could determine the first such byte without any further memory + accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. + Choose code that works in both cases. */ + + char_ptr = (unsigned char *) longword_ptr; + while (*char_ptr && (*char_ptr != c)) + char_ptr++; + return (char *) char_ptr; +} diff --git a/lib/strchrnul.valgrind b/lib/strchrnul.valgrind new file mode 100644 index 0000000..1cf50ec --- /dev/null +++ b/lib/strchrnul.valgrind @@ -0,0 +1,28 @@ +# Suppress a valgrind message about use of uninitialized memory in strchrnul(). + +# 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 . + +# This use is OK because it provides only a speedup. +{ + strchrnul-value4 + Memcheck:Value4 + fun:strchrnul +} +{ + strchrnul-value8 + Memcheck:Value8 + fun:strchrnul +} diff --git a/lib/strdup.c b/lib/strdup.c new file mode 100644 index 0000000..2a0df02 --- /dev/null +++ b/lib/strdup.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1991, 1996-1998, 2002-2004, 2006-2007, 2009-2022 Free Software + Foundation, Inc. + + This file is part of 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 _LIBC +# include +#endif + +/* Get specification. */ +#include + +#include + +#undef __strdup +#ifdef _LIBC +# undef strdup +#endif + +#ifndef weak_alias +# define __strdup strdup +#endif + +/* Duplicate S, returning an identical malloc'd string. */ +char * +__strdup (const char *s) +{ + size_t len = strlen (s) + 1; + void *new = malloc (len); + + if (new == NULL) + return NULL; + + return (char *) memcpy (new, s, len); +} +#ifdef libc_hidden_def +libc_hidden_def (__strdup) +#endif +#ifdef weak_alias +weak_alias (__strdup, strdup) +#endif diff --git a/lib/streq.h b/lib/streq.h new file mode 100644 index 0000000..49f73c1 --- /dev/null +++ b/lib/streq.h @@ -0,0 +1,176 @@ +/* Optimized string comparison. + Copyright (C) 2001-2002, 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 Bruno Haible . */ + +#ifndef _GL_STREQ_H +#define _GL_STREQ_H + +#include + +/* STREQ_OPT allows to optimize string comparison with a small literal string. + STREQ_OPT (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + is semantically equivalent to + strcmp (s, "EUC-KR") == 0 + just faster. */ + +/* Help GCC to generate good code for string comparisons with + immediate strings. */ +#if (defined __GNUC__ || defined __clang__) && defined __OPTIMIZE__ + +static inline int +streq9 (const char *s1, const char *s2) +{ + return strcmp (s1 + 9, s2 + 9) == 0; +} + +static inline int +streq8 (const char *s1, const char *s2, char s28) +{ + if (s1[8] == s28) + { + if (s28 == 0) + return 1; + else + return streq9 (s1, s2); + } + else + return 0; +} + +static inline int +streq7 (const char *s1, const char *s2, char s27, char s28) +{ + if (s1[7] == s27) + { + if (s27 == 0) + return 1; + else + return streq8 (s1, s2, s28); + } + else + return 0; +} + +static inline int +streq6 (const char *s1, const char *s2, char s26, char s27, char s28) +{ + if (s1[6] == s26) + { + if (s26 == 0) + return 1; + else + return streq7 (s1, s2, s27, s28); + } + else + return 0; +} + +static inline int +streq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) +{ + if (s1[5] == s25) + { + if (s25 == 0) + return 1; + else + return streq6 (s1, s2, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[4] == s24) + { + if (s24 == 0) + return 1; + else + return streq5 (s1, s2, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[3] == s23) + { + if (s23 == 0) + return 1; + else + return streq4 (s1, s2, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[2] == s22) + { + if (s22 == 0) + return 1; + else + return streq3 (s1, s2, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[1] == s21) + { + if (s21 == 0) + return 1; + else + return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[0] == s20) + { + if (s20 == 0) + return 1; + else + return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) + +#else + +#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + (strcmp (s1, s2) == 0) + +#endif + +#endif /* _GL_STREQ_H */ diff --git a/lib/strerror-override.c b/lib/strerror-override.c new file mode 100644 index 0000000..6be1afd --- /dev/null +++ b/lib/strerror-override.c @@ -0,0 +1,306 @@ +/* strerror-override.c --- POSIX compatible system error routine + + Copyright (C) 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 . */ + +/* Written by Bruno Haible , 2010. */ + +#include + +#include "strerror-override.h" + +#include + +#if GNULIB_defined_EWINSOCK /* native Windows platforms */ +# if HAVE_WINSOCK2_H +# include +# 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 * +strerror_override (int errnum) +{ + /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ + switch (errnum) + { +# if REPLACE_STRERROR_0 + case 0: + return "Success"; +# endif + +# if GNULIB_defined_ESOCK /* native Windows platforms with older */ + case EINPROGRESS: + return "Operation now in progress"; + case EALREADY: + return "Operation already in progress"; + case ENOTSOCK: + return "Socket operation on non-socket"; + case EDESTADDRREQ: + return "Destination address required"; + case EMSGSIZE: + return "Message too long"; + case EPROTOTYPE: + return "Protocol wrong type for socket"; + case ENOPROTOOPT: + return "Protocol not available"; + case EPROTONOSUPPORT: + return "Protocol not supported"; + case EOPNOTSUPP: + return "Operation not supported"; + case EAFNOSUPPORT: + return "Address family not supported by protocol"; + case EADDRINUSE: + return "Address already in use"; + case EADDRNOTAVAIL: + return "Cannot assign requested address"; + case ENETDOWN: + return "Network is down"; + case ENETUNREACH: + return "Network is unreachable"; + case ECONNRESET: + return "Connection reset by peer"; + case ENOBUFS: + return "No buffer space available"; + case EISCONN: + return "Transport endpoint is already connected"; + case ENOTCONN: + return "Transport endpoint is not connected"; + case ETIMEDOUT: + return "Connection timed out"; + case ECONNREFUSED: + return "Connection refused"; + case ELOOP: + return "Too many levels of symbolic links"; + case EHOSTUNREACH: + return "No route to host"; + case EWOULDBLOCK: + return "Operation would block"; +# endif +# if GNULIB_defined_ESTREAMS /* native Windows platforms with older */ + case ETXTBSY: + return "Text file busy"; + case ENODATA: + return "No data available"; + case ENOSR: + return "Out of streams resources"; + case ENOSTR: + return "Device not a stream"; + case ETIME: + return "Timer expired"; + case EOTHER: + return "Other error"; +# endif +# if GNULIB_defined_EWINSOCK /* native Windows platforms */ + case ESOCKTNOSUPPORT: + return "Socket type not supported"; + case EPFNOSUPPORT: + return "Protocol family not supported"; + case ESHUTDOWN: + return "Cannot send after transport endpoint shutdown"; + case ETOOMANYREFS: + return "Too many references: cannot splice"; + case EHOSTDOWN: + return "Host is down"; + case EPROCLIM: + return "Too many processes"; + case EUSERS: + return "Too many users"; + case EDQUOT: + return "Disk quota exceeded"; + case ESTALE: + return "Stale NFS file handle"; + case EREMOTE: + return "Object is remote"; +# if HAVE_WINSOCK2_H + /* WSA_INVALID_HANDLE maps to EBADF */ + /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ + /* WSA_INVALID_PARAMETER maps to EINVAL */ + case WSA_OPERATION_ABORTED: + return "Overlapped operation aborted"; + case WSA_IO_INCOMPLETE: + return "Overlapped I/O event object not in signaled state"; + case WSA_IO_PENDING: + return "Overlapped operations will complete later"; + /* WSAEINTR maps to EINTR */ + /* WSAEBADF maps to EBADF */ + /* WSAEACCES maps to EACCES */ + /* WSAEFAULT maps to EFAULT */ + /* WSAEINVAL maps to EINVAL */ + /* WSAEMFILE maps to EMFILE */ + /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ + /* WSAEINPROGRESS maps to EINPROGRESS */ + /* WSAEALREADY maps to EALREADY */ + /* WSAENOTSOCK maps to ENOTSOCK */ + /* WSAEDESTADDRREQ maps to EDESTADDRREQ */ + /* WSAEMSGSIZE maps to EMSGSIZE */ + /* WSAEPROTOTYPE maps to EPROTOTYPE */ + /* WSAENOPROTOOPT maps to ENOPROTOOPT */ + /* WSAEPROTONOSUPPORT maps to EPROTONOSUPPORT */ + /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ + /* WSAEOPNOTSUPP maps to EOPNOTSUPP */ + /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ + /* WSAEAFNOSUPPORT maps to EAFNOSUPPORT */ + /* WSAEADDRINUSE maps to EADDRINUSE */ + /* WSAEADDRNOTAVAIL maps to EADDRNOTAVAIL */ + /* WSAENETDOWN maps to ENETDOWN */ + /* WSAENETUNREACH maps to ENETUNREACH */ + /* WSAENETRESET maps to ENETRESET */ + /* WSAECONNABORTED maps to ECONNABORTED */ + /* WSAECONNRESET maps to ECONNRESET */ + /* WSAENOBUFS maps to ENOBUFS */ + /* WSAEISCONN maps to EISCONN */ + /* WSAENOTCONN maps to ENOTCONN */ + /* WSAESHUTDOWN is ESHUTDOWN */ + /* WSAETOOMANYREFS is ETOOMANYREFS */ + /* WSAETIMEDOUT maps to ETIMEDOUT */ + /* WSAECONNREFUSED maps to ECONNREFUSED */ + /* WSAELOOP maps to ELOOP */ + /* WSAENAMETOOLONG maps to ENAMETOOLONG */ + /* WSAEHOSTDOWN is EHOSTDOWN */ + /* WSAEHOSTUNREACH maps to EHOSTUNREACH */ + /* WSAENOTEMPTY maps to ENOTEMPTY */ + /* WSAEPROCLIM is EPROCLIM */ + /* WSAEUSERS is EUSERS */ + /* WSAEDQUOT is EDQUOT */ + /* WSAESTALE is ESTALE */ + /* WSAEREMOTE is EREMOTE */ + case WSASYSNOTREADY: + return "Network subsystem is unavailable"; + case WSAVERNOTSUPPORTED: + return "Winsock.dll version out of range"; + case WSANOTINITIALISED: + return "Successful WSAStartup not yet performed"; + case WSAEDISCON: + return "Graceful shutdown in progress"; + case WSAENOMORE: case WSA_E_NO_MORE: + return "No more results"; + case WSAECANCELLED: case WSA_E_CANCELLED: + return "Call was canceled"; + case WSAEINVALIDPROCTABLE: + return "Procedure call table is invalid"; + case WSAEINVALIDPROVIDER: + return "Service provider is invalid"; + case WSAEPROVIDERFAILEDINIT: + return "Service provider failed to initialize"; + case WSASYSCALLFAILURE: + return "System call failure"; + case WSASERVICE_NOT_FOUND: + return "Service not found"; + case WSATYPE_NOT_FOUND: + return "Class type not found"; + case WSAEREFUSED: + return "Database query was refused"; + case WSAHOST_NOT_FOUND: + return "Host not found"; + case WSATRY_AGAIN: + return "Nonauthoritative host not found"; + case WSANO_RECOVERY: + return "Nonrecoverable error"; + case WSANO_DATA: + return "Valid name, no data record of requested type"; + /* WSA_QOS_* omitted */ +# endif +# endif + +# if GNULIB_defined_ENOMSG + case ENOMSG: + return "No message of desired type"; +# endif + +# if GNULIB_defined_EIDRM + case EIDRM: + return "Identifier removed"; +# endif + +# if GNULIB_defined_ENOLINK + case ENOLINK: + return "Link has been severed"; +# endif + +# if GNULIB_defined_EPROTO + case EPROTO: + return "Protocol error"; +# endif + +# if GNULIB_defined_EMULTIHOP + case EMULTIHOP: + return "Multihop attempted"; +# endif + +# if GNULIB_defined_EBADMSG + case EBADMSG: + return "Bad message"; +# endif + +# if GNULIB_defined_EOVERFLOW + case EOVERFLOW: + return "Value too large for defined data type"; +# endif + +# if GNULIB_defined_ENOTSUP + case ENOTSUP: + return "Not supported"; +# endif + +# if GNULIB_defined_ENETRESET + case ENETRESET: + return "Network dropped connection on reset"; +# endif + +# if GNULIB_defined_ECONNABORTED + case ECONNABORTED: + return "Software caused connection abort"; +# endif + +# if GNULIB_defined_ESTALE + case ESTALE: + return "Stale NFS file handle"; +# endif + +# if GNULIB_defined_EDQUOT + case EDQUOT: + return "Disk quota exceeded"; +# endif + +# if GNULIB_defined_ECANCELED + case ECANCELED: + return "Operation canceled"; +# endif + +# if GNULIB_defined_EOWNERDEAD + case EOWNERDEAD: + return "Owner died"; +# endif + +# if GNULIB_defined_ENOTRECOVERABLE + case ENOTRECOVERABLE: + return "State not recoverable"; +# endif + +# if GNULIB_defined_EILSEQ + case EILSEQ: + return "Invalid or incomplete multibyte or wide character"; +# endif + + default: + return NULL; + } +} + +#endif diff --git a/lib/strerror-override.h b/lib/strerror-override.h new file mode 100644 index 0000000..d010d27 --- /dev/null +++ b/lib/strerror-override.h @@ -0,0 +1,57 @@ +/* strerror-override.h --- POSIX compatible system error routine + + Copyright (C) 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 . */ + +#ifndef _GL_STRERROR_OVERRIDE_H +# define _GL_STRERROR_OVERRIDE_H + +# include +# include + +/* Reasonable buffer size that should never trigger ERANGE; if this + proves too small, we intentionally abort(), to remind us to fix + this value. */ +# define STACKBUF_LEN 256 + +/* If ERRNUM maps to an errno value defined by gnulib, return a string + describing the error. Otherwise return NULL. */ +# if REPLACE_STRERROR_0 \ + || GNULIB_defined_ESOCK \ + || GNULIB_defined_ESTREAMS \ + || GNULIB_defined_EWINSOCK \ + || GNULIB_defined_ENOMSG \ + || GNULIB_defined_EIDRM \ + || GNULIB_defined_ENOLINK \ + || GNULIB_defined_EPROTO \ + || GNULIB_defined_EMULTIHOP \ + || GNULIB_defined_EBADMSG \ + || GNULIB_defined_EOVERFLOW \ + || GNULIB_defined_ENOTSUP \ + || GNULIB_defined_ENETRESET \ + || GNULIB_defined_ECONNABORTED \ + || GNULIB_defined_ESTALE \ + || GNULIB_defined_EDQUOT \ + || GNULIB_defined_ECANCELED \ + || GNULIB_defined_EOWNERDEAD \ + || GNULIB_defined_ENOTRECOVERABLE \ + || GNULIB_defined_EILSEQ +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/lib/strerror.c b/lib/strerror.c new file mode 100644 index 0000000..67c5216 --- /dev/null +++ b/lib/strerror.c @@ -0,0 +1,71 @@ +/* strerror.c --- POSIX compatible system error routine + + 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 +#include +#include + +#include "intprops.h" +#include "strerror-override.h" +#include "verify.h" + +/* Use the system functions, not the gnulib overrides in this file. */ +#undef sprintf + +char * +strerror (int n) +#undef strerror +{ + static char buf[STACKBUF_LEN]; + size_t len; + + /* Cast away const, due to the historical signature of strerror; + callers should not be modifying the string. */ + const char *msg = strerror_override (n); + if (msg) + return (char *) msg; + + msg = strerror (n); + + /* Our strerror_r implementation might use the system's strerror + buffer, so all other clients of strerror have to see the error + copied into a buffer that we manage. This is not thread-safe, + even if the system strerror is, but portable programs shouldn't + be using strerror if they care about thread-safety. */ + if (!msg || !*msg) + { + static char const fmt[] = "Unknown error %d"; + verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); + sprintf (buf, fmt, n); + errno = EINVAL; + return buf; + } + + /* Fix STACKBUF_LEN if this ever aborts. */ + len = strlen (msg); + if (sizeof buf <= len) + abort (); + + memcpy (buf, msg, len + 1); + return buf; +} diff --git a/lib/strerror_r.c b/lib/strerror_r.c new file mode 100644 index 0000000..85a2189 --- /dev/null +++ b/lib/strerror_r.c @@ -0,0 +1,451 @@ +/* strerror_r.c --- POSIX compatible system error routine + + Copyright (C) 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 . */ + +/* Written by Bruno Haible , 2010. */ + +#include + +/* Enable declaration of sys_nerr and sys_errlist in on NetBSD. */ +#define _NETBSD_SOURCE 1 + +/* Specification. */ +#include + +#include +#include +#include +#if !HAVE_SNPRINTF +# include +#endif + +#include "strerror-override.h" + +#if STRERROR_R_CHAR_P + +# if HAVE___XPG_STRERROR_R +_GL_EXTERN_C int __xpg_strerror_r (int errnum, char *buf, size_t buflen); +# endif + +#elif HAVE_DECL_STRERROR_R + +/* The system's strerror_r function's API is OK, except that its third argument + is 'int', not 'size_t', or its return type is wrong. */ + +# include + +#else + +/* Use the system's strerror(). Exclude glibc and cygwin because the + system strerror_r has the wrong return type, and cygwin 1.7.9 + strerror_r clobbers strerror. */ +# undef strerror + +# if defined __NetBSD__ || defined __hpux || (defined _WIN32 && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__ + +/* No locking needed. */ + +/* Get catgets internationalization functions. */ +# if HAVE_CATGETS +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Get sys_nerr, sys_errlist on HP-UX (otherwise only declared in C++ mode). + Get sys_nerr, sys_errlist on IRIX (otherwise only declared with _SGIAPI). */ +# if defined __hpux || defined __sgi +extern int sys_nerr; +extern char *sys_errlist[]; +# endif + +/* Get sys_nerr on Solaris. */ +# if defined __sun && !defined _LP64 +extern int sys_nerr; +# endif + +#ifdef __cplusplus +} +#endif + +# else + +# include "glthread/lock.h" + +/* This lock protects the buffer returned by strerror(). We assume that + no other uses of strerror() exist in the program. */ +gl_lock_define_initialized(static, strerror_lock) + +# endif + +#endif + +/* On MSVC, there is no snprintf() function, just a _snprintf(). + It is of lower quality, but sufficient for the simple use here. + We only have to make sure to NUL terminate the result (_snprintf + does not NUL terminate, like strncpy). */ +#if !HAVE_SNPRINTF +static int +local_snprintf (char *buf, size_t buflen, const char *format, ...) +{ + va_list args; + int result; + + va_start (args, format); + result = _vsnprintf (buf, buflen, format, args); + va_end (args); + if (buflen > 0 && (result < 0 || result >= buflen)) + buf[buflen - 1] = '\0'; + return result; +} +# undef snprintf +# define snprintf local_snprintf +#endif + +/* Copy as much of MSG into BUF as possible, without corrupting errno. + Return 0 if MSG fit in BUFLEN, otherwise return ERANGE. */ +static int +safe_copy (char *buf, size_t buflen, const char *msg) +{ + size_t len = strlen (msg); + size_t moved = len < buflen ? len : buflen - 1; + + /* Although POSIX lets memmove corrupt errno, we don't + know of any implementation where this is a real problem. */ + memmove (buf, msg, moved); + buf[moved] = '\0'; + return len < buflen ? 0 : ERANGE; +} + + +int +strerror_r (int errnum, char *buf, size_t buflen) +#undef strerror_r +{ + /* Filter this out now, so that rest of this replacement knows that + there is room for a non-empty message and trailing NUL. */ + if (buflen <= 1) + { + if (buflen) + *buf = '\0'; + return ERANGE; + } + *buf = '\0'; + + /* Check for gnulib overrides. */ + { + char const *msg = strerror_override (errnum); + + if (msg) + return safe_copy (buf, buflen, msg); + } + + { + int ret; + int saved_errno = errno; + +#if STRERROR_R_CHAR_P + + { + ret = 0; + +# if HAVE___XPG_STRERROR_R + ret = __xpg_strerror_r (errnum, buf, buflen); + if (ret < 0) + ret = errno; +# endif + + if (!*buf) + { + /* glibc 2.13 would not touch buf on err, so we have to fall + back to GNU strerror_r which always returns a thread-safe + untruncated string to (partially) copy into our buf. */ + char *errstring = strerror_r (errnum, buf, buflen); + ret = errstring ? safe_copy (buf, buflen, errstring) : errno; + } + } + +#elif HAVE_DECL_STRERROR_R + + if (buflen > INT_MAX) + buflen = INT_MAX; + +# ifdef __hpux + /* On HP-UX 11.31, strerror_r always fails when buflen < 80; it + also fails to change buf on EINVAL. */ + { + char stackbuf[80]; + + if (buflen < sizeof stackbuf) + { + ret = strerror_r (errnum, stackbuf, sizeof stackbuf); + if (ret == 0) + ret = safe_copy (buf, buflen, stackbuf); + } + else + ret = strerror_r (errnum, buf, buflen); + } +# else + ret = strerror_r (errnum, buf, buflen); + + /* Some old implementations may return (-1, EINVAL) instead of EINVAL. + But on Haiku, valid error numbers are negative. */ +# if !defined __HAIKU__ + if (ret < 0) + ret = errno; +# endif +# endif + +# if defined _AIX || defined __HAIKU__ + /* AIX and Haiku return 0 rather than ERANGE when truncating strings; try + again until we are sure we got the entire string. */ + if (!ret && strlen (buf) == buflen - 1) + { + char stackbuf[STACKBUF_LEN]; + size_t len; + strerror_r (errnum, stackbuf, sizeof stackbuf); + len = strlen (stackbuf); + /* STACKBUF_LEN should have been large enough. */ + if (len + 1 == sizeof stackbuf) + abort (); + if (buflen <= len) + ret = ERANGE; + } +# else + /* Solaris 10 does not populate buf on ERANGE. OpenBSD 4.7 + truncates early on ERANGE rather than return a partial integer. + We prefer the maximal string. We set buf[0] earlier, and we + know of no implementation that modifies buf to be an + unterminated string, so this strlen should be portable in + practice (rather than pulling in a safer strnlen). */ + if (ret == ERANGE && strlen (buf) < buflen - 1) + { + char stackbuf[STACKBUF_LEN]; + + /* STACKBUF_LEN should have been large enough. */ + if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE) + abort (); + safe_copy (buf, buflen, stackbuf); + } +# endif + +#else /* strerror_r is not declared. */ + + /* Try to do what strerror (errnum) does, but without clobbering the + buffer used by strerror(). */ + +# if defined __NetBSD__ || defined __hpux || (defined _WIN32 && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Windows, Cygwin */ + + /* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE + and above. + HP-UX: sys_nerr, sys_errlist are declared explicitly above. + native Windows: sys_nerr, sys_errlist are declared in . + Cygwin: sys_nerr, sys_errlist are declared in . */ + if (errnum >= 0 && errnum < sys_nerr) + { +# if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) +# if defined __NetBSD__ + nl_catd catd = catopen ("libc", NL_CAT_LOCALE); + const char *errmsg = + (catd != (nl_catd)-1 + ? catgets (catd, 1, errnum, sys_errlist[errnum]) + : sys_errlist[errnum]); +# endif +# if defined __hpux + nl_catd catd = catopen ("perror", NL_CAT_LOCALE); + const char *errmsg = + (catd != (nl_catd)-1 + ? catgets (catd, 1, 1 + errnum, sys_errlist[errnum]) + : sys_errlist[errnum]); +# endif +# else + const char *errmsg = sys_errlist[errnum]; +# endif + if (errmsg == NULL || *errmsg == '\0') + ret = EINVAL; + else + ret = safe_copy (buf, buflen, errmsg); +# if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) + if (catd != (nl_catd)-1) + catclose (catd); +# endif + } + else + ret = EINVAL; + +# elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */ + + /* For a valid error number, the system's strerror() function returns + a pointer to a not copied string, not to a buffer. */ + if (errnum >= 0 && errnum < sys_nerr) + { + char *errmsg = strerror (errnum); + + if (errmsg == NULL || *errmsg == '\0') + ret = EINVAL; + else + ret = safe_copy (buf, buflen, errmsg); + } + else + ret = EINVAL; + +# else + + gl_lock_lock (strerror_lock); + + { + char *errmsg = strerror (errnum); + + /* For invalid error numbers, strerror() on + - IRIX 6.5 returns NULL, + - HP-UX 11 returns an empty string. */ + if (errmsg == NULL || *errmsg == '\0') + ret = EINVAL; + else + ret = safe_copy (buf, buflen, errmsg); + } + + gl_lock_unlock (strerror_lock); + +# endif + +#endif + +#if defined _WIN32 && !defined __CYGWIN__ + /* MSVC 14 defines names for many error codes in the range 100..140, + but _sys_errlist contains strings only for the error codes + < _sys_nerr = 43. */ + if (ret == EINVAL) + { + const char *errmsg; + + switch (errnum) + { + case 100 /* EADDRINUSE */: + errmsg = "Address already in use"; + break; + case 101 /* EADDRNOTAVAIL */: + errmsg = "Cannot assign requested address"; + break; + case 102 /* EAFNOSUPPORT */: + errmsg = "Address family not supported by protocol"; + break; + case 103 /* EALREADY */: + errmsg = "Operation already in progress"; + break; + case 105 /* ECANCELED */: + errmsg = "Operation canceled"; + break; + case 106 /* ECONNABORTED */: + errmsg = "Software caused connection abort"; + break; + case 107 /* ECONNREFUSED */: + errmsg = "Connection refused"; + break; + case 108 /* ECONNRESET */: + errmsg = "Connection reset by peer"; + break; + case 109 /* EDESTADDRREQ */: + errmsg = "Destination address required"; + break; + case 110 /* EHOSTUNREACH */: + errmsg = "No route to host"; + break; + case 112 /* EINPROGRESS */: + errmsg = "Operation now in progress"; + break; + case 113 /* EISCONN */: + errmsg = "Transport endpoint is already connected"; + break; + case 114 /* ELOOP */: + errmsg = "Too many levels of symbolic links"; + break; + case 115 /* EMSGSIZE */: + errmsg = "Message too long"; + break; + case 116 /* ENETDOWN */: + errmsg = "Network is down"; + break; + case 117 /* ENETRESET */: + errmsg = "Network dropped connection on reset"; + break; + case 118 /* ENETUNREACH */: + errmsg = "Network is unreachable"; + break; + case 119 /* ENOBUFS */: + errmsg = "No buffer space available"; + break; + case 123 /* ENOPROTOOPT */: + errmsg = "Protocol not available"; + break; + case 126 /* ENOTCONN */: + errmsg = "Transport endpoint is not connected"; + break; + case 128 /* ENOTSOCK */: + errmsg = "Socket operation on non-socket"; + break; + case 129 /* ENOTSUP */: + errmsg = "Not supported"; + break; + case 130 /* EOPNOTSUPP */: + errmsg = "Operation not supported"; + break; + case 132 /* EOVERFLOW */: + errmsg = "Value too large for defined data type"; + break; + case 133 /* EOWNERDEAD */: + errmsg = "Owner died"; + break; + case 134 /* EPROTO */: + errmsg = "Protocol error"; + break; + case 135 /* EPROTONOSUPPORT */: + errmsg = "Protocol not supported"; + break; + case 136 /* EPROTOTYPE */: + errmsg = "Protocol wrong type for socket"; + break; + case 138 /* ETIMEDOUT */: + errmsg = "Connection timed out"; + break; + case 140 /* EWOULDBLOCK */: + errmsg = "Operation would block"; + break; + default: + errmsg = NULL; + break; + } + if (errmsg != NULL) + ret = safe_copy (buf, buflen, errmsg); + } +#endif + + if (ret == EINVAL && !*buf) + { +#if defined __HAIKU__ + /* For consistency with perror(). */ + snprintf (buf, buflen, "Unknown Application Error (%d)", errnum); +#else + snprintf (buf, buflen, "Unknown error %d", errnum); +#endif + } + + errno = saved_errno; + return ret; + } +} diff --git a/lib/string.in.h b/lib/string.in.h new file mode 100644 index 0000000..c943294 --- /dev/null +++ b/lib/string.in.h @@ -0,0 +1,1269 @@ +/* A GNU-like . + + Copyright (C) 1995-1996, 2001-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_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 + +/* NetBSD 5.0 mis-defines NULL. */ +#include + +/* MirBSD defines mbslen as a macro. */ +#if @GNULIB_MBSLEN@ && defined __MirBSD__ +# include +#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__ \ + && ! defined __GLIBC__ +# 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 +_GL_EXTERN_C void __cdecl free (void *); +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +#else +# if defined _MSC_VER +_GL_EXTERN_C void __cdecl free (void *); +# else +_GL_EXTERN_C void free (void *); +# 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@ +# if !@HAVE_FFSL@ +_GL_FUNCDECL_SYS (ffsl, int, (long int i)); +# endif +_GL_CXXALIAS_SYS (ffsl, int, (long int i)); +_GL_CXXALIASWARN (ffsl); +#elif defined GNULIB_POSIXCHECK +# undef ffsl +# if HAVE_RAW_DECL_FFSL +_GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module"); +# endif +#endif + + +/* Find the index of the least-significant set bit. */ +#if @GNULIB_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 +_GL_CXXALIAS_SYS (ffsll, int, (long long int i)); +# endif +_GL_CXXALIASWARN (ffsll); +#elif defined GNULIB_POSIXCHECK +# undef ffsll +# if HAVE_RAW_DECL_FFSLL +_GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module"); +# endif +#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) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); +# else + /* 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); } */ +_GL_CXXALIAS_SYS_CAST2 (memchr, + void *, (void const *__s, int __c, size_t __n), + 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)); +_GL_CXXALIASWARN1 (memchr, void const *, + (void const *__s, int __c, size_t __n)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (memchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memchr +/* Assume memchr is always declared. */ +_GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " + "use gnulib module memchr for portability" ); +#endif + +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +#if @GNULIB_MEMMEM@ +# if @REPLACE_MEMMEM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define memmem rpl_memmem +# endif +_GL_FUNCDECL_RPL (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 3))); +_GL_CXXALIAS_RPL (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len)); +# else +# if ! @HAVE_DECL_MEMMEM@ +_GL_FUNCDECL_SYS (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 3))); +# endif +_GL_CXXALIAS_SYS (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len)); +# endif +_GL_CXXALIASWARN (memmem); +#elif defined GNULIB_POSIXCHECK +# undef memmem +# if HAVE_RAW_DECL_MEMMEM +_GL_WARN_ON_USE (memmem, "memmem is unportable and often quadratic - " + "use gnulib module memmem-simple for portability, " + "and module memmem for speed" ); +# endif +#endif + +/* Copy N bytes of SRC to DEST, return pointer to bytes after the + last written byte. */ +#if @GNULIB_MEMPCPY@ +# if ! @HAVE_MEMPCPY@ +_GL_FUNCDECL_SYS (mempcpy, void *, + (void *restrict __dest, void const *restrict __src, + size_t __n) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (mempcpy, void *, + (void *restrict __dest, void const *restrict __src, + size_t __n)); +_GL_CXXALIASWARN (mempcpy); +#elif defined GNULIB_POSIXCHECK +# undef mempcpy +# if HAVE_RAW_DECL_MEMPCPY +_GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - " + "use gnulib module mempcpy for portability"); +# endif +#endif + +/* Search backwards through a block for a byte (specified as an int). */ +#if @GNULIB_MEMRCHR@ +# if ! @HAVE_DECL_MEMRCHR@ +_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const void * std::memrchr (const void *, int, size_t); } + extern "C++" { void * std::memrchr (void *, int, size_t); } */ +_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)); +# else +_GL_CXXALIASWARN (memrchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memrchr +# if HAVE_RAW_DECL_MEMRCHR +_GL_WARN_ON_USE (memrchr, "memrchr is unportable - " + "use gnulib module memrchr for portability"); +# endif +#endif + +/* Find the first occurrence of C in S. More efficient than + memchr(S,C,N), at the expense of undefined behavior if C does not + occur within N bytes. */ +#if @GNULIB_RAWMEMCHR@ +# if ! @HAVE_RAWMEMCHR@ +_GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const void * std::rawmemchr (const void *, int); } + extern "C++" { void * std::rawmemchr (void *, int); } */ +_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)); +# else +_GL_CXXALIASWARN (rawmemchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef rawmemchr +# if HAVE_RAW_DECL_RAWMEMCHR +_GL_WARN_ON_USE (rawmemchr, "rawmemchr is unportable - " + "use gnulib module rawmemchr for portability"); +# endif +#endif + +/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */ +#if @GNULIB_STPCPY@ +# if ! @HAVE_STPCPY@ +_GL_FUNCDECL_SYS (stpcpy, char *, + (char *restrict __dst, char const *restrict __src) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (stpcpy, char *, + (char *restrict __dst, char const *restrict __src)); +_GL_CXXALIASWARN (stpcpy); +#elif defined GNULIB_POSIXCHECK +# undef stpcpy +# if HAVE_RAW_DECL_STPCPY +_GL_WARN_ON_USE (stpcpy, "stpcpy is unportable - " + "use gnulib module stpcpy for portability"); +# endif +#endif + +/* Copy no more than N bytes of SRC to DST, returning a pointer past the + last non-NUL byte written into DST. */ +#if @GNULIB_STPNCPY@ +# if @REPLACE_STPNCPY@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef stpncpy +# define stpncpy rpl_stpncpy +# endif +_GL_FUNCDECL_RPL (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n)); +# else +# if ! @HAVE_STPNCPY@ +_GL_FUNCDECL_SYS (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n)); +# endif +_GL_CXXALIASWARN (stpncpy); +#elif defined GNULIB_POSIXCHECK +# undef stpncpy +# if HAVE_RAW_DECL_STPNCPY +_GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " + "use gnulib module stpncpy for portability"); +# endif +#endif + +#if defined GNULIB_POSIXCHECK +/* strchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +# undef strchr +/* Assume strchr is always declared. */ +_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. */ +#if @GNULIB_STRCHRNUL@ +# if @REPLACE_STRCHRNUL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strchrnul rpl_strchrnul +# endif +_GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strchrnul, char *, + (const char *str, int ch)); +# else +# if ! @HAVE_STRCHRNUL@ +_GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * std::strchrnul (const char *, int); } + extern "C++" { char * std::strchrnul (char *, int); } */ +_GL_CXXALIAS_SYS_CAST2 (strchrnul, + char *, (char const *__s, int __c_in), + 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)); +# else +_GL_CXXALIASWARN (strchrnul); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strchrnul +# if HAVE_RAW_DECL_STRCHRNUL +_GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - " + "use gnulib module strchrnul for portability"); +# endif +#endif + +/* Duplicate S, returning an identical malloc'd string. */ +#if @GNULIB_STRDUP@ +# if @REPLACE_STRDUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strdup +# define strdup rpl_strdup +# endif +_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@ || __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); +#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 + +/* Append no more than N characters from SRC onto DEST. */ +#if @GNULIB_STRNCAT@ +# if @REPLACE_STRNCAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strncat +# define strncat rpl_strncat +# endif +_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 *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 +_GL_WARN_ON_USE (strncat, "strncat is unportable - " + "use gnulib module strncat for portability"); +# endif +#endif + +/* Return a newly allocated copy of at most N bytes of STRING. */ +#if @GNULIB_STRNDUP@ +# if @REPLACE_STRNDUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strndup +# define strndup rpl_strndup +# endif +_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@ || __GNUC__ >= 11 +_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 *__s, size_t __n)); +# endif +_GL_CXXALIASWARN (strndup); +#else +# if __GNUC__ >= 11 +/* 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 + +/* Find the length (number of bytes) of STRING, but scan at most + MAXLEN bytes. If no '\0' terminator is found in that many bytes, + return MAXLEN. */ +#if @GNULIB_STRNLEN@ +# if @REPLACE_STRNLEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strnlen +# define strnlen rpl_strnlen +# endif +_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 *__s, size_t __maxlen)); +# else +# if ! @HAVE_DECL_STRNLEN@ +_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 *__s, size_t __maxlen)); +# endif +_GL_CXXALIASWARN (strnlen); +#elif defined GNULIB_POSIXCHECK +# undef strnlen +# if HAVE_RAW_DECL_STRNLEN +_GL_WARN_ON_USE (strnlen, "strnlen is unportable - " + "use gnulib module strnlen for portability"); +# endif +#endif + +#if defined GNULIB_POSIXCHECK +/* strcspn() assumes the second argument is a list of single-byte characters. + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +# undef strcspn +/* Assume strcspn is always declared. */ +_GL_WARN_ON_USE (strcspn, "strcspn cannot work correctly on character strings " + "in multibyte locales - " + "use mbscspn if you care about internationalization"); +#endif + +/* Find the first occurrence in S of any character in ACCEPT. */ +#if @GNULIB_STRPBRK@ +# if ! @HAVE_STRPBRK@ +_GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C" { const char * strpbrk (const char *, const char *); } + extern "C++" { char * strpbrk (char *, const char *); } */ +_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)); +_GL_CXXALIASWARN1 (strpbrk, char const *, + (char const *__s, char const *__accept)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (strpbrk); +# endif +# if defined GNULIB_POSIXCHECK +/* strpbrk() assumes the second argument is a list of single-byte characters. + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +# undef strpbrk +_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_CXX (strpbrk, + const char *, char *, (const char *, const char *), + "strpbrk is unportable - " + "use gnulib module strpbrk for portability"); +# endif +#endif + +#if defined GNULIB_POSIXCHECK +/* strspn() assumes the second argument is a list of single-byte characters. + Even in this simple case, it cannot work with multibyte strings. */ +# undef strspn +/* Assume strspn is always declared. */ +_GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " + "in multibyte locales - " + "use mbsspn if you care about internationalization"); +#endif + +#if defined GNULIB_POSIXCHECK +/* strrchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +# undef strrchr +/* Assume strrchr is always declared. */ +_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. + If one is found, overwrite it with a NUL, and advance *STRINGP + to point to the next char after it. Otherwise, set *STRINGP to NULL. + If *STRINGP was already NULL, nothing happens. + Return the old value of *STRINGP. + + This is a variant of strtok() that is multithread-safe and supports + empty fields. + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + Caveat: It doesn't work with multibyte strings unless all of the delimiter + characters are ASCII characters < 0x30. + + See also strtok_r(). */ +#if @GNULIB_STRSEP@ +# if ! @HAVE_STRSEP@ +_GL_FUNCDECL_SYS (strsep, char *, + (char **restrict __stringp, char const *restrict __delim) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (strsep, char *, + (char **restrict __stringp, char const *restrict __delim)); +_GL_CXXALIASWARN (strsep); +# if defined GNULIB_POSIXCHECK +# undef strsep +_GL_WARN_ON_USE (strsep, "strsep cannot work correctly on character strings " + "in multibyte locales - " + "use mbssep if you care about internationalization"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strsep +# if HAVE_RAW_DECL_STRSEP +_GL_WARN_ON_USE (strsep, "strsep is unportable - " + "use gnulib module strsep for portability"); +# endif +#endif + +#if @GNULIB_STRSTR@ +# if @REPLACE_STRSTR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strstr rpl_strstr +# endif +_GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle)); +# else + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * strstr (const char *, const char *); } + extern "C++" { char * strstr (char *, const char *); } */ +_GL_CXXALIAS_SYS_CAST2 (strstr, + char *, (const char *haystack, const char *needle), + 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)); +_GL_CXXALIASWARN1 (strstr, const char *, + (const char *haystack, const char *needle)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (strstr); +# endif +#elif defined GNULIB_POSIXCHECK +/* strstr() does not work with multibyte strings if the locale encoding is + different from UTF-8: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strstr +/* Assume strstr is always declared. */ +_GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot " + "work correctly on character strings in most " + "multibyte locales - " + "use mbsstr if you care about internationalization, " + "or use strstr if you care about speed"); +#endif + +/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive + comparison. */ +#if @GNULIB_STRCASESTR@ +# if @REPLACE_STRCASESTR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strcasestr rpl_strcasestr +# endif +_GL_FUNCDECL_RPL (strcasestr, char *, + (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strcasestr, char *, + (const char *haystack, const char *needle)); +# else +# if ! @HAVE_STRCASESTR@ +_GL_FUNCDECL_SYS (strcasestr, char *, + (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * strcasestr (const char *, const char *); } + extern "C++" { char * strcasestr (char *, const char *); } */ +_GL_CXXALIAS_SYS_CAST2 (strcasestr, + char *, (const char *haystack, const char *needle), + 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)); +_GL_CXXALIASWARN1 (strcasestr, const char *, + (const char *haystack, const char *needle)); +# else +_GL_CXXALIASWARN (strcasestr); +# endif +#elif defined GNULIB_POSIXCHECK +/* strcasestr() does not work with multibyte strings: + It is a glibc extension, and glibc implements it only for unibyte + locales. */ +# undef strcasestr +# if HAVE_RAW_DECL_STRCASESTR +_GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character " + "strings in multibyte locales - " + "use mbscasestr if you care about " + "internationalization, or use c-strcasestr if you want " + "a locale independent function"); +# endif +#endif + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = strtok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" + + This is a variant of strtok() that is multithread-safe. + + For the POSIX documentation for this function, see: + https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + Caveat: It doesn't work with multibyte strings unless all of the delimiter + characters are ASCII characters < 0x30. + + See also strsep(). */ +#if @GNULIB_STRTOK_R@ +# if @REPLACE_STRTOK_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strtok_r +# define strtok_r rpl_strtok_r +# endif +_GL_FUNCDECL_RPL (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr)); +# else +# if @UNDEFINE_STRTOK_R@ || defined GNULIB_POSIXCHECK +# undef strtok_r +# endif +# if ! @HAVE_DECL_STRTOK_R@ +_GL_FUNCDECL_SYS (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr)); +# endif +_GL_CXXALIASWARN (strtok_r); +# if defined GNULIB_POSIXCHECK +_GL_WARN_ON_USE (strtok_r, "strtok_r cannot work correctly on character " + "strings in multibyte locales - " + "use mbstok_r if you care about internationalization"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strtok_r +# if HAVE_RAW_DECL_STRTOK_R +_GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " + "use gnulib module strtok_r for portability"); +# endif +#endif + + +/* The following functions are not specified by POSIX. They are gnulib + extensions. */ + +#if @GNULIB_MBSLEN@ +/* Return the number of multibyte characters in the character string STRING. + This considers multibyte characters, unlike strlen, which counts bytes. */ +# ifdef __MirBSD__ /* MirBSD defines mbslen as a macro. Override it. */ +# undef mbslen +# endif +# if @HAVE_MBSLEN@ /* AIX, OSF/1, MirBSD define mbslen already in libc. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbslen rpl_mbslen +# endif +_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); +# else +_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string)); +# endif +_GL_CXXALIASWARN (mbslen); +#endif + +#if @GNULIB_MBSNLEN@ +/* Return the number of multibyte characters in the character string starting + at STRING and ending at STRING + LEN. */ +_GL_EXTERN_C size_t mbsnlen (const char *string, size_t len) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1)); +#endif + +#if @GNULIB_MBSCHR@ +/* Locate the first single-byte character C in the character string STRING, + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +# if defined __hpux +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbschr rpl_mbschr /* avoid collision with HP-UX function */ +# endif +_GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c)); +# else +_GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c)); +# endif +_GL_CXXALIASWARN (mbschr); +#endif + +#if @GNULIB_MBSRCHR@ +/* Locate the last single-byte character C in the character string STRING, + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strrchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +# if defined __hpux || defined __INTERIX +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbsrchr rpl_mbsrchr /* avoid collision with system function */ +# endif +_GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c)); +# else +_GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c)); +# endif +_GL_CXXALIASWARN (mbsrchr); +#endif + +#if @GNULIB_MBSSTR@ +/* Find the first occurrence of the character string NEEDLE in the character + string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK. + Unlike strstr(), this function works correctly in multibyte locales with + encodings different from UTF-8. */ +_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSCASECMP@ +/* Compare the character strings S1 and S2, ignoring case, returning less than, + equal to or greater than zero if S1 is lexicographically less than, equal to + or greater than S2. + Note: This function may, in multibyte locales, return 0 for strings of + different lengths! + Unlike strcasecmp(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSNCASECMP@ +/* Compare the initial segment of the character string S1 consisting of at most + N characters with the initial segment of the character string S2 consisting + of at most N characters, ignoring case, returning less than, equal to or + greater than zero if the initial segment of S1 is lexicographically less + than, equal to or greater than the initial segment of S2. + Note: This function may, in multibyte locales, return 0 for initial segments + of different lengths! + Unlike strncasecmp(), this function works correctly in multibyte locales. + But beware that N is not a byte count but a character count! */ +_GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSPCASECMP@ +/* Compare the initial segment of the character string STRING consisting of + at most mbslen (PREFIX) characters with the character string PREFIX, + ignoring case. If the two match, return a pointer to the first byte + after this prefix in STRING. Otherwise, return NULL. + Note: This function may, in multibyte locales, return non-NULL if STRING + is of smaller length than PREFIX! + Unlike strncasecmp(), this function works correctly in multibyte + locales. */ +_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSCASESTR@ +/* Find the first occurrence of the character string NEEDLE in the character + string HAYSTACK, using case-insensitive comparison. + Note: This function may, in multibyte locales, return success even if + strlen (haystack) < strlen (needle) ! + Unlike strcasestr(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSCSPN@ +/* Find the first occurrence in the character string STRING of any character + in the character string ACCEPT. Return the number of bytes from the + beginning of the string to this occurrence, or to the end of the string + if none exists. + Unlike strcspn(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C size_t mbscspn (const char *string, const char *accept) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSPBRK@ +/* Find the first occurrence in the character string STRING of any character + in the character string ACCEPT. Return the pointer to it, or NULL if none + exists. + Unlike strpbrk(), this function works correctly in multibyte locales. */ +# if defined __hpux +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ +# endif +_GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept)); +# else +_GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept)); +# endif +_GL_CXXALIASWARN (mbspbrk); +#endif + +#if @GNULIB_MBSSPN@ +/* Find the first occurrence in the character string STRING of any character + not in the character string REJECT. Return the number of bytes from the + beginning of the string to this occurrence, or to the end of the string + if none exists. + Unlike strspn(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C size_t mbsspn (const char *string, const char *reject) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSSEP@ +/* Search the next delimiter (multibyte character listed in the character + string DELIM) starting at the character string *STRINGP. + If one is found, overwrite it with a NUL, and advance *STRINGP to point + to the next multibyte character after it. Otherwise, set *STRINGP to NULL. + If *STRINGP was already NULL, nothing happens. + Return the old value of *STRINGP. + + This is a variant of mbstok_r() that supports empty fields. + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + + See also mbstok_r(). */ +_GL_EXTERN_C char * mbssep (char **stringp, const char *delim) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSTOK_R@ +/* Parse the character string STRING into tokens separated by characters in + the character string DELIM. + If STRING is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = mbstok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + + See also mbssep(). */ +_GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim, + char **save_ptr) + _GL_ARG_NONNULL ((2, 3)); +#endif + +/* Map any int, typically from errno, into an error message. */ +#if @GNULIB_STRERROR@ +# if @REPLACE_STRERROR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strerror +# define strerror rpl_strerror +# endif +_GL_FUNCDECL_RPL (strerror, char *, (int)); +_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. */ +_GL_WARN_ON_USE (strerror, "strerror is unportable - " + "use gnulib module strerror to guarantee non-NULL result"); +#endif + +/* Map any int, typically from errno, into an error message. Multithread-safe. + Uses the POSIX declaration, not the glibc declaration. */ +#if @GNULIB_STRERROR_R@ +# if @REPLACE_STRERROR_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strerror_r +# define strerror_r rpl_strerror_r +# endif +_GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)); +# else +# if !@HAVE_DECL_STRERROR_R@ +_GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)); +# endif +# if @HAVE_DECL_STRERROR_R@ +_GL_CXXALIASWARN (strerror_r); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strerror_r +# if HAVE_RAW_DECL_STRERROR_R +_GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " + "use gnulib module strerror_r-posix for portability"); +# 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) +# define strsignal rpl_strsignal +# endif +_GL_FUNCDECL_RPL (strsignal, char *, (int __sig)); +_GL_CXXALIAS_RPL (strsignal, char *, (int __sig)); +# else +# if ! @HAVE_DECL_STRSIGNAL@ +_GL_FUNCDECL_SYS (strsignal, char *, (int __sig)); +# endif +/* Need to cast, because on Cygwin 1.5.x systems, the return type is + 'const char *'. */ +_GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig)); +# endif +_GL_CXXALIASWARN (strsignal); +#elif defined GNULIB_POSIXCHECK +# undef strsignal +# if HAVE_RAW_DECL_STRSIGNAL +_GL_WARN_ON_USE (strsignal, "strsignal is unportable - " + "use gnulib module strsignal for portability"); +# endif +#endif + +#if @GNULIB_STRVERSCMP@ +# if !@HAVE_STRVERSCMP@ +_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *)); +_GL_CXXALIASWARN (strverscmp); +#elif defined GNULIB_POSIXCHECK +# undef strverscmp +# if HAVE_RAW_DECL_STRVERSCMP +_GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " + "use gnulib module strverscmp for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_STRING_H */ +#endif /* _@GUARD_PREFIX@_STRING_H */ +#endif diff --git a/lib/strings.in.h b/lib/strings.in.h new file mode 100644 index 0000000..2c31d2e --- /dev/null +++ b/lib/strings.in.h @@ -0,0 +1,122 @@ +/* A substitute . + + 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 . */ + +#ifndef _@GUARD_PREFIX@_STRINGS_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* Minix 3.1.8 has a bug: must be included before . + But avoid namespace pollution on glibc systems. */ +#if defined __minix && !defined __GLIBC__ +# include +#endif + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_STRINGS_H@ +# @INCLUDE_NEXT@ @NEXT_STRINGS_H@ +#endif + +#ifndef _@GUARD_PREFIX@_STRINGS_H +#define _@GUARD_PREFIX@_STRINGS_H + +#if ! @HAVE_DECL_STRNCASECMP@ +/* Get size_t. */ +# 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. */ + +#ifdef __cplusplus +extern "C" { +#endif + + + /* Find the index of the least-significant set bit. */ +#if @GNULIB_FFS@ +# if !@HAVE_FFS@ +_GL_FUNCDECL_SYS (ffs, int, (int i)); +# endif +_GL_CXXALIAS_SYS (ffs, int, (int i)); +_GL_CXXALIASWARN (ffs); +#elif defined GNULIB_POSIXCHECK +# undef ffs +# if HAVE_RAW_DECL_FFS +_GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module"); +# endif +#endif + +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. + Note: This function does not work in multibyte locales. */ +#if ! @HAVE_STRCASECMP@ +extern int strcasecmp (char const *s1, char const *s2) + _GL_ARG_NONNULL ((1, 2)); +#endif +#if defined GNULIB_POSIXCHECK +/* strcasecmp() does not work with multibyte strings: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strcasecmp +# if HAVE_RAW_DECL_STRCASECMP +_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " + "strings in multibyte locales - " + "use mbscasecmp if you care about " + "internationalization, or use c_strcasecmp , " + "gnulib module c-strcase) if you want a locale " + "independent function"); +# endif +#endif + +/* Compare no more than N bytes of strings S1 and S2, ignoring case, + returning less than, equal to or greater than zero if S1 is + lexicographically less than, equal to or greater than S2. + Note: This function cannot work correctly in multibyte locales. */ +#if ! @HAVE_DECL_STRNCASECMP@ +extern int strncasecmp (char const *s1, char const *s2, size_t n) + _GL_ARG_NONNULL ((1, 2)); +#endif +#if defined GNULIB_POSIXCHECK +/* strncasecmp() does not work with multibyte strings: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strncasecmp +# if HAVE_RAW_DECL_STRNCASECMP +_GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " + "strings in multibyte locales - " + "use mbsncasecmp or mbspcasecmp if you care about " + "internationalization, or use c_strncasecmp , " + "gnulib module c-strcase) if you want a locale " + "independent function"); +# endif +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _@GUARD_PREFIX@_STRING_H */ +#endif /* _@GUARD_PREFIX@_STRING_H */ diff --git a/lib/stripslash.c b/lib/stripslash.c new file mode 100644 index 0000000..aee89b7 --- /dev/null +++ b/lib/stripslash.c @@ -0,0 +1,45 @@ +/* stripslash.c -- remove redundant trailing slashes from a file name + + Copyright (C) 1990, 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 . */ + +#include + +#include "dirname.h" + +/* Remove trailing slashes from FILE. Return true if a trailing slash + was removed. This is useful when using file name completion from a + shell that adds a "/" after directory names (such as tcsh and + bash), because on symlinks to directories, several system calls + have different semantics according to whether a trailing slash is + present. */ + +bool +strip_trailing_slashes (char *file) +{ + char *base = last_component (file); + char *base_lim; + bool had_slash; + + /* last_component returns "" for file system roots, but we need to turn + "///" into "/". */ + if (! *base) + base = file; + base_lim = base + base_len (base); + had_slash = (*base_lim != '\0'); + *base_lim = '\0'; + return had_slash; +} diff --git a/lib/strncasecmp.c b/lib/strncasecmp.c new file mode 100644 index 0000000..35d215b --- /dev/null +++ b/lib/strncasecmp.c @@ -0,0 +1,62 @@ +/* strncasecmp.c -- case insensitive string comparator + Copyright (C) 1998-1999, 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* Compare no more than N bytes of strings S1 and S2, ignoring case, + returning less than, equal to or greater than zero if S1 is + lexicographically less than, equal to or greater than S2. + Note: This function cannot work correctly in multibyte locales. */ + +int +strncasecmp (const char *s1, const char *s2, size_t n) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = TOLOWER (*p1); + c2 = TOLOWER (*p2); + + if (--n == 0 || c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* 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 _GL_CMP (c1, c2); +} diff --git a/lib/strndup.c b/lib/strndup.c new file mode 100644 index 0000000..72cbc57 --- /dev/null +++ b/lib/strndup.c @@ -0,0 +1,36 @@ +/* A replacement function, for systems that lack strndup. + + Copyright (C) 1996-1998, 2001-2003, 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 . */ + +#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/lib/strnlen.c b/lib/strnlen.c new file mode 100644 index 0000000..c8fc69c --- /dev/null +++ b/lib/strnlen.c @@ -0,0 +1,30 @@ +/* Find the length of STRING, but scan at most MAXLEN characters. + Copyright (C) 2005-2007, 2009-2022 Free Software Foundation, Inc. + Written by Simon Josefsson. + + 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 + +/* 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/lib/strnlen1.c b/lib/strnlen1.c new file mode 100644 index 0000000..c22f96b --- /dev/null +++ b/lib/strnlen1.c @@ -0,0 +1,35 @@ +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + Copyright (C) 2005-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 . */ + +#include + +/* Specification. */ +#include "strnlen1.h" + +#include + +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + If no '\0' terminator is found in that many characters, return MAXLEN. */ +/* This is the same as strnlen (string, maxlen - 1) + 1. */ +size_t +strnlen1 (const char *string, size_t maxlen) +{ + const char *end = (const char *) memchr (string, '\0', maxlen); + if (end != NULL) + return end - string + 1; + else + return maxlen; +} diff --git a/lib/strnlen1.h b/lib/strnlen1.h new file mode 100644 index 0000000..d45dd91 --- /dev/null +++ b/lib/strnlen1.h @@ -0,0 +1,40 @@ +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + Copyright (C) 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 _STRNLEN1_H +#define _STRNLEN1_H + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + If no '\0' terminator is found in that many characters, return MAXLEN. */ +/* This is the same as strnlen (string, maxlen - 1) + 1. */ +extern size_t strnlen1 (const char *string, size_t maxlen) + _GL_ATTRIBUTE_PURE; + + +#ifdef __cplusplus +} +#endif + + +#endif /* _STRNLEN1_H */ diff --git a/lib/strpbrk.c b/lib/strpbrk.c new file mode 100644 index 0000000..d8d9994 --- /dev/null +++ b/lib/strpbrk.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1991, 1994, 2000, 2002-2003, 2006, 2009-2022 Free Software + Foundation, Inc. + + 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 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 +#include + +#if _LIBC +# undef strpbrk +#endif + +/* Find the first occurrence in S of any character in ACCEPT. */ +char * +strpbrk (const char *s, const char *accept) +{ + while (*s != '\0') + { + const char *a = accept; + while (*a != '\0') + if (*a++ == *s) + return (char *) s; + ++s; + } + + return NULL; +} diff --git a/lib/strptime.c b/lib/strptime.c new file mode 100644 index 0000000..27b3fb6 --- /dev/null +++ b/lib/strptime.c @@ -0,0 +1,1163 @@ +/* Copyright (C) 2002, 2004-2005, 2007, 2009-2022 Free Software Foundation, + Inc. + This file is part of 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 _LIBC +# include +#endif + +#include + +#include +#include +#ifdef _LIBC +# include +#endif +#include +#include +#include +#include + +#ifdef _LIBC +# include "../locale/localeinfo.h" +#endif + +#ifndef _LIBC +enum ptime_locale_status { not, loc, raw }; +#endif + + + +#define match_char(ch1, ch2) if (ch1 != ch2) return NULL +#if defined _LIBC && defined __GNUC__ && __GNUC__ >= 2 +# define match_string(cs1, s2) \ + ({ size_t len = strlen (cs1); \ + int result = __strncasecmp_l ((cs1), (s2), len, locale) == 0; \ + if (result) (s2) += len; \ + result; }) +#else +/* Oh come on. Get a reasonable compiler. */ +# define match_string(cs1, s2) \ + (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) +#endif +/* We intentionally do not use isdigit() for testing because this will + lead to problems with the wide character version. */ +#define get_number(from, to, n) \ + do { \ + int __n = n; \ + val = 0; \ + while (*rp == ' ') \ + ++rp; \ + if (*rp < '0' || *rp > '9') \ + return NULL; \ + do { \ + val *= 10; \ + val += *rp++ - '0'; \ + } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ + if (val < from || val > to) \ + return NULL; \ + } while (0) +#ifdef _NL_CURRENT +# define get_alt_number(from, to, n) \ + ({ \ + __label__ do_normal; \ + \ + if (*decided != raw) \ + { \ + val = _nl_parse_alt_digit (&rp HELPER_LOCALE_ARG); \ + if (val == -1 && *decided != loc) \ + { \ + *decided = loc; \ + goto do_normal; \ + } \ + if (val < from || val > to) \ + return NULL; \ + } \ + else \ + { \ + do_normal: \ + get_number (from, to, n); \ + } \ + 0; \ + }) +#else +# define get_alt_number(from, to, n) \ + /* We don't have the alternate representation. */ \ + get_number(from, to, n) +#endif +#define recursive(new_fmt) \ + (*(new_fmt) != '\0' \ + && (rp = __strptime_internal (rp, (new_fmt), tm, \ + decided, era_cnt LOCALE_ARG)) != NULL) + + +#ifdef _LIBC +/* This is defined in locale/C-time.c in the GNU libc. */ +extern const struct locale_data _nl_C_LC_TIME attribute_hidden; + +# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) +# define ab_weekday_name \ + (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) +# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) +# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) +# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) +# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) +# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) +# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) +# define HERE_T_FMT_AMPM \ + (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) +# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) + +# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) +#else +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const ab_weekday_name[][4] = + { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +static char const ab_month_name[][4] = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; +# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" +# define HERE_D_FMT "%m/%d/%y" +# define HERE_AM_STR "AM" +# define HERE_PM_STR "PM" +# define HERE_T_FMT_AMPM "%I:%M:%S %p" +# define HERE_T_FMT "%H:%M:%S" + +static const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; +#endif + +#if defined _LIBC +/* We use this code also for the extended locale handling where the + function gets as an additional argument the locale which has to be + used. To access the values we have to redefine the _NL_CURRENT + macro. */ +# define strptime __strptime_l +# undef _NL_CURRENT +# define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +# undef _NL_CURRENT_WORD +# define _NL_CURRENT_WORD(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].word) +# define LOCALE_PARAM , locale +# define LOCALE_ARG , locale +# define LOCALE_PARAM_PROTO , __locale_t locale +# define LOCALE_PARAM_DECL __locale_t locale; +# define HELPER_LOCALE_ARG , current +# define ISSPACE(Ch) __isspace_l (Ch, locale) +#else +# define LOCALE_PARAM +# define LOCALE_ARG +# define LOCALE_PARAM_DECL +# define LOCALE_PARAM_PROTO +# define HELPER_LOCALE_ARG +# define ISSPACE(Ch) isspace (Ch) +#endif + + + + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* Compute the day of the week. */ +static void +day_of_the_week (struct tm *tm) +{ + /* We know that January 1st 1970 was a Thursday (= 4). Compute the + difference between this data in the one on TM and so determine + the weekday. */ + int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); + int corr_quad = corr_year / 4; + int wday = (-473 + + (365 * (tm->tm_year - 70)) + + corr_quad + - ((corr_quad + (corr_quad < 0)) / 25 - (corr_quad < 0)) + + ((corr_quad / 25) / 4) + + __mon_yday[0][tm->tm_mon] + + tm->tm_mday - 1); + tm->tm_wday = ((wday % 7) + 7) % 7; +} + +/* Compute the day of the year. */ +static void +day_of_the_year (struct tm *tm) +{ + tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] + + (tm->tm_mday - 1)); +} + + +#ifdef _LIBC +char * +internal_function +#else +static char * +#endif +__strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM) + const char *rp; + const char *fmt; + struct tm *tm; + enum ptime_locale_status *decided; + int era_cnt; + LOCALE_PARAM_DECL +{ +#ifdef _LIBC + struct locale_data *const current = locale->__locales[LC_TIME]; +#endif + + int cnt; + size_t val; + int have_I, is_pm; + int century, want_century; + int want_era; + int have_wday, want_xday; + int have_yday; + int have_mon, have_mday; + int have_uweek, have_wweek; + int week_no; +#ifdef _NL_CURRENT + size_t num_eras; + struct era_entry *era = NULL; + const char *rp_backup; +#endif + + have_I = is_pm = 0; + century = -1; + want_century = 0; + want_era = 0; + week_no = 0; + + have_wday = want_xday = have_yday = have_mon = have_mday = have_uweek = 0; + have_wweek = 0; + + while (*fmt != '\0') + { + /* A white space in the format string matches 0 more or white + space in the input string. */ + if (ISSPACE (*fmt)) + { + while (ISSPACE (*rp)) + ++rp; + ++fmt; + continue; + } + + /* Any character but '%' must be matched by the same character + in the input string. */ + if (*fmt != '%') + { + match_char (*fmt++, *rp++); + continue; + } + + ++fmt; +#ifndef _NL_CURRENT + /* We need this for handling the 'E' modifier. */ + start_over: +#else + /* Make back up of current processing pointer. */ + rp_backup = rp; +#endif + + switch (*fmt++) + { + case '%': + /* Match the '%' character itself. */ + match_char ('%', *rp++); + break; + case 'a': + case 'A': + /* Match day of week. */ + for (cnt = 0; cnt < 7; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), + weekday_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), + ab_weekday_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (*decided != loc + && (match_string (weekday_name[cnt], rp) + || match_string (ab_weekday_name[cnt], rp))) + { + *decided = raw; + break; + } + } + if (cnt == 7) + /* Does not match a weekday name. */ + return NULL; + tm->tm_wday = cnt; + have_wday = 1; + break; + case 'b': + case 'B': + case 'h': + /* Match month name. */ + for (cnt = 0; cnt < 12; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), + month_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), + ab_month_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (match_string (month_name[cnt], rp) + || match_string (ab_month_name[cnt], rp)) + { + *decided = raw; + break; + } + } + if (cnt == 12) + /* Does not match a month name. */ + return NULL; + tm->tm_mon = cnt; + want_xday = 1; + break; + case 'c': + /* Match locale's date and time format. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + /* Match century number. */ +#ifdef _NL_CURRENT + match_century: +#endif + get_number (0, 99, 2); + century = val; + want_xday = 1; + break; + case 'd': + case 'e': + /* Match day of month. */ + get_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'F': + if (!recursive ("%Y-%m-%d")) + return NULL; + want_xday = 1; + break; + case 'x': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + /* Fall through. */ + case 'D': + /* Match standard day format. */ + if (!recursive (HERE_D_FMT)) + return NULL; + want_xday = 1; + break; + case 'k': + case 'H': + /* Match hour in 24-hour clock. */ + get_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'l': + /* Match hour in 12-hour clock. GNU extension. */ + case 'I': + /* Match hour in 12-hour clock. */ + get_number (1, 12, 2); + tm->tm_hour = val % 12; + have_I = 1; + break; + case 'j': + /* Match day number of year. */ + get_number (1, 366, 3); + tm->tm_yday = val - 1; + have_yday = 1; + break; + case 'm': + /* Match number of month. */ + get_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minute. */ + get_number (0, 59, 2); + tm->tm_min = val; + break; + case 'n': + case 't': + /* Match any white space. */ + while (ISSPACE (*rp)) + ++rp; + break; + case 'p': + /* Match locale's equivalent of AM/PM. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) + *decided = loc; + is_pm = 1; + break; + } + *decided = raw; + } +#endif + if (!match_string (HERE_AM_STR, rp)) + { + if (match_string (HERE_PM_STR, rp)) + is_pm = 1; + else + return NULL; + } + break; + case 'q': + /* Match quarter of year. GNU extension. */ + get_number (1, 4, 1); + tm->tm_mon = (val - 1) * 3; + tm->tm_mday = 1; + have_mon = 1; + have_mday = 1; + want_xday = 1; + break; + case 'r': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), + HERE_T_FMT_AMPM)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_T_FMT_AMPM)) + return NULL; + break; + case 'R': + if (!recursive ("%H:%M")) + return NULL; + break; + case 's': + { + /* The number of seconds may be very high so we cannot use + the 'get_number' macro. Instead read the number + character for character and construct the result while + doing this. */ + time_t secs = 0; + if (*rp < '0' || *rp > '9') + /* We need at least one digit. */ + return NULL; + + do + { + secs *= 10; + secs += *rp++ - '0'; + } + while (*rp >= '0' && *rp <= '9'); + + if (localtime_r (&secs, tm) == NULL) + /* Error in function. */ + return NULL; + } + break; + case 'S': + get_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'X': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + /* Fall through. */ + case 'T': + if (!recursive (HERE_T_FMT)) + return NULL; + break; + case 'u': + get_number (1, 7, 1); + tm->tm_wday = val % 7; + have_wday = 1; + break; + case 'g': + get_number (0, 99, 2); + /* XXX This cannot determine any field in TM. */ + break; + case 'G': + if (*rp < '0' || *rp > '9') + return NULL; + /* XXX Ignore the number since we would need some more + information to compute a real date. */ + do + ++rp; + while (*rp >= '0' && *rp <= '9'); + break; + case 'U': + get_number (0, 53, 2); + week_no = val; + have_uweek = 1; + break; + case 'W': + get_number (0, 53, 2); + week_no = val; + have_wweek = 1; + break; + case 'V': + get_number (0, 53, 2); + /* XXX This cannot determine any field in TM without some + information. */ + break; + case 'w': + /* Match number of weekday. */ + get_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': +#ifdef _NL_CURRENT + match_year_in_century: +#endif + /* Match year within century. */ + get_number (0, 99, 2); + /* The "Year 2000: The Millennium Rollover" paper suggests that + values in the range 69-99 refer to the twentieth century. */ + tm->tm_year = val >= 69 ? val : val + 100; + /* Indicate that we want to use the century, if specified. */ + want_century = 1; + want_xday = 1; + break; + case 'Y': + /* Match year including century number. */ + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'Z': + /* XXX How to handle this? */ + break; + case 'z': + /* We recognize two formats: if two digits are given, these + specify hours. If fours digits are used, minutes are + also specified. */ + { + _GL_UNUSED bool neg; + int n; + + val = 0; + while (*rp == ' ') + ++rp; + if (*rp != '+' && *rp != '-') + return NULL; + neg = *rp++ == '-'; + n = 0; + while (n < 4 && *rp >= '0' && *rp <= '9') + { + val = val * 10 + *rp++ - '0'; + ++n; + } + if (n == 2) + val *= 100; + else if (n != 4) + /* Only two or four digits recognized. */ + return NULL; + else + { + /* We have to convert the minutes into decimal. */ + if (val % 100 >= 60) + return NULL; + val = (val / 100) * 100 + ((val % 100) * 50) / 30; + } + if (val > 1200) + return NULL; +#if defined _LIBC || HAVE_TM_GMTOFF + tm->tm_gmtoff = (val * 3600) / 100; + if (neg) + tm->tm_gmtoff = -tm->tm_gmtoff; +#endif + } + break; + case 'E': +#ifdef _NL_CURRENT + switch (*fmt++) + { + case 'c': + /* Match locale's alternate date and time format. */ + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + if (*decided != raw) + { + if (era_cnt >= 0) + { + era = _nl_select_era_entry (era_cnt HELPER_LOCALE_ARG); + if (era != NULL && match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + else + return NULL; + } + + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt + HELPER_LOCALE_ARG); + if (era != NULL && match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + } + if (era_cnt != (int) num_eras) + break; + + era_cnt = -1; + if (*decided == loc) + return NULL; + + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + goto match_century; + case 'y': + if (*decided != raw) + { + get_number(0, 9999, 4); + tm->tm_year = val; + want_era = 1; + want_xday = 1; + want_century = 1; + + if (era_cnt >= 0) + { + assert (*decided == loc); + + era = _nl_select_era_entry (era_cnt HELPER_LOCALE_ARG); + bool match = false; + if (era != NULL) + { + int delta = ((tm->tm_year - era->offset) + * era->absolute_direction); + match = (delta >= 0 + && delta < (((int64_t) era->stop_date[0] + - (int64_t) era->start_date[0]) + * era->absolute_direction)); + } + if (! match) + return NULL; + + break; + } + + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; ++era_cnt) + { + era = _nl_select_era_entry (era_cnt + HELPER_LOCALE_ARG); + if (era != NULL) + { + int delta = ((tm->tm_year - era->offset) + * era->absolute_direction); + if (delta >= 0 + && delta < (((int64_t) era->stop_date[0] + - (int64_t) era->start_date[0]) + * era->absolute_direction)) + { + *decided = loc; + break; + } + } + } + if (era_cnt != (int) num_eras) + break; + + era_cnt = -1; + if (*decided == loc) + return NULL; + + *decided = raw; + } + + goto match_year_in_century; + case 'Y': + if (*decided != raw) + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt HELPER_LOCALE_ARG); + if (era != NULL && recursive (era->era_format)) + break; + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + *decided = loc; + era_cnt = -1; + break; + } + + *decided = raw; + } + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'x': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_D_FMT)) + return NULL; + break; + case 'X': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_T_FMT)) + return NULL; + break; + default: + return NULL; + } + break; +#else + /* We have no information about the era format. Just use + the normal format. */ + if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' + && *fmt != 'x' && *fmt != 'X') + /* This is an illegal format. */ + return NULL; + + goto start_over; +#endif + case 'O': + switch (*fmt++) + { + case 'd': + case 'e': + /* Match day of month using alternate numeric symbols. */ + get_alt_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'H': + /* Match hour in 24-hour clock using alternate numeric + symbols. */ + get_alt_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock using alternate numeric + symbols. */ + get_alt_number (1, 12, 2); + tm->tm_hour = val % 12; + have_I = 1; + break; + case 'm': + /* Match month using alternate numeric symbols. */ + get_alt_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minutes using alternate numeric symbols. */ + get_alt_number (0, 59, 2); + tm->tm_min = val; + break; + case 'q': + /* Match quarter using alternate numeric symbols. */ + get_alt_number (1, 4, 1); + tm->tm_mon = (val - 1) * 3; + tm->tm_mday = 1; + have_mon = 1; + have_mday = 1; + want_xday = 1; + break; + case 'S': + /* Match seconds using alternate numeric symbols. */ + get_alt_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'U': + get_alt_number (0, 53, 2); + week_no = val; + have_uweek = 1; + break; + case 'W': + get_alt_number (0, 53, 2); + week_no = val; + have_wweek = 1; + break; + case 'V': + get_alt_number (0, 53, 2); + /* XXX This cannot determine any field in TM without + further information. */ + break; + case 'w': + /* Match number of weekday using alternate numeric symbols. */ + get_alt_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': + /* Match year within century using alternate numeric symbols. */ + get_alt_number (0, 99, 2); + tm->tm_year = val >= 69 ? val : val + 100; + want_xday = 1; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + } + + if (have_I && is_pm) + tm->tm_hour += 12; + + if (century != -1) + { + if (want_century) + tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; + else + /* Only the century, but not the year. Strange, but so be it. */ + tm->tm_year = (century - 19) * 100; + } + + if (era_cnt != -1) + { +#ifdef _NL_CURRENT + era = _nl_select_era_entry (era_cnt HELPER_LOCALE_ARG); + if (era == NULL) + return NULL; + if (want_era) + tm->tm_year = (era->start_date[0] + + ((tm->tm_year - era->offset) + * era->absolute_direction)); + else + /* Era start year assumed. */ + tm->tm_year = era->start_date[0]; +#endif + } + else + if (want_era) + { + /* No era found but we have seen an E modifier. Rectify some + values. */ + if (want_century && century == -1 && tm->tm_year < 69) + tm->tm_year += 100; + } + + if (want_xday && !have_wday) + { + if ( !(have_mon && have_mday) && have_yday) + { + /* We don't have tm_mon and/or tm_mday, compute them. */ + int t_mon = 0; + while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) + t_mon++; + if (!have_mon) + tm->tm_mon = t_mon - 1; + if (!have_mday) + tm->tm_mday = + (tm->tm_yday + - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); + } + day_of_the_week (tm); + } + + if (want_xday && !have_yday) + day_of_the_year (tm); + + if ((have_uweek || have_wweek) && have_wday) + { + int save_wday = tm->tm_wday; + int save_mday = tm->tm_mday; + int save_mon = tm->tm_mon; + int w_offset = have_uweek ? 0 : 1; + + tm->tm_mday = 1; + tm->tm_mon = 0; + day_of_the_week (tm); + if (have_mday) + tm->tm_mday = save_mday; + if (have_mon) + tm->tm_mon = save_mon; + + if (!have_yday) + tm->tm_yday = ((7 - (tm->tm_wday - w_offset)) % 7 + + (week_no - 1) *7 + + save_wday - w_offset); + + if (!have_mday || !have_mon) + { + int t_mon = 0; + while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] + <= tm->tm_yday) + t_mon++; + if (!have_mon) + tm->tm_mon = t_mon - 1; + if (!have_mday) + tm->tm_mday = + (tm->tm_yday + - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); + } + + tm->tm_wday = save_wday; + } + + return (char *) rp; +} + + +char * +strptime (buf, format, tm LOCALE_PARAM) + const char *restrict buf; + const char *restrict format; + struct tm *restrict tm; + LOCALE_PARAM_DECL +{ + enum ptime_locale_status decided; + +#ifdef _NL_CURRENT + decided = not; +#else + decided = raw; +#endif + return __strptime_internal (buf, format, tm, &decided, -1 LOCALE_ARG); +} + +#ifdef _LIBC +weak_alias (__strptime_l, strptime_l) +#endif diff --git a/lib/strtok_r.c b/lib/strtok_r.c new file mode 100644 index 0000000..021cfb8 --- /dev/null +++ b/lib/strtok_r.c @@ -0,0 +1,76 @@ +/* Reentrant string tokenizer. Generic version. + Copyright (C) 1991, 1996-1999, 2001, 2004, 2007, 2009-2022 Free Software + Foundation, Inc. + This file is part of 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef _LIBC +# undef strtok_r +# undef __strtok_r +#else +# define __strtok_r strtok_r +# define __rawmemchr strchr +#endif + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = strtok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" +*/ +char * +__strtok_r (char *s, const char *delim, char **save_ptr) +{ + char *token; + + if (s == NULL) + s = *save_ptr; + + /* Scan leading delimiters. */ + s += strspn (s, delim); + if (*s == '\0') + { + *save_ptr = s; + return NULL; + } + + /* Find the end of the token. */ + token = s; + s = strpbrk (token, delim); + if (s == NULL) + /* This token finishes the string. */ + *save_ptr = __rawmemchr (token, '\0'); + else + { + /* Terminate the token and make *SAVE_PTR point past it. */ + *s = '\0'; + *save_ptr = s + 1; + } + return token; +} +#ifdef weak_alias +libc_hidden_def (__strtok_r) +weak_alias (__strtok_r, strtok_r) +#endif diff --git a/lib/strtol.c b/lib/strtol.c new file mode 100644 index 0000000..6c2e933 --- /dev/null +++ b/lib/strtol.c @@ -0,0 +1,408 @@ +/* Convert string representation of a number into an integer value. + + Copyright (C) 1991-1992, 1994-1999, 2003, 2005-2007, 2009-2022 Free Software + Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@gnu.org. + + 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 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 . */ + +#ifdef _LIBC +# define USE_NUMBER_GROUPING +#else +# include +#endif + +#include +#include +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#include +#include +#include +#include + +#ifdef USE_NUMBER_GROUPING +# include "../locale/localeinfo.h" +#endif + +/* Nonzero if we are defining 'strtoul' or 'strtoull', operating on + unsigned integers. */ +#ifndef UNSIGNED +# define UNSIGNED 0 +# define INT LONG int +#else +# define INT unsigned LONG int +#endif + +/* Determine the name. */ +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# undef strtol +# if UNSIGNED +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol __wcstoull_l +# else +# define strtol __wcstoul_l +# endif +# else +# ifdef QUAD +# define strtol __strtoull_l +# else +# define strtol __strtoul_l +# endif +# endif +# else +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol __wcstoll_l +# else +# define strtol __wcstol_l +# endif +# else +# ifdef QUAD +# define strtol __strtoll_l +# else +# define strtol __strtol_l +# endif +# endif +# endif +#else +# if UNSIGNED +# undef strtol +# ifdef USE_WIDE_CHAR +# ifdef QUAD +# define strtol wcstoull +# else +# define strtol wcstoul +# endif +# else +# ifdef QUAD +# define strtol strtoull +# else +# define strtol strtoul +# endif +# endif +# else +# ifdef USE_WIDE_CHAR +# undef strtol +# ifdef QUAD +# define strtol wcstoll +# else +# define strtol wcstol +# endif +# else +# ifdef QUAD +# undef strtol +# define strtol strtoll +# endif +# endif +# endif +#endif + +/* If QUAD is defined, we are defining 'strtoll' or 'strtoull', + operating on 'long long int's. */ +#ifdef QUAD +# define LONG long long +# define STRTOL_LONG_MIN LLONG_MIN +# define STRTOL_LONG_MAX LLONG_MAX +# define STRTOL_ULONG_MAX ULLONG_MAX +# if __GNUC__ == 2 && __GNUC_MINOR__ < 7 + /* Work around gcc bug with using this constant. */ + static const unsigned long long int maxquad = ULLONG_MAX; +# undef STRTOL_ULONG_MAX +# define STRTOL_ULONG_MAX maxquad +# endif +#else +# define LONG long +# define STRTOL_LONG_MIN LONG_MIN +# define STRTOL_LONG_MAX LONG_MAX +# define STRTOL_ULONG_MAX ULONG_MAX +#endif + + +#ifdef USE_NUMBER_GROUPING +# define GROUP_PARAM_PROTO , int group +#else +# define GROUP_PARAM_PROTO +#endif + +/* We use this code also for the extended locale handling where the + function gets as an additional argument the locale which has to be + used. To access the values we have to redefine the _NL_CURRENT + macro. */ +#ifdef USE_IN_EXTENDED_LOCALE_MODEL +# undef _NL_CURRENT +# define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +# define LOCALE_PARAM , loc +# define LOCALE_PARAM_PROTO , __locale_t loc +#else +# define LOCALE_PARAM +# define LOCALE_PARAM_PROTO +#endif + +#ifdef USE_WIDE_CHAR +# include +# include +# define L_(Ch) L##Ch +# define UCHAR_TYPE wint_t +# define STRING_TYPE wchar_t +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define ISSPACE(Ch) __iswspace_l ((Ch), loc) +# define ISALPHA(Ch) __iswalpha_l ((Ch), loc) +# define TOUPPER(Ch) __towupper_l ((Ch), loc) +# else +# define ISSPACE(Ch) iswspace (Ch) +# define ISALPHA(Ch) iswalpha (Ch) +# define TOUPPER(Ch) towupper (Ch) +# endif +#else +# define L_(Ch) Ch +# define UCHAR_TYPE unsigned char +# define STRING_TYPE char +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define ISSPACE(Ch) __isspace_l ((unsigned char) (Ch), loc) +# define ISALPHA(Ch) __isalpha_l ((unsigned char) (Ch), loc) +# define TOUPPER(Ch) __toupper_l ((unsigned char) (Ch), loc) +# else +# define ISSPACE(Ch) isspace ((unsigned char) (Ch)) +# define ISALPHA(Ch) isalpha ((unsigned char) (Ch)) +# define TOUPPER(Ch) toupper ((unsigned char) (Ch)) +# endif +#endif + +#ifdef USE_NUMBER_GROUPING +# define INTERNAL(X) INTERNAL1(X) +# define INTERNAL1(X) __##X##_internal +# define WEAKNAME(X) WEAKNAME1(X) +#else +# define INTERNAL(X) X +#endif + +#ifdef USE_NUMBER_GROUPING +/* This file defines a function to check for correct grouping. */ +# include "grouping.h" +#endif + + + +/* Convert NPTR to an 'unsigned long int' or 'long int' in base BASE. + If BASE is 0 the base is determined by the presence of a leading + zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. + If BASE is < 2 or > 36, it is reset to 10. + If ENDPTR is not NULL, a pointer to the character after the last + one converted is stored in *ENDPTR. */ + +INT +INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, + int base GROUP_PARAM_PROTO LOCALE_PARAM_PROTO) +{ + int negative; + register unsigned LONG int cutoff; + register unsigned int cutlim; + register unsigned LONG int i; + register const STRING_TYPE *s; + register UCHAR_TYPE c; + const STRING_TYPE *save, *end; + int overflow; + +#ifdef USE_NUMBER_GROUPING +# ifdef USE_IN_EXTENDED_LOCALE_MODEL + struct locale_data *current = loc->__locales[LC_NUMERIC]; +# endif + /* The thousands character of the current locale. */ + wchar_t thousands = L'\0'; + /* The numeric grouping specification of the current locale, + in the format described in . */ + const char *grouping; + + if (group) + { + grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); + if (*grouping <= 0 || *grouping == CHAR_MAX) + grouping = NULL; + else + { + /* Figure out the thousands separator character. */ +# if defined _LIBC || defined _HAVE_BTOWC + thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP)); + if (thousands == WEOF) + thousands = L'\0'; +# endif + if (thousands == L'\0') + grouping = NULL; + } + } + else + grouping = NULL; +#endif + + if (base < 0 || base == 1 || base > 36) + { + __set_errno (EINVAL); + return 0; + } + + save = s = nptr; + + /* Skip white space. */ + while (ISSPACE (*s)) + ++s; + if (*s == L_('\0')) + goto noconv; + + /* Check for a sign. */ + if (*s == L_('-')) + { + negative = 1; + ++s; + } + else if (*s == L_('+')) + { + negative = 0; + ++s; + } + else + negative = 0; + + /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ + if (*s == L_('0')) + { + if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X')) + { + s += 2; + base = 16; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; + + /* Save the pointer so we can check later if anything happened. */ + save = s; + +#ifdef USE_NUMBER_GROUPING + if (group) + { + /* Find the end of the digit string and check its grouping. */ + end = s; + for (c = *end; c != L_('\0'); c = *++end) + if ((wchar_t) c != thousands + && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9')) + && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base)) + break; + if (*s == thousands) + end = s; + else + end = correctly_grouped_prefix (s, end, thousands, grouping); + } + else +#endif + end = NULL; + + cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base; + cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base; + + overflow = 0; + i = 0; + for (c = *s; c != L_('\0'); c = *++s) + { + if (s == end) + break; + if (c >= L_('0') && c <= L_('9')) + c -= L_('0'); + else if (ISALPHA (c)) + c = TOUPPER (c) - L_('A') + 10; + else + break; + if ((int) c >= base) + break; + /* Check for overflow. */ + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (unsigned LONG int) base; + i += c; + } + } + + /* Check if anything actually happened. */ + if (s == save) + goto noconv; + + /* Store in ENDPTR the address of one character + past the last character we converted. */ + if (endptr != NULL) + *endptr = (STRING_TYPE *) s; + +#if !UNSIGNED + /* Check for a value that is within the range of + 'unsigned LONG int', but outside the range of 'LONG int'. */ + if (overflow == 0 + && i > (negative + ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1 + : (unsigned LONG int) STRTOL_LONG_MAX)) + overflow = 1; +#endif + + if (overflow) + { + __set_errno (ERANGE); +#if UNSIGNED + return STRTOL_ULONG_MAX; +#else + return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX; +#endif + } + + /* Return the result of the appropriate sign. */ + return negative ? -i : i; + +noconv: + /* We must handle a special case here: the base is 0 or 16 and the + first two characters are '0' and 'x', but the rest are no + hexadecimal digits. This is no error case. We return 0 and + ENDPTR points to the 'x'. */ + if (endptr != NULL) + { + if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X') + && save[-2] == L_('0')) + *endptr = (STRING_TYPE *) &save[-1]; + else + /* There was no number to convert. */ + *endptr = (STRING_TYPE *) nptr; + } + + return 0L; +} + +#ifdef USE_NUMBER_GROUPING +/* External user entry point. */ + +INT +# ifdef weak_function +weak_function +# endif +strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr, + int base LOCALE_PARAM_PROTO) +{ + return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM); +} +#endif diff --git a/lib/strtoll.c b/lib/strtoll.c new file mode 100644 index 0000000..acea42e --- /dev/null +++ b/lib/strtoll.c @@ -0,0 +1,33 @@ +/* Function to parse a 'long long int' from text. + Copyright (C) 1995-1997, 1999, 2001, 2009-2022 Free Software Foundation, + Inc. + This file is part of 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 3 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 . */ + +#define QUAD 1 + +#include + +#ifdef _LIBC +# ifdef SHARED +# include + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +compat_symbol (libc, __strtoll_internal, __strtoq_internal, GLIBC_2_0); +# endif + +# endif +weak_alias (strtoll, strtoq) +#endif diff --git a/lib/symlink.c b/lib/symlink.c new file mode 100644 index 0000000..26310af --- /dev/null +++ b/lib/symlink.c @@ -0,0 +1,57 @@ +/* Stub for symlink(). + 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 3 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 +#include + + +#if HAVE_SYMLINK + +# undef symlink + +/* Create a symlink, but reject trailing slash. */ +int +rpl_symlink (char const *contents, char const *name) +{ + size_t len = strlen (name); + if (len && name[len - 1] == '/') + { + struct stat st; + if (lstat (name, &st) == 0 || errno == EOVERFLOW) + errno = EEXIST; + return -1; + } + return symlink (contents, name); +} + +#else /* !HAVE_SYMLINK */ + +/* The system does not support symlinks. */ +int +symlink (_GL_UNUSED char const *contents, + _GL_UNUSED char const *name) +{ + errno = ENOSYS; + return -1; +} + +#endif /* !HAVE_SYMLINK */ diff --git a/lib/sys-limits.h b/lib/sys-limits.h new file mode 100644 index 0000000..d154f0b --- /dev/null +++ b/lib/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/lib/sys_file.in.h b/lib/sys_file.in.h new file mode 100644 index 0000000..1ae54f8 --- /dev/null +++ b/lib/sys_file.in.h @@ -0,0 +1,63 @@ +/* Provide a more complete sys/file.h. + + 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 Richard W.M. Jones. */ + +#ifndef _@GUARD_PREFIX@_SYS_FILE_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_SYS_FILE_H@ +# @INCLUDE_NEXT@ @NEXT_SYS_FILE_H@ +#endif + +#ifndef _@GUARD_PREFIX@_SYS_FILE_H +#define _@GUARD_PREFIX@_SYS_FILE_H + +#ifndef LOCK_SH +/* Operations for the 'flock' call (same as Linux kernel constants). */ +# define LOCK_SH 1 /* Shared lock. */ +# define LOCK_EX 2 /* Exclusive lock. */ +# define LOCK_UN 8 /* Unlock. */ + +/* Can be OR'd in to one of the above. */ +# define LOCK_NB 4 /* Don't block when locking. */ +#endif + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +#if @GNULIB_FLOCK@ +/* Apply or remove advisory locks on an open file. + Return 0 if successful, otherwise -1 and errno set. */ +# if !@HAVE_FLOCK@ +extern int flock (int fd, int operation); +# endif +#elif defined GNULIB_POSIXCHECK +# undef flock +# if HAVE_RAW_DECL_FLOCK +_GL_WARN_ON_USE (flock, "flock is unportable - " + "use gnulib module flock for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_FILE_H */ +#endif /* _@GUARD_PREFIX@_SYS_FILE_H */ diff --git a/lib/sys_ioctl.in.h b/lib/sys_ioctl.in.h new file mode 100644 index 0000000..7f1cdc8 --- /dev/null +++ b/lib/sys_ioctl.in.h @@ -0,0 +1,79 @@ +/* Substitute for and wrapper around . + 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 . */ + +#ifndef _@GUARD_PREFIX@_SYS_IOCTL_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_SYS_IOCTL_H@ +# @INCLUDE_NEXT@ @NEXT_SYS_IOCTL_H@ +#endif + +#ifndef _@GUARD_PREFIX@_SYS_IOCTL_H +#define _@GUARD_PREFIX@_SYS_IOCTL_H + +/* AIX 5.1 and Solaris 10 declare ioctl() in and in , + but not in . + Haiku declares ioctl() in , but not in . + But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Declare overridden functions. */ + +#if @GNULIB_IOCTL@ +# if @REPLACE_IOCTL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ioctl +# define ioctl rpl_ioctl +# endif +_GL_FUNCDECL_RPL (ioctl, int, + (int fd, int request, ... /* {void *,char *} arg */)); +_GL_CXXALIAS_RPL (ioctl, int, + (int fd, int request, ... /* {void *,char *} arg */)); +# else +# if @SYS_IOCTL_H_HAVE_WINSOCK2_H@ || 1 +_GL_FUNCDECL_SYS (ioctl, int, + (int fd, int request, ... /* {void *,char *} arg */)); +# endif +_GL_CXXALIAS_SYS (ioctl, int, + (int fd, int request, ... /* {void *,char *} arg */)); +# endif +_GL_CXXALIASWARN (ioctl); +#elif @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +# undef ioctl +# define ioctl ioctl_used_without_requesting_gnulib_module_ioctl +#elif defined GNULIB_POSIXCHECK +# undef ioctl +# if HAVE_RAW_DECL_IOCTL +_GL_WARN_ON_USE (ioctl, "ioctl does not portably work on sockets - " + "use gnulib module ioctl for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_IOCTL_H */ +#endif /* _@GUARD_PREFIX@_SYS_IOCTL_H */ diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h new file mode 100644 index 0000000..e730e61 --- /dev/null +++ b/lib/sys_random.in.h @@ -0,0 +1,98 @@ +/* Substitute for . + Copyright (C) 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 . */ + +# if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +# endif +@PRAGMA_COLUMNS@ + +#ifndef _@GUARD_PREFIX@_SYS_RANDOM_H + +#if @HAVE_SYS_RANDOM_H@ + +/* On uClibc < 1.0.35, assumes prior inclusion of . + Do not use __UCLIBC__ here, as it might not be defined yet. + But avoid namespace pollution on glibc systems. */ +# ifndef __GLIBC__ +# include +# endif +/* On Mac OS X 10.5, assumes prior inclusion of . + On Max OS X 10.13, assumes prior inclusion of a file that + includes , such as or . */ +# if defined __APPLE__ && defined __MACH__ /* Mac OS X */ +# include +# include +# endif + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYS_RANDOM_H@ + +#endif + +#ifndef _@GUARD_PREFIX@_SYS_RANDOM_H +#define _@GUARD_PREFIX@_SYS_RANDOM_H + +#include + +/* Define the GRND_* constants. */ +#ifndef GRND_NONBLOCK +# define GRND_NONBLOCK 1 +# define GRND_RANDOM 2 +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Declare overridden functions. */ + + +#if @GNULIB_GETRANDOM@ +/* Fill a buffer with random bytes. */ +# if @REPLACE_GETRANDOM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getrandom +# define getrandom rpl_getrandom +# endif +_GL_FUNCDECL_RPL (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags)); +# else +# if !@HAVE_GETRANDOM@ +_GL_FUNCDECL_SYS (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (getrandom, ssize_t, + (void *buffer, size_t length, unsigned int flags)); +# endif +_GL_CXXALIASWARN (getrandom); +#elif defined GNULIB_POSIXCHECK +# undef getrandom +# if HAVE_RAW_DECL_GETRANDOM +_GL_WARN_ON_USE (getrandom, "getrandom is unportable - " + "use gnulib module getrandom for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_RANDOM_H */ +#endif /* _@GUARD_PREFIX@_SYS_RANDOM_H */ diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h new file mode 100644 index 0000000..2bd0e0f --- /dev/null +++ b/lib/sys_select.in.h @@ -0,0 +1,331 @@ +/* Substitute for . + 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 . */ + +# if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +# endif +@PRAGMA_COLUMNS@ + +/* On OSF/1 and Solaris 2.6, and + both include . + On Cygwin and OpenBSD, includes . + Simply delegate to the system's header in this case. */ +#if (@HAVE_SYS_SELECT_H@ \ + && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H \ + && ((defined __osf__ && defined _SYS_TYPES_H_ \ + && defined _OSF_SOURCE) \ + || (defined __sun && defined _SYS_TYPES_H \ + && (! (defined _XOPEN_SOURCE || defined _POSIX_C_SOURCE) \ + || defined __EXTENSIONS__)))) + +# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H +# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ + +#elif (@HAVE_SYS_SELECT_H@ \ + && (defined _CYGWIN_SYS_TIME_H \ + || (!defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H \ + && ((defined __osf__ && defined _SYS_TIME_H_ \ + && defined _OSF_SOURCE) \ + || (defined __OpenBSD__ && defined _SYS_TIME_H_) \ + || (defined __sun && defined _SYS_TIME_H \ + && (! (defined _XOPEN_SOURCE \ + || defined _POSIX_C_SOURCE) \ + || defined __EXTENSIONS__)))))) + +# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H +# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ + +/* On IRIX 6.5, includes , which includes + , which includes . At this point we cannot + include , because that includes , which + gives a syntax error because has not been completely + processed. Simply delegate to the system's header in this case. */ +#elif @HAVE_SYS_SELECT_H@ && defined __sgi && (defined _SYS_BSD_TYPES_H && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H) + +# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H +# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ + +/* On OpenBSD 5.0, includes , which includes + . At this point we cannot include , because that + includes gnulib's pthread.h override, which gives a syntax error because + /usr/include/pthread.h has not been completely processed. Simply delegate + to the system's header in this case. */ +#elif @HAVE_SYS_SELECT_H@ && defined __OpenBSD__ && (defined _PTHREAD_H_ && !defined PTHREAD_MUTEX_INITIALIZER) + +# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ + +#else + +#ifndef _@GUARD_PREFIX@_SYS_SELECT_H + +/* On many platforms, assumes prior inclusion of + . Also, mingw defines sigset_t there, instead of + in where it belongs. */ +#include + +#if @HAVE_SYS_SELECT_H@ + +/* On OSF/1 4.0, provides only a forward declaration + of 'struct timeval', and no definition of this type. + Also, Mac OS X, AIX, HP-UX, IRIX, Solaris, Interix declare select() + in . + But avoid namespace pollution on glibc systems and "unknown type + name" problems on Cygwin. */ +# if !(defined __GLIBC__ || defined __CYGWIN__) +# include +# endif + +/* On AIX 7 and Solaris 10, provides an FD_ZERO implementation + that relies on memset(), but without including . + But in any case avoid namespace pollution on glibc systems. */ +# if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __osf__ || defined __BEOS__) \ + && ! defined __GLIBC__ +# include +# endif + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@ + +#endif + +/* Get definition of 'sigset_t'. + But avoid namespace pollution on glibc systems and "unknown type + name" problems on Cygwin. + On OS/2 kLIBC, sigset_t is defined in , too. In addition, + if is included, -> -> + are included. Then -> are included by GNULIB. By the + way, requires PAGE_SIZE defined in . However, + has not been processed, yet. As a result, 'PAGE_SIZE' + undeclared error occurs in . + Do this after the include_next (for the sake of OpenBSD 5.0) but before + the split double-inclusion guard (for the sake of Solaris). */ +#if !((defined __GLIBC__ || defined __CYGWIN__ || defined __KLIBC__) \ + && !defined __UCLIBC__) +# include +#endif + +#ifndef _@GUARD_PREFIX@_SYS_SELECT_H +#define _@GUARD_PREFIX@_SYS_SELECT_H + +#if !@HAVE_SYS_SELECT_H@ +/* A platform that lacks . */ +/* Get the 'struct timeval' and 'fd_set' types and the FD_* macros + on most platforms. */ +# include +/* On HP-UX 11, provides an FD_ZERO implementation + that relies on memset(), but without including . */ +# if defined __hpux +# include +# endif +/* On native Windows platforms: + Get the 'fd_set' type. + Get the close() declaration before we override it. */ +# if @HAVE_WINSOCK2_H@ +# if !defined _GL_INCLUDING_WINSOCK2_H +# define _GL_INCLUDING_WINSOCK2_H +# include +# undef _GL_INCLUDING_WINSOCK2_H +# endif +# include +# endif +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Fix some definitions from . */ + +#if @HAVE_WINSOCK2_H@ + +# if !GNULIB_defined_rpl_fd_isset + +/* Re-define FD_ISSET to avoid a WSA call while we are not using + network sockets. */ +static int +rpl_fd_isset (SOCKET fd, fd_set * set) +{ + u_int i; + if (set == NULL) + return 0; + + for (i = 0; i < set->fd_count; i++) + if (set->fd_array[i] == fd) + return 1; + + return 0; +} + +# define GNULIB_defined_rpl_fd_isset 1 +# endif + +# undef FD_ISSET +# define FD_ISSET(fd, set) rpl_fd_isset(fd, set) + +#endif + +/* Hide some function declarations from . */ + +#if @HAVE_WINSOCK2_H@ +# if !defined _@GUARD_PREFIX@_UNISTD_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef close +# define close close_used_without_including_unistd_h +# elif !defined __clang__ + _GL_WARN_ON_USE (close, + "close() used without including "); +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gethostname +# define gethostname gethostname_used_without_including_unistd_h +# elif !defined __clang__ + _GL_WARN_ON_USE (gethostname, + "gethostname() used without including "); +# endif +# endif +# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef socket +# define socket socket_used_without_including_sys_socket_h +# undef connect +# define connect connect_used_without_including_sys_socket_h +# undef accept +# define accept accept_used_without_including_sys_socket_h +# undef bind +# define bind bind_used_without_including_sys_socket_h +# undef getpeername +# define getpeername getpeername_used_without_including_sys_socket_h +# undef getsockname +# define getsockname getsockname_used_without_including_sys_socket_h +# undef getsockopt +# define getsockopt getsockopt_used_without_including_sys_socket_h +# undef listen +# define listen listen_used_without_including_sys_socket_h +# undef recv +# define recv recv_used_without_including_sys_socket_h +# undef send +# define send send_used_without_including_sys_socket_h +# undef recvfrom +# define recvfrom recvfrom_used_without_including_sys_socket_h +# undef sendto +# define sendto sendto_used_without_including_sys_socket_h +# undef setsockopt +# define setsockopt setsockopt_used_without_including_sys_socket_h +# undef shutdown +# define shutdown shutdown_used_without_including_sys_socket_h +# elif !defined __clang__ + _GL_WARN_ON_USE (socket, + "socket() used without including "); + _GL_WARN_ON_USE (connect, + "connect() used without including "); + _GL_WARN_ON_USE (accept, + "accept() used without including "); + _GL_WARN_ON_USE (bind, + "bind() used without including "); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including "); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including "); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including "); + _GL_WARN_ON_USE (listen, + "listen() used without including "); + _GL_WARN_ON_USE (recv, + "recv() used without including "); + _GL_WARN_ON_USE (send, + "send() used without including "); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including "); + _GL_WARN_ON_USE (sendto, + "sendto() used without including "); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including "); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including "); +# endif +# endif +#endif + + +#if @GNULIB_PSELECT@ +# if @REPLACE_PSELECT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef pselect +# define pselect rpl_pselect +# endif +_GL_FUNCDECL_RPL (pselect, int, + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + struct timespec const *restrict, const sigset_t *restrict)); +_GL_CXXALIAS_RPL (pselect, int, + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + struct timespec const *restrict, const sigset_t *restrict)); +# else +# if !@HAVE_PSELECT@ +_GL_FUNCDECL_SYS (pselect, int, + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + struct timespec const *restrict, const sigset_t *restrict)); +# endif +/* Need to cast, because on AIX 7, the second, third, fourth argument may be + void *restrict, void *restrict, void *restrict. */ +_GL_CXXALIAS_SYS_CAST (pselect, int, + (int, + fd_set *restrict, fd_set *restrict, fd_set *restrict, + struct timespec const *restrict, + const sigset_t *restrict)); +# endif +_GL_CXXALIASWARN (pselect); +#elif defined GNULIB_POSIXCHECK +# undef pselect +# if HAVE_RAW_DECL_PSELECT +_GL_WARN_ON_USE (pselect, "pselect is not portable - " + "use gnulib module pselect for portability"); +# endif +#endif + +#if @GNULIB_SELECT@ +# if @REPLACE_SELECT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef select +# define select rpl_select +# endif +_GL_FUNCDECL_RPL (select, int, + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + struct timeval *restrict)); +_GL_CXXALIAS_RPL (select, int, + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + timeval *restrict)); +# else +_GL_CXXALIAS_SYS (select, int, + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + timeval *restrict)); +# endif +_GL_CXXALIASWARN (select); +#elif @HAVE_WINSOCK2_H@ +# undef select +# define select select_used_without_requesting_gnulib_module_select +#elif defined GNULIB_POSIXCHECK +# undef select +# if HAVE_RAW_DECL_SELECT +_GL_WARN_ON_USE (select, "select is not always POSIX compliant - " + "use gnulib module select for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */ +#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */ +#endif /* OSF/1 */ diff --git a/lib/sys_socket.c b/lib/sys_socket.c new file mode 100644 index 0000000..0bfd60f --- /dev/null +++ b/lib/sys_socket.c @@ -0,0 +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/lib/sys_socket.in.h b/lib/sys_socket.in.h new file mode 100644 index 0000000..acdf7ee --- /dev/null +++ b/lib/sys_socket.in.h @@ -0,0 +1,734 @@ +/* Provide a sys/socket header file for systems lacking it (read: MinGW) + and for systems where it is incomplete. + Copyright (C) 2005-2022 Free Software Foundation, Inc. + Written by Simon Josefsson. + + 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 . */ + +/* This file is supposed to be used on platforms that lack , + on platforms where cannot be included standalone, and on + platforms where does not provide all necessary definitions. + It is intended to provide definitions and prototypes needed by an + application. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#if defined _GL_ALREADY_INCLUDING_SYS_SOCKET_H +/* Special invocation convention: + - On Cygwin 1.5.x we have a sequence of nested includes + -> -> -> , + and the latter includes . In this situation, the functions + are not yet declared, therefore we cannot provide the C++ aliases. */ + +#@INCLUDE_NEXT@ @NEXT_SYS_SOCKET_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_SYS_SOCKET_H + +#if @HAVE_SYS_SOCKET_H@ + +# define _GL_ALREADY_INCLUDING_SYS_SOCKET_H + +/* On many platforms, assumes prior inclusion of + . */ +# include + +/* On FreeBSD 6.4, defines some macros that assume that NULL + is defined. */ +# include + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYS_SOCKET_H@ + +# undef _GL_ALREADY_INCLUDING_SYS_SOCKET_H + +#endif + +#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 +#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. */ + +#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 + +#if @HAVE_STRUCT_SOCKADDR_STORAGE@ +/* Make the 'struct sockaddr_storage' field 'ss_family' visible on AIX 7.1. */ +# if !@HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@ +# ifndef ss_family +# define ss_family __ss_family +# endif +# endif +#else +# include +/* Code taken from glibc sysdeps/unix/sysv/linux/bits/socket.h on + 2009-05-08, licensed under LGPLv2.1+, plus portability fixes. */ +# define __ss_aligntype unsigned long int +# define _SS_SIZE 256 +# define _SS_PADSIZE \ + (_SS_SIZE - ((sizeof (sa_family_t) >= alignof (__ss_aligntype) \ + ? sizeof (sa_family_t) \ + : alignof (__ss_aligntype)) \ + + sizeof (__ss_aligntype))) + +# if !GNULIB_defined_struct_sockaddr_storage +struct sockaddr_storage +{ + sa_family_t ss_family; /* Address family, etc. */ + __ss_aligntype __ss_align; /* Force desired alignment. */ + char __ss_padding[_SS_PADSIZE]; +}; +# define GNULIB_defined_struct_sockaddr_storage 1 +# endif + +#endif + +/* Get struct iovec. */ +/* But avoid namespace pollution on glibc systems. */ +#if ! defined __GLIBC__ +# include +#endif + +#if @HAVE_SYS_SOCKET_H@ + +/* A platform that has . */ + +/* For shutdown(). */ +# if !defined SHUT_RD +# define SHUT_RD 0 +# endif +# if !defined SHUT_WR +# define SHUT_WR 1 +# endif +# if !defined SHUT_RDWR +# 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__ +# error "Cygwin does have a sys/socket.h, doesn't it?!?" +# endif + +/* A platform that lacks . + + Currently only MinGW is supported. See the gnulib manual regarding + Windows sockets. MinGW has the header files winsock2.h and + ws2tcpip.h that declare the sys/socket.h definitions we need. Note + that you can influence which definitions you get by setting the + WINVER symbol before including these two files. For example, + getaddrinfo is only available if _WIN32_WINNT >= 0x0501 (that + symbol is set indirectly through WINVER). You can set this by + adding AC_DEFINE(WINVER, 0x0501) to configure.ac. Note that your + 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. */ + +# if @HAVE_WINSOCK2_H@ +# include +# endif +# if @HAVE_WS2TCPIP_H@ +# include +# endif + +/* For shutdown(). */ +# if !defined SHUT_RD && defined SD_RECEIVE +# define SHUT_RD SD_RECEIVE +# endif +# if !defined SHUT_WR && defined SD_SEND +# define SHUT_WR SD_SEND +# endif +# if !defined SHUT_RDWR && defined SD_BOTH +# define SHUT_RDWR SD_BOTH +# endif + +# if @HAVE_WINSOCK2_H@ +/* Include headers needed by the emulation code. */ +# include +# include +/* If these headers don't define socklen_t, does. */ +# endif + +/* Rudimentary 'struct msghdr'; this works as long as you don't try to + access msg_control or msg_controllen. */ +struct msghdr { + void *msg_name; + socklen_t msg_namelen; + struct iovec *msg_iov; + int msg_iovlen; + int msg_flags; +}; + +#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@ + +# if !GNULIB_defined_rpl_fd_isset + +/* Re-define FD_ISSET to avoid a WSA call while we are not using + network sockets. */ +_GL_SYS_SOCKET_INLINE int +rpl_fd_isset (SOCKET fd, fd_set * set) +{ + u_int i; + if (set == NULL) + return 0; + + for (i = 0; i < set->fd_count; i++) + if (set->fd_array[i] == fd) + return 1; + + return 0; +} + +# define GNULIB_defined_rpl_fd_isset 1 +# endif + +# undef FD_ISSET +# define FD_ISSET(fd, set) rpl_fd_isset(fd, set) + +#endif + +/* Hide some function declarations from . */ + +#if @HAVE_WINSOCK2_H@ +# if !defined _@GUARD_PREFIX@_UNISTD_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef close +# define close close_used_without_including_unistd_h +# elif !defined __clang__ + _GL_WARN_ON_USE (close, + "close() used without including "); +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gethostname +# define gethostname gethostname_used_without_including_unistd_h +# else + _GL_WARN_ON_USE (gethostname, + "gethostname() used without including "); +# endif +# endif +# if !defined _@GUARD_PREFIX@_SYS_SELECT_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef select +# define select select_used_without_including_sys_select_h +# else + _GL_WARN_ON_USE (select, + "select() used without including "); +# endif +# endif +#endif + +/* Wrap everything else to use libc file descriptors for sockets. */ + +#if @GNULIB_SOCKET@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef socket +# define socket rpl_socket +# endif +_GL_FUNCDECL_RPL (socket, int, (int domain, int type, int protocol)); +_GL_CXXALIAS_RPL (socket, int, (int domain, int type, int protocol)); +# else +_GL_CXXALIAS_SYS (socket, int, (int domain, int type, int protocol)); +# endif +_GL_CXXALIASWARN (socket); +#elif @HAVE_WINSOCK2_H@ +# undef socket +# define socket socket_used_without_requesting_gnulib_module_socket +#elif defined GNULIB_POSIXCHECK +# undef socket +# if HAVE_RAW_DECL_SOCKET +_GL_WARN_ON_USE (socket, "socket is not always POSIX compliant - " + "use gnulib module socket for portability"); +# endif +#endif + +#if @GNULIB_CONNECT@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef connect +# define connect rpl_connect +# endif +_GL_FUNCDECL_RPL (connect, int, + (int fd, const struct sockaddr *addr, socklen_t addrlen) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (connect, int, + (int fd, const struct sockaddr *addr, socklen_t addrlen)); +# else +/* Need to cast, because on NonStop Kernel, the third parameter is + size_t addrlen. */ +_GL_CXXALIAS_SYS_CAST (connect, int, + (int fd, + const struct sockaddr *addr, socklen_t addrlen)); +# endif +_GL_CXXALIASWARN (connect); +#elif @HAVE_WINSOCK2_H@ +# undef connect +# define connect socket_used_without_requesting_gnulib_module_connect +#elif defined GNULIB_POSIXCHECK +# undef connect +# if HAVE_RAW_DECL_CONNECT +_GL_WARN_ON_USE (connect, "connect is not always POSIX compliant - " + "use gnulib module connect for portability"); +# endif +#endif + +#if @GNULIB_ACCEPT@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef accept +# define accept rpl_accept +# endif +_GL_FUNCDECL_RPL (accept, int, + (int fd, + struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); +_GL_CXXALIAS_RPL (accept, int, + (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. */ +_GL_CXXALIAS_SYS_CAST (accept, int, + (int fd, + struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); +# endif +_GL_CXXALIASWARN (accept); +#elif @HAVE_WINSOCK2_H@ +# undef accept +# define accept accept_used_without_requesting_gnulib_module_accept +#elif defined GNULIB_POSIXCHECK +# undef accept +# if HAVE_RAW_DECL_ACCEPT +_GL_WARN_ON_USE (accept, "accept is not always POSIX compliant - " + "use gnulib module accept for portability"); +# endif +#endif + +#if @GNULIB_BIND@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef bind +# define bind rpl_bind +# endif +_GL_FUNCDECL_RPL (bind, int, + (int fd, const struct sockaddr *addr, socklen_t addrlen) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (bind, int, + (int fd, const struct sockaddr *addr, socklen_t addrlen)); +# else +/* Need to cast, because on NonStop Kernel, the third parameter is + size_t addrlen. */ +_GL_CXXALIAS_SYS_CAST (bind, int, + (int fd, + const struct sockaddr *addr, socklen_t addrlen)); +# endif +_GL_CXXALIASWARN (bind); +#elif @HAVE_WINSOCK2_H@ +# undef bind +# define bind bind_used_without_requesting_gnulib_module_bind +#elif defined GNULIB_POSIXCHECK +# undef bind +# if HAVE_RAW_DECL_BIND +_GL_WARN_ON_USE (bind, "bind is not always POSIX compliant - " + "use gnulib module bind for portability"); +# endif +#endif + +#if @GNULIB_GETPEERNAME@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getpeername +# define getpeername rpl_getpeername +# endif +_GL_FUNCDECL_RPL (getpeername, int, + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (getpeername, int, + (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. */ +_GL_CXXALIAS_SYS_CAST (getpeername, int, + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); +# endif +_GL_CXXALIASWARN (getpeername); +#elif @HAVE_WINSOCK2_H@ +# undef getpeername +# define getpeername getpeername_used_without_requesting_gnulib_module_getpeername +#elif defined GNULIB_POSIXCHECK +# undef getpeername +# if HAVE_RAW_DECL_GETPEERNAME +_GL_WARN_ON_USE (getpeername, "getpeername is not always POSIX compliant - " + "use gnulib module getpeername for portability"); +# endif +#endif + +#if @GNULIB_GETSOCKNAME@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getsockname +# define getsockname rpl_getsockname +# endif +_GL_FUNCDECL_RPL (getsockname, int, + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (getsockname, int, + (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. */ +_GL_CXXALIAS_SYS_CAST (getsockname, int, + (int fd, struct sockaddr *restrict addr, + socklen_t *restrict addrlen)); +# endif +_GL_CXXALIASWARN (getsockname); +#elif @HAVE_WINSOCK2_H@ +# undef getsockname +# define getsockname getsockname_used_without_requesting_gnulib_module_getsockname +#elif defined GNULIB_POSIXCHECK +# undef getsockname +# if HAVE_RAW_DECL_GETSOCKNAME +_GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - " + "use gnulib module getsockname for portability"); +# endif +#endif + +#if @GNULIB_GETSOCKOPT@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getsockopt +# define getsockopt rpl_getsockopt +# endif +_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 *restrict optval, socklen_t *restrict optlen)); +# endif +_GL_CXXALIASWARN (getsockopt); +#elif @HAVE_WINSOCK2_H@ +# undef getsockopt +# define getsockopt getsockopt_used_without_requesting_gnulib_module_getsockopt +#elif defined GNULIB_POSIXCHECK +# undef getsockopt +# if HAVE_RAW_DECL_GETSOCKOPT +_GL_WARN_ON_USE (getsockopt, "getsockopt is not always POSIX compliant - " + "use gnulib module getsockopt for portability"); +# endif +#endif + +#if @GNULIB_LISTEN@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef listen +# define listen rpl_listen +# endif +_GL_FUNCDECL_RPL (listen, int, (int fd, int backlog)); +_GL_CXXALIAS_RPL (listen, int, (int fd, int backlog)); +# else +_GL_CXXALIAS_SYS (listen, int, (int fd, int backlog)); +# endif +_GL_CXXALIASWARN (listen); +#elif @HAVE_WINSOCK2_H@ +# undef listen +# define listen listen_used_without_requesting_gnulib_module_listen +#elif defined GNULIB_POSIXCHECK +# undef listen +# if HAVE_RAW_DECL_LISTEN +_GL_WARN_ON_USE (listen, "listen is not always POSIX compliant - " + "use gnulib module listen for portability"); +# endif +#endif + +#if @GNULIB_RECV@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef recv +# define recv rpl_recv +# endif +_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 +/* 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@ +# undef recv +# define recv recv_used_without_requesting_gnulib_module_recv +#elif defined GNULIB_POSIXCHECK +# undef recv +# if HAVE_RAW_DECL_RECV +_GL_WARN_ON_USE (recv, "recv is not always POSIX compliant - " + "use gnulib module recv for portability"); +# endif +#endif + +#if @GNULIB_SEND@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef send +# define send rpl_send +# endif +_GL_FUNCDECL_RPL (send, ssize_t, + (int fd, const void *buf, size_t len, int flags) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (send, ssize_t, + (int fd, const void *buf, size_t len, int flags)); +# else +/* 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@ +# undef send +# define send send_used_without_requesting_gnulib_module_send +#elif defined GNULIB_POSIXCHECK +# undef send +# if HAVE_RAW_DECL_SEND +_GL_WARN_ON_USE (send, "send is not always POSIX compliant - " + "use gnulib module send for portability"); +# endif +#endif + +#if @GNULIB_RECVFROM@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef recvfrom +# define recvfrom rpl_recvfrom +# endif +_GL_FUNCDECL_RPL (recvfrom, ssize_t, + (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 *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 *restrict buf, size_t len, int flags, + struct sockaddr *restrict from, + socklen_t *restrict fromlen)); +# endif +_GL_CXXALIASWARN (recvfrom); +#elif @HAVE_WINSOCK2_H@ +# undef recvfrom +# define recvfrom recvfrom_used_without_requesting_gnulib_module_recvfrom +#elif defined GNULIB_POSIXCHECK +# undef recvfrom +# if HAVE_RAW_DECL_RECVFROM +_GL_WARN_ON_USE (recvfrom, "recvfrom is not always POSIX compliant - " + "use gnulib module recvfrom for portability"); +# endif +#endif + +#if @GNULIB_SENDTO@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef sendto +# define sendto rpl_sendto +# endif +_GL_FUNCDECL_RPL (sendto, ssize_t, + (int fd, const void *buf, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (sendto, ssize_t, + (int fd, const void *buf, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen)); +# else +/* Need to cast, because on NonStop Kernel, the sixth parameter is + size_t tolen. */ +_GL_CXXALIAS_SYS_CAST (sendto, ssize_t, + (int fd, const void *buf, size_t len, int flags, + const struct sockaddr *to, socklen_t tolen)); +# endif +_GL_CXXALIASWARN (sendto); +#elif @HAVE_WINSOCK2_H@ +# undef sendto +# define sendto sendto_used_without_requesting_gnulib_module_sendto +#elif defined GNULIB_POSIXCHECK +# undef sendto +# if HAVE_RAW_DECL_SENDTO +_GL_WARN_ON_USE (sendto, "sendto is not always POSIX compliant - " + "use gnulib module sendto for portability"); +# endif +#endif + +#if @GNULIB_SETSOCKOPT@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setsockopt +# define setsockopt rpl_setsockopt +# endif +_GL_FUNCDECL_RPL (setsockopt, int, (int fd, int level, int optname, + const void * optval, socklen_t optlen) + _GL_ARG_NONNULL ((4))); +_GL_CXXALIAS_RPL (setsockopt, int, (int fd, int level, int optname, + const void * optval, socklen_t optlen)); +# else +/* Need to cast, because on NonStop Kernel, the fifth parameter is + size_t optlen. */ +_GL_CXXALIAS_SYS_CAST (setsockopt, int, + (int fd, int level, int optname, + const void * optval, socklen_t optlen)); +# endif +_GL_CXXALIASWARN (setsockopt); +#elif @HAVE_WINSOCK2_H@ +# undef setsockopt +# define setsockopt setsockopt_used_without_requesting_gnulib_module_setsockopt +#elif defined GNULIB_POSIXCHECK +# undef setsockopt +# if HAVE_RAW_DECL_SETSOCKOPT +_GL_WARN_ON_USE (setsockopt, "setsockopt is not always POSIX compliant - " + "use gnulib module setsockopt for portability"); +# endif +#endif + +#if @GNULIB_SHUTDOWN@ +# if @HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef shutdown +# define shutdown rpl_shutdown +# endif +_GL_FUNCDECL_RPL (shutdown, int, (int fd, int how)); +_GL_CXXALIAS_RPL (shutdown, int, (int fd, int how)); +# else +_GL_CXXALIAS_SYS (shutdown, int, (int fd, int how)); +# endif +_GL_CXXALIASWARN (shutdown); +#elif @HAVE_WINSOCK2_H@ +# undef shutdown +# define shutdown shutdown_used_without_requesting_gnulib_module_shutdown +#elif defined GNULIB_POSIXCHECK +# undef shutdown +# if HAVE_RAW_DECL_SHUTDOWN +_GL_WARN_ON_USE (shutdown, "shutdown is not always POSIX compliant - " + "use gnulib module shutdown for portability"); +# endif +#endif + +#if @GNULIB_ACCEPT4@ +/* Accept a connection on a socket, with specific opening flags. + 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 +# endif +_GL_FUNCDECL_RPL (accept4, int, + (int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int flags)); +_GL_CXXALIAS_RPL (accept4, int, + (int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int flags)); +# else +_GL_FUNCDECL_SYS (accept4, int, + (int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int flags)); +_GL_CXXALIAS_SYS (accept4, int, + (int sockfd, struct sockaddr *addr, socklen_t *addrlen, + int flags)); +# endif +_GL_CXXALIASWARN (accept4); +#elif defined GNULIB_POSIXCHECK +# undef accept4 +# if HAVE_RAW_DECL_ACCEPT4 +_GL_WARN_ON_USE (accept4, "accept4 is unportable - " + "use gnulib module accept4 for portability"); +# endif +#endif + +_GL_INLINE_HEADER_END + +#endif /* _@GUARD_PREFIX@_SYS_SOCKET_H */ +#endif /* _@GUARD_PREFIX@_SYS_SOCKET_H */ +#endif diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h new file mode 100644 index 0000000..28ddd42 --- /dev/null +++ b/lib/sys_stat.in.h @@ -0,0 +1,928 @@ +/* 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_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/lib/sys_time.in.h b/lib/sys_time.in.h new file mode 100644 index 0000000..87db1a8 --- /dev/null +++ b/lib/sys_time.in.h @@ -0,0 +1,224 @@ +/* Provide a more complete sys/time.h. + + 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 Paul Eggert. */ + +#ifndef _@GUARD_PREFIX@_SYS_TIME_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* On Cygwin and on many BSDish systems, includes itself + recursively via . + Simply delegate to the system's header in this case; it is a no-op. + Without this extra ifdef, the C++ gettimeofday declaration below + would be a forward declaration in gnulib's nested . */ +#if defined _CYGWIN_SYS_TIME_H || defined _SYS_TIME_H || defined _SYS_TIME_H_ +# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ +#else + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_SYS_TIME_H@ +# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ +#endif + +#ifndef _@GUARD_PREFIX@_SYS_TIME_H +#define _@GUARD_PREFIX@_SYS_TIME_H + +#if ! @HAVE_SYS_TIME_H@ +# include +#endif + +/* On native Windows with MSVC, get the 'struct timeval' type. + Also, on native Windows with a 64-bit time_t, where we are overriding the + 'struct timeval' type, get all declarations of system functions whose + signature contains 'struct timeval'. */ +#if (defined _MSC_VER || @REPLACE_STRUCT_TIMEVAL@) && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H +# define _GL_INCLUDING_WINSOCK2_H +# include +# undef _GL_INCLUDING_WINSOCK2_H +#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. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !@HAVE_STRUCT_TIMEVAL@ || @REPLACE_STRUCT_TIMEVAL@ + +# if @REPLACE_STRUCT_TIMEVAL@ +# define timeval rpl_timeval +# endif + +# if !GNULIB_defined_struct_timeval +struct timeval +{ + time_t tv_sec; + long int tv_usec; +}; +# define GNULIB_defined_struct_timeval 1 +# endif + +#endif + +#ifdef __cplusplus +} +#endif + +#if @GNULIB_GETTIMEOFDAY@ +# if @REPLACE_GETTIMEOFDAY@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gettimeofday +# define gettimeofday rpl_gettimeofday +# endif +_GL_FUNCDECL_RPL (gettimeofday, int, + (struct timeval *restrict, void *restrict) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (gettimeofday, int, + (struct timeval *restrict, void *restrict)); +# else +# if !@HAVE_GETTIMEOFDAY@ +_GL_FUNCDECL_SYS (gettimeofday, int, + (struct timeval *restrict, void *restrict) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on glibc systems, by default, the second argument is + struct timezone *. */ +_GL_CXXALIAS_SYS_CAST (gettimeofday, int, + (struct timeval *restrict, void *restrict)); +# endif +_GL_CXXALIASWARN (gettimeofday); +# if defined __cplusplus && defined GNULIB_NAMESPACE +namespace GNULIB_NAMESPACE { + typedef ::timeval +# undef timeval + timeval; +# if @REPLACE_STRUCT_TIMEVAL@ +# define timeval rpl_timeval + typedef ::timeval timeval; +# endif +} +# endif +#elif defined GNULIB_POSIXCHECK +# undef gettimeofday +# if HAVE_RAW_DECL_GETTIMEOFDAY +_GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - " + "use gnulib module gettimeofday for portability"); +# endif +#endif + +/* Hide some function declarations from . */ + +#if defined _MSC_VER && @HAVE_WINSOCK2_H@ +# if !defined _@GUARD_PREFIX@_UNISTD_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef close +# define close close_used_without_including_unistd_h +# elif !defined __clang__ + _GL_WARN_ON_USE (close, + "close() used without including "); +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gethostname +# define gethostname gethostname_used_without_including_unistd_h +# else + _GL_WARN_ON_USE (gethostname, + "gethostname() used without including "); +# endif +# endif +# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef socket +# define socket socket_used_without_including_sys_socket_h +# undef connect +# define connect connect_used_without_including_sys_socket_h +# undef accept +# define accept accept_used_without_including_sys_socket_h +# undef bind +# define bind bind_used_without_including_sys_socket_h +# undef getpeername +# define getpeername getpeername_used_without_including_sys_socket_h +# undef getsockname +# define getsockname getsockname_used_without_including_sys_socket_h +# undef getsockopt +# define getsockopt getsockopt_used_without_including_sys_socket_h +# undef listen +# define listen listen_used_without_including_sys_socket_h +# undef recv +# define recv recv_used_without_including_sys_socket_h +# undef send +# define send send_used_without_including_sys_socket_h +# undef recvfrom +# define recvfrom recvfrom_used_without_including_sys_socket_h +# undef sendto +# define sendto sendto_used_without_including_sys_socket_h +# undef setsockopt +# define setsockopt setsockopt_used_without_including_sys_socket_h +# undef shutdown +# define shutdown shutdown_used_without_including_sys_socket_h +# else + _GL_WARN_ON_USE (socket, + "socket() used without including "); + _GL_WARN_ON_USE (connect, + "connect() used without including "); + _GL_WARN_ON_USE (accept, + "accept() used without including "); + _GL_WARN_ON_USE (bind, + "bind() used without including "); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including "); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including "); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including "); + _GL_WARN_ON_USE (listen, + "listen() used without including "); + _GL_WARN_ON_USE (recv, + "recv() used without including "); + _GL_WARN_ON_USE (send, + "send() used without including "); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including "); + _GL_WARN_ON_USE (sendto, + "sendto() used without including "); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including "); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including "); +# endif +# endif +# if !defined _@GUARD_PREFIX@_SYS_SELECT_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef select +# define select select_used_without_including_sys_select_h +# else + _GL_WARN_ON_USE (select, + "select() used without including "); +# endif +# endif +#endif + +#endif /* _@GUARD_PREFIX@_SYS_TIME_H */ +#endif /* _CYGWIN_SYS_TIME_H */ +#endif /* _@GUARD_PREFIX@_SYS_TIME_H */ diff --git a/lib/sys_types.in.h b/lib/sys_types.in.h new file mode 100644 index 0000000..698e88d --- /dev/null +++ b/lib/sys_types.in.h @@ -0,0 +1,106 @@ +/* Provide a more complete sys/types.h. + + 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 __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 + +/* Override off_t if Large File Support is requested on native Windows. */ +#if @WINDOWS_64_BIT_OFF_T@ +/* Same as int64_t in . */ +# if defined _MSC_VER +# define off_t __int64 +# else +# define off_t long long int +# endif +/* Indicator, for gnulib internal purposes. */ +# 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 __CYGWIN__) && ! defined __GLIBC__ +# include +#endif + +#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ +#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ +#endif /* __need_XXX */ diff --git a/lib/sys_uio.in.h b/lib/sys_uio.in.h new file mode 100644 index 0000000..788d461 --- /dev/null +++ b/lib/sys_uio.in.h @@ -0,0 +1,63 @@ +/* Substitute for . + 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 __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +# endif +@PRAGMA_COLUMNS@ + +#ifndef _@GUARD_PREFIX@_SYS_UIO_H + +#if @HAVE_SYS_UIO_H@ + +/* On OpenBSD 4.4, assumes prior inclusion of . */ +# include + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYS_UIO_H@ + +#endif + +#ifndef _@GUARD_PREFIX@_SYS_UIO_H +#define _@GUARD_PREFIX@_SYS_UIO_H + +#if !@HAVE_SYS_UIO_H@ +/* A platform that lacks . */ +/* Get 'size_t' and 'ssize_t'. */ +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# if !GNULIB_defined_struct_iovec +/* All known platforms that lack also lack any declaration + of struct iovec in any other header. */ +struct iovec { + void *iov_base; + size_t iov_len; +}; +# define GNULIB_defined_struct_iovec 1 +# endif + +# ifdef __cplusplus +} +# endif + +#endif + +#endif /* _@GUARD_PREFIX@_SYS_UIO_H */ +#endif /* _@GUARD_PREFIX@_SYS_UIO_H */ diff --git a/lib/sys_wait.in.h b/lib/sys_wait.in.h new file mode 100644 index 0000000..7c48c2e --- /dev/null +++ b/lib/sys_wait.in.h @@ -0,0 +1,131 @@ +/* A POSIX-like . + Copyright (C) 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 . */ + + +#ifndef _@GUARD_PREFIX@_SYS_WAIT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if !(defined _WIN32 && ! defined __CYGWIN__) +# @INCLUDE_NEXT@ @NEXT_SYS_WAIT_H@ +#endif + +#ifndef _@GUARD_PREFIX@_SYS_WAIT_H +#define _@GUARD_PREFIX@_SYS_WAIT_H + +/* Get pid_t. */ +#include + + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +#if !(defined _WIN32 && ! defined __CYGWIN__) +/* Unix API. */ + +/* The following macros apply to an argument x, that is a status of a process, + as returned by waitpid(). + On nearly all systems, including Linux/x86, WEXITSTATUS are bits 15..8 and + WTERMSIG are bits 7..0, while BeOS uses the opposite. Therefore programs + have to use the abstract macros. */ + +/* For valid x, exactly one of WIFSIGNALED(x), WIFEXITED(x), WIFSTOPPED(x) + is true. */ +# ifndef WIFSIGNALED +# define WIFSIGNALED(x) (WTERMSIG (x) != 0 && WTERMSIG(x) != 0x7f) +# endif +# ifndef WIFEXITED +# define WIFEXITED(x) (WTERMSIG (x) == 0) +# endif +# ifndef WIFSTOPPED +# define WIFSTOPPED(x) (WTERMSIG (x) == 0x7f) +# endif + +/* The termination signal. Only to be accessed if WIFSIGNALED(x) is true. */ +# ifndef WTERMSIG +# define WTERMSIG(x) ((x) & 0x7f) +# endif + +/* The exit status. Only to be accessed if WIFEXITED(x) is true. */ +# ifndef WEXITSTATUS +# define WEXITSTATUS(x) (((x) >> 8) & 0xff) +# endif + +/* The stopping signal. Only to be accessed if WIFSTOPPED(x) is true. */ +# ifndef WSTOPSIG +# define WSTOPSIG(x) (((x) >> 8) & 0x7f) +# endif + +/* True if the process dumped core. Not standardized by POSIX. */ +# ifndef WCOREDUMP +# define WCOREDUMP(x) ((x) & 0x80) +# endif + +#else +/* Native Windows API. */ + +# include /* for SIGTERM */ + +/* The following macros apply to an argument x, that is a status of a process, + as returned by waitpid() or, equivalently, _cwait() or GetExitCodeProcess(). + This value is simply an 'int', not composed of bit fields. */ + +/* When an unhandled fatal signal terminates a process, the exit code is 3. */ +# define WIFSIGNALED(x) ((x) == 3) +# define WIFEXITED(x) ((x) != 3) +# define WIFSTOPPED(x) 0 + +/* The signal that terminated a process is not known posthum. */ +# define WTERMSIG(x) SIGTERM + +# define WEXITSTATUS(x) (x) + +/* There are no stopping signals. */ +# define WSTOPSIG(x) 0 + +/* There are no core dumps. */ +# define WCOREDUMP(x) 0 + +#endif + + +/* Declarations of functions. */ + +#if @GNULIB_WAITPID@ +# if defined _WIN32 && ! defined __CYGWIN__ +_GL_FUNCDECL_SYS (waitpid, pid_t, (pid_t pid, int *statusp, int options)); +# endif +/* Need to cast, because on Cygwin, the second parameter is + __wait_status_ptr_t statusp. */ +_GL_CXXALIAS_SYS_CAST (waitpid, pid_t, (pid_t pid, int *statusp, int options)); +_GL_CXXALIASWARN (waitpid); +#elif defined GNULIB_POSIXCHECK +# undef waitpid +# if HAVE_RAW_DECL_WAITPID +_GL_WARN_ON_USE (waitpid, "waitpid is unportable - " + "use gnulib module sys_wait for portability"); +# endif +#endif + + +#endif /* _@GUARD_PREFIX@_SYS_WAIT_H */ +#endif /* _@GUARD_PREFIX@_SYS_WAIT_H */ diff --git a/lib/tempname.c b/lib/tempname.c new file mode 100644 index 0000000..5fc5efe --- /dev/null +++ b/lib/tempname.c @@ -0,0 +1,345 @@ +/* Copyright (C) 1991-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 + . */ + +#if !_LIBC +# include +# include "tempname.h" +#endif + +#include +#include +#include + +#include + +#include +#ifndef P_tmpdir +# define P_tmpdir "/tmp" +#endif +#ifndef TMP_MAX +# define TMP_MAX 238328 +#endif +#ifndef __GT_FILE +# define __GT_FILE 0 +# define __GT_DIR 1 +# define __GT_NOCREATE 2 +#endif +#if !_LIBC && (GT_FILE != __GT_FILE || GT_DIR != __GT_DIR \ + || GT_NOCREATE != __GT_NOCREATE) +# error report this to bug-gnulib@gnu.org +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if _LIBC +# define struct_stat64 struct stat64 +# define __secure_getenv __libc_secure_getenv +#else +# define struct_stat64 struct stat +# define __gen_tempname gen_tempname +# define __mkdir mkdir +# define __open open +# define __lstat64(file, buf) lstat (file, buf) +# define __stat64(file, buf) stat (file, buf) +# define __getrandom getrandom +# define __clock_gettime64 clock_gettime +# define __timespec64 timespec +#endif + +/* Use getrandom if it works, falling back on a 64-bit linear + congruential generator that starts with Var's value + mixed in with a clock's low-order bits if available. */ +typedef uint_fast64_t random_value; +#define RANDOM_VALUE_MAX UINT_FAST64_MAX +#define BASE_62_DIGITS 10 /* 62**10 < UINT_FAST64_MAX */ +#define BASE_62_POWER (62LL * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62) + +static random_value +random_bits (random_value var, bool use_getrandom) +{ + random_value r; + /* Without GRND_NONBLOCK it can be blocked for minutes on some systems. */ + if (use_getrandom && __getrandom (&r, sizeof r, GRND_NONBLOCK) == sizeof r) + return r; +#if _LIBC || (defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME) + /* Add entropy if getrandom did not work. */ + struct __timespec64 tv; + __clock_gettime64 (CLOCK_MONOTONIC, &tv); + var ^= tv.tv_nsec; +#endif + return 2862933555777941757 * var + 3037000493; +} + +#if _LIBC +/* Return nonzero if DIR is an existent directory. */ +static int +direxists (const char *dir) +{ + struct_stat64 buf; + return __stat64 (dir, &buf) == 0 && S_ISDIR (buf.st_mode); +} + +/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is + non-null and exists, uses it; otherwise uses the first of $TMPDIR, + P_tmpdir, /tmp that exists. Copies into TMPL a template suitable + for use with mk[s]temp. Will fail (-1) if DIR is non-null and + doesn't exist, none of the searched dirs exists, or there's not + enough space in TMPL. */ +int +__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, + int try_tmpdir) +{ + const char *d; + size_t dlen, plen; + + if (!pfx || !pfx[0]) + { + pfx = "file"; + plen = 4; + } + else + { + plen = strlen (pfx); + if (plen > 5) + plen = 5; + } + + if (try_tmpdir) + { + d = __secure_getenv ("TMPDIR"); + if (d != NULL && direxists (d)) + dir = d; + else if (dir != NULL && direxists (dir)) + /* nothing */ ; + else + dir = NULL; + } + if (dir == NULL) + { + if (direxists (P_tmpdir)) + dir = P_tmpdir; + else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) + dir = "/tmp"; + else + { + __set_errno (ENOENT); + return -1; + } + } + + dlen = strlen (dir); + while (dlen > 1 && dir[dlen - 1] == '/') + dlen--; /* remove trailing slashes */ + + /* check we have room for "${dir}/${pfx}XXXXXX\0" */ + if (tmpl_len < dlen + 1 + plen + 6 + 1) + { + __set_errno (EINVAL); + return -1; + } + + sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); + return 0; +} +#endif /* _LIBC */ + +#if _LIBC +static int try_tempname_len (char *, int, void *, int (*) (char *, void *), + size_t); +#endif + +static int +try_file (char *tmpl, void *flags) +{ + int *openflags = flags; + return __open (tmpl, + (*openflags & ~O_ACCMODE) + | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); +} + +static int +try_dir (char *tmpl, _GL_UNUSED void *flags) +{ + return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); +} + +static int +try_nocreate (char *tmpl, _GL_UNUSED void *flags) +{ + struct_stat64 st; + + if (__lstat64 (tmpl, &st) == 0 || errno == EOVERFLOW) + __set_errno (EEXIST); + return errno == ENOENT ? 0 : -1; +} + +/* These are the characters used in temporary file names. */ +static const char letters[] = +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e., end in at least X_SUFFIX_LEN "X"s, + possibly with a suffix). + The name constructed does not exist at the time of the call to + this function. TMPL is overwritten with the result. + + KIND may be one of: + __GT_NOCREATE: simply verify that the name does not exist + at the time of the call. + __GT_FILE: create the file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. + __GT_DIR: create a directory, which will be mode 0700. + + We use a clever algorithm to get hard-to-predict names. */ +#ifdef _LIBC +static +#endif +int +gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind, + size_t x_suffix_len) +{ + static int (*const tryfunc[]) (char *, void *) = + { + [__GT_FILE] = try_file, + [__GT_DIR] = try_dir, + [__GT_NOCREATE] = try_nocreate + }; + return try_tempname_len (tmpl, suffixlen, &flags, tryfunc[kind], + x_suffix_len); +} + +#ifdef _LIBC +static +#endif +int +try_tempname_len (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *), size_t x_suffix_len) +{ + size_t len; + char *XXXXXX; + unsigned int count; + int fd = -1; + int save_errno = errno; + + /* A lower bound on the number of temporary files to attempt to + generate. The maximum total number of temporary file names that + can exist for a given template is 62**6. It should never be + necessary to try all of these combinations. Instead if a reasonable + number of names is tried (we define reasonable as 62**3) fail to + give the system administrator the chance to remove the problems. + This value requires that X_SUFFIX_LEN be at least 3. */ +#define ATTEMPTS_MIN (62 * 62 * 62) + + /* The number of times to attempt to generate a temporary file. To + conform to POSIX, this must be no smaller than TMP_MAX. */ +#if ATTEMPTS_MIN < TMP_MAX + unsigned int attempts = TMP_MAX; +#else + unsigned int attempts = ATTEMPTS_MIN; +#endif + + /* A random variable. The initial value is used only the for fallback path + on 'random_bits' on 'getrandom' failure. Its initial value tries to use + some entropy from the ASLR and ignore possible bits from the stack + alignment. */ + random_value v = ((uintptr_t) &v) / alignof (max_align_t); + + /* How many random base-62 digits can currently be extracted from V. */ + int vdigits = 0; + + /* Whether to consume entropy when acquiring random bits. On the + first try it's worth the entropy cost with __GT_NOCREATE, which + is inherently insecure and can use the entropy to make it a bit + less secure. On the (rare) second and later attempts it might + help against DoS attacks. */ + bool use_getrandom = tryfunc == try_nocreate; + + /* Least unfair value for V. If V is less than this, V can generate + BASE_62_DIGITS digits fairly. Otherwise it might be biased. */ + random_value const unfair_min + = RANDOM_VALUE_MAX - RANDOM_VALUE_MAX % BASE_62_POWER; + + len = strlen (tmpl); + if (len < x_suffix_len + suffixlen + || strspn (&tmpl[len - x_suffix_len - suffixlen], "X") < x_suffix_len) + { + __set_errno (EINVAL); + return -1; + } + + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - x_suffix_len - suffixlen]; + + for (count = 0; count < attempts; ++count) + { + for (size_t i = 0; i < x_suffix_len; i++) + { + if (vdigits == 0) + { + do + { + v = random_bits (v, use_getrandom); + use_getrandom = true; + } + while (unfair_min <= v); + + vdigits = BASE_62_DIGITS; + } + + XXXXXX[i] = letters[v % 62]; + v /= 62; + vdigits--; + } + + fd = tryfunc (tmpl, args); + if (fd >= 0) + { + __set_errno (save_errno); + return fd; + } + else if (errno != EEXIST) + return -1; + } + + /* We got out of the loop because we ran out of combinations to try. */ + __set_errno (EEXIST); + return -1; +} + +int +__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) +{ + return gen_tempname_len (tmpl, suffixlen, flags, kind, 6); +} + +#if !_LIBC +int +try_tempname (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *)) +{ + return try_tempname_len (tmpl, suffixlen, args, tryfunc, 6); +} +#endif diff --git a/lib/tempname.h b/lib/tempname.h new file mode 100644 index 0000000..c172820 --- /dev/null +++ b/lib/tempname.h @@ -0,0 +1,72 @@ +/* Create a temporary file or directory. + + Copyright (C) 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 . */ + +/* header written by Eric Blake */ + +#ifndef GL_TEMPNAME_H +# define GL_TEMPNAME_H + +# include + +# ifdef __GT_FILE +# define GT_FILE __GT_FILE +# define GT_DIR __GT_DIR +# define GT_NOCREATE __GT_NOCREATE +# else +# define GT_FILE 0 +# define GT_DIR 1 +# define GT_NOCREATE 2 +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). + The name constructed does not exist at the time of the call to + gen_tempname. TMPL is overwritten with the result. + + KIND may be one of: + GT_NOCREATE: simply verify that the name does not exist + at the time of the call. + GT_FILE: create a large file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. + GT_DIR: create a directory, which will be mode 0700. + + We use a clever algorithm to get hard-to-predict names. */ +extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind); +/* Similar, except X_SUFFIX_LEN gives the number of Xs. */ +extern int gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind, + size_t x_suffix_len); + +/* Similar to gen_tempname, but TRYFUNC is called for each temporary + name to try. If TRYFUNC returns a non-negative number, TRY_GEN_TEMPNAME + returns with this value. Otherwise, if errno is set to EEXIST, another + name is tried, or else TRY_GEN_TEMPNAME returns -1. */ +extern int try_tempname (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *)); +/* Similar, except X_SUFFIX_LEN gives the number of Xs. */ +extern int try_tempname_len (char *tmpl, int suffixlen, void *args, + int (*tryfunc) (char *, void *), + size_t x_suffix_len); + +#ifdef __cplusplus +} +#endif + +#endif /* GL_TEMPNAME_H */ diff --git a/lib/thread-optim.h b/lib/thread-optim.h new file mode 100644 index 0000000..daf887f --- /dev/null +++ b/lib/thread-optim.h @@ -0,0 +1,60 @@ +/* Optimization of multithreaded code. + + Copyright (C) 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 Bruno Haible , 2020. */ + +#ifndef _THREAD_OPTIM_H +#define _THREAD_OPTIM_H + +/* This file defines a way to optimize multithreaded code for the single-thread + case, based on the variable '__libc_single_threaded', defined in + glibc >= 2.32. */ + +/* Typical use: In a block or function, use + + bool mt = gl_multithreaded (); + ... + if (mt) + if (pthread_mutex_lock (&lock)) abort (); + ... + if (mt) + if (pthread_mutex_unlock (&lock)) abort (); + + The gl_multithreaded () invocation determines whether the program currently + is multithreaded. + + if (mt) STATEMENT executes STATEMENT in the multithreaded case, and skips + it in the single-threaded case. + + The code between the gl_multithreaded () invocation and any use of the + variable 'mt' must not create threads or invoke functions that may + indirectly create threads (e.g. 'dlopen' may, indirectly through C++ + initializers of global variables in the shared library being opened, + create threads). + + The lock here is meant to synchronize threads in the same process. The + same optimization cannot be applied to locks that synchronize different + processes (e.g. through shared memory mappings). */ + +#if HAVE_SYS_SINGLE_THREADED_H /* glibc >= 2.32 */ +# include +# define gl_multithreaded() !__libc_single_threaded +#else +# define gl_multithreaded() 1 +#endif + +#endif /* _THREAD_OPTIM_H */ diff --git a/lib/time.in.h b/lib/time.in.h new file mode 100644 index 0000000..6d4c771 --- /dev/null +++ b/lib/time.in.h @@ -0,0 +1,452 @@ +/* A more-standard . + + 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 . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* 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. (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) \ + && !defined __MINGW32__) \ + || defined _@GUARD_PREFIX@_TIME_H) + +# @INCLUDE_NEXT@ @NEXT_TIME_H@ + +#else + +# 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. */ +# include + +/* 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. */ + +/* 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 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 +# elif @UNISTD_H_DEFINES_STRUCT_TIMESPEC@ +# include +# else + +# ifdef __cplusplus +extern "C" { +# endif + +# if !GNULIB_defined_struct_timespec +# undef timespec +# define timespec rpl_timespec +struct timespec +{ + time_t tv_sec; + long int tv_nsec; +}; +# define GNULIB_defined_struct_timespec 1 +# endif + +# ifdef __cplusplus +} +# endif + +# endif +# endif + +# if !GNULIB_defined_struct_time_t_must_be_integral +/* 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. */ +struct __time_t_must_be_integral { + unsigned int __floating_time_t_unsupported : (time_t) 1; +}; +# 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) +# define nanosleep rpl_nanosleep +# endif +_GL_FUNCDECL_RPL (nanosleep, int, + (struct timespec const *__rqtp, struct timespec *__rmtp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (nanosleep, int, + (struct timespec const *__rqtp, struct timespec *__rmtp)); +# else +# if ! @HAVE_NANOSLEEP@ +_GL_FUNCDECL_SYS (nanosleep, int, + (struct timespec const *__rqtp, struct timespec *__rmtp) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (nanosleep, int, + (struct timespec const *__rqtp, struct timespec *__rmtp)); +# endif +_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@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mktime rpl_mktime +# endif +_GL_FUNCDECL_RPL (mktime, time_t, (struct tm *__tp) _GL_ARG_NONNULL ((1))); +_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 + . */ +# if @GNULIB_TIME_R@ +# if @REPLACE_LOCALTIME_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef localtime_r +# define localtime_r rpl_localtime_r +# endif +_GL_FUNCDECL_RPL (localtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (localtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result)); +# else +# if ! @HAVE_DECL_LOCALTIME_R@ +_GL_FUNCDECL_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result)); +# endif +# if @HAVE_DECL_LOCALTIME_R@ +_GL_CXXALIASWARN (localtime_r); +# endif +# if @REPLACE_LOCALTIME_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gmtime_r +# define gmtime_r rpl_gmtime_r +# endif +_GL_FUNCDECL_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result)); +# else +# if ! @HAVE_DECL_LOCALTIME_R@ +_GL_FUNCDECL_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer, + struct tm *restrict __result)); +# endif +# if @HAVE_DECL_LOCALTIME_R@ +_GL_CXXALIASWARN (gmtime_r); +# endif +# endif + +/* 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, + char const *restrict __format, + struct tm *restrict __tm) + _GL_ARG_NONNULL ((1, 2, 3))); +# endif +_GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf, + char const *restrict __format, + struct tm *restrict __tm)); +_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@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef timegm +# define timegm rpl_timegm +# endif +_GL_FUNCDECL_RPL (timegm, time_t, (struct tm *__tm) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (timegm, time_t, (struct tm *__tm)); +# else +# if ! @HAVE_TIMEGM@ +_GL_FUNCDECL_SYS (timegm, time_t, (struct tm *__tm) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (timegm, time_t, (struct tm *__tm)); +# endif +_GL_CXXALIASWARN (timegm); +# endif + +/* Encourage applications to avoid unsafe functions that can overrun + buffers when given outlandish struct tm values. Portable + applications should use strftime (or even sprintf) instead. */ +# if defined GNULIB_POSIXCHECK +# undef asctime +_GL_WARN_ON_USE (asctime, "asctime can overrun buffers in some cases - " + "better use strftime (or even sprintf) instead"); +# endif +# if defined GNULIB_POSIXCHECK +# undef asctime_r +_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 (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 (ctime_r, "ctime_r can overrun buffers in some cases - " + "better use strftime (or even sprintf) instead"); +# endif + +#endif diff --git a/lib/time_r.c b/lib/time_r.c new file mode 100644 index 0000000..d4b2275 --- /dev/null +++ b/lib/time_r.c @@ -0,0 +1,44 @@ +/* Reentrant time functions like localtime_r. + + Copyright (C) 2003, 2006-2007, 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 . */ + +/* Written by Paul Eggert. */ + +#include + +#include + +static struct tm * +copy_tm_result (struct tm *dest, struct tm const *src) +{ + if (! src) + return 0; + *dest = *src; + return dest; +} + + +struct tm * +gmtime_r (time_t const * restrict t, struct tm * restrict tp) +{ + return copy_tm_result (tp, gmtime (t)); +} + +struct tm * +localtime_r (time_t const * restrict t, struct tm * restrict tp) +{ + return copy_tm_result (tp, localtime (t)); +} diff --git a/lib/timegm.c b/lib/timegm.c new file mode 100644 index 0000000..a1b19ef --- /dev/null +++ b/lib/timegm.c @@ -0,0 +1,58 @@ +/* Convert UTC calendar time to simple time. Like mktime but assumes UTC. + + Copyright (C) 1994-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 "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) +{ + 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/lib/timespec.c b/lib/timespec.c new file mode 100644 index 0000000..9d136cb --- /dev/null +++ b/lib/timespec.c @@ -0,0 +1,21 @@ +/* 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 3 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_TIMESPEC_INLINE _GL_EXTERN_INLINE +#include "timespec.h" diff --git a/lib/timespec.h b/lib/timespec.h new file mode 100644 index 0000000..9e35828 --- /dev/null +++ b/lib/timespec.h @@ -0,0 +1,102 @@ +/* timespec -- System time interface + + Copyright (C) 2000, 2002, 2004-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 3 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 ! defined TIMESPEC_H +#define TIMESPEC_H + +#include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef _GL_TIMESPEC_INLINE +# define _GL_TIMESPEC_INLINE _GL_INLINE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "arg-nonnull.h" + +/* Inverse resolution of timespec timestamps (in units per second), + and log base 10 of the inverse resolution. */ + +enum { TIMESPEC_HZ = 1000000000 }; +enum { LOG10_TIMESPEC_HZ = 9 }; + +/* Obsolescent names for backward compatibility. + They are misnomers, because TIMESPEC_RESOLUTION is not a resolution. */ + +enum { TIMESPEC_RESOLUTION = TIMESPEC_HZ }; +enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ }; + +/* Return a timespec with seconds S and nanoseconds NS. */ + +_GL_TIMESPEC_INLINE struct timespec +make_timespec (time_t s, long int ns) +{ + struct timespec r; + r.tv_sec = s; + r.tv_nsec = ns; + return r; +} + +/* Return negative, zero, positive if A < B, A == B, A > B, respectively. */ + +_GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE +timespec_cmp (struct timespec a, struct timespec b) +{ + return 2 * _GL_CMP (a.tv_sec, b.tv_sec) + _GL_CMP (a.tv_nsec, b.tv_nsec); +} + +/* Return -1, 0, 1, depending on the sign of A. A.tv_nsec must be + nonnegative. */ +_GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE +timespec_sign (struct timespec a) +{ + return _GL_CMP (a.tv_sec, 0) + (!a.tv_sec & !!a.tv_nsec); +} + +struct timespec timespec_add (struct timespec, struct timespec) + _GL_ATTRIBUTE_CONST; +struct timespec timespec_sub (struct timespec, struct timespec) + _GL_ATTRIBUTE_CONST; +struct timespec dtotimespec (double) + _GL_ATTRIBUTE_CONST; + +/* Return an approximation to A, of type 'double'. */ +_GL_TIMESPEC_INLINE double +timespectod (struct timespec a) +{ + return a.tv_sec + a.tv_nsec / 1e9; +} + +long int gettime_res (void); +struct timespec current_timespec (void); +void gettime (struct timespec *) _GL_ARG_NONNULL ((1)); +int settime (struct timespec const *) _GL_ARG_NONNULL ((1)); + +#ifdef __cplusplus +} +#endif + +_GL_INLINE_HEADER_END + +#endif diff --git a/lib/tmpdir.c b/lib/tmpdir.c new file mode 100644 index 0000000..3e47875 --- /dev/null +++ b/lib/tmpdir.c @@ -0,0 +1,165 @@ +/* Copyright (C) 1999, 2001-2002, 2006, 2009-2022 Free Software Foundation, + Inc. + This file is part of 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 3 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 . */ + +/* Extracted from sysdeps/posix/tempname.c. */ + +#include + +/* Specification. */ +#include "tmpdir.h" + +#include +#include +#include + +#include +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#include +#ifndef P_tmpdir +# ifdef _P_tmpdir /* native Windows */ +# define P_tmpdir _P_tmpdir +# else +# define P_tmpdir "/tmp" +# endif +#endif + +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include +#endif + +#include "pathmax.h" + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Don't assume that UNICODE is not defined. */ +# undef GetTempPath +# define GetTempPath GetTempPathA +#endif + +#if _LIBC +# define struct_stat64 struct stat64 +#else +# define struct_stat64 struct stat +# define __libc_secure_getenv secure_getenv +# define __xstat64(version, path, buf) stat (path, buf) +#endif + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + */ +#if defined _WIN32 || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Native Windows, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +#endif + + +/* Return nonzero if DIR is an existent directory. */ +static bool +direxists (const char *dir) +{ + struct_stat64 buf; + return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); +} + +/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is + non-null and exists, uses it; otherwise uses the first of $TMPDIR, + P_tmpdir, /tmp that exists. Copies into TMPL a template suitable + for use with mk[s]temp. Will fail (-1) if DIR is non-null and + doesn't exist, none of the searched dirs exists, or there's not + enough space in TMPL. */ +int +path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, + bool try_tmpdir) +{ + const char *d; + size_t dlen, plen; + bool add_slash; + + if (!pfx || !pfx[0]) + { + pfx = "file"; + plen = 4; + } + else + { + plen = strlen (pfx); + if (plen > 5) + plen = 5; + } + + if (try_tmpdir) + { + d = __libc_secure_getenv ("TMPDIR"); + if (d != NULL && direxists (d)) + dir = d; + else if (dir != NULL && direxists (dir)) + /* nothing */ ; + else + dir = NULL; + } + if (dir == NULL) + { +#if defined _WIN32 && ! defined __CYGWIN__ + char dirbuf[PATH_MAX]; + DWORD retval; + + /* Find Windows temporary file directory. + We try this before P_tmpdir because Windows defines P_tmpdir to "\\" + and will therefore try to put all temporary files in the root + directory (unless $TMPDIR is set). */ + retval = GetTempPath (PATH_MAX, dirbuf); + if (retval > 0 && retval < PATH_MAX && direxists (dirbuf)) + dir = dirbuf; + else +#endif + if (direxists (P_tmpdir)) + dir = P_tmpdir; + else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) + dir = "/tmp"; + else + { + __set_errno (ENOENT); + return -1; + } + } + + dlen = strlen (dir); +#ifdef __VMS + add_slash = 0; +#else + add_slash = dlen != 0 && !ISSLASH (dir[dlen - 1]); +#endif + + /* check we have room for "${dir}/${pfx}XXXXXX\0" */ + if (tmpl_len < dlen + add_slash + plen + 6 + 1) + { + __set_errno (EINVAL); + return -1; + } + + memcpy (tmpl, dir, dlen); + sprintf (tmpl + dlen, &"/%.*sXXXXXX"[!add_slash], (int) plen, pfx); + return 0; +} diff --git a/lib/tmpdir.h b/lib/tmpdir.h new file mode 100644 index 0000000..ec14ee1 --- /dev/null +++ b/lib/tmpdir.h @@ -0,0 +1,26 @@ +/* Determine a temporary directory. + Copyright (C) 2001-2002, 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 3 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 + +/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is + non-null and exists, uses it; otherwise uses the first of $TMPDIR, + P_tmpdir, /tmp that exists. Copies into TMPL a template suitable + for use with mk[s]temp. Will fail (-1) if DIR is non-null and + doesn't exist, none of the searched dirs exists, or there's not + enough space in TMPL. */ +extern int path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, bool try_tmpdir); diff --git a/lib/u64.c b/lib/u64.c new file mode 100644 index 0000000..0eefeae --- /dev/null +++ b/lib/u64.c @@ -0,0 +1,22 @@ +/* uint64_t-like operations that work even on hosts lacking uint64_t + + 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_U64_INLINE _GL_EXTERN_INLINE +#include "u64.h" +typedef int dummy; diff --git a/lib/u64.h b/lib/u64.h new file mode 100644 index 0000000..1908e7c --- /dev/null +++ b/lib/u64.h @@ -0,0 +1,179 @@ +/* uint64_t-like operations that work even on hosts lacking uint64_t + + Copyright (C) 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 + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef _GL_U64_INLINE +# define _GL_U64_INLINE _GL_INLINE +#endif + +/* Return X rotated left by N bits, where 0 < N < 64. */ +#define u64rol(x, n) u64or (u64shl (x, n), u64shr (x, 64 - n)) + +#ifdef UINT64_MAX + +/* Native implementations are trivial. See below for comments on what + these operations do. */ +typedef uint64_t u64; +# define u64hilo(hi, lo) ((u64) (((u64) (hi) << 32) + (lo))) +# define u64init(hi, lo) u64hilo (hi, lo) +# define u64lo(x) ((u64) (x)) +# define u64size(x) u64lo (x) +# define u64lt(x, y) ((x) < (y)) +# define u64and(x, y) ((x) & (y)) +# define u64or(x, y) ((x) | (y)) +# define u64xor(x, y) ((x) ^ (y)) +# define u64plus(x, y) ((x) + (y)) +# define u64shl(x, n) ((x) << (n)) +# define u64shr(x, n) ((x) >> (n)) + +#else + +/* u64 is a 64-bit unsigned integer value. + u64init (HI, LO), is like u64hilo (HI, LO), but for use in + initializer contexts. */ +# ifdef WORDS_BIGENDIAN +typedef struct { uint32_t hi, lo; } u64; +# define u64init(hi, lo) { hi, lo } +# else +typedef struct { uint32_t lo, hi; } u64; +# define u64init(hi, lo) { lo, hi } +# endif + +/* Given the high and low-order 32-bit quantities HI and LO, return a u64 + value representing (HI << 32) + LO. */ +_GL_U64_INLINE u64 +u64hilo (uint32_t hi, uint32_t lo) +{ + u64 r; + r.hi = hi; + r.lo = lo; + return r; +} + +/* Return a u64 value representing LO. */ +_GL_U64_INLINE u64 +u64lo (uint32_t lo) +{ + u64 r; + r.hi = 0; + r.lo = lo; + return r; +} + +/* Return a u64 value representing SIZE. */ +_GL_U64_INLINE u64 +u64size (size_t size) +{ + u64 r; + r.hi = size >> 31 >> 1; + r.lo = size; + return r; +} + +/* Return X < Y. */ +_GL_U64_INLINE int +u64lt (u64 x, u64 y) +{ + return x.hi < y.hi || (x.hi == y.hi && x.lo < y.lo); +} + +/* Return X & Y. */ +_GL_U64_INLINE u64 +u64and (u64 x, u64 y) +{ + u64 r; + r.hi = x.hi & y.hi; + r.lo = x.lo & y.lo; + return r; +} + +/* Return X | Y. */ +_GL_U64_INLINE u64 +u64or (u64 x, u64 y) +{ + u64 r; + r.hi = x.hi | y.hi; + r.lo = x.lo | y.lo; + return r; +} + +/* Return X ^ Y. */ +_GL_U64_INLINE u64 +u64xor (u64 x, u64 y) +{ + u64 r; + r.hi = x.hi ^ y.hi; + r.lo = x.lo ^ y.lo; + return r; +} + +/* Return X + Y. */ +_GL_U64_INLINE u64 +u64plus (u64 x, u64 y) +{ + u64 r; + r.lo = x.lo + y.lo; + r.hi = x.hi + y.hi + (r.lo < x.lo); + return r; +} + +/* Return X << N. */ +_GL_U64_INLINE u64 +u64shl (u64 x, int n) +{ + u64 r; + if (n < 32) + { + r.hi = (x.hi << n) | (x.lo >> (32 - n)); + r.lo = x.lo << n; + } + else + { + r.hi = x.lo << (n - 32); + r.lo = 0; + } + return r; +} + +/* Return X >> N. */ +_GL_U64_INLINE u64 +u64shr (u64 x, int n) +{ + u64 r; + if (n < 32) + { + r.hi = x.hi >> n; + r.lo = (x.hi << (32 - n)) | (x.lo >> n); + } + else + { + r.hi = 0; + r.lo = x.hi >> (n - 32); + } + return r; +} + +#endif + +_GL_INLINE_HEADER_END diff --git a/lib/unicase.in.h b/lib/unicase.in.h new file mode 100644 index 0000000..9bcc79e --- /dev/null +++ b/lib/unicase.in.h @@ -0,0 +1,473 @@ +/* Unicode character case mappings. + Copyright (C) 2002, 2009-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#ifndef _UNICASE_H +#define _UNICASE_H + +#include "unitypes.h" + +/* Get bool. */ +#include + +/* Get size_t. */ +#include + +/* Get uninorm_t. */ +#include "uninorm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ========================================================================= */ + +/* Character case mappings. + These mappings are locale and context independent. + WARNING! These functions are not sufficient for languages such as German. + Better use the functions below that treat an entire string at once and are + language aware. */ + +/* Return the uppercase mapping of a Unicode character. */ +extern ucs4_t + uc_toupper (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Return the lowercase mapping of a Unicode character. */ +extern ucs4_t + uc_tolower (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Return the titlecase mapping of a Unicode character. */ +extern ucs4_t + uc_totitle (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* String case mappings. */ + +/* These functions are locale dependent. The iso639_language argument + identifies the language (e.g. "tr" for Turkish). NULL means to use + locale independent case mappings. */ + +/* Return the ISO 639 language code of the current locale. + Return "" if it is unknown, or in the "C" locale. */ +extern const char * + uc_locale_language (void) + _UC_ATTRIBUTE_PURE; + +/* Conventions: + + All functions prefixed with u8_ operate on UTF-8 encoded strings. + Their unit is an uint8_t (1 byte). + + All functions prefixed with u16_ operate on UTF-16 encoded strings. + Their unit is an uint16_t (a 2-byte word). + + All functions prefixed with u32_ operate on UCS-4 encoded strings. + Their unit is an uint32_t (a 4-byte word). + + All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly + n units. + + Functions returning a string result take a (resultbuf, lengthp) argument + pair. If resultbuf is not NULL and the result fits into *lengthp units, + it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly + allocated string is returned. In both cases, *lengthp is set to the + length (number of units) of the returned string. In case of error, + NULL is returned and errno is set. */ + +/* Return the uppercase mapping of a string. + The nf argument identifies the normalization form to apply after the + case-mapping. It can also be NULL, for no normalization. */ +extern uint8_t * + u8_toupper (const uint8_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_toupper (const uint16_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_toupper (const uint32_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Return the lowercase mapping of a string. + The nf argument identifies the normalization form to apply after the + case-mapping. It can also be NULL, for no normalization. */ +extern uint8_t * + u8_tolower (const uint8_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_tolower (const uint16_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_tolower (const uint32_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Return the titlecase mapping of a string. + The nf argument identifies the normalization form to apply after the + case-mapping. It can also be NULL, for no normalization. */ +extern uint8_t * + u8_totitle (const uint8_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_totitle (const uint16_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_totitle (const uint32_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* The case-mapping context given by a prefix string. */ +typedef struct casing_prefix_context + { + /* These fields are private, undocumented. */ + uint32_t last_char_except_ignorable; + uint32_t last_char_normal_or_above; + } + casing_prefix_context_t; +/* The case-mapping context of the empty prefix string. */ +extern const casing_prefix_context_t unicase_empty_prefix_context; +/* Return the case-mapping context of a given prefix string. */ +extern casing_prefix_context_t + u8_casing_prefix_context (const uint8_t *s, size_t n); +extern casing_prefix_context_t + u16_casing_prefix_context (const uint16_t *s, size_t n); +extern casing_prefix_context_t + u32_casing_prefix_context (const uint32_t *s, size_t n); +/* Return the case-mapping context of the prefix concat(A, S), given the + case-mapping context of the prefix A. */ +extern casing_prefix_context_t + u8_casing_prefixes_context (const uint8_t *s, size_t n, + casing_prefix_context_t a_context); +extern casing_prefix_context_t + u16_casing_prefixes_context (const uint16_t *s, size_t n, + casing_prefix_context_t a_context); +extern casing_prefix_context_t + u32_casing_prefixes_context (const uint32_t *s, size_t n, + casing_prefix_context_t a_context); + +/* The case-mapping context given by a suffix string. */ +typedef struct casing_suffix_context + { + /* These fields are private, undocumented. */ + uint32_t first_char_except_ignorable; + uint32_t bits; + } + casing_suffix_context_t; +/* The case-mapping context of the empty suffix string. */ +extern const casing_suffix_context_t unicase_empty_suffix_context; +/* Return the case-mapping context of a given suffix string. */ +extern casing_suffix_context_t + u8_casing_suffix_context (const uint8_t *s, size_t n); +extern casing_suffix_context_t + u16_casing_suffix_context (const uint16_t *s, size_t n); +extern casing_suffix_context_t + u32_casing_suffix_context (const uint32_t *s, size_t n); +/* Return the case-mapping context of the suffix concat(S, A), given the + case-mapping context of the suffix A. */ +extern casing_suffix_context_t + u8_casing_suffixes_context (const uint8_t *s, size_t n, + casing_suffix_context_t a_context); +extern casing_suffix_context_t + u16_casing_suffixes_context (const uint16_t *s, size_t n, + casing_suffix_context_t a_context); +extern casing_suffix_context_t + u32_casing_suffixes_context (const uint32_t *s, size_t n, + casing_suffix_context_t a_context); + +/* Return the uppercase mapping of a string that is surrounded by a prefix + and a suffix. */ +extern uint8_t * + u8_ct_toupper (const uint8_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_ct_toupper (const uint16_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_ct_toupper (const uint32_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Return the lowercase mapping of a string that is surrounded by a prefix + and a suffix. */ +extern uint8_t * + u8_ct_tolower (const uint8_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_ct_tolower (const uint16_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_ct_tolower (const uint32_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Return the titlecase mapping of a string that is surrounded by a prefix + and a suffix. */ +extern uint8_t * + u8_ct_totitle (const uint8_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_ct_totitle (const uint16_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_ct_totitle (const uint32_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Return the case folded string. + Comparing uN_casefold (S1) and uN_casefold (S2) with uN_cmp2() is equivalent + to comparing S1 and S2 with uN_casecmp(). + The nf argument identifies the normalization form to apply after the + case-mapping. It can also be NULL, for no normalization. */ +extern uint8_t * + u8_casefold (const uint8_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_casefold (const uint16_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_casefold (const uint32_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); +/* Likewise, for a string that is surrounded by a prefix and a suffix. */ +extern uint8_t * + u8_ct_casefold (const uint8_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_ct_casefold (const uint16_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_ct_casefold (const uint32_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + uninorm_t nf, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Compare S1 and S2, ignoring differences in case and normalization. + The nf argument identifies the normalization form to apply after the + case-mapping. It can also be NULL, for no normalization. + If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and + return 0. Upon failure, return -1 with errno set. */ +extern int + u8_casecmp (const uint8_t *s1, size_t n1, + const uint8_t *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); +extern int + u16_casecmp (const uint16_t *s1, size_t n1, + const uint16_t *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); +extern int + u32_casecmp (const uint32_t *s1, size_t n1, + const uint32_t *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); +extern int + ulc_casecmp (const char *s1, size_t n1, + const char *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); + +/* Convert the string S of length N to a NUL-terminated byte sequence, in such + a way that comparing uN_casexfrm (S1) and uN_casexfrm (S2) with the gnulib + function memcmp2() is equivalent to comparing S1 and S2 with uN_casecoll(). + NF must be either UNINORM_NFC, UNINORM_NFKC, or NULL for no normalization. */ +extern char * + u8_casexfrm (const uint8_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + char *_UC_RESTRICT resultbuf, size_t *lengthp); +extern char * + u16_casexfrm (const uint16_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + char *_UC_RESTRICT resultbuf, size_t *lengthp); +extern char * + u32_casexfrm (const uint32_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + char *_UC_RESTRICT resultbuf, size_t *lengthp); +extern char * + ulc_casexfrm (const char *s, size_t n, const char *iso639_language, + uninorm_t nf, + char *_UC_RESTRICT resultbuf, size_t *lengthp); + +/* Compare S1 and S2, ignoring differences in case and normalization, using the + collation rules of the current locale. + The nf argument identifies the normalization form to apply after the + case-mapping. It must be either UNINORM_NFC or UNINORM_NFKC. It can also + be NULL, for no normalization. + If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and + return 0. Upon failure, return -1 with errno set. */ +extern int + u8_casecoll (const uint8_t *s1, size_t n1, + const uint8_t *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); +extern int + u16_casecoll (const uint16_t *s1, size_t n1, + const uint16_t *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); +extern int + u32_casecoll (const uint32_t *s1, size_t n1, + const uint32_t *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); +extern int + ulc_casecoll (const char *s1, size_t n1, + const char *s2, size_t n2, + const char *iso639_language, uninorm_t nf, int *resultp); + + +/* Set *RESULTP to true if mapping NFD(S) to upper case is a no-op, or to false + otherwise, and return 0. Upon failure, return -1 with errno set. */ +extern int + u8_is_uppercase (const uint8_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u16_is_uppercase (const uint16_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u32_is_uppercase (const uint32_t *s, size_t n, + const char *iso639_language, + bool *resultp); + +/* Set *RESULTP to true if mapping NFD(S) to lower case is a no-op, or to false + otherwise, and return 0. Upon failure, return -1 with errno set. */ +extern int + u8_is_lowercase (const uint8_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u16_is_lowercase (const uint16_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u32_is_lowercase (const uint32_t *s, size_t n, + const char *iso639_language, + bool *resultp); + +/* Set *RESULTP to true if mapping NFD(S) to title case is a no-op, or to false + otherwise, and return 0. Upon failure, return -1 with errno set. */ +extern int + u8_is_titlecase (const uint8_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u16_is_titlecase (const uint16_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u32_is_titlecase (const uint32_t *s, size_t n, + const char *iso639_language, + bool *resultp); + +/* Set *RESULTP to true if applying case folding to NFD(S) is a no-op, or to + false otherwise, and return 0. Upon failure, return -1 with errno set. */ +extern int + u8_is_casefolded (const uint8_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u16_is_casefolded (const uint16_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u32_is_casefolded (const uint32_t *s, size_t n, + const char *iso639_language, + bool *resultp); + +/* Set *RESULTP to true if case matters for S, that is, if mapping NFD(S) to + either upper case or lower case or title case is not a no-op. + Set *RESULTP to false if NFD(S) maps to itself under the upper case mapping, + under the lower case mapping, and under the title case mapping; in other + words, when NFD(S) consists entirely of caseless characters. + Upon failure, return -1 with errno set. */ +extern int + u8_is_cased (const uint8_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u16_is_cased (const uint16_t *s, size_t n, + const char *iso639_language, + bool *resultp); +extern int + u32_is_cased (const uint32_t *s, size_t n, + const char *iso639_language, + bool *resultp); + + +/* ========================================================================= */ + +#ifdef __cplusplus +} +#endif + +#endif /* _UNICASE_H */ diff --git a/lib/unicase/cased.c b/lib/unicase/cased.c new file mode 100644 index 0000000..05e5198 --- /dev/null +++ b/lib/unicase/cased.c @@ -0,0 +1,61 @@ +/* Test whether a Unicode character is cased. + Copyright (C) 2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "caseprop.h" + +/* Quoting the Unicode standard: + Definition: A character is defined to be "cased" if it has the Lowercase + or Uppercase property or has a General_Category value of + Titlecase_Letter. */ + +#if 0 + +#include "unictype.h" + +bool +uc_is_cased (ucs4_t uc) +{ + return (uc_is_property_lowercase (uc) + || uc_is_property_uppercase (uc) + || uc_is_general_category (uc, UC_TITLECASE_LETTER)); +} + +#else + +#include "unictype/bitmap.h" + +/* Define u_casing_property_cased table. */ +#include "cased.h" + +bool +uc_is_cased (ucs4_t uc) +{ + return bitmap_lookup (&u_casing_property_cased, uc); +} + +#endif diff --git a/lib/unicase/cased.h b/lib/unicase/cased.h new file mode 100644 index 0000000..cc222dc --- /dev/null +++ b/lib/unicase/cased.h @@ -0,0 +1,403 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Casing Properties of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#define header_0 16 +#define header_2 9 +#define header_3 127 +#define header_4 15 +static const +struct + { + int header[1]; + int level1[2]; + short level2[2 << 7]; + unsigned int level3[24 << 4]; + } +u_casing_property_cased = +{ + { 2 }, + { + 3 * sizeof (int) / sizeof (short) + 0, + 3 * sizeof (int) / sizeof (short) + 128 + }, + { + 3 + 256 * sizeof (short) / sizeof (int) + 0, + 3 + 256 * sizeof (short) / sizeof (int) + 16, + 3 + 256 * sizeof (short) / sizeof (int) + 32, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 48, + 3 + 256 * sizeof (short) / sizeof (int) + 64, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 80, + 3 + 256 * sizeof (short) / sizeof (int) + 96, + 3 + 256 * sizeof (short) / sizeof (int) + 112, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 128, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 144, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 160, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 176, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 192, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 208, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 224, + 3 + 256 * sizeof (short) / sizeof (int) + 240, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 256, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 272, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 288, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 304, + 3 + 256 * sizeof (short) / sizeof (int) + 320, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 336, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 352, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 368, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, + { + 0x00000000U, 0x00000000U, 0x07FFFFFEU, 0x07FFFFFEU, + 0x00000000U, 0x04200400U, 0xFF7FFFFFU, 0xFF7FFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xF7FFFFFFU, 0xFFFFFFF0U, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFEFFFFFU, 0x01FFFFFFU, 0x00000003U, 0x0000001FU, + 0x00000000U, 0x00000000U, 0x00000020U, 0xBCCF0000U, + 0xFFFFD740U, 0xFFFFFFFBU, 0xFFFFFFFFU, 0xFFBFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFC03U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFEFFFFU, 0x007FFFFFU, 0xFFFFFFFFU, + 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFFFFFFU, 0xFFFF20BFU, 0xE7FFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3F3FFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFF01FFU, 0xE7FFFFFFU, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0x3F3FFFFFU, 0xFFFFFFFFU, 0xAAFF3F3FU, 0x3FFFFFFFU, + 0xFFFFFFFFU, 0x5FDFFFFFU, 0x0FCF1FDCU, 0x1FDC1FFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x80020000U, + 0x1FFF0000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x3E2FFC84U, 0xF21FBD50U, 0x000043E0U, 0xFFFFFFFFU, + 0x00000018U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFC00000U, 0xFFFFFFFFU, 0x000003FFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000C781FU, + 0xFFFFFFFFU, 0x000020BFU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x00003FFFU, + 0x3FFFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFFFFFCU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFF78FFU, 0xFFFFFFFFU, 0x03EB07FFU, 0x07600000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFF0000U, 0xF7FFFFFFU, 0xFFFF01FFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00F8007FU, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x07FFFFFEU, 0x07FFFFFEU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, + 0x00000000U, 0xFFFF0000U, 0xFF0FFFFFU, 0x0FFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0xF7FF0000U, + 0xFFB7F7FFU, 0x1BFBFFFBU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFB9U, 0x07FDFFFFU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0x0007FFFFU, 0xFFFFFFFFU, 0x0007FFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFFFFFFU, + 0xDFFFFFFFU, 0xEBFFDE64U, 0xFFFFFFEFU, 0xFFFFFFFFU, + 0xDFDFE7BFU, 0x7BFFFFFFU, 0xFFFDFC5FU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFF3FU, 0xF7FFFFFDU, 0xF7FFFFFFU, + 0xFFDFFFFFU, 0xFFDFFFFFU, 0xFFFF7FFFU, 0xFFFF7FFFU, + 0xFFFFFDFFU, 0xFFFFFDFFU, 0x00000FF7U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x7FFFFBFFU, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFF0000U, 0xFFFF03FFU, 0xFFFF03FFU, + 0x000003FFU, 0x00000000U, 0x00000000U, 0x00000000U + } +}; diff --git a/lib/unicase/caseprop.h b/lib/unicase/caseprop.h new file mode 100644 index 0000000..3223ee4 --- /dev/null +++ b/lib/unicase/caseprop.h @@ -0,0 +1,42 @@ +/* Case related properties of Unicode characters. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include +#include "unitypes.h" + +/* Determine whether a character is "cased" according to the Unicode Standard, + , section 3.13, + definition D120. */ +extern bool + uc_is_cased (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Determine whether a character is "case-ignorable" + according to the Unicode Standard, + , section 3.13, + definition D121. */ +extern bool + uc_is_case_ignorable (ucs4_t uc) + _UC_ATTRIBUTE_CONST; diff --git a/lib/unicase/context.h b/lib/unicase/context.h new file mode 100644 index 0000000..8040a06 --- /dev/null +++ b/lib/unicase/context.h @@ -0,0 +1,73 @@ +/* Case-mapping contexts of UTF-8/UTF-16/UTF-32 substring. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + + +/* The context of a prefix string combines the information of the "Before C" + conditions of the Unicode Standard, + , section 3.13, + table 3-14 "Context Specification for Casing". + + casing_prefix_context_t contains the following fields: + + // Helper for evaluating the FINAL_SIGMA condition: + // Last character that was not case-ignorable. + ucs4_t last_char_except_ignorable; + + // Helper for evaluating the AFTER_SOFT_DOTTED and AFTER_I conditions: + // Last character that was of combining class 230 ("Above") or 0. + ucs4_t last_char_normal_or_above; + + Three bits would be sufficient to carry the context information, but + that would require to invoke uc_is_cased and uc_is_property_soft_dotted + ahead of time, more often than actually needed. */ + + +/* The context of a suffix string combines the information of the "After C" + conditions of the Unicode Standard, + , section 3.13, + table 3-14 "Context Specification for Casing". + + casing_suffix_context_t contains the following fields: + + // For evaluating the FINAL_SIGMA condition: + // First character that was not case-ignorable. + ucs4_t first_char_except_ignorable; + + // For evaluating the MORE_ABOVE condition: + // Bit 0 is set if the suffix contains a character of combining class + // 230 (Above) with no character of combining class 0 or 230 (Above) + // before it. + // + // For evaluating the BEFORE_DOT condition: + // Bit 1 is set if the suffix contains a COMBINING DOT ABOVE (U+0307) + // with no character of combining class 0 or 230 (Above) before it. + // + uint32_t bits; + + Three bits would be sufficient to carry the context information, but + that would require to invoke uc_is_cased ahead of time, more often than + actually needed. */ +#define SCC_MORE_ABOVE_MASK 1 +#define SCC_BEFORE_DOT_MASK 2 diff --git a/lib/unicase/empty-prefix-context.c b/lib/unicase/empty-prefix-context.c new file mode 100644 index 0000000..233f20c --- /dev/null +++ b/lib/unicase/empty-prefix-context.c @@ -0,0 +1,35 @@ +/* Case-mapping context of empty prefix string. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unicase.h" + +const casing_prefix_context_t unicase_empty_prefix_context = + { + 0xFFFD /* last_char_except_ignorable */, + 0xFFFD /* last_char_normal_or_above */ + }; diff --git a/lib/unicase/empty-suffix-context.c b/lib/unicase/empty-suffix-context.c new file mode 100644 index 0000000..39ce29e --- /dev/null +++ b/lib/unicase/empty-suffix-context.c @@ -0,0 +1,35 @@ +/* Case-mapping context of empty suffix string. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unicase.h" + +const casing_suffix_context_t unicase_empty_suffix_context = + { + 0xFFFD /* first_char_except_ignorable */, + 0 /* bits */ + }; diff --git a/lib/unicase/ignorable.c b/lib/unicase/ignorable.c new file mode 100644 index 0000000..1ebf801 --- /dev/null +++ b/lib/unicase/ignorable.c @@ -0,0 +1,79 @@ +/* Test whether a Unicode character is case-ignorable. + Copyright (C) 2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "caseprop.h" + +/* Quoting the Unicode standard: + Definition: A character is defined to be "case-ignorable" if it has the + value MidLetter {or the value MidNumLet} for the Word_Break property or + its General_Category is one of Nonspacing_Mark (Mn), Enclosing_Mark (Me), + Format (Cf), Modifier_Letter (Lm), or Modifier_Symbol (Sk). + The text marked in braces was added in Unicode 5.1.0, see + section "Update of + Definition of case-ignorable". */ +/* Since this predicate is only used for the "Before C" and "After C" + conditions of FINAL_SIGMA, we exclude the "cased" characters here. + This simplifies the evaluation of the regular expressions + \p{cased} (\p{case-ignorable})* C + and + C (\p{case-ignorable})* \p{cased} + */ + +#if 0 + +#include "unictype.h" +#include "uniwbrk.h" + +bool +uc_is_case_ignorable (ucs4_t uc) +{ + int wbp = uc_wordbreak_property (uc); + + return (wbp == WBP_MIDLETTER || wbp == WBP_MIDNUMLET + || uc_is_general_category_withtable (uc, UC_CATEGORY_MASK_Mn + | UC_CATEGORY_MASK_Me + | UC_CATEGORY_MASK_Cf + | UC_CATEGORY_MASK_Lm + | UC_CATEGORY_MASK_Sk)) + && !uc_is_cased (uc); +} + +#else + +#include "unictype/bitmap.h" + +/* Define u_casing_property_case_ignorable table. */ +#include "ignorable.h" + +bool +uc_is_case_ignorable (ucs4_t uc) +{ + return bitmap_lookup (&u_casing_property_case_ignorable, uc); +} + +#endif diff --git a/lib/unicase/ignorable.h b/lib/unicase/ignorable.h new file mode 100644 index 0000000..cc7db0e --- /dev/null +++ b/lib/unicase/ignorable.h @@ -0,0 +1,664 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Casing Properties of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#define header_0 16 +#define header_2 9 +#define header_3 127 +#define header_4 15 +static const +struct + { + int header[1]; + int level1[15]; + short level2[3 << 7]; + unsigned int level3[54 << 4]; + } +u_casing_property_case_ignorable = +{ + { 15 }, + { + 16 * sizeof (int) / sizeof (short) + 0, + 16 * sizeof (int) / sizeof (short) + 128, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 * sizeof (int) / sizeof (short) + 256 + }, + { + 16 + 384 * sizeof (short) / sizeof (int) + 0, + 16 + 384 * sizeof (short) / sizeof (int) + 16, + 16 + 384 * sizeof (short) / sizeof (int) + 32, + 16 + 384 * sizeof (short) / sizeof (int) + 48, + 16 + 384 * sizeof (short) / sizeof (int) + 64, + 16 + 384 * sizeof (short) / sizeof (int) + 80, + 16 + 384 * sizeof (short) / sizeof (int) + 96, + 16 + 384 * sizeof (short) / sizeof (int) + 112, + 16 + 384 * sizeof (short) / sizeof (int) + 128, + 16 + 384 * sizeof (short) / sizeof (int) + 144, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 160, + 16 + 384 * sizeof (short) / sizeof (int) + 176, + 16 + 384 * sizeof (short) / sizeof (int) + 192, + 16 + 384 * sizeof (short) / sizeof (int) + 208, + 16 + 384 * sizeof (short) / sizeof (int) + 224, + 16 + 384 * sizeof (short) / sizeof (int) + 240, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 256, + 16 + 384 * sizeof (short) / sizeof (int) + 272, + 16 + 384 * sizeof (short) / sizeof (int) + 288, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 304, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 320, + 16 + 384 * sizeof (short) / sizeof (int) + 336, + 16 + 384 * sizeof (short) / sizeof (int) + 352, + 16 + 384 * sizeof (short) / sizeof (int) + 368, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 384, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 400, + 16 + 384 * sizeof (short) / sizeof (int) + 416, + 16 + 384 * sizeof (short) / sizeof (int) + 432, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 448, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 464, + 16 + 384 * sizeof (short) / sizeof (int) + 480, + 16 + 384 * sizeof (short) / sizeof (int) + 496, + 16 + 384 * sizeof (short) / sizeof (int) + 512, + 16 + 384 * sizeof (short) / sizeof (int) + 528, + 16 + 384 * sizeof (short) / sizeof (int) + 544, + 16 + 384 * sizeof (short) / sizeof (int) + 560, + 16 + 384 * sizeof (short) / sizeof (int) + 576, + 16 + 384 * sizeof (short) / sizeof (int) + 592, + 16 + 384 * sizeof (short) / sizeof (int) + 608, + 16 + 384 * sizeof (short) / sizeof (int) + 624, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 640, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 656, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 672, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 688, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 704, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 720, + 16 + 384 * sizeof (short) / sizeof (int) + 736, + 16 + 384 * sizeof (short) / sizeof (int) + 752, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 768, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 784, + 16 + 384 * sizeof (short) / sizeof (int) + 800, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 816, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 832, + -1, + -1, + -1, + -1, + -1, + -1, + 16 + 384 * sizeof (short) / sizeof (int) + 848, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, + { + 0x00000000U, 0x04004000U, 0x40000000U, 0x00000001U, + 0x00000000U, 0x0190A100U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFE000000U, 0xFFFFFFFCU, 0xFFFFFFE0U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFDFU, 0x0030FFFFU, + 0x000000B0U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x000003F8U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x82000000U, 0x00000000U, + 0xFFFE0000U, 0xBFFFFFFFU, 0x000000B6U, 0x00100000U, + 0x17FF003FU, 0x00000000U, 0xFFFFF801U, 0x00010000U, + 0x00000000U, 0x00000000U, 0xBFC00000U, 0x00003DFFU, + 0x00028000U, 0xFFFF0000U, 0x000007FFU, 0x00000000U, + 0x00000000U, 0x0001FFC0U, 0x00000000U, 0x243FF800U, + 0xFFC00000U, 0x00003FFFU, 0x0E000000U, 0x00000000U, + 0xFF030100U, 0x00000000U, 0xFFFFFE00U, 0xFFFFFFFFU, + 0x00000007U, 0x14000000U, 0x00FE21FEU, 0x0002000CU, + 0x00000002U, 0x10000000U, 0x0000201EU, 0x4000000CU, + 0x00000006U, 0x10000000U, 0x00023986U, 0x00230000U, + 0x00000006U, 0x10000000U, 0x000021BEU, 0xFC00000CU, + 0x00000002U, 0x90000000U, 0x0060201EU, 0x0000000CU, + 0x00000004U, 0x00000000U, 0x00002001U, 0x00000000U, + 0x00000011U, 0xD0000000U, 0x00603DC1U, 0x0000000CU, + 0x00000002U, 0x90000000U, 0x00003040U, 0x0000000CU, + 0x00000003U, 0x18000000U, 0x0000201EU, 0x0000000CU, + 0x00000002U, 0x00000000U, 0x005C0400U, 0x00000000U, + 0x00000000U, 0x07F20000U, 0x00007FC0U, 0x00000000U, + 0x00000000U, 0x1FF20000U, 0x00003F40U, 0x00000000U, + 0x03000000U, 0x02A00000U, 0x00000000U, 0x7FFE0000U, + 0xFEFFE0DFU, 0x1FFFFFFFU, 0x00000040U, 0x00000000U, + 0x00000000U, 0x66FDE000U, 0xC3000000U, 0x001E0001U, + 0x20002064U, 0x00000000U, 0x00000000U, 0x10000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0xE0000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x001C0000U, 0x000C0000U, 0x000C0000U, 0x000C0000U, + 0x00000000U, 0x3FB00000U, 0x208FFE40U, 0x00000000U, + 0x0000F800U, 0x00000000U, 0x00000008U, 0x00000000U, + 0x00000060U, 0x00000200U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x0E040187U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x09800000U, 0x00000000U, 0x7F400000U, 0x9FF81FE5U, + 0x00000000U, 0xFFFF0080U, 0x00007FFFU, 0x00000000U, + 0x0000000FU, 0x17D00000U, 0x00000004U, 0x000FF800U, + 0x00000003U, 0x00003B3CU, 0x00000000U, 0x0003A340U, + 0x00000000U, 0x00CFF000U, 0x00000000U, 0x3F000000U, + 0x00000000U, 0x00000000U, 0xFFF70000U, 0x031021FDU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xA0000000U, 0xE000E003U, 0x6000E000U, + 0x0300F800U, 0x00007C90U, 0x00000000U, 0x0000FFDFU, + 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x0001FFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00038000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x80008000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFFFFFFU, + 0x00000000U, 0x00008000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000020U, 0x083E3C00U, 0x00000000U, 0x00000000U, + 0x7E000000U, 0x00000000U, 0x00000000U, 0x70000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00200000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x3F000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00001000U, 0x00000000U, 0x00000000U, 0xBFF78000U, + 0xC0000000U, 0x00000000U, 0x00000000U, 0x00030000U, + 0xFFFFFFFFU, 0x00000003U, 0x00000000U, 0x00000000U, + 0x00000700U, 0x00000000U, 0x00000000U, 0x001C0000U, + 0x00000844U, 0x00001060U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000030U, 0x8003FFFFU, + 0x00000000U, 0x00003FC0U, 0x0003FF80U, 0x00000000U, + 0x00000007U, 0x33C80000U, 0x00008000U, 0x00000060U, + 0x00000000U, 0x00667E00U, 0x00001008U, 0x10010000U, + 0x00000000U, 0xC19D0000U, 0x20000002U, 0x00583000U, + 0x00000000U, 0x00000000U, 0x08000000U, 0x00000E00U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00002120U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x40000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFFFC0000U, 0x00000007U, 0x00000000U, + 0x0008FFFFU, 0x0000FFFFU, 0x00240000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x80000000U, + 0x04004080U, 0x40000000U, 0x00000001U, 0x00010000U, + 0xC0000000U, 0x00000000U, 0x00000000U, 0x0E000008U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x20000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000001U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x07C00000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000006U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x0000F06EU, 0x87000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000060U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x000000F0U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00001800U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x0001FFC0U, 0x00000000U, + 0x0000003CU, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000002U, 0xFF000000U, 0x0000007FU, 0x80190000U, + 0x00000003U, 0x26780000U, 0x00002004U, 0x00000000U, + 0x00000007U, 0x001FEF80U, 0x00000000U, 0x00080000U, + 0x00000003U, 0x7FC00000U, 0x00009E00U, 0x00000000U, + 0x00000000U, 0x40D38000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x80000000U, 0x000007F8U, + 0x00000003U, 0x18000000U, 0x00000001U, 0x001F1FC0U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xFF000000U, 0x4000005CU, 0x00000000U, + 0x00000000U, 0x85F80000U, 0x0000000DU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xB03C0000U, 0x30000001U, 0x00000000U, + 0x00000000U, 0xA7F80000U, 0x00000001U, 0x00000000U, + 0x00000000U, 0x00BF2800U, 0x00000000U, 0x00000000U, + 0xE0000000U, 0x00000FBCU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x06FF8000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x58000000U, 0x00000008U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x0CF00000U, 0x00000001U, + 0x000007FEU, 0x79F80000U, 0x0E7E0080U, 0x00000000U, + 0x037FFC00U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0xBF7F0000U, 0x00000000U, 0x00000000U, + 0xFFFC0000U, 0x006DFCFFU, 0x00000000U, 0x00000000U, + 0x00000000U, 0xB47E0000U, 0x000000BFU, 0x00000000U, + 0x00A30000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00180000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x01FF0000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x001F0000U, + 0x00000000U, 0x007F0000U, 0x0000000FU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00008000U, 0x00000000U, + 0xFFFF8000U, 0x00000000U, 0x00000000U, 0x0000001BU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x60000000U, 0x0000000FU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFF3FFFU, 0x0000007FU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0xFFF80380U, + 0x00000FE7U, 0x00003C00U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x0000001CU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xF87FFFFFU, 0xFFFFFFFFU, 0x00201FFFU, + 0xF8000010U, 0x0000FFFEU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xF9FFFF7FU, 0x000007DBU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x3FFF0000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00004000U, 0x00000000U, 0x0000F000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x007F0000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000FF0U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0xF8000000U, + 0x00000002U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU + } +}; diff --git a/lib/unicase/simple-mapping.h b/lib/unicase/simple-mapping.h new file mode 100644 index 0000000..d3a8013 --- /dev/null +++ b/lib/unicase/simple-mapping.h @@ -0,0 +1,47 @@ +/* Simple case mapping for Unicode characters. + Copyright (C) 2002, 2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +ucs4_t +FUNC (ucs4_t uc) +{ + unsigned int index1 = uc >> mapping_header_0; + if (index1 < mapping_header_1) + { + int lookup1 = u_mapping.level1[index1]; + if (lookup1 >= 0) + { + unsigned int index2 = (uc >> mapping_header_2) & mapping_header_3; + int lookup2 = u_mapping.level2[lookup1 + index2]; + if (lookup2 >= 0) + { + unsigned int index3 = (uc & mapping_header_4); + int lookup3 = u_mapping.level3[lookup2 + index3]; + + return uc + lookup3; + } + } + } + return uc; +} diff --git a/lib/unicase/special-casing-table.gperf b/lib/unicase/special-casing-table.gperf new file mode 100644 index 0000000..4539fc6 --- /dev/null +++ b/lib/unicase/special-casing-table.gperf @@ -0,0 +1,160 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Special casing rules of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +struct special_casing_rule { char code[3]; }; +%struct-type +%language=ANSI-C +%define slot-name code +%define hash-function-name gl_unicase_special_hash +%define lookup-function-name gl_unicase_special_lookup +%compare-lengths +%compare-strncmp +%readonly-tables +%omit-struct-type +%% +"\x00\x49\x00", 1, SCC_MORE_ABOVE , { 'l', 't' }, { 0x0049, 0, 0 }, { 0x0069, 0x0307, 0 }, { 0x0049, 0, 0 }, { 0x0069, 0, 0 } +"\x00\x49\x01", 1, -SCC_BEFORE_DOT , { 't', 'r' }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 } +"\x00\x49\x02", 1, -SCC_BEFORE_DOT , { 'a', 'z' }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 } +"\x00\x49\x03", 1, SCC_ALWAYS , { 't', 'r' }, { 0x0049, 0, 0 }, { 0x0069, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 } +"\x00\x49\x04", 0, SCC_ALWAYS , { 'a', 'z' }, { 0x0049, 0, 0 }, { 0x0069, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 } +"\x00\x4a\x00", 0, SCC_MORE_ABOVE , { 'l', 't' }, { 0x004A, 0, 0 }, { 0x006A, 0x0307, 0 }, { 0x004A, 0, 0 }, { 0x006A, 0, 0 } +"\x00\x69\x00", 1, SCC_ALWAYS , { 't', 'r' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 } +"\x00\x69\x01", 0, SCC_ALWAYS , { 'a', 'z' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 } +"\x00\xcc\x00", 0, SCC_ALWAYS , { 'l', 't' }, { 0x00CC, 0, 0 }, { 0x0069, 0x0307, 0x0300 }, { 0x00CC, 0, 0 }, { 0x00EC, 0, 0 } +"\x00\xcd\x00", 0, SCC_ALWAYS , { 'l', 't' }, { 0x00CD, 0, 0 }, { 0x0069, 0x0307, 0x0301 }, { 0x00CD, 0, 0 }, { 0x00ED, 0, 0 } +"\x00\xdf\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0053, 0x0053, 0 }, { 0x00DF, 0, 0 }, { 0x0053, 0x0073, 0 }, { 0x0073, 0x0073, 0 } +"\x01\x28\x00", 0, SCC_ALWAYS , { 'l', 't' }, { 0x0128, 0, 0 }, { 0x0069, 0x0307, 0x0303 }, { 0x0128, 0, 0 }, { 0x0129, 0, 0 } +"\x01\x2e\x00", 0, SCC_MORE_ABOVE , { 'l', 't' }, { 0x012E, 0, 0 }, { 0x012F, 0x0307, 0 }, { 0x012E, 0, 0 }, { 0x012F, 0, 0 } +"\x01\x30\x00", 1, SCC_ALWAYS , { 't', 'r' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 } +"\x01\x30\x01", 1, SCC_ALWAYS , { 'a', 'z' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 } +"\x01\x30\x02", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0130, 0, 0 }, { 0x0069, 0x0307, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0x0307, 0 } +"\x01\x49\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x02BC, 0x004E, 0 }, { 0x0149, 0, 0 }, { 0x02BC, 0x004E, 0 }, { 0x02BC, 0x006E, 0 } +"\x01\xf0\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x004A, 0x030C, 0 }, { 0x01F0, 0, 0 }, { 0x004A, 0x030C, 0 }, { 0x006A, 0x030C, 0 } +"\x03\x07\x00", 1, SCC_AFTER_SOFT_DOTTED, { 'l', 't' }, { 0, 0, 0 }, { 0x0307, 0, 0 }, { 0, 0, 0 }, { 0x0307, 0, 0 } +"\x03\x07\x01", 1, SCC_AFTER_I , { 't', 'r' }, { 0x0307, 0, 0 }, { 0, 0, 0 }, { 0x0307, 0, 0 }, { 0x0307, 0, 0 } +"\x03\x07\x02", 0, SCC_AFTER_I , { 'a', 'z' }, { 0x0307, 0, 0 }, { 0, 0, 0 }, { 0x0307, 0, 0 }, { 0x0307, 0, 0 } +"\x03\x90\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0301 }, { 0x0390, 0, 0 }, { 0x0399, 0x0308, 0x0301 }, { 0x03B9, 0x0308, 0x0301 } +"\x03\xa3\x00", 0, SCC_FINAL_SIGMA , { '\0', '\0' }, { 0x03A3, 0, 0 }, { 0x03C2, 0, 0 }, { 0x03A3, 0, 0 }, { 0x03C3, 0, 0 } +"\x03\xb0\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0301 }, { 0x03B0, 0, 0 }, { 0x03A5, 0x0308, 0x0301 }, { 0x03C5, 0x0308, 0x0301 } +"\x05\x87\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0535, 0x0552, 0 }, { 0x0587, 0, 0 }, { 0x0535, 0x0582, 0 }, { 0x0565, 0x0582, 0 } +"\x1e\x96\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0048, 0x0331, 0 }, { 0x1E96, 0, 0 }, { 0x0048, 0x0331, 0 }, { 0x0068, 0x0331, 0 } +"\x1e\x97\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0054, 0x0308, 0 }, { 0x1E97, 0, 0 }, { 0x0054, 0x0308, 0 }, { 0x0074, 0x0308, 0 } +"\x1e\x98\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0057, 0x030A, 0 }, { 0x1E98, 0, 0 }, { 0x0057, 0x030A, 0 }, { 0x0077, 0x030A, 0 } +"\x1e\x99\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0059, 0x030A, 0 }, { 0x1E99, 0, 0 }, { 0x0059, 0x030A, 0 }, { 0x0079, 0x030A, 0 } +"\x1e\x9a\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0041, 0x02BE, 0 }, { 0x1E9A, 0, 0 }, { 0x0041, 0x02BE, 0 }, { 0x0061, 0x02BE, 0 } +"\x1e\x9e\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1E9E, 0, 0 }, { 0x00DF, 0, 0 }, { 0x1E9E, 0, 0 }, { 0x0073, 0x0073, 0 } +"\x1f\x50\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0 }, { 0x1F50, 0, 0 }, { 0x03A5, 0x0313, 0 }, { 0x03C5, 0x0313, 0 } +"\x1f\x52\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0x0300 }, { 0x1F52, 0, 0 }, { 0x03A5, 0x0313, 0x0300 }, { 0x03C5, 0x0313, 0x0300 } +"\x1f\x54\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0x0301 }, { 0x1F54, 0, 0 }, { 0x03A5, 0x0313, 0x0301 }, { 0x03C5, 0x0313, 0x0301 } +"\x1f\x56\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0x0342 }, { 0x1F56, 0, 0 }, { 0x03A5, 0x0313, 0x0342 }, { 0x03C5, 0x0313, 0x0342 } +"\x1f\x80\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F08, 0x0399, 0 }, { 0x1F80, 0, 0 }, { 0x1F88, 0, 0 }, { 0x1F00, 0x03B9, 0 } +"\x1f\x81\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F09, 0x0399, 0 }, { 0x1F81, 0, 0 }, { 0x1F89, 0, 0 }, { 0x1F01, 0x03B9, 0 } +"\x1f\x82\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0A, 0x0399, 0 }, { 0x1F82, 0, 0 }, { 0x1F8A, 0, 0 }, { 0x1F02, 0x03B9, 0 } +"\x1f\x83\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0B, 0x0399, 0 }, { 0x1F83, 0, 0 }, { 0x1F8B, 0, 0 }, { 0x1F03, 0x03B9, 0 } +"\x1f\x84\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0C, 0x0399, 0 }, { 0x1F84, 0, 0 }, { 0x1F8C, 0, 0 }, { 0x1F04, 0x03B9, 0 } +"\x1f\x85\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0D, 0x0399, 0 }, { 0x1F85, 0, 0 }, { 0x1F8D, 0, 0 }, { 0x1F05, 0x03B9, 0 } +"\x1f\x86\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0E, 0x0399, 0 }, { 0x1F86, 0, 0 }, { 0x1F8E, 0, 0 }, { 0x1F06, 0x03B9, 0 } +"\x1f\x87\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0F, 0x0399, 0 }, { 0x1F87, 0, 0 }, { 0x1F8F, 0, 0 }, { 0x1F07, 0x03B9, 0 } +"\x1f\x88\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F08, 0x0399, 0 }, { 0x1F80, 0, 0 }, { 0x1F88, 0, 0 }, { 0x1F00, 0x03B9, 0 } +"\x1f\x89\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F09, 0x0399, 0 }, { 0x1F81, 0, 0 }, { 0x1F89, 0, 0 }, { 0x1F01, 0x03B9, 0 } +"\x1f\x8a\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0A, 0x0399, 0 }, { 0x1F82, 0, 0 }, { 0x1F8A, 0, 0 }, { 0x1F02, 0x03B9, 0 } +"\x1f\x8b\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0B, 0x0399, 0 }, { 0x1F83, 0, 0 }, { 0x1F8B, 0, 0 }, { 0x1F03, 0x03B9, 0 } +"\x1f\x8c\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0C, 0x0399, 0 }, { 0x1F84, 0, 0 }, { 0x1F8C, 0, 0 }, { 0x1F04, 0x03B9, 0 } +"\x1f\x8d\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0D, 0x0399, 0 }, { 0x1F85, 0, 0 }, { 0x1F8D, 0, 0 }, { 0x1F05, 0x03B9, 0 } +"\x1f\x8e\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0E, 0x0399, 0 }, { 0x1F86, 0, 0 }, { 0x1F8E, 0, 0 }, { 0x1F06, 0x03B9, 0 } +"\x1f\x8f\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0F, 0x0399, 0 }, { 0x1F87, 0, 0 }, { 0x1F8F, 0, 0 }, { 0x1F07, 0x03B9, 0 } +"\x1f\x90\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F28, 0x0399, 0 }, { 0x1F90, 0, 0 }, { 0x1F98, 0, 0 }, { 0x1F20, 0x03B9, 0 } +"\x1f\x91\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F29, 0x0399, 0 }, { 0x1F91, 0, 0 }, { 0x1F99, 0, 0 }, { 0x1F21, 0x03B9, 0 } +"\x1f\x92\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2A, 0x0399, 0 }, { 0x1F92, 0, 0 }, { 0x1F9A, 0, 0 }, { 0x1F22, 0x03B9, 0 } +"\x1f\x93\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2B, 0x0399, 0 }, { 0x1F93, 0, 0 }, { 0x1F9B, 0, 0 }, { 0x1F23, 0x03B9, 0 } +"\x1f\x94\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2C, 0x0399, 0 }, { 0x1F94, 0, 0 }, { 0x1F9C, 0, 0 }, { 0x1F24, 0x03B9, 0 } +"\x1f\x95\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2D, 0x0399, 0 }, { 0x1F95, 0, 0 }, { 0x1F9D, 0, 0 }, { 0x1F25, 0x03B9, 0 } +"\x1f\x96\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2E, 0x0399, 0 }, { 0x1F96, 0, 0 }, { 0x1F9E, 0, 0 }, { 0x1F26, 0x03B9, 0 } +"\x1f\x97\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2F, 0x0399, 0 }, { 0x1F97, 0, 0 }, { 0x1F9F, 0, 0 }, { 0x1F27, 0x03B9, 0 } +"\x1f\x98\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F28, 0x0399, 0 }, { 0x1F90, 0, 0 }, { 0x1F98, 0, 0 }, { 0x1F20, 0x03B9, 0 } +"\x1f\x99\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F29, 0x0399, 0 }, { 0x1F91, 0, 0 }, { 0x1F99, 0, 0 }, { 0x1F21, 0x03B9, 0 } +"\x1f\x9a\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2A, 0x0399, 0 }, { 0x1F92, 0, 0 }, { 0x1F9A, 0, 0 }, { 0x1F22, 0x03B9, 0 } +"\x1f\x9b\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2B, 0x0399, 0 }, { 0x1F93, 0, 0 }, { 0x1F9B, 0, 0 }, { 0x1F23, 0x03B9, 0 } +"\x1f\x9c\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2C, 0x0399, 0 }, { 0x1F94, 0, 0 }, { 0x1F9C, 0, 0 }, { 0x1F24, 0x03B9, 0 } +"\x1f\x9d\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2D, 0x0399, 0 }, { 0x1F95, 0, 0 }, { 0x1F9D, 0, 0 }, { 0x1F25, 0x03B9, 0 } +"\x1f\x9e\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2E, 0x0399, 0 }, { 0x1F96, 0, 0 }, { 0x1F9E, 0, 0 }, { 0x1F26, 0x03B9, 0 } +"\x1f\x9f\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2F, 0x0399, 0 }, { 0x1F97, 0, 0 }, { 0x1F9F, 0, 0 }, { 0x1F27, 0x03B9, 0 } +"\x1f\xa0\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F68, 0x0399, 0 }, { 0x1FA0, 0, 0 }, { 0x1FA8, 0, 0 }, { 0x1F60, 0x03B9, 0 } +"\x1f\xa1\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F69, 0x0399, 0 }, { 0x1FA1, 0, 0 }, { 0x1FA9, 0, 0 }, { 0x1F61, 0x03B9, 0 } +"\x1f\xa2\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6A, 0x0399, 0 }, { 0x1FA2, 0, 0 }, { 0x1FAA, 0, 0 }, { 0x1F62, 0x03B9, 0 } +"\x1f\xa3\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6B, 0x0399, 0 }, { 0x1FA3, 0, 0 }, { 0x1FAB, 0, 0 }, { 0x1F63, 0x03B9, 0 } +"\x1f\xa4\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6C, 0x0399, 0 }, { 0x1FA4, 0, 0 }, { 0x1FAC, 0, 0 }, { 0x1F64, 0x03B9, 0 } +"\x1f\xa5\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6D, 0x0399, 0 }, { 0x1FA5, 0, 0 }, { 0x1FAD, 0, 0 }, { 0x1F65, 0x03B9, 0 } +"\x1f\xa6\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6E, 0x0399, 0 }, { 0x1FA6, 0, 0 }, { 0x1FAE, 0, 0 }, { 0x1F66, 0x03B9, 0 } +"\x1f\xa7\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6F, 0x0399, 0 }, { 0x1FA7, 0, 0 }, { 0x1FAF, 0, 0 }, { 0x1F67, 0x03B9, 0 } +"\x1f\xa8\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F68, 0x0399, 0 }, { 0x1FA0, 0, 0 }, { 0x1FA8, 0, 0 }, { 0x1F60, 0x03B9, 0 } +"\x1f\xa9\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F69, 0x0399, 0 }, { 0x1FA1, 0, 0 }, { 0x1FA9, 0, 0 }, { 0x1F61, 0x03B9, 0 } +"\x1f\xaa\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6A, 0x0399, 0 }, { 0x1FA2, 0, 0 }, { 0x1FAA, 0, 0 }, { 0x1F62, 0x03B9, 0 } +"\x1f\xab\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6B, 0x0399, 0 }, { 0x1FA3, 0, 0 }, { 0x1FAB, 0, 0 }, { 0x1F63, 0x03B9, 0 } +"\x1f\xac\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6C, 0x0399, 0 }, { 0x1FA4, 0, 0 }, { 0x1FAC, 0, 0 }, { 0x1F64, 0x03B9, 0 } +"\x1f\xad\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6D, 0x0399, 0 }, { 0x1FA5, 0, 0 }, { 0x1FAD, 0, 0 }, { 0x1F65, 0x03B9, 0 } +"\x1f\xae\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6E, 0x0399, 0 }, { 0x1FA6, 0, 0 }, { 0x1FAE, 0, 0 }, { 0x1F66, 0x03B9, 0 } +"\x1f\xaf\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6F, 0x0399, 0 }, { 0x1FA7, 0, 0 }, { 0x1FAF, 0, 0 }, { 0x1F67, 0x03B9, 0 } +"\x1f\xb2\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1FBA, 0x0399, 0 }, { 0x1FB2, 0, 0 }, { 0x1FBA, 0x0345, 0 }, { 0x1F70, 0x03B9, 0 } +"\x1f\xb3\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0399, 0 }, { 0x1FB3, 0, 0 }, { 0x1FBC, 0, 0 }, { 0x03B1, 0x03B9, 0 } +"\x1f\xb4\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0386, 0x0399, 0 }, { 0x1FB4, 0, 0 }, { 0x0386, 0x0345, 0 }, { 0x03AC, 0x03B9, 0 } +"\x1f\xb6\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0342, 0 }, { 0x1FB6, 0, 0 }, { 0x0391, 0x0342, 0 }, { 0x03B1, 0x0342, 0 } +"\x1f\xb7\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0342, 0x0399 }, { 0x1FB7, 0, 0 }, { 0x0391, 0x0342, 0x0345 }, { 0x03B1, 0x0342, 0x03B9 } +"\x1f\xbc\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0399, 0 }, { 0x1FB3, 0, 0 }, { 0x1FBC, 0, 0 }, { 0x03B1, 0x03B9, 0 } +"\x1f\xc2\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1FCA, 0x0399, 0 }, { 0x1FC2, 0, 0 }, { 0x1FCA, 0x0345, 0 }, { 0x1F74, 0x03B9, 0 } +"\x1f\xc3\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0399, 0 }, { 0x1FC3, 0, 0 }, { 0x1FCC, 0, 0 }, { 0x03B7, 0x03B9, 0 } +"\x1f\xc4\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0389, 0x0399, 0 }, { 0x1FC4, 0, 0 }, { 0x0389, 0x0345, 0 }, { 0x03AE, 0x03B9, 0 } +"\x1f\xc6\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0342, 0 }, { 0x1FC6, 0, 0 }, { 0x0397, 0x0342, 0 }, { 0x03B7, 0x0342, 0 } +"\x1f\xc7\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0342, 0x0399 }, { 0x1FC7, 0, 0 }, { 0x0397, 0x0342, 0x0345 }, { 0x03B7, 0x0342, 0x03B9 } +"\x1f\xcc\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0399, 0 }, { 0x1FC3, 0, 0 }, { 0x1FCC, 0, 0 }, { 0x03B7, 0x03B9, 0 } +"\x1f\xd2\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0300 }, { 0x1FD2, 0, 0 }, { 0x0399, 0x0308, 0x0300 }, { 0x03B9, 0x0308, 0x0300 } +"\x1f\xd3\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0301 }, { 0x1FD3, 0, 0 }, { 0x0399, 0x0308, 0x0301 }, { 0x03B9, 0x0308, 0x0301 } +"\x1f\xd6\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0342, 0 }, { 0x1FD6, 0, 0 }, { 0x0399, 0x0342, 0 }, { 0x03B9, 0x0342, 0 } +"\x1f\xd7\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0342 }, { 0x1FD7, 0, 0 }, { 0x0399, 0x0308, 0x0342 }, { 0x03B9, 0x0308, 0x0342 } +"\x1f\xe2\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0300 }, { 0x1FE2, 0, 0 }, { 0x03A5, 0x0308, 0x0300 }, { 0x03C5, 0x0308, 0x0300 } +"\x1f\xe3\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0301 }, { 0x1FE3, 0, 0 }, { 0x03A5, 0x0308, 0x0301 }, { 0x03C5, 0x0308, 0x0301 } +"\x1f\xe4\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A1, 0x0313, 0 }, { 0x1FE4, 0, 0 }, { 0x03A1, 0x0313, 0 }, { 0x03C1, 0x0313, 0 } +"\x1f\xe6\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0342, 0 }, { 0x1FE6, 0, 0 }, { 0x03A5, 0x0342, 0 }, { 0x03C5, 0x0342, 0 } +"\x1f\xe7\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0342 }, { 0x1FE7, 0, 0 }, { 0x03A5, 0x0308, 0x0342 }, { 0x03C5, 0x0308, 0x0342 } +"\x1f\xf2\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1FFA, 0x0399, 0 }, { 0x1FF2, 0, 0 }, { 0x1FFA, 0x0345, 0 }, { 0x1F7C, 0x03B9, 0 } +"\x1f\xf3\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0399, 0 }, { 0x1FF3, 0, 0 }, { 0x1FFC, 0, 0 }, { 0x03C9, 0x03B9, 0 } +"\x1f\xf4\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x038F, 0x0399, 0 }, { 0x1FF4, 0, 0 }, { 0x038F, 0x0345, 0 }, { 0x03CE, 0x03B9, 0 } +"\x1f\xf6\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0342, 0 }, { 0x1FF6, 0, 0 }, { 0x03A9, 0x0342, 0 }, { 0x03C9, 0x0342, 0 } +"\x1f\xf7\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0342, 0x0399 }, { 0x1FF7, 0, 0 }, { 0x03A9, 0x0342, 0x0345 }, { 0x03C9, 0x0342, 0x03B9 } +"\x1f\xfc\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0399, 0 }, { 0x1FF3, 0, 0 }, { 0x1FFC, 0, 0 }, { 0x03C9, 0x03B9, 0 } +"\xfb\x00\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0046, 0 }, { 0xFB00, 0, 0 }, { 0x0046, 0x0066, 0 }, { 0x0066, 0x0066, 0 } +"\xfb\x01\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0049, 0 }, { 0xFB01, 0, 0 }, { 0x0046, 0x0069, 0 }, { 0x0066, 0x0069, 0 } +"\xfb\x02\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x004C, 0 }, { 0xFB02, 0, 0 }, { 0x0046, 0x006C, 0 }, { 0x0066, 0x006C, 0 } +"\xfb\x03\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0046, 0x0049 }, { 0xFB03, 0, 0 }, { 0x0046, 0x0066, 0x0069 }, { 0x0066, 0x0066, 0x0069 } +"\xfb\x04\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0046, 0x004C }, { 0xFB04, 0, 0 }, { 0x0046, 0x0066, 0x006C }, { 0x0066, 0x0066, 0x006C } +"\xfb\x05\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0053, 0x0054, 0 }, { 0xFB05, 0, 0 }, { 0x0053, 0x0074, 0 }, { 0x0073, 0x0074, 0 } +"\xfb\x06\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0053, 0x0054, 0 }, { 0xFB06, 0, 0 }, { 0x0053, 0x0074, 0 }, { 0x0073, 0x0074, 0 } +"\xfb\x13\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x0546, 0 }, { 0xFB13, 0, 0 }, { 0x0544, 0x0576, 0 }, { 0x0574, 0x0576, 0 } +"\xfb\x14\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x0535, 0 }, { 0xFB14, 0, 0 }, { 0x0544, 0x0565, 0 }, { 0x0574, 0x0565, 0 } +"\xfb\x15\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x053B, 0 }, { 0xFB15, 0, 0 }, { 0x0544, 0x056B, 0 }, { 0x0574, 0x056B, 0 } +"\xfb\x16\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x054E, 0x0546, 0 }, { 0xFB16, 0, 0 }, { 0x054E, 0x0576, 0 }, { 0x057E, 0x0576, 0 } +"\xfb\x17\x00", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x053D, 0 }, { 0xFB17, 0, 0 }, { 0x0544, 0x056D, 0 }, { 0x0574, 0x056D, 0 } diff --git a/lib/unicase/special-casing-table.h b/lib/unicase/special-casing-table.h new file mode 100644 index 0000000..aeb7425 --- /dev/null +++ b/lib/unicase/special-casing-table.h @@ -0,0 +1,333 @@ +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf -m 10 ./unicase/special-casing-table.gperf */ +/* Computed positions: -k'1-3' */ + + +#define TOTAL_KEYWORDS 122 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 3 +#define MIN_HASH_VALUE 0 +#define MAX_HASH_VALUE 121 +/* maximum key range = 122, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +/*ARGSUSED*/ +static unsigned int +gl_unicase_special_hash (register const char *str, register size_t len) +{ + static const unsigned char asso_values[] = + { + 2, 0, 4, 5, 37, 12, 121, 4, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 120, + 119, 118, 117, 116, 122, 122, 122, 122, 122, 122, + 5, 3, 122, 122, 122, 122, 122, 122, 122, 122, + 115, 122, 122, 122, 122, 122, 114, 122, 6, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 1, 111, 122, 122, 122, 122, 122, + 109, 122, 108, 122, 107, 122, 106, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 33, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 105, 104, + 103, 102, 101, 100, 99, 31, 98, 97, 96, 95, + 94, 93, 92, 91, 28, 90, 89, 88, 87, 86, + 27, 24, 23, 20, 19, 85, 84, 83, 16, 82, + 81, 80, 79, 15, 78, 77, 76, 75, 74, 73, + 72, 71, 70, 69, 68, 67, 64, 122, 65, 64, + 63, 122, 62, 61, 122, 122, 122, 122, 60, 122, + 122, 122, 122, 122, 59, 58, 57, 122, 56, 55, + 122, 122, 122, 122, 14, 55, 122, 122, 122, 122, + 53, 52, 122, 122, 51, 50, 122, 122, 122, 122, + 122, 122, 122, 50, 122, 122, 48, 47, 46, 122, + 45, 44, 122, 122, 122, 122, 122, 122, 122, 122, + 46, 122, 42, 41, 39, 122, 38, 35, 122, 122, + 122, 0, 33, 122, 122, 122, 122 + }; + return asso_values[(unsigned char)str[2]+1] + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]]; +} + +const struct special_casing_rule * +gl_unicase_special_lookup (register const char *str, register size_t len) +{ + static const unsigned char lengthtable[] = + { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 + }; + static const struct special_casing_rule wordlist[] = + { +#line 150 "./unicase/special-casing-table.gperf" + {"\373\001\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0049, 0 }, { 0xFB01, 0, 0 }, { 0x0046, 0x0069, 0 }, { 0x0066, 0x0069, 0 }}, +#line 55 "./unicase/special-casing-table.gperf" + {"\001I\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x02BC, 0x004E, 0 }, { 0x0149, 0, 0 }, { 0x02BC, 0x004E, 0 }, { 0x02BC, 0x006E, 0 }}, +#line 149 "./unicase/special-casing-table.gperf" + {"\373\000\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0046, 0 }, { 0xFB00, 0, 0 }, { 0x0046, 0x0066, 0 }, { 0x0066, 0x0066, 0 }}, +#line 39 "./unicase/special-casing-table.gperf" + {"\000I\000", 1, SCC_MORE_ABOVE , { 'l', 't' }, { 0x0049, 0, 0 }, { 0x0069, 0x0307, 0 }, { 0x0049, 0, 0 }, { 0x0069, 0, 0 }}, +#line 151 "./unicase/special-casing-table.gperf" + {"\373\002\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x004C, 0 }, { 0xFB02, 0, 0 }, { 0x0046, 0x006C, 0 }, { 0x0066, 0x006C, 0 }}, +#line 152 "./unicase/special-casing-table.gperf" + {"\373\003\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0046, 0x0049 }, { 0xFB03, 0, 0 }, { 0x0046, 0x0066, 0x0069 }, { 0x0066, 0x0066, 0x0069 }}, +#line 52 "./unicase/special-casing-table.gperf" + {"\0010\000", 1, SCC_ALWAYS , { 't', 'r' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }}, +#line 40 "./unicase/special-casing-table.gperf" + {"\000I\001", 1, -SCC_BEFORE_DOT , { 't', 'r' }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }}, +#line 41 "./unicase/special-casing-table.gperf" + {"\000I\002", 1, -SCC_BEFORE_DOT , { 'a', 'z' }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }}, +#line 57 "./unicase/special-casing-table.gperf" + {"\003\007\000", 1, SCC_AFTER_SOFT_DOTTED, { 'l', 't' }, { 0, 0, 0 }, { 0x0307, 0, 0 }, { 0, 0, 0 }, { 0x0307, 0, 0 }}, +#line 53 "./unicase/special-casing-table.gperf" + {"\0010\001", 1, SCC_ALWAYS , { 'a', 'z' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }}, +#line 54 "./unicase/special-casing-table.gperf" + {"\0010\002", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0130, 0, 0 }, { 0x0069, 0x0307, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0x0307, 0 }}, +#line 154 "./unicase/special-casing-table.gperf" + {"\373\005\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0053, 0x0054, 0 }, { 0xFB05, 0, 0 }, { 0x0053, 0x0074, 0 }, { 0x0073, 0x0074, 0 }}, +#line 58 "./unicase/special-casing-table.gperf" + {"\003\007\001", 1, SCC_AFTER_I , { 't', 'r' }, { 0x0307, 0, 0 }, { 0, 0, 0 }, { 0x0307, 0, 0 }, { 0x0307, 0, 0 }}, +#line 59 "./unicase/special-casing-table.gperf" + {"\003\007\002", 0, SCC_AFTER_I , { 'a', 'z' }, { 0x0307, 0, 0 }, { 0, 0, 0 }, { 0x0307, 0, 0 }, { 0x0307, 0, 0 }}, +#line 43 "./unicase/special-casing-table.gperf" + {"\000I\004", 0, SCC_ALWAYS , { 'a', 'z' }, { 0x0049, 0, 0 }, { 0x0069, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }}, +#line 47 "./unicase/special-casing-table.gperf" + {"\000\314\000", 0, SCC_ALWAYS , { 'l', 't' }, { 0x00CC, 0, 0 }, { 0x0069, 0x0307, 0x0300 }, { 0x00CC, 0, 0 }, { 0x00EC, 0, 0 }}, +#line 133 "./unicase/special-casing-table.gperf" + {"\037\314\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0399, 0 }, { 0x1FC3, 0, 0 }, { 0x1FCC, 0, 0 }, { 0x03B7, 0x03B9, 0 }}, +#line 109 "./unicase/special-casing-table.gperf" + {"\037\243\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6B, 0x0399, 0 }, { 0x1FA3, 0, 0 }, { 0x1FAB, 0, 0 }, { 0x1F63, 0x03B9, 0 }}, +#line 104 "./unicase/special-casing-table.gperf" + {"\037\236\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2E, 0x0399, 0 }, { 0x1F96, 0, 0 }, { 0x1F9E, 0, 0 }, { 0x1F26, 0x03B9, 0 }}, +#line 61 "./unicase/special-casing-table.gperf" + {"\003\243\000", 0, SCC_FINAL_SIGMA , { '\0', '\0' }, { 0x03A3, 0, 0 }, { 0x03C2, 0, 0 }, { 0x03A3, 0, 0 }, { 0x03C3, 0, 0 }}, +#line 69 "./unicase/special-casing-table.gperf" + {"\036\236\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1E9E, 0, 0 }, { 0x00DF, 0, 0 }, { 0x1E9E, 0, 0 }, { 0x0073, 0x0073, 0 }}, +#line 100 "./unicase/special-casing-table.gperf" + {"\037\232\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2A, 0x0399, 0 }, { 0x1F92, 0, 0 }, { 0x1F9A, 0, 0 }, { 0x1F22, 0x03B9, 0 }}, +#line 99 "./unicase/special-casing-table.gperf" + {"\037\231\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F29, 0x0399, 0 }, { 0x1F91, 0, 0 }, { 0x1F99, 0, 0 }, { 0x1F21, 0x03B9, 0 }}, +#line 68 "./unicase/special-casing-table.gperf" + {"\036\232\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0041, 0x02BE, 0 }, { 0x1E9A, 0, 0 }, { 0x0041, 0x02BE, 0 }, { 0x0061, 0x02BE, 0 }}, +#line 67 "./unicase/special-casing-table.gperf" + {"\036\231\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0059, 0x030A, 0 }, { 0x1E99, 0, 0 }, { 0x0059, 0x030A, 0 }, { 0x0079, 0x030A, 0 }}, +#line 98 "./unicase/special-casing-table.gperf" + {"\037\230\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F28, 0x0399, 0 }, { 0x1F90, 0, 0 }, { 0x1F98, 0, 0 }, { 0x1F20, 0x03B9, 0 }}, +#line 97 "./unicase/special-casing-table.gperf" + {"\037\227\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2F, 0x0399, 0 }, { 0x1F97, 0, 0 }, { 0x1F9F, 0, 0 }, { 0x1F27, 0x03B9, 0 }}, +#line 66 "./unicase/special-casing-table.gperf" + {"\036\230\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0057, 0x030A, 0 }, { 0x1E98, 0, 0 }, { 0x0057, 0x030A, 0 }, { 0x0077, 0x030A, 0 }}, +#line 65 "./unicase/special-casing-table.gperf" + {"\036\227\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0054, 0x0308, 0 }, { 0x1E97, 0, 0 }, { 0x0054, 0x0308, 0 }, { 0x0074, 0x0308, 0 }}, +#line 96 "./unicase/special-casing-table.gperf" + {"\037\226\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2E, 0x0399, 0 }, { 0x1F96, 0, 0 }, { 0x1F9E, 0, 0 }, { 0x1F26, 0x03B9, 0 }}, +#line 90 "./unicase/special-casing-table.gperf" + {"\037\220\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F28, 0x0399, 0 }, { 0x1F90, 0, 0 }, { 0x1F98, 0, 0 }, { 0x1F20, 0x03B9, 0 }}, +#line 64 "./unicase/special-casing-table.gperf" + {"\036\226\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0048, 0x0331, 0 }, { 0x1E96, 0, 0 }, { 0x0048, 0x0331, 0 }, { 0x0068, 0x0331, 0 }}, +#line 60 "./unicase/special-casing-table.gperf" + {"\003\220\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0301 }, { 0x0390, 0, 0 }, { 0x0399, 0x0308, 0x0301 }, { 0x03B9, 0x0308, 0x0301 }}, +#line 81 "./unicase/special-casing-table.gperf" + {"\037\207\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0F, 0x0399, 0 }, { 0x1F87, 0, 0 }, { 0x1F8F, 0, 0 }, { 0x1F07, 0x03B9, 0 }}, +#line 45 "./unicase/special-casing-table.gperf" + {"\000i\000", 1, SCC_ALWAYS , { 't', 'r' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }}, +#line 148 "./unicase/special-casing-table.gperf" + {"\037\374\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0399, 0 }, { 0x1FF3, 0, 0 }, { 0x1FFC, 0, 0 }, { 0x03C9, 0x03B9, 0 }}, +#line 153 "./unicase/special-casing-table.gperf" + {"\373\004\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0046, 0x0046, 0x004C }, { 0xFB04, 0, 0 }, { 0x0046, 0x0066, 0x006C }, { 0x0066, 0x0066, 0x006C }}, +#line 147 "./unicase/special-casing-table.gperf" + {"\037\367\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0342, 0x0399 }, { 0x1FF7, 0, 0 }, { 0x03A9, 0x0342, 0x0345 }, { 0x03C9, 0x0342, 0x03B9 }}, +#line 46 "./unicase/special-casing-table.gperf" + {"\000i\001", 0, SCC_ALWAYS , { 'a', 'z' }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }, { 0x0130, 0, 0 }, { 0x0069, 0, 0 }}, +#line 42 "./unicase/special-casing-table.gperf" + {"\000I\003", 1, SCC_ALWAYS , { 't', 'r' }, { 0x0049, 0, 0 }, { 0x0069, 0, 0 }, { 0x0049, 0, 0 }, { 0x0131, 0, 0 }}, +#line 146 "./unicase/special-casing-table.gperf" + {"\037\366\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0342, 0 }, { 0x1FF6, 0, 0 }, { 0x03A9, 0x0342, 0 }, { 0x03C9, 0x0342, 0 }}, +#line 145 "./unicase/special-casing-table.gperf" + {"\037\364\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x038F, 0x0399, 0 }, { 0x1FF4, 0, 0 }, { 0x038F, 0x0345, 0 }, { 0x03CE, 0x03B9, 0 }}, +#line 63 "./unicase/special-casing-table.gperf" + {"\005\207\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0535, 0x0552, 0 }, { 0x0587, 0, 0 }, { 0x0535, 0x0582, 0 }, { 0x0565, 0x0582, 0 }}, +#line 144 "./unicase/special-casing-table.gperf" + {"\037\363\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A9, 0x0399, 0 }, { 0x1FF3, 0, 0 }, { 0x1FFC, 0, 0 }, { 0x03C9, 0x03B9, 0 }}, +#line 143 "./unicase/special-casing-table.gperf" + {"\037\362\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1FFA, 0x0399, 0 }, { 0x1FF2, 0, 0 }, { 0x1FFA, 0x0345, 0 }, { 0x1F7C, 0x03B9, 0 }}, +#line 56 "./unicase/special-casing-table.gperf" + {"\001\360\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x004A, 0x030C, 0 }, { 0x01F0, 0, 0 }, { 0x004A, 0x030C, 0 }, { 0x006A, 0x030C, 0 }}, +#line 142 "./unicase/special-casing-table.gperf" + {"\037\347\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0342 }, { 0x1FE7, 0, 0 }, { 0x03A5, 0x0308, 0x0342 }, { 0x03C5, 0x0308, 0x0342 }}, +#line 141 "./unicase/special-casing-table.gperf" + {"\037\346\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0342, 0 }, { 0x1FE6, 0, 0 }, { 0x03A5, 0x0342, 0 }, { 0x03C5, 0x0342, 0 }}, +#line 140 "./unicase/special-casing-table.gperf" + {"\037\344\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A1, 0x0313, 0 }, { 0x1FE4, 0, 0 }, { 0x03A1, 0x0313, 0 }, { 0x03C1, 0x0313, 0 }}, +#line 139 "./unicase/special-casing-table.gperf" + {"\037\343\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0301 }, { 0x1FE3, 0, 0 }, { 0x03A5, 0x0308, 0x0301 }, { 0x03C5, 0x0308, 0x0301 }}, +#line 138 "./unicase/special-casing-table.gperf" + {"\037\342\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0300 }, { 0x1FE2, 0, 0 }, { 0x03A5, 0x0308, 0x0300 }, { 0x03C5, 0x0308, 0x0300 }}, +#line 49 "./unicase/special-casing-table.gperf" + {"\000\337\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0053, 0x0053, 0 }, { 0x00DF, 0, 0 }, { 0x0053, 0x0073, 0 }, { 0x0073, 0x0073, 0 }}, +#line 137 "./unicase/special-casing-table.gperf" + {"\037\327\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0342 }, { 0x1FD7, 0, 0 }, { 0x0399, 0x0308, 0x0342 }, { 0x03B9, 0x0308, 0x0342 }}, +#line 136 "./unicase/special-casing-table.gperf" + {"\037\326\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0342, 0 }, { 0x1FD6, 0, 0 }, { 0x0399, 0x0342, 0 }, { 0x03B9, 0x0342, 0 }}, +#line 135 "./unicase/special-casing-table.gperf" + {"\037\323\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0301 }, { 0x1FD3, 0, 0 }, { 0x0399, 0x0308, 0x0301 }, { 0x03B9, 0x0308, 0x0301 }}, +#line 134 "./unicase/special-casing-table.gperf" + {"\037\322\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0399, 0x0308, 0x0300 }, { 0x1FD2, 0, 0 }, { 0x0399, 0x0308, 0x0300 }, { 0x03B9, 0x0308, 0x0300 }}, +#line 48 "./unicase/special-casing-table.gperf" + {"\000\315\000", 0, SCC_ALWAYS , { 'l', 't' }, { 0x00CD, 0, 0 }, { 0x0069, 0x0307, 0x0301 }, { 0x00CD, 0, 0 }, { 0x00ED, 0, 0 }}, +#line 132 "./unicase/special-casing-table.gperf" + {"\037\307\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0342, 0x0399 }, { 0x1FC7, 0, 0 }, { 0x0397, 0x0342, 0x0345 }, { 0x03B7, 0x0342, 0x03B9 }}, +#line 131 "./unicase/special-casing-table.gperf" + {"\037\306\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0342, 0 }, { 0x1FC6, 0, 0 }, { 0x0397, 0x0342, 0 }, { 0x03B7, 0x0342, 0 }}, +#line 130 "./unicase/special-casing-table.gperf" + {"\037\304\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0389, 0x0399, 0 }, { 0x1FC4, 0, 0 }, { 0x0389, 0x0345, 0 }, { 0x03AE, 0x03B9, 0 }}, +#line 129 "./unicase/special-casing-table.gperf" + {"\037\303\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0397, 0x0399, 0 }, { 0x1FC3, 0, 0 }, { 0x1FCC, 0, 0 }, { 0x03B7, 0x03B9, 0 }}, +#line 128 "./unicase/special-casing-table.gperf" + {"\037\302\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1FCA, 0x0399, 0 }, { 0x1FC2, 0, 0 }, { 0x1FCA, 0x0345, 0 }, { 0x1F74, 0x03B9, 0 }}, +#line 127 "./unicase/special-casing-table.gperf" + {"\037\274\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0399, 0 }, { 0x1FB3, 0, 0 }, { 0x1FBC, 0, 0 }, { 0x03B1, 0x03B9, 0 }}, +#line 126 "./unicase/special-casing-table.gperf" + {"\037\267\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0342, 0x0399 }, { 0x1FB7, 0, 0 }, { 0x0391, 0x0342, 0x0345 }, { 0x03B1, 0x0342, 0x03B9 }}, +#line 125 "./unicase/special-casing-table.gperf" + {"\037\266\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0342, 0 }, { 0x1FB6, 0, 0 }, { 0x0391, 0x0342, 0 }, { 0x03B1, 0x0342, 0 }}, +#line 124 "./unicase/special-casing-table.gperf" + {"\037\264\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0386, 0x0399, 0 }, { 0x1FB4, 0, 0 }, { 0x0386, 0x0345, 0 }, { 0x03AC, 0x03B9, 0 }}, +#line 123 "./unicase/special-casing-table.gperf" + {"\037\263\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0391, 0x0399, 0 }, { 0x1FB3, 0, 0 }, { 0x1FBC, 0, 0 }, { 0x03B1, 0x03B9, 0 }}, +#line 122 "./unicase/special-casing-table.gperf" + {"\037\262\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1FBA, 0x0399, 0 }, { 0x1FB2, 0, 0 }, { 0x1FBA, 0x0345, 0 }, { 0x1F70, 0x03B9, 0 }}, +#line 62 "./unicase/special-casing-table.gperf" + {"\003\260\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0308, 0x0301 }, { 0x03B0, 0, 0 }, { 0x03A5, 0x0308, 0x0301 }, { 0x03C5, 0x0308, 0x0301 }}, +#line 121 "./unicase/special-casing-table.gperf" + {"\037\257\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6F, 0x0399, 0 }, { 0x1FA7, 0, 0 }, { 0x1FAF, 0, 0 }, { 0x1F67, 0x03B9, 0 }}, +#line 120 "./unicase/special-casing-table.gperf" + {"\037\256\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6E, 0x0399, 0 }, { 0x1FA6, 0, 0 }, { 0x1FAE, 0, 0 }, { 0x1F66, 0x03B9, 0 }}, +#line 119 "./unicase/special-casing-table.gperf" + {"\037\255\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6D, 0x0399, 0 }, { 0x1FA5, 0, 0 }, { 0x1FAD, 0, 0 }, { 0x1F65, 0x03B9, 0 }}, +#line 118 "./unicase/special-casing-table.gperf" + {"\037\254\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6C, 0x0399, 0 }, { 0x1FA4, 0, 0 }, { 0x1FAC, 0, 0 }, { 0x1F64, 0x03B9, 0 }}, +#line 117 "./unicase/special-casing-table.gperf" + {"\037\253\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6B, 0x0399, 0 }, { 0x1FA3, 0, 0 }, { 0x1FAB, 0, 0 }, { 0x1F63, 0x03B9, 0 }}, +#line 116 "./unicase/special-casing-table.gperf" + {"\037\252\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6A, 0x0399, 0 }, { 0x1FA2, 0, 0 }, { 0x1FAA, 0, 0 }, { 0x1F62, 0x03B9, 0 }}, +#line 115 "./unicase/special-casing-table.gperf" + {"\037\251\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F69, 0x0399, 0 }, { 0x1FA1, 0, 0 }, { 0x1FA9, 0, 0 }, { 0x1F61, 0x03B9, 0 }}, +#line 114 "./unicase/special-casing-table.gperf" + {"\037\250\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F68, 0x0399, 0 }, { 0x1FA0, 0, 0 }, { 0x1FA8, 0, 0 }, { 0x1F60, 0x03B9, 0 }}, +#line 113 "./unicase/special-casing-table.gperf" + {"\037\247\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6F, 0x0399, 0 }, { 0x1FA7, 0, 0 }, { 0x1FAF, 0, 0 }, { 0x1F67, 0x03B9, 0 }}, +#line 112 "./unicase/special-casing-table.gperf" + {"\037\246\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6E, 0x0399, 0 }, { 0x1FA6, 0, 0 }, { 0x1FAE, 0, 0 }, { 0x1F66, 0x03B9, 0 }}, +#line 111 "./unicase/special-casing-table.gperf" + {"\037\245\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6D, 0x0399, 0 }, { 0x1FA5, 0, 0 }, { 0x1FAD, 0, 0 }, { 0x1F65, 0x03B9, 0 }}, +#line 110 "./unicase/special-casing-table.gperf" + {"\037\244\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6C, 0x0399, 0 }, { 0x1FA4, 0, 0 }, { 0x1FAC, 0, 0 }, { 0x1F64, 0x03B9, 0 }}, +#line 108 "./unicase/special-casing-table.gperf" + {"\037\242\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F6A, 0x0399, 0 }, { 0x1FA2, 0, 0 }, { 0x1FAA, 0, 0 }, { 0x1F62, 0x03B9, 0 }}, +#line 107 "./unicase/special-casing-table.gperf" + {"\037\241\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F69, 0x0399, 0 }, { 0x1FA1, 0, 0 }, { 0x1FA9, 0, 0 }, { 0x1F61, 0x03B9, 0 }}, +#line 106 "./unicase/special-casing-table.gperf" + {"\037\240\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F68, 0x0399, 0 }, { 0x1FA0, 0, 0 }, { 0x1FA8, 0, 0 }, { 0x1F60, 0x03B9, 0 }}, +#line 105 "./unicase/special-casing-table.gperf" + {"\037\237\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2F, 0x0399, 0 }, { 0x1F97, 0, 0 }, { 0x1F9F, 0, 0 }, { 0x1F27, 0x03B9, 0 }}, +#line 103 "./unicase/special-casing-table.gperf" + {"\037\235\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2D, 0x0399, 0 }, { 0x1F95, 0, 0 }, { 0x1F9D, 0, 0 }, { 0x1F25, 0x03B9, 0 }}, +#line 102 "./unicase/special-casing-table.gperf" + {"\037\234\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2C, 0x0399, 0 }, { 0x1F94, 0, 0 }, { 0x1F9C, 0, 0 }, { 0x1F24, 0x03B9, 0 }}, +#line 101 "./unicase/special-casing-table.gperf" + {"\037\233\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2B, 0x0399, 0 }, { 0x1F93, 0, 0 }, { 0x1F9B, 0, 0 }, { 0x1F23, 0x03B9, 0 }}, +#line 95 "./unicase/special-casing-table.gperf" + {"\037\225\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2D, 0x0399, 0 }, { 0x1F95, 0, 0 }, { 0x1F9D, 0, 0 }, { 0x1F25, 0x03B9, 0 }}, +#line 94 "./unicase/special-casing-table.gperf" + {"\037\224\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2C, 0x0399, 0 }, { 0x1F94, 0, 0 }, { 0x1F9C, 0, 0 }, { 0x1F24, 0x03B9, 0 }}, +#line 93 "./unicase/special-casing-table.gperf" + {"\037\223\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2B, 0x0399, 0 }, { 0x1F93, 0, 0 }, { 0x1F9B, 0, 0 }, { 0x1F23, 0x03B9, 0 }}, +#line 92 "./unicase/special-casing-table.gperf" + {"\037\222\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F2A, 0x0399, 0 }, { 0x1F92, 0, 0 }, { 0x1F9A, 0, 0 }, { 0x1F22, 0x03B9, 0 }}, +#line 91 "./unicase/special-casing-table.gperf" + {"\037\221\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F29, 0x0399, 0 }, { 0x1F91, 0, 0 }, { 0x1F99, 0, 0 }, { 0x1F21, 0x03B9, 0 }}, +#line 89 "./unicase/special-casing-table.gperf" + {"\037\217\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0F, 0x0399, 0 }, { 0x1F87, 0, 0 }, { 0x1F8F, 0, 0 }, { 0x1F07, 0x03B9, 0 }}, +#line 88 "./unicase/special-casing-table.gperf" + {"\037\216\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0E, 0x0399, 0 }, { 0x1F86, 0, 0 }, { 0x1F8E, 0, 0 }, { 0x1F06, 0x03B9, 0 }}, +#line 87 "./unicase/special-casing-table.gperf" + {"\037\215\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0D, 0x0399, 0 }, { 0x1F85, 0, 0 }, { 0x1F8D, 0, 0 }, { 0x1F05, 0x03B9, 0 }}, +#line 86 "./unicase/special-casing-table.gperf" + {"\037\214\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0C, 0x0399, 0 }, { 0x1F84, 0, 0 }, { 0x1F8C, 0, 0 }, { 0x1F04, 0x03B9, 0 }}, +#line 85 "./unicase/special-casing-table.gperf" + {"\037\213\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0B, 0x0399, 0 }, { 0x1F83, 0, 0 }, { 0x1F8B, 0, 0 }, { 0x1F03, 0x03B9, 0 }}, +#line 84 "./unicase/special-casing-table.gperf" + {"\037\212\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0A, 0x0399, 0 }, { 0x1F82, 0, 0 }, { 0x1F8A, 0, 0 }, { 0x1F02, 0x03B9, 0 }}, +#line 83 "./unicase/special-casing-table.gperf" + {"\037\211\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F09, 0x0399, 0 }, { 0x1F81, 0, 0 }, { 0x1F89, 0, 0 }, { 0x1F01, 0x03B9, 0 }}, +#line 82 "./unicase/special-casing-table.gperf" + {"\037\210\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F08, 0x0399, 0 }, { 0x1F80, 0, 0 }, { 0x1F88, 0, 0 }, { 0x1F00, 0x03B9, 0 }}, +#line 80 "./unicase/special-casing-table.gperf" + {"\037\206\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0E, 0x0399, 0 }, { 0x1F86, 0, 0 }, { 0x1F8E, 0, 0 }, { 0x1F06, 0x03B9, 0 }}, +#line 79 "./unicase/special-casing-table.gperf" + {"\037\205\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0D, 0x0399, 0 }, { 0x1F85, 0, 0 }, { 0x1F8D, 0, 0 }, { 0x1F05, 0x03B9, 0 }}, +#line 78 "./unicase/special-casing-table.gperf" + {"\037\204\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0C, 0x0399, 0 }, { 0x1F84, 0, 0 }, { 0x1F8C, 0, 0 }, { 0x1F04, 0x03B9, 0 }}, +#line 77 "./unicase/special-casing-table.gperf" + {"\037\203\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0B, 0x0399, 0 }, { 0x1F83, 0, 0 }, { 0x1F8B, 0, 0 }, { 0x1F03, 0x03B9, 0 }}, +#line 76 "./unicase/special-casing-table.gperf" + {"\037\202\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F0A, 0x0399, 0 }, { 0x1F82, 0, 0 }, { 0x1F8A, 0, 0 }, { 0x1F02, 0x03B9, 0 }}, +#line 75 "./unicase/special-casing-table.gperf" + {"\037\201\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F09, 0x0399, 0 }, { 0x1F81, 0, 0 }, { 0x1F89, 0, 0 }, { 0x1F01, 0x03B9, 0 }}, +#line 74 "./unicase/special-casing-table.gperf" + {"\037\200\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x1F08, 0x0399, 0 }, { 0x1F80, 0, 0 }, { 0x1F88, 0, 0 }, { 0x1F00, 0x03B9, 0 }}, +#line 73 "./unicase/special-casing-table.gperf" + {"\037V\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0x0342 }, { 0x1F56, 0, 0 }, { 0x03A5, 0x0313, 0x0342 }, { 0x03C5, 0x0313, 0x0342 }}, +#line 72 "./unicase/special-casing-table.gperf" + {"\037T\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0x0301 }, { 0x1F54, 0, 0 }, { 0x03A5, 0x0313, 0x0301 }, { 0x03C5, 0x0313, 0x0301 }}, +#line 71 "./unicase/special-casing-table.gperf" + {"\037R\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0x0300 }, { 0x1F52, 0, 0 }, { 0x03A5, 0x0313, 0x0300 }, { 0x03C5, 0x0313, 0x0300 }}, +#line 70 "./unicase/special-casing-table.gperf" + {"\037P\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x03A5, 0x0313, 0 }, { 0x1F50, 0, 0 }, { 0x03A5, 0x0313, 0 }, { 0x03C5, 0x0313, 0 }}, +#line 44 "./unicase/special-casing-table.gperf" + {"\000J\000", 0, SCC_MORE_ABOVE , { 'l', 't' }, { 0x004A, 0, 0 }, { 0x006A, 0x0307, 0 }, { 0x004A, 0, 0 }, { 0x006A, 0, 0 }}, +#line 51 "./unicase/special-casing-table.gperf" + {"\001.\000", 0, SCC_MORE_ABOVE , { 'l', 't' }, { 0x012E, 0, 0 }, { 0x012F, 0x0307, 0 }, { 0x012E, 0, 0 }, { 0x012F, 0, 0 }}, +#line 50 "./unicase/special-casing-table.gperf" + {"\001(\000", 0, SCC_ALWAYS , { 'l', 't' }, { 0x0128, 0, 0 }, { 0x0069, 0x0307, 0x0303 }, { 0x0128, 0, 0 }, { 0x0129, 0, 0 }}, +#line 160 "./unicase/special-casing-table.gperf" + {"\373\027\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x053D, 0 }, { 0xFB17, 0, 0 }, { 0x0544, 0x056D, 0 }, { 0x0574, 0x056D, 0 }}, +#line 159 "./unicase/special-casing-table.gperf" + {"\373\026\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x054E, 0x0546, 0 }, { 0xFB16, 0, 0 }, { 0x054E, 0x0576, 0 }, { 0x057E, 0x0576, 0 }}, +#line 158 "./unicase/special-casing-table.gperf" + {"\373\025\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x053B, 0 }, { 0xFB15, 0, 0 }, { 0x0544, 0x056B, 0 }, { 0x0574, 0x056B, 0 }}, +#line 157 "./unicase/special-casing-table.gperf" + {"\373\024\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x0535, 0 }, { 0xFB14, 0, 0 }, { 0x0544, 0x0565, 0 }, { 0x0574, 0x0565, 0 }}, +#line 156 "./unicase/special-casing-table.gperf" + {"\373\023\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0544, 0x0546, 0 }, { 0xFB13, 0, 0 }, { 0x0544, 0x0576, 0 }, { 0x0574, 0x0576, 0 }}, +#line 155 "./unicase/special-casing-table.gperf" + {"\373\006\000", 0, SCC_ALWAYS , { '\0', '\0' }, { 0x0053, 0x0054, 0 }, { 0xFB06, 0, 0 }, { 0x0053, 0x0074, 0 }, { 0x0073, 0x0074, 0 }} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register unsigned int key = gl_unicase_special_hash (str, len); + + if (key <= MAX_HASH_VALUE) + if (len == lengthtable[key]) + { + register const char *s = wordlist[key].code; + + if (*str == *s && !memcmp (str + 1, s + 1, len - 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/lib/unicase/special-casing.c b/lib/unicase/special-casing.c new file mode 100644 index 0000000..37156f6 --- /dev/null +++ b/lib/unicase/special-casing.c @@ -0,0 +1,33 @@ +/* Special casing table. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unicase/special-casing.h" + +#include + +#include "unicase/special-casing-table.h" diff --git a/lib/unicase/special-casing.in.h b/lib/unicase/special-casing.in.h new file mode 100644 index 0000000..2a011df --- /dev/null +++ b/lib/unicase/special-casing.in.h @@ -0,0 +1,69 @@ +/* Special casing table. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* A special casing context. + A context is negated through x -> -x. */ +enum +{ + SCC_ALWAYS = 0, + SCC_FINAL_SIGMA = 1, + SCC_AFTER_SOFT_DOTTED = 2, + SCC_MORE_ABOVE = 3, + SCC_BEFORE_DOT = 4, + SCC_AFTER_I = 5 +}; + +struct special_casing_rule +{ + /* The first two bytes are the code, in big-endian order. The third byte + only distinguishes different rules pertaining to the same code. */ + /*unsigned*/ char code[3]; + + /* True when this rule is not the last one for the given code. */ + /*bool*/ unsigned int has_next : 1; + + /* Context. */ + signed int context : 7; + + /* Language, or an empty string. */ + char language[2]; + + /* Mapping to upper case. Between 0 and 3 characters. Filled with 0s. */ + unsigned short upper[3]; + + /* Mapping to lower case. Between 0 and 3 characters. Filled with 0s. */ + unsigned short lower[3]; + + /* Mapping to title case. Between 0 and 3 characters. Filled with 0s. */ + unsigned short title[3]; + + /* Casefolding mapping. Between 0 and 3 characters. Filled with 0s. */ + unsigned short casefold[3]; +}; + +extern const struct special_casing_rule * + gl_unicase_special_lookup (const char *str, size_t len); diff --git a/lib/unicase/tolower.c b/lib/unicase/tolower.c new file mode 100644 index 0000000..b3e1172 --- /dev/null +++ b/lib/unicase/tolower.c @@ -0,0 +1,35 @@ +/* Lowercase mapping for Unicode characters (locale and context independent). + Copyright (C) 2002, 2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unicase.h" + +/* Define u_mapping table. */ +#include "tolower.h" + +#define FUNC uc_tolower +#include "simple-mapping.h" diff --git a/lib/unicase/tolower.h b/lib/unicase/tolower.h new file mode 100644 index 0000000..baf72b8 --- /dev/null +++ b/lib/unicase/tolower.h @@ -0,0 +1,735 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Simple character mapping of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#define mapping_header_0 16 +#define mapping_header_1 2 +#define mapping_header_2 7 +#define mapping_header_3 511 +#define mapping_header_4 127 +static const +struct + { + int level1[2]; + short level2[2 << 9]; + int level3[35 << 7]; + } +u_mapping = +{ + { 0, 512 }, + { + 0, 128, 256, 384, 512, -1, 640, 768, + 896, 1024, 1152, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1280, -1, -1, -1, -1, -1, 1408, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1536, -1, -1, 1664, 1792, 1920, 2048, + -1, -1, 2176, 2304, -1, -1, -1, -1, + -1, 2432, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 2560, 2688, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2816, 2944, 3072, 3200, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3328, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3456, 3584, 3712, 3840, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3968, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4096, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4224, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 4352, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 0, + 32, 32, 32, 32, 32, 32, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + -199, 0, 1, 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + -121, 1, 0, 1, 0, 1, 0, 0, + 0, 210, 1, 0, 1, 0, 206, 1, + 0, 205, 205, 1, 0, 0, 79, 202, + 203, 1, 0, 205, 207, 0, 211, 209, + 1, 0, 0, 0, 211, 213, 0, 214, + 1, 0, 1, 0, 1, 0, 218, 1, + 0, 218, 0, 0, 1, 0, 218, 1, + 0, 217, 217, 1, 0, 1, 0, 219, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 1, 0, 2, + 1, 0, 2, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 2, 1, 0, 1, 0, -97, -56, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + -130, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 10795, 1, 0, -163, 10792, 0, + 0, 1, 0, -195, 69, 71, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 116, + 0, 0, 0, 0, 0, 0, 38, 0, + 37, 37, 37, 0, 64, 0, 63, 63, + 0, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 0, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, -60, 0, 0, 1, + 0, -7, 1, 0, 0, -130, -130, -130, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 15, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, + 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, + 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, + 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, + 7264, 7264, 7264, 7264, 7264, 7264, 0, 7264, + 0, 0, 0, 0, 0, 7264, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, + 8, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, + -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, + -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, + -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, + -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, + -3008, -3008, -3008, 0, 0, -3008, -3008, -3008, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7615, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, -8, 0, -8, 0, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -8, -8, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -74, -74, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -86, -86, -86, -86, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -100, -100, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, -8, -112, -112, -7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -128, -128, -126, -126, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7517, 0, + 0, 0, -8383, -8262, 0, 0, 0, 0, + 0, 0, 28, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, -10743, -3814, -10727, 0, 0, 1, + 0, 1, 0, 1, 0, -10780, -10749, -10783, + -10782, 0, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, -10815, -10815, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, -35332, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 1, 0, -42280, 0, 0, + 1, 0, 1, 0, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, -42308, -42319, -42315, -42305, -42308, 0, + -42258, -42282, -42261, 928, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, -48, -42307, -35384, 1, + 0, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 0, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 0, 39, 39, 39, 39, + 39, 39, 39, 0, 39, 39, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + } +}; diff --git a/lib/unicase/u-casemap.h b/lib/unicase/u-casemap.h new file mode 100644 index 0000000..973866a --- /dev/null +++ b/lib/unicase/u-casemap.h @@ -0,0 +1,424 @@ +/* Case mapping for UTF-8/UTF-16/UTF-32 strings (locale dependent). + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +UNIT * +FUNC (const UNIT *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + ucs4_t (*single_character_map) (ucs4_t), + size_t offset_in_rule, /* offset in 'struct special_casing_rule' */ + uninorm_t nf, + UNIT *resultbuf, size_t *lengthp) +{ + /* The result being accumulated. */ + UNIT *result; + size_t length; + size_t allocated; + + /* Initialize the accumulator. */ + if (nf != NULL || resultbuf == NULL) + { + result = NULL; + allocated = 0; + } + else + { + result = resultbuf; + allocated = *lengthp; + } + length = 0; + + { + const UNIT *s_end = s + n; + + /* Helper for evaluating the FINAL_SIGMA condition: + Last character that was not case-ignorable. */ + ucs4_t last_char_except_ignorable = + prefix_context.last_char_except_ignorable; + + /* Helper for evaluating the AFTER_SOFT_DOTTED and AFTER_I conditions: + Last character that was of combining class 230 ("Above") or 0. */ + ucs4_t last_char_normal_or_above = + prefix_context.last_char_normal_or_above; + + while (s < s_end) + { + ucs4_t uc; + int count = U_MBTOUC_UNSAFE (&uc, s, s_end - s); + + ucs4_t mapped_uc[3]; + unsigned int mapped_count; + + if (uc < 0x10000) + { + /* Look first in the special-casing table. */ + char code[3]; + + code[0] = (uc >> 8) & 0xff; + code[1] = uc & 0xff; + + for (code[2] = 0; ; code[2]++) + { + const struct special_casing_rule *rule = + gl_unicase_special_lookup (code, 3); + + if (rule == NULL) + break; + + /* Test if the condition applies. */ + /* Does the language apply? */ + if (rule->language[0] == '\0' + || (iso639_language != NULL + && iso639_language[0] == rule->language[0] + && iso639_language[1] == rule->language[1])) + { + /* Does the context apply? */ + int context = rule->context; + bool applies; + + if (context < 0) + context = - context; + switch (context) + { + case SCC_ALWAYS: + applies = true; + break; + + case SCC_FINAL_SIGMA: + /* "Before" condition: preceded by a sequence + consisting of a cased letter and a case-ignorable + sequence. + "After" condition: not followed by a sequence + consisting of a case-ignorable sequence and then a + cased letter. */ + /* Test the "before" condition. */ + applies = uc_is_cased (last_char_except_ignorable); + /* Test the "after" condition. */ + if (applies) + { + const UNIT *s2 = s + count; + for (;;) + { + if (s2 < s_end) + { + ucs4_t uc2; + int count2 = U_MBTOUC_UNSAFE (&uc2, s2, s_end - s2); + /* Our uc_is_case_ignorable function is + known to return false for all cased + characters. So we can call + uc_is_case_ignorable first. */ + if (!uc_is_case_ignorable (uc2)) + { + applies = ! uc_is_cased (uc2); + break; + } + s2 += count2; + } + else + { + applies = ! uc_is_cased (suffix_context.first_char_except_ignorable); + break; + } + } + } + break; + + case SCC_AFTER_SOFT_DOTTED: + /* "Before" condition: There is a Soft_Dotted character + before it, with no intervening character of + combining class 0 or 230 (Above). */ + /* Test the "before" condition. */ + applies = uc_is_property_soft_dotted (last_char_normal_or_above); + break; + + case SCC_MORE_ABOVE: + /* "After" condition: followed by a character of + combining class 230 (Above) with no intervening + character of combining class 0 or 230 (Above). */ + /* Test the "after" condition. */ + { + const UNIT *s2 = s + count; + applies = false; + for (;;) + { + if (s2 < s_end) + { + ucs4_t uc2; + int count2 = U_MBTOUC_UNSAFE (&uc2, s2, s_end - s2); + int ccc = uc_combining_class (uc2); + if (ccc == UC_CCC_A) + { + applies = true; + break; + } + if (ccc == UC_CCC_NR) + break; + s2 += count2; + } + else + { + applies = ((suffix_context.bits & SCC_MORE_ABOVE_MASK) != 0); + break; + } + } + } + break; + + case SCC_BEFORE_DOT: + /* "After" condition: followed by COMBINING DOT ABOVE + (U+0307). Any sequence of characters with a + combining class that is neither 0 nor 230 may + intervene between the current character and the + combining dot above. */ + /* Test the "after" condition. */ + { + const UNIT *s2 = s + count; + applies = false; + for (;;) + { + if (s2 < s_end) + { + ucs4_t uc2; + int count2 = U_MBTOUC_UNSAFE (&uc2, s2, s_end - s2); + if (uc2 == 0x0307) /* COMBINING DOT ABOVE */ + { + applies = true; + break; + } + { + int ccc = uc_combining_class (uc2); + if (ccc == UC_CCC_A || ccc == UC_CCC_NR) + break; + } + s2 += count2; + } + else + { + applies = ((suffix_context.bits & SCC_BEFORE_DOT_MASK) != 0); + break; + } + } + } + break; + + case SCC_AFTER_I: + /* "Before" condition: There is an uppercase I before + it, and there is no intervening character of + combining class 0 or 230 (Above). */ + /* Test the "before" condition. */ + applies = (last_char_normal_or_above == 'I'); + break; + + default: + abort (); + } + if (rule->context < 0) + applies = !applies; + + if (applies) + { + /* The rule applies. + Look up the mapping (0 to 3 characters). */ + const unsigned short *mapped_in_rule = + (const unsigned short *)((const char *)rule + offset_in_rule); + + if (mapped_in_rule[0] == 0) + mapped_count = 0; + else + { + mapped_uc[0] = mapped_in_rule[0]; + if (mapped_in_rule[1] == 0) + mapped_count = 1; + else + { + mapped_uc[1] = mapped_in_rule[1]; + if (mapped_in_rule[2] == 0) + mapped_count = 2; + else + { + mapped_uc[2] = mapped_in_rule[2]; + mapped_count = 3; + } + } + } + goto found_mapping; + } + } + + /* Optimization: Save a hash table lookup in the next round. */ + if (!rule->has_next) + break; + } + } + + /* No special-cased mapping. So use the locale and context independent + mapping. */ + mapped_uc[0] = single_character_map (uc); + mapped_count = 1; + + found_mapping: + /* Found the mapping: uc maps to mapped_uc[0..mapped_count-1]. */ + { + unsigned int i; + + for (i = 0; i < mapped_count; i++) + { + ucs4_t muc = mapped_uc[i]; + + /* Append muc to the result accumulator. */ + if (length < allocated) + { + int ret = U_UCTOMB (result + length, muc, allocated - length); + if (ret == -1) + { + errno = EINVAL; + goto fail; + } + if (ret >= 0) + { + length += ret; + goto done_appending; + } + } + { + size_t old_allocated = allocated; + size_t new_allocated = 2 * old_allocated; + if (new_allocated < 64) + new_allocated = 64; + if (new_allocated < old_allocated) /* integer overflow? */ + abort (); + { + UNIT *larger_result; + if (result == NULL) + { + larger_result = (UNIT *) malloc (new_allocated * sizeof (UNIT)); + if (larger_result == NULL) + { + errno = ENOMEM; + goto fail; + } + } + else if (result == resultbuf) + { + larger_result = (UNIT *) malloc (new_allocated * sizeof (UNIT)); + if (larger_result == NULL) + { + errno = ENOMEM; + goto fail; + } + U_CPY (larger_result, resultbuf, length); + } + else + { + larger_result = + (UNIT *) realloc (result, new_allocated * sizeof (UNIT)); + if (larger_result == NULL) + { + errno = ENOMEM; + goto fail; + } + } + result = larger_result; + allocated = new_allocated; + { + int ret = U_UCTOMB (result + length, muc, allocated - length); + if (ret == -1) + { + errno = EINVAL; + goto fail; + } + if (ret < 0) + abort (); + length += ret; + goto done_appending; + } + } + } + done_appending: ; + } + } + + if (!uc_is_case_ignorable (uc)) + last_char_except_ignorable = uc; + + { + int ccc = uc_combining_class (uc); + if (ccc == UC_CCC_A || ccc == UC_CCC_NR) + last_char_normal_or_above = uc; + } + + s += count; + } + } + + if (nf != NULL) + { + /* Finally, normalize the result. */ + UNIT *normalized_result; + + normalized_result = U_NORMALIZE (nf, result, length, resultbuf, lengthp); + if (normalized_result == NULL) + goto fail; + + free (result); + return normalized_result; + } + + if (length == 0) + { + if (result == NULL) + { + /* Return a non-NULL value. NULL means error. */ + result = (UNIT *) malloc (1); + if (result == NULL) + { + errno = ENOMEM; + goto fail; + } + } + } + else if (result != resultbuf && length < allocated) + { + /* Shrink the allocated memory if possible. */ + UNIT *memory; + + memory = (UNIT *) realloc (result, length * sizeof (UNIT)); + if (memory != NULL) + result = memory; + } + + *lengthp = length; + return result; + + fail: + if (result != resultbuf) + { + int saved_errno = errno; + free (result); + errno = saved_errno; + } + return NULL; +} diff --git a/lib/unicase/u8-casemap.c b/lib/unicase/u8-casemap.c new file mode 100644 index 0000000..fb5a66c --- /dev/null +++ b/lib/unicase/u8-casemap.c @@ -0,0 +1,48 @@ +/* Case mapping for UTF-8 strings (locale dependent). + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unicasemap.h" + +#include +#include +#include + +#include "unistr.h" +#include "unictype.h" +#include "uninorm.h" +#include "unicase/caseprop.h" +#include "context.h" +#include "unicase/special-casing.h" + +#define FUNC u8_casemap +#define UNIT uint8_t +#define U_MBTOUC_UNSAFE u8_mbtouc_unsafe +#define U_UCTOMB u8_uctomb +#define U_CPY u8_cpy +#define U_NORMALIZE u8_normalize +#include "u-casemap.h" diff --git a/lib/unicase/u8-tolower.c b/lib/unicase/u8-tolower.c new file mode 100644 index 0000000..63459fc --- /dev/null +++ b/lib/unicase/u8-tolower.c @@ -0,0 +1,128 @@ +/* Lowercase mapping for UTF-8 strings (locale dependent). + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unicase.h" + +#include + +#include "unicase/unicasemap.h" +#include "unicase/special-casing.h" + +uint8_t * +u8_tolower (const uint8_t *s, size_t n, const char *iso639_language, + uninorm_t nf, + uint8_t *resultbuf, size_t *lengthp) +{ + return u8_casemap (s, n, + unicase_empty_prefix_context, unicase_empty_suffix_context, + iso639_language, + uc_tolower, offsetof (struct special_casing_rule, lower[0]), + nf, + resultbuf, lengthp); +} + + +#ifdef TEST + +#include +#include +#include +#include + +/* Read the contents of an input stream, and return it, terminated with a NUL + byte. */ +char * +read_file (FILE *stream) +{ +#define BUFSIZE 4096 + char *buf = NULL; + int alloc = 0; + int size = 0; + int count; + + while (! feof (stream)) + { + if (size + BUFSIZE > alloc) + { + alloc = alloc + alloc / 2; + if (alloc < size + BUFSIZE) + alloc = size + BUFSIZE; + buf = realloc (buf, alloc); + if (buf == NULL) + { + fprintf (stderr, "out of memory\n"); + exit (1); + } + } + count = fread (buf + size, 1, BUFSIZE, stream); + if (count == 0) + { + if (ferror (stream)) + { + perror ("fread"); + exit (1); + } + } + else + size += count; + } + buf = realloc (buf, size + 1); + if (buf == NULL) + { + fprintf (stderr, "out of memory\n"); + exit (1); + } + buf[size] = '\0'; + return buf; +#undef BUFSIZE +} + +int +main (int argc, char * argv[]) +{ + setlocale (LC_ALL, ""); + if (argc == 1) + { + /* Display the lower case of the input string. */ + char *input = read_file (stdin); + int length = strlen (input); + size_t output_length; + uint8_t *output = + u8_tolower ((uint8_t *) input, length, uc_locale_language (), + NULL, + NULL, &output_length); + + fwrite (output, 1, output_length, stdout); + + return 0; + } + else + return 1; +} + +#endif /* TEST */ diff --git a/lib/unicase/unicasemap.h b/lib/unicase/unicasemap.h new file mode 100644 index 0000000..a03088e --- /dev/null +++ b/lib/unicase/unicasemap.h @@ -0,0 +1,60 @@ +/* Case mapping for UTF-8/UTF-16/UTF-32 strings (locale dependent). + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +#include "unitypes.h" +#include "unicase.h" +#include "uninorm.h" + +extern uint8_t * + u8_casemap (const uint8_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + ucs4_t (*single_character_map) (ucs4_t), + size_t offset_in_rule, /* offset in 'struct special_casing_rule' */ + uninorm_t nf, + uint8_t *resultbuf, size_t *lengthp); + +extern uint16_t * + u16_casemap (const uint16_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + ucs4_t (*single_character_map) (ucs4_t), + size_t offset_in_rule, /* offset in 'struct special_casing_rule' */ + uninorm_t nf, + uint16_t *resultbuf, size_t *lengthp); + +extern uint32_t * + u32_casemap (const uint32_t *s, size_t n, + casing_prefix_context_t prefix_context, + casing_suffix_context_t suffix_context, + const char *iso639_language, + ucs4_t (*single_character_map) (ucs4_t), + size_t offset_in_rule, /* offset in 'struct special_casing_rule' */ + uninorm_t nf, + uint32_t *resultbuf, size_t *lengthp); diff --git a/lib/unictype.in.h b/lib/unictype.in.h new file mode 100644 index 0000000..2f0efef --- /dev/null +++ b/lib/unictype.in.h @@ -0,0 +1,1090 @@ +/* Unicode character classification and properties. + Copyright (C) 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 . */ + +#ifndef _UNICTYPE_H +#define _UNICTYPE_H + +#include "unitypes.h" + +/* Get bool. */ +#include + +/* Get size_t. */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ========================================================================= */ + +/* Field 1 of Unicode Character Database: Character name. + See "uniname.h". */ + +/* ========================================================================= */ + +/* Field 2 of Unicode Character Database: General category. */ + +/* Data type denoting a General category value. This is not just a bitmask, + but rather a bitmask and a pointer to the lookup table, so that programs + that use only the predefined bitmasks (i.e. don't combine bitmasks with & + and |) don't have a link-time dependency towards the big general table. */ +typedef struct +{ + uint32_t bitmask : 31; + /*bool*/ unsigned int generic : 1; + union + { + const void *table; /* when generic is 0 */ + bool (*lookup_fn) (ucs4_t uc, uint32_t bitmask); /* when generic is 1 */ + } lookup; +} +uc_general_category_t; + +/* Bits and bit masks denoting General category values. UnicodeData-3.2.0.html + says a 32-bit integer will always suffice to represent them. + These bit masks can only be used with the uc_is_general_category_withtable + function. */ +enum +{ + UC_CATEGORY_MASK_L = 0x0000001f, + UC_CATEGORY_MASK_LC = 0x00000007, + UC_CATEGORY_MASK_Lu = 0x00000001, + UC_CATEGORY_MASK_Ll = 0x00000002, + UC_CATEGORY_MASK_Lt = 0x00000004, + UC_CATEGORY_MASK_Lm = 0x00000008, + UC_CATEGORY_MASK_Lo = 0x00000010, + UC_CATEGORY_MASK_M = 0x000000e0, + UC_CATEGORY_MASK_Mn = 0x00000020, + UC_CATEGORY_MASK_Mc = 0x00000040, + UC_CATEGORY_MASK_Me = 0x00000080, + UC_CATEGORY_MASK_N = 0x00000700, + UC_CATEGORY_MASK_Nd = 0x00000100, + UC_CATEGORY_MASK_Nl = 0x00000200, + UC_CATEGORY_MASK_No = 0x00000400, + UC_CATEGORY_MASK_P = 0x0003f800, + UC_CATEGORY_MASK_Pc = 0x00000800, + UC_CATEGORY_MASK_Pd = 0x00001000, + UC_CATEGORY_MASK_Ps = 0x00002000, + UC_CATEGORY_MASK_Pe = 0x00004000, + UC_CATEGORY_MASK_Pi = 0x00008000, + UC_CATEGORY_MASK_Pf = 0x00010000, + UC_CATEGORY_MASK_Po = 0x00020000, + UC_CATEGORY_MASK_S = 0x003c0000, + UC_CATEGORY_MASK_Sm = 0x00040000, + UC_CATEGORY_MASK_Sc = 0x00080000, + UC_CATEGORY_MASK_Sk = 0x00100000, + UC_CATEGORY_MASK_So = 0x00200000, + UC_CATEGORY_MASK_Z = 0x01c00000, + UC_CATEGORY_MASK_Zs = 0x00400000, + UC_CATEGORY_MASK_Zl = 0x00800000, + UC_CATEGORY_MASK_Zp = 0x01000000, + UC_CATEGORY_MASK_C = 0x3e000000, + UC_CATEGORY_MASK_Cc = 0x02000000, + UC_CATEGORY_MASK_Cf = 0x04000000, + UC_CATEGORY_MASK_Cs = 0x08000000, + UC_CATEGORY_MASK_Co = 0x10000000, + UC_CATEGORY_MASK_Cn = 0x20000000 +}; + +/* Predefined General category values. */ +extern const uc_general_category_t UC_CATEGORY_L; +extern const uc_general_category_t UC_CATEGORY_LC; +extern const uc_general_category_t UC_CATEGORY_Lu; +extern const uc_general_category_t UC_CATEGORY_Ll; +extern const uc_general_category_t UC_CATEGORY_Lt; +extern const uc_general_category_t UC_CATEGORY_Lm; +extern const uc_general_category_t UC_CATEGORY_Lo; +extern const uc_general_category_t UC_CATEGORY_M; +extern const uc_general_category_t UC_CATEGORY_Mn; +extern const uc_general_category_t UC_CATEGORY_Mc; +extern const uc_general_category_t UC_CATEGORY_Me; +extern const uc_general_category_t UC_CATEGORY_N; +extern const uc_general_category_t UC_CATEGORY_Nd; +extern const uc_general_category_t UC_CATEGORY_Nl; +extern const uc_general_category_t UC_CATEGORY_No; +extern const uc_general_category_t UC_CATEGORY_P; +extern const uc_general_category_t UC_CATEGORY_Pc; +extern const uc_general_category_t UC_CATEGORY_Pd; +extern const uc_general_category_t UC_CATEGORY_Ps; +extern const uc_general_category_t UC_CATEGORY_Pe; +extern const uc_general_category_t UC_CATEGORY_Pi; +extern const uc_general_category_t UC_CATEGORY_Pf; +extern const uc_general_category_t UC_CATEGORY_Po; +extern const uc_general_category_t UC_CATEGORY_S; +extern const uc_general_category_t UC_CATEGORY_Sm; +extern const uc_general_category_t UC_CATEGORY_Sc; +extern const uc_general_category_t UC_CATEGORY_Sk; +extern const uc_general_category_t UC_CATEGORY_So; +extern const uc_general_category_t UC_CATEGORY_Z; +extern const uc_general_category_t UC_CATEGORY_Zs; +extern const uc_general_category_t UC_CATEGORY_Zl; +extern const uc_general_category_t UC_CATEGORY_Zp; +extern const uc_general_category_t UC_CATEGORY_C; +extern const uc_general_category_t UC_CATEGORY_Cc; +extern const uc_general_category_t UC_CATEGORY_Cf; +extern const uc_general_category_t UC_CATEGORY_Cs; +extern const uc_general_category_t UC_CATEGORY_Co; +extern const uc_general_category_t UC_CATEGORY_Cn; +/* Non-public. */ +extern const uc_general_category_t _UC_CATEGORY_NONE; + +/* Alias names for predefined General category values. */ +#define UC_LETTER UC_CATEGORY_L +#define UC_CASED_LETTER UC_CATEGORY_LC +#define UC_UPPERCASE_LETTER UC_CATEGORY_Lu +#define UC_LOWERCASE_LETTER UC_CATEGORY_Ll +#define UC_TITLECASE_LETTER UC_CATEGORY_Lt +#define UC_MODIFIER_LETTER UC_CATEGORY_Lm +#define UC_OTHER_LETTER UC_CATEGORY_Lo +#define UC_MARK UC_CATEGORY_M +#define UC_NON_SPACING_MARK UC_CATEGORY_Mn +#define UC_COMBINING_SPACING_MARK UC_CATEGORY_Mc +#define UC_ENCLOSING_MARK UC_CATEGORY_Me +#define UC_NUMBER UC_CATEGORY_N +#define UC_DECIMAL_DIGIT_NUMBER UC_CATEGORY_Nd +#define UC_LETTER_NUMBER UC_CATEGORY_Nl +#define UC_OTHER_NUMBER UC_CATEGORY_No +#define UC_PUNCTUATION UC_CATEGORY_P +#define UC_CONNECTOR_PUNCTUATION UC_CATEGORY_Pc +#define UC_DASH_PUNCTUATION UC_CATEGORY_Pd +#define UC_OPEN_PUNCTUATION UC_CATEGORY_Ps /* a.k.a. UC_START_PUNCTUATION */ +#define UC_CLOSE_PUNCTUATION UC_CATEGORY_Pe /* a.k.a. UC_END_PUNCTUATION */ +#define UC_INITIAL_QUOTE_PUNCTUATION UC_CATEGORY_Pi +#define UC_FINAL_QUOTE_PUNCTUATION UC_CATEGORY_Pf +#define UC_OTHER_PUNCTUATION UC_CATEGORY_Po +#define UC_SYMBOL UC_CATEGORY_S +#define UC_MATH_SYMBOL UC_CATEGORY_Sm +#define UC_CURRENCY_SYMBOL UC_CATEGORY_Sc +#define UC_MODIFIER_SYMBOL UC_CATEGORY_Sk +#define UC_OTHER_SYMBOL UC_CATEGORY_So +#define UC_SEPARATOR UC_CATEGORY_Z +#define UC_SPACE_SEPARATOR UC_CATEGORY_Zs +#define UC_LINE_SEPARATOR UC_CATEGORY_Zl +#define UC_PARAGRAPH_SEPARATOR UC_CATEGORY_Zp +#define UC_OTHER UC_CATEGORY_C +#define UC_CONTROL UC_CATEGORY_Cc +#define UC_FORMAT UC_CATEGORY_Cf +#define UC_SURROGATE UC_CATEGORY_Cs /* all of them are invalid characters */ +#define UC_PRIVATE_USE UC_CATEGORY_Co +#define UC_UNASSIGNED UC_CATEGORY_Cn /* some of them are invalid characters */ + +/* Return the union of two general categories. + This corresponds to the unions of the two sets of characters. */ +extern uc_general_category_t + uc_general_category_or (uc_general_category_t category1, + uc_general_category_t category2); + +/* Return the intersection of two general categories as bit masks. + This *does*not* correspond to the intersection of the two sets of + characters. */ +extern uc_general_category_t + uc_general_category_and (uc_general_category_t category1, + uc_general_category_t category2); + +/* Return the intersection of a general category with the complement of a + second general category, as bit masks. + This *does*not* correspond to the intersection with complement, when + viewing the categories as sets of characters. */ +extern uc_general_category_t + uc_general_category_and_not (uc_general_category_t category1, + uc_general_category_t category2); + +/* Return the name of a general category. */ +extern const char * + uc_general_category_name (uc_general_category_t category) + _UC_ATTRIBUTE_PURE; + +/* Return the long name of a general category. */ +extern const char * + uc_general_category_long_name (uc_general_category_t category) + _UC_ATTRIBUTE_PURE; + +/* Return the general category given by name, e.g. "Lu", or by long name, + e.g. "Uppercase Letter". */ +extern uc_general_category_t + uc_general_category_byname (const char *category_name) + _UC_ATTRIBUTE_PURE; + +/* Return the general category of a Unicode character. */ +extern uc_general_category_t + uc_general_category (ucs4_t uc) + _UC_ATTRIBUTE_PURE; + +/* Test whether a Unicode character belongs to a given category. + The CATEGORY argument can be the combination of several predefined + general categories. */ +extern bool + uc_is_general_category (ucs4_t uc, uc_general_category_t category) + _UC_ATTRIBUTE_PURE; +/* Likewise. This function uses a big table comprising all categories. */ +extern bool + uc_is_general_category_withtable (ucs4_t uc, uint32_t bitmask) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Field 3 of Unicode Character Database: Canonical combining class. */ + +/* The possible results of uc_combining_class (0..255) are described in + UCD.html. The list here is not definitive; more values can be added + in future versions. */ +enum +{ + UC_CCC_NR = 0, /* Not Reordered */ + UC_CCC_OV = 1, /* Overlay */ + UC_CCC_NK = 7, /* Nukta */ + UC_CCC_KV = 8, /* Kana Voicing */ + UC_CCC_VR = 9, /* Virama */ + UC_CCC_ATBL = 200, /* Attached Below Left */ + UC_CCC_ATB = 202, /* Attached Below */ + UC_CCC_ATA = 214, /* Attached Above */ + UC_CCC_ATAR = 216, /* Attached Above Right */ + UC_CCC_BL = 218, /* Below Left */ + UC_CCC_B = 220, /* Below */ + UC_CCC_BR = 222, /* Below Right */ + UC_CCC_L = 224, /* Left */ + UC_CCC_R = 226, /* Right */ + UC_CCC_AL = 228, /* Above Left */ + UC_CCC_A = 230, /* Above */ + UC_CCC_AR = 232, /* Above Right */ + UC_CCC_DB = 233, /* Double Below */ + UC_CCC_DA = 234, /* Double Above */ + UC_CCC_IS = 240 /* Iota Subscript */ +}; + +/* Return the canonical combining class of a Unicode character. */ +extern int + uc_combining_class (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Return the name of a canonical combining class. */ +extern const char * + uc_combining_class_name (int ccc) + _UC_ATTRIBUTE_CONST; + +/* Return the long name of a canonical combining class. */ +extern const char * + uc_combining_class_long_name (int ccc) + _UC_ATTRIBUTE_CONST; + +/* Return the canonical combining class given by name, e.g. "BL", or by long + name, e.g. "Below Left". */ +extern int + uc_combining_class_byname (const char *ccc_name) + _UC_ATTRIBUTE_PURE; + +/* ========================================================================= */ + +/* Field 4 of Unicode Character Database: Bidi class. + Before Unicode 4.0, this field was called "Bidirectional category". */ + +enum +{ + UC_BIDI_L, /* Left-to-Right */ + UC_BIDI_LRE, /* Left-to-Right Embedding */ + UC_BIDI_LRO, /* Left-to-Right Override */ + UC_BIDI_R, /* Right-to-Left */ + UC_BIDI_AL, /* Right-to-Left Arabic */ + UC_BIDI_RLE, /* Right-to-Left Embedding */ + UC_BIDI_RLO, /* Right-to-Left Override */ + UC_BIDI_PDF, /* Pop Directional Format */ + UC_BIDI_EN, /* European Number */ + UC_BIDI_ES, /* European Number Separator */ + UC_BIDI_ET, /* European Number Terminator */ + UC_BIDI_AN, /* Arabic Number */ + UC_BIDI_CS, /* Common Number Separator */ + UC_BIDI_NSM, /* Non-Spacing Mark */ + UC_BIDI_BN, /* Boundary Neutral */ + UC_BIDI_B, /* Paragraph Separator */ + UC_BIDI_S, /* Segment Separator */ + UC_BIDI_WS, /* Whitespace */ + UC_BIDI_ON, /* Other Neutral */ + UC_BIDI_LRI, /* Left-to-Right Isolate */ + UC_BIDI_RLI, /* Right-to-Left Isolate */ + UC_BIDI_FSI, /* First Strong Isolate */ + UC_BIDI_PDI /* Pop Directional Isolate */ +}; + +/* Return the name of a bidi class. */ +extern const char * + uc_bidi_class_name (int bidi_class) + _UC_ATTRIBUTE_CONST; +/* Same; obsolete function name. */ +extern const char * + uc_bidi_category_name (int category) + _UC_ATTRIBUTE_CONST; + +/* Return the long name of a bidi class. */ +extern const char * + uc_bidi_class_long_name (int bidi_class) + _UC_ATTRIBUTE_CONST; + +/* Return the bidi class given by name, e.g. "LRE", or by long name, e.g. + "Left-to-Right Embedding". */ +extern int + uc_bidi_class_byname (const char *bidi_class_name) + _UC_ATTRIBUTE_PURE; +/* Same; obsolete function name. */ +extern int + uc_bidi_category_byname (const char *category_name) + _UC_ATTRIBUTE_PURE; + +/* Return the bidi class of a Unicode character. */ +extern int + uc_bidi_class (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +/* Same; obsolete function name. */ +extern int + uc_bidi_category (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test whether a Unicode character belongs to a given bidi class. */ +extern bool + uc_is_bidi_class (ucs4_t uc, int bidi_class) + _UC_ATTRIBUTE_CONST; +/* Same; obsolete function name. */ +extern bool + uc_is_bidi_category (ucs4_t uc, int category) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Field 5 of Unicode Character Database: Character decomposition mapping. + See "uninorm.h". */ + +/* ========================================================================= */ + +/* Field 6 of Unicode Character Database: Decimal digit value. */ + +/* Return the decimal digit value of a Unicode character. */ +extern int + uc_decimal_value (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Field 7 of Unicode Character Database: Digit value. */ + +/* Return the digit value of a Unicode character. */ +extern int + uc_digit_value (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Field 8 of Unicode Character Database: Numeric value. */ + +/* Return the numeric value of a Unicode character. */ +typedef struct +{ + int numerator; + int denominator; +} +uc_fraction_t; +extern uc_fraction_t + uc_numeric_value (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Field 9 of Unicode Character Database: Mirrored. */ + +/* Return the mirrored character of a Unicode character UC in *PUC. */ +extern bool + uc_mirror_char (ucs4_t uc, ucs4_t *puc); + +/* ========================================================================= */ + +/* Field 10 of Unicode Character Database: Unicode 1.0 Name. + Not available in this library. */ + +/* ========================================================================= */ + +/* Field 11 of Unicode Character Database: ISO 10646 comment. + Not available in this library. */ + +/* ========================================================================= */ + +/* Field 12, 13, 14 of Unicode Character Database: Uppercase mapping, + lowercase mapping, titlecase mapping. See "unicase.h". */ + +/* ========================================================================= */ + +/* Field 2 of the file ArabicShaping.txt in the Unicode Character Database. */ + +/* Possible joining types. */ +enum +{ + UC_JOINING_TYPE_U, /* Non_Joining */ + UC_JOINING_TYPE_T, /* Transparent */ + UC_JOINING_TYPE_C, /* Join_Causing */ + UC_JOINING_TYPE_L, /* Left_Joining */ + UC_JOINING_TYPE_R, /* Right_Joining */ + UC_JOINING_TYPE_D /* Dual_Joining */ +}; + +/* Return the name of a joining type. */ +extern const char * + uc_joining_type_name (int joining_type) + _UC_ATTRIBUTE_CONST; + +/* Return the long name of a joining type. */ +extern const char * + uc_joining_type_long_name (int joining_type) + _UC_ATTRIBUTE_CONST; + +/* Return the joining type given by name, e.g. "D", or by long name, e.g. + "Dual Joining". */ +extern int + uc_joining_type_byname (const char *joining_type_name) + _UC_ATTRIBUTE_PURE; + +/* Return the joining type of a Unicode character. */ +extern int + uc_joining_type (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Field 3 of the file ArabicShaping.txt in the Unicode Character Database. */ + +/* Possible joining groups. + This enumeration may be extended in the future. */ +enum +{ + UC_JOINING_GROUP_NONE, /* No_Joining_Group */ + UC_JOINING_GROUP_AIN, /* Ain */ + UC_JOINING_GROUP_ALAPH, /* Alaph */ + UC_JOINING_GROUP_ALEF, /* Alef */ + UC_JOINING_GROUP_BEH, /* Beh */ + UC_JOINING_GROUP_BETH, /* Beth */ + UC_JOINING_GROUP_BURUSHASKI_YEH_BARREE, /* Burushaski_Yeh_Barree */ + UC_JOINING_GROUP_DAL, /* Dal */ + UC_JOINING_GROUP_DALATH_RISH, /* Dalath_Rish */ + UC_JOINING_GROUP_E, /* E */ + UC_JOINING_GROUP_FARSI_YEH, /* Farsi_Yeh */ + UC_JOINING_GROUP_FE, /* Fe */ + UC_JOINING_GROUP_FEH, /* Feh */ + UC_JOINING_GROUP_FINAL_SEMKATH, /* Final_Semkath */ + UC_JOINING_GROUP_GAF, /* Gaf */ + UC_JOINING_GROUP_GAMAL, /* Gamal */ + UC_JOINING_GROUP_HAH, /* Hah */ + UC_JOINING_GROUP_HE, /* He */ + UC_JOINING_GROUP_HEH, /* Heh */ + UC_JOINING_GROUP_HEH_GOAL, /* Heh_Goal */ + UC_JOINING_GROUP_HETH, /* Heth */ + UC_JOINING_GROUP_KAF, /* Kaf */ + UC_JOINING_GROUP_KAPH, /* Kaph */ + UC_JOINING_GROUP_KHAPH, /* Khaph */ + UC_JOINING_GROUP_KNOTTED_HEH, /* Knotted_Heh */ + UC_JOINING_GROUP_LAM, /* Lam */ + UC_JOINING_GROUP_LAMADH, /* Lamadh */ + UC_JOINING_GROUP_MEEM, /* Meem */ + UC_JOINING_GROUP_MIM, /* Mim */ + UC_JOINING_GROUP_NOON, /* Noon */ + UC_JOINING_GROUP_NUN, /* Nun */ + UC_JOINING_GROUP_NYA, /* Nya */ + UC_JOINING_GROUP_PE, /* Pe */ + UC_JOINING_GROUP_QAF, /* Qaf */ + UC_JOINING_GROUP_QAPH, /* Qaph */ + UC_JOINING_GROUP_REH, /* Reh */ + UC_JOINING_GROUP_REVERSED_PE, /* Reversed_Pe */ + UC_JOINING_GROUP_SAD, /* Sad */ + UC_JOINING_GROUP_SADHE, /* Sadhe */ + UC_JOINING_GROUP_SEEN, /* Seen */ + UC_JOINING_GROUP_SEMKATH, /* Semkath */ + UC_JOINING_GROUP_SHIN, /* Shin */ + UC_JOINING_GROUP_SWASH_KAF, /* Swash_Kaf */ + UC_JOINING_GROUP_SYRIAC_WAW, /* Syriac_Waw */ + UC_JOINING_GROUP_TAH, /* Tah */ + UC_JOINING_GROUP_TAW, /* Taw */ + UC_JOINING_GROUP_TEH_MARBUTA, /* Teh_Marbuta */ + UC_JOINING_GROUP_TEH_MARBUTA_GOAL, /* Teh_Marbuta_Goal */ + UC_JOINING_GROUP_TETH, /* Teth */ + UC_JOINING_GROUP_WAW, /* Waw */ + UC_JOINING_GROUP_YEH, /* Yeh */ + UC_JOINING_GROUP_YEH_BARREE, /* Yeh_Barree */ + UC_JOINING_GROUP_YEH_WITH_TAIL, /* Yeh_With_Tail */ + UC_JOINING_GROUP_YUDH, /* Yudh */ + UC_JOINING_GROUP_YUDH_HE, /* Yudh_He */ + UC_JOINING_GROUP_ZAIN, /* Zain */ + UC_JOINING_GROUP_ZHAIN, /* Zhain */ + UC_JOINING_GROUP_ROHINGYA_YEH, /* Rohingya_Yeh */ + UC_JOINING_GROUP_STRAIGHT_WAW, /* Straight_Waw */ + UC_JOINING_GROUP_MANICHAEAN_ALEPH, /* Manichaean_Aleph */ + UC_JOINING_GROUP_MANICHAEAN_BETH, /* Manichaean_Beth */ + UC_JOINING_GROUP_MANICHAEAN_GIMEL, /* Manichaean_Gimel */ + UC_JOINING_GROUP_MANICHAEAN_DALETH, /* Manichaean_Daleth */ + UC_JOINING_GROUP_MANICHAEAN_WAW, /* Manichaean_Waw */ + UC_JOINING_GROUP_MANICHAEAN_ZAYIN, /* Manichaean_Zayin */ + UC_JOINING_GROUP_MANICHAEAN_HETH, /* Manichaean_Heth */ + UC_JOINING_GROUP_MANICHAEAN_TETH, /* Manichaean_Teth */ + UC_JOINING_GROUP_MANICHAEAN_YODH, /* Manichaean_Yodh */ + UC_JOINING_GROUP_MANICHAEAN_KAPH, /* Manichaean_Kaph */ + UC_JOINING_GROUP_MANICHAEAN_LAMEDH, /* Manichaean_Lamedh */ + UC_JOINING_GROUP_MANICHAEAN_DHAMEDH, /* Manichaean_Dhamedh */ + UC_JOINING_GROUP_MANICHAEAN_THAMEDH, /* Manichaean_Thamedh */ + UC_JOINING_GROUP_MANICHAEAN_MEM, /* Manichaean_Mem */ + UC_JOINING_GROUP_MANICHAEAN_NUN, /* Manichaean_Nun */ + UC_JOINING_GROUP_MANICHAEAN_SAMEKH, /* Manichaean_Aleph */ + UC_JOINING_GROUP_MANICHAEAN_AYIN, /* Manichaean_Ayin */ + UC_JOINING_GROUP_MANICHAEAN_PE, /* Manichaean_Pe */ + UC_JOINING_GROUP_MANICHAEAN_SADHE, /* Manichaean_Sadhe */ + UC_JOINING_GROUP_MANICHAEAN_QOPH, /* Manichaean_Qoph */ + UC_JOINING_GROUP_MANICHAEAN_RESH, /* Manichaean_Resh */ + UC_JOINING_GROUP_MANICHAEAN_TAW, /* Manichaean_Taw */ + UC_JOINING_GROUP_MANICHAEAN_ONE, /* Manichaean_One */ + UC_JOINING_GROUP_MANICHAEAN_FIVE, /* Manichaean_Five */ + UC_JOINING_GROUP_MANICHAEAN_TEN, /* Manichaean_Ten */ + UC_JOINING_GROUP_MANICHAEAN_TWENTY, /* Manichaean_Twenty */ + UC_JOINING_GROUP_MANICHAEAN_HUNDRED, /* Manichaean_Hundred */ + UC_JOINING_GROUP_AFRICAN_FEH, /* African_Feh */ + UC_JOINING_GROUP_AFRICAN_QAF, /* African_Qaf */ + UC_JOINING_GROUP_AFRICAN_NOON, /* African_Noon */ + UC_JOINING_GROUP_MALAYALAM_NGA, /* Malayalam_Nga */ + UC_JOINING_GROUP_MALAYALAM_JA, /* Malayalam_Ja */ + UC_JOINING_GROUP_MALAYALAM_NYA, /* Malayalam_Nya */ + UC_JOINING_GROUP_MALAYALAM_TTA, /* Malayalam_Tta */ + UC_JOINING_GROUP_MALAYALAM_NNA, /* Malayalam_Nna */ + UC_JOINING_GROUP_MALAYALAM_NNNA, /* Malayalam_Nnna */ + UC_JOINING_GROUP_MALAYALAM_BHA, /* Malayalam_Bha */ + UC_JOINING_GROUP_MALAYALAM_RA, /* Malayalam_Ra */ + UC_JOINING_GROUP_MALAYALAM_LLA, /* Malayalam_Lla */ + UC_JOINING_GROUP_MALAYALAM_LLLA, /* Malayalam_Llla */ + UC_JOINING_GROUP_MALAYALAM_SSA, /* Malayalam_Ssa */ + UC_JOINING_GROUP_HANIFI_ROHINGYA_PA, /* Hanifi_Rohingya_Pa */ + UC_JOINING_GROUP_HANIFI_ROHINGYA_KINNA_YA, /* Hanifi_Rohingya_Kinna_Ya */ + UC_JOINING_GROUP_THIN_YEH, /* Thin_Yeh */ + UC_JOINING_GROUP_VERTICAL_TAIL /* Vertical_Tail */ +}; + +/* Return the name of a joining group. */ +extern const char * + uc_joining_group_name (int joining_group) + _UC_ATTRIBUTE_CONST; + +/* Return the joining group given by name, e.g. "Teh_Marbuta". */ +extern int + uc_joining_group_byname (const char *joining_group_name) + _UC_ATTRIBUTE_PURE; + +/* Return the joining group of a Unicode character. */ +extern int + uc_joining_group (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Common API for properties. */ + +/* Data type denoting a property. This is not just a number, but rather a + pointer to the test functions, so that programs that use only few of the + properties don't have a link-time dependency towards all the tables. */ +typedef struct +{ + bool (*test_fn) (ucs4_t uc); +} +uc_property_t; + +/* Predefined properties. */ +/* General. */ +extern const uc_property_t UC_PROPERTY_WHITE_SPACE; +extern const uc_property_t UC_PROPERTY_ALPHABETIC; +extern const uc_property_t UC_PROPERTY_OTHER_ALPHABETIC; +extern const uc_property_t UC_PROPERTY_NOT_A_CHARACTER; +extern const uc_property_t UC_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT; +extern const uc_property_t UC_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT; +extern const uc_property_t UC_PROPERTY_DEPRECATED; +extern const uc_property_t UC_PROPERTY_LOGICAL_ORDER_EXCEPTION; +extern const uc_property_t UC_PROPERTY_VARIATION_SELECTOR; +extern const uc_property_t UC_PROPERTY_PRIVATE_USE; +extern const uc_property_t UC_PROPERTY_UNASSIGNED_CODE_VALUE; +/* Case. */ +extern const uc_property_t UC_PROPERTY_UPPERCASE; +extern const uc_property_t UC_PROPERTY_OTHER_UPPERCASE; +extern const uc_property_t UC_PROPERTY_LOWERCASE; +extern const uc_property_t UC_PROPERTY_OTHER_LOWERCASE; +extern const uc_property_t UC_PROPERTY_TITLECASE; +extern const uc_property_t UC_PROPERTY_CASED; +extern const uc_property_t UC_PROPERTY_CASE_IGNORABLE; +extern const uc_property_t UC_PROPERTY_CHANGES_WHEN_LOWERCASED; +extern const uc_property_t UC_PROPERTY_CHANGES_WHEN_UPPERCASED; +extern const uc_property_t UC_PROPERTY_CHANGES_WHEN_TITLECASED; +extern const uc_property_t UC_PROPERTY_CHANGES_WHEN_CASEFOLDED; +extern const uc_property_t UC_PROPERTY_CHANGES_WHEN_CASEMAPPED; +extern const uc_property_t UC_PROPERTY_SOFT_DOTTED; +/* Identifiers. */ +extern const uc_property_t UC_PROPERTY_ID_START; +extern const uc_property_t UC_PROPERTY_OTHER_ID_START; +extern const uc_property_t UC_PROPERTY_ID_CONTINUE; +extern const uc_property_t UC_PROPERTY_OTHER_ID_CONTINUE; +extern const uc_property_t UC_PROPERTY_XID_START; +extern const uc_property_t UC_PROPERTY_XID_CONTINUE; +extern const uc_property_t UC_PROPERTY_PATTERN_WHITE_SPACE; +extern const uc_property_t UC_PROPERTY_PATTERN_SYNTAX; +/* Shaping and rendering. */ +extern const uc_property_t UC_PROPERTY_JOIN_CONTROL; +extern const uc_property_t UC_PROPERTY_GRAPHEME_BASE; +extern const uc_property_t UC_PROPERTY_GRAPHEME_EXTEND; +extern const uc_property_t UC_PROPERTY_OTHER_GRAPHEME_EXTEND; +extern const uc_property_t UC_PROPERTY_GRAPHEME_LINK; +/* Bidi. */ +extern const uc_property_t UC_PROPERTY_BIDI_CONTROL; +extern const uc_property_t UC_PROPERTY_BIDI_LEFT_TO_RIGHT; +extern const uc_property_t UC_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT; +extern const uc_property_t UC_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT; +extern const uc_property_t UC_PROPERTY_BIDI_EUROPEAN_DIGIT; +extern const uc_property_t UC_PROPERTY_BIDI_EUR_NUM_SEPARATOR; +extern const uc_property_t UC_PROPERTY_BIDI_EUR_NUM_TERMINATOR; +extern const uc_property_t UC_PROPERTY_BIDI_ARABIC_DIGIT; +extern const uc_property_t UC_PROPERTY_BIDI_COMMON_SEPARATOR; +extern const uc_property_t UC_PROPERTY_BIDI_BLOCK_SEPARATOR; +extern const uc_property_t UC_PROPERTY_BIDI_SEGMENT_SEPARATOR; +extern const uc_property_t UC_PROPERTY_BIDI_WHITESPACE; +extern const uc_property_t UC_PROPERTY_BIDI_NON_SPACING_MARK; +extern const uc_property_t UC_PROPERTY_BIDI_BOUNDARY_NEUTRAL; +extern const uc_property_t UC_PROPERTY_BIDI_PDF; +extern const uc_property_t UC_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE; +extern const uc_property_t UC_PROPERTY_BIDI_OTHER_NEUTRAL; +/* Numeric. */ +extern const uc_property_t UC_PROPERTY_HEX_DIGIT; +extern const uc_property_t UC_PROPERTY_ASCII_HEX_DIGIT; +/* CJK. */ +extern const uc_property_t UC_PROPERTY_IDEOGRAPHIC; +extern const uc_property_t UC_PROPERTY_UNIFIED_IDEOGRAPH; +extern const uc_property_t UC_PROPERTY_RADICAL; +extern const uc_property_t UC_PROPERTY_IDS_BINARY_OPERATOR; +extern const uc_property_t UC_PROPERTY_IDS_TRINARY_OPERATOR; +/* Emoji. */ +extern const uc_property_t UC_PROPERTY_EMOJI; +extern const uc_property_t UC_PROPERTY_EMOJI_PRESENTATION; +extern const uc_property_t UC_PROPERTY_EMOJI_MODIFIER; +extern const uc_property_t UC_PROPERTY_EMOJI_MODIFIER_BASE; +extern const uc_property_t UC_PROPERTY_EMOJI_COMPONENT; +extern const uc_property_t UC_PROPERTY_EXTENDED_PICTOGRAPHIC; +/* Misc. */ +extern const uc_property_t UC_PROPERTY_ZERO_WIDTH; +extern const uc_property_t UC_PROPERTY_SPACE; +extern const uc_property_t UC_PROPERTY_NON_BREAK; +extern const uc_property_t UC_PROPERTY_ISO_CONTROL; +extern const uc_property_t UC_PROPERTY_FORMAT_CONTROL; +extern const uc_property_t UC_PROPERTY_DASH; +extern const uc_property_t UC_PROPERTY_HYPHEN; +extern const uc_property_t UC_PROPERTY_PUNCTUATION; +extern const uc_property_t UC_PROPERTY_LINE_SEPARATOR; +extern const uc_property_t UC_PROPERTY_PARAGRAPH_SEPARATOR; +extern const uc_property_t UC_PROPERTY_QUOTATION_MARK; +extern const uc_property_t UC_PROPERTY_SENTENCE_TERMINAL; +extern const uc_property_t UC_PROPERTY_TERMINAL_PUNCTUATION; +extern const uc_property_t UC_PROPERTY_CURRENCY_SYMBOL; +extern const uc_property_t UC_PROPERTY_MATH; +extern const uc_property_t UC_PROPERTY_OTHER_MATH; +extern const uc_property_t UC_PROPERTY_PAIRED_PUNCTUATION; +extern const uc_property_t UC_PROPERTY_LEFT_OF_PAIR; +extern const uc_property_t UC_PROPERTY_COMBINING; +extern const uc_property_t UC_PROPERTY_COMPOSITE; +extern const uc_property_t UC_PROPERTY_DECIMAL_DIGIT; +extern const uc_property_t UC_PROPERTY_NUMERIC; +extern const uc_property_t UC_PROPERTY_DIACRITIC; +extern const uc_property_t UC_PROPERTY_EXTENDER; +extern const uc_property_t UC_PROPERTY_IGNORABLE_CONTROL; +extern const uc_property_t UC_PROPERTY_REGIONAL_INDICATOR; + +/* Return the property given by name, e.g. "White space". */ +extern uc_property_t + uc_property_byname (const char *property_name); + +/* Test whether a property is valid. */ +#define uc_property_is_valid(property) ((property).test_fn != NULL) + +/* Test whether a Unicode character has a given property. */ +extern bool + uc_is_property (ucs4_t uc, uc_property_t property); +extern bool uc_is_property_white_space (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_alphabetic (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_alphabetic (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_not_a_character (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_default_ignorable_code_point (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_default_ignorable_code_point (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_deprecated (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_logical_order_exception (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_variation_selector (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_private_use (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_unassigned_code_value (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_uppercase (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_uppercase (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_lowercase (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_lowercase (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_titlecase (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_cased (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_case_ignorable (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_changes_when_lowercased (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_changes_when_uppercased (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_changes_when_titlecased (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_changes_when_casefolded (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_changes_when_casemapped (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_soft_dotted (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_id_start (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_id_start (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_id_continue (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_id_continue (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_xid_start (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_xid_continue (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_pattern_white_space (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_pattern_syntax (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_join_control (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_grapheme_base (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_grapheme_extend (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_grapheme_extend (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_grapheme_link (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_control (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_left_to_right (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_hebrew_right_to_left (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_arabic_right_to_left (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_european_digit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_eur_num_separator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_eur_num_terminator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_arabic_digit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_common_separator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_block_separator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_segment_separator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_whitespace (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_non_spacing_mark (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_boundary_neutral (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_pdf (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_embedding_or_override (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_bidi_other_neutral (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_hex_digit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_ascii_hex_digit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_ideographic (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_unified_ideograph (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_radical (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_ids_binary_operator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_ids_trinary_operator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_emoji (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_emoji_presentation (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_emoji_modifier (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_emoji_modifier_base (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_emoji_component (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_extended_pictographic (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_zero_width (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_space (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_non_break (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_iso_control (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_format_control (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_dash (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_hyphen (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_punctuation (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_line_separator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_paragraph_separator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_quotation_mark (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_sentence_terminal (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_terminal_punctuation (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_currency_symbol (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_math (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_other_math (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_paired_punctuation (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_left_of_pair (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_combining (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_composite (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_decimal_digit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_numeric (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_diacritic (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_extender (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_ignorable_control (ucs4_t uc) + _UC_ATTRIBUTE_CONST; +extern bool uc_is_property_regional_indicator (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Subdivision of the Unicode characters into scripts. */ + +typedef struct +{ + unsigned int code : 21; + unsigned int start : 1; + unsigned int end : 1; +} +uc_interval_t; +typedef struct +{ + unsigned int nintervals; + const uc_interval_t *intervals; + const char *name; +} +uc_script_t; + +/* Return the script of a Unicode character. */ +extern const uc_script_t * + uc_script (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Return the script given by name, e.g. "HAN". */ +extern const uc_script_t * + uc_script_byname (const char *script_name) + _UC_ATTRIBUTE_PURE; + +/* Test whether a Unicode character belongs to a given script. */ +extern bool + uc_is_script (ucs4_t uc, const uc_script_t *script) + _UC_ATTRIBUTE_PURE; + +/* Get the list of all scripts. */ +extern void + uc_all_scripts (const uc_script_t **scripts, size_t *count); + +/* ========================================================================= */ + +/* Subdivision of the Unicode character range into blocks. */ + +typedef struct +{ + ucs4_t start; + ucs4_t end; + const char *name; +} +uc_block_t; + +/* Return the block a character belongs to. */ +extern const uc_block_t * + uc_block (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test whether a Unicode character belongs to a given block. */ +extern bool + uc_is_block (ucs4_t uc, const uc_block_t *block) + _UC_ATTRIBUTE_PURE; + +/* Get the list of all blocks. */ +extern void + uc_all_blocks (const uc_block_t **blocks, size_t *count); + +/* ========================================================================= */ + +/* Properties taken from language standards. */ + +/* Test whether a Unicode character is considered whitespace in ISO C 99. */ +extern bool + uc_is_c_whitespace (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test whether a Unicode character is considered whitespace in Java. */ +extern bool + uc_is_java_whitespace (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +enum +{ + UC_IDENTIFIER_START, /* valid as first or subsequent character */ + UC_IDENTIFIER_VALID, /* valid as subsequent character only */ + UC_IDENTIFIER_INVALID, /* not valid */ + UC_IDENTIFIER_IGNORABLE /* ignorable (Java only) */ +}; + +/* Return the categorization of a Unicode character w.r.t. the ISO C 99 + identifier syntax. */ +extern int + uc_c_ident_category (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Return the categorization of a Unicode character w.r.t. the Java + identifier syntax. */ +extern int + uc_java_ident_category (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +/* Like ISO C and . These functions are deprecated, + because this set of functions was designed with ASCII in mind and cannot + reflect the more diverse reality of the Unicode character set. But they + can be a quick-and-dirty porting aid when migrating from wchar_t APIs + to Unicode strings. */ + +/* Test for any character for which 'uc_is_alpha' or 'uc_is_digit' is true. */ +extern bool + uc_is_alnum (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character for which 'uc_is_upper' or 'uc_is_lower' is true, + or any character that is one of a locale-specific set of characters for + which none of 'uc_is_cntrl', 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' + is true. */ +extern bool + uc_is_alpha (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any control character. */ +extern bool + uc_is_cntrl (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character that corresponds to a decimal-digit character. */ +extern bool + uc_is_digit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character for which 'uc_is_print' is true and 'uc_is_space' + is false. */ +extern bool + uc_is_graph (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character that corresponds to a lowercase letter or is one + of a locale-specific set of characters for which none of 'uc_is_cntrl', + 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' is true. */ +extern bool + uc_is_lower (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any printing character. */ +extern bool + uc_is_print (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any printing character that is one of a locale-specific set of + characters for which neither 'uc_is_space' nor 'uc_is_alnum' is true. */ +extern bool + uc_is_punct (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character that corresponds to a locale-specific set of + characters for which none of 'uc_is_alnum', 'uc_is_graph', or 'uc_is_punct' + is true. */ +extern bool + uc_is_space (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character that corresponds to an uppercase letter or is one + of a locale-specific set of character for which none of 'uc_is_cntrl', + 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' is true. */ +extern bool + uc_is_upper (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* Test for any character that corresponds to a hexadecimal-digit + character. */ +extern bool + uc_is_xdigit (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* GNU extension. */ +/* Test for any character that corresponds to a standard blank character or + a locale-specific set of characters for which 'uc_is_alnum' is false. */ +extern bool + uc_is_blank (ucs4_t uc) + _UC_ATTRIBUTE_CONST; + +/* ========================================================================= */ + +#ifdef __cplusplus +} +#endif + +#endif /* _UNICTYPE_H */ diff --git a/lib/unictype/bitmap.h b/lib/unictype/bitmap.h new file mode 100644 index 0000000..5bd4636 --- /dev/null +++ b/lib/unictype/bitmap.h @@ -0,0 +1,48 @@ +/* Three-level bitmap lookup. + Copyright (C) 2000-2002, 2005-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2000-2002. + + 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 . */ + +static inline int bitmap_lookup (const void *table, ucs4_t uc); + +/* These values are currently hardcoded into gen-uni-tables.c, function + output_predicate(). */ +#define header_0 16 +#define header_2 9 +#define header_3 127 +#define header_4 15 + +static inline int +bitmap_lookup (const void *table, ucs4_t uc) +{ + unsigned int index1 = uc >> header_0; + if (index1 < ((const int *) table)[0]) + { + int lookup1 = ((const int *) table)[1 + index1]; + if (lookup1 >= 0) + { + unsigned int index2 = (uc >> header_2) & header_3; + int lookup2 = ((const short *) table)[lookup1 + index2]; + if (lookup2 >= 0) + { + unsigned int index3 = (uc >> 5) & header_4; + unsigned int lookup3 = ((const unsigned int *) table)[lookup2 + index3]; + + return (lookup3 >> (uc & 0x1f)) & 1; + } + } + } + return 0; +} diff --git a/lib/unictype/combiningclass.c b/lib/unictype/combiningclass.c new file mode 100644 index 0000000..4c691d5 --- /dev/null +++ b/lib/unictype/combiningclass.c @@ -0,0 +1,47 @@ +/* Combining classes of Unicode characters. + Copyright (C) 2002, 2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 "unictype.h" + +/* Define u_combclass table. */ +#include "combiningclass.h" + +int +uc_combining_class (ucs4_t uc) +{ + unsigned int index1 = uc >> combclass_header_0; + if (index1 < combclass_header_1) + { + int lookup1 = u_combclass.level1[index1]; + if (lookup1 >= 0) + { + unsigned int index2 = (uc >> combclass_header_2) & combclass_header_3; + int lookup2 = u_combclass.level2[lookup1 + index2]; + if (lookup2 >= 0) + { + unsigned int index3 = (uc & combclass_header_4); + unsigned int lookup3 = u_combclass.level3[lookup2 + index3]; + + return lookup3; + } + } + } + return 0; +} diff --git a/lib/unictype/combiningclass.h b/lib/unictype/combiningclass.h new file mode 100644 index 0000000..e6cb6fe --- /dev/null +++ b/lib/unictype/combiningclass.h @@ -0,0 +1,1591 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Combining class of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-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 . */ + +#define combclass_header_0 16 +#define combclass_header_1 2 +#define combclass_header_2 7 +#define combclass_header_3 511 +#define combclass_header_4 127 +static const +struct + { + int level1[2]; + short level2[2 << 9]; + unsigned char level3[89 << 7]; + } +u_combclass = +{ + { 0, 512 }, + { + -1, -1, -1, -1, -1, -1, 0, -1, + -1, 128, -1, 256, 384, 512, 640, 768, + 896, 1024, 1152, 1280, 1408, 1408, 1408, 1536, + 1664, 1408, 1792, 1920, 2048, 2176, 2304, 2432, + 2560, 2688, -1, -1, -1, -1, 2816, -1, + -1, -1, -1, -1, -1, -1, 2944, 3072, + -1, 3200, 3328, -1, 3456, 3584, 3712, 3840, + 3968, 4096, -1, 4224, -1, -1, -1, -1, + -1, 4352, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4480, 4608, 4736, -1, -1, -1, -1, + 4864, 4992, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 5120, 5248, -1, -1, + 5376, 5504, 5632, 5760, -1, 5888, -1, 6016, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 6144, -1, + -1, -1, -1, -1, 6272, -1, -1, -1, + -1, -1, -1, 6400, -1, 6528, 6656, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 6784, 6912, -1, -1, + -1, -1, 7040, -1, -1, 7168, 7296, 7424, + 7552, 7680, 7808, 7936, 8064, 8192, 8320, -1, + 8448, 8576, -1, 8704, 8832, 8960, 9088, -1, + 7680, -1, 9216, 9344, 9472, 9600, -1, -1, + 8832, -1, 9728, 9856, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 9984, 10112, -1, + -1, -1, -1, -1, -1, -1, -1, 10240, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10368, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 10496, 10624, 10752, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 10880, -1, 10112, -1, -1, 11008, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 11136, 11264, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, + { + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 232, 220, 220, + 220, 220, 232, 216, 220, 220, 220, 220, + 220, 202, 202, 220, 220, 220, 220, 202, + 202, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 220, 1, 1, 1, 1, + 1, 220, 220, 220, 220, 230, 230, 230, + 230, 230, 230, 230, 230, 240, 230, 220, + 220, 220, 230, 230, 230, 220, 220, 0, + 230, 230, 230, 220, 220, 220, 220, 230, + 232, 220, 220, 230, 233, 234, 234, 233, + 234, 234, 233, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 230, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 230, 230, 230, 230, 220, 230, + 230, 230, 222, 220, 230, 230, 230, 230, + 230, 230, 220, 220, 220, 220, 220, 220, + 230, 230, 220, 230, 230, 222, 228, 230, + 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 19, 20, 21, 22, 0, 23, + 0, 24, 25, 0, 230, 220, 0, 18, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 230, 230, + 30, 31, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34, 230, 230, 220, 220, 230, + 230, 230, 230, 230, 220, 230, 230, 220, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 230, + 230, 230, 230, 230, 230, 0, 0, 230, + 230, 230, 230, 220, 230, 0, 0, 230, + 230, 0, 220, 230, 230, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 220, 230, 230, 220, 230, 230, 220, + 220, 220, 230, 220, 220, 230, 220, 230, + 230, 230, 220, 230, 220, 230, 220, 230, + 220, 230, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 230, 230, 230, 230, 230, + 230, 230, 220, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 230, + 230, 230, 0, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 0, 230, 230, 230, + 0, 230, 230, 230, 230, 230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 220, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 220, 220, 220, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 230, 230, 230, 230, 220, + 220, 220, 220, 220, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 0, 220, 230, 230, 220, 230, + 230, 220, 230, 230, 230, 220, 220, 220, + 27, 28, 29, 230, 230, 230, 220, 230, + 230, 220, 220, 230, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 230, 220, 230, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 84, 91, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 103, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 118, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 122, 122, 122, 122, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 220, 220, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 220, 0, 220, + 0, 216, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 129, 130, 0, 132, 0, 0, 0, + 0, 0, 130, 130, 130, 130, 0, 0, + 130, 0, 230, 230, 9, 0, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, + 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 222, 230, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 230, + 220, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 230, 230, + 230, 230, 230, 230, 230, 0, 0, 220, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 220, 220, 220, + 220, 220, 220, 230, 230, 220, 0, 220, + 220, 230, 230, 220, 220, 230, 230, 230, + 230, 230, 220, 230, 230, 230, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 230, 220, 230, 230, 230, + 230, 230, 230, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 0, 1, 220, 220, 220, + 220, 220, 230, 230, 220, 220, 220, 220, + 230, 0, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 220, 0, 0, + 0, 0, 0, 0, 230, 0, 0, 0, + 230, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 220, 230, 230, 230, 230, 230, + 230, 230, 220, 230, 230, 234, 214, 220, + 202, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 232, 228, + 228, 220, 218, 230, 233, 220, 230, 220, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 1, 1, 230, 230, 230, 230, + 1, 1, 1, 230, 230, 0, 0, 0, + 0, 230, 0, 0, 0, 1, 1, 230, + 220, 230, 1, 1, 220, 220, 220, 220, + 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 230, + 230, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 218, 228, 232, 222, 224, 224, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 230, + 0, 0, 0, 0, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 220, 220, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 0, 230, 230, 220, 0, 0, 230, + 230, 0, 0, 0, 0, 0, 230, 230, + 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 230, 220, + 220, 220, 220, 220, 220, 220, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 220, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 230, + 230, 230, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 220, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 1, 220, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 230, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 220, 220, + 230, 230, 230, 220, 230, 220, 220, 220, + 220, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 220, 230, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 230, + 230, 230, 230, 230, 230, 0, 0, 0, + 230, 230, 230, 230, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 0, + 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 216, 216, 1, + 1, 1, 0, 0, 0, 226, 216, 216, + 216, 216, 216, 0, 0, 0, 0, 0, + 0, 0, 0, 220, 220, 220, 220, 220, + 220, 220, 220, 0, 0, 230, 230, 230, + 230, 230, 220, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 230, 230, 230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 230, 230, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 230, 0, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 0, 0, 230, 230, 230, 230, 230, + 230, 230, 0, 230, 230, 0, 230, 230, + 230, 230, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 230, 230, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 220, 220, 220, 220, 220, 220, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 230, 230, 230, + 230, 230, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + } +}; diff --git a/lib/unictype/pr_soft_dotted.c b/lib/unictype/pr_soft_dotted.c new file mode 100644 index 0000000..daf812d --- /dev/null +++ b/lib/unictype/pr_soft_dotted.c @@ -0,0 +1,43 @@ +/* Properties of Unicode characters. + Copyright (C) 2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unictype.h" + +#include "bitmap.h" + +/* Define u_property_soft_dotted table. */ +#include "pr_soft_dotted.h" + +bool +uc_is_property_soft_dotted (ucs4_t uc) +{ + return bitmap_lookup (&u_property_soft_dotted, uc); +} + +const uc_property_t UC_PROPERTY_SOFT_DOTTED = + { &uc_is_property_soft_dotted }; diff --git a/lib/unictype/pr_soft_dotted.h b/lib/unictype/pr_soft_dotted.h new file mode 100644 index 0000000..529fa2a --- /dev/null +++ b/lib/unictype/pr_soft_dotted.h @@ -0,0 +1,347 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Properties of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#define header_0 16 +#define header_2 9 +#define header_3 127 +#define header_4 15 +static const +struct + { + int header[1]; + int level1[2]; + short level2[2 << 7]; + unsigned int level3[10 << 4]; + } +u_property_soft_dotted = +{ + { 2 }, + { + 3 * sizeof (int) / sizeof (short) + 0, + 3 * sizeof (int) / sizeof (short) + 128 + }, + { + 3 + 256 * sizeof (short) / sizeof (int) + 0, + 3 + 256 * sizeof (short) / sizeof (int) + 16, + 3 + 256 * sizeof (short) / sizeof (int) + 32, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 48, + 3 + 256 * sizeof (short) / sizeof (int) + 64, + 3 + 256 * sizeof (short) / sizeof (int) + 80, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 96, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 112, + 3 + 256 * sizeof (short) / sizeof (int) + 128, + -1, + -1, + -1, + 3 + 256 * sizeof (short) / sizeof (int) + 144, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + }, + { + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000600U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00008000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000200U, 0x00000100U, + 0x20000000U, 0x00040000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00080000U, + 0x00000000U, 0x00000000U, 0x01400000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000004U, + 0x00400000U, 0x00000110U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00002000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000800U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00020000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000300U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x10000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x0000000CU, 0x00C00000U, 0x00000000U, + 0x00000C00U, 0xC0000000U, 0x00000000U, 0x000C0000U, + 0x00000000U, 0x000000C0U, 0x0C000000U, 0x00000000U, + 0x0000C000U, 0x00000000U, 0x0000000CU, 0x00C00000U, + 0x00000000U, 0x00000C00U, 0xC0000000U, 0x00000000U, + 0x000C0000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x04000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U + } +}; diff --git a/lib/uninorm.in.h b/lib/uninorm.in.h new file mode 100644 index 0000000..fd6affb --- /dev/null +++ b/lib/uninorm.in.h @@ -0,0 +1,249 @@ +/* Normalization forms (composition and decomposition) of Unicode strings. + Copyright (C) 2001-2002, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 _UNINORM_H +#define _UNINORM_H + +/* Get size_t. */ +#include + +#include "unitypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Conventions: + + All functions prefixed with u8_ operate on UTF-8 encoded strings. + Their unit is an uint8_t (1 byte). + + All functions prefixed with u16_ operate on UTF-16 encoded strings. + Their unit is an uint16_t (a 2-byte word). + + All functions prefixed with u32_ operate on UCS-4 encoded strings. + Their unit is an uint32_t (a 4-byte word). + + All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly + n units. + + Functions returning a string result take a (resultbuf, lengthp) argument + pair. If resultbuf is not NULL and the result fits into *lengthp units, + it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly + allocated string is returned. In both cases, *lengthp is set to the + length (number of units) of the returned string. In case of error, + NULL is returned and errno is set. */ + + +enum +{ + UC_DECOMP_CANONICAL,/* Canonical decomposition. */ + UC_DECOMP_FONT, /* A font variant (e.g. a blackletter form). */ + UC_DECOMP_NOBREAK, /* A no-break version of a space or hyphen. */ + UC_DECOMP_INITIAL, /* An initial presentation form (Arabic). */ + UC_DECOMP_MEDIAL, /* A medial presentation form (Arabic). */ + UC_DECOMP_FINAL, /* A final presentation form (Arabic). */ + UC_DECOMP_ISOLATED,/* An isolated presentation form (Arabic). */ + UC_DECOMP_CIRCLE, /* An encircled form. */ + UC_DECOMP_SUPER, /* A superscript form. */ + UC_DECOMP_SUB, /* A subscript form. */ + UC_DECOMP_VERTICAL,/* A vertical layout presentation form. */ + UC_DECOMP_WIDE, /* A wide (or zenkaku) compatibility character. */ + UC_DECOMP_NARROW, /* A narrow (or hankaku) compatibility character. */ + UC_DECOMP_SMALL, /* A small variant form (CNS compatibility). */ + UC_DECOMP_SQUARE, /* A CJK squared font variant. */ + UC_DECOMP_FRACTION,/* A vulgar fraction form. */ + UC_DECOMP_COMPAT /* Otherwise unspecified compatibility character. */ +}; + +/* Maximum size of decomposition of a single Unicode character. */ +#define UC_DECOMPOSITION_MAX_LENGTH 32 + +/* Return the character decomposition mapping of a Unicode character. + DECOMPOSITION must point to an array of at least UC_DECOMPOSITION_MAX_LENGTH + ucs_t elements. + When a decomposition exists, DECOMPOSITION[0..N-1] and *DECOMP_TAG are + filled and N is returned. Otherwise -1 is returned. */ +extern int + uc_decomposition (ucs4_t uc, int *decomp_tag, ucs4_t *decomposition); + +/* Return the canonical character decomposition mapping of a Unicode character. + DECOMPOSITION must point to an array of at least UC_DECOMPOSITION_MAX_LENGTH + ucs_t elements. + When a decomposition exists, DECOMPOSITION[0..N-1] is filled and N is + returned. Otherwise -1 is returned. */ +extern int + uc_canonical_decomposition (ucs4_t uc, ucs4_t *decomposition); + + +/* Attempt to combine the Unicode characters uc1, uc2. + uc1 is known to have canonical combining class 0. + Return the combination of uc1 and uc2, if it exists. + Return 0 otherwise. + Not all decompositions can be recombined using this function. See the + Unicode file CompositionExclusions.txt for details. */ +extern ucs4_t + uc_composition (ucs4_t uc1, ucs4_t uc2) + _UC_ATTRIBUTE_CONST; + + +/* An object of type uninorm_t denotes a Unicode normalization form. */ +struct unicode_normalization_form; +typedef const struct unicode_normalization_form *uninorm_t; + +/* UNINORM_NFD: Normalization form D: canonical decomposition. */ +extern const struct unicode_normalization_form uninorm_nfd; +#define UNINORM_NFD (&uninorm_nfd) + +/* UNINORM_NFC: Normalization form C: canonical decomposition, then + canonical composition. */ +extern const struct unicode_normalization_form uninorm_nfc; +#define UNINORM_NFC (&uninorm_nfc) + +/* UNINORM_NFKD: Normalization form KD: compatibility decomposition. */ +extern const struct unicode_normalization_form uninorm_nfkd; +#define UNINORM_NFKD (&uninorm_nfkd) + +/* UNINORM_NFKC: Normalization form KC: compatibility decomposition, then + canonical composition. */ +extern const struct unicode_normalization_form uninorm_nfkc; +#define UNINORM_NFKC (&uninorm_nfkc) + +/* Test whether a normalization form does compatibility decomposition. */ +#define uninorm_is_compat_decomposing(nf) \ + ((* (const unsigned int *) (nf) >> 0) & 1) + +/* Test whether a normalization form includes canonical composition. */ +#define uninorm_is_composing(nf) \ + ((* (const unsigned int *) (nf) >> 1) & 1) + +/* Return the decomposing variant of a normalization form. + This maps NFC,NFD -> NFD and NFKC,NFKD -> NFKD. */ +extern uninorm_t + uninorm_decomposing_form (uninorm_t nf) + _UC_ATTRIBUTE_PURE; + + +/* Return the specified normalization form of a string. */ +extern uint8_t * + u8_normalize (uninorm_t nf, const uint8_t *s, size_t n, + uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint16_t * + u16_normalize (uninorm_t nf, const uint16_t *s, size_t n, + uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); +extern uint32_t * + u32_normalize (uninorm_t nf, const uint32_t *s, size_t n, + uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); + + +/* Compare S1 and S2, ignoring differences in normalization. + NF must be either UNINORM_NFD or UNINORM_NFKD. + If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and + return 0. Upon failure, return -1 with errno set. */ +extern int + u8_normcmp (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, + uninorm_t nf, int *resultp); +extern int + u16_normcmp (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, + uninorm_t nf, int *resultp); +extern int + u32_normcmp (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2, + uninorm_t nf, int *resultp); + + +/* Converts the string S of length N to a NUL-terminated byte sequence, in such + a way that comparing uN_normxfrm (S1) and uN_normxfrm (S2) with uN_cmp2() is + equivalent to comparing S1 and S2 with uN_normcoll(). + NF must be either UNINORM_NFC or UNINORM_NFKC. */ +extern char * + u8_normxfrm (const uint8_t *s, size_t n, uninorm_t nf, + char *resultbuf, size_t *lengthp); +extern char * + u16_normxfrm (const uint16_t *s, size_t n, uninorm_t nf, + char *resultbuf, size_t *lengthp); +extern char * + u32_normxfrm (const uint32_t *s, size_t n, uninorm_t nf, + char *resultbuf, size_t *lengthp); + + +/* Compare S1 and S2, ignoring differences in normalization, using the + collation rules of the current locale. + NF must be either UNINORM_NFC or UNINORM_NFKC. + If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and + return 0. Upon failure, return -1 with errno set. */ +extern int + u8_normcoll (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, + uninorm_t nf, int *resultp); +extern int + u16_normcoll (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, + uninorm_t nf, int *resultp); +extern int + u32_normcoll (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2, + uninorm_t nf, int *resultp); + + +/* Normalization of a stream of Unicode characters. + + A "stream of Unicode characters" is essentially a function that accepts an + ucs4_t argument repeatedly, optionally combined with a function that + "flushes" the stream. */ + +/* Data type of a stream of Unicode characters that normalizes its input + according to a given normalization form and passes the normalized character + sequence to the encapsulated stream of Unicode characters. */ +struct uninorm_filter; + +/* Bring data buffered in the filter to its destination, the encapsulated + stream, then close and free the filter. + Return 0 if successful, or -1 with errno set upon failure. */ +extern int + uninorm_filter_free (struct uninorm_filter *filter); + +/* Create and return a normalization filter for Unicode characters. + The pair (stream_func, stream_data) is the encapsulated stream. + stream_func (stream_data, uc) receives the Unicode character uc + and returns 0 if successful, or -1 with errno set upon failure. + Return the new filter, or NULL with errno set upon failure. */ +extern struct uninorm_filter * + uninorm_filter_create (uninorm_t nf, + int (*stream_func) (void *stream_data, ucs4_t uc), + void *stream_data) + _GL_ATTRIBUTE_DEALLOC (uninorm_filter_free, 1); + +/* Stuff a Unicode character into a normalizing filter. + Return 0 if successful, or -1 with errno set upon failure. */ +extern int + uninorm_filter_write (struct uninorm_filter *filter, ucs4_t uc); + +/* Bring data buffered in the filter to its destination, the encapsulated + stream. + Return 0 if successful, or -1 with errno set upon failure. + Note! If after calling this function, additional characters are written + into the filter, the resulting character sequence in the encapsulated stream + will not necessarily be normalized. */ +extern int + uninorm_filter_flush (struct uninorm_filter *filter); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _UNINORM_H */ diff --git a/lib/uninorm/decompose-internal.c b/lib/uninorm/decompose-internal.c new file mode 100644 index 0000000..1ed8235 --- /dev/null +++ b/lib/uninorm/decompose-internal.c @@ -0,0 +1,29 @@ +/* Decomposition of Unicode strings. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 "decompose-internal.h" + +#define ELEMENT struct ucs4_with_ccc +#define COMPARE(a,b) ((a)->ccc - (b)->ccc) +#define STATIC +#define STATIC_FROMTO static +#define merge_sort_fromto gl_uninorm_decompose_merge_sort_fromto +#define merge_sort_inplace gl_uninorm_decompose_merge_sort_inplace +#include "array-mergesort.h" diff --git a/lib/uninorm/decompose-internal.h b/lib/uninorm/decompose-internal.h new file mode 100644 index 0000000..15d8250 --- /dev/null +++ b/lib/uninorm/decompose-internal.h @@ -0,0 +1,36 @@ +/* Decomposition of Unicode strings. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 "unitypes.h" + +/* Variant of uc_decomposition that does not produce the 'tag'. */ +extern int + uc_compat_decomposition (ucs4_t uc, ucs4_t *decomposition); + +/* A Unicode character together with its canonical combining class. */ +struct ucs4_with_ccc +{ + ucs4_t code; + int ccc; /* range 0..255 */ +}; + +/* Stable-sort an array of 'struct ucs4_with_ccc'. */ +extern void + gl_uninorm_decompose_merge_sort_inplace (struct ucs4_with_ccc *src, size_t n, + struct ucs4_with_ccc *tmp); diff --git a/lib/uninorm/normalize-internal.h b/lib/uninorm/normalize-internal.h new file mode 100644 index 0000000..aae6dbd --- /dev/null +++ b/lib/uninorm/normalize-internal.h @@ -0,0 +1,35 @@ +/* Normalization of Unicode strings. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 "unitypes.h" + +/* Complete definition of normalization form descriptor. */ +struct unicode_normalization_form +{ + /* Bit mask containing meta-information. + This must be the first field. */ + unsigned int description; + #define NF_IS_COMPAT_DECOMPOSING (1 << 0) + #define NF_IS_COMPOSING (1 << 1) + /* Function that decomposes a Unicode character. */ + int (*decomposer) (ucs4_t uc, ucs4_t *decomposition); + /* Function that combines two Unicode characters, a starter and another + character. */ + ucs4_t (*composer) (ucs4_t uc1, ucs4_t uc2); + /* Decomposing variant. */ + const struct unicode_normalization_form *decomposing_variant; +}; diff --git a/lib/uninorm/u-normalize-internal.h b/lib/uninorm/u-normalize-internal.h new file mode 100644 index 0000000..f0d9c6e --- /dev/null +++ b/lib/uninorm/u-normalize-internal.h @@ -0,0 +1,380 @@ +/* Decomposition and composition of Unicode strings. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + 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 . */ + +UNIT * +FUNC (uninorm_t nf, const UNIT *s, size_t n, + UNIT *resultbuf, size_t *lengthp) +{ + int (*decomposer) (ucs4_t uc, ucs4_t *decomposition) = nf->decomposer; + ucs4_t (*composer) (ucs4_t uc1, ucs4_t uc2) = nf->composer; + + /* The result being accumulated. */ + UNIT *result; + size_t length; + size_t allocated; + /* The buffer for sorting. */ + #define SORTBUF_PREALLOCATED 64 + struct ucs4_with_ccc sortbuf_preallocated[2 * SORTBUF_PREALLOCATED]; + struct ucs4_with_ccc *sortbuf; /* array of size 2 * sortbuf_allocated */ + size_t sortbuf_allocated; + size_t sortbuf_count; + + /* Initialize the accumulator. */ + if (resultbuf == NULL) + { + result = NULL; + allocated = 0; + } + else + { + result = resultbuf; + allocated = *lengthp; + } + length = 0; + + /* Initialize the buffer for sorting. */ + sortbuf = sortbuf_preallocated; + sortbuf_allocated = SORTBUF_PREALLOCATED; + sortbuf_count = 0; + + { + const UNIT *s_end = s + n; + + for (;;) + { + int count; + ucs4_t decomposed[UC_DECOMPOSITION_MAX_LENGTH]; + int decomposed_count; + int i; + + if (s < s_end) + { + /* Fetch the next character. */ + count = U_MBTOUC_UNSAFE (&decomposed[0], s, s_end - s); + decomposed_count = 1; + + /* Decompose it, recursively. + It would be possible to precompute the recursive decomposition + and store it in a table. But this would significantly increase + the size of the decomposition tables, because for example for + U+1FC1 the recursive canonical decomposition and the recursive + compatibility decomposition are different. */ + { + int curr; + + for (curr = 0; curr < decomposed_count; ) + { + /* Invariant: decomposed[0..curr-1] is fully decomposed, i.e. + all elements are atomic. */ + ucs4_t curr_decomposed[UC_DECOMPOSITION_MAX_LENGTH]; + int curr_decomposed_count; + + curr_decomposed_count = decomposer (decomposed[curr], curr_decomposed); + if (curr_decomposed_count >= 0) + { + /* Move curr_decomposed[0..curr_decomposed_count-1] over + decomposed[curr], making room. It's not worth using + memcpy() here, since the counts are so small. */ + int shift = curr_decomposed_count - 1; + + if (shift < 0) + abort (); + if (shift > 0) + { + int j; + + decomposed_count += shift; + if (decomposed_count > UC_DECOMPOSITION_MAX_LENGTH) + abort (); + for (j = decomposed_count - 1 - shift; j > curr; j--) + decomposed[j + shift] = decomposed[j]; + } + for (; shift >= 0; shift--) + decomposed[curr + shift] = curr_decomposed[shift]; + } + else + { + /* decomposed[curr] is atomic. */ + curr++; + } + } + } + } + else + { + count = 0; + decomposed_count = 0; + } + + i = 0; + for (;;) + { + ucs4_t uc; + int ccc; + + if (s < s_end) + { + /* Fetch the next character from the decomposition. */ + if (i == decomposed_count) + break; + uc = decomposed[i]; + ccc = uc_combining_class (uc); + } + else + { + /* End of string reached. */ + uc = 0; + ccc = 0; + } + + if (ccc == 0) + { + size_t j; + + /* Apply the canonical ordering algorithm to the accumulated + sequence of characters. */ + if (sortbuf_count > 1) + gl_uninorm_decompose_merge_sort_inplace (sortbuf, sortbuf_count, + sortbuf + sortbuf_count); + + if (composer != NULL) + { + /* Attempt to combine decomposed characters, as specified + in the Unicode Standard Annex #15 "Unicode Normalization + Forms". We need to check + 1. whether the first accumulated character is a + "starter" (i.e. has ccc = 0). This is usually the + case. But when the string starts with a + non-starter, the sortbuf also starts with a + non-starter. Btw, this check could also be + omitted, because the composition table has only + entries (code1, code2) for which code1 is a + starter; if the first accumulated character is not + a starter, no lookup will succeed. + 2. If the sortbuf has more than one character, check + for each of these characters that are not "blocked" + from the starter (i.e. have a ccc that is higher + than the ccc of the previous character) whether it + can be combined with the first character. + 3. If only one character is left in sortbuf, check + whether it can be combined with the next character + (also a starter). */ + if (sortbuf_count > 0 && sortbuf[0].ccc == 0) + { + for (j = 1; j < sortbuf_count; ) + { + if (sortbuf[j].ccc > sortbuf[j - 1].ccc) + { + ucs4_t combined = + composer (sortbuf[0].code, sortbuf[j].code); + if (combined) + { + size_t k; + + sortbuf[0].code = combined; + /* sortbuf[0].ccc = 0, still valid. */ + for (k = j + 1; k < sortbuf_count; k++) + sortbuf[k - 1] = sortbuf[k]; + sortbuf_count--; + continue; + } + } + j++; + } + if (s < s_end && sortbuf_count == 1) + { + ucs4_t combined = + composer (sortbuf[0].code, uc); + if (combined) + { + uc = combined; + ccc = 0; + /* uc could be further combined with subsequent + characters. So don't put it into sortbuf[0] in + this round, only in the next round. */ + sortbuf_count = 0; + } + } + } + } + + for (j = 0; j < sortbuf_count; j++) + { + ucs4_t muc = sortbuf[j].code; + + /* Append muc to the result accumulator. */ + if (length < allocated) + { + int ret = + U_UCTOMB (result + length, muc, allocated - length); + if (ret == -1) + { + errno = EINVAL; + goto fail; + } + if (ret >= 0) + { + length += ret; + goto done_appending; + } + } + { + size_t old_allocated = allocated; + size_t new_allocated = 2 * old_allocated; + if (new_allocated < 64) + new_allocated = 64; + if (new_allocated < old_allocated) /* integer overflow? */ + abort (); + { + UNIT *larger_result; + if (result == NULL) + { + larger_result = + (UNIT *) malloc (new_allocated * sizeof (UNIT)); + if (larger_result == NULL) + { + errno = ENOMEM; + goto fail; + } + } + else if (result == resultbuf) + { + larger_result = + (UNIT *) malloc (new_allocated * sizeof (UNIT)); + if (larger_result == NULL) + { + errno = ENOMEM; + goto fail; + } + U_CPY (larger_result, resultbuf, length); + } + else + { + larger_result = + (UNIT *) realloc (result, new_allocated * sizeof (UNIT)); + if (larger_result == NULL) + { + errno = ENOMEM; + goto fail; + } + } + result = larger_result; + allocated = new_allocated; + { + int ret = + U_UCTOMB (result + length, muc, allocated - length); + if (ret == -1) + { + errno = EINVAL; + goto fail; + } + if (ret < 0) + abort (); + length += ret; + goto done_appending; + } + } + } + done_appending: ; + } + + /* sortbuf is now empty. */ + sortbuf_count = 0; + } + + if (!(s < s_end)) + /* End of string reached. */ + break; + + /* Append (uc, ccc) to sortbuf. */ + if (sortbuf_count == sortbuf_allocated) + { + struct ucs4_with_ccc *new_sortbuf; + + sortbuf_allocated = 2 * sortbuf_allocated; + if (sortbuf_allocated < sortbuf_count) /* integer overflow? */ + abort (); + new_sortbuf = + (struct ucs4_with_ccc *) malloc (2 * sortbuf_allocated * sizeof (struct ucs4_with_ccc)); + if (new_sortbuf == NULL) + { + errno = ENOMEM; + goto fail; + } + memcpy (new_sortbuf, sortbuf, + sortbuf_count * sizeof (struct ucs4_with_ccc)); + if (sortbuf != sortbuf_preallocated) + free (sortbuf); + sortbuf = new_sortbuf; + } + sortbuf[sortbuf_count].code = uc; + sortbuf[sortbuf_count].ccc = ccc; + sortbuf_count++; + + i++; + } + + if (!(s < s_end)) + /* End of string reached. */ + break; + + s += count; + } + } + + if (length == 0) + { + if (result == NULL) + { + /* Return a non-NULL value. NULL means error. */ + result = (UNIT *) malloc (1); + if (result == NULL) + { + errno = ENOMEM; + goto fail; + } + } + } + else if (result != resultbuf && length < allocated) + { + /* Shrink the allocated memory if possible. */ + UNIT *memory; + + memory = (UNIT *) realloc (result, length * sizeof (UNIT)); + if (memory != NULL) + result = memory; + } + + if (sortbuf_count > 0) + abort (); + if (sortbuf != sortbuf_preallocated) + free (sortbuf); + + *lengthp = length; + return result; + + fail: + { + int saved_errno = errno; + if (sortbuf != sortbuf_preallocated) + free (sortbuf); + if (result != resultbuf) + free (result); + errno = saved_errno; + } + return NULL; +} diff --git a/lib/uninorm/u8-normalize.c b/lib/uninorm/u8-normalize.c new file mode 100644 index 0000000..fe40d11 --- /dev/null +++ b/lib/uninorm/u8-normalize.c @@ -0,0 +1,46 @@ +/* Normalization of UTF-8 strings. + Copyright (C) 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2009. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "uninorm.h" + +#include +#include +#include +#include + +#include "unistr.h" +#include "unictype.h" +#include "normalize-internal.h" +#include "uninorm/decompose-internal.h" + +#define FUNC u8_normalize +#define UNIT uint8_t +#define U_MBTOUC_UNSAFE u8_mbtouc_unsafe +#define U_UCTOMB u8_uctomb +#define U_CPY u8_cpy +#include "u-normalize-internal.h" diff --git a/lib/unistd--.h b/lib/unistd--.h new file mode 100644 index 0000000..d395f7e --- /dev/null +++ b/lib/unistd--.h @@ -0,0 +1,32 @@ +/* Like unistd.h, but redefine some names to avoid glitches. + + Copyright (C) 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 + (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 Paul Eggert. */ + +#include +#include "unistd-safer.h" + +#undef dup +#define dup dup_safer + +#undef pipe +#define pipe pipe_safer + +#if GNULIB_PIPE2_SAFER +# undef pipe2 +# define pipe2 pipe2_safer +#endif diff --git a/lib/unistd-safer.h b/lib/unistd-safer.h new file mode 100644 index 0000000..db82c85 --- /dev/null +++ b/lib/unistd-safer.h @@ -0,0 +1,31 @@ +/* Invoke unistd-like functions, but avoid some glitches. + + Copyright (C) 2001, 2003, 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 + (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 Paul Eggert and Eric Blake. */ + +int dup_safer (int); +int fd_safer (int); +int pipe_safer (int[2]); + +#if GNULIB_FD_SAFER_FLAG +int dup_safer_flag (int, int); +int fd_safer_flag (int, int); +#endif + +#if GNULIB_PIPE2_SAFER +int pipe2_safer (int[2], int); +#endif diff --git a/lib/unistd.c b/lib/unistd.c new file mode 100644 index 0000000..95978e6 --- /dev/null +++ b/lib/unistd.c @@ -0,0 +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/lib/unistd.in.h b/lib/unistd.in.h new file mode 100644 index 0000000..57df09e --- /dev/null +++ b/lib/unistd.in.h @@ -0,0 +1,2327 @@ +/* Substitute for and wrapper around . + Copyright (C) 2003-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 _@GUARD_PREFIX@_UNISTD_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#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(). */ +#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ + && !defined _GL_INCLUDING_WINSOCK2_H +# define _GL_INCLUDING_WINSOCK2_H +# include +# undef _GL_INCLUDING_WINSOCK2_H +#endif + +#if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H +#define _@GUARD_PREFIX@_UNISTD_H + +/* NetBSD 5.0 mis-defines NULL. Also get size_t. */ +/* 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 and Android 4.3 declare unlinkat in , not in + . */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ + && (defined __CYGWIN__ || defined __ANDROID__) \ + && ! defined __GLIBC__ +# include +#endif + +/* mingw fails to declare _exit in . */ +/* mingw, MSVC, BeOS, Haiku declare environ in , not in + . */ +/* Solaris declares getcwd not only in but also in . */ +/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system is + included here. */ +/* But avoid namespace pollution on glibc systems. */ +#if !defined __GLIBC__ && !defined __osf__ +# define __need_system_stdlib_h +# include +# undef __need_system_stdlib_h +#endif + +/* 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 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 . + NonStop Kernel declares gethostname in , not in . */ +/* But avoid namespace pollution on glibc systems. */ +#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \ + || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \ + && !defined __GLIBC__ +# include +#endif + +/* 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 + +/* 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 + +/* 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. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* 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@ +# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef socket +# define socket socket_used_without_including_sys_socket_h +# undef connect +# define connect connect_used_without_including_sys_socket_h +# undef accept +# define accept accept_used_without_including_sys_socket_h +# undef bind +# define bind bind_used_without_including_sys_socket_h +# undef getpeername +# define getpeername getpeername_used_without_including_sys_socket_h +# undef getsockname +# define getsockname getsockname_used_without_including_sys_socket_h +# undef getsockopt +# define getsockopt getsockopt_used_without_including_sys_socket_h +# undef listen +# define listen listen_used_without_including_sys_socket_h +# undef recv +# define recv recv_used_without_including_sys_socket_h +# undef send +# define send send_used_without_including_sys_socket_h +# undef recvfrom +# define recvfrom recvfrom_used_without_including_sys_socket_h +# undef sendto +# define sendto sendto_used_without_including_sys_socket_h +# undef setsockopt +# define setsockopt setsockopt_used_without_including_sys_socket_h +# undef shutdown +# define shutdown shutdown_used_without_including_sys_socket_h +# else + _GL_WARN_ON_USE (socket, + "socket() used without including "); + _GL_WARN_ON_USE (connect, + "connect() used without including "); + _GL_WARN_ON_USE (accept, + "accept() used without including "); + _GL_WARN_ON_USE (bind, + "bind() used without including "); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including "); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including "); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including "); + _GL_WARN_ON_USE (listen, + "listen() used without including "); + _GL_WARN_ON_USE (recv, + "recv() used without including "); + _GL_WARN_ON_USE (send, + "send() used without including "); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including "); + _GL_WARN_ON_USE (sendto, + "sendto() used without including "); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including "); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including "); +# endif +# endif +# if !defined _@GUARD_PREFIX@_SYS_SELECT_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef select +# define select select_used_without_including_sys_select_h +# else + _GL_WARN_ON_USE (select, + "select() used without including "); +# endif +# endif +#endif + + +/* OS/2 EMX lacks these macros. */ +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +/* Ensure *_OK macros exist. */ +#ifndef F_OK +# define F_OK 0 +# define X_OK 1 +# define W_OK 2 +# define R_OK 4 +#endif + + +/* Declare overridden functions. */ + + +#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, "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 +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_CHOWN@ +/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE + 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)); +# 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); +#elif defined GNULIB_POSIXCHECK +# undef dup2 +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_DUP3@ +/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the + specified flags. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + 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 +# endif +_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags)); +_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags)); +# else +_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags)); +_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags)); +# endif +_GL_CXXALIASWARN (dup3); +#elif defined GNULIB_POSIXCHECK +# undef dup3 +# if HAVE_RAW_DECL_DUP3 +_GL_WARN_ON_USE (dup3, "dup3 is unportable - " + "use gnulib module dup3 for portability"); +# endif +#endif + + +#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 +# ifdef __cplusplus +extern "C" { +# endif +extern char **environ; +# ifdef __cplusplus +} +# endif +# endif +# endif +#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; +} +# undef environ +# define environ (*rpl_environ ()) +# endif +#endif + + +#if @GNULIB_EUIDACCESS@ +/* Like access(), except that it uses the effective user id and group id of + the current process. */ +# if !@HAVE_EUIDACCESS@ +_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode)); +_GL_CXXALIASWARN (euidaccess); +# if defined GNULIB_POSIXCHECK +/* Like access(), this function is a security risk. */ +_GL_WARN_ON_USE (euidaccess, "the euidaccess function is a security risk - " + "use the gnulib module faccessat instead"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef euidaccess +# if HAVE_RAW_DECL_EUIDACCESS +_GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - " + "use gnulib module euidaccess for portability"); +# endif +#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 @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 +_GL_CXXALIAS_SYS (faccessat, int, + (int fd, char const *file, int mode, int flag)); +# endif +_GL_CXXALIASWARN (faccessat); +#elif defined GNULIB_POSIXCHECK +# undef faccessat +# if HAVE_RAW_DECL_FACCESSAT +_GL_WARN_ON_USE (faccessat, "faccessat is not portable - " + "use gnulib module faccessat for portability"); +# endif +#endif + + +#if @GNULIB_FCHDIR@ +/* Change the process' current working directory to the directory on which + 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*/)); + +/* Gnulib internal hooks needed to maintain the fchdir metadata. */ +_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename) + _GL_ARG_NONNULL ((2)); +_GL_EXTERN_C void _gl_unregister_fd (int fd); +_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd); +_GL_EXTERN_C const char *_gl_directory_name (int fd); + +# else +# if !@HAVE_DECL_FCHDIR@ +_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); +# endif +# endif +_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/)); +_GL_CXXALIASWARN (fchdir); +#elif defined GNULIB_POSIXCHECK +# undef fchdir +# if HAVE_RAW_DECL_FCHDIR +_GL_WARN_ON_USE (fchdir, "fchdir is unportable - " + "use gnulib module fchdir for portability"); +# endif +#endif + + +#if @GNULIB_FCHOWNAT@ +# if @REPLACE_FCHOWNAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fchownat +# define fchownat rpl_fchownat +# endif +_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag)); +# else +# if !@HAVE_FCHOWNAT@ +_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag)); +# endif +_GL_CXXALIASWARN (fchownat); +#elif defined GNULIB_POSIXCHECK +# undef fchownat +# if HAVE_RAW_DECL_FCHOWNAT +_GL_WARN_ON_USE (fchownat, "fchownat is not portable - " + "use gnulib module fchownat for portability"); +# endif +#endif + + +#if @GNULIB_FDATASYNC@ +/* 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 +_GL_CXXALIAS_SYS (fdatasync, int, (int fd)); +_GL_CXXALIASWARN (fdatasync); +#elif defined GNULIB_POSIXCHECK +# undef fdatasync +# if HAVE_RAW_DECL_FDATASYNC +_GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - " + "use gnulib module fdatasync for portability"); +# endif +#endif + + +#if @GNULIB_FSYNC@ +/* 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 +_GL_CXXALIAS_SYS (fsync, int, (int fd)); +_GL_CXXALIASWARN (fsync); +#elif defined GNULIB_POSIXCHECK +# undef fsync +# if HAVE_RAW_DECL_FSYNC +_GL_WARN_ON_USE (fsync, "fsync is unportable - " + "use gnulib module fsync for portability"); +# endif +#endif + + +#if @GNULIB_FTRUNCATE@ +/* 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 +# define ftruncate rpl_ftruncate +# endif +_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length)); +_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length)); +# else +# if !@HAVE_FTRUNCATE@ +_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); +# endif +_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); +# endif +_GL_CXXALIASWARN (ftruncate); +#elif defined GNULIB_POSIXCHECK +# undef ftruncate +# if HAVE_RAW_DECL_FTRUNCATE +_GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " + "use gnulib module ftruncate for portability"); +# endif +#endif + + +#if @GNULIB_GETCWD@ +/* Get the name of the current working directory, and put it in SIZE bytes + of BUF. + 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 + necessary. */ +# if @REPLACE_GETCWD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getcwd rpl_getcwd +# 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. */ +_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size)); +# endif +_GL_CXXALIASWARN (getcwd); +#elif defined GNULIB_POSIXCHECK +# undef getcwd +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_GETDOMAINNAME@ +/* Return the NIS domain name of the machine. + WARNING! The NIS domain name is unrelated to the fully qualified host name + of the machine. It is also unrelated to email addresses. + WARNING! The NIS domain name is usually the empty string or "(none)" when + not using NIS. + + Put up to LEN bytes of the NIS domain name into NAME. + Null terminate it if the name is shorter than LEN. + If the NIS domain name is longer than LEN, set errno = EINVAL and return -1. + Return 0 if successful, otherwise set errno and return -1. */ +# if @REPLACE_GETDOMAINNAME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getdomainname +# define getdomainname rpl_getdomainname +# endif +_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len)); +# else +# if !@HAVE_DECL_GETDOMAINNAME@ +_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len)); +# endif +_GL_CXXALIASWARN (getdomainname); +#elif defined GNULIB_POSIXCHECK +# undef getdomainname +# if HAVE_RAW_DECL_GETDOMAINNAME +_GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - " + "use gnulib module getdomainname for portability"); +# endif +#endif + + +#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 @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_CXXALIASWARN (getdtablesize); +#elif defined GNULIB_POSIXCHECK +# undef getdtablesize +# if HAVE_RAW_DECL_GETDTABLESIZE +_GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - " + "use gnulib module getdtablesize for portability"); +# endif +#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. + If N is 0, return the group count; otherwise, N describes how many + entries are available in GROUPS. Return -1 and set errno if N is + not 0 and not large enough. Fails with ENOSYS on some systems. */ +# if @REPLACE_GETGROUPS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getgroups +# define getgroups rpl_getgroups +# endif +_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups)); +_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups)); +# else +# if !@HAVE_GETGROUPS@ +_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups)); +# endif +_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups)); +# endif +_GL_CXXALIASWARN (getgroups); +#elif defined GNULIB_POSIXCHECK +# undef getgroups +# if HAVE_RAW_DECL_GETGROUPS +_GL_WARN_ON_USE (getgroups, "getgroups is unportable - " + "use gnulib module getgroups for portability"); +# endif +#endif + + +#if @GNULIB_GETHOSTNAME@ +/* Return the standard host name of the machine. + WARNING! The host name may or may not be fully qualified. + + Put up to LEN bytes of the host name into NAME. + Null terminate it if the name is shorter than LEN. + If the host name is longer than LEN, set errno = EINVAL and return -1. + Return 0 if successful, otherwise set errno and return -1. */ +# if @UNISTD_H_HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gethostname +# define gethostname rpl_gethostname +# endif +_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); +# else +# if !@HAVE_GETHOSTNAME@ +_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second + parameter is + int len. */ +_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len)); +# endif +_GL_CXXALIASWARN (gethostname); +#elif @UNISTD_H_HAVE_WINSOCK2_H@ +# undef gethostname +# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname +#elif defined GNULIB_POSIXCHECK +# undef gethostname +# if HAVE_RAW_DECL_GETHOSTNAME +_GL_WARN_ON_USE (gethostname, "gethostname is unportable - " + "use gnulib module gethostname for portability"); +# endif +#endif + + +#if @GNULIB_GETLOGIN@ +/* Returns the user's login name, or NULL if it cannot be found. Upon error, + returns NULL with errno set. + + 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_DECL_GETLOGIN@ +_GL_FUNCDECL_SYS (getlogin, char *, (void)); +# endif +_GL_CXXALIAS_SYS (getlogin, char *, (void)); +_GL_CXXALIASWARN (getlogin); +#elif defined GNULIB_POSIXCHECK +# undef getlogin +# if HAVE_RAW_DECL_GETLOGIN +_GL_WARN_ON_USE (getlogin, "getlogin is unportable - " + "use gnulib module getlogin for portability"); +# endif +#endif + + +#if @GNULIB_GETLOGIN_R@ +/* Copies the user's login name to NAME. + The array pointed to by NAME has room for SIZE bytes. + + Returns 0 if successful. Upon error, an error number is returned, or -1 in + 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 . + + 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 @REPLACE_GETLOGIN_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getlogin_r rpl_getlogin_r +# endif +_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size)); +# else +# if !@HAVE_DECL_GETLOGIN_R@ +_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on Solaris 10 systems, the second argument is + int size. */ +_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size)); +# endif +_GL_CXXALIASWARN (getlogin_r); +#elif defined GNULIB_POSIXCHECK +# undef getlogin_r +# if HAVE_RAW_DECL_GETLOGIN_R +_GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - " + "use gnulib module getlogin_r for portability"); +# endif +#endif + + +#if @GNULIB_GETPAGESIZE@ +# if @REPLACE_GETPAGESIZE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getpagesize rpl_getpagesize +# endif +_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. */ +# if !defined _gl_getpagesize && defined _SC_PAGESIZE +# if ! (defined __VMS && __VMS_VER < 70000000) +# define _gl_getpagesize() sysconf (_SC_PAGESIZE) +# endif +# endif +/* This is for older VMS. */ +# if !defined _gl_getpagesize && defined __VMS +# ifdef __ALPHA +# define _gl_getpagesize() 8192 +# else +# define _gl_getpagesize() 512 +# endif +# endif +/* This is for BeOS. */ +# if !defined _gl_getpagesize && @HAVE_OS_H@ +# include +# if defined B_PAGE_SIZE +# define _gl_getpagesize() B_PAGE_SIZE +# endif +# endif +/* This is for AmigaOS4.0. */ +# if !defined _gl_getpagesize && defined __amigaos4__ +# define _gl_getpagesize() 2048 +# endif +/* This is for older Unix systems. */ +# if !defined _gl_getpagesize && @HAVE_SYS_PARAM_H@ +# include +# ifdef EXEC_PAGESIZE +# define _gl_getpagesize() EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define CLSIZE 1 +# endif +# define _gl_getpagesize() (NBPG * CLSIZE) +# else +# ifdef NBPC +# define _gl_getpagesize() NBPC +# endif +# endif +# endif +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getpagesize() _gl_getpagesize () +# else +# if !GNULIB_defined_getpagesize_function +_GL_UNISTD_INLINE int +getpagesize () +{ + return _gl_getpagesize (); +} +# define GNULIB_defined_getpagesize_function 1 +# endif +# endif +# endif +# endif +/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t. */ +_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void)); +# endif +# if @HAVE_DECL_GETPAGESIZE@ +_GL_CXXALIASWARN (getpagesize); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getpagesize +# if HAVE_RAW_DECL_GETPAGESIZE +_GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - " + "use gnulib module getpagesize for portability"); +# endif +#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. */ +# if !@HAVE_DECL_GETUSERSHELL@ +_GL_FUNCDECL_SYS (getusershell, char *, (void)); +# endif +_GL_CXXALIAS_SYS (getusershell, char *, (void)); +_GL_CXXALIASWARN (getusershell); +#elif defined GNULIB_POSIXCHECK +# undef getusershell +# if HAVE_RAW_DECL_GETUSERSHELL +_GL_WARN_ON_USE (getusershell, "getusershell is unportable - " + "use gnulib module getusershell for portability"); +# endif +#endif + +#if @GNULIB_GETUSERSHELL@ +/* Rewind to pointer that is advanced at each getusershell() call. */ +# if !@HAVE_DECL_GETUSERSHELL@ +_GL_FUNCDECL_SYS (setusershell, void, (void)); +# endif +_GL_CXXALIAS_SYS (setusershell, void, (void)); +_GL_CXXALIASWARN (setusershell); +#elif defined GNULIB_POSIXCHECK +# undef setusershell +# if HAVE_RAW_DECL_SETUSERSHELL +_GL_WARN_ON_USE (setusershell, "setusershell is unportable - " + "use gnulib module getusershell for portability"); +# endif +#endif + +#if @GNULIB_GETUSERSHELL@ +/* Free the pointer that is advanced at each getusershell() call and + associated resources. */ +# if !@HAVE_DECL_GETUSERSHELL@ +_GL_FUNCDECL_SYS (endusershell, void, (void)); +# endif +_GL_CXXALIAS_SYS (endusershell, void, (void)); +_GL_CXXALIASWARN (endusershell); +#elif defined GNULIB_POSIXCHECK +# undef endusershell +# if HAVE_RAW_DECL_ENDUSERSHELL +_GL_WARN_ON_USE (endusershell, "endusershell is unportable - " + "use gnulib module getusershell for portability"); +# endif +#endif + + +#if @GNULIB_GROUP_MEMBER@ +/* Determine whether group id is in calling user's group list. */ +# if !@HAVE_GROUP_MEMBER@ +_GL_FUNCDECL_SYS (group_member, int, (gid_t gid)); +# endif +_GL_CXXALIAS_SYS (group_member, int, (gid_t gid)); +_GL_CXXALIASWARN (group_member); +#elif defined GNULIB_POSIXCHECK +# undef group_member +# if HAVE_RAW_DECL_GROUP_MEMBER +_GL_WARN_ON_USE (group_member, "group_member is unportable - " + "use gnulib module group-member for portability"); +# endif +#endif + + +#if @GNULIB_ISATTY@ +# if @REPLACE_ISATTY@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# 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 +_GL_CXXALIASWARN (isatty); +#elif defined GNULIB_POSIXCHECK +# undef isatty +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_LCHOWN@ +/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE + 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 +# define lchown rpl_lchown +# endif +_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)); +# else +# if !@HAVE_LCHOWN@ +_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)); +# endif +_GL_CXXALIASWARN (lchown); +#elif defined GNULIB_POSIXCHECK +# undef lchown +# if HAVE_RAW_DECL_LCHOWN +_GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - " + "use gnulib module lchown for portability"); +# endif +#endif + + +#if @GNULIB_LINK@ +/* 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 +# endif +_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2)); +# else +# if !@HAVE_LINK@ +_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2)); +# endif +_GL_CXXALIASWARN (link); +#elif defined GNULIB_POSIXCHECK +# undef link +# if HAVE_RAW_DECL_LINK +_GL_WARN_ON_USE (link, "link is unportable - " + "use gnulib module link for portability"); +# endif +#endif + + +#if @GNULIB_LINKAT@ +/* Create a new hard link for an existing file, relative to two + directories. FLAG controls whether symlinks are followed. + Return 0 if successful, otherwise -1 and errno set. */ +# if @REPLACE_LINKAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef linkat +# define linkat rpl_linkat +# endif +_GL_FUNCDECL_RPL (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag) + _GL_ARG_NONNULL ((2, 4))); +_GL_CXXALIAS_RPL (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag)); +# else +# if !@HAVE_LINKAT@ +_GL_FUNCDECL_SYS (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag) + _GL_ARG_NONNULL ((2, 4))); +# endif +_GL_CXXALIAS_SYS (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag)); +# endif +_GL_CXXALIASWARN (linkat); +#elif defined GNULIB_POSIXCHECK +# undef linkat +# if HAVE_RAW_DECL_LINKAT +_GL_WARN_ON_USE (linkat, "linkat is unportable - " + "use gnulib module linkat for portability"); +# endif +#endif + + +#if @GNULIB_LSEEK@ +/* 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 +_GL_CXXALIASWARN (lseek); +#elif defined GNULIB_POSIXCHECK +# undef lseek +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_PIPE@ +/* Create a pipe, defaulting to O_BINARY mode. + 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. */ +# if !@HAVE_PIPE@ +_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (pipe, int, (int fd[2])); +_GL_CXXALIASWARN (pipe); +#elif defined GNULIB_POSIXCHECK +# undef pipe +# if HAVE_RAW_DECL_PIPE +_GL_WARN_ON_USE (pipe, "pipe is unportable - " + "use gnulib module pipe-posix for portability"); +# endif +#endif + + +#if @GNULIB_PIPE2@ +/* Create a pipe, applying the given flags when opening the read-end of the + pipe and the write-end of the pipe. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + 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 +# endif +_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags)); +# else +_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags)); +# endif +_GL_CXXALIASWARN (pipe2); +#elif defined GNULIB_POSIXCHECK +# undef pipe2 +# if HAVE_RAW_DECL_PIPE2 +_GL_WARN_ON_USE (pipe2, "pipe2 is unportable - " + "use gnulib module pipe2 for portability"); +# endif +#endif + + +#if @GNULIB_PREAD@ +/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET. + 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 +# define pread rpl_pread +# endif +_GL_FUNCDECL_RPL (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset)); +# else +# if !@HAVE_PREAD@ +_GL_FUNCDECL_SYS (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset)); +# endif +_GL_CXXALIASWARN (pread); +#elif defined GNULIB_POSIXCHECK +# undef pread +# if HAVE_RAW_DECL_PREAD +_GL_WARN_ON_USE (pread, "pread is unportable - " + "use gnulib module pread for portability"); +# endif +#endif + + +#if @GNULIB_PWRITE@ +/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET. + 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 +# define pwrite rpl_pwrite +# endif +_GL_FUNCDECL_RPL (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset)); +# else +# if !@HAVE_PWRITE@ +_GL_FUNCDECL_SYS (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset)); +# endif +_GL_CXXALIASWARN (pwrite); +#elif defined GNULIB_POSIXCHECK +# undef pwrite +# if HAVE_RAW_DECL_PWRITE +_GL_WARN_ON_USE (pwrite, "pwrite is unportable - " + "use gnulib module pwrite for portability"); +# endif +#endif + + +#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 +# define read rpl_read +# endif +_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 +_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); +# endif +_GL_CXXALIASWARN (read); +#endif + + +#if @GNULIB_READLINK@ +/* Read the contents of the symbolic link FILE and place the first BUFSIZE + 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 *restrict file, + char *restrict buf, size_t bufsize) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (readlink, ssize_t, + (const char *restrict file, + char *restrict buf, size_t bufsize)); +# else +# if !@HAVE_READLINK@ +_GL_FUNCDECL_SYS (readlink, ssize_t, + (const char *restrict file, + char *restrict buf, size_t bufsize) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (readlink, ssize_t, + (const char *restrict file, + char *restrict buf, size_t bufsize)); +# endif +_GL_CXXALIASWARN (readlink); +#elif defined GNULIB_POSIXCHECK +# undef readlink +# if HAVE_RAW_DECL_READLINK +_GL_WARN_ON_USE (readlink, "readlink is unportable - " + "use gnulib module readlink for portability"); +# endif +#endif + + +#if @GNULIB_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 *restrict file, + char *restrict buf, size_t len) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (readlinkat, ssize_t, + (int fd, char const *restrict file, + char *restrict buf, size_t len)); +# endif +_GL_CXXALIASWARN (readlinkat); +#elif defined GNULIB_POSIXCHECK +# undef readlinkat +# if HAVE_RAW_DECL_READLINKAT +_GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - " + "use gnulib module readlinkat for portability"); +# endif +#endif + + +#if @GNULIB_RMDIR@ +/* Remove the directory DIR. */ +# if @REPLACE_RMDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define rmdir rpl_rmdir +# 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 +_GL_CXXALIASWARN (rmdir); +#elif defined GNULIB_POSIXCHECK +# undef rmdir +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_SETHOSTNAME@ +/* Set the host name of the machine. + The host name may or may not be fully qualified. + + Put LEN bytes of NAME into the host name. + Return 0 if successful, otherwise, set errno and return -1. + + Platforms with no ability to set the hostname return -1 and set + errno = ENOSYS. */ +# if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@ +_GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5 + and FreeBSD 6.4 the second parameter is int. On Solaris 11 + 2011-10, the first parameter is not const. */ +_GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len)); +_GL_CXXALIASWARN (sethostname); +#elif defined GNULIB_POSIXCHECK +# undef sethostname +# if HAVE_RAW_DECL_SETHOSTNAME +_GL_WARN_ON_USE (sethostname, "sethostname is unportable - " + "use gnulib module sethostname for portability"); +# endif +#endif + + +#if @GNULIB_SLEEP@ +/* 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 +# define sleep rpl_sleep +# endif +_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n)); +_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n)); +# else +# if !@HAVE_SLEEP@ +_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n)); +# endif +_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n)); +# endif +_GL_CXXALIASWARN (sleep); +#elif defined GNULIB_POSIXCHECK +# undef sleep +# if HAVE_RAW_DECL_SLEEP +_GL_WARN_ON_USE (sleep, "sleep is unportable - " + "use gnulib module sleep for portability"); +# endif +#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) +# undef symlink +# define symlink rpl_symlink +# endif +_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file)); +# else +# if !@HAVE_SYMLINK@ +_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file)); +# endif +_GL_CXXALIASWARN (symlink); +#elif defined GNULIB_POSIXCHECK +# undef symlink +# if HAVE_RAW_DECL_SYMLINK +_GL_WARN_ON_USE (symlink, "symlink is not portable - " + "use gnulib module symlink for portability"); +# endif +#endif + + +#if @GNULIB_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 +_GL_CXXALIAS_SYS (symlinkat, int, + (char const *contents, int fd, char const *file)); +# endif +_GL_CXXALIASWARN (symlinkat); +#elif defined GNULIB_POSIXCHECK +# undef symlinkat +# if HAVE_RAW_DECL_SYMLINKAT +_GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " + "use gnulib module symlinkat for portability"); +# endif +#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. */ +# if @REPLACE_TTYNAME_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ttyname_r +# define ttyname_r rpl_ttyname_r +# endif +_GL_FUNCDECL_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen)); +# else +# if !@HAVE_DECL_TTYNAME_R@ +_GL_FUNCDECL_SYS (ttyname_r, int, + (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (ttyname_r, int, + (int fd, char *buf, size_t buflen)); +# endif +_GL_CXXALIASWARN (ttyname_r); +#elif defined GNULIB_POSIXCHECK +# undef ttyname_r +# if HAVE_RAW_DECL_TTYNAME_R +_GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - " + "use gnulib module ttyname_r for portability"); +# endif +#endif + + +#if @GNULIB_UNLINK@ +# if @REPLACE_UNLINK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unlink +# define unlink rpl_unlink +# 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 +_GL_CXXALIASWARN (unlink); +#elif defined GNULIB_POSIXCHECK +# undef unlink +# if HAVE_RAW_DECL_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 + + +#if @GNULIB_UNLINKAT@ +# if @REPLACE_UNLINKAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unlinkat +# define unlinkat rpl_unlinkat +# endif +_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag)); +# else +# if !@HAVE_UNLINKAT@ +_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag)); +# endif +_GL_CXXALIASWARN (unlinkat); +#elif defined GNULIB_POSIXCHECK +# undef unlinkat +# if HAVE_RAW_DECL_UNLINKAT +_GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " + "use gnulib module unlinkat for portability"); +# endif +#endif + + +#if @GNULIB_USLEEP@ +/* 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 +# define usleep rpl_usleep +# endif +_GL_FUNCDECL_RPL (usleep, int, (useconds_t n)); +_GL_CXXALIAS_RPL (usleep, int, (useconds_t n)); +# else +# if !@HAVE_USLEEP@ +_GL_FUNCDECL_SYS (usleep, int, (useconds_t n)); +# endif +/* 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 +# undef usleep +# if HAVE_RAW_DECL_USLEEP +_GL_WARN_ON_USE (usleep, "usleep is unportable - " + "use gnulib module usleep for portability"); +# endif +#endif + + +#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 +# define write rpl_write +# endif +_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 +_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); +# endif +_GL_CXXALIASWARN (write); +#endif + +_GL_INLINE_HEADER_END + +#endif /* _@GUARD_PREFIX@_UNISTD_H */ +#endif /* _GL_INCLUDING_UNISTD_H */ +#endif /* _@GUARD_PREFIX@_UNISTD_H */ diff --git a/lib/unistr.in.h b/lib/unistr.in.h new file mode 100644 index 0000000..4d48751 --- /dev/null +++ b/lib/unistr.in.h @@ -0,0 +1,753 @@ +/* Elementary Unicode string functions. + Copyright (C) 2001-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 . */ + +#ifndef _UNISTR_H +#define _UNISTR_H + +#include "unitypes.h" + +/* Get bool. */ +#include + +/* Get size_t, ptrdiff_t. */ +#include + +/* Get free(). */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Conventions: + + All functions prefixed with u8_ operate on UTF-8 encoded strings. + Their unit is an uint8_t (1 byte). + + All functions prefixed with u16_ operate on UTF-16 encoded strings. + Their unit is an uint16_t (a 2-byte word). + + All functions prefixed with u32_ operate on UCS-4 encoded strings. + Their unit is an uint32_t (a 4-byte word). + + All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly + n units. + + All arguments starting with "str" and the arguments of functions starting + with u8_str/u16_str/u32_str denote a NUL terminated string, i.e. a string + which terminates at the first NUL unit. This termination unit is + considered part of the string for all memory allocation purposes, but + is not considered part of the string for all other logical purposes. + + Functions returning a string result take a (resultbuf, lengthp) argument + pair. If resultbuf is not NULL and the result fits into *lengthp units, + it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly + allocated string is returned. In both cases, *lengthp is set to the + length (number of units) of the returned string. In case of error, + NULL is returned and errno is set. */ + + +/* Elementary string checks. */ + +/* Check whether an UTF-8 string is well-formed. + Return NULL if valid, or a pointer to the first invalid unit otherwise. */ +extern const uint8_t * + u8_check (const uint8_t *s, size_t n) + _UC_ATTRIBUTE_PURE; + +/* Check whether an UTF-16 string is well-formed. + Return NULL if valid, or a pointer to the first invalid unit otherwise. */ +extern const uint16_t * + u16_check (const uint16_t *s, size_t n) + _UC_ATTRIBUTE_PURE; + +/* Check whether an UCS-4 string is well-formed. + Return NULL if valid, or a pointer to the first invalid unit otherwise. */ +extern const uint32_t * + u32_check (const uint32_t *s, size_t n) + _UC_ATTRIBUTE_PURE; + + +/* Elementary string conversions. */ + +/* Convert an UTF-8 string to an UTF-16 string. */ +extern uint16_t * + u8_to_u16 (const uint8_t *s, size_t n, uint16_t *resultbuf, + size_t *lengthp); + +/* Convert an UTF-8 string to an UCS-4 string. */ +extern uint32_t * + u8_to_u32 (const uint8_t *s, size_t n, uint32_t *resultbuf, + size_t *lengthp); + +/* Convert an UTF-16 string to an UTF-8 string. */ +extern uint8_t * + u16_to_u8 (const uint16_t *s, size_t n, uint8_t *resultbuf, + size_t *lengthp); + +/* Convert an UTF-16 string to an UCS-4 string. */ +extern uint32_t * + u16_to_u32 (const uint16_t *s, size_t n, uint32_t *resultbuf, + size_t *lengthp); + +/* Convert an UCS-4 string to an UTF-8 string. */ +extern uint8_t * + u32_to_u8 (const uint32_t *s, size_t n, uint8_t *resultbuf, + size_t *lengthp); + +/* Convert an UCS-4 string to an UTF-16 string. */ +extern uint16_t * + u32_to_u16 (const uint32_t *s, size_t n, uint16_t *resultbuf, + size_t *lengthp); + + +/* Elementary string functions. */ + +/* Return the length (number of units) of the first character in S, which is + no longer than N. Return 0 if it is the NUL character. Return -1 upon + failure. */ +/* Similar to mblen(), except that s must not be NULL. */ +extern int + u8_mblen (const uint8_t *s, size_t n) + _UC_ATTRIBUTE_PURE; +extern int + u16_mblen (const uint16_t *s, size_t n) + _UC_ATTRIBUTE_PURE; +extern int + u32_mblen (const uint32_t *s, size_t n) + _UC_ATTRIBUTE_PURE; + +/* Return the length (number of units) of the first character in S, putting + its 'ucs4_t' representation in *PUC. Upon failure, *PUC is set to 0xfffd, + and an appropriate number of units is returned. + The number of available units, N, must be > 0. */ +/* Similar to mbtowc(), except that puc and s must not be NULL, n must be > 0, + and the NUL character is not treated specially. */ +/* The variants with _unsafe suffix are for backward compatibility with + libunistring versions < 0.9.7. */ + +#if GNULIB_UNISTR_U8_MBTOUC_UNSAFE || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n); +# else +extern int + u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n); +static inline int +u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else + return u8_mbtouc_unsafe_aux (puc, s, n); +} +# endif +#endif + +#if GNULIB_UNISTR_U16_MBTOUC_UNSAFE || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n); +# else +extern int + u16_mbtouc_unsafe_aux (ucs4_t *puc, const uint16_t *s, size_t n); +static inline int +u16_mbtouc_unsafe (ucs4_t *puc, const uint16_t *s, size_t n) +{ + uint16_t c = *s; + + if (c < 0xd800 || c >= 0xe000) + { + *puc = c; + return 1; + } + else + return u16_mbtouc_unsafe_aux (puc, s, n); +} +# endif +#endif + +#if GNULIB_UNISTR_U32_MBTOUC_UNSAFE || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u32_mbtouc_unsafe (ucs4_t *puc, const uint32_t *s, size_t n); +# else +static inline int +u32_mbtouc_unsafe (ucs4_t *puc, + const uint32_t *s, _GL_ATTRIBUTE_MAYBE_UNUSED size_t n) +{ + uint32_t c = *s; + + if (c < 0xd800 || (c >= 0xe000 && c < 0x110000)) + *puc = c; + else + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} +# endif +#endif + +#if GNULIB_UNISTR_U8_MBTOUC || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n); +# else +extern int + u8_mbtouc_aux (ucs4_t *puc, const uint8_t *s, size_t n); +static inline int +u8_mbtouc (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else + return u8_mbtouc_aux (puc, s, n); +} +# endif +#endif + +#if GNULIB_UNISTR_U16_MBTOUC || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n); +# else +extern int + u16_mbtouc_aux (ucs4_t *puc, const uint16_t *s, size_t n); +static inline int +u16_mbtouc (ucs4_t *puc, const uint16_t *s, size_t n) +{ + uint16_t c = *s; + + if (c < 0xd800 || c >= 0xe000) + { + *puc = c; + return 1; + } + else + return u16_mbtouc_aux (puc, s, n); +} +# endif +#endif + +#if GNULIB_UNISTR_U32_MBTOUC || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u32_mbtouc (ucs4_t *puc, const uint32_t *s, size_t n); +# else +static inline int +u32_mbtouc (ucs4_t *puc, const uint32_t *s, + _GL_ATTRIBUTE_MAYBE_UNUSED size_t n) +{ + uint32_t c = *s; + + if (c < 0xd800 || (c >= 0xe000 && c < 0x110000)) + *puc = c; + else + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} +# endif +#endif + +/* Return the length (number of units) of the first character in S, putting + its 'ucs4_t' representation in *PUC. Upon failure, *PUC is set to 0xfffd, + and -1 is returned for an invalid sequence of units, -2 is returned for an + incomplete sequence of units. + The number of available units, N, must be > 0. */ +/* Similar to u*_mbtouc(), except that the return value gives more details + about the failure, similar to mbrtowc(). */ + +#if GNULIB_UNISTR_U8_MBTOUCR || HAVE_LIBUNISTRING +extern int + u8_mbtoucr (ucs4_t *puc, const uint8_t *s, size_t n); +#endif + +#if GNULIB_UNISTR_U16_MBTOUCR || HAVE_LIBUNISTRING +extern int + u16_mbtoucr (ucs4_t *puc, const uint16_t *s, size_t n); +#endif + +#if GNULIB_UNISTR_U32_MBTOUCR || HAVE_LIBUNISTRING +extern int + u32_mbtoucr (ucs4_t *puc, const uint32_t *s, size_t n); +#endif + +/* Put the multibyte character represented by UC in S, returning its + length. Return -1 upon failure, -2 if the number of available units, N, + is too small. The latter case cannot occur if N >= 6/2/1, respectively. */ +/* Similar to wctomb(), except that s must not be NULL, and the argument n + must be specified. */ + +#if GNULIB_UNISTR_U8_UCTOMB || HAVE_LIBUNISTRING +/* Auxiliary function, also used by u8_chr, u8_strchr, u8_strrchr. */ +extern int + u8_uctomb_aux (uint8_t *s, ucs4_t uc, ptrdiff_t n); +# if !HAVE_INLINE +extern int + u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n); +# else +static inline int +u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n) +{ + if (uc < 0x80 && n > 0) + { + s[0] = uc; + return 1; + } + else + return u8_uctomb_aux (s, uc, n); +} +# endif +#endif + +#if GNULIB_UNISTR_U16_UCTOMB || HAVE_LIBUNISTRING +/* Auxiliary function, also used by u16_chr, u16_strchr, u16_strrchr. */ +extern int + u16_uctomb_aux (uint16_t *s, ucs4_t uc, ptrdiff_t n); +# if !HAVE_INLINE +extern int + u16_uctomb (uint16_t *s, ucs4_t uc, ptrdiff_t n); +# else +static inline int +u16_uctomb (uint16_t *s, ucs4_t uc, ptrdiff_t n) +{ + if (uc < 0xd800 && n > 0) + { + s[0] = uc; + return 1; + } + else + return u16_uctomb_aux (s, uc, n); +} +# endif +#endif + +#if GNULIB_UNISTR_U32_UCTOMB || HAVE_LIBUNISTRING +# if !HAVE_INLINE +extern int + u32_uctomb (uint32_t *s, ucs4_t uc, ptrdiff_t n); +# else +static inline int +u32_uctomb (uint32_t *s, ucs4_t uc, ptrdiff_t n) +{ + if (uc < 0xd800 || (uc >= 0xe000 && uc < 0x110000)) + { + if (n > 0) + { + *s = uc; + return 1; + } + else + return -2; + } + else + return -1; +} +# endif +#endif + +/* Copy N units from SRC to DEST. */ +/* Similar to memcpy(). */ +extern uint8_t * + u8_cpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_cpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_cpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n); + +/* Copy N units from SRC to DEST, guaranteeing correct behavior for + overlapping memory areas. */ +/* Similar to memmove(). */ +extern uint8_t * + u8_move (uint8_t *dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_move (uint16_t *dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_move (uint32_t *dest, const uint32_t *src, size_t n); + +/* Set the first N characters of S to UC. UC should be a character that + occupies only 1 unit. */ +/* Similar to memset(). */ +extern uint8_t * + u8_set (uint8_t *s, ucs4_t uc, size_t n); +extern uint16_t * + u16_set (uint16_t *s, ucs4_t uc, size_t n); +extern uint32_t * + u32_set (uint32_t *s, ucs4_t uc, size_t n); + +/* Compare S1 and S2, each of length N. */ +/* Similar to memcmp(). */ +extern int + u8_cmp (const uint8_t *s1, const uint8_t *s2, size_t n) + _UC_ATTRIBUTE_PURE; +extern int + u16_cmp (const uint16_t *s1, const uint16_t *s2, size_t n) + _UC_ATTRIBUTE_PURE; +extern int + u32_cmp (const uint32_t *s1, const uint32_t *s2, size_t n) + _UC_ATTRIBUTE_PURE; + +/* Compare S1 and S2. */ +/* Similar to the gnulib function memcmp2(). */ +extern int + u8_cmp2 (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2) + _UC_ATTRIBUTE_PURE; +extern int + u16_cmp2 (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2) + _UC_ATTRIBUTE_PURE; +extern int + u32_cmp2 (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2) + _UC_ATTRIBUTE_PURE; + +/* Search the string at S for UC. */ +/* Similar to memchr(). */ +extern uint8_t * + u8_chr (const uint8_t *s, size_t n, ucs4_t uc) + _UC_ATTRIBUTE_PURE; +extern uint16_t * + u16_chr (const uint16_t *s, size_t n, ucs4_t uc) + _UC_ATTRIBUTE_PURE; +extern uint32_t * + u32_chr (const uint32_t *s, size_t n, ucs4_t uc) + _UC_ATTRIBUTE_PURE; + +/* Count the number of Unicode characters in the N units from S. */ +/* Similar to mbsnlen(). */ +extern size_t + u8_mbsnlen (const uint8_t *s, size_t n) + _UC_ATTRIBUTE_PURE; +extern size_t + u16_mbsnlen (const uint16_t *s, size_t n) + _UC_ATTRIBUTE_PURE; +extern size_t + u32_mbsnlen (const uint32_t *s, size_t n) + _UC_ATTRIBUTE_PURE; + +/* Elementary string functions with memory allocation. */ + +/* Make a freshly allocated copy of S, of length N. */ +extern uint8_t * + u8_cpy_alloc (const uint8_t *s, size_t n); +extern uint16_t * + u16_cpy_alloc (const uint16_t *s, size_t n); +extern uint32_t * + u32_cpy_alloc (const uint32_t *s, size_t n); + +/* Elementary string functions on NUL terminated strings. */ + +/* Return the length (number of units) of the first character in S. + Return 0 if it is the NUL character. Return -1 upon failure. */ +extern int + u8_strmblen (const uint8_t *s) + _UC_ATTRIBUTE_PURE; +extern int + u16_strmblen (const uint16_t *s) + _UC_ATTRIBUTE_PURE; +extern int + u32_strmblen (const uint32_t *s) + _UC_ATTRIBUTE_PURE; + +/* Return the length (number of units) of the first character in S, putting + its 'ucs4_t' representation in *PUC. Return 0 if it is the NUL + character. Return -1 upon failure. */ +extern int + u8_strmbtouc (ucs4_t *puc, const uint8_t *s); +extern int + u16_strmbtouc (ucs4_t *puc, const uint16_t *s); +extern int + u32_strmbtouc (ucs4_t *puc, const uint32_t *s); + +/* Forward iteration step. Advances the pointer past the next character, + or returns NULL if the end of the string has been reached. Puts the + character's 'ucs4_t' representation in *PUC. */ +extern const uint8_t * + u8_next (ucs4_t *puc, const uint8_t *s); +extern const uint16_t * + u16_next (ucs4_t *puc, const uint16_t *s); +extern const uint32_t * + u32_next (ucs4_t *puc, const uint32_t *s); + +/* Backward iteration step. Advances the pointer to point to the previous + character, or returns NULL if the beginning of the string had been reached. + Puts the character's 'ucs4_t' representation in *PUC. */ +extern const uint8_t * + u8_prev (ucs4_t *puc, const uint8_t *s, const uint8_t *start); +extern const uint16_t * + u16_prev (ucs4_t *puc, const uint16_t *s, const uint16_t *start); +extern const uint32_t * + u32_prev (ucs4_t *puc, const uint32_t *s, const uint32_t *start); + +/* Return the number of units in S. */ +/* Similar to strlen(), wcslen(). */ +extern size_t + u8_strlen (const uint8_t *s) + _UC_ATTRIBUTE_PURE; +extern size_t + u16_strlen (const uint16_t *s) + _UC_ATTRIBUTE_PURE; +extern size_t + u32_strlen (const uint32_t *s) + _UC_ATTRIBUTE_PURE; + +/* Return the number of units in S, but at most MAXLEN. */ +/* Similar to strnlen(), wcsnlen(). */ +extern size_t + u8_strnlen (const uint8_t *s, size_t maxlen) + _UC_ATTRIBUTE_PURE; +extern size_t + u16_strnlen (const uint16_t *s, size_t maxlen) + _UC_ATTRIBUTE_PURE; +extern size_t + u32_strnlen (const uint32_t *s, size_t maxlen) + _UC_ATTRIBUTE_PURE; + +/* Copy SRC to DEST. */ +/* Similar to strcpy(), wcscpy(). */ +extern uint8_t * + u8_strcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src); +extern uint16_t * + u16_strcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src); +extern uint32_t * + u32_strcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src); + +/* Copy SRC to DEST, returning the address of the terminating NUL in DEST. */ +/* Similar to stpcpy(). */ +extern uint8_t * + u8_stpcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src); +extern uint16_t * + u16_stpcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src); +extern uint32_t * + u32_stpcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src); + +/* Copy no more than N units of SRC to DEST. */ +/* Similar to strncpy(), wcsncpy(). */ +extern uint8_t * + u8_strncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_strncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_strncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n); + +/* Copy no more than N units of SRC to DEST. Return a pointer past the last + non-NUL unit written into DEST. */ +/* Similar to stpncpy(). */ +extern uint8_t * + u8_stpncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_stpncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_stpncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n); + +/* Append SRC onto DEST. */ +/* Similar to strcat(), wcscat(). */ +extern uint8_t * + u8_strcat (uint8_t *_UC_RESTRICT dest, const uint8_t *src); +extern uint16_t * + u16_strcat (uint16_t *_UC_RESTRICT dest, const uint16_t *src); +extern uint32_t * + u32_strcat (uint32_t *_UC_RESTRICT dest, const uint32_t *src); + +/* Append no more than N units of SRC onto DEST. */ +/* Similar to strncat(), wcsncat(). */ +extern uint8_t * + u8_strncat (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n); +extern uint16_t * + u16_strncat (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n); +extern uint32_t * + u32_strncat (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n); + +/* Compare S1 and S2. */ +/* Similar to strcmp(), wcscmp(). */ +#ifdef __sun +/* Avoid a collision with the u8_strcmp() function in Solaris 11 libc. */ +extern int + u8_strcmp_gnu (const uint8_t *s1, const uint8_t *s2) + _UC_ATTRIBUTE_PURE; +# define u8_strcmp u8_strcmp_gnu +#else +extern int + u8_strcmp (const uint8_t *s1, const uint8_t *s2) + _UC_ATTRIBUTE_PURE; +#endif +extern int + u16_strcmp (const uint16_t *s1, const uint16_t *s2) + _UC_ATTRIBUTE_PURE; +extern int + u32_strcmp (const uint32_t *s1, const uint32_t *s2) + _UC_ATTRIBUTE_PURE; + +/* Compare S1 and S2 using the collation rules of the current locale. + Return -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2. + Upon failure, set errno and return any value. */ +/* Similar to strcoll(), wcscoll(). */ +extern int + u8_strcoll (const uint8_t *s1, const uint8_t *s2); +extern int + u16_strcoll (const uint16_t *s1, const uint16_t *s2); +extern int + u32_strcoll (const uint32_t *s1, const uint32_t *s2); + +/* Compare no more than N units of S1 and S2. */ +/* Similar to strncmp(), wcsncmp(). */ +extern int + u8_strncmp (const uint8_t *s1, const uint8_t *s2, size_t n) + _UC_ATTRIBUTE_PURE; +extern int + u16_strncmp (const uint16_t *s1, const uint16_t *s2, size_t n) + _UC_ATTRIBUTE_PURE; +extern int + u32_strncmp (const uint32_t *s1, const uint32_t *s2, size_t n) + _UC_ATTRIBUTE_PURE; + +/* Duplicate S, returning an identical malloc'd string. */ +/* Similar to strdup(), wcsdup(). */ +extern uint8_t * + u8_strdup (const uint8_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; +extern uint16_t * + u16_strdup (const uint16_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; +extern uint32_t * + u32_strdup (const uint32_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + +/* Find the first occurrence of UC in STR. */ +/* Similar to strchr(), wcschr(). */ +extern uint8_t * + u8_strchr (const uint8_t *str, ucs4_t uc) + _UC_ATTRIBUTE_PURE; +extern uint16_t * + u16_strchr (const uint16_t *str, ucs4_t uc) + _UC_ATTRIBUTE_PURE; +extern uint32_t * + u32_strchr (const uint32_t *str, ucs4_t uc) + _UC_ATTRIBUTE_PURE; + +/* Find the last occurrence of UC in STR. */ +/* Similar to strrchr(), wcsrchr(). */ +extern uint8_t * + u8_strrchr (const uint8_t *str, ucs4_t uc) + _UC_ATTRIBUTE_PURE; +extern uint16_t * + u16_strrchr (const uint16_t *str, ucs4_t uc) + _UC_ATTRIBUTE_PURE; +extern uint32_t * + u32_strrchr (const uint32_t *str, ucs4_t uc) + _UC_ATTRIBUTE_PURE; + +/* Return the length of the initial segment of STR which consists entirely + of Unicode characters not in REJECT. */ +/* Similar to strcspn(), wcscspn(). */ +extern size_t + u8_strcspn (const uint8_t *str, const uint8_t *reject) + _UC_ATTRIBUTE_PURE; +extern size_t + u16_strcspn (const uint16_t *str, const uint16_t *reject) + _UC_ATTRIBUTE_PURE; +extern size_t + u32_strcspn (const uint32_t *str, const uint32_t *reject) + _UC_ATTRIBUTE_PURE; + +/* Return the length of the initial segment of STR which consists entirely + of Unicode characters in ACCEPT. */ +/* Similar to strspn(), wcsspn(). */ +extern size_t + u8_strspn (const uint8_t *str, const uint8_t *accept) + _UC_ATTRIBUTE_PURE; +extern size_t + u16_strspn (const uint16_t *str, const uint16_t *accept) + _UC_ATTRIBUTE_PURE; +extern size_t + u32_strspn (const uint32_t *str, const uint32_t *accept) + _UC_ATTRIBUTE_PURE; + +/* Find the first occurrence in STR of any character in ACCEPT. */ +/* Similar to strpbrk(), wcspbrk(). */ +extern uint8_t * + u8_strpbrk (const uint8_t *str, const uint8_t *accept) + _UC_ATTRIBUTE_PURE; +extern uint16_t * + u16_strpbrk (const uint16_t *str, const uint16_t *accept) + _UC_ATTRIBUTE_PURE; +extern uint32_t * + u32_strpbrk (const uint32_t *str, const uint32_t *accept) + _UC_ATTRIBUTE_PURE; + +/* Find the first occurrence of NEEDLE in HAYSTACK. */ +/* Similar to strstr(), wcsstr(). */ +extern uint8_t * + u8_strstr (const uint8_t *haystack, const uint8_t *needle) + _UC_ATTRIBUTE_PURE; +extern uint16_t * + u16_strstr (const uint16_t *haystack, const uint16_t *needle) + _UC_ATTRIBUTE_PURE; +extern uint32_t * + u32_strstr (const uint32_t *haystack, const uint32_t *needle) + _UC_ATTRIBUTE_PURE; + +/* Test whether STR starts with PREFIX. */ +extern bool + u8_startswith (const uint8_t *str, const uint8_t *prefix) + _UC_ATTRIBUTE_PURE; +extern bool + u16_startswith (const uint16_t *str, const uint16_t *prefix) + _UC_ATTRIBUTE_PURE; +extern bool + u32_startswith (const uint32_t *str, const uint32_t *prefix) + _UC_ATTRIBUTE_PURE; + +/* Test whether STR ends with SUFFIX. */ +extern bool + u8_endswith (const uint8_t *str, const uint8_t *suffix) + _UC_ATTRIBUTE_PURE; +extern bool + u16_endswith (const uint16_t *str, const uint16_t *suffix) + _UC_ATTRIBUTE_PURE; +extern bool + u32_endswith (const uint32_t *str, const uint32_t *suffix) + _UC_ATTRIBUTE_PURE; + +/* Divide STR into tokens separated by characters in DELIM. + This interface is actually more similar to wcstok than to strtok. */ +/* Similar to strtok_r(), wcstok(). */ +extern uint8_t * + u8_strtok (uint8_t *_UC_RESTRICT str, const uint8_t *delim, + uint8_t **ptr); +extern uint16_t * + u16_strtok (uint16_t *_UC_RESTRICT str, const uint16_t *delim, + uint16_t **ptr); +extern uint32_t * + u32_strtok (uint32_t *_UC_RESTRICT str, const uint32_t *delim, + uint32_t **ptr); + + +#ifdef __cplusplus +} +#endif + +#endif /* _UNISTR_H */ diff --git a/lib/unistr/u-cpy.h b/lib/unistr/u-cpy.h new file mode 100644 index 0000000..f0b3bc8 --- /dev/null +++ b/lib/unistr/u-cpy.h @@ -0,0 +1,33 @@ +/* Copy piece of UTF-8/UTF-16/UTF-32 string. + Copyright (C) 1999, 2002, 2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 + +UNIT * +FUNC (UNIT *dest, const UNIT *src, size_t n) +{ +#if 0 + UNIT *destptr = dest; + + for (; n > 0; n--) + *destptr++ = *src++; +#else + if (n > 0) + memcpy ((char *) dest, (const char *) src, n * sizeof (UNIT)); +#endif + return dest; +} diff --git a/lib/unistr/u8-cpy.c b/lib/unistr/u8-cpy.c new file mode 100644 index 0000000..e25c264 --- /dev/null +++ b/lib/unistr/u8-cpy.c @@ -0,0 +1,33 @@ +/* Copy piece of UTF-8 string. + Copyright (C) 2002, 2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#include + +/* Specification. */ +#include "unistr.h" + +#define FUNC u8_cpy +#define UNIT uint8_t +#include "u-cpy.h" diff --git a/lib/unistr/u8-mbtouc-unsafe-aux.c b/lib/unistr/u8-mbtouc-unsafe-aux.c new file mode 100644 index 0000000..36e40af --- /dev/null +++ b/lib/unistr/u8-mbtouc-unsafe-aux.c @@ -0,0 +1,139 @@ +/* Conversion UTF-8 to UCS-4. + Copyright (C) 2001-2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + 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 "unistr.h" + +#if defined IN_LIBUNISTRING || HAVE_INLINE + +int +u8_mbtouc_unsafe_aux (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return 1; + } + } + else if (c < 0xf0) + { + if (n >= 3) + { + if ((s[1] ^ 0x80) < 0x40) + { + if ((s[2] ^ 0x80) < 0x40) + { + if ((c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 3; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + if (n == 1 || (s[1] ^ 0x80) >= 0x40) + return 1; + else + return 2; + } + } + else if (c < 0xf8) + { + if (n >= 4) + { + if ((s[1] ^ 0x80) < 0x40) + { + if ((s[2] ^ 0x80) < 0x40) + { + if ((s[3] ^ 0x80) < 0x40) + { + if ((c >= 0xf1 || s[1] >= 0x90) + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) + ) + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 4; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 3; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + if (n == 1 || (s[1] ^ 0x80) >= 0x40) + return 1; + else if (n == 2 || (s[2] ^ 0x80) >= 0x40) + return 2; + else + return 3; + } + } + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} + +#endif diff --git a/lib/unistr/u8-mbtouc-unsafe.c b/lib/unistr/u8-mbtouc-unsafe.c new file mode 100644 index 0000000..3dd30a1 --- /dev/null +++ b/lib/unistr/u8-mbtouc-unsafe.c @@ -0,0 +1,150 @@ +/* Look at first character in UTF-8 string. + Copyright (C) 1999-2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + 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 + +#if defined IN_LIBUNISTRING +/* Tell unistr.h to declare u8_mbtouc_unsafe as 'extern', not + 'static inline'. */ +# include "unistring-notinline.h" +#endif + +/* Specification. */ +#include "unistr.h" + +#if !HAVE_INLINE + +int +u8_mbtouc_unsafe (ucs4_t *puc, const uint8_t *s, size_t n) +{ + uint8_t c = *s; + + if (c < 0x80) + { + *puc = c; + return 1; + } + else if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + if ((s[1] ^ 0x80) < 0x40) + { + *puc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (s[1] ^ 0x80); + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + return 1; + } + } + else if (c < 0xf0) + { + if (n >= 3) + { + if ((s[1] ^ 0x80) < 0x40) + { + if ((s[2] ^ 0x80) < 0x40) + { + if ((c >= 0xe1 || s[1] >= 0xa0) + && (c != 0xed || s[1] < 0xa0)) + { + *puc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (s[1] ^ 0x80) << 6) + | (unsigned int) (s[2] ^ 0x80); + return 3; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 3; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + if (n == 1 || (s[1] ^ 0x80) >= 0x40) + return 1; + else + return 2; + } + } + else if (c < 0xf8) + { + if (n >= 4) + { + if ((s[1] ^ 0x80) < 0x40) + { + if ((s[2] ^ 0x80) < 0x40) + { + if ((s[3] ^ 0x80) < 0x40) + { + if ((c >= 0xf1 || s[1] >= 0x90) + && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90)) + ) + { + *puc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (s[1] ^ 0x80) << 12) + | ((unsigned int) (s[2] ^ 0x80) << 6) + | (unsigned int) (s[3] ^ 0x80); + return 4; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 4; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 3; + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 2; + } + /* invalid multibyte character */ + } + else + { + /* incomplete multibyte character */ + *puc = 0xfffd; + if (n == 1 || (s[1] ^ 0x80) >= 0x40) + return 1; + else if (n == 2 || (s[2] ^ 0x80) >= 0x40) + return 2; + else + return 3; + } + } + } + /* invalid multibyte character */ + *puc = 0xfffd; + return 1; +} + +#endif diff --git a/lib/unistr/u8-strlen.c b/lib/unistr/u8-strlen.c new file mode 100644 index 0000000..6892ec0 --- /dev/null +++ b/lib/unistr/u8-strlen.c @@ -0,0 +1,29 @@ +/* Determine length of UTF-8 string. + Copyright (C) 2002, 2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 "unistr.h" + +#include + +size_t +u8_strlen (const uint8_t *s) +{ + return strlen ((const char *) s); +} diff --git a/lib/unistr/u8-uctomb-aux.c b/lib/unistr/u8-uctomb-aux.c new file mode 100644 index 0000000..5ca2191 --- /dev/null +++ b/lib/unistr/u8-uctomb-aux.c @@ -0,0 +1,60 @@ +/* Conversion UCS-4 to UTF-8. + Copyright (C) 2002, 2006-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 "unistr.h" + +#include "attribute.h" + +int +u8_uctomb_aux (uint8_t *s, ucs4_t uc, ptrdiff_t n) +{ + int count; + + if (uc < 0x80) + /* The case n >= 1 is already handled by the caller. */ + return -2; + else if (uc < 0x800) + count = 2; + else if (uc < 0x10000) + { + if (uc < 0xd800 || uc >= 0xe000) + count = 3; + else + return -1; + } + else if (uc < 0x110000) + count = 4; + else + return -1; + + if (n < count) + return -2; + + switch (count) /* note: code falls through cases! */ + { + case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000; + FALLTHROUGH; + case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800; + FALLTHROUGH; + case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0; + /*case 1:*/ s[0] = uc; + } + return count; +} diff --git a/lib/unistr/u8-uctomb.c b/lib/unistr/u8-uctomb.c new file mode 100644 index 0000000..2259b1d --- /dev/null +++ b/lib/unistr/u8-uctomb.c @@ -0,0 +1,79 @@ +/* Store a character in UTF-8 string. + Copyright (C) 2002, 2005-2006, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 + +#if defined IN_LIBUNISTRING +/* Tell unistr.h to declare u8_uctomb as 'extern', not 'static inline'. */ +# include "unistring-notinline.h" +#endif + +/* Specification. */ +#include "unistr.h" + +#include "attribute.h" + +#if !HAVE_INLINE + +int +u8_uctomb (uint8_t *s, ucs4_t uc, ptrdiff_t n) +{ + if (uc < 0x80) + { + if (n > 0) + { + s[0] = uc; + return 1; + } + /* else return -2, below. */ + } + else + { + int count; + + if (uc < 0x800) + count = 2; + else if (uc < 0x10000) + { + if (uc < 0xd800 || uc >= 0xe000) + count = 3; + else + return -1; + } + else if (uc < 0x110000) + count = 4; + else + return -1; + + if (n >= count) + { + switch (count) /* note: code falls through cases! */ + { + case 4: s[3] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x10000; + FALLTHROUGH; + case 3: s[2] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0x800; + FALLTHROUGH; + case 2: s[1] = 0x80 | (uc & 0x3f); uc = uc >> 6; uc |= 0xc0; + /*case 1:*/ s[0] = uc; + } + return count; + } + } + return -2; +} + +#endif diff --git a/lib/unitypes.in.h b/lib/unitypes.in.h new file mode 100644 index 0000000..4ea83aa --- /dev/null +++ b/lib/unitypes.in.h @@ -0,0 +1,61 @@ +/* Elementary types and macros for the GNU UniString library. + Copyright (C) 2002, 2005-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 _UNITYPES_H +#define _UNITYPES_H + +/* Get uint8_t, uint16_t, uint32_t. */ +#include + +/* Type representing a Unicode character. */ +typedef uint32_t ucs4_t; + +/* Attribute of a function whose result depends only on the arguments + (not pointers!) and which has no side effects. */ +#ifndef _UC_ATTRIBUTE_CONST +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined __clang__ +# define _UC_ATTRIBUTE_CONST __attribute__ ((__const__)) +# else +# define _UC_ATTRIBUTE_CONST +# endif +#endif + +/* Attribute of a function whose result depends only on the arguments + (possibly pointers) and global memory, and which has no side effects. */ +#ifndef _UC_ATTRIBUTE_PURE +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ +# define _UC_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define _UC_ATTRIBUTE_PURE +# endif +#endif + +/* Qualifier in a function declaration, that asserts that the caller must + pass a pointer to a different object in the specified pointer argument + than in the other pointer arguments. */ +#ifndef _UC_RESTRICT +# if defined __restrict \ + || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ + || __clang_major__ >= 3 +# define _UC_RESTRICT __restrict +# elif 199901L <= __STDC_VERSION__ || defined restrict +# define _UC_RESTRICT restrict +# else +# define _UC_RESTRICT +# endif +#endif + +#endif /* _UNITYPES_H */ diff --git a/lib/uniwidth.in.h b/lib/uniwidth.in.h new file mode 100644 index 0000000..d5e62c4 --- /dev/null +++ b/lib/uniwidth.in.h @@ -0,0 +1,72 @@ +/* Display width functions. + Copyright (C) 2001-2002, 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 . */ + +#ifndef _UNIWIDTH_H +#define _UNIWIDTH_H + +#include "unitypes.h" + +/* Get size_t. */ +#include + +/* Get locale_charset() declaration. */ +#include "localcharset.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Display width. */ + +/* These functions are locale dependent. The encoding argument identifies + the encoding (e.g. "ISO-8859-2" for Polish). */ + +/* Determine number of column positions required for UC. */ +extern int + uc_width (ucs4_t uc, const char *encoding) + _UC_ATTRIBUTE_PURE; + +/* Determine number of column positions required for first N units + (or fewer if S ends before this) in S. */ +extern int + u8_width (const uint8_t *s, size_t n, const char *encoding) + _UC_ATTRIBUTE_PURE; +extern int + u16_width (const uint16_t *s, size_t n, const char *encoding) + _UC_ATTRIBUTE_PURE; +extern int + u32_width (const uint32_t *s, size_t n, const char *encoding) + _UC_ATTRIBUTE_PURE; + +/* Determine number of column positions required for S. */ +extern int + u8_strwidth (const uint8_t *s, const char *encoding) + _UC_ATTRIBUTE_PURE; +extern int + u16_strwidth (const uint16_t *s, const char *encoding) + _UC_ATTRIBUTE_PURE; +extern int + u32_strwidth (const uint32_t *s, const char *encoding) + _UC_ATTRIBUTE_PURE; + + +#ifdef __cplusplus +} +#endif + +#endif /* _UNIWIDTH_H */ diff --git a/lib/uniwidth/cjk.h b/lib/uniwidth/cjk.h new file mode 100644 index 0000000..b791ba9 --- /dev/null +++ b/lib/uniwidth/cjk.h @@ -0,0 +1,37 @@ +/* Test for CJK encoding. + Copyright (C) 2001-2002, 2005-2007, 2009-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 "streq.h" + +static int +is_cjk_encoding (const char *encoding) +{ + if (0 + /* Legacy Japanese encodings */ + || STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) + /* Legacy Chinese encodings */ + || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) + || STREQ_OPT (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) + || STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) + || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) + /* Legacy Korean encodings */ + || STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + || STREQ_OPT (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) + || STREQ_OPT (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) + return 1; + return 0; +} diff --git a/lib/uniwidth/width.c b/lib/uniwidth/width.c new file mode 100644 index 0000000..1c945a8 --- /dev/null +++ b/lib/uniwidth/width.c @@ -0,0 +1,95 @@ +/* Determine display width of Unicode character. + Copyright (C) 2001-2002, 2006-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2002. + + 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 "uniwidth.h" + +#include "cjk.h" + +/* The non-spacing attribute table consists of: + * Non-spacing characters; generated from PropList.txt or + "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt" + * Format control characters; generated from + "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt" + * Zero width characters; generated from + "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt" + * Hangul Jamo characters that have conjoining behaviour: + - jungseong = syllable-middle vowels + - jongseong = syllable-final consonants + Rationale: + 1) These characters act like combining characters. They have no + equivalent in legacy character sets. Therefore the EastAsianWidth.txt + file does not really matter for them; UAX #11 East Asian Width + makes it clear that it focus + is on compatibility with traditional Japanese layout. + By contrast, the same glyphs without conjoining behaviour are available + in the U+3130..U+318F block, and these characters are mapped to legacy + character sets, and traditional Japanese layout matters for them. + 2) glibc does the same thing, see + + + */ +#include "uniwidth/width0.h" + +#include "uniwidth/width2.h" +#include "unictype/bitmap.h" + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + + +/* Determine number of column positions required for UC. */ +int +uc_width (ucs4_t uc, const char *encoding) +{ + /* Test for non-spacing or control character. */ + if ((uc >> 9) < SIZEOF (nonspacing_table_ind)) + { + int ind = nonspacing_table_ind[uc >> 9]; + if (ind >= 0) + if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1) + { + if (uc > 0 && uc < 0xa0) + return -1; + else + return 0; + } + } + else if ((uc >> 9) == (0xe0000 >> 9)) + { + if (uc >= 0xe0100) + { + if (uc <= 0xe01ef) + return 0; + } + else + { + if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001) + return 0; + } + } + /* Test for double-width character. */ + if (bitmap_lookup (&u_width2, uc)) + return 2; + /* In ancient CJK encodings, Cyrillic and most other characters are + double-width as well. */ + if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9 + && is_cjk_encoding (encoding)) + return 2; + return 1; +} diff --git a/lib/uniwidth/width0.h b/lib/uniwidth/width0.h new file mode 100644 index 0000000..eda0a1d --- /dev/null +++ b/lib/uniwidth/width0.h @@ -0,0 +1,485 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Table of non-spacing or control characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +static const unsigned char nonspacing_table_data[47*64] = { + /* 0x0000-0x01ff */ + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0000-0x003f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x0040-0x007f */ + 0xff, 0xff, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, /* 0x0080-0x00bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00c0-0x00ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0100-0x013f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0140-0x017f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180-0x01bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0-0x01ff */ + /* 0x0200-0x03ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200-0x023f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240-0x027f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280-0x02bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c0-0x02ff */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x0300-0x033f */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x0340-0x037f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0380-0x03bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x03c0-0x03ff */ + /* 0x0400-0x05ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0400-0x043f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0440-0x047f */ + 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0480-0x04bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04c0-0x04ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0500-0x053f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0540-0x057f */ + 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, /* 0x0580-0x05bf */ + 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x05c0-0x05ff */ + /* 0x0600-0x07ff */ + 0x3f, 0x00, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, /* 0x0600-0x063f */ + 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, /* 0x0640-0x067f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0680-0x06bf */ + 0x00, 0x00, 0xc0, 0xbf, 0x9f, 0x3d, 0x00, 0x00, /* 0x06c0-0x06ff */ + 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x0700-0x073f */ + 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0740-0x077f */ + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, /* 0x0780-0x07bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x20, /* 0x07c0-0x07ff */ + /* 0x0800-0x09ff */ + 0x00, 0x00, 0xc0, 0xfb, 0xef, 0x3e, 0x00, 0x00, /* 0x0800-0x083f */ + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x0840-0x087f */ + 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ + 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x08c0-0x08ff */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, /* 0x0900-0x093f */ + 0xfe, 0x21, 0xfe, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0940-0x097f */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0980-0x09bf */ + 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, /* 0x09c0-0x09ff */ + /* 0x0a00-0x0bff */ + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a00-0x0a3f */ + 0x86, 0x39, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, /* 0x0a40-0x0a7f */ + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a80-0x0abf */ + 0xbe, 0x21, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xfc, /* 0x0ac0-0x0aff */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ + 0x1e, 0x20, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0b40-0x0b7f */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b80-0x0bbf */ + 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0bc0-0x0bff */ + /* 0x0c00-0x0dff */ + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, /* 0x0c00-0x0c3f */ + 0xc1, 0x3d, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ + 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0x0d00-0x0d3f */ + 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d80-0x0dbf */ + 0x00, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0dc0-0x0dff */ + /* 0x0e00-0x0fff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x07, /* 0x0e00-0x0e3f */ + 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e40-0x0e7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1f, /* 0x0e80-0x0ebf */ + 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0ec0-0x0eff */ + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xa0, 0x02, /* 0x0f00-0x0f3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, /* 0x0f40-0x0f7f */ + 0xdf, 0xe0, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, /* 0x0f80-0x0fbf */ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0fc0-0x0fff */ + /* 0x1000-0x11ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x66, /* 0x1000-0x103f */ + 0x00, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x1e, 0x00, /* 0x1040-0x107f */ + 0x64, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x1080-0x10bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c0-0x10ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1100-0x113f */ + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x1140-0x117f */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x1180-0x11bf */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x11c0-0x11ff */ + /* 0x1200-0x13ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1200-0x123f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1240-0x127f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1280-0x12bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x12c0-0x12ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1300-0x133f */ + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, /* 0x1340-0x137f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1380-0x13bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13c0-0x13ff */ + /* 0x1600-0x17ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1600-0x163f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1640-0x167f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1680-0x16bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16c0-0x16ff */ + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1700-0x173f */ + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1740-0x177f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, /* 0x1780-0x17bf */ + 0x40, 0xfe, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x17c0-0x17ff */ + /* 0x1800-0x19ff */ + 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x1880-0x18bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18c0-0x18ff */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x04, 0x0e, /* 0x1900-0x193f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1940-0x197f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1980-0x19bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x19c0-0x19ff */ + /* 0x1a00-0x1bff */ + 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ + 0x00, 0x00, 0x40, 0x7f, 0xe5, 0x1f, 0xf8, 0x9f, /* 0x1a40-0x1a7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x1a80-0x1abf */ + 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ac0-0x1aff */ + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x17, /* 0x1b00-0x1b3f */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x1b40-0x1b7f */ + 0x03, 0x00, 0x00, 0x00, 0x3c, 0x3b, 0x00, 0x00, /* 0x1b80-0x1bbf */ + 0x00, 0x00, 0x00, 0x00, 0x40, 0xa3, 0x03, 0x00, /* 0x1bc0-0x1bff */ + /* 0x1c00-0x1dff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, /* 0x1c00-0x1c3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c40-0x1c7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c80-0x1cbf */ + 0x00, 0x00, 0xf7, 0xff, 0xfd, 0x21, 0x10, 0x03, /* 0x1cc0-0x1cff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d00-0x1d3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d40-0x1d7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d80-0x1dbf */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x1dc0-0x1dff */ + /* 0x2000-0x21ff */ + 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ + 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, /* 0x2040-0x207f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2080-0x20bf */ + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, /* 0x20c0-0x20ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2100-0x213f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2140-0x217f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2180-0x21bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21c0-0x21ff */ + /* 0x2c00-0x2dff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c00-0x2c3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c40-0x2c7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c80-0x2cbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, /* 0x2cc0-0x2cff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d00-0x2d3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x2d40-0x2d7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d80-0x2dbf */ + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x2dc0-0x2dff */ + /* 0x3000-0x31ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x3000-0x303f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3040-0x307f */ + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, /* 0x3080-0x30bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30c0-0x30ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3100-0x313f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3140-0x317f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3180-0x31bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x31c0-0x31ff */ + /* 0xa600-0xa7ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa600-0xa63f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf7, 0x3f, /* 0xa640-0xa67f */ + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, /* 0xa680-0xa6bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0xa6c0-0xa6ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa700-0xa73f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa740-0xa77f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa780-0xa7bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa7c0-0xa7ff */ + /* 0xa800-0xa9ff */ + 0x44, 0x08, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, /* 0xa800-0xa83f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ + 0x30, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x80, /* 0xa8c0-0xa8ff */ + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, /* 0xa900-0xa93f */ + 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa940-0xa97f */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x33, /* 0xa980-0xa9bf */ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ + /* 0xaa00-0xabff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x66, 0x00, /* 0xaa00-0xaa3f */ + 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0xaa40-0xaa7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xc1, /* 0xaa80-0xaabf */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x00, /* 0xaac0-0xaaff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab00-0xab3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab40-0xab7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab80-0xabbf */ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00, /* 0xabc0-0xabff */ + /* 0xd600-0xd7ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd600-0xd63f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd640-0xd67f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd680-0xd6bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd6c0-0xd6ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd700-0xd73f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd740-0xd77f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0xd780-0xd7bf */ + 0x7f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, /* 0xd7c0-0xd7ff */ + /* 0xfa00-0xfbff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa00-0xfa3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa40-0xfa7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa80-0xfabf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfac0-0xfaff */ + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0xfb00-0xfb3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb40-0xfb7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb80-0xfbbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfbc0-0xfbff */ + /* 0xfe00-0xffff */ + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, /* 0xfe00-0xfe3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe40-0xfe7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe80-0xfebf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xfec0-0xfeff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff00-0xff3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff40-0xff7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff80-0xffbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, /* 0xffc0-0xffff */ + /* 0x10000-0x101ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10000-0x1003f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10040-0x1007f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10080-0x100bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100c0-0x100ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10100-0x1013f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10140-0x1017f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10180-0x101bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0x101c0-0x101ff */ + /* 0x10200-0x103ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10200-0x1023f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10240-0x1027f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10280-0x102bf */ + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* 0x102c0-0x102ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10300-0x1033f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, /* 0x10340-0x1037f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10380-0x103bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x103c0-0x103ff */ + /* 0x10a00-0x10bff */ + 0x6e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x10a00-0x10a3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a40-0x10a7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a80-0x10abf */ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0x10ac0-0x10aff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b00-0x10b3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b40-0x10b7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b80-0x10bbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10bc0-0x10bff */ + /* 0x10c00-0x10dff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c00-0x10c3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c40-0x10c7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c80-0x10cbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10cc0-0x10cff */ + 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, /* 0x10d00-0x10d3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10d40-0x10d7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10d80-0x10dbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10dc0-0x10dff */ + /* 0x10e00-0x10fff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10e00-0x10e3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10e40-0x10e7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, /* 0x10e80-0x10ebf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10ec0-0x10eff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10f00-0x10f3f */ + 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10f40-0x10f7f */ + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10f80-0x10fbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10fc0-0x10fff */ + /* 0x11000-0x111ff */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11000-0x1103f */ + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x80, /* 0x11040-0x1107f */ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x26, /* 0x11080-0x110bf */ + 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110c0-0x110ff */ + 0x07, 0x00, 0x00, 0x00, 0x80, 0xef, 0x1f, 0x00, /* 0x11100-0x1113f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, /* 0x11140-0x1117f */ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, /* 0x11180-0x111bf */ + 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x111c0-0x111ff */ + /* 0x11200-0x113ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd3, 0x40, /* 0x11200-0x1123f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11240-0x1127f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11280-0x112bf */ + 0x00, 0x00, 0x00, 0x80, 0xf8, 0x07, 0x00, 0x00, /* 0x112c0-0x112ff */ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0x11300-0x1133f */ + 0x01, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x1f, 0x00, /* 0x11340-0x1137f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11380-0x113bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x113c0-0x113ff */ + /* 0x11400-0x115ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11400-0x1143f */ + 0x5c, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0x11440-0x1147f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x85, /* 0x11480-0x114bf */ + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x114c0-0x114ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11500-0x1153f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11540-0x1157f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb0, /* 0x11580-0x115bf */ + 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, /* 0x115c0-0x115ff */ + /* 0x11600-0x117ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa7, /* 0x11600-0x1163f */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11640-0x1167f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xbf, 0x00, /* 0x11680-0x116bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x116c0-0x116ff */ + 0x00, 0x00, 0x00, 0xe0, 0xbc, 0x0f, 0x00, 0x00, /* 0x11700-0x1173f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11740-0x1177f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11780-0x117bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x117c0-0x117ff */ + /* 0x11800-0x119ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x06, /* 0x11800-0x1183f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11840-0x1187f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11880-0x118bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118c0-0x118ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, /* 0x11900-0x1193f */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11940-0x1197f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11980-0x119bf */ + 0x00, 0x00, 0xf0, 0x0c, 0x01, 0x00, 0x00, 0x00, /* 0x119c0-0x119ff */ + /* 0x11a00-0x11bff */ + 0x7e, 0x06, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x79, /* 0x11a00-0x11a3f */ + 0x80, 0x00, 0x7e, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x11a40-0x11a7f */ + 0x00, 0xfc, 0x7f, 0x03, 0x00, 0x00, 0x00, 0x00, /* 0x11a80-0x11abf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11ac0-0x11aff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11b00-0x11b3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11b40-0x11b7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11b80-0x11bbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11bc0-0x11bff */ + /* 0x11c00-0x11dff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x3f, /* 0x11c00-0x11c3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11c40-0x11c7f */ + 0x00, 0x00, 0xfc, 0xff, 0xff, 0xfc, 0x6d, 0x00, /* 0x11c80-0x11cbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11cc0-0x11cff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xb4, /* 0x11d00-0x11d3f */ + 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11d40-0x11d7f */ + 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11d80-0x11dbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11dc0-0x11dff */ + /* 0x11e00-0x11fff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11e00-0x11e3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11e40-0x11e7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11e80-0x11ebf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, /* 0x11ec0-0x11eff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11f00-0x11f3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11f40-0x11f7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11f80-0x11fbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11fc0-0x11fff */ + /* 0x13400-0x135ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, /* 0x13400-0x1343f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13440-0x1347f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13480-0x134bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x134c0-0x134ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13500-0x1353f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13540-0x1357f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13580-0x135bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x135c0-0x135ff */ + /* 0x16a00-0x16bff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16a00-0x16a3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16a40-0x16a7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16a80-0x16abf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, /* 0x16ac0-0x16aff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, /* 0x16b00-0x16b3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16b40-0x16b7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16b80-0x16bbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16bc0-0x16bff */ + /* 0x16e00-0x16fff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16e00-0x16e3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16e40-0x16e7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16e80-0x16ebf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16ec0-0x16eff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16f00-0x16f3f */ + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16f40-0x16f7f */ + 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16f80-0x16fbf */ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, /* 0x16fc0-0x16fff */ + /* 0x1bc00-0x1bdff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bc00-0x1bc3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bc40-0x1bc7f */ + 0x00, 0x00, 0x00, 0x60, 0x0f, 0x00, 0x00, 0x00, /* 0x1bc80-0x1bcbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bcc0-0x1bcff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bd00-0x1bd3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bd40-0x1bd7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bd80-0x1bdbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bdc0-0x1bdff */ + /* 0x1ce00-0x1cfff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ce00-0x1ce3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ce40-0x1ce7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ce80-0x1cebf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cec0-0x1ceff */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, /* 0x1cf00-0x1cf3f */ + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cf40-0x1cf7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cf80-0x1cfbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cfc0-0x1cfff */ + /* 0x1d000-0x1d1ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d000-0x1d03f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d040-0x1d07f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d080-0x1d0bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0c0-0x1d0ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d100-0x1d13f */ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xf8, 0xff, /* 0x1d140-0x1d17f */ + 0xe7, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x1d180-0x1d1bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d1c0-0x1d1ff */ + /* 0x1d200-0x1d3ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d200-0x1d23f */ + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d240-0x1d27f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d280-0x1d2bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d2c0-0x1d2ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d300-0x1d33f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d340-0x1d37f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d380-0x1d3bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d3c0-0x1d3ff */ + /* 0x1da00-0x1dbff */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf8, /* 0x1da00-0x1da3f */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x20, 0x00, /* 0x1da40-0x1da7f */ + 0x10, 0x00, 0x00, 0xf8, 0xfe, 0xff, 0x00, 0x00, /* 0x1da80-0x1dabf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1dac0-0x1daff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1db00-0x1db3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1db40-0x1db7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1db80-0x1dbbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1dbc0-0x1dbff */ + /* 0x1e000-0x1e1ff */ + 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07, 0x00, 0x00, /* 0x1e000-0x1e03f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e040-0x1e07f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e080-0x1e0bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0c0-0x1e0ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, /* 0x1e100-0x1e13f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e140-0x1e17f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e180-0x1e1bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e1c0-0x1e1ff */ + /* 0x1e200-0x1e3ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e200-0x1e23f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e240-0x1e27f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, /* 0x1e280-0x1e2bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, /* 0x1e2c0-0x1e2ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e300-0x1e33f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e340-0x1e37f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e380-0x1e3bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e3c0-0x1e3ff */ + /* 0x1e800-0x1e9ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e800-0x1e83f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e840-0x1e87f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e880-0x1e8bf */ + 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8c0-0x1e8ff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e900-0x1e93f */ + 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e940-0x1e97f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e980-0x1e9bf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x1e9c0-0x1e9ff */ +}; +static const signed char nonspacing_table_ind[248] = { + 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000-0x0fff */ + 8, 9, -1, 10, 11, 12, 13, -1, /* 0x1000-0x1fff */ + 14, -1, -1, -1, -1, -1, 15, -1, /* 0x2000-0x2fff */ + 16, -1, -1, -1, -1, -1, -1, -1, /* 0x3000-0x3fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x4000-0x4fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x5000-0x5fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x6000-0x6fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x7000-0x7fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x8000-0x8fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9000-0x9fff */ + -1, -1, -1, 17, 18, 19, -1, -1, /* 0xa000-0xafff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb000-0xbfff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc000-0xcfff */ + -1, -1, -1, 20, -1, -1, -1, -1, /* 0xd000-0xdfff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ + -1, -1, -1, -1, -1, 21, -1, 22, /* 0xf000-0xffff */ + 23, 24, -1, -1, -1, 25, 26, 27, /* 0x10000-0x10fff */ + 28, 29, 30, 31, 32, 33, 34, 35, /* 0x11000-0x11fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ + -1, -1, 36, -1, -1, -1, -1, -1, /* 0x13000-0x13fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x14000-0x14fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x15000-0x15fff */ + -1, -1, -1, -1, -1, 37, -1, 38, /* 0x16000-0x16fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x17000-0x17fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18000-0x18fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x19000-0x19fff */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1a000-0x1afff */ + -1, -1, -1, -1, -1, -1, 39, -1, /* 0x1b000-0x1bfff */ + -1, -1, -1, -1, -1, -1, -1, 40, /* 0x1c000-0x1cfff */ + 41, 42, -1, -1, -1, 43, -1, -1, /* 0x1d000-0x1dfff */ + 44, 45, -1, -1, 46, -1, -1, -1 /* 0x1e000-0x1efff */ +}; diff --git a/lib/uniwidth/width2.h b/lib/uniwidth/width2.h new file mode 100644 index 0000000..25364d3 --- /dev/null +++ b/lib/uniwidth/width2.h @@ -0,0 +1,549 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Width 2 property of Unicode characters. */ +/* Generated automatically by gen-uni-tables.c for Unicode 14.0.0. */ + +/* Copyright (C) 2000-2022 Free Software Foundation, Inc. + + This file is free software. + It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". + You can redistribute it and/or modify it under either + - the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3, or (at your + option) any later version, or + - the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version, or + - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". + + 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 and the GNU General Public License + for more details. + + You should have received a copy of the GNU Lesser General Public + License and of the GNU General Public License along with this + program. If not, see . */ + +#define header_0 16 +#define header_2 9 +#define header_3 127 +#define header_4 15 +static const +struct + { + int header[1]; + int level1[4]; + short level2[3 << 7]; + unsigned int level3[28 << 4]; + } +u_width2 = +{ + { 4 }, + { + 5 * sizeof (int) / sizeof (short) + 0, + 5 * sizeof (int) / sizeof (short) + 128, + 5 * sizeof (int) / sizeof (short) + 256, + 5 * sizeof (int) / sizeof (short) + 256 + }, + { + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 0, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 16, + 5 + 384 * sizeof (short) / sizeof (int) + 32, + 5 + 384 * sizeof (short) / sizeof (int) + 48, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 64, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 80, + 5 + 384 * sizeof (short) / sizeof (int) + 96, + 5 + 384 * sizeof (short) / sizeof (int) + 112, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 144, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 160, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 176, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 192, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 208, + 5 + 384 * sizeof (short) / sizeof (int) + 224, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 240, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 256, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 272, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 288, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 304, + 5 + 384 * sizeof (short) / sizeof (int) + 320, + 5 + 384 * sizeof (short) / sizeof (int) + 336, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 352, + 5 + 384 * sizeof (short) / sizeof (int) + 368, + 5 + 384 * sizeof (short) / sizeof (int) + 384, + 5 + 384 * sizeof (short) / sizeof (int) + 400, + 5 + 384 * sizeof (short) / sizeof (int) + 416, + 5 + 384 * sizeof (short) / sizeof (int) + 432, + -1, + -1, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128, + 5 + 384 * sizeof (short) / sizeof (int) + 128 + }, + { + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x0C000000U, 0x00000600U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00091E00U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x60000000U, + 0x00300000U, 0x00000000U, 0x000FFF00U, 0x80000000U, + 0x00080000U, 0x60000C02U, 0x00104030U, 0x242C0400U, + 0x00000C20U, 0x00000100U, 0x00B85000U, 0x00000000U, + 0x00E00000U, 0x80010000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x18000000U, 0x00000000U, 0x00210000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x1FFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFF0000U, 0xFFFF0000U, 0xFFFFFFFFU, 0x0000FFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000001U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x0000007FU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x0003000FU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x00000000U, + 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0x00000007U, 0x00070000U, 0xFFFF00F0U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0FFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000010U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00008000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x07FE4000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFBFE001U, 0xFFFFFFFFU, 0xDFFFFFFFU, + 0x000FFFFFU, 0xFFFFFFFFU, 0x000F87FFU, 0xFF11FFFFU, + 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFFFFFDU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x9FFFFFFFU, + 0xFFFFFFFFU, 0x3FFFFFFFU, 0xFFFF7800U, 0x040000FFU, + 0x00600000U, 0x00000010U, 0x00000000U, 0xF8000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xE0E7103FU, 0x1FF01800U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00010FFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0xFFFFF000U, 0xF7FFFFFFU, 0xFFFFFFBFU, 0xFFFFFFFFU, + 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x1F1F0000U, + 0xFFFF007FU, 0x07FF1FFFU, 0x03FF003FU, 0x007F00FFU, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U + } +}; diff --git a/lib/unlink.c b/lib/unlink.c new file mode 100644 index 0000000..b549dd4 --- /dev/null +++ b/lib/unlink.c @@ -0,0 +1,98 @@ +/* Work around unlink bugs. + + 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 . */ + +#include + +#include + +#include +#include +#include +#include + +#include "filename.h" + +#undef unlink +#if defined _WIN32 && !defined __CYGWIN__ +# define unlink _unlink +#endif + +/* Remove file NAME. + Return 0 if successful, -1 if not. */ + +int +rpl_unlink (char const *name) +{ + /* Work around Solaris 9 bug where unlink("file/") succeeds. */ + size_t len = strlen (name); + int result = 0; + if (len && ISSLASH (name[len - 1])) + { + /* We can't unlink(2) something if it doesn't exist. If it does + exist, then it resolved to a directory, due to the trailing + slash, and POSIX requires that the unlink attempt to remove + that directory (which would leave the symlink dangling). + Unfortunately, Solaris 9 is one of the platforms where the + root user can unlink directories, and we don't want to + cripple this behavior on real directories, even if it is + seldom needed (at any rate, it's nicer to let coreutils' + unlink(1) give the correct errno for non-root users). But we + don't know whether name was an actual directory, or a symlink + to a directory; and due to the bug of ignoring trailing + slash, Solaris 9 would end up successfully unlinking the + symlink instead of the directory. Technically, we could use + realpath to find the canonical directory name to attempt + deletion on. But that is a lot of work for a corner case; so + we instead just use an lstat on the shortened name, and + reject symlinks with trailing slashes. The root user of + unlink(1) will just have to live with the rule that they + can't delete a directory via a symlink. */ + struct stat st; + result = lstat (name, &st); + if (result == 0 || errno == EOVERFLOW) + { + /* Trailing NUL will overwrite the trailing slash. */ + char *short_name = malloc (len); + if (!short_name) + return -1; + memcpy (short_name, name, len); + while (len && ISSLASH (short_name[len - 1])) + short_name[--len] = '\0'; + if (len && (lstat (short_name, &st) || S_ISLNK (st.st_mode))) + { + free (short_name); + errno = EPERM; + return -1; + } + free (short_name); + result = 0; + } + } + if (!result) + { +#if UNLINK_PARENT_BUG + if (len >= 2 && name[len - 1] == '.' && name[len - 2] == '.' + && (len == 2 || ISSLASH (name[len - 3]))) + { + errno = EISDIR; /* could also use EPERM */ + return -1; + } +#endif + result = unlink (name); + } + return result; +} diff --git a/lib/unlocked-io.h b/lib/unlocked-io.h new file mode 100644 index 0000000..7461d74 --- /dev/null +++ b/lib/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/lib/utime.c b/lib/utime.c new file mode 100644 index 0000000..799be0f --- /dev/null +++ b/lib/utime.c @@ -0,0 +1,288 @@ +/* Work around platform bugs in utime. + 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 3 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 + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ + +# include +# include +# include +# include "filename.h" +# include "malloca.h" + +/* Don't assume that UNICODE is not defined. */ +# undef CreateFile +# define CreateFile CreateFileA +# undef GetFileAttributes +# define GetFileAttributes GetFileAttributesA + +int +_gl_utimens_windows (const char *name, struct timespec ts[2]) +{ + /* 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--; + } + + 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; + } + + DWORD error; + + /* Open a handle to the file. + CreateFile + + */ + HANDLE handle = + CreateFile (rname, + FILE_READ_ATTRIBUTES | FILE_WRITE_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 (handle == INVALID_HANDLE_VALUE) + { + error = GetLastError (); + goto failed; + } + + if (check_dir) + { + /* GetFileAttributes + */ + DWORD attributes = GetFileAttributes (rname); + if (attributes == INVALID_FILE_ATTRIBUTES) + { + error = GetLastError (); + CloseHandle (handle); + goto failed; + } + if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + { + CloseHandle (handle); + if (malloca_rname != NULL) + freea (malloca_rname); + errno = ENOTDIR; + return -1; + } + } + + { + /* Use SetFileTime(). See + + */ + FILETIME last_access_time; + FILETIME last_write_time; + if (ts == NULL) + { + /* GetSystemTimeAsFileTime is the same as + GetSystemTime followed by SystemTimeToFileTime. + . + It would be overkill to use + GetSystemTimePreciseAsFileTime + . */ + FILETIME current_time; + GetSystemTimeAsFileTime (¤t_time); + last_access_time = current_time; + last_write_time = current_time; + } + else + { + { + ULONGLONG time_since_16010101 = + (ULONGLONG) ts[0].tv_sec * 10000000 + ts[0].tv_nsec / 100 + 116444736000000000LL; + last_access_time.dwLowDateTime = (DWORD) time_since_16010101; + last_access_time.dwHighDateTime = time_since_16010101 >> 32; + } + { + ULONGLONG time_since_16010101 = + (ULONGLONG) ts[1].tv_sec * 10000000 + ts[1].tv_nsec / 100 + 116444736000000000LL; + last_write_time.dwLowDateTime = (DWORD) time_since_16010101; + last_write_time.dwHighDateTime = time_since_16010101 >> 32; + } + } + if (SetFileTime (handle, NULL, &last_access_time, &last_write_time)) + { + CloseHandle (handle); + if (malloca_rname != NULL) + freea (malloca_rname); + return 0; + } + else + { + #if 0 + DWORD sft_error = GetLastError (); + fprintf (stderr, "utimens SetFileTime error 0x%x\n", (unsigned int) sft_error); + #endif + CloseHandle (handle); + if (malloca_rname != NULL) + freea (malloca_rname); + errno = EINVAL; + return -1; + } + } + + failed: + { + #if 0 + fprintf (stderr, "utimens CreateFile/GetFileAttributes 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_NETPATH: /* rname is such as '\\nonexistentserver\share'. */ + 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'. */ + errno = (ts != NULL ? EPERM : 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; + } +} + +int +utime (const char *name, const struct utimbuf *ts) +{ + if (ts == NULL) + return _gl_utimens_windows (name, NULL); + else + { + struct timespec ts_with_nanoseconds[2]; + ts_with_nanoseconds[0].tv_sec = ts->actime; + ts_with_nanoseconds[0].tv_nsec = 0; + ts_with_nanoseconds[1].tv_sec = ts->modtime; + ts_with_nanoseconds[1].tv_nsec = 0; + return _gl_utimens_windows (name, ts_with_nanoseconds); + } +} + +#else + +# include +# include +# include "filename.h" + +int +utime (const char *name, const struct utimbuf *ts) +#undef utime +{ +# if REPLACE_FUNC_UTIME_FILE + /* macOS 10.13 mistakenly succeeds when given a symbolic link to a + non-directory with a trailing slash. */ + size_t len = strlen (name); + if (len > 0 && ISSLASH (name[len - 1])) + { + struct stat buf; + + if (stat (name, &buf) == -1 && errno != EOVERFLOW) + return -1; + } +# endif /* REPLACE_FUNC_UTIME_FILE */ + + return utime (name, ts); +} + +#endif diff --git a/lib/utime.in.h b/lib/utime.in.h new file mode 100644 index 0000000..6cf17b6 --- /dev/null +++ b/lib/utime.in.h @@ -0,0 +1,112 @@ +/* Substitute for and wrapper around . + 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 _@GUARD_PREFIX@_UTIME_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_UTIME_H@ +# @INCLUDE_NEXT@ @NEXT_UTIME_H@ +#endif + +#ifndef _@GUARD_PREFIX@_UTIME_H +#define _@GUARD_PREFIX@_UTIME_H + +#if !@HAVE_UTIME_H@ +# include +#endif + +#if @GNULIB_UTIME@ +/* Get struct timespec. */ +# 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. */ + + +#if defined _WIN32 && ! defined __CYGWIN__ + +/* Define 'struct utimbuf' as an alias of 'struct _utimbuf' + (or possibly, if present, 'struct __utimbuf64'). */ +# define utimbuf _utimbuf + +#endif + + +#if @GNULIB_UTIME@ +# if @REPLACE_UTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define utime rpl_utime +# endif +_GL_FUNCDECL_RPL (utime, int, (const char *filename, const struct utimbuf *ts) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (utime, int, (const char *filename, const struct utimbuf *ts)); +# elif defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef utime +# define utime _utime +# endif +_GL_CXXALIAS_MDA (utime, int, (const char *filename, const struct utimbuf *ts)); +# else +# if !@HAVE_UTIME@ +_GL_FUNCDECL_SYS (utime, int, (const char *filename, const struct utimbuf *ts) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (utime, int, (const char *filename, const struct utimbuf *ts)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (utime); +# endif +#elif defined GNULIB_POSIXCHECK +# undef utime +# if HAVE_RAW_DECL_UTIME +_GL_WARN_ON_USE (utime, + "utime is unportable - " + "use gnulib module canonicalize-lgpl for portability"); +# endif +#elif @GNULIB_MDA_UTIME@ +/* On native Windows, map 'utime' to '_utime', so that -loldnames is not + required. In C++ with GNULIB_NAMESPACE, avoid differences between + platforms by defining GNULIB_NAMESPACE::utime always. */ +# if defined _WIN32 && !defined __CYGWIN__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef utime +# define utime _utime +# endif +_GL_CXXALIAS_MDA (utime, int, (const char *filename, const struct utimbuf *ts)); +# else +_GL_CXXALIAS_SYS (utime, int, (const char *filename, const struct utimbuf *ts)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (utime); +# endif +#endif + +#if @GNULIB_UTIME@ +extern int _gl_utimens_windows (const char *filename, struct timespec ts[2]); +#endif + + +#endif /* _@GUARD_PREFIX@_UTIME_H */ +#endif /* _@GUARD_PREFIX@_UTIME_H */ diff --git a/lib/utimens.c b/lib/utimens.c new file mode 100644 index 0000000..2fa1251 --- /dev/null +++ b/lib/utimens.c @@ -0,0 +1,647 @@ +/* Set file access and modification times. + + Copyright (C) 2003-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 3 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. */ + +/* derived from a function in touch.c */ + +#include + +#define _GL_UTIMENS_INLINE _GL_EXTERN_INLINE +#include "utimens.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stat-time.h" +#include "timespec.h" + +/* On native Windows, use SetFileTime; but avoid this when compiling + GNU Emacs, which arranges for this in some other way and which + defines WIN32_LEAN_AND_MEAN itself. */ + +#if defined _WIN32 && ! defined __CYGWIN__ && ! defined EMACS_CONFIGURATION +# define USE_SETFILETIME +# define WIN32_LEAN_AND_MEAN +# include +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif +#endif + +/* Avoid recursion with rpl_futimens or rpl_utimensat. */ +#undef futimens +#if !HAVE_NEARLY_WORKING_UTIMENSAT +# undef utimensat +#endif + +/* Solaris 9 mistakenly succeeds when given a non-directory with a + trailing slash. Force the use of rpl_stat for a fix. */ +#ifndef REPLACE_FUNC_STAT_FILE +# define REPLACE_FUNC_STAT_FILE 0 +#endif + +#if HAVE_UTIMENSAT || HAVE_FUTIMENS +/* Cache variables for whether the utimensat syscall works; used to + avoid calling the syscall if we know it will just fail with ENOSYS, + and to avoid unnecessary work in massaging timestamps if the + syscall will work. Multiple variables are needed, to distinguish + between the following scenarios on Linux: + utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS + kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW + kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec + kernel 2.6.32 used with xfs or ntfs-3g fail to honor UTIME_OMIT + utimensat completely works + For each cache variable: 0 = unknown, 1 = yes, -1 = no. */ +static int utimensat_works_really; +static int lutimensat_works_really; +#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ + +/* Validate the requested timestamps. Return 0 if the resulting + timespec can be used for utimensat (after possibly modifying it to + work around bugs in utimensat). Return a positive value if the + timespec needs further adjustment based on stat results: 1 if any + adjustment is needed for utimes, and 2 if any adjustment is needed + for Linux utimensat. Return -1, with errno set to EINVAL, if + timespec is out of range. */ +static int +validate_timespec (struct timespec timespec[2]) +{ + int result = 0; + int utime_omit_count = 0; + if ((timespec[0].tv_nsec != UTIME_NOW + && timespec[0].tv_nsec != UTIME_OMIT + && ! (0 <= timespec[0].tv_nsec + && timespec[0].tv_nsec < TIMESPEC_HZ)) + || (timespec[1].tv_nsec != UTIME_NOW + && timespec[1].tv_nsec != UTIME_OMIT + && ! (0 <= timespec[1].tv_nsec + && timespec[1].tv_nsec < TIMESPEC_HZ))) + { + errno = EINVAL; + return -1; + } + /* Work around Linux kernel 2.6.25 bug, where utimensat fails with + EINVAL if tv_sec is not 0 when using the flag values of tv_nsec. + Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT + fails to bump ctime. */ + if (timespec[0].tv_nsec == UTIME_NOW + || timespec[0].tv_nsec == UTIME_OMIT) + { + timespec[0].tv_sec = 0; + result = 1; + if (timespec[0].tv_nsec == UTIME_OMIT) + utime_omit_count++; + } + if (timespec[1].tv_nsec == UTIME_NOW + || timespec[1].tv_nsec == UTIME_OMIT) + { + timespec[1].tv_sec = 0; + result = 1; + if (timespec[1].tv_nsec == UTIME_OMIT) + utime_omit_count++; + } + return result + (utime_omit_count == 1); +} + +/* Normalize any UTIME_NOW or UTIME_OMIT values in (*TS)[0] and (*TS)[1], + using STATBUF to obtain the current timestamps of the file. If + both times are UTIME_NOW, set *TS to NULL (as this can avoid some + permissions issues). If both times are UTIME_OMIT, return true + (nothing further beyond the prior collection of STATBUF is + necessary); otherwise return false. */ +static bool +update_timespec (struct stat const *statbuf, struct timespec **ts) +{ + struct timespec *timespec = *ts; + if (timespec[0].tv_nsec == UTIME_OMIT + && timespec[1].tv_nsec == UTIME_OMIT) + return true; + if (timespec[0].tv_nsec == UTIME_NOW + && timespec[1].tv_nsec == UTIME_NOW) + { + *ts = NULL; + return false; + } + + if (timespec[0].tv_nsec == UTIME_OMIT) + timespec[0] = get_stat_atime (statbuf); + else if (timespec[0].tv_nsec == UTIME_NOW) + gettime (×pec[0]); + + if (timespec[1].tv_nsec == UTIME_OMIT) + timespec[1] = get_stat_mtime (statbuf); + else if (timespec[1].tv_nsec == UTIME_NOW) + gettime (×pec[1]); + + return false; +} + +/* Set the access and modification timestamps of FD (a.k.a. FILE) to be + TIMESPEC[0] and TIMESPEC[1], respectively. + FD must be either negative -- in which case it is ignored -- + or a file descriptor that is open on FILE. + If FD is nonnegative, then FILE can be NULL, which means + use just futimes (or equivalent) instead of utimes (or equivalent), + and fail if on an old system without futimes (or equivalent). + If TIMESPEC is null, set the timestamps to the current time. + Return 0 on success, -1 (setting errno) on failure. */ + +int +fdutimens (int fd, char const *file, struct timespec const timespec[2]) +{ + struct timespec adjusted_timespec[2]; + struct timespec *ts = timespec ? adjusted_timespec : NULL; + int adjustment_needed = 0; + struct stat st; + + if (ts) + { + adjusted_timespec[0] = timespec[0]; + adjusted_timespec[1] = timespec[1]; + adjustment_needed = validate_timespec (ts); + } + if (adjustment_needed < 0) + return -1; + + /* Require that at least one of FD or FILE are potentially valid, to avoid + a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather + than failing. */ + if (fd < 0 && !file) + { + errno = EBADF; + return -1; + } + + /* Some Linux-based NFS clients are buggy, and mishandle timestamps + of files in NFS file systems in some cases. We have no + configure-time test for this, but please see + for references to + some of the problems with Linux 2.6.16. If this affects you, + compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to + help in some cases, albeit at a cost in performance. But you + really should upgrade your kernel to a fixed version, since the + problem affects many applications. */ + +#if HAVE_BUGGY_NFS_TIME_STAMPS + if (fd < 0) + sync (); + else + fsync (fd); +#endif + + /* POSIX 2008 added two interfaces to set file timestamps with + nanosecond resolution; newer Linux implements both functions via + a single syscall. We provide a fallback for ENOSYS (for example, + compiling against Linux 2.6.25 kernel headers and glibc 2.7, but + running on Linux 2.6.18 kernel). */ +#if HAVE_UTIMENSAT || HAVE_FUTIMENS + if (0 <= utimensat_works_really) + { + int result; +# if __linux__ || __sun + /* As recently as Linux kernel 2.6.32 (Dec 2009), several file + systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, + but work if both times are either explicitly specified or + UTIME_NOW. Work around it with a preparatory [f]stat prior + to calling futimens/utimensat; fortunately, there is not much + timing impact due to the extra syscall even on file systems + where UTIME_OMIT would have worked. + + The same bug occurs in Solaris 11.1 (Apr 2013). + + FIXME: Simplify this for Linux in 2016 and for Solaris in + 2024, when file system bugs are no longer common. */ + if (adjustment_needed == 2) + { + if (fd < 0 ? stat (file, &st) : fstat (fd, &st)) + return -1; + if (ts[0].tv_nsec == UTIME_OMIT) + ts[0] = get_stat_atime (&st); + else if (ts[1].tv_nsec == UTIME_OMIT) + ts[1] = get_stat_mtime (&st); + /* Note that st is good, in case utimensat gives ENOSYS. */ + adjustment_needed++; + } +# endif +# if HAVE_UTIMENSAT + if (fd < 0) + { +# if defined __APPLE__ && defined __MACH__ + size_t len = strlen (file); + if (len > 0 && file[len - 1] == '/') + { + struct stat statbuf; + if (stat (file, &statbuf) < 0) + return -1; + if (!S_ISDIR (statbuf.st_mode)) + { + errno = ENOTDIR; + return -1; + } + } +# endif + result = utimensat (AT_FDCWD, file, ts, 0); +# ifdef __linux__ + /* Work around a kernel bug: + https://bugzilla.redhat.com/show_bug.cgi?id=442352 + https://bugzilla.redhat.com/show_bug.cgi?id=449910 + It appears that utimensat can mistakenly return 280 rather + than -1 upon ENOSYS failure. + FIXME: remove in 2010 or whenever the offending kernels + are no longer in common use. */ + if (0 < result) + errno = ENOSYS; +# endif /* __linux__ */ + if (result == 0 || errno != ENOSYS) + { + utimensat_works_really = 1; + return result; + } + } +# endif /* HAVE_UTIMENSAT */ +# if HAVE_FUTIMENS + if (0 <= fd) + { + result = futimens (fd, ts); +# ifdef __linux__ + /* Work around the same bug as above. */ + if (0 < result) + errno = ENOSYS; +# endif /* __linux__ */ + if (result == 0 || errno != ENOSYS) + { + utimensat_works_really = 1; + return result; + } + } +# endif /* HAVE_FUTIMENS */ + } + utimensat_works_really = -1; + lutimensat_works_really = -1; +#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ + +#ifdef USE_SETFILETIME + /* On native Windows, use SetFileTime(). See + + */ + if (0 <= fd) + { + HANDLE handle; + FILETIME current_time; + FILETIME last_access_time; + FILETIME last_write_time; + + handle = (HANDLE) _get_osfhandle (fd); + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + if (ts == NULL || ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) + { + /* GetSystemTimeAsFileTime + . + It would be overkill to use + GetSystemTimePreciseAsFileTime + . */ + GetSystemTimeAsFileTime (¤t_time); + } + + if (ts == NULL || ts[0].tv_nsec == UTIME_NOW) + { + last_access_time = current_time; + } + else if (ts[0].tv_nsec == UTIME_OMIT) + { + last_access_time.dwLowDateTime = 0; + last_access_time.dwHighDateTime = 0; + } + else + { + ULONGLONG time_since_16010101 = + (ULONGLONG) ts[0].tv_sec * 10000000 + ts[0].tv_nsec / 100 + 116444736000000000LL; + last_access_time.dwLowDateTime = (DWORD) time_since_16010101; + last_access_time.dwHighDateTime = time_since_16010101 >> 32; + } + + if (ts == NULL || ts[1].tv_nsec == UTIME_NOW) + { + last_write_time = current_time; + } + else if (ts[1].tv_nsec == UTIME_OMIT) + { + last_write_time.dwLowDateTime = 0; + last_write_time.dwHighDateTime = 0; + } + else + { + ULONGLONG time_since_16010101 = + (ULONGLONG) ts[1].tv_sec * 10000000 + ts[1].tv_nsec / 100 + 116444736000000000LL; + last_write_time.dwLowDateTime = (DWORD) time_since_16010101; + last_write_time.dwHighDateTime = time_since_16010101 >> 32; + } + + if (SetFileTime (handle, NULL, &last_access_time, &last_write_time)) + return 0; + else + { + DWORD sft_error = GetLastError (); + #if 0 + fprintf (stderr, "fdutimens SetFileTime error 0x%x\n", (unsigned int) sft_error); + #endif + switch (sft_error) + { + case ERROR_ACCESS_DENIED: /* fd was opened without O_RDWR */ + errno = EACCES; /* not specified by POSIX */ + break; + default: + errno = EINVAL; + break; + } + return -1; + } + } +#endif + + /* The platform lacks an interface to set file timestamps with + nanosecond resolution, so do the best we can, discarding any + fractional part of the timestamp. */ + + if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0)) + { + if (adjustment_needed != 3 + && (fd < 0 ? stat (file, &st) : fstat (fd, &st))) + return -1; + if (ts && update_timespec (&st, &ts)) + return 0; + } + + { +#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES + struct timeval timeval[2]; + struct timeval *t; + if (ts) + { + timeval[0].tv_sec = ts[0].tv_sec; + timeval[0].tv_usec = ts[0].tv_nsec / 1000; + timeval[1].tv_sec = ts[1].tv_sec; + timeval[1].tv_usec = ts[1].tv_nsec / 1000; + t = timeval; + } + else + t = NULL; + + if (fd < 0) + { +# if HAVE_FUTIMESAT + return futimesat (AT_FDCWD, file, t); +# endif + } + else + { + /* If futimesat or futimes fails here, don't try to speed things + up by returning right away. glibc can incorrectly fail with + errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0 + in high security mode doesn't allow ordinary users to read + /proc/self, so glibc incorrectly fails with errno == EACCES. + If errno == EIO, EPERM, or EROFS, it's probably safe to fail + right away, but these cases are rare enough that they're not + worth optimizing, and who knows what other messed-up systems + are out there? So play it safe and fall back on the code + below. */ + +# if (HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) || HAVE_FUTIMES +# if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG +# undef futimes +# define futimes(fd, t) futimesat (fd, NULL, t) +# endif + if (futimes (fd, t) == 0) + { +# if __linux__ && __GLIBC__ + /* Work around a longstanding glibc bug, still present as + of 2010-12-27. On older Linux kernels that lack both + utimensat and utimes, glibc's futimes rounds instead of + truncating when falling back on utime. The same bug + occurs in futimesat with a null 2nd arg. */ + if (t) + { + bool abig = 500000 <= t[0].tv_usec; + bool mbig = 500000 <= t[1].tv_usec; + if ((abig | mbig) && fstat (fd, &st) == 0) + { + /* If these two subtractions overflow, they'll + track the overflows inside the buggy glibc. */ + time_t adiff = st.st_atime - t[0].tv_sec; + time_t mdiff = st.st_mtime - t[1].tv_sec; + + struct timeval *tt = NULL; + struct timeval truncated_timeval[2]; + truncated_timeval[0] = t[0]; + truncated_timeval[1] = t[1]; + if (abig && adiff == 1 && get_stat_atime_ns (&st) == 0) + { + tt = truncated_timeval; + tt[0].tv_usec = 0; + } + if (mbig && mdiff == 1 && get_stat_mtime_ns (&st) == 0) + { + tt = truncated_timeval; + tt[1].tv_usec = 0; + } + if (tt) + futimes (fd, tt); + } + } +# endif + + return 0; + } +# endif + } +#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ + + if (!file) + { +#if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) \ + || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) + errno = ENOSYS; +#endif + return -1; + } + +#ifdef USE_SETFILETIME + return _gl_utimens_windows (file, ts); +#elif HAVE_WORKING_UTIMES + return utimes (file, t); +#else + { + struct utimbuf utimbuf; + struct utimbuf *ut; + if (ts) + { + utimbuf.actime = ts[0].tv_sec; + utimbuf.modtime = ts[1].tv_sec; + ut = &utimbuf; + } + else + ut = NULL; + + return utime (file, ut); + } +#endif /* !HAVE_WORKING_UTIMES */ + } +} + +/* Set the access and modification timestamps of FILE to be + TIMESPEC[0] and TIMESPEC[1], respectively. */ +int +utimens (char const *file, struct timespec const timespec[2]) +{ + return fdutimens (-1, file, timespec); +} + +/* Set the access and modification timestamps of FILE to be + TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing + symlinks. Fail with ENOSYS if the platform does not support + changing symlink timestamps, but FILE was a symlink. */ +int +lutimens (char const *file, struct timespec const timespec[2]) +{ + struct timespec adjusted_timespec[2]; + struct timespec *ts = timespec ? adjusted_timespec : NULL; + int adjustment_needed = 0; + struct stat st; + + if (ts) + { + adjusted_timespec[0] = timespec[0]; + adjusted_timespec[1] = timespec[1]; + adjustment_needed = validate_timespec (ts); + } + if (adjustment_needed < 0) + return -1; + + /* The Linux kernel did not support symlink timestamps until + utimensat, in version 2.6.22, so we don't need to mimic + fdutimens' worry about buggy NFS clients. But we do have to + worry about bogus return values. */ + +#if HAVE_UTIMENSAT + if (0 <= lutimensat_works_really) + { + int result; +# if __linux__ || __sun + /* As recently as Linux kernel 2.6.32 (Dec 2009), several file + systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT, + but work if both times are either explicitly specified or + UTIME_NOW. Work around it with a preparatory lstat prior to + calling utimensat; fortunately, there is not much timing + impact due to the extra syscall even on file systems where + UTIME_OMIT would have worked. + + The same bug occurs in Solaris 11.1 (Apr 2013). + + FIXME: Simplify this for Linux in 2016 and for Solaris in + 2024, when file system bugs are no longer common. */ + if (adjustment_needed == 2) + { + if (lstat (file, &st)) + return -1; + if (ts[0].tv_nsec == UTIME_OMIT) + ts[0] = get_stat_atime (&st); + else if (ts[1].tv_nsec == UTIME_OMIT) + ts[1] = get_stat_mtime (&st); + /* Note that st is good, in case utimensat gives ENOSYS. */ + adjustment_needed++; + } +# endif + result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); +# ifdef __linux__ + /* Work around a kernel bug: + https://bugzilla.redhat.com/show_bug.cgi?id=442352 + https://bugzilla.redhat.com/show_bug.cgi?id=449910 + It appears that utimensat can mistakenly return 280 rather + than -1 upon ENOSYS failure. + FIXME: remove in 2010 or whenever the offending kernels + are no longer in common use. */ + if (0 < result) + errno = ENOSYS; +# endif + if (result == 0 || errno != ENOSYS) + { + utimensat_works_really = 1; + lutimensat_works_really = 1; + return result; + } + } + lutimensat_works_really = -1; +#endif /* HAVE_UTIMENSAT */ + + /* The platform lacks an interface to set file timestamps with + nanosecond resolution, so do the best we can, discarding any + fractional part of the timestamp. */ + + if (adjustment_needed || REPLACE_FUNC_STAT_FILE) + { + if (adjustment_needed != 3 && lstat (file, &st)) + return -1; + if (ts && update_timespec (&st, &ts)) + return 0; + } + + /* On Linux, lutimes is a thin wrapper around utimensat, so there is + no point trying lutimes if utimensat failed with ENOSYS. */ +#if HAVE_LUTIMES && !HAVE_UTIMENSAT + { + struct timeval timeval[2]; + struct timeval *t; + int result; + if (ts) + { + timeval[0].tv_sec = ts[0].tv_sec; + timeval[0].tv_usec = ts[0].tv_nsec / 1000; + timeval[1].tv_sec = ts[1].tv_sec; + timeval[1].tv_usec = ts[1].tv_nsec / 1000; + t = timeval; + } + else + t = NULL; + + result = lutimes (file, t); + if (result == 0 || errno != ENOSYS) + return result; + } +#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ + + /* Out of luck for symlinks, but we still handle regular files. */ + if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) + return -1; + if (!S_ISLNK (st.st_mode)) + return fdutimens (-1, file, ts); + errno = ENOSYS; + return -1; +} diff --git a/lib/utimens.h b/lib/utimens.h new file mode 100644 index 0000000..2ccc06e --- /dev/null +++ b/lib/utimens.h @@ -0,0 +1,49 @@ +/* Set file access and modification times. + + Copyright 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 3 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 +int fdutimens (int, char const *, struct timespec const [2]); +int utimens (char const *, struct timespec const [2]); +int lutimens (char const *, struct timespec const [2]); + +#if GNULIB_FDUTIMENSAT +# include +# include + +#ifndef _GL_INLINE_HEADER_BEGIN + #error "Please include config.h first." +#endif +_GL_INLINE_HEADER_BEGIN +#ifndef _GL_UTIMENS_INLINE +# define _GL_UTIMENS_INLINE _GL_INLINE +#endif + +int fdutimensat (int fd, int dir, char const *name, struct timespec const [2], + int atflag); + +/* Using this function makes application code slightly more readable. */ +_GL_UTIMENS_INLINE int +lutimensat (int dir, char const *file, struct timespec const times[2]) +{ + return utimensat (dir, file, times, AT_SYMLINK_NOFOLLOW); +} + +_GL_INLINE_HEADER_END + +#endif diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c new file mode 100644 index 0000000..4857452 --- /dev/null +++ b/lib/vasnprintf.c @@ -0,0 +1,5872 @@ +/* vsprintf with automatic memory allocation. + Copyright (C) 1999, 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 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 . */ + +/* This file can be parametrized with the following macros: + VASNPRINTF The name of the function being defined. + FCHAR_T The element type of the format string. + DCHAR_T The element type of the destination (result) string. + FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters + in the format string are ASCII. MUST be set if + FCHAR_T and DCHAR_T are not the same type. + DIRECTIVE Structure denoting a format directive. + Depends on FCHAR_T. + DIRECTIVES Structure denoting the set of format directives of a + format string. Depends on FCHAR_T. + PRINTF_PARSE Function that parses a format string. + Depends on FCHAR_T. + DCHAR_CPY memcpy like function for DCHAR_T[] arrays. + DCHAR_SET memset like function for DCHAR_T[] arrays. + DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. + SNPRINTF The system's snprintf (or similar) function. + This may be either snprintf or swprintf. + TCHAR_T The element type of the argument and result string + of the said SNPRINTF function. This may be either + char or wchar_t. The code exploits that + sizeof (TCHAR_T) | sizeof (DCHAR_T) and + alignof (TCHAR_T) <= alignof (DCHAR_T). + DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type. + 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. + 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 + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifndef VASNPRINTF +# include +#endif + +/* 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 +# include "vasnwprintf.h" +# else +# include "vasnprintf.h" +# endif +#endif + +#include /* localeconv() */ +#include /* snprintf(), sprintf() */ +#include /* abort(), malloc(), realloc(), free() */ +#include /* memcpy(), strlen() */ +#include /* errno */ +#include /* CHAR_BIT */ +#include /* DBL_MAX_EXP, LDBL_MAX_EXP */ +#if HAVE_NL_LANGINFO +# include +#endif +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# include "wprintf-parse.h" +# else +# include "printf-parse.h" +# endif +#endif + +/* Checked size_t computations. */ +#include "xsize.h" + +#include "attribute.h" +#include "verify.h" + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "float+.h" +#endif + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnand-nolibm.h" +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnanl-nolibm.h" +# include "fpucw.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnand-nolibm.h" +# include "printf-frexp.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnanl-nolibm.h" +# include "printf-frexpl.h" +# include "fpucw.h" +#endif + +/* Default parameters. */ +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# define VASNPRINTF vasnwprintf +# define FCHAR_T wchar_t +# define DCHAR_T wchar_t +# define TCHAR_T wchar_t +# define DCHAR_IS_TCHAR 1 +# define DIRECTIVE wchar_t_directive +# define DIRECTIVES wchar_t_directives +# define PRINTF_PARSE wprintf_parse +# define DCHAR_CPY wmemcpy +# define DCHAR_SET wmemset +# else +# define VASNPRINTF vasnprintf +# define FCHAR_T char +# define DCHAR_T char +# define TCHAR_T char +# define DCHAR_IS_TCHAR 1 +# define DIRECTIVE char_directive +# define DIRECTIVES char_directives +# define PRINTF_PARSE printf_parse +# define DCHAR_CPY memcpy +# define DCHAR_SET memset +# endif +#endif +#if WIDE_CHAR_VERSION + /* TCHAR_T is wchar_t. */ +# define USE_SNPRINTF 1 +# if HAVE_DECL__SNWPRINTF + /* On Windows, the function swprintf() has a different signature than + on Unix; we use the function _snwprintf() or - on mingw - snwprintf() + instead. The mingw function snwprintf() has fewer bugs than the + MSVCRT function _snwprintf(), so prefer that. */ +# if defined __MINGW32__ +# define SNPRINTF snwprintf +# else +# define SNPRINTF _snwprintf +# define USE_MSVC__SNPRINTF 1 +# endif +# else + /* Unix. */ +# define SNPRINTF swprintf +# endif +#else + /* TCHAR_T is char. */ + /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. + But don't use it on BeOS, since BeOS snprintf produces no output if the + size argument is >= 0x3000000. + Also don't use it on Linux libc5, since there snprintf with size = 1 + writes any output without bounds, like sprintf. */ +# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1) +# define USE_SNPRINTF 1 +# else +# define USE_SNPRINTF 0 +# endif +# if HAVE_DECL__SNPRINTF + /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT + function _snprintf(), so prefer that. */ +# if defined __MINGW32__ +# define SNPRINTF snprintf + /* 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. */ +# define SNPRINTF snprintf + /* Here we need to call the native snprintf, not rpl_snprintf. */ +# undef snprintf +# endif +#endif +/* Here we need to call the native sprintf, not rpl_sprintf. */ +#undef sprintf + +/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" + warnings in this file. Use -Dlint to suppress them. */ +#if defined GCC_LINT || defined lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ +#endif + +/* Avoid some warnings from "gcc -Wshadow". + This file doesn't use the exp() and remainder() functions. */ +#undef exp +#define exp expo +#undef remainder +#define remainder rem + +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION +# if (HAVE_STRNLEN && !defined _AIX) +# define local_strnlen strnlen +# else +# ifndef local_strnlen_defined +# define local_strnlen_defined 1 +static size_t +local_strnlen (const char *string, size_t maxlen) +{ + const char *end = memchr (string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} +# endif +# endif +#endif + +#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 + /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid + a dependency towards this library, here is a local substitute. + Define this substitute only once, even if this file is included + twice in the same compilation unit. */ +# ifndef local_wcslen_defined +# define local_wcslen_defined 1 +static size_t +local_wcslen (const wchar_t *s) +{ + const wchar_t *ptr; + + for (ptr = s; *ptr != (wchar_t) 0; ptr++) + ; + return ptr - s; +} +# endif +# endif +#endif + +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION +# if HAVE_WCSNLEN +# define local_wcsnlen wcsnlen +# else +# ifndef local_wcsnlen_defined +# define local_wcsnlen_defined 1 +static size_t +local_wcsnlen (const wchar_t *s, size_t maxlen) +{ + const wchar_t *ptr; + + for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--) + ; + return ptr - s; +} +# endif +# 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 +# define decimal_point_char_defined 1 +static char +decimal_point_char (void) +{ + const char *point; + /* Determine it in a multithread-safe way. We know nl_langinfo is + multithread-safe on glibc systems and Mac OS X systems, but is not required + to be multithread-safe by POSIX. sprintf(), however, is multithread-safe. + localeconv() is rarely multithread-safe. */ +# if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__)) + point = nl_langinfo (RADIXCHAR); +# elif 1 + char pointbuf[5]; + sprintf (pointbuf, "%#.0f", 1.0); + point = &pointbuf[1]; +# else + point = localeconv () -> decimal_point; +# endif + /* The decimal point is always a single byte: either '.' or ','. */ + return (point[0] != '\0' ? point[0] : '.'); +} +# endif +#endif + +#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zero (double x) +{ + return isnand (x) || x + x == x; +} + +#endif + +#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zerol (long double x) +{ + return isnanl (x) || x + x == x; +} + +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL + +/* Converting 'long double' to decimal without rare rounding bugs requires + real bignums. We use the naming conventions of GNU gmp, but vastly simpler + (and slower) algorithms. */ + +typedef unsigned int mp_limb_t; +# define GMP_LIMB_BITS 32 +verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS); + +typedef unsigned long long mp_twolimb_t; +# define GMP_TWOLIMB_BITS 64 +verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS); + +/* Representation of a bignum >= 0. */ +typedef struct +{ + size_t nlimbs; + mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */ +} mpn_t; + +/* Compute the product of two bignums >= 0. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +multiply (mpn_t src1, mpn_t src2, mpn_t *dest) +{ + const mp_limb_t *p1; + const mp_limb_t *p2; + size_t len1; + size_t len2; + + if (src1.nlimbs <= src2.nlimbs) + { + len1 = src1.nlimbs; + p1 = src1.limbs; + len2 = src2.nlimbs; + p2 = src2.limbs; + } + else + { + len1 = src2.nlimbs; + p1 = src2.limbs; + len2 = src1.nlimbs; + p2 = src1.limbs; + } + /* Now 0 <= len1 <= len2. */ + if (len1 == 0) + { + /* src1 or src2 is zero. */ + dest->nlimbs = 0; + dest->limbs = (mp_limb_t *) malloc (1); + } + else + { + /* Here 1 <= len1 <= len2. */ + size_t dlen; + mp_limb_t *dp; + size_t k, i, j; + + dlen = len1 + len2; + dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); + if (dp == NULL) + return NULL; + for (k = len2; k > 0; ) + dp[--k] = 0; + for (i = 0; i < len1; i++) + { + mp_limb_t digit1 = p1[i]; + mp_twolimb_t carry = 0; + for (j = 0; j < len2; j++) + { + mp_limb_t digit2 = p2[j]; + carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; + carry += dp[i + j]; + dp[i + j] = (mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; + } + dp[i + len2] = (mp_limb_t) carry; + } + /* Normalise. */ + while (dlen > 0 && dp[dlen - 1] == 0) + dlen--; + dest->nlimbs = dlen; + dest->limbs = dp; + } + return dest->limbs; +} + +/* Compute the quotient of a bignum a >= 0 and a bignum b > 0. + a is written as a = q * b + r with 0 <= r < b. q is the quotient, r + the remainder. + Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, + q is incremented. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +divide (mpn_t a, mpn_t b, mpn_t *q) +{ + /* Algorithm: + First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]] + with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS). + If m=n=1, perform a single-precision division: + r:=0, j:=m, + while j>0 do + {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j = + = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r=n>1, perform a multiple-precision division: + We have a/b < beta^(m-n+1). + s:=intDsize-1-(highest bit in b[n-1]), 0<=s=beta/2. + For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).} + Compute q* : + q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]). + In case of overflow (q* >= beta) set q* := beta-1. + Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2] + and c3 := b[n-2] * q*. + {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow + occurred. Furthermore 0 <= c3 < beta^2. + If there was overflow and + r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2, + the next test can be skipped.} + While c3 > c2, {Here 0 <= c2 < c3 < beta^2} + Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2]. + If q* > 0: + Put r := r - b * q* * beta^j. In detail: + [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]]. + hence: u:=0, for i:=0 to n-1 do + u := u + q* * b[i], + r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry), + u:=u div beta (+ 1, if carry in subtraction) + r[n+j]:=r[n+j]-u. + {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1 + < q* + 1 <= beta, + the carry u does not overflow.} + If a negative carry occurs, put q* := q* - 1 + and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]]. + Set q[j] := q*. + Normalise [q[m-n],..,q[0]]; this yields the quotient q. + Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the + rest r. + The room for q[j] can be allocated at the memory location of r[n+j]. + Finally, round-to-even: + Shift r left by 1 bit. + If r > b or if r = b and q[0] is odd, q := q+1. + */ + const mp_limb_t *a_ptr = a.limbs; + size_t a_len = a.nlimbs; + const mp_limb_t *b_ptr = b.limbs; + size_t b_len = b.nlimbs; + mp_limb_t *roomptr; + mp_limb_t *tmp_roomptr = NULL; + mp_limb_t *q_ptr; + size_t q_len; + mp_limb_t *r_ptr; + size_t r_len; + + /* Allocate room for a_len+2 digits. + (Need a_len+1 digits for the real division and 1 more digit for the + final rounding of q.) */ + roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); + if (roomptr == NULL) + return NULL; + + /* Normalise a. */ + while (a_len > 0 && a_ptr[a_len - 1] == 0) + a_len--; + + /* Normalise b. */ + for (;;) + { + if (b_len == 0) + /* Division by zero. */ + abort (); + if (b_ptr[b_len - 1] == 0) + b_len--; + else + break; + } + + /* Here m = a_len >= 0 and n = b_len > 0. */ + + if (a_len < b_len) + { + /* m beta^(m-2) <= a/b < beta^m */ + r_ptr = roomptr; + q_ptr = roomptr + 1; + { + mp_limb_t den = b_ptr[0]; + mp_limb_t remainder = 0; + const mp_limb_t *sourceptr = a_ptr + a_len; + mp_limb_t *destptr = q_ptr + a_len; + size_t count; + for (count = a_len; count > 0; count--) + { + mp_twolimb_t num = + ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr; + *--destptr = num / den; + remainder = num % den; + } + /* Normalise and store r. */ + if (remainder > 0) + { + r_ptr[0] = remainder; + r_len = 1; + } + else + r_len = 0; + /* Normalise q. */ + q_len = a_len; + if (q_ptr[q_len - 1] == 0) + q_len--; + } + } + else + { + /* n>1: multiple precision division. + beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==> + beta^(m-n-1) <= a/b < beta^(m-n+1). */ + /* Determine s. */ + size_t s; + { + 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) \ + || (__clang_major__ >= 4) + s = __builtin_clz (msd); +# else +# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT + if (GMP_LIMB_BITS <= DBL_MANT_BIT) + { + /* Use 'double' operations. + Assumes an IEEE 754 'double' implementation. */ +# define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) +# define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1) +# define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { double value; unsigned int word[NWORDS]; } m; + + /* Use a single integer to floating-point conversion. */ + m.value = msd; + + s = GMP_LIMB_BITS + - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK) + - DBL_EXP_BIAS); + } + else +# undef NWORDS +# endif + { + s = 31; + if (msd >= 0x10000) + { + msd = msd >> 16; + s -= 16; + } + if (msd >= 0x100) + { + msd = msd >> 8; + s -= 8; + } + if (msd >= 0x10) + { + msd = msd >> 4; + s -= 4; + } + if (msd >= 0x4) + { + msd = msd >> 2; + s -= 2; + } + if (msd >= 0x2) + { + msd = msd >> 1; + s -= 1; + } + } +# endif + } + /* 0 <= s < GMP_LIMB_BITS. + Copy b, shifting it left by s bits. */ + if (s > 0) + { + tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t)); + if (tmp_roomptr == NULL) + { + free (roomptr); + return NULL; + } + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = tmp_roomptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + /* accu must be zero, since that was how s was determined. */ + if (accu != 0) + abort (); + } + b_ptr = tmp_roomptr; + } + /* Copy a, shifting it left by s bits, yields r. + Memory layout: + At the beginning: r = roomptr[0..a_len], + at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */ + r_ptr = roomptr; + if (s == 0) + { + memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t)); + r_ptr[a_len] = 0; + } + else + { + const mp_limb_t *sourceptr = a_ptr; + mp_limb_t *destptr = r_ptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = a_len; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + *destptr++ = (mp_limb_t) accu; + } + q_ptr = roomptr + b_len; + q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */ + { + size_t j = a_len - b_len; /* m-n */ + mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */ + mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */ + mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */ + ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd; + /* Division loop, traversed m-n+1 times. + j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */ + for (;;) + { + mp_limb_t q_star; + mp_limb_t c1; + if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */ + { + /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */ + mp_twolimb_t num = + ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS) + | r_ptr[j + b_len - 1]; + q_star = num / b_msd; + c1 = num % b_msd; + } + else + { + /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */ + q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */ + /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta + <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta + <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) + {<= beta !}. + If yes, jump directly to the subtraction loop. + (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta + <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */ + if (r_ptr[j + b_len] > b_msd + || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd) + /* r[j+n] >= b[n-1]+1 or + r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a + carry. */ + goto subtract; + } + /* q_star = q*, + c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, 0, decrease it by + b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2 + this can happen only twice. */ + if (c3 > c2) + { + q_star = q_star - 1; /* q* := q* - 1 */ + if (c3 - c2 > b_msdd) + q_star = q_star - 1; /* q* := q* - 1 */ + } + } + if (q_star > 0) + subtract: + { + /* Subtract r := r - b * q* * beta^j. */ + mp_limb_t cr; + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = r_ptr + j; + mp_twolimb_t carry = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + /* Here 0 <= carry <= q*. */ + carry = + carry + + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++ + + (mp_limb_t) ~(*destptr); + /* Here 0 <= carry <= beta*q* + beta-1. */ + *destptr++ = ~(mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; /* <= q* */ + } + cr = (mp_limb_t) carry; + } + /* Subtract cr from r_ptr[j + b_len], then forget about + r_ptr[j + b_len]. */ + if (cr > r_ptr[j + b_len]) + { + /* Subtraction gave a carry. */ + q_star = q_star - 1; /* q* := q* - 1 */ + /* Add b back. */ + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = r_ptr + j; + mp_limb_t carry = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + mp_limb_t source1 = *sourceptr++; + mp_limb_t source2 = *destptr; + *destptr++ = source1 + source2 + carry; + carry = + (carry + ? source1 >= (mp_limb_t) ~source2 + : source1 > (mp_limb_t) ~source2); + } + } + /* Forget about the carry and about r[j+n]. */ + } + } + /* q* is determined. Store it as q[j]. */ + q_ptr[j] = q_star; + if (j == 0) + break; + j--; + } + } + r_len = b_len; + /* Normalise q. */ + if (q_ptr[q_len - 1] == 0) + q_len--; +# if 0 /* Not needed here, since we need r only to compare it with b/2, and + b is shifted left by s bits. */ + /* Shift r right by s bits. */ + if (s > 0) + { + mp_limb_t ptr = r_ptr + r_len; + mp_twolimb_t accu = 0; + size_t count; + for (count = r_len; count > 0; count--) + { + accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS; + accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s); + *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS); + } + } +# endif + /* Normalise r. */ + while (r_len > 0 && r_ptr[r_len - 1] == 0) + r_len--; + } + /* Compare r << 1 with b. */ + if (r_len > b_len) + goto increment_q; + { + size_t i; + for (i = b_len;;) + { + mp_limb_t r_i = + (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0) + | (i < r_len ? r_ptr[i] << 1 : 0); + mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0); + if (r_i > b_i) + goto increment_q; + if (r_i < b_i) + goto keep_q; + if (i == 0) + break; + i--; + } + } + if (q_len > 0 && ((q_ptr[0] & 1) != 0)) + /* q is odd. */ + increment_q: + { + size_t i; + for (i = 0; i < q_len; i++) + if (++(q_ptr[i]) != 0) + goto keep_q; + q_ptr[q_len++] = 1; + } + keep_q: + if (tmp_roomptr != NULL) + free (tmp_roomptr); + q->limbs = q_ptr; + q->nlimbs = q_len; + return roomptr; +} + +/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal + representation. + Destroys the contents of a. + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +convert_to_decimal (mpn_t a, size_t extra_zeroes) +{ + mp_limb_t *a_ptr = a.limbs; + 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); + /* 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; + for (; extra_zeroes > 0; extra_zeroes--) + *d_ptr++ = '0'; + while (a_len > 0) + { + /* Divide a by 10^9, in-place. */ + mp_limb_t remainder = 0; + mp_limb_t *ptr = a_ptr + a_len; + size_t count; + for (count = a_len; count > 0; count--) + { + mp_twolimb_t num = + ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr; + *ptr = num / 1000000000; + remainder = num % 1000000000; + } + /* Store the remainder as 9 decimal digits. */ + for (count = 9; count > 0; count--) + { + *d_ptr++ = '0' + (remainder % 10); + remainder = remainder / 10; + } + /* Normalize a. */ + if (a_ptr[a_len - 1] == 0) + a_len--; + } + /* Remove leading zeroes. */ + while (d_ptr > c_ptr && d_ptr[-1] == '0') + d_ptr--; + /* But keep at least one zero. */ + if (d_ptr == c_ptr) + *d_ptr++ = '0'; + /* Terminate the string. */ + *d_ptr = '\0'; + } + return c_ptr; +} + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and >= 0: + write x as x = 2^e * m, where m is a bignum. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +decode_long_double (long double x, int *ep, mpn_t *mp) +{ + mpn_t m; + int exp; + long double y; + size_t i; + + /* Allocate memory for result. */ + m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); + if (m.limbs == NULL) + return NULL; + /* Split into exponential part and mantissa. */ + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); + /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the + latter is an integer. */ + /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'long double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int', + doesn't matter). */ +# if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0 +# if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2)); + hi = (int) y; + y -= hi; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# else + { + mp_limb_t d; + y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS); + d = (int) y; + y -= d; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d; + } +# endif +# endif + for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + hi = (int) y; + y -= hi; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess + precision. */ + if (!(y == 0.0L)) + abort (); +# endif + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; + *mp = m; + *ep = exp - LDBL_MANT_BIT; + return m.limbs; +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and >= 0: + write x as x = 2^e * m, where m is a bignum. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +decode_double (double x, int *ep, mpn_t *mp) +{ + mpn_t m; + int exp; + double y; + size_t i; + + /* Allocate memory for result. */ + m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); + if (m.limbs == NULL) + return NULL; + /* Split into exponential part and mantissa. */ + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); + /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the + latter is an integer. */ + /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'double' values between 0 and 2^16 (to 'unsigned int' or 'int', + doesn't matter). */ +# if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0 +# if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2)); + hi = (int) y; + y -= hi; + if (!(y >= 0.0 && y < 1.0)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# else + { + mp_limb_t d; + y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS); + d = (int) y; + y -= d; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d; + } +# endif +# endif + for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + hi = (int) y; + y -= hi; + if (!(y >= 0.0 && y < 1.0)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } + if (!(y == 0.0)) + abort (); + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; + *mp = m; + *ep = exp - DBL_MANT_BIT; + return m.limbs; +} + +# endif + +/* Assuming x = 2^e * m is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) +{ + int s; + size_t extra_zeroes; + unsigned int abs_n; + unsigned int abs_s; + mp_limb_t *pow5_ptr; + size_t pow5_len; + unsigned int s_limbs; + unsigned int s_bits; + mpn_t pow5; + mpn_t z; + void *z_memory; + char *digits; + + if (memory == NULL) + return NULL; + /* x = 2^e * m, hence + y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) + = round (2^s * 5^n * m). */ + s = e + n; + extra_zeroes = 0; + /* Factor out a common power of 10 if possible. */ + if (s > 0 && n > 0) + { + extra_zeroes = (s < n ? s : n); + s -= extra_zeroes; + n -= extra_zeroes; + } + /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes. + Before converting to decimal, we need to compute + z = round (2^s * 5^n * m). */ + /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same + sign. 2.322 is slightly larger than log(5)/log(2). */ + abs_n = (n >= 0 ? n : -n); + abs_s = (s >= 0 ? s : -s); + pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1 + + abs_s / GMP_LIMB_BITS + 1) + * sizeof (mp_limb_t)); + if (pow5_ptr == NULL) + { + free (memory); + return NULL; + } + /* Initialize with 1. */ + pow5_ptr[0] = 1; + pow5_len = 1; + /* Multiply with 5^|n|. */ + if (abs_n > 0) + { + static mp_limb_t const small_pow5[13 + 1] = + { + 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, + 48828125, 244140625, 1220703125 + }; + unsigned int n13; + for (n13 = 0; n13 <= abs_n; n13 += 13) + { + mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13]; + size_t j; + mp_twolimb_t carry = 0; + for (j = 0; j < pow5_len; j++) + { + mp_limb_t digit2 = pow5_ptr[j]; + carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; + pow5_ptr[j] = (mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; + } + if (carry > 0) + pow5_ptr[pow5_len++] = (mp_limb_t) carry; + } + } + s_limbs = abs_s / GMP_LIMB_BITS; + s_bits = abs_s % GMP_LIMB_BITS; + if (n >= 0 ? s >= 0 : s <= 0) + { + /* Multiply with 2^|s|. */ + if (s_bits > 0) + { + mp_limb_t *ptr = pow5_ptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = pow5_len; count > 0; count--) + { + accu += (mp_twolimb_t) *ptr << s_bits; + *ptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + if (accu > 0) + { + *ptr = (mp_limb_t) accu; + pow5_len++; + } + } + if (s_limbs > 0) + { + size_t count; + for (count = pow5_len; count > 0;) + { + count--; + pow5_ptr[s_limbs + count] = pow5_ptr[count]; + } + for (count = s_limbs; count > 0;) + { + count--; + pow5_ptr[count] = 0; + } + pow5_len += s_limbs; + } + pow5.limbs = pow5_ptr; + pow5.nlimbs = pow5_len; + if (n >= 0) + { + /* Multiply m with pow5. No division needed. */ + z_memory = multiply (m, pow5, &z); + } + else + { + /* Divide m by pow5 and round. */ + z_memory = divide (m, pow5, &z); + } + } + else + { + pow5.limbs = pow5_ptr; + pow5.nlimbs = pow5_len; + if (n >= 0) + { + /* n >= 0, s < 0. + Multiply m with pow5, then divide by 2^|s|. */ + mpn_t numerator; + mpn_t denominator; + void *tmp_memory; + tmp_memory = multiply (m, pow5, &numerator); + if (tmp_memory == NULL) + { + free (pow5_ptr); + free (memory); + return NULL; + } + /* Construct 2^|s|. */ + { + mp_limb_t *ptr = pow5_ptr + pow5_len; + size_t i; + for (i = 0; i < s_limbs; i++) + ptr[i] = 0; + ptr[s_limbs] = (mp_limb_t) 1 << s_bits; + denominator.limbs = ptr; + denominator.nlimbs = s_limbs + 1; + } + z_memory = divide (numerator, denominator, &z); + free (tmp_memory); + } + else + { + /* n < 0, s > 0. + Multiply m with 2^s, then divide by pow5. */ + mpn_t numerator; + mp_limb_t *num_ptr; + num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1) + * sizeof (mp_limb_t)); + if (num_ptr == NULL) + { + free (pow5_ptr); + free (memory); + return NULL; + } + { + mp_limb_t *destptr = num_ptr; + { + size_t i; + for (i = 0; i < s_limbs; i++) + *destptr++ = 0; + } + if (s_bits > 0) + { + const mp_limb_t *sourceptr = m.limbs; + mp_twolimb_t accu = 0; + size_t count; + for (count = m.nlimbs; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s_bits; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + if (accu > 0) + *destptr++ = (mp_limb_t) accu; + } + else + { + const mp_limb_t *sourceptr = m.limbs; + size_t count; + for (count = m.nlimbs; count > 0; count--) + *destptr++ = *sourceptr++; + } + numerator.limbs = num_ptr; + numerator.nlimbs = destptr - num_ptr; + } + z_memory = divide (numerator, pow5, &z); + free (num_ptr); + } + } + free (pow5_ptr); + free (memory); + + /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ + + if (z_memory == NULL) + return NULL; + digits = convert_to_decimal (z, extra_zeroes); + free (z_memory); + return digits; +} + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_long_double (long double x, int n) +{ + int e IF_LINT(= 0); + mpn_t m; + void *memory = decode_long_double (x, &e, &m); + return scale10_round_decimal_decoded (e, m, memory, n); +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_double (double x, int n) +{ + int e IF_LINT(= 0); + mpn_t m; + void *memory = decode_double (x, &e, &m); + return scale10_round_decimal_decoded (e, m, memory, n); +} + +# endif + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and > 0: + Return an approximation for n with 10^n <= x < 10^(n+1). + The approximation is usually the right n, but may be off by 1 sometimes. */ +static int +floorlog10l (long double x) +{ + int exp; + long double y; + double z; + double l; + + /* Split into exponential part and mantissa. */ + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); + if (y == 0.0L) + return INT_MIN; + if (y < 0.5L) + { + while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) + { + y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); + exp -= GMP_LIMB_BITS; + } + if (y < (1.0L / (1 << 16))) + { + y *= 1.0L * (1 << 16); + exp -= 16; + } + if (y < (1.0L / (1 << 8))) + { + y *= 1.0L * (1 << 8); + exp -= 8; + } + if (y < (1.0L / (1 << 4))) + { + y *= 1.0L * (1 << 4); + exp -= 4; + } + if (y < (1.0L / (1 << 2))) + { + y *= 1.0L * (1 << 2); + exp -= 2; + } + if (y < (1.0L / (1 << 1))) + { + y *= 1.0L * (1 << 1); + exp -= 1; + } + } + if (!(y >= 0.5L && y < 1.0L)) + abort (); + /* Compute an approximation for l = log2(x) = exp + log2(y). */ + l = exp; + z = y; + if (z < 0.70710678118654752444) + { + z *= 1.4142135623730950488; + l -= 0.5; + } + if (z < 0.8408964152537145431) + { + z *= 1.1892071150027210667; + l -= 0.25; + } + if (z < 0.91700404320467123175) + { + z *= 1.0905077326652576592; + l -= 0.125; + } + if (z < 0.9576032806985736469) + { + z *= 1.0442737824274138403; + l -= 0.0625; + } + /* Now 0.95 <= z <= 1.01. */ + z = 1 - z; + /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) + Four terms are enough to get an approximation with error < 10^-7. */ + l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); + /* Finally multiply with log(2)/log(10), yields an approximation for + log10(x). */ + l *= 0.30102999566398119523; + /* Round down to the next integer. */ + return (int) l + (l < 0 ? -1 : 0); +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and > 0: + Return an approximation for n with 10^n <= x < 10^(n+1). + The approximation is usually the right n, but may be off by 1 sometimes. */ +static int +floorlog10 (double x) +{ + int exp; + double y; + double z; + double l; + + /* Split into exponential part and mantissa. */ + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); + if (y == 0.0) + return INT_MIN; + if (y < 0.5) + { + while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) + { + y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); + exp -= GMP_LIMB_BITS; + } + if (y < (1.0 / (1 << 16))) + { + y *= 1.0 * (1 << 16); + exp -= 16; + } + if (y < (1.0 / (1 << 8))) + { + y *= 1.0 * (1 << 8); + exp -= 8; + } + if (y < (1.0 / (1 << 4))) + { + y *= 1.0 * (1 << 4); + exp -= 4; + } + if (y < (1.0 / (1 << 2))) + { + y *= 1.0 * (1 << 2); + exp -= 2; + } + if (y < (1.0 / (1 << 1))) + { + y *= 1.0 * (1 << 1); + exp -= 1; + } + } + if (!(y >= 0.5 && y < 1.0)) + abort (); + /* Compute an approximation for l = log2(x) = exp + log2(y). */ + l = exp; + z = y; + if (z < 0.70710678118654752444) + { + z *= 1.4142135623730950488; + l -= 0.5; + } + if (z < 0.8408964152537145431) + { + z *= 1.1892071150027210667; + l -= 0.25; + } + if (z < 0.91700404320467123175) + { + z *= 1.0905077326652576592; + l -= 0.125; + } + if (z < 0.9576032806985736469) + { + z *= 1.0442737824274138403; + l -= 0.0625; + } + /* Now 0.95 <= z <= 1.01. */ + z = 1 - z; + /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) + Four terms are enough to get an approximation with error < 10^-7. */ + l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); + /* Finally multiply with log(2)/log(10), yields an approximation for + log10(x). */ + l *= 0.30102999566398119523; + /* Round down to the next integer. */ + return (int) l + (l < 0 ? -1 : 0); +} + +# endif + +/* Tests whether a string of digits consists of exactly PRECISION zeroes and + a single '1' digit. */ +static int +is_borderline (const char *digits, size_t precision) +{ + for (; precision > 0; precision--, digits++) + if (*digits != '0') + return 0; + if (*digits != '1') + return 0; + digits++; + return *digits == '\0'; +} + +#endif + +#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 + translation unit. */ +# if WIDE_CHAR_VERSION +# define MAX_ROOM_NEEDED wmax_room_needed +# else +# define MAX_ROOM_NEEDED max_room_needed +# endif + +/* Returns the number of TCHAR_T units needed as temporary space for the result + of sprintf or SNPRINTF of a single conversion directive. */ +static size_t +MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, + arg_type type, int flags, size_t width, int has_precision, + size_t precision, int pad_ourselves) +{ + size_t tmp_length; + + switch (conversion) + { + case 'd': case 'i': case 'u': + 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 if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Multiply by 2, as an estimate for FLAG_GROUP. */ + tmp_length = xsum (tmp_length, tmp_length); + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); + break; + + case 'o': + 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 if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); + break; + + case 'x': case 'X': + 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 if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 2, to account for a leading sign or alternate form. */ + tmp_length = xsum (tmp_length, 2); + break; + + case 'f': case 'F': + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) (LDBL_MAX_EXP + * 0.30103 /* binary -> decimal */ + * 2 /* estimate for FLAG_GROUP */ + ) + + 1 /* turn floor into ceil */ + + 10; /* sign, decimal point etc. */ + else + tmp_length = + (unsigned int) (DBL_MAX_EXP + * 0.30103 /* binary -> decimal */ + * 2 /* estimate for FLAG_GROUP */ + ) + + 1 /* turn floor into ceil */ + + 10; /* sign, decimal point etc. */ + tmp_length = xsum (tmp_length, precision); + break; + + case 'e': case 'E': case 'g': case 'G': + tmp_length = + 12; /* sign, decimal point, exponent etc. */ + tmp_length = xsum (tmp_length, precision); + break; + + case 'a': case 'A': + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) (LDBL_DIG + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (DBL_DIG + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + break; + + case 'c': +# if HAVE_WINT_T && !WIDE_CHAR_VERSION + if (type == TYPE_WIDE_CHAR) + { + 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; + break; + + case 's': +# if HAVE_WCHAR_T + if (type == TYPE_WIDE_STRING) + { +# if WIDE_CHAR_VERSION + /* ISO C says about %ls in fwprintf: + "If the precision is not specified or is greater than the size + of the array, the array shall contain a null wide character." + So if there is a precision, we must not use wcslen. */ + const wchar_t *arg = ap->arg[arg_index].a.a_wide_string; + + if (has_precision) + tmp_length = local_wcsnlen (arg, precision); + else + tmp_length = local_wcslen (arg); +# else + /* ISO C says about %ls in fprintf: + "If a precision is specified, no more than that many bytes are + written (including shift sequences, if any), and the array + shall contain a null wide character if, to equal the multibyte + character sequence length given by the precision, the function + would need to access a wide character one past the end of the + array." + So if there is a precision, we must not use wcslen. */ + /* This case has already been handled separately in VASNPRINTF. */ + abort (); +# endif + } + else +# endif + { +# if WIDE_CHAR_VERSION + /* ISO C says about %s in fwprintf: + "If the precision is not specified or is greater than the size + of the converted array, the converted array shall contain a + null wide character." + So if there is a precision, we must not use strlen. */ + /* This case has already been handled separately in VASNPRINTF. */ + abort (); +# else + /* ISO C says about %s in fprintf: + "If the precision is not specified or greater than the size of + the array, the array shall contain a null character." + So if there is a precision, we must not use strlen. */ + const char *arg = ap->arg[arg_index].a.a_string; + + if (has_precision) + tmp_length = local_strnlen (arg, precision); + else + tmp_length = strlen (arg); +# endif + } + break; + + case 'p': + tmp_length = + (unsigned int) (sizeof (void *) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1 /* turn floor into ceil */ + + 2; /* account for leading 0x */ + break; + + default: + abort (); + } + + if (!pad_ourselves) + { +# if ENABLE_UNISTDIO + /* Padding considers the number of characters, therefore the number of + elements after padding may be + > max (tmp_length, width) + but is certainly + <= tmp_length + width. */ + tmp_length = xsum (tmp_length, width); +# else + /* Padding considers the number of elements, says POSIX. */ + if (tmp_length < width) + tmp_length = width; +# endif + } + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + return tmp_length; +} + +#endif + +DCHAR_T * +VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + const FCHAR_T *format, va_list args) +{ + DIRECTIVES d; + arguments a; + + if (PRINTF_PARSE (format, &d, &a) < 0) + /* 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); \ + if (a.arg != a.direct_alloc_arg) \ + free (a.arg); + + if (PRINTF_FETCHARGS (args, &a) < 0) + { + CLEANUP (); + errno = EINVAL; + return NULL; + } + + { + size_t buf_neededlength; + TCHAR_T *buf; + TCHAR_T *buf_malloced; + const FCHAR_T *cp; + size_t i; + DIRECTIVE *dp; + /* Output string accumulator. */ + DCHAR_T *result; + size_t allocated; + size_t length; + + /* Allocate a small buffer that will hold a directive passed to + sprintf or snprintf. */ + buf_neededlength = + xsum4 (7, d.max_width_length, d.max_precision_length, 6); +#if HAVE_ALLOCA + if (buf_neededlength < 4000 / sizeof (TCHAR_T)) + { + buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T)); + buf_malloced = NULL; + } + else +#endif + { + size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T)); + if (size_overflow_p (buf_memsize)) + goto out_of_memory_1; + buf = (TCHAR_T *) malloc (buf_memsize); + if (buf == NULL) + goto out_of_memory_1; + buf_malloced = buf; + } + + if (resultbuf != NULL) + { + result = resultbuf; + allocated = *lengthp; + } + else + { + result = NULL; + allocated = 0; + } + length = 0; + /* Invariants: + result is either == resultbuf or == NULL or malloc-allocated. + 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_ELSE(needed, oom_statement) \ + if ((needed) > allocated) \ + { \ + size_t memory_size; \ + DCHAR_T *memory; \ + \ + allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \ + if ((needed) > allocated) \ + allocated = (needed); \ + memory_size = xtimes (allocated, sizeof (DCHAR_T)); \ + if (size_overflow_p (memory_size)) \ + oom_statement \ + if (result == resultbuf || result == NULL) \ + memory = (DCHAR_T *) malloc (memory_size); \ + else \ + memory = (DCHAR_T *) realloc (result, memory_size); \ + if (memory == NULL) \ + 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++) + { + if (cp != dp->dir_start) + { + size_t n = dp->dir_start - cp; + size_t augmented_length = xsum (length, n); + + ENSURE_ALLOCATION (augmented_length); + /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we + need that the format string contains only ASCII characters + if FCHAR_T and DCHAR_T are not the same type. */ + if (sizeof (FCHAR_T) == sizeof (DCHAR_T)) + { + DCHAR_CPY (result + length, (const DCHAR_T *) cp, n); + length = augmented_length; + } + else + { + do + result[length++] = *cp++; + while (--n > 0); + } + } + if (i == d.count) + break; + + /* Execute a single directive. */ + if (dp->conversion == '%') + { + size_t augmented_length; + + if (!(dp->arg_index == ARG_NONE)) + abort (); + augmented_length = xsum (length, 1); + ENSURE_ALLOCATION (augmented_length); + result[length] = '%'; + length = augmented_length; + } + else + { + if (!(dp->arg_index != ARG_NONE)) + abort (); + + if (dp->conversion == 'n') + { + switch (a.arg[dp->arg_index].type) + { + case TYPE_COUNT_SCHAR_POINTER: + *a.arg[dp->arg_index].a.a_count_schar_pointer = length; + break; + case TYPE_COUNT_SHORT_POINTER: + *a.arg[dp->arg_index].a.a_count_short_pointer = length; + break; + case TYPE_COUNT_INT_POINTER: + *a.arg[dp->arg_index].a.a_count_int_pointer = length; + break; + case TYPE_COUNT_LONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longint_pointer = length; + break; + case TYPE_COUNT_LONGLONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; + break; + default: + abort (); + } + } +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + else if (dp->conversion == 'U') + { + 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; + + 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; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + switch (type) + { + case TYPE_U8_STRING: + { + const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string; + const uint8_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u8_strmblen (arg_end); + 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; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u8_strmblen (arg_end); + 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; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u8_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (characters < width && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT8_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-8 to locale encoding. */ + converted = + u8_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-8 to UTF-16/UTF-32. */ + converted = + U8_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), + { free (converted); goto out_of_memory; }); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (characters < width && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + case TYPE_U16_STRING: + { + const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string; + const uint16_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u16_strmblen (arg_end); + 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; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u16_strmblen (arg_end); + 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; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u16_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (characters < width && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT16_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-16 to locale encoding. */ + converted = + u16_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-16 to UTF-8/UTF-32. */ + converted = + U16_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), + { free (converted); goto out_of_memory; }); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (characters < width && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + case TYPE_U32_STRING: + { + const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string; + const uint32_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u32_strmblen (arg_end); + 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; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u32_strmblen (arg_end); + 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; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u32_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (characters < width && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT32_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-32 to locale encoding. */ + converted = + u32_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-32 to UTF-8/UTF-16. */ + converted = + U32_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), + { free (converted); goto out_of_memory; }); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (characters < width && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + default: + abort (); + } + } +#endif +#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 +# else + && a.arg[dp->arg_index].type == TYPE_WIDE_STRING +# endif + ) + { + /* The normal handling of the 's' directive below requires + allocating a temporary buffer. The determination of its + length (tmp_length), in the case when a precision is + specified, below requires a conversion between a char[] + string and a wchar_t[] wide string. It could be done, but + we have no guarantee that the implementation of sprintf will + use the exactly same algorithm. Without this guarantee, it + is possible to have buffer overrun bugs. In order to avoid + such bugs, we implement the entire processing of the 's' + directive ourselves. */ + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + + 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; + } + + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + +# if WIDE_CHAR_VERSION + /* %s in vasnwprintf. See the specification of fwprintf. */ + { + const char *arg = a.arg[dp->arg_index].a.a_string; + const char *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only as many bytes as needed to produce PRECISION + wide characters, from the left. */ +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count; +# if HAVE_MBRTOWC + count = mbrlen (arg_end, MB_CUR_MAX, &state); +# else + count = mblen (arg_end, MB_CUR_MAX); +# endif + if (count == 0) + /* 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; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of wide + characters. */ +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (;;) + { + int count; +# if HAVE_MBRTOWC + count = mbrlen (arg_end, MB_CUR_MAX, &state); +# else + count = mblen (arg_end, MB_CUR_MAX); +# endif + if (count == 0) + /* 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; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (characters < width && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + + if (has_precision || has_width) + { + /* We know the number of wide characters in advance. */ + size_t remaining; +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + ENSURE_ALLOCATION (xsum (length, characters)); + for (remaining = characters; remaining > 0; remaining--) + { + wchar_t wc; + int count; +# if HAVE_MBRTOWC + count = mbrtowc (&wc, arg, arg_end - arg, &state); +# else + count = mbtowc (&wc, arg, arg_end - arg); +# endif + if (count <= 0) + /* mbrtowc not consistent with mbrlen, or mbtowc + not consistent with mblen. */ + abort (); + result[length++] = wc; + arg += count; + } + if (!(arg == arg_end)) + abort (); + } + else + { +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + while (arg < arg_end) + { + wchar_t wc; + int count; +# if HAVE_MBRTOWC + count = mbrtowc (&wc, arg, arg_end - arg, &state); +# else + count = mbtowc (&wc, arg, arg_end - arg); +# endif + if (count <= 0) + /* mbrtowc not consistent with mbrlen, or mbtowc + not consistent with mblen. */ + abort (); + ENSURE_ALLOCATION (xsum (length, 1)); + result[length++] = wc; + arg += count; + } + } + + if (characters < width && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } +# else + /* %ls in vasnprintf. See the specification of fprintf. */ + { + const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; + const wchar_t *arg_end; + size_t characters; +# if !DCHAR_IS_TCHAR + /* This code assumes that TCHAR_T is 'char'. */ + verify (sizeof (TCHAR_T) == 1); + TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; +# endif + size_t w; + + if (has_precision) + { + /* Use only as many wide characters as needed to produce + at most PRECISION bytes, from the left. */ +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + while (precision > 0) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg_end == 0) + /* Found the terminating null wide character. */ + break; + 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 < (unsigned int) count) + break; + arg_end++; + characters += count; + precision -= count; + } + } +# if DCHAR_IS_TCHAR + else if (has_width) +# else + else +# endif + { + /* Use the entire string, and count the number of + bytes. */ +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (;;) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg_end == 0) + /* Found the terminating null wide character. */ + break; + 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; + } + arg_end++; + characters += count; + } + } +# if DCHAR_IS_TCHAR + else + { + /* Use the entire string. */ + arg_end = arg + local_wcslen (arg); + /* The number of bytes doesn't matter. */ + characters = 0; + } +# endif + +# if !DCHAR_IS_TCHAR + /* Convert the string into a piece of temporary memory. */ + tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T)); + if (tmpsrc == NULL) + goto out_of_memory; + { + TCHAR_T *tmpptr = tmpsrc; + size_t remaining; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + for (remaining = characters; remaining > 0; ) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); + count = local_wcrtomb (cbuf, *arg, &state); + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (tmpptr, cbuf, count); + tmpptr += count; + arg++; + remaining -= count; + } + if (!(arg == arg_end)) + abort (); + } + + /* 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) + { + free (tmpsrc); + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + return NULL; + } + free (tmpsrc); +# 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_precision || has_width) + { + /* We know the number of bytes in advance. */ + size_t remaining; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + ENSURE_ALLOCATION (xsum (length, characters)); + for (remaining = characters; remaining > 0; ) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); + count = local_wcrtomb (cbuf, *arg, &state); + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (result + length, cbuf, count); + length += count; + arg++; + remaining -= count; + } + if (!(arg == arg_end)) + abort (); + } + else + { +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + while (arg < arg_end) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); + 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; + } + ENSURE_ALLOCATION (xsum (length, count)); + memcpy (result + length, cbuf, count); + length += count; + arg++; + } + } +# 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 + } +#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) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + return NULL; + } +# 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)) + && (0 +# if NEED_PRINTF_DOUBLE + || a.arg[dp->arg_index].type == TYPE_DOUBLE +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# endif + ) +# endif + ) + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; + 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; + + 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_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + /* Allocate a temporary buffer of sufficient size. */ + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) ((LDBL_DIG + 1) + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) ((DBL_DIG + 1) + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + + if (tmp_length < width) + tmp_length = width; + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (DCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } + + pad_ptr = NULL; + p = tmp; + if (type == TYPE_LONGDOUBLE) + { +# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE + long double arg = a.arg[dp->arg_index].a.a_longdouble; + + if (isnanl (arg)) + { + if (dp->conversion == 'A') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion == 'A') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + int exponent; + long double mantissa; + + if (arg > 0.0L) + mantissa = printf_frexpl (arg, &exponent); + else + { + exponent = 0; + mantissa = 0.0L; + } + + if (has_precision + && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1) + { + /* Round the mantissa. */ + long double tail = mantissa; + size_t q; + + for (q = precision; ; q--) + { + int digit = (int) tail; + tail -= digit; + if (q == 0) + { + if (digit & 1 ? tail >= 0.5L : tail > 0.5L) + tail = 1 - tail; + else + tail = - tail; + break; + } + tail *= 16.0L; + } + if (tail != 0.0L) + for (q = precision; q > 0; q--) + tail *= 0.0625L; + mantissa += tail; + } + + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + { + int digit; + + digit = (int) mantissa; + mantissa -= digit; + *p++ = '0' + digit; + if ((flags & FLAG_ALT) + || mantissa > 0.0L || precision > 0) + { + *p++ = decimal_point_char (); + /* This loop terminates because we assume + that FLT_RADIX is a power of 2. */ + while (mantissa > 0.0L) + { + mantissa *= 16.0L; + digit = (int) mantissa; + mantissa -= digit; + *p++ = digit + + (digit < 10 + ? '0' + : dp->conversion - 10); + if (precision > 0) + precision--; + } + while (precision > 0) + { + *p++ = '0'; + precision--; + } + } + } + *p++ = dp->conversion - 'A' + 'P'; +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + + END_LONG_DOUBLE_ROUNDING (); + } +# else + abort (); +# endif + } + else + { +# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnand (arg)) + { + if (dp->conversion == 'A') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0 or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion == 'A') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + int exponent; + double mantissa; + + if (arg > 0.0) + mantissa = printf_frexp (arg, &exponent); + else + { + exponent = 0; + mantissa = 0.0; + } + + if (has_precision + && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1) + { + /* Round the mantissa. */ + double tail = mantissa; + size_t q; + + for (q = precision; ; q--) + { + int digit = (int) tail; + tail -= digit; + if (q == 0) + { + if (digit & 1 ? tail >= 0.5 : tail > 0.5) + tail = 1 - tail; + else + tail = - tail; + break; + } + tail *= 16.0; + } + if (tail != 0.0) + for (q = precision; q > 0; q--) + tail *= 0.0625; + mantissa += tail; + } + + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + { + int digit; + + digit = (int) mantissa; + mantissa -= digit; + *p++ = '0' + digit; + if ((flags & FLAG_ALT) + || mantissa > 0.0 || precision > 0) + { + *p++ = decimal_point_char (); + /* This loop terminates because we assume + that FLT_RADIX is a power of 2. */ + while (mantissa > 0.0) + { + mantissa *= 16.0; + digit = (int) mantissa; + mantissa -= digit; + *p++ = digit + + (digit < 10 + ? '0' + : dp->conversion - 10); + if (precision > 0) + precision--; + } + while (precision > 0) + { + *p++ = '0'; + precision--; + } + } + } + *p++ = dp->conversion - 'A' + 'P'; +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + } +# else + abort (); +# endif + } + + /* The generated string now extends from tmp to p, with the + zero padding insertion point being at pad_ptr. */ + count = p - tmp; + + if (count < width) + { + size_t pad = width - count; + DCHAR_T *end = p + pad; + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > tmp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + + p = end; + } + + count = p - tmp; + + 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); + + ENSURE_ALLOCATION (n); + } + + /* 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 + else if ((dp->conversion == 'f' || dp->conversion == 'F' + || dp->conversion == 'e' || dp->conversion == 'E' + || dp->conversion == 'g' || dp->conversion == 'G' + || dp->conversion == 'a' || dp->conversion == 'A') + && (0 +# if NEED_PRINTF_DOUBLE + || a.arg[dp->arg_index].type == TYPE_DOUBLE +# elif NEED_PRINTF_INFINITE_DOUBLE + || (a.arg[dp->arg_index].type == TYPE_DOUBLE + /* The systems (mingw) which produce wrong output + for Inf, -Inf, and NaN also do so for -0.0. + Therefore we treat this case here as well. */ + && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double)) +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# elif NEED_PRINTF_INFINITE_LONG_DOUBLE + || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE + /* Some systems produce wrong output for Inf, + -Inf, and NaN. Some systems in this category + (IRIX 5.3) also do so for -0.0. Therefore we + treat this case here as well. */ + && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble)) +# endif + )) + { +# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) + arg_type type = a.arg[dp->arg_index].type; +# endif + int flags = dp->flags; + size_t width; + size_t count; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + 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_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + /* POSIX specifies the default precision to be 6 for %f, %F, + %e, %E, but not for %g, %G. Implementations appear to use + the same default precision also for %g, %G. But for %a, %A, + the default precision is 0. */ + if (!has_precision) + if (!(dp->conversion == 'a' || dp->conversion == 'A')) + precision = 6; + + /* Allocate a temporary buffer of sufficient size. */ +# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1); +# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0); +# elif NEED_PRINTF_LONG_DOUBLE + tmp_length = LDBL_DIG + 1; +# elif NEED_PRINTF_DOUBLE + tmp_length = DBL_DIG + 1; +# else + tmp_length = 0; +# endif + if (tmp_length < precision) + tmp_length = precision; +# if NEED_PRINTF_LONG_DOUBLE +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + if (type == TYPE_LONGDOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + if (!(isnanl (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10l (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } + } +# endif +# if NEED_PRINTF_DOUBLE +# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE + if (type == TYPE_DOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') + { + double arg = a.arg[dp->arg_index].a.a_double; + if (!(isnand (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10 (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } + } +# endif + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + + if (tmp_length < width) + tmp_length = width; + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (DCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } + + pad_ptr = NULL; + p = tmp; + +# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + if (type == TYPE_LONGDOUBLE) +# endif + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + + if (isnanl (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { +# if NEED_PRINTF_LONG_DOUBLE + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + char *digits; + size_t ndigits; + + digits = + scale10_round_decimal_long_double (arg, precision); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + int exponent; + + if (arg == 0.0L) + { + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else + { + /* arg > 0.0L. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)precision - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision+1. */ + if (is_borderline (digits, precision)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_long_double (arg, + (int)precision - exponent + 1); + if (digits2 == NULL) + { + free (digits); + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + if (strlen (digits2) == precision + 1) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision+1. */ + + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+.2d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+.2d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0L) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ + { + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = '0'; + } + } + } + else + { + /* arg > 0.0L. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + if (is_borderline (digits, precision - 1)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent + 1); + if (digits2 == NULL) + { + free (digits); + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + if (strlen (digits2) == precision) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t ecount = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; ecount > 0; ecount--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t ecount = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; ecount > 0; ecount--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+.2d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+.2d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + + free (digits); + } + } + else + abort (); +# else + /* arg is finite. */ + if (!(arg == 0.0L)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else if (dp->conversion == 'a' || dp->conversion == 'A') + { + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion - 'A' + 'P'; + *p++ = '+'; + *p++ = '0'; + } + else + abort (); +# endif + } + + END_LONG_DOUBLE_ROUNDING (); + } + } +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + else +# endif +# endif +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + { + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnand (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0 or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { +# if NEED_PRINTF_DOUBLE + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + char *digits; + size_t ndigits; + + digits = + scale10_round_decimal_double (arg, precision); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + int exponent; + + if (arg == 0.0) + { + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else + { + /* arg > 0.0. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10 (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_double (arg, + (int)precision - exponent); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision+1. */ + if (is_borderline (digits, precision)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_double (arg, + (int)precision - exponent + 1); + if (digits2 == NULL) + { + free (digits); + goto out_of_memory; + } + if (strlen (digits2) == precision + 1) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision+1. */ + + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if defined _WIN32 && ! defined __CYGWIN__ + { '%', '+', '.', '3', 'd', '\0' }; +# else + { '%', '+', '.', '2', 'd', '\0' }; +# endif + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + { + static const char decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if defined _WIN32 && ! defined __CYGWIN__ + "%+.3d"; +# else + "%+.2d"; +# endif + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, decimal_format, exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, decimal_format, exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } + } +# endif + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ + { + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = '0'; + } + } + } + else + { + /* arg > 0.0. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10 (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + if (is_borderline (digits, precision - 1)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_double (arg, + (int)(precision - 1) - exponent + 1); + if (digits2 == NULL) + { + free (digits); + goto out_of_memory; + } + if (strlen (digits2) == precision) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t ecount = exponent + 1; + /* Note: ecount <= precision = ndigits. */ + for (; ecount > 0; ecount--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t ecount = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; ecount > 0; ecount--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if defined _WIN32 && ! defined __CYGWIN__ + { '%', '+', '.', '3', 'd', '\0' }; +# else + { '%', '+', '.', '2', 'd', '\0' }; +# endif + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + { + static const char decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if defined _WIN32 && ! defined __CYGWIN__ + "%+.3d"; +# else + "%+.2d"; +# endif + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, decimal_format, exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, decimal_format, exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } + } +# endif + } + + free (digits); + } + } + else + abort (); +# else + /* arg is finite. */ + if (!(arg == 0.0)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + /* Produce the same number of exponent digits as + the native printf implementation. */ +# if defined _WIN32 && ! defined __CYGWIN__ + *p++ = '0'; +# endif + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else + abort (); +# endif + } + } + } +# endif + + /* The generated string now extends from tmp to p, with the + zero padding insertion point being at pad_ptr. */ + count = p - tmp; + + if (count < width) + { + size_t pad = width - count; + DCHAR_T *end = p + pad; + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > tmp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + + p = end; + } + + count = p - tmp; + + 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); + + ENSURE_ALLOCATION (n); + } + + /* 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 !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 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION + int has_precision; + size_t precision; +#endif +#if NEED_PRINTF_UNBOUNDED_PRECISION + int prec_ourselves; +#else +# define prec_ourselves 0 +#endif +#if NEED_PRINTF_FLAG_LEFTADJUST +# define pad_ourselves 1 +#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int pad_ourselves; +#else +# define pad_ourselves 0 +#endif + TCHAR_T *fbp; + unsigned int prefix_count; + int prefixes[2] IF_LINT (= { 0 }); + int orig_errno; +#if !USE_SNPRINTF + size_t tmp_length; + TCHAR_T tmpbuf[700]; + TCHAR_T *tmp; +#endif + +#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) + { + 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); + } +#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 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } +#endif + + /* Decide whether to handle the precision ourselves. */ +#if NEED_PRINTF_UNBOUNDED_PRECISION + switch (dp->conversion) + { + case 'd': case 'i': case 'u': + case 'o': + case 'x': case 'X': case 'p': + prec_ourselves = has_precision && (precision > 0); + break; + default: + prec_ourselves = 0; + break; + } +#endif + + /* Decide whether to perform the padding ourselves. */ +#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION) + switch (dp->conversion) + { +# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO + /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need + to perform the padding after this conversion. Functions + with unistdio extensions perform the padding based on + character count rather than element count. */ + case 'c': case 's': +# endif +# if NEED_PRINTF_FLAG_ZERO + case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': + case 'a': case 'A': +# endif + pad_ourselves = 1; + break; + default: + pad_ourselves = prec_ourselves; + break; + } +#endif + +#if !USE_SNPRINTF + /* Allocate a temporary buffer of sufficient size for calling + sprintf. */ + tmp_length = + MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type, + flags, width, has_precision, precision, + pad_ourselves); + + if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (TCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } +#endif + + /* Construct the format string for calling snprintf or + sprintf. */ + fbp = buf; + *fbp++ = '%'; +#if NEED_PRINTF_FLAG_GROUPING + /* The underlying implementation doesn't support the ' flag. + Produce no grouping characters in this case; this is + acceptable because the grouping is locale dependent. */ +#else + if (flags & FLAG_GROUP) + *fbp++ = '\''; +#endif + if (flags & FLAG_LEFT) + *fbp++ = '-'; + if (flags & FLAG_SHOWSIGN) + *fbp++ = '+'; + if (flags & FLAG_SPACE) + *fbp++ = ' '; + if (flags & FLAG_ALT) + *fbp++ = '#'; +#if __GLIBC__ >= 2 && !defined __UCLIBC__ + if (flags & FLAG_LOCALIZED) + *fbp++ = 'I'; +#endif + if (!pad_ourselves) + { + if (flags & FLAG_ZERO) + *fbp++ = '0'; + if (dp->width_start != dp->width_end) + { + size_t n = dp->width_end - dp->width_start; + /* The width specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->width_start; + do + *fbp++ = *mp++; + while (--n > 0); + } + } + } + if (!prec_ourselves) + { + if (dp->precision_start != dp->precision_end) + { + size_t n = dp->precision_end - dp->precision_start; + /* The precision specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->precision_start; + do + *fbp++ = *mp++; + while (--n > 0); + } + } + } + + switch (type) + { + case TYPE_LONGLONGINT: + case TYPE_ULONGLONGINT: +#if defined _WIN32 && ! defined __CYGWIN__ + *fbp++ = 'I'; + *fbp++ = '6'; + *fbp++ = '4'; + break; +#else + *fbp++ = 'l'; +#endif + FALLTHROUGH; + case TYPE_LONGINT: + case TYPE_ULONGINT: +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: +#endif +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: +#endif + *fbp++ = 'l'; + break; + case TYPE_LONGDOUBLE: + *fbp++ = 'L'; + break; + default: + break; + } +#if NEED_PRINTF_DIRECTIVE_F + if (dp->conversion == 'F') + *fbp = 'f'; + else +#endif + *fbp = dp->conversion; +#if USE_SNPRINTF +# 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, + snprintf does not write more than the specified number + of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes + '4', '5', '6' into buf, not '4', '5', '\0'.) + - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf + allows us to recognize the case of an insufficient + buffer size: it returns -1 in this case. + 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 + + 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'; +#endif + + /* Construct the arguments for calling snprintf or sprintf. */ + prefix_count = 0; + if (!pad_ourselves && dp->width_arg_index != ARG_NONE) + { + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; + } + if (!prec_ourselves && dp->precision_arg_index != ARG_NONE) + { + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; + } + +#if USE_SNPRINTF + /* The SNPRINTF result is appended after result[0..length]. + The latter is an array of DCHAR_T; SNPRINTF appends an + array of TCHAR_T to it. This is possible because + sizeof (TCHAR_T) divides sizeof (DCHAR_T) and + alignof (TCHAR_T) <= alignof (DCHAR_T). */ +# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T)) + /* Ensure that maxlen below will be >= 2. Needed on BeOS, + where an snprintf() with maxlen==1 acts like sprintf(). */ + ENSURE_ALLOCATION (xsum (length, + (2 + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR)); + /* Prepare checking whether snprintf returns the count + via %n. */ + *(TCHAR_T *) (result + length) = '\0'; +#endif + + orig_errno = errno; + + for (;;) + { + int count = -1; + +#if USE_SNPRINTF + int retcount = 0; + size_t maxlen = allocated - length; + /* SNPRINTF can fail if its second argument is + > INT_MAX. */ + if (maxlen > INT_MAX / TCHARS_PER_DCHAR) + maxlen = INT_MAX / TCHARS_PER_DCHAR; + maxlen = maxlen * TCHARS_PER_DCHAR; +# define SNPRINTF_BUF(arg) \ + switch (prefix_count) \ + { \ + case 0: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + arg, &count); \ + break; \ + case 1: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + prefixes[0], arg, &count); \ + break; \ + case 2: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + prefixes[0], prefixes[1], arg, \ + &count); \ + break; \ + default: \ + abort (); \ + } +#else +# define SNPRINTF_BUF(arg) \ + switch (prefix_count) \ + { \ + case 0: \ + count = sprintf (tmp, buf, arg); \ + break; \ + case 1: \ + count = sprintf (tmp, buf, prefixes[0], arg); \ + break; \ + case 2: \ + count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ + arg); \ + break; \ + default: \ + abort (); \ + } +#endif + + errno = 0; + switch (type) + { + case TYPE_SCHAR: + { + int arg = a.arg[dp->arg_index].a.a_schar; + SNPRINTF_BUF (arg); + } + break; + case TYPE_UCHAR: + { + unsigned int arg = a.arg[dp->arg_index].a.a_uchar; + SNPRINTF_BUF (arg); + } + break; + case TYPE_SHORT: + { + int arg = a.arg[dp->arg_index].a.a_short; + SNPRINTF_BUF (arg); + } + break; + case TYPE_USHORT: + { + unsigned int arg = a.arg[dp->arg_index].a.a_ushort; + SNPRINTF_BUF (arg); + } + break; + case TYPE_INT: + { + int arg = a.arg[dp->arg_index].a.a_int; + SNPRINTF_BUF (arg); + } + break; + case TYPE_UINT: + { + unsigned int arg = a.arg[dp->arg_index].a.a_uint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGINT: + { + long int arg = a.arg[dp->arg_index].a.a_longint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_ULONGINT: + { + unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGLONGINT: + { + long long int arg = a.arg[dp->arg_index].a.a_longlongint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_ULONGLONGINT: + { + unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_DOUBLE: + { + double arg = a.arg[dp->arg_index].a.a_double; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGDOUBLE: + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + SNPRINTF_BUF (arg); + } + break; + case TYPE_CHAR: + { + int arg = a.arg[dp->arg_index].a.a_char; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: + { + wint_t arg = a.arg[dp->arg_index].a.a_wide_char; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_STRING: + { + const char *arg = a.arg[dp->arg_index].a.a_string; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: + { + const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_POINTER: + { + void *arg = a.arg[dp->arg_index].a.a_pointer; + SNPRINTF_BUF (arg); + } + break; + default: + abort (); + } + +#if USE_SNPRINTF + /* Portability: Not all implementations of snprintf() + are ISO C 99 compliant. Determine the number of + bytes that snprintf() has produced or would have + produced. */ + if (count >= 0) + { + /* Verify that snprintf() has NUL-terminated its + result. */ + if ((unsigned int) count < maxlen + && ((TCHAR_T *) (result + length)) [count] != '\0') + abort (); + /* Portability hack. */ + if (retcount > count) + count = retcount; + } + else + { + /* snprintf() doesn't understand the '%n' + directive. */ + if (fbp[1] != '\0') + { + /* Don't use the '%n' directive; instead, look + at the snprintf() return value. */ + fbp[1] = '\0'; + continue; + } + else + { + /* Look at the snprintf() return value. */ + if (retcount < 0) + { +# 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 + that would have been required) when the + buffer is too small. + But a failure at this point can also come + from other reasons than a too small buffer, + such as an invalid wide string argument to + the %ls directive, or possibly an invalid + floating-point argument. */ + size_t tmp_length = + MAX_ROOM_NEEDED (&a, dp->arg_index, + dp->conversion, type, flags, + width, + has_precision, + precision, pad_ourselves); + + if (maxlen < tmp_length) + { + /* Make more room. But try to do through + this reallocation only once. */ + size_t bigger_need = + xsum (length, + xsum (tmp_length, + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR); + /* And always grow proportionally. + (There may be several arguments, each + needing a little more room than the + previous one.) */ + size_t bigger_need2 = + xsum (xtimes (allocated, 2), 12); + if (bigger_need < bigger_need2) + bigger_need = bigger_need2; + ENSURE_ALLOCATION (bigger_need); + continue; + } +# endif + } + else + count = retcount; + } + } +#endif + + /* Attempt to handle failure. */ + if (count < 0) + { + /* 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; + } + + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + + return NULL; + } + +#if USE_SNPRINTF + /* Handle overflow of the allocated buffer. + If such an overflow occurs, a C99 compliant snprintf() + returns a count >= maxlen. However, a non-compliant + snprintf() function returns only count = maxlen - 1. To + cover both cases, test whether count >= maxlen - 1. */ + if ((unsigned int) count + 1 >= maxlen) + { + /* If maxlen already has attained its allowed maximum, + allocating more memory will not increase maxlen. + Instead of looping, bail out. */ + if (maxlen == INT_MAX / TCHARS_PER_DCHAR) + goto overflow; + else + { + /* Need at least (count + 1) * sizeof (TCHAR_T) + bytes. (The +1 is for the trailing NUL.) + But ask for (count + 2) * sizeof (TCHAR_T) + bytes, so that in the next round, we likely get + maxlen > (unsigned int) count + 1 + and so we don't get here again. + And allocate proportionally, to avoid looping + eternally if snprintf() reports a too small + count. */ + size_t n = + xmax (xsum (length, + ((unsigned int) count + 2 + + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR), + xtimes (allocated, 2)); + + ENSURE_ALLOCATION (n); + continue; + } + } +#endif + +#if NEED_PRINTF_UNBOUNDED_PRECISION + if (prec_ourselves) + { + /* Handle the precision. */ + TCHAR_T *prec_ptr = +# if USE_SNPRINTF + (TCHAR_T *) (result + length); +# else + tmp; +# endif + size_t prefix_count; + size_t move; + + prefix_count = 0; + /* Put the additional zeroes after the sign. */ + if (count >= 1 + && (*prec_ptr == '-' || *prec_ptr == '+' + || *prec_ptr == ' ')) + prefix_count = 1; + /* Put the additional zeroes after the 0x prefix if + (flags & FLAG_ALT) || (dp->conversion == 'p'). */ + else if (count >= 2 + && prec_ptr[0] == '0' + && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X')) + prefix_count = 2; + + move = count - prefix_count; + if (precision > move) + { + /* Insert zeroes. */ + size_t insert = precision - move; + TCHAR_T *prec_end; + +# if USE_SNPRINTF + size_t n = + xsum (length, + (count + insert + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR); + length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + ENSURE_ALLOCATION (n); + length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + prec_ptr = (TCHAR_T *) (result + length); +# endif + + prec_end = prec_ptr + count; + prec_ptr += prefix_count; + + while (prec_end > prec_ptr) + { + prec_end--; + prec_end[insert] = prec_end[0]; + } + + prec_end += insert; + do + *--prec_end = '0'; + while (prec_end > prec_ptr); + + count += insert; + } + } +#endif + +#if !USE_SNPRINTF + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); +#endif + +#if !DCHAR_IS_TCHAR + /* Convert from TCHAR_T[] to DCHAR_T[]. */ + if (dp->conversion == 'c' || dp->conversion == 's') + { + /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING + TYPE_WIDE_STRING. + The result string is not certainly ASCII. */ + const TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; + /* This code assumes that TCHAR_T is 'char'. */ + verify (sizeof (TCHAR_T) == 1); +# if USE_SNPRINTF + tmpsrc = (TCHAR_T *) (result + length); +# else + tmpsrc = tmp; +# endif + tmpdst = + DCHAR_CONV_FROM_ENCODING (locale_charset (), + iconveh_question_mark, + tmpsrc, count, + NULL, + NULL, &tmpdst_len); + if (tmpdst == NULL) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + return NULL; + } + 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; + } + else + { + /* The result string is ASCII. + Simple 1:1 conversion. */ +# if USE_SNPRINTF + /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a + no-op conversion, in-place on the array starting + at (result + length). */ + if (sizeof (DCHAR_T) != sizeof (TCHAR_T)) +# endif + { + const TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t n; + +# if USE_SNPRINTF + if (result == resultbuf) + { + tmpsrc = (TCHAR_T *) (result + length); + /* ENSURE_ALLOCATION will not move tmpsrc + (because it's part of resultbuf). */ + ENSURE_ALLOCATION (xsum (length, count)); + } + else + { + /* ENSURE_ALLOCATION will move the array + (because it uses realloc(). */ + ENSURE_ALLOCATION (xsum (length, count)); + tmpsrc = (TCHAR_T *) (result + length); + } +# else + tmpsrc = tmp; + ENSURE_ALLOCATION (xsum (length, count)); +# endif + tmpdst = result + length; + /* Copy backwards, because of overlapping. */ + tmpsrc += count; + tmpdst += count; + for (n = count; n > 0; n--) + *--tmpdst = *--tmpsrc; + } + } +#endif + +#if DCHAR_IS_TCHAR && !USE_SNPRINTF + /* Make room for the result. */ + if (count > allocated - length) + { + /* Need at least count elements. But allocate + proportionally. */ + size_t n = + xmax (xsum (length, count), xtimes (allocated, 2)); + + ENSURE_ALLOCATION (n); + } +#endif + + /* Here count <= allocated - length. */ + + /* Perform padding. */ +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + if (pad_ourselves && has_width) + { + size_t w; +# 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, count); +# else + /* The width is compared against the number of _bytes_ + of the converted value, says POSIX. */ + w = count; +# endif + if (w < width) + { + size_t pad = width - w; + + /* Make room for the result. */ + if (xsum (count, pad) > allocated - length) + { + /* Need at least count + pad elements. But + allocate proportionally. */ + size_t n = + xmax (xsum3 (length, count, pad), + xtimes (allocated, 2)); + +# if USE_SNPRINTF + length += count; + ENSURE_ALLOCATION (n); + length -= count; +# else + ENSURE_ALLOCATION (n); +# endif + } + /* Here count + pad <= allocated - length. */ + + { +# if !DCHAR_IS_TCHAR || USE_SNPRINTF + DCHAR_T * const rp = result + length; +# else + DCHAR_T * const rp = tmp; +# endif + DCHAR_T *p = rp + count; + DCHAR_T *end = p + pad; + DCHAR_T *pad_ptr; +# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO + if (dp->conversion == 'c' + || dp->conversion == 's') + /* No zero-padding for string directives. */ + pad_ptr = NULL; + else +# endif + { + pad_ptr = (*rp == '-' ? rp + 1 : rp); + /* No zero-padding of "inf" and "nan". */ + if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') + || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) + pad_ptr = NULL; + } + /* The generated string now extends from rp to p, + with the zero padding insertion point being at + pad_ptr. */ + + count = count + pad; /* = end - rp */ + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > rp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + } + } + } +#endif + + /* Here still count <= allocated - length. */ + +#if !DCHAR_IS_TCHAR || USE_SNPRINTF + /* The snprintf() result did fit. */ +#else + /* Append the sprintf() result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); +#endif +#if !USE_SNPRINTF + if (tmp != tmpbuf) + free (tmp); +#endif + +#if NEED_PRINTF_DIRECTIVE_F + if (dp->conversion == 'F') + { + /* Convert the %f result to upper case for %F. */ + DCHAR_T *rp = result + length; + size_t rc; + for (rc = count; rc > 0; rc--, rp++) + if (*rp >= 'a' && *rp <= 'z') + *rp = *rp - 'a' + 'A'; + } +#endif + + length += count; + break; + } + errno = orig_errno; +#undef pad_ourselves +#undef prec_ourselves + } + } + } + + /* Add the final NUL. */ + ENSURE_ALLOCATION (xsum (length, 1)); + result[length] = '\0'; + + if (result != resultbuf && length + 1 < allocated) + { + /* Shrink the allocated memory if possible. */ + DCHAR_T *memory; + + memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T)); + if (memory != NULL) + result = memory; + } + + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + *lengthp = length; + /* Note that we can produce a big string of a length > INT_MAX. POSIX + says that snprintf() fails with errno = EOVERFLOW in this case, but + that's only because snprintf() returns an 'int'. This function does + not have this limitation. */ + return result; + +#if USE_SNPRINTF + overflow: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EOVERFLOW; + return NULL; +#endif + + out_of_memory: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + out_of_memory_1: + CLEANUP (); + errno = ENOMEM; + return NULL; + } +} + +#undef MAX_ROOM_NEEDED +#undef TCHARS_PER_DCHAR +#undef SNPRINTF +#undef USE_SNPRINTF +#undef DCHAR_SET +#undef DCHAR_CPY +#undef PRINTF_PARSE +#undef DIRECTIVES +#undef DIRECTIVE +#undef DCHAR_IS_TCHAR +#undef TCHAR_T +#undef DCHAR_T +#undef FCHAR_T +#undef VASNPRINTF diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h new file mode 100644 index 0000000..27cf54c --- /dev/null +++ b/lib/vasnprintf.h @@ -0,0 +1,72 @@ +/* vsprintf with automatic memory allocation. + Copyright (C) 2002-2004, 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 . */ + +#ifndef _VASNPRINTF_H +#define _VASNPRINTF_H + +/* Get va_list. */ +#include + +/* Get size_t. */ +#include + +/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD. */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Write formatted output to a string dynamically allocated with malloc(). + You can pass a preallocated buffer for the result in RESULTBUF and its + size in *LENGTHP; otherwise you pass RESULTBUF = NULL. + If successful, return the address of the string (this may be = RESULTBUF + if no dynamic memory allocation was necessary) and set *LENGTHP to the + number of resulting bytes, excluding the trailing NUL. Upon error, set + errno and return NULL. + + When dynamic memory allocation occurs, the preallocated buffer is left + alone (with possibly modified contents). This makes it possible to use + a statically allocated or stack-allocated buffer, like this: + + char buf[100]; + size_t len = sizeof (buf); + char *output = vasnprintf (buf, &len, format, args); + if (output == NULL) + ... error handling ...; + else + { + ... use the output string ...; + if (output != buf) + free (output); + } + */ +#if REPLACE_VASNPRINTF +# define asnprintf rpl_asnprintf +# define vasnprintf rpl_vasnprintf +#endif +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 +} +#endif + +#endif /* _VASNPRINTF_H */ diff --git a/lib/vasprintf.c b/lib/vasprintf.c new file mode 100644 index 0000000..218275f --- /dev/null +++ b/lib/vasprintf.c @@ -0,0 +1,50 @@ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 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 . */ + +#include + +/* Specification. */ +#ifdef IN_LIBASPRINTF +# include "vasprintf.h" +#else +# include +#endif + +#include +#include +#include + +#include "vasnprintf.h" + +int +vasprintf (char **resultp, const char *format, va_list args) +{ + size_t length; + char *result = vasnprintf (NULL, &length, format, args); + if (result == NULL) + return -1; + + if (length > INT_MAX) + { + free (result); + errno = EOVERFLOW; + return -1; + } + + *resultp = result; + /* Return the number of resulting bytes, excluding the trailing NUL. */ + return length; +} diff --git a/lib/verify.h b/lib/verify.h new file mode 100644 index 0000000..07b2f48 --- /dev/null +++ b/lib/verify.h @@ -0,0 +1,315 @@ +/* Compile-time assert-like macros. + + Copyright (C) 2005-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, Bruno Haible, and Jim Meyering. */ + +#ifndef _GL_VERIFY_H +#define _GL_VERIFY_H + + +/* 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_ASSERT1 to 1 if _Static_assert (R) works as + per C2x. This is supported by GCC 9.1+. + + Support compilers claiming conformance to the relevant standard, + and also support GCC when not pedantic. If we were willing to slow + '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__) || 4 <= __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 +# include +# undef _Static_assert +#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. + + If _Static_assert works, verify (R) uses it directly. Similarly, + _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct + that is an operand of sizeof. + + The code below uses several ideas for C++ compilers, and for C + compilers that do not support _Static_assert: + + * The first step is ((R) ? 1 : -1). Given an expression R, of + integral or boolean or floating-point type, this yields an + expression of integral type, whose value is later verified to be + constant and nonnegative. + + * Next this expression W is wrapped in a type + struct _gl_verify_type { + unsigned int _gl_verify_error_if_negative: W; + }. + If W is negative, this yields a compile-time error. No compiler can + deal with a bit-field of negative size. + + One might think that an array size check would have the same + effect, that is, that the type struct { unsigned int dummy[W]; } + would work as well. However, inside a function, some compilers + (such as C++ compilers and GNU C) allow local parameters and + variables inside array size expressions. With these compilers, + an array size check would not properly diagnose this misuse of + the verify macro: + + void function (int n) { verify (n < 0); } + + * For the verify macro, the struct _gl_verify_type will need to + somehow be embedded into a declaration. To be portable, this + declaration must declare an object, a constant, a function, or a + typedef name. If the declared entity uses the type directly, + such as in + + struct dummy {...}; + typedef struct {...} dummy; + extern struct {...} *dummy; + extern void dummy (struct {...} *); + extern struct {...} *dummy (void); + + two uses of the verify macro would yield colliding declarations + if the entity names are not disambiguated. A workaround is to + attach the current line number to the entity name: + + #define _GL_CONCAT0(x, y) x##y + #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) + extern struct {...} * _GL_CONCAT (dummy, __LINE__); + + But this has the problem that two invocations of verify from + within the same macro would collide, since the __LINE__ value + would be the same for both invocations. (The GCC __COUNTER__ + macro solves this problem, but is not portable.) + + A solution is to use the sizeof operator. It yields a number, + getting rid of the identity of the type. Declarations like + + extern int dummy [sizeof (struct {...})]; + extern void dummy (int [sizeof (struct {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; + + can be repeated. + + * Should the implementation use a named struct or an unnamed struct? + Which of the following alternatives can be used? + + extern int dummy [sizeof (struct {...})]; + extern int dummy [sizeof (struct _gl_verify_type {...})]; + extern void dummy (int [sizeof (struct {...})]); + extern void dummy (int [sizeof (struct _gl_verify_type {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; + extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; + + In the second and sixth case, the struct type is exported to the + outer scope; two such declarations therefore collide. GCC warns + about the first, third, and fourth cases. So the only remaining + possibility is the fifth case: + + extern int (*dummy (void)) [sizeof (struct {...})]; + + * GCC warns about duplicate declarations of the dummy function if + -Wredundant-decls is used. GCC 4.3 and later have a builtin + __COUNTER__ macro that can let us generate unique identifiers for + each dummy function, to suppress this warning. + + * This implementation exploits the fact that older versions of GCC, + 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 + within a function body; but inside a function, you can always + arrange to use verify_expr instead. + + * In C++, any struct definition inside sizeof is invalid. + Use a template type to work around the problem. */ + +/* Concatenate two preprocessor tokens. */ +#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) +#define _GL_CONCAT0(x, y) x##y + +/* _GL_COUNTER is an integer, preferably one that changes each time we + use it. Use __COUNTER__ if it works, falling back on __LINE__ + otherwise. __LINE__ isn't perfect, but it's better than a + constant. */ +#if defined __COUNTER__ && __COUNTER__ != __COUNTER__ +# define _GL_COUNTER __COUNTER__ +#else +# define _GL_COUNTER __LINE__ +#endif + +/* Generate a symbol with the given prefix, making it unique if + possible. */ +#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) + +/* Verify requirement R at compile-time, as an integer constant expression + that returns 1. If R is false, fail at compile-time, preferably + with a diagnostic that includes the string-literal DIAGNOSTIC. */ + +#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ + (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) + +#ifdef __cplusplus +# if !GNULIB_defined_struct__gl_verify_type +template + struct _gl_verify_type { + unsigned int _gl_verify_error_if_negative: w; + }; +# define GNULIB_defined_struct__gl_verify_type 1 +# endif +# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ + _gl_verify_type<(R) ? 1 : -1> +#elif defined _GL_HAVE__STATIC_ASSERT +# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ + struct { \ + _Static_assert (R, DIAGNOSTIC); \ + int _gl_dummy; \ + } +#else +# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ + struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } +#endif + +/* Verify requirement R at compile-time, as a declaration without a + 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 { ... }. */ + +#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, ...) \ + extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ + [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] +#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_ASSERT1 && !defined _Static_assert +# define _Static_assert(...) \ + _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) +# endif +# 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_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. Return the value of the + expression E. */ + +#define verify_expr(R, E) \ + (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) + +/* Verify requirement R at compile-time, as a declaration without a + 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 + +/* 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 (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 + when 'assume' silences warnings even with older GCCs. */ +# define assume(R) ((R) ? (void) 0 : __builtin_trap ()) +#else + /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6. */ +# define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) +#endif + +/* @assert.h omit end@ */ + +#endif diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c new file mode 100644 index 0000000..80999e9 --- /dev/null +++ b/lib/vsnprintf.c @@ -0,0 +1,70 @@ +/* Formatted output to strings. + Copyright (C) 2004, 2006-2022 Free Software Foundation, Inc. + Written by Simon Josefsson and Yoann Vandoorselaere . + + 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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include + +#include +#include +#include +#include +#include + +#include "vasnprintf.h" + +/* Print formatted output to string STR. Similar to vsprintf, but + additional length SIZE limit how much is written into STR. Returns + string length of formatted string (which may be larger than SIZE). + STR may be NULL, in which case nothing will be written. On error, + return a negative value. */ +int +vsnprintf (char *str, size_t size, const char *format, va_list args) +{ + char *output; + size_t len; + size_t lenbuf = size; + + output = vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + + if (!output) + return -1; + + if (output != str) + { + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); + } + + if (len > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } + + return len; +} diff --git a/lib/w32sock.h b/lib/w32sock.h new file mode 100644 index 0000000..17db3f1 --- /dev/null +++ b/lib/w32sock.h @@ -0,0 +1,140 @@ +/* w32sock.h --- internal auxiliary functions for Windows socket functions + + 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 . */ + +/* Written by Paolo Bonzini */ + +#include + +/* Get O_RDWR and O_BINARY. */ +#include + +/* Get _open_osfhandle(). */ +#include + +/* Get _get_osfhandle(). */ +#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)) + +static inline void +set_winsock_errno (void) +{ + int err = WSAGetLastError (); + + /* Map some WSAE* errors to the runtime library's error codes. */ + switch (err) + { + case WSA_INVALID_HANDLE: + errno = EBADF; + break; + case WSA_NOT_ENOUGH_MEMORY: + errno = ENOMEM; + break; + case WSA_INVALID_PARAMETER: + errno = EINVAL; + break; + case WSAENAMETOOLONG: + errno = ENAMETOOLONG; + break; + case WSAENOTEMPTY: + errno = ENOTEMPTY; + break; + case WSAEWOULDBLOCK: + errno = EWOULDBLOCK; + break; + case WSAEINPROGRESS: + errno = EINPROGRESS; + break; + case WSAEALREADY: + errno = EALREADY; + break; + case WSAENOTSOCK: + errno = ENOTSOCK; + break; + case WSAEDESTADDRREQ: + errno = EDESTADDRREQ; + break; + case WSAEMSGSIZE: + errno = EMSGSIZE; + break; + case WSAEPROTOTYPE: + errno = EPROTOTYPE; + break; + case WSAENOPROTOOPT: + errno = ENOPROTOOPT; + break; + case WSAEPROTONOSUPPORT: + errno = EPROTONOSUPPORT; + break; + case WSAEOPNOTSUPP: + errno = EOPNOTSUPP; + break; + case WSAEAFNOSUPPORT: + errno = EAFNOSUPPORT; + break; + case WSAEADDRINUSE: + errno = EADDRINUSE; + break; + case WSAEADDRNOTAVAIL: + errno = EADDRNOTAVAIL; + break; + case WSAENETDOWN: + errno = ENETDOWN; + break; + case WSAENETUNREACH: + errno = ENETUNREACH; + break; + case WSAENETRESET: + errno = ENETRESET; + break; + case WSAECONNABORTED: + errno = ECONNABORTED; + break; + case WSAECONNRESET: + errno = ECONNRESET; + break; + case WSAENOBUFS: + errno = ENOBUFS; + break; + case WSAEISCONN: + errno = EISCONN; + break; + case WSAENOTCONN: + errno = ENOTCONN; + break; + case WSAETIMEDOUT: + errno = ETIMEDOUT; + break; + case WSAECONNREFUSED: + errno = ECONNREFUSED; + break; + case WSAELOOP: + errno = ELOOP; + break; + case WSAEHOSTUNREACH: + errno = EHOSTUNREACH; + break; + default: + errno = (err > 10000 && err < 10025) ? err - 10000 : err; + break; + } +} diff --git a/lib/wait-process.c b/lib/wait-process.c new file mode 100644 index 0000000..b12bd3c --- /dev/null +++ b/lib/wait-process.c @@ -0,0 +1,370 @@ +/* Waiting for a subprocess to finish. + Copyright (C) 2001-2003, 2005-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 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 "wait-process.h" + +#include +#include +#include +#include + +#include +#include + +#include "error.h" +#include "fatal-signal.h" +#include "xalloc.h" +#include "gettext.h" + +#define _(str) gettext (str) + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + + +#if defined _WIN32 && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN +# include + +/* The return value of _spawnvp() is really a process handle as returned + by CreateProcess(). Therefore we can kill it using TerminateProcess. */ +# define kill(pid,sig) TerminateProcess ((HANDLE) (pid), sig) + +#endif + + +/* Type of an entry in the slaves array. + The 'used' bit determines whether this entry is currently in use. + (If pid_t was an atomic type like sig_atomic_t, we could just set the + 'child' field to 0 when unregistering a slave process, and wouldn't need + the 'used' field.) + The 'used' and 'child' fields are accessed from within the cleanup_slaves() + action, therefore we mark them as 'volatile'. */ +typedef struct +{ + volatile sig_atomic_t used; + volatile pid_t child; +} +slaves_entry_t; + +/* The registered slave subprocesses. */ +static slaves_entry_t static_slaves[32]; +static slaves_entry_t * volatile slaves = static_slaves; +static sig_atomic_t volatile slaves_count = 0; +static size_t slaves_allocated = SIZEOF (static_slaves); + +/* The termination signal for slave subprocesses. + 2003-10-07: Terminator becomes Governator. */ +#ifdef SIGHUP +# define TERMINATOR SIGHUP +#else +# define TERMINATOR SIGTERM +#endif + +/* The cleanup action. It gets called asynchronously. */ +static _GL_ASYNC_SAFE void +cleanup_slaves (void) +{ + for (;;) + { + /* Get the last registered slave. */ + size_t n = slaves_count; + if (n == 0) + break; + n--; + slaves_count = n; + /* Skip unused entries in the slaves array. */ + if (slaves[n].used) + { + pid_t slave = slaves[n].child; + + /* Kill the slave. */ + kill (slave, TERMINATOR); + } + } +} + +/* The cleanup action, taking a signal argument. + It gets called asynchronously. */ +static _GL_ASYNC_SAFE void +cleanup_slaves_action (_GL_UNUSED int sig) +{ + cleanup_slaves (); +} + +/* Register a subprocess as being a slave process. This means that the + subprocess will be terminated when its creator receives a catchable fatal + signal or exits normally. Registration ends when wait_subprocess() + notices that the subprocess has exited. */ +void +register_slave_subprocess (pid_t child) +{ + static bool cleanup_slaves_registered = false; + if (!cleanup_slaves_registered) + { + atexit (cleanup_slaves); + if (at_fatal_signal (cleanup_slaves_action) < 0) + xalloc_die (); + cleanup_slaves_registered = true; + } + + /* Try to store the new slave in an unused entry of the slaves array. */ + { + slaves_entry_t *s = slaves; + slaves_entry_t *s_end = s + slaves_count; + + for (; s < s_end; s++) + if (!s->used) + { + /* The two uses of 'volatile' in the slaves_entry_t type above + (and ISO C 99 section 5.1.2.3.(5)) ensure that we mark the + entry as used only after the child pid has been written to the + memory location s->child. */ + s->child = child; + s->used = 1; + return; + } + } + + if (slaves_count == slaves_allocated) + { + /* Extend the slaves array. Note that we cannot use xrealloc(), + because then the cleanup_slaves() function could access an already + deallocated array. */ + slaves_entry_t *old_slaves = slaves; + size_t new_slaves_allocated = 2 * slaves_allocated; + slaves_entry_t *new_slaves = + (slaves_entry_t *) + malloc (new_slaves_allocated * sizeof (slaves_entry_t)); + if (new_slaves == NULL) + { + /* xalloc_die() will call exit() which will invoke cleanup_slaves(). + Additionally we need to kill child, because it's not yet among + the slaves list. */ + kill (child, TERMINATOR); + xalloc_die (); + } + memcpy (new_slaves, old_slaves, + slaves_allocated * sizeof (slaves_entry_t)); + slaves = new_slaves; + slaves_allocated = new_slaves_allocated; + /* Now we can free the old slaves array. */ + if (old_slaves != static_slaves) + free (old_slaves); + } + /* The three uses of 'volatile' in the types above (and ISO C 99 section + 5.1.2.3.(5)) ensure that we increment the slaves_count only after the + new slave and its 'used' bit have been written to the memory locations + that make up slaves[slaves_count]. */ + slaves[slaves_count].child = child; + slaves[slaves_count].used = 1; + slaves_count++; +} + +/* Unregister a child from the list of slave subprocesses. */ +static void +unregister_slave_subprocess (pid_t child) +{ + /* The easiest way to remove an entry from a list that can be used by + an asynchronous signal handler is just to mark it as unused. For this, + we rely on sig_atomic_t. */ + slaves_entry_t *s = slaves; + slaves_entry_t *s_end = s + slaves_count; + + for (; s < s_end; s++) + if (s->used && s->child == child) + s->used = 0; +} + + +/* Wait for a subprocess to finish. Return its exit code. + If it didn't terminate correctly, exit if exit_on_error is true, otherwise + return 127. */ +int +wait_subprocess (pid_t child, const char *progname, + bool ignore_sigpipe, bool null_stderr, + bool slave_process, bool exit_on_error, + int *termsigp) +{ +#if HAVE_WAITID && defined WNOWAIT && 0 + /* Commented out because waitid() without WEXITED and with WNOWAIT doesn't + work: On Solaris 7 and OSF/1 4.0, it returns -1 and sets errno = ECHILD, + and on HP-UX 10.20 it just hangs. */ + /* Use of waitid() with WNOWAIT avoids a race condition: If slave_process is + true, and this process sleeps a very long time between the return from + waitpid() and the execution of unregister_slave_subprocess(), and + meanwhile another process acquires the same PID as child, and then - still + before unregister_slave_subprocess() - this process gets a fatal signal, + it would kill the other totally unrelated process. */ + siginfo_t info; + + if (termsigp != NULL) + *termsigp = 0; + for (;;) + { + if (waitid (P_PID, child, &info, WEXITED | (slave_process ? WNOWAIT : 0)) + < 0) + { +# ifdef EINTR + if (errno == EINTR) + continue; +# endif + if (exit_on_error || !null_stderr) + error (exit_on_error ? EXIT_FAILURE : 0, errno, + _("%s subprocess"), progname); + return 127; + } + + /* info.si_code is set to one of CLD_EXITED, CLD_KILLED, CLD_DUMPED, + CLD_TRAPPED, CLD_STOPPED, CLD_CONTINUED. Loop until the program + terminates. */ + if (info.si_code == CLD_EXITED + || info.si_code == CLD_KILLED || info.si_code == CLD_DUMPED) + break; + } + + /* The child process has exited or was signalled. */ + + if (slave_process) + { + /* Unregister the child from the list of slave subprocesses, so that + later, when we exit, we don't kill a totally unrelated process which + may have acquired the same pid. */ + unregister_slave_subprocess (child); + + /* Now remove the zombie from the process list. */ + for (;;) + { + if (waitid (P_PID, child, &info, WEXITED) < 0) + { +# ifdef EINTR + if (errno == EINTR) + continue; +# endif + if (exit_on_error || !null_stderr) + error (exit_on_error ? EXIT_FAILURE : 0, errno, + _("%s subprocess"), progname); + return 127; + } + break; + } + } + + switch (info.si_code) + { + case CLD_KILLED: + case CLD_DUMPED: + if (termsigp != NULL) + *termsigp = info.si_status; /* TODO: or info.si_signo? */ +# ifdef SIGPIPE + if (info.si_status == SIGPIPE && ignore_sigpipe) + return 0; +# endif + if (exit_on_error || (!null_stderr && termsigp == NULL)) + error (exit_on_error ? EXIT_FAILURE : 0, 0, + _("%s subprocess got fatal signal %d"), + progname, info.si_status); + return 127; + case CLD_EXITED: + if (info.si_status == 127) + { + if (exit_on_error || !null_stderr) + error (exit_on_error ? EXIT_FAILURE : 0, 0, + _("%s subprocess failed"), progname); + return 127; + } + return info.si_status; + default: + abort (); + } +#else + /* waitpid() is just as portable as wait() nowadays. */ + int status; + + if (termsigp != NULL) + *termsigp = 0; + status = 0; + for (;;) + { + int result = waitpid (child, &status, 0); + + if (result != child) + { +# ifdef EINTR + if (errno == EINTR) + continue; +# endif +# if 0 /* defined ECHILD */ + if (errno == ECHILD) + { + /* Child process nonexistent?! Assume it terminated + successfully. */ + status = 0; + break; + } +# endif + if (exit_on_error || !null_stderr) + error (exit_on_error ? EXIT_FAILURE : 0, errno, + _("%s subprocess"), progname); + return 127; + } + + /* One of WIFSIGNALED (status), WIFEXITED (status), WIFSTOPPED (status) + must always be true, since we did not specify WCONTINUED in the + waitpid() call. Loop until the program terminates. */ + if (!WIFSTOPPED (status)) + break; + } + + /* The child process has exited or was signalled. */ + + if (slave_process) + /* Unregister the child from the list of slave subprocesses, so that + later, when we exit, we don't kill a totally unrelated process which + may have acquired the same pid. */ + unregister_slave_subprocess (child); + + if (WIFSIGNALED (status)) + { + if (termsigp != NULL) + *termsigp = WTERMSIG (status); +# ifdef SIGPIPE + if (WTERMSIG (status) == SIGPIPE && ignore_sigpipe) + return 0; +# endif + if (exit_on_error || (!null_stderr && termsigp == NULL)) + error (exit_on_error ? EXIT_FAILURE : 0, 0, + _("%s subprocess got fatal signal %d"), + progname, (int) WTERMSIG (status)); + return 127; + } + if (!WIFEXITED (status)) + abort (); + if (WEXITSTATUS (status) == 127) + { + if (exit_on_error || !null_stderr) + error (exit_on_error ? EXIT_FAILURE : 0, 0, + _("%s subprocess failed"), progname); + return 127; + } + return WEXITSTATUS (status); +#endif +} diff --git a/lib/wait-process.h b/lib/wait-process.h new file mode 100644 index 0000000..61bdf13 --- /dev/null +++ b/lib/wait-process.h @@ -0,0 +1,74 @@ +/* Waiting for a subprocess to finish. + Copyright (C) 2001-2003, 2006, 2008-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 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 _WAIT_PROCESS_H +#define _WAIT_PROCESS_H + +/* Get pid_t. */ +#include +#include +#include + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Wait for a subprocess to finish. Return its exit code. + If it didn't terminate correctly, exit if exit_on_error is true, otherwise + return 127. + Arguments: + - child is the pid of the subprocess. + - progname is the name of the program executed by the subprocess, used for + error messages. + - If ignore_sigpipe is true, consider a subprocess termination due to + SIGPIPE as equivalent to a success. This is suitable for processes whose + only purpose is to write to standard output. This flag can be safely set + to false when the process' standard output is known to go to DEV_NULL. + - If null_stderr is true, the usual error message to stderr will be omitted. + This is suitable when the subprocess does not fulfill an important task. + - slave_process should be set to true if the process has been launched as a + slave process. + - If exit_on_error is true, any error will cause the main process to exit + with an error status. + - If termsigp is not NULL: *termsig will be set to the signal that + terminated the subprocess (if supported by the platform: not on native + Windows platforms), otherwise 0, and the error message about the signal + that terminated the subprocess will be omitted. + Prerequisites: The signal handler for SIGCHLD should not be set to SIG_IGN, + otherwise this function will not work. */ +extern int wait_subprocess (pid_t child, const char *progname, + bool ignore_sigpipe, bool null_stderr, + bool slave_process, bool exit_on_error, + int *termsigp); + +/* Register a subprocess as being a slave process. This means that the + subprocess will be terminated when its creator receives a catchable fatal + signal or exits normally. Registration ends when wait_subprocess() + notices that the subprocess has exited. */ +extern void register_slave_subprocess (pid_t child); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _WAIT_PROCESS_H */ diff --git a/lib/waitpid.c b/lib/waitpid.c new file mode 100644 index 0000000..66c199f --- /dev/null +++ b/lib/waitpid.c @@ -0,0 +1,30 @@ +/* Wait for process state change. + Copyright (C) 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 . */ + +#include + +/* Specification. */ +#include + +/* Implementation for native Windows systems. */ + +#include /* for _cwait, WAIT_CHILD */ + +pid_t +waitpid (pid_t pid, int *statusp, int options) +{ + return _cwait (statusp, pid, WAIT_CHILD); +} diff --git a/lib/warn-on-use.h b/lib/warn-on-use.h new file mode 100644 index 0000000..94f5b92 --- /dev/null +++ b/lib/warn-on-use.h @@ -0,0 +1,149 @@ +/* A C macro for emitting warnings if a function is used. + 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 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 . */ + +/* _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. + + _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the + attribute used in _GL_WARN_ON_USE. If the compiler does not support + this feature, it expands to empty. + + These macros are 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. + _GL_WARN_ON_USE is for functions with 'extern' linkage. + _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline' + linkage. + + 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 + or better (avoiding contradictory use of 'static' and 'extern'): + #if HAVE_RAW_DECL_ENVIRON + static char *** + _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared") + rpl_environ (void) { return &environ; } + # 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) \ +_GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) +# define _GL_WARN_ON_USE_ATTRIBUTE(message) \ + __attribute__ ((__warning__ (message))) +# elif __clang_major__ >= 4 +/* Another compiler attribute is available in clang. */ +# define _GL_WARN_ON_USE(function, message) \ +_GL_WARN_EXTERN_C __typeof__ (function) function \ + __attribute__ ((__diagnose_if__ (1, message, "warning"))) +# define _GL_WARN_ON_USE_ATTRIBUTE(message) \ + __attribute__ ((__diagnose_if__ (1, message, "warning"))) +# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +/* Verify the existence of the function. */ +# define _GL_WARN_ON_USE(function, message) \ +_GL_WARN_EXTERN_C __typeof__ (function) function +# define _GL_WARN_ON_USE_ATTRIBUTE(message) +# else /* Unsupported. */ +# define _GL_WARN_ON_USE(function, message) \ +_GL_WARN_EXTERN_C int _gl_warn_on_use +# define _GL_WARN_ON_USE_ATTRIBUTE(message) +# endif +#endif + +/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message") + is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode 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 !defined __cplusplus +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ + _GL_WARN_ON_USE (function, msg) +# else +# 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_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_gcc function parameters_and_attributes \ + __attribute__ ((__warning__ (msg))) +# elif __clang_major__ >= 4 +/* Another compiler attribute is available in clang. */ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_clang function parameters_and_attributes \ + __attribute__ ((__diagnose_if__ (1, msg, "warning"))) +# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +/* Verify the existence of the function. */ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_gcc function parameters_and_attributes +# else /* Unsupported. */ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +_GL_WARN_EXTERN_C int _gl_warn_on_use +# endif +# 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/lib/wchar.in.h b/lib/wchar.in.h new file mode 100644 index 0000000..d7792e5 --- /dev/null +++ b/lib/wchar.in.h @@ -0,0 +1,1322 @@ +/* A substitute for ISO C99 , for platforms that have issues. + + 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. */ + +/* + * ISO C 99 for platforms that have issues. + * + * + * For now, this just ensures proper prerequisite inclusion order and + * the declaration of wcwidth(). + */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +#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, 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. */ + +#@INCLUDE_NEXT@ @NEXT_WCHAR_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_WCHAR_H + +#define _GL_ALREADY_INCLUDING_WCHAR_H + +#if @HAVE_FEATURES_H@ +# include /* for __GLIBC__ */ +#endif + +/* 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 + +/* Include the original if it exists. + Some builds of uClibc lack it. */ +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_WCHAR_H@ +# @INCLUDE_NEXT@ @NEXT_WCHAR_H@ +#endif + +#undef _GL_ALREADY_INCLUDING_WCHAR_H + +#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. */ +#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. */ + + +/* Define wint_t and WEOF. (Also done in wctype.in.h.) */ +#if !@HAVE_WINT_T@ && !defined wint_t +# define wint_t int +# ifndef WEOF +# define WEOF -1 +# endif +#else +/* 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 +# if @HAVE_CRTDEFS_H@ +# include +# else +# include +# endif +typedef unsigned int rpl_wint_t; +# undef wint_t +# define wint_t rpl_wint_t +# define GNULIB_defined_wint_t 1 +# endif +# endif +# ifndef WEOF +# define WEOF ((wint_t) -1) +# endif +#endif + + +/* 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. + 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 +# 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 +_GL_EXTERN_C void __cdecl free (void *); +# else +_GL_EXTERN_C void free (void *); +# endif +# endif +#else +# if defined _MSC_VER +_GL_EXTERN_C void __cdecl free (void *); +# else +_GL_EXTERN_C void free (void *); +# endif +#endif + +/* Convert a single-byte character to a wide character. */ +#if @GNULIB_BTOWC@ +# if @REPLACE_BTOWC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef btowc +# define btowc rpl_btowc +# endif +_GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); +_GL_CXXALIAS_RPL (btowc, wint_t, (int c)); +# else +# if !@HAVE_BTOWC@ +_GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); +# endif +/* 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 +_GL_WARN_ON_USE (btowc, "btowc is unportable - " + "use gnulib module btowc for portability"); +# endif +#endif + + +/* Convert a wide character to a single-byte character. */ +#if @GNULIB_WCTOB@ +# if @REPLACE_WCTOB@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wctob +# define wctob rpl_wctob +# endif +_GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); +_GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); +# else +# if !defined wctob && !@HAVE_DECL_WCTOB@ +/* wctob is provided by gnulib, or wctob exists but is not declared. */ +_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 +_GL_WARN_ON_USE (wctob, "wctob is unportable - " + "use gnulib module wctob for portability"); +# endif +#endif + + +/* Test whether *PS is in the initial state. */ +#if @GNULIB_MBSINIT@ +# if @REPLACE_MBSINIT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbsinit +# define mbsinit rpl_mbsinit +# endif +_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps)); +_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps)); +# else +# if !@HAVE_MBSINIT@ +_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 +_GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - " + "use gnulib module mbsinit for portability"); +# endif +#endif + + +/* Convert a multibyte character to a wide character. */ +#if @GNULIB_MBRTOWC@ +# if @REPLACE_MBRTOWC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbrtowc +# define mbrtowc rpl_mbrtowc +# endif +_GL_FUNCDECL_RPL (mbrtowc, size_t, + (wchar_t *restrict pwc, const char *restrict s, size_t n, + mbstate_t *restrict ps)); +_GL_CXXALIAS_RPL (mbrtowc, size_t, + (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 *restrict pwc, const char *restrict s, size_t n, + mbstate_t *restrict ps)); +# endif +_GL_CXXALIAS_SYS (mbrtowc, size_t, + (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 +_GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - " + "use gnulib module mbrtowc for portability"); +# endif +#endif + + +/* Recognize a multibyte character. */ +#if @GNULIB_MBRLEN@ +# if @REPLACE_MBRLEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbrlen +# define mbrlen rpl_mbrlen +# endif +_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 *restrict s, size_t n, mbstate_t *restrict ps)); +# endif +_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 +_GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - " + "use gnulib module mbrlen for portability"); +# endif +#endif + + +/* Convert a string to a wide string. */ +#if @GNULIB_MBSRTOWCS@ +# if @REPLACE_MBSRTOWCS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbsrtowcs +# define mbsrtowcs rpl_mbsrtowcs +# endif +_GL_FUNCDECL_RPL (mbsrtowcs, size_t, + (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 *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 *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 *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 +_GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - " + "use gnulib module mbsrtowcs for portability"); +# endif +#endif + + +/* Convert a string to a wide string. */ +#if @GNULIB_MBSNRTOWCS@ +# if @REPLACE_MBSNRTOWCS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbsnrtowcs +# define mbsnrtowcs rpl_mbsnrtowcs +# endif +_GL_FUNCDECL_RPL (mbsnrtowcs, size_t, + (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 *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 *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 *restrict dest, + const char **restrict srcp, size_t srclen, size_t len, + mbstate_t *restrict ps)); +# endif +_GL_CXXALIASWARN (mbsnrtowcs); +#elif defined GNULIB_POSIXCHECK +# undef mbsnrtowcs +# if HAVE_RAW_DECL_MBSNRTOWCS +_GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - " + "use gnulib module mbsnrtowcs for portability"); +# endif +#endif + + +/* Convert a wide character to a multibyte character. */ +#if @GNULIB_WCRTOMB@ +# if @REPLACE_WCRTOMB@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcrtomb +# define wcrtomb rpl_wcrtomb +# endif +_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 *restrict s, wchar_t wc, mbstate_t *restrict ps)); +# endif +_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 +_GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - " + "use gnulib module wcrtomb for portability"); +# endif +#endif + + +/* Convert a wide string to a string. */ +#if @GNULIB_WCSRTOMBS@ +# if @REPLACE_WCSRTOMBS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsrtombs +# define wcsrtombs rpl_wcsrtombs +# endif +_GL_FUNCDECL_RPL (wcsrtombs, size_t, + (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 *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 *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 *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 +_GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - " + "use gnulib module wcsrtombs for portability"); +# endif +#endif + + +/* Convert a wide string to a string. */ +#if @GNULIB_WCSNRTOMBS@ +# if @REPLACE_WCSNRTOMBS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsnrtombs +# define wcsnrtombs rpl_wcsnrtombs +# endif +_GL_FUNCDECL_RPL (wcsnrtombs, size_t, + (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 *restrict dest, + const wchar_t **restrict srcp, size_t srclen, + size_t len, + mbstate_t *restrict ps)); +# else +# if !@HAVE_WCSNRTOMBS@ || (defined __cplusplus && defined __sun) +_GL_FUNCDECL_SYS (wcsnrtombs, size_t, + (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 *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 +_GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - " + "use gnulib module wcsnrtombs for portability"); +# endif +#endif + + +/* Return the number of screen columns needed for WC. */ +#if @GNULIB_WCWIDTH@ +# if @REPLACE_WCWIDTH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcwidth +# define wcwidth rpl_wcwidth +# endif +_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); +_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); +# else +# if !@HAVE_DECL_WCWIDTH@ +/* wcwidth exists but is not declared. */ +_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 +_GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " + "use gnulib module wcwidth for portability"); +# endif +#endif + + +/* Search N wide characters of S for C. */ +#if @GNULIB_WMEMCHR@ +# if !@HAVE_WMEMCHR@ +_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n) + _GL_ATTRIBUTE_PURE); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { + const wchar_t * std::wmemchr (const wchar_t *, wchar_t, size_t); + wchar_t * std::wmemchr (wchar_t *, wchar_t, size_t); + } */ +_GL_CXXALIAS_SYS_CAST2 (wmemchr, + wchar_t *, (const wchar_t *, wchar_t, size_t), + const wchar_t *, (const wchar_t *, wchar_t, size_t)); +# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_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)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (wmemchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wmemchr +# if HAVE_RAW_DECL_WMEMCHR +_GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - " + "use gnulib module wmemchr for portability"); +# endif +#endif + + +/* Compare N wide characters of S1 and S2. */ +#if @GNULIB_WMEMCMP@ +# if !@HAVE_WMEMCMP@ +_GL_FUNCDECL_SYS (wmemcmp, int, + (const wchar_t *s1, const wchar_t *s2, size_t n) + _GL_ATTRIBUTE_PURE); +# 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 +_GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " + "use gnulib module wmemcmp for portability"); +# endif +#endif + + +/* Copy N wide characters of SRC to DEST. */ +#if @GNULIB_WMEMCPY@ +# if !@HAVE_WMEMCPY@ +_GL_FUNCDECL_SYS (wmemcpy, wchar_t *, + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wmemcpy, wchar_t *, + (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 +_GL_WARN_ON_USE (wmemcpy, "wmemcpy is unportable - " + "use gnulib module wmemcpy for portability"); +# endif +#endif + + +/* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for + overlapping memory areas. */ +#if @GNULIB_WMEMMOVE@ +# if !@HAVE_WMEMMOVE@ +_GL_FUNCDECL_SYS (wmemmove, wchar_t *, + (wchar_t *dest, const wchar_t *src, size_t n)); +# 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 +_GL_WARN_ON_USE (wmemmove, "wmemmove is unportable - " + "use gnulib module wmemmove for portability"); +# endif +#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 +_GL_WARN_ON_USE (wmemset, "wmemset is unportable - " + "use gnulib module wmemset for portability"); +# endif +#endif + + +/* Return the number of wide characters in S. */ +#if @GNULIB_WCSLEN@ +# if !@HAVE_WCSLEN@ +_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 +_GL_WARN_ON_USE (wcslen, "wcslen is unportable - " + "use gnulib module wcslen for portability"); +# endif +#endif + + +/* Return the number of wide characters in S, but at most MAXLEN. */ +#if @GNULIB_WCSNLEN@ +# if !@HAVE_WCSNLEN@ +_GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen) + _GL_ATTRIBUTE_PURE); +# endif +_GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)); +_GL_CXXALIASWARN (wcsnlen); +#elif defined GNULIB_POSIXCHECK +# undef wcsnlen +# if HAVE_RAW_DECL_WCSNLEN +_GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - " + "use gnulib module wcsnlen for portability"); +# endif +#endif + + +/* Copy SRC to DEST. */ +#if @GNULIB_WCSCPY@ +# if !@HAVE_WCSCPY@ +_GL_FUNCDECL_SYS (wcscpy, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); +# endif +_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 +_GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - " + "use gnulib module wcscpy for portability"); +# endif +#endif + + +/* 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 *restrict dest, const wchar_t *restrict src)); +# endif +_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); +_GL_CXXALIASWARN (wcpcpy); +#elif defined GNULIB_POSIXCHECK +# undef wcpcpy +# if HAVE_RAW_DECL_WCPCPY +_GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " + "use gnulib module wcpcpy for portability"); +# endif +#endif + + +/* Copy no more than N wide characters of SRC to DEST. */ +#if @GNULIB_WCSNCPY@ +# if !@HAVE_WCSNCPY@ +_GL_FUNCDECL_SYS (wcsncpy, wchar_t *, + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wcsncpy, wchar_t *, + (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 +_GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - " + "use gnulib module wcsncpy for portability"); +# endif +#endif + + +/* Copy no more than N characters of SRC to DEST, returning the address of + the last character written into DEST. */ +#if @GNULIB_WCPNCPY@ +# if !@HAVE_WCPNCPY@ +_GL_FUNCDECL_SYS (wcpncpy, wchar_t *, + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +# endif +_GL_CXXALIAS_SYS (wcpncpy, wchar_t *, + (wchar_t *restrict dest, + const wchar_t *restrict src, size_t n)); +_GL_CXXALIASWARN (wcpncpy); +#elif defined GNULIB_POSIXCHECK +# undef wcpncpy +# if HAVE_RAW_DECL_WCPNCPY +_GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - " + "use gnulib module wcpncpy for portability"); +# endif +#endif + + +/* Append SRC onto DEST. */ +#if @GNULIB_WCSCAT@ +# if !@HAVE_WCSCAT@ +_GL_FUNCDECL_SYS (wcscat, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src)); +# endif +_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 +_GL_WARN_ON_USE (wcscat, "wcscat is unportable - " + "use gnulib module wcscat for portability"); +# endif +#endif + + +/* Append no more than N wide characters of SRC onto DEST. */ +#if @GNULIB_WCSNCAT@ +# if !@HAVE_WCSNCAT@ +_GL_FUNCDECL_SYS (wcsncat, wchar_t *, + (wchar_t *restrict dest, const wchar_t *restrict src, + size_t n)); +# endif +_GL_CXXALIAS_SYS (wcsncat, wchar_t *, + (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 +_GL_WARN_ON_USE (wcsncat, "wcsncat is unportable - " + "use gnulib module wcsncat for portability"); +# endif +#endif + + +/* Compare S1 and S2. */ +#if @GNULIB_WCSCMP@ +# if !@HAVE_WCSCMP@ +_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 +_GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - " + "use gnulib module wcscmp for portability"); +# endif +#endif + + +/* Compare no more than N wide characters of S1 and S2. */ +#if @GNULIB_WCSNCMP@ +# if !@HAVE_WCSNCMP@ +_GL_FUNCDECL_SYS (wcsncmp, int, + (const wchar_t *s1, const wchar_t *s2, size_t n) + _GL_ATTRIBUTE_PURE); +# 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 +_GL_WARN_ON_USE (wcsncmp, "wcsncmp is unportable - " + "use gnulib module wcsncmp for portability"); +# endif +#endif + + +/* Compare S1 and S2, ignoring case. */ +#if @GNULIB_WCSCASECMP@ +# if !@HAVE_WCSCASECMP@ +_GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2) + _GL_ATTRIBUTE_PURE); +# endif +_GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)); +_GL_CXXALIASWARN (wcscasecmp); +#elif defined GNULIB_POSIXCHECK +# undef wcscasecmp +# if HAVE_RAW_DECL_WCSCASECMP +_GL_WARN_ON_USE (wcscasecmp, "wcscasecmp is unportable - " + "use gnulib module wcscasecmp for portability"); +# endif +#endif + + +/* Compare no more than N chars of S1 and S2, ignoring case. */ +#if @GNULIB_WCSNCASECMP@ +# if !@HAVE_WCSNCASECMP@ +_GL_FUNCDECL_SYS (wcsncasecmp, int, + (const wchar_t *s1, const wchar_t *s2, size_t n) + _GL_ATTRIBUTE_PURE); +# endif +_GL_CXXALIAS_SYS (wcsncasecmp, int, + (const wchar_t *s1, const wchar_t *s2, size_t n)); +_GL_CXXALIASWARN (wcsncasecmp); +#elif defined GNULIB_POSIXCHECK +# undef wcsncasecmp +# if HAVE_RAW_DECL_WCSNCASECMP +_GL_WARN_ON_USE (wcsncasecmp, "wcsncasecmp is unportable - " + "use gnulib module wcsncasecmp for portability"); +# endif +#endif + + +/* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE + category of the current locale. */ +#if @GNULIB_WCSCOLL@ +# if !@HAVE_WCSCOLL@ +_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 +_GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - " + "use gnulib module wcscoll for portability"); +# endif +#endif + + +/* Transform S2 into array pointed to by S1 such that if wcscmp is applied + to two transformed strings the result is the as applying 'wcscoll' to the + original strings. */ +#if @GNULIB_WCSXFRM@ +# if !@HAVE_WCSXFRM@ +_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 *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 +_GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - " + "use gnulib module wcsxfrm for portability"); +# endif +#endif + + +/* Duplicate S, returning an identical malloc'd string. */ +#if @GNULIB_WCSDUP@ +# 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); +#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 + + +/* Find the first occurrence of WC in WCS. */ +#if @GNULIB_WCSCHR@ +# if !@HAVE_WCSCHR@ +_GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc) + _GL_ATTRIBUTE_PURE); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { + const wchar_t * std::wcschr (const wchar_t *, wchar_t); + wchar_t * std::wcschr (wchar_t *, wchar_t); + } */ +_GL_CXXALIAS_SYS_CAST2 (wcschr, + wchar_t *, (const wchar_t *, wchar_t), + const wchar_t *, (const wchar_t *, wchar_t)); +# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__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)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (wcschr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wcschr +# if HAVE_RAW_DECL_WCSCHR +_GL_WARN_ON_USE (wcschr, "wcschr is unportable - " + "use gnulib module wcschr for portability"); +# endif +#endif + + +/* Find the last occurrence of WC in WCS. */ +#if @GNULIB_WCSRCHR@ +# if !@HAVE_WCSRCHR@ +_GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc) + _GL_ATTRIBUTE_PURE); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { + const wchar_t * std::wcsrchr (const wchar_t *, wchar_t); + wchar_t * std::wcsrchr (wchar_t *, wchar_t); + } */ +_GL_CXXALIAS_SYS_CAST2 (wcsrchr, + wchar_t *, (const wchar_t *, wchar_t), + const wchar_t *, (const wchar_t *, wchar_t)); +# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__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)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (wcsrchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wcsrchr +# if HAVE_RAW_DECL_WCSRCHR +_GL_WARN_ON_USE (wcsrchr, "wcsrchr is unportable - " + "use gnulib module wcsrchr for portability"); +# endif +#endif + + +/* Return the length of the initial segmet of WCS which consists entirely + of wide characters not in REJECT. */ +#if @GNULIB_WCSCSPN@ +# if !@HAVE_WCSCSPN@ +_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 +_GL_WARN_ON_USE (wcscspn, "wcscspn is unportable - " + "use gnulib module wcscspn for portability"); +# endif +#endif + + +/* Return the length of the initial segmet of WCS which consists entirely + of wide characters in ACCEPT. */ +#if @GNULIB_WCSSPN@ +# if !@HAVE_WCSSPN@ +_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 +_GL_WARN_ON_USE (wcsspn, "wcsspn is unportable - " + "use gnulib module wcsspn for portability"); +# endif +#endif + + +/* Find the first occurrence in WCS of any character in ACCEPT. */ +#if @GNULIB_WCSPBRK@ +# if !@HAVE_WCSPBRK@ +_GL_FUNCDECL_SYS (wcspbrk, wchar_t *, + (const wchar_t *wcs, const wchar_t *accept) + _GL_ATTRIBUTE_PURE); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { + const wchar_t * std::wcspbrk (const wchar_t *, const wchar_t *); + wchar_t * std::wcspbrk (wchar_t *, const wchar_t *); + } */ +_GL_CXXALIAS_SYS_CAST2 (wcspbrk, + wchar_t *, (const wchar_t *, const wchar_t *), + const wchar_t *, (const wchar_t *, const wchar_t *)); +# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_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)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (wcspbrk); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wcspbrk +# if HAVE_RAW_DECL_WCSPBRK +_GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - " + "use gnulib module wcspbrk for portability"); +# endif +#endif + + +/* Find the first occurrence of NEEDLE in HAYSTACK. */ +#if @GNULIB_WCSSTR@ +# if !@HAVE_WCSSTR@ +_GL_FUNCDECL_SYS (wcsstr, wchar_t *, + (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: + extern "C++" { + const wchar_t * std::wcsstr (const wchar_t *, const wchar_t *); + wchar_t * std::wcsstr (wchar_t *, const wchar_t *); + } */ +_GL_CXXALIAS_SYS_CAST2 (wcsstr, + 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 *restrict haystack, + const wchar_t *restrict needle)); +_GL_CXXALIASWARN1 (wcsstr, const wchar_t *, + (const wchar_t *restrict haystack, + const wchar_t *restrict needle)); +# elif __GLIBC__ >= 2 +_GL_CXXALIASWARN (wcsstr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef wcsstr +# if HAVE_RAW_DECL_WCSSTR +_GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - " + "use gnulib module wcsstr for portability"); +# endif +#endif + + +/* Divide WCS into tokens separated by characters in DELIM. */ +#if @GNULIB_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 *restrict wcs, const wchar_t *restrict delim, + wchar_t **restrict ptr)); +# endif +_GL_CXXALIAS_SYS (wcstok, wchar_t *, + (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 +_GL_WARN_ON_USE (wcstok, "wcstok is unportable - " + "use gnulib module wcstok for portability"); +# endif +#endif + + +/* Determine number of column positions required for first N wide + characters (or fewer if S ends before this) in S. */ +#if @GNULIB_WCSWIDTH@ +# if @REPLACE_WCSWIDTH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcswidth +# define wcswidth rpl_wcswidth +# endif +_GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n) + _GL_ATTRIBUTE_PURE); +_GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n)); +# else +# if !@HAVE_WCSWIDTH@ +_GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n) + _GL_ATTRIBUTE_PURE); +# 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 +_GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - " + "use gnulib module wcswidth for portability"); +# endif +#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/lib/wcrtomb.c b/lib/wcrtomb.c new file mode 100644 index 0000000..e14d802 --- /dev/null +++ b/lib/wcrtomb.c @@ -0,0 +1,80 @@ +/* Convert wide character to multibyte character. + 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 + +#include +#include + + +size_t +wcrtomb (char *s, wchar_t wc, mbstate_t *ps) +#undef wcrtomb +{ + /* 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) + return ret; + else + { + errno = EILSEQ; + return (size_t)(-1); + } +#endif + } +} diff --git a/lib/wctype-h.c b/lib/wctype-h.c new file mode 100644 index 0000000..1278143 --- /dev/null +++ b/lib/wctype-h.c @@ -0,0 +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/lib/wctype.in.h b/lib/wctype.in.h new file mode 100644 index 0000000..98cafee --- /dev/null +++ b/lib/wctype.in.h @@ -0,0 +1,732 @@ +/* A substitute for ISO C99 , for platforms that lack it. + + 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 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. + */ + +#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 . */ +# include +#endif + +/* 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. + BeOS 5 has the functions but no . */ +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_WCTYPE_H@ +# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@ +#endif + +#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 +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Solaris 2.6 includes which includes which + #defines a number of identifiers in the application namespace. Revert + these #defines. */ +#ifdef __sun +# undef multibyte +# undef eucw1 +# undef eucw2 +# undef eucw3 +# undef scrw1 +# undef scrw2 +# undef scrw3 +#endif + +/* Define wint_t and WEOF. (Also done in wchar.in.h.) */ +#if !@HAVE_WINT_T@ && !defined wint_t +# define wint_t int +# ifndef WEOF +# define WEOF -1 +# endif +#else +/* 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 +# if @HAVE_CRTDEFS_H@ +# include +# else +# include +# endif +typedef unsigned int rpl_wint_t; +# undef wint_t +# define wint_t rpl_wint_t +# define GNULIB_defined_wint_t 1 +# endif +# endif +# ifndef WEOF +# define WEOF ((wint_t) -1) +# endif +#endif + + +#if !GNULIB_defined_wctype_functions + +/* 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@ + +# 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); +} + +# 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 +# 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 +# define towlower rpl_towlower +# define towupper rpl_towupper +# 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@ +rpl_iswalnum +# else +iswalnum +# endif + (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswalpha +# else +iswalpha +# endif + (wint_t wc) +{ + return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswblank +# else +iswblank +# endif + (wint_t wc) +{ + return wc == ' ' || wc == '\t'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswcntrl +# else +iswcntrl +# endif + (wint_t wc) +{ + return (wc & ~0x1f) == 0 || wc == 0x7f; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWDIGIT@ +rpl_iswdigit +# else +iswdigit +# endif + (wint_t wc) +{ + return wc >= '0' && wc <= '9'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswgraph +# else +iswgraph +# endif + (wint_t wc) +{ + return wc >= '!' && wc <= '~'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswlower +# else +iswlower +# endif + (wint_t wc) +{ + return wc >= 'a' && wc <= 'z'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswprint +# else +iswprint +# endif + (wint_t wc) +{ + return wc >= ' ' && wc <= '~'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswpunct +# else +iswpunct +# endif + (wint_t wc) +{ + return (wc >= '!' && wc <= '~' + && !((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswspace +# else +iswspace +# endif + (wint_t wc) +{ + return (wc == ' ' || wc == '\t' + || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWCNTRL@ +rpl_iswupper +# else +iswupper +# endif + (wint_t wc) +{ + return wc >= 'A' && wc <= 'Z'; +} + +_GL_WCTYPE_INLINE int +# if @REPLACE_ISWXDIGIT@ +rpl_iswxdigit +# else +iswxdigit +# endif + (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); +} + +_GL_WCTYPE_INLINE wint_t +# if @REPLACE_TOWLOWER@ +rpl_towlower +# else +towlower +# endif + (wint_t wc) +{ + return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); +} + +_GL_WCTYPE_INLINE wint_t +# if @REPLACE_TOWLOWER@ +rpl_towupper +# else +towupper +# endif + (wint_t wc) +{ + return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); +} + +# 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 +_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__ && !@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 + to take a wchar_t argument and return a wchar_t result. mingw declares + these functions to take a wint_t argument and return a wint_t result. + This means that: + 1. When the user passes an argument outside the range 0x0000..0xFFFF, the + function will look only at the lower 16 bits. This is allowed according + to POSIX. + 2. The return value is returned in the lower 16 bits of the result register. + The upper 16 bits are random: whatever happened to be in that part of the + result register. We need to fix this by adding a zero-extend from + wchar_t to wint_t after the call. */ + +_GL_WCTYPE_INLINE wint_t +rpl_towlower (wint_t wc) +{ + return (wint_t) (wchar_t) towlower (wc); +} +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define towlower rpl_towlower +# endif + +_GL_WCTYPE_INLINE wint_t +rpl_towupper (wint_t wc) +{ + return (wint_t) (wchar_t) towupper (wc); +} +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define towupper rpl_towupper +# endif + +# endif /* __MINGW32__ && !@GNULIBHEADERS_OVERRIDE_WINT_T@ */ + +# define GNULIB_defined_wctype_functions 1 +#endif + +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswalnum, 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); +_GL_CXXALIASWARN (iswdigit); +_GL_CXXALIASWARN (iswgraph); +_GL_CXXALIASWARN (iswlower); +_GL_CXXALIASWARN (iswprint); +_GL_CXXALIASWARN (iswpunct); +_GL_CXXALIASWARN (iswspace); +_GL_CXXALIASWARN (iswupper); +_GL_CXXALIASWARN (iswxdigit); +#endif + +#if @GNULIB_ISWBLANK@ +# if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@ +_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@ +# if !GNULIB_defined_wctype_t +typedef void * wctype_t; +# define GNULIB_defined_wctype_t 1 +# endif +#endif + +/* Get a descriptor for a wide character property. */ +#if @GNULIB_WCTYPE@ +# if !@HAVE_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 +_GL_WARN_ON_USE (wctype, "wctype is unportable - " + "use gnulib module wctype for portability"); +# endif +#endif + +/* Test whether a wide character has a given property. + 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 @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 +_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 +_GL_WARN_ON_USE (iswctype, "iswctype is unportable - " + "use gnulib module iswctype for portability"); +# endif +#endif + +#if @REPLACE_TOWLOWER@ || defined __MINGW32__ +_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc)); +_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); +#else +_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 +typedef void * wctrans_t; +# define GNULIB_defined_wctrans_t 1 +# endif +#endif + +/* Get a descriptor for a wide character case conversion. */ +#if @GNULIB_WCTRANS@ +# if !@HAVE_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 +_GL_WARN_ON_USE (wctrans, "wctrans is unportable - " + "use gnulib module wctrans for portability"); +# endif +#endif + +/* Perform a given case conversion on a wide character. + The argument WC must be either a wchar_t value or WEOF. + The argument DESC must have been returned by the wctrans() function. */ +#if @GNULIB_TOWCTRANS@ +# if !@HAVE_WCTRANS_T@ +_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 +_GL_WARN_ON_USE (towctrans, "towctrans is unportable - " + "use gnulib module towctrans for portability"); +# endif +#endif + +_GL_INLINE_HEADER_END + +#endif /* _@GUARD_PREFIX@_WCTYPE_H */ +#endif /* _@GUARD_PREFIX@_WCTYPE_H */ +#endif diff --git a/lib/wcwidth.c b/lib/wcwidth.c new file mode 100644 index 0000000..f99a0a6 --- /dev/null +++ b/lib/wcwidth.c @@ -0,0 +1,73 @@ +/* Determine the number of screen columns needed for a character. + Copyright (C) 2006-2007, 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 . */ + +#include + +/* Specification. */ +#include + +/* Get iswprint. */ +#include + +#include "localcharset.h" +#include "streq.h" +#include "uniwidth.h" + +/* Returns 1 if the current locale is an UTF-8 locale, 0 otherwise. */ +static inline int +is_locale_utf8 (void) +{ + const char *encoding = locale_charset (); + return STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0); +} + +#if GNULIB_WCHAR_SINGLE_LOCALE +/* When we know that the locale does not change, provide a speedup by + caching the value of is_locale_utf8. */ +static int cached_is_locale_utf8 = -1; +static inline int +is_locale_utf8_cached (void) +{ + if (cached_is_locale_utf8 < 0) + cached_is_locale_utf8 = is_locale_utf8 (); + return cached_is_locale_utf8; +} +#else +/* By default, don't make assumptions, hence no caching. */ +# define is_locale_utf8_cached is_locale_utf8 +#endif + +int +wcwidth (wchar_t wc) +#undef wcwidth +{ + /* In UTF-8 locales, use a Unicode aware width function. */ + if (is_locale_utf8_cached ()) + { + /* We assume that in a UTF-8 locale, a wide character is the same as a + Unicode character. */ + return uc_width (wc, "UTF-8"); + } + else + { + /* Otherwise, fall back to the system's wcwidth function. */ +#if HAVE_WCWIDTH + return wcwidth (wc); +#else + return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; +#endif + } +} diff --git a/lib/windows-initguard.h b/lib/windows-initguard.h new file mode 100644 index 0000000..a29d7e9 --- /dev/null +++ b/lib/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/lib/windows-mutex.c b/lib/windows-mutex.c new file mode 100644 index 0000000..28e429c --- /dev/null +++ b/lib/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/lib/windows-mutex.h b/lib/windows-mutex.h new file mode 100644 index 0000000..7aedfdf --- /dev/null +++ b/lib/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/lib/windows-once.c b/lib/windows-once.c new file mode 100644 index 0000000..deea548 --- /dev/null +++ b/lib/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/lib/windows-once.h b/lib/windows-once.h new file mode 100644 index 0000000..85534c9 --- /dev/null +++ b/lib/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/lib/windows-recmutex.c b/lib/windows-recmutex.c new file mode 100644 index 0000000..d8087ac --- /dev/null +++ b/lib/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/lib/windows-recmutex.h b/lib/windows-recmutex.h new file mode 100644 index 0000000..746e75c --- /dev/null +++ b/lib/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/lib/windows-rwlock.c b/lib/windows-rwlock.c new file mode 100644 index 0000000..d186e03 --- /dev/null +++ b/lib/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/lib/windows-rwlock.h b/lib/windows-rwlock.h new file mode 100644 index 0000000..65c5ab4 --- /dev/null +++ b/lib/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/lib/windows-spawn.c b/lib/windows-spawn.c new file mode 100644 index 0000000..a9212d4 --- /dev/null +++ b/lib/windows-spawn.c @@ -0,0 +1,727 @@ +/* Auxiliary functions for the creation of subprocesses. Native Windows API. + Copyright (C) 2001, 2003-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + 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 "windows-spawn.h" + +/* Get declarations of the native Windows API functions. */ +#define WIN32_LEAN_AND_MEAN +#include + +#include +#include +#include +#include +#include + +/* Get _get_osfhandle(). */ +#if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +#else +# include +#endif +#include + +#include "findprog.h" + +/* Don't assume that UNICODE is not defined. */ +#undef STARTUPINFO +#define STARTUPINFO STARTUPINFOA +#undef CreateProcess +#define CreateProcess CreateProcessA + +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037*?" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" + +/* Returns the length of a quoted argument string. */ +static size_t +quoted_arg_length (const char *string) +{ + bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + return length; +} + +/* Produces a quoted argument string. + Stores exactly quoted_arg_length (STRING) + 1 bytes, including the final + NUL byte, at MEM. + Returns a pointer past the stored quoted argument string. */ +static char * +quoted_arg_string (const char *string, char *mem) +{ + bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + char *p; + unsigned int backslashes; + const char *s; + + p = mem; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p++ = '\0'; + + return p; +} + +const char ** +prepare_spawn (const char * const *argv, char **mem_to_free) +{ + size_t argc; + const char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = (const char **) malloc ((1 + argc + 1) * sizeof (const char *)); + + /* Add an element upfront that can be used when argv[0] turns out to be a + script, not a program. + On Unix, this would be "/bin/sh". On native Windows, "sh" is actually + "sh.exe". We have to omit the directory part and rely on the search in + PATH, because the mingw "mount points" are not visible inside Windows + CreateProcess(). */ + new_argv[0] = "sh.exe"; + + /* Put quoted arguments into the new argument vector. */ + size_t needed_size = 0; + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + size_t length; + + if (string[0] == '\0') + length = strlen ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + length = quoted_arg_length (string); + else + length = strlen (string); + needed_size += length + 1; + } + + char *mem; + if (needed_size == 0) + mem = NULL; + else + { + mem = (char *) malloc (needed_size); + if (mem == NULL) + { + /* Memory allocation failure. */ + free (new_argv); + errno = ENOMEM; + return NULL; + } + } + *mem_to_free = mem; + + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + new_argv[1 + i] = mem; + if (string[0] == '\0') + { + size_t length = strlen ("\"\""); + memcpy (mem, "\"\"", length + 1); + mem += length + 1; + } + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + mem = quoted_arg_string (string, mem); + } + else + { + size_t length = strlen (string); + memcpy (mem, string, length + 1); + mem += length + 1; + } + } + new_argv[1 + argc] = NULL; + + return new_argv; +} + +char * +compose_command (const char * const *argv) +{ + /* Just concatenate the argv[] strings, separated by spaces. */ + char *command; + + /* Determine the size of the needed block of memory. */ + size_t total_size = 0; + const char * const *ap; + const char *p; + for (ap = argv; (p = *ap) != NULL; ap++) + total_size += strlen (p) + 1; + size_t command_size = (total_size > 0 ? total_size : 1); + + /* Allocate the block of memory. */ + command = (char *) malloc (command_size); + if (command == NULL) + { + errno = ENOMEM; + return NULL; + } + + /* Fill it. */ + if (total_size > 0) + { + char *cp = command; + for (ap = argv; (p = *ap) != NULL; ap++) + { + size_t size = strlen (p) + 1; + memcpy (cp, p, size - 1); + cp += size; + cp[-1] = ' '; + } + cp[-1] = '\0'; + } + else + *command = '\0'; + + return command; +} + +char * +compose_envblock (const char * const *envp) +{ + /* This is a bit hairy, because we don't have a lock that would prevent other + threads from making modifications in ENVP. So, just make sure we don't + crash; but if other threads are making modifications, part of the result + may be wrong. */ + retry: + { + /* Guess the size of the needed block of memory. + The guess will be exact if other threads don't make modifications. */ + size_t total_size = 0; + const char * const *ep; + const char *p; + for (ep = envp; (p = *ep) != NULL; ep++) + total_size += strlen (p) + 1; + size_t envblock_size = total_size; + + /* Allocate the block of memory. */ + char *envblock = (char *) malloc (envblock_size + 1); + if (envblock == NULL) + { + errno = ENOMEM; + return NULL; + } + size_t envblock_used = 0; + for (ep = envp; (p = *ep) != NULL; ep++) + { + size_t size = strlen (p) + 1; + if (envblock_used + size > envblock_size) + { + /* Other threads did modifications. Need more memory. */ + envblock_size += envblock_size / 2; + if (envblock_used + size > envblock_size) + envblock_size = envblock_used + size; + + char *new_envblock = (char *) realloc (envblock, envblock_size + 1); + if (new_envblock == NULL) + { + free (envblock); + errno = ENOMEM; + return NULL; + } + envblock = new_envblock; + } + memcpy (envblock + envblock_used, p, size); + envblock_used += size; + if (envblock[envblock_used - 1] != '\0') + { + /* Other threads did modifications. Restart. */ + free (envblock); + goto retry; + } + } + envblock[envblock_used] = '\0'; + return envblock; + } +} + +int +init_inheritable_handles (struct inheritable_handles *inh_handles, + bool duplicate) +{ + /* Determine the minimal count of handles we need to care about. */ + size_t handles_count; + { + /* _getmaxstdio + + Default value is 512. */ + unsigned int fdmax = _getmaxstdio (); + if (fdmax < 3) + fdmax = 3; + for (; fdmax > 3; fdmax--) + { + unsigned int fd = fdmax - 1; + /* _get_osfhandle + */ + HANDLE handle = (HANDLE) _get_osfhandle (fd); + if (handle != INVALID_HANDLE_VALUE) + { + DWORD hflags; + /* GetHandleInformation + */ + if (GetHandleInformation (handle, &hflags)) + { + if ((hflags & HANDLE_FLAG_INHERIT) != 0) + /* fd denotes an inheritable descriptor. */ + break; + } + } + } + handles_count = fdmax; + } + /* Note: handles_count >= 3. */ + + /* Allocate the arrays. */ + size_t handles_allocated = handles_count; + HANDLE *handles_array = + (HANDLE *) malloc (handles_allocated * sizeof (HANDLE)); + if (handles_array == NULL) + { + errno = ENOMEM; + return -1; + } + unsigned char *flags_array = + (unsigned char *) malloc (handles_allocated * sizeof (unsigned char)); + if (flags_array == NULL) + { + free (handles_array); + errno = ENOMEM; + return -1; + } + + /* Fill in the two arrays. */ + { + HANDLE curr_process = (duplicate ? GetCurrentProcess () : INVALID_HANDLE_VALUE); + unsigned int fd; + for (fd = 0; fd < handles_count; fd++) + { + handles_array[fd] = INVALID_HANDLE_VALUE; + /* _get_osfhandle + */ + HANDLE handle = (HANDLE) _get_osfhandle (fd); + if (handle != INVALID_HANDLE_VALUE) + { + DWORD hflags; + /* GetHandleInformation + */ + if (GetHandleInformation (handle, &hflags)) + { + if ((hflags & HANDLE_FLAG_INHERIT) != 0) + { + /* fd denotes an inheritable descriptor. */ + if (duplicate) + { + if (!DuplicateHandle (curr_process, handle, + curr_process, &handles_array[fd], + 0, TRUE, DUPLICATE_SAME_ACCESS)) + { + unsigned int i; + for (i = 0; i < fd; i++) + if (handles_array[i] != INVALID_HANDLE_VALUE) + CloseHandle (handles_array[i]); + free (flags_array); + free (handles_array); + errno = EBADF; /* arbitrary */ + return -1; + } + } + else + handles_array[fd] = handle; + + flags_array[fd] = 0; + } + } + } + } + } + + /* Return the result. */ + inh_handles->count = handles_count; + inh_handles->allocated = handles_allocated; + inh_handles->handles = handles_array; + inh_handles->flags = flags_array; + return 0; +} + +int +compose_handles_block (const struct inheritable_handles *inh_handles, + STARTUPINFO *sinfo) +{ + /* STARTUPINFO + */ + sinfo->dwFlags = STARTF_USESTDHANDLES; + sinfo->hStdInput = inh_handles->handles[0]; + sinfo->hStdOutput = inh_handles->handles[1]; + sinfo->hStdError = inh_handles->handles[2]; + + /* On newer versions of Windows, more file descriptors / handles than the + first three can be passed. + The format is as follows: Let N be an exclusive upper bound for the file + descriptors to be passed. Two arrays are constructed in memory: + - flags[0..N-1], of element type 'unsigned char', + - handles[0..N-1], of element type 'HANDLE' or 'intptr_t'. + For used entries, handles[i] is the handle, and flags[i] is a set of flags, + a combination of: + 1 for open file descriptors, + 64 for handles of type FILE_TYPE_CHAR, + 8 for handles of type FILE_TYPE_PIPE, + 32 for O_APPEND. + For unused entries - this may include any of the first three, since they + are already passed above -, handles[i] is INVALID_HANDLE_VALUE and flags[i] + is zero. + lpReserved2 now is a pointer to the concatenation (without padding) of: + - an 'unsigned int' whose value is N, + - the contents of the flags[0..N-1] array, + - the contents of the handles[0..N-1] array. + cbReserved2 is the size (in bytes) of the object at lpReserved2. */ + + size_t handles_count = inh_handles->count; + + sinfo->cbReserved2 = + sizeof (unsigned int) + + handles_count * sizeof (unsigned char) + + handles_count * sizeof (HANDLE); + /* Add some padding, so that we can work with a properly aligned HANDLE + array. */ + char *hblock = (char *) malloc (sinfo->cbReserved2 + (sizeof (HANDLE) - 1)); + if (hblock == NULL) + { + errno = ENOMEM; + return -1; + } + unsigned char *flags = (unsigned char *) (hblock + sizeof (unsigned int)); + char *handles = (char *) (flags + handles_count); + HANDLE *handles_aligned = + (HANDLE *) (((uintptr_t) handles + (sizeof (HANDLE) - 1)) + & - (uintptr_t) sizeof (HANDLE)); + + * (unsigned int *) hblock = handles_count; + { + unsigned int fd; + for (fd = 0; fd < handles_count; fd++) + { + handles_aligned[fd] = INVALID_HANDLE_VALUE; + flags[fd] = 0; + + HANDLE handle = inh_handles->handles[fd]; + if (handle != INVALID_HANDLE_VALUE + /* The first three are possibly already passed above. + But they need to passed here as well, if they have some flags. */ + && (fd >= 3 || inh_handles->flags[fd] != 0)) + { + DWORD hflags; + /* GetHandleInformation + */ + if (GetHandleInformation (handle, &hflags)) + { + if ((hflags & HANDLE_FLAG_INHERIT) != 0) + { + /* fd denotes an inheritable descriptor. */ + handles_aligned[fd] = handle; + /* On Microsoft Windows, it would be sufficient to set + flags[fd] = 1. But on ReactOS or Wine, adding the bit + that indicates the handle type may be necessary. So, + just do it everywhere. */ + flags[fd] = 1 | inh_handles->flags[fd]; + switch (GetFileType (handle)) + { + case FILE_TYPE_CHAR: + flags[fd] |= 64; + break; + case FILE_TYPE_PIPE: + flags[fd] |= 8; + break; + default: + break; + } + } + else + /* We shouldn't have any non-inheritable handles in + inh_handles->handles. */ + abort (); + } + } + } + } + if (handles != (char *) handles_aligned) + memmove (handles, (char *) handles_aligned, handles_count * sizeof (HANDLE)); + + sinfo->lpReserved2 = (BYTE *) hblock; + + return 0; +} + +void +free_inheritable_handles (struct inheritable_handles *inh_handles) +{ + free (inh_handles->flags); + free (inh_handles->handles); +} + +int +convert_CreateProcess_error (DWORD error) +{ + /* Some of these errors probably cannot happen. But who knows... */ + switch (error) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_BAD_PATHNAME: + case ERROR_BAD_NET_NAME: + case ERROR_INVALID_NAME: + case ERROR_DIRECTORY: + return ENOENT; + break; + + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + return EACCES; + break; + + case ERROR_OUTOFMEMORY: + return ENOMEM; + break; + + case ERROR_BUFFER_OVERFLOW: + case ERROR_FILENAME_EXCED_RANGE: + return ENAMETOOLONG; + break; + + case ERROR_BAD_FORMAT: + case ERROR_BAD_EXE_FORMAT: + return ENOEXEC; + break; + + default: + return EINVAL; + break; + } +} + +intptr_t +spawnpvech (int mode, + const char *progname, const char * const *argv, + const char * const *envp, + const char *currdir, + HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle) +{ + /* Validate the arguments. */ + if (!(mode == P_WAIT + || mode == P_NOWAIT + || mode == P_DETACH + || mode == P_OVERLAY) + || progname == NULL || argv == NULL) + { + errno = EINVAL; + return -1; + } + + /* Implement the 'p' letter: search for PROGNAME in getenv ("PATH"). */ + const char *resolved_progname = + find_in_given_path (progname, getenv ("PATH"), NULL, false); + if (resolved_progname == NULL) + return -1; + + /* Compose the command. */ + char *command = compose_command (argv); + if (command == NULL) + goto out_of_memory_1; + + /* Copy *ENVP into a contiguous block of memory. */ + char *envblock; + if (envp == NULL) + envblock = NULL; + else + { + envblock = compose_envblock (envp); + if (envblock == NULL) + goto out_of_memory_2; + } + + /* Collect the inheritable handles. */ + struct inheritable_handles inh_handles; + if (init_inheritable_handles (&inh_handles, false) < 0) + { + int saved_errno = errno; + if (envblock != NULL) + free (envblock); + free (command); + if (resolved_progname != progname) + free ((char *) resolved_progname); + errno = saved_errno; + return -1; + } + inh_handles.handles[0] = stdin_handle; inh_handles.flags[0] = 0; + inh_handles.handles[1] = stdout_handle; inh_handles.flags[1] = 0; + inh_handles.handles[2] = stderr_handle; inh_handles.flags[2] = 0; + + /* CreateProcess + */ + /* */ + DWORD process_creation_flags = (mode == P_DETACH ? DETACHED_PROCESS : 0); + /* STARTUPINFO + */ + STARTUPINFO sinfo; + sinfo.cb = sizeof (STARTUPINFO); + sinfo.lpReserved = NULL; + sinfo.lpDesktop = NULL; + sinfo.lpTitle = NULL; + if (compose_handles_block (&inh_handles, &sinfo) < 0) + { + int saved_errno = errno; + free_inheritable_handles (&inh_handles); + if (envblock != NULL) + free (envblock); + free (command); + if (resolved_progname != progname) + free ((char *) resolved_progname); + errno = saved_errno; + return -1; + } + + PROCESS_INFORMATION pinfo; + if (!CreateProcess (resolved_progname, command, NULL, NULL, TRUE, + process_creation_flags, envblock, currdir, &sinfo, + &pinfo)) + { + DWORD error = GetLastError (); + + free (sinfo.lpReserved2); + free_inheritable_handles (&inh_handles); + if (envblock != NULL) + free (envblock); + free (command); + if (resolved_progname != progname) + free ((char *) resolved_progname); + + errno = convert_CreateProcess_error (error); + return -1; + } + + if (pinfo.hThread) + CloseHandle (pinfo.hThread); + free (sinfo.lpReserved2); + free_inheritable_handles (&inh_handles); + if (envblock != NULL) + free (envblock); + free (command); + if (resolved_progname != progname) + free ((char *) resolved_progname); + + switch (mode) + { + case P_WAIT: + { + /* Wait until it terminates. Then get its exit status code. */ + switch (WaitForSingleObject (pinfo.hProcess, INFINITE)) + { + case WAIT_OBJECT_0: + break; + case WAIT_FAILED: + errno = ECHILD; + return -1; + default: + abort (); + } + + DWORD exit_code; + if (!GetExitCodeProcess (pinfo.hProcess, &exit_code)) + { + errno = ECHILD; + return -1; + } + CloseHandle (pinfo.hProcess); + return exit_code; + } + + case P_NOWAIT: + /* Return pinfo.hProcess, not pinfo.dwProcessId. */ + return (intptr_t) pinfo.hProcess; + + case P_DETACH: + case P_OVERLAY: + CloseHandle (pinfo.hProcess); + return 0; + + default: + /* Already checked above. */ + abort (); + } + + /*NOTREACHED*/ + out_of_memory_2: + free (command); + out_of_memory_1: + if (resolved_progname != progname) + free ((char *) resolved_progname); + errno = ENOMEM; + return -1; +} diff --git a/lib/windows-spawn.h b/lib/windows-spawn.h new file mode 100644 index 0000000..0be407b --- /dev/null +++ b/lib/windows-spawn.h @@ -0,0 +1,157 @@ +/* Auxiliary functions for the creation of subprocesses. Native Windows API. + Copyright (C) 2001, 2003-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + 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 _WINDOWS_SPAWN_H +#define _WINDOWS_SPAWN_H + +#include +#include +#include + +/* Get declarations of the native Windows API functions. */ +#define WIN32_LEAN_AND_MEAN +#include + + +/* Prepares an argument vector before calling spawn(). + + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Windows CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + - '*', '?' characters may get expanded through wildcard expansion in the + callee: By default, in the callee, the initialization code before main() + takes the result of GetCommandLine(), wildcard-expands it, and passes it + to main(). The exceptions to this rule are: + - programs that inspect GetCommandLine() and ignore argv, + - mingw programs that have a global variable 'int _CRT_glob = 0;', + - Cygwin programs, when invoked from a Cygwin program. + + prepare_spawn creates and returns a new argument vector, where the arguments + are appropriately quoted and an additional argument "sh.exe" has been added + at the beginning. The new argument vector is freshly allocated. The memory + for all its elements is allocated within *MEM_TO_FREE, which is freshly + allocated as well. In case of memory allocation failure, NULL is returned, + with errno set. + */ +extern const char ** prepare_spawn (const char * const *argv, + char **mem_to_free); + +/* Composes the command to be passed to CreateProcess(). + ARGV must contain appropriately quoted arguments, as returned by + prepare_spawn. + Returns a freshly allocated string. In case of memory allocation failure, + NULL is returned, with errno set. */ +extern char * compose_command (const char * const *argv) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + +/* Composes the block of memory that contains the environment variables. + ENVP must contain an environment (a NULL-terminated array of string of the + form VARIABLE=VALUE). + Returns a freshly allocated block of memory. In case of memory allocation + failure, NULL is returned, with errno set. */ +extern char * compose_envblock (const char * const *envp) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + + +/* This struct keeps track of which handles to pass to a subprocess, and with + which flags. All of the handles here are inheritable. + Regarding handle inheritance, see + */ +struct inheritable_handles +{ + /* The number of occupied entries in the two arrays below. + 3 <= count <= allocated. */ + size_t count; + /* The number of allocated entries in the two arrays below. */ + size_t allocated; + /* handles[0..count-1] are the occupied entries. + handles[fd] is either INVALID_HANDLE_VALUE or an inheritable handle. */ + HANDLE *handles; + /* flags[0..count-1] are the occupied entries. + flags[fd] is only relevant if handles[fd] != INVALID_HANDLE_VALUE. + It is a bit mask consisting of: + - 32 for O_APPEND. + */ + unsigned char *flags; +}; + +/* Initializes a set of inheritable handles, filling in all inheritable handles + assigned to file descriptors. + If DUPLICATE is true, the handles stored in the set are duplicates. + Returns 0 upon success. In case of failure, -1 is returned, with errno set. + */ +extern int init_inheritable_handles (struct inheritable_handles *inh_handles, + bool duplicate); + +/* Fills a set of inheritable handles into a STARTUPINFO for CreateProcess(). + Returns 0 upon success. In case of failure, -1 is returned, with errno set. + */ +extern int compose_handles_block (const struct inheritable_handles *inh_handles, + STARTUPINFOA *sinfo); + +/* Frees the memory held by a set of inheritable handles. */ +extern void free_inheritable_handles (struct inheritable_handles *inh_handles); + + +/* Converts a CreateProcess() error code (retrieved through GetLastError()) to + an errno value. */ +extern int convert_CreateProcess_error (DWORD error); + + +/* Creates a subprocess. + MODE is either P_WAIT or P_NOWAIT. + PROGNAME is the program to invoke. + ARGV is the NULL-terminated array of arguments, ARGV[0] being PROGNAME by + convention. + ENVP is the NULL-terminated set of environment variable assignments, or NULL + to inherit the initial environ variable assignments from the caller and + ignore all calls to putenv(), setenv(), unsetenv() done in the caller. + CURRDIR is the directory in which to start the program, or NULL to inherit + the working directory from the caller. + STDIN_HANDLE, STDOUT_HANDLE, STDERR_HANDLE are the handles to use for the + first three file descriptors in the callee process. + Returns + - 0 for success (if MODE is P_WAIT), or + - a handle that be passed to _cwait (on Windows) or waitpid (on OS/2), or + - -1 upon error, with errno set. + */ +extern intptr_t spawnpvech (int mode, + const char *progname, const char * const *argv, + const char * const *envp, + const char *currdir, + HANDLE stdin_handle, HANDLE stdout_handle, + HANDLE stderr_handle); + +#endif /* _WINDOWS_SPAWN_H */ diff --git a/lib/wmemchr-impl.h b/lib/wmemchr-impl.h new file mode 100644 index 0000000..f92a362 --- /dev/null +++ b/lib/wmemchr-impl.h @@ -0,0 +1,27 @@ +/* Search wide character array for a wide character. + Copyright (C) 1999, 2011-2022 Free Software Foundation, Inc. + Written by Bruno Haible , 1999. + + 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 . */ + +wchar_t * +wmemchr (const wchar_t *s, wchar_t c, size_t n) +{ + for (; n > 0; s++, n--) + { + if (*s == c) + return (wchar_t *) s; + } + return NULL; +} diff --git a/lib/wmemchr.c b/lib/wmemchr.c new file mode 100644 index 0000000..127e1a5 --- /dev/null +++ b/lib/wmemchr.c @@ -0,0 +1,23 @@ +/* Search wide character array for a wide character. + Copyright (C) 2011-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 + +#include "wmemchr-impl.h" diff --git a/lib/wmempcpy.c b/lib/wmempcpy.c new file mode 100644 index 0000000..cdfa913 --- /dev/null +++ b/lib/wmempcpy.c @@ -0,0 +1,28 @@ +/* Copy wide character array, return pointer after last written wide character. + Copyright (C) 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 . */ + +#include + +/* Specification. */ +#include + +/* Copy N wide characters of SRC to DEST. + Return pointer to wide characters after the last written wide character. */ +wchar_t * +wmempcpy (wchar_t *dest, const wchar_t *src, size_t n) +{ + return wmemcpy (dest, src, n) + n; +} diff --git a/lib/write.c b/lib/write.c new file mode 100644 index 0000000..bcbc97c --- /dev/null +++ b/lib/write.c @@ -0,0 +1,155 @@ +/* POSIX compatible 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 + +/* 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. */ + +#if defined _WIN32 && ! defined __CYGWIN__ + +# include +# include +# include + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" +# endif +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif + +/* Don't assume that UNICODE is not defined. */ +# undef GetNamedPipeHandleState +# define GetNamedPipeHandleState GetNamedPipeHandleStateA + +# undef write + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +static ssize_t +write_nothrow (int fd, const void *buf, size_t count) +{ + ssize_t result; + + TRY_MSVC_INVAL + { + result = _write (fd, buf, count); + } + CATCH_MSVC_INVAL + { + result = -1; + errno = EBADF; + } + DONE_MSVC_INVAL; + + return result; +} +# else +# define write_nothrow _write +# endif + +ssize_t +rpl_write (int fd, const void *buf, size_t count) +{ + for (;;) + { + ssize_t ret = write_nothrow (fd, buf, count); + + if (ret < 0) + { +# if GNULIB_NONBLOCKING + if (errno == ENOSPC) + { + 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. + We can get here in four situations: + 1. When the pipe buffer is full. + 2. When count <= pipe_buf_size and the number of + free bytes in the pipe buffer is < count. + 3. When count > pipe_buf_size and the number of free + bytes in the pipe buffer is > 0, < pipe_buf_size. + 4. When count > pipe_buf_size and the pipe buffer is + entirely empty. + The cases 1 and 2 are POSIX compliant. In cases 3 and + 4 POSIX specifies that write() must split the request + and succeed with a partial write. We fix case 4. + We don't fix case 3 because it is not essential for + programs. */ + DWORD out_size; /* size of the buffer for outgoing data */ + DWORD in_size; /* size of the buffer for incoming data */ + if (GetNamedPipeInfo (h, NULL, &out_size, &in_size, NULL)) + { + size_t reduced_count = count; + /* In theory we need only one of out_size, in_size. + But I don't know which of the two. The description + is ambiguous. */ + if (out_size != 0 && out_size < reduced_count) + reduced_count = out_size; + if (in_size != 0 && in_size < reduced_count) + reduced_count = in_size; + if (reduced_count < count) + { + /* Attempt to write only the first part. */ + count = reduced_count; + continue; + } + } + /* Change errno from ENOSPC to EAGAIN. */ + errno = EAGAIN; + } + } + } + else +# endif + { +# if GNULIB_SIGPIPE + if (GetLastError () == ERROR_NO_DATA + && 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; + } +# endif + } + } + return ret; + } +} + +#endif diff --git a/lib/xalloc-die.c b/lib/xalloc-die.c new file mode 100644 index 0000000..5b947f1 --- /dev/null +++ b/lib/xalloc-die.c @@ -0,0 +1,41 @@ +/* Report a memory allocation failure and exit. + + 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 + (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 "xalloc.h" + +#include + +#include "error.h" +#include "exitfail.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +void +xalloc_die (void) +{ + error (exit_failure, 0, "%s", _("memory exhausted")); + + /* _Noreturn cannot be given to error, since it may return if + its first argument is 0. To help compilers understand the + xalloc_die does not return, call abort. Also, the abort is a + safety feature if exit_failure is 0 (which shouldn't happen). */ + abort (); +} diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h new file mode 100644 index 0000000..aefa6fd --- /dev/null +++ b/lib/xalloc-oversized.h @@ -0,0 +1,65 @@ +/* xalloc-oversized.h -- memory allocation size checking + + Copyright (C) 1990-2000, 2003-2004, 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 . */ + +#ifndef XALLOC_OVERSIZED_H_ +#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) \ + __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/lib/xalloc.h b/lib/xalloc.h new file mode 100644 index 0000000..9f4bf8d --- /dev/null +++ b/lib/xalloc.h @@ -0,0 +1,213 @@ +/* xalloc.h -- malloc with out-of-memory checking + + 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 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 XALLOC_H_ +#define XALLOC_H_ + +#include +#include +#include + +#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 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); + +#endif /* GNULIB_XALLOC_DIE */ + +#if GNULIB_XALLOC + +void *xmalloc (size_t s) + _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_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_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 *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_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_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 + following macros to a function pointer or array type, you need to typedef + it first and use the typedef name. */ + +/* Allocate an object of type T dynamically, with error checking. */ +/* extern t *XMALLOC (typename 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)))) + +/* 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))) + +/* 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)))) + + +/* 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) + _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)); +XALLOC_INLINE void * +xnrealloc (void *p, size_t n, size_t s) +{ + return xreallocarray (p, n, s); +} + +/* Return a pointer to a new buffer of N bytes. This is like xmalloc, + except it returns 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 + possible. */ + +template inline T * +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 xreallocarray (p, n, s); +} + +template inline T * +x2realloc (T *p, size_t *pn) +{ + return (T *) x2realloc ((void *) p, pn); +} + +template inline T * +x2nrealloc (T *p, size_t *pn, size_t s) +{ + return (T *) x2nrealloc ((void *) p, pn, s); +} + +template inline T * +xmemdup (T const *p, size_t s) +{ + return (T *) xmemdup ((void const *) p, s); +} + +#endif /* GNULIB_XALLOC && C++ */ + + +_GL_INLINE_HEADER_END + +#endif /* !XALLOC_H_ */ diff --git a/lib/xmalloc.c b/lib/xmalloc.c new file mode 100644 index 0000000..993c1ee --- /dev/null +++ b/lib/xmalloc.c @@ -0,0 +1,339 @@ +/* xmalloc.c -- malloc with out of memory checking + + 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 + (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 + +#define XALLOC_INLINE _GL_EXTERN_INLINE + +#include "xalloc.h" + +#include "ialloc.h" +#include "intprops.h" +#include "minmax.h" + +#include +#include + +static void * _GL_ATTRIBUTE_PURE +nonnull (void *p) +{ + if (!p) + xalloc_die (); + return p; +} + +/* Allocate S bytes of memory dynamically, with error checking. */ + +void * +xmalloc (size_t s) +{ + return nonnull (malloc (s)); +} + +void * +ximalloc (idx_t s) +{ + return nonnull (imalloc (s)); +} + +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 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) +{ + 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 = floor (1.5 * N) + 1 to make progress even if N == 0. */ + if (INT_ADD_WRAPV (n, (n >> 1) + 1, &n)) + xalloc_die (); + } + + p = xreallocarray (p, n, s); + *pn = n; + return p; +} + +/* 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 * +xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s) +{ + 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 (INT_ADD_WRAPV (n0, n0 >> 1, &n)) + 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 + = (INT_MULTIPLY_WRAPV (n, s, &nbytes) + ? 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 + && (INT_ADD_WRAPV (n0, n_incr_min, &n) + || (0 <= n_max && n_max < n) + || INT_MULTIPLY_WRAPV (n, s, &nbytes))) + xalloc_die (); + pa = xrealloc (pa, nbytes); + *pn = n; + return pa; +} + +/* Allocate S bytes of zeroed memory dynamically, with error checking. + There's no need for xnzalloc (N, S), since it would be equivalent + to xcalloc (N, S). */ + +void * +xzalloc (size_t 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 + checking. S must be nonzero. */ + +void * +xcalloc (size_t n, size_t s) +{ + 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 + for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any + need for an arithmetic overflow check. */ + +void * +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 * +xstrdup (char const *string) +{ + return xmemdup (string, strlen (string) + 1); +} diff --git a/lib/xmemdup0.c b/lib/xmemdup0.c new file mode 100644 index 0000000..f968e84 --- /dev/null +++ b/lib/xmemdup0.c @@ -0,0 +1,45 @@ +/* xmemdup0.c -- copy a block of arbitrary bytes, plus a trailing NUL + + 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 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 "xmemdup0.h" +#include "xalloc.h" + +#include + +/* Clone an arbitrary block of bytes P of size S, with error checking, + and include a terminating NUL byte. P is of type 'void const *', + to make it easier to use this with other mem* functions that return + 'void *', but since appending a NUL byte only makes sense on bytes, + the return type is 'char *'. + + The terminating NUL makes it safe to use strlen or rawmemchr to + check for embedded NUL; it also speeds up algorithms such as escape + sequence processing on arbitrary memory, by making it always safe + to read the byte after the escape character rather than having to + check if each escape character is the last byte in the object. */ + +char * +xmemdup0 (void const *p, size_t s) +{ + char *result = xcharalloc (s + 1); + if (s > 0) + memcpy (result, p, s); + result[s] = 0; + return result; +} diff --git a/lib/xmemdup0.h b/lib/xmemdup0.h new file mode 100644 index 0000000..b822a24 --- /dev/null +++ b/lib/xmemdup0.h @@ -0,0 +1,36 @@ +/* xmemdup0.h -- copy a block of arbitrary bytes, plus a trailing NUL + + 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 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 XMEMDUP_H_ +# define XMEMDUP_H_ + +# include + + +# ifdef __cplusplus +extern "C" { +# endif + +char *xmemdup0 (void const *p, size_t s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; + +# ifdef __cplusplus +} +# endif + +#endif /* !XMEMDUP0_H_ */ diff --git a/lib/xsize.c b/lib/xsize.c new file mode 100644 index 0000000..761e343 --- /dev/null +++ b/lib/xsize.c @@ -0,0 +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/lib/xsize.h b/lib/xsize.h new file mode 100644 index 0000000..0bfa4c8 --- /dev/null +++ b/lib/xsize.h @@ -0,0 +1,108 @@ +/* xsize.h -- Checked size_t computations. + + Copyright (C) 2003, 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 . */ + +#ifndef _XSIZE_H +#define _XSIZE_H + +/* Get size_t. */ +#include + +/* Get SIZE_MAX. */ +#include +#if HAVE_STDINT_H +# 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 +#endif + +/* The size of memory objects is often computed through expressions of + type size_t. Example: + void* p = malloc (header_size + n * element_size). + These computations can lead to overflow. When this happens, malloc() + returns a piece of memory that is way too small, and the program then + crashes while attempting to fill the memory. + To avoid this, the functions and macros in this file check for overflow. + The convention is that SIZE_MAX represents overflow. + malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc + implementation that uses mmap --, it's recommended to use size_overflow_p() + or size_in_bounds_p() before invoking malloc(). + The example thus becomes: + size_t size = xsum (header_size, xtimes (n, element_size)); + void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); +*/ + +/* Convert an arbitrary value >= 0 to type size_t. */ +#define xcast_size_t(N) \ + ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) + +/* Sum of two sizes, with overflow check. */ +XSIZE_INLINE size_t ATTRIBUTE_PURE +xsum (size_t size1, size_t size2) +{ + size_t sum = size1 + size2; + return (sum >= size1 ? sum : SIZE_MAX); +} + +/* Sum of three sizes, with overflow check. */ +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 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 ATTRIBUTE_PURE +xmax (size_t size1, size_t size2) +{ + /* No explicit check is needed here, because for any n: + max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ + return (size1 >= size2 ? size1 : size2); +} + +/* Multiplication of a count with an element size, with overflow check. + The count must be >= 0 and the element size must be > 0. + This is a macro, not a function, so that it works correctly even + when N is of a wider type and N > SIZE_MAX. */ +#define xtimes(N, ELSIZE) \ + ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) + +/* Check for overflow. */ +#define size_overflow_p(SIZE) \ + ((SIZE) == SIZE_MAX) +/* Check against overflow. */ +#define size_in_bounds_p(SIZE) \ + ((SIZE) != SIZE_MAX) + +_GL_INLINE_HEADER_END + +#endif /* _XSIZE_H */ diff --git a/lib/xstrndup.c b/lib/xstrndup.c new file mode 100644 index 0000000..a420212 --- /dev/null +++ b/lib/xstrndup.c @@ -0,0 +1,36 @@ +/* Duplicate a bounded initial segment of a string, with out-of-memory + checking. + Copyright (C) 2003, 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 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/lib/xstrndup.h b/lib/xstrndup.h new file mode 100644 index 0000000..fdd6573 --- /dev/null +++ b/lib/xstrndup.h @@ -0,0 +1,25 @@ +/* Duplicate a bounded initial segment of a string, with out-of-memory + checking. + Copyright (C) 2003, 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 . */ + +#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) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; -- cgit v1.2.3